Enhanced warden to allow reserving cells on remote hosts.
Change-Id: I20598dbf2705d454cd00b7e8ce5b04edcbf34fa9
diff --git a/utils/warden/src/main/java/org/onlab/warden/Warden.java b/utils/warden/src/main/java/org/onlab/warden/Warden.java
index f6c091a..e1c8f48 100644
--- a/utils/warden/src/main/java/org/onlab/warden/Warden.java
+++ b/utils/warden/src/main/java/org/onlab/warden/Warden.java
@@ -47,8 +47,6 @@
private static final String KEY_NOT_NULL = "User key cannot be null";
private static final String UTF_8 = "UTF-8";
- private static final String AUTHORIZED_KEYS = "authorized_keys";
-
private static final long TIMEOUT = 10; // 10 seconds
private static final int MAX_MINUTES = 240; // 4 hours max
private static final int MINUTE = 60_000; // 1 minute
@@ -62,13 +60,12 @@
private final Random random = new Random();
- private final Timer timer = new Timer("cell-pruner", true);
-
/**
* Creates a new cell warden.
*/
Warden() {
random.setSeed(System.currentTimeMillis());
+ Timer timer = new Timer("cell-pruner", true);
timer.schedule(new Reposessor(), MINUTE / 4, MINUTE / 2);
}
@@ -87,7 +84,7 @@
*
* @return list of cell names
*/
- Set<String> getAvailableCells() {
+ private Set<String> getAvailableCells() {
Set<String> available = new HashSet<>(getCells());
available.removeAll(getReservedCells());
return ImmutableSet.copyOf(available);
@@ -98,7 +95,7 @@
*
* @return list of cell names
*/
- Set<String> getReservedCells() {
+ private Set<String> getReservedCells() {
String[] list = reserved.list();
return list != null ? ImmutableSet.copyOf(list) : ImmutableSet.of();
}
@@ -109,7 +106,7 @@
* @param userName user name
* @return cell reservation record or null if user does not have one
*/
- Reservation currentUserReservation(String userName) {
+ private Reservation currentUserReservation(String userName) {
checkNotNull(userName, USER_NOT_NULL);
for (String cellName : getReservedCells()) {
Reservation reservation = currentCellReservation(cellName);
@@ -223,9 +220,10 @@
* @param sshKey ssh key
*/
private void createCell(Reservation reservation, String sshKey) {
- String cellInfo = getCellInfo(reservation.cellName);
- String cmd = String.format("bin/create-cell %s %s %s",
- reservation.cellName, cellInfo, sshKey);
+ CellInfo cellInfo = getCellInfo(reservation.cellName);
+ String cmd = String.format("ssh %s warden/bin/create-cell %s %s %s",
+ cellInfo.hostName, cellInfo.cellName,
+ cellInfo.ipPrefix, sshKey);
exec(cmd);
}
@@ -235,19 +233,22 @@
* @param reservation reservation record
*/
private void destroyCell(Reservation reservation) {
- exec("bin/destroy-cell " + reservation.cellName);
+ CellInfo cellInfo = getCellInfo(reservation.cellName);
+ exec(String.format("ssh %s warden/bin/destroy-cell %s",
+ cellInfo.hostName, cellInfo.cellName));
}
/**
- * Reads the definition of the specified cell.
+ * Reads the information about the specified cell.
*
* @param cellName cell name
- * @return cell definition
+ * @return cell information
*/
- String getCellInfo(String cellName) {
+ private CellInfo getCellInfo(String cellName) {
File cellFile = new File(supported, cellName);
try (InputStream stream = new FileInputStream(cellFile)) {
- return new String(ByteStreams.toByteArray(stream), UTF_8);
+ String[] fields = new String(ByteStreams.toByteArray(stream), UTF_8).split(" ");
+ return new CellInfo(cellName, fields[0], fields[1]);
} catch (IOException e) {
throw new IllegalStateException("Unable to definition for cell " + cellName, e);
}
@@ -266,7 +267,7 @@
}
// Creates an audit log entry.
- void log(String userName, String cellName, String action) {
+ private void log(String userName, String cellName, String action) {
try (FileOutputStream fos = new FileOutputStream(log, true);
PrintWriter pw = new PrintWriter(fos)) {
SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
@@ -278,8 +279,21 @@
}
}
+ // Carrier of cell information
+ private final class CellInfo {
+ final String cellName;
+ final String hostName;
+ final String ipPrefix;
+
+ private CellInfo(String cellName, String hostName, String ipPrefix) {
+ this.cellName = cellName;
+ this.hostName = hostName;
+ this.ipPrefix = ipPrefix;
+ }
+ }
+
// Task for re-possessing overdue cells
- private class Reposessor extends TimerTask {
+ private final class Reposessor extends TimerTask {
@Override
public void run() {
long now = System.currentTimeMillis();
diff --git a/utils/warden/src/main/java/org/onlab/warden/WardenServlet.java b/utils/warden/src/main/java/org/onlab/warden/WardenServlet.java
index a5f4f29..950fd42 100644
--- a/utils/warden/src/main/java/org/onlab/warden/WardenServlet.java
+++ b/utils/warden/src/main/java/org/onlab/warden/WardenServlet.java
@@ -48,11 +48,13 @@
Reservation reservation = warden.currentCellReservation(cellName);
if (reservation != null) {
long expiration = reservation.time + reservation.duration * 60_000;
- out.println(String.format("%-10s\t%-10s\t%s\t%s\t%s minutes", cellName,
+ long remaining = (expiration - System.currentTimeMillis()) / 60_000;
+ out.println(String.format("%-10s\t%-10s\t%s\t%s\t%s mins (%s remaining)",
+ cellName,
reservation.userName,
fmt.format(new Date(reservation.time)),
fmt.format(new Date(expiration)),
- reservation.duration));
+ reservation.duration, remaining));
} else {
out.println(String.format("%-10s\t%-10s", cellName, "available"));
}