Committed by
Gerrit Code Review
Enhanced warden to allow reserving cells on remote hosts.
Change-Id: I20598dbf2705d454cd00b7e8ce5b04edcbf34fa9
Showing
2 changed files
with
35 additions
and
19 deletions
| ... | @@ -47,8 +47,6 @@ class Warden { | ... | @@ -47,8 +47,6 @@ class Warden { |
| 47 | private static final String KEY_NOT_NULL = "User key cannot be null"; | 47 | private static final String KEY_NOT_NULL = "User key cannot be null"; |
| 48 | private static final String UTF_8 = "UTF-8"; | 48 | private static final String UTF_8 = "UTF-8"; |
| 49 | 49 | ||
| 50 | - private static final String AUTHORIZED_KEYS = "authorized_keys"; | ||
| 51 | - | ||
| 52 | private static final long TIMEOUT = 10; // 10 seconds | 50 | private static final long TIMEOUT = 10; // 10 seconds |
| 53 | private static final int MAX_MINUTES = 240; // 4 hours max | 51 | private static final int MAX_MINUTES = 240; // 4 hours max |
| 54 | private static final int MINUTE = 60_000; // 1 minute | 52 | private static final int MINUTE = 60_000; // 1 minute |
| ... | @@ -62,13 +60,12 @@ class Warden { | ... | @@ -62,13 +60,12 @@ class Warden { |
| 62 | 60 | ||
| 63 | private final Random random = new Random(); | 61 | private final Random random = new Random(); |
| 64 | 62 | ||
| 65 | - private final Timer timer = new Timer("cell-pruner", true); | ||
| 66 | - | ||
| 67 | /** | 63 | /** |
| 68 | * Creates a new cell warden. | 64 | * Creates a new cell warden. |
| 69 | */ | 65 | */ |
| 70 | Warden() { | 66 | Warden() { |
| 71 | random.setSeed(System.currentTimeMillis()); | 67 | random.setSeed(System.currentTimeMillis()); |
| 68 | + Timer timer = new Timer("cell-pruner", true); | ||
| 72 | timer.schedule(new Reposessor(), MINUTE / 4, MINUTE / 2); | 69 | timer.schedule(new Reposessor(), MINUTE / 4, MINUTE / 2); |
| 73 | } | 70 | } |
| 74 | 71 | ||
| ... | @@ -87,7 +84,7 @@ class Warden { | ... | @@ -87,7 +84,7 @@ class Warden { |
| 87 | * | 84 | * |
| 88 | * @return list of cell names | 85 | * @return list of cell names |
| 89 | */ | 86 | */ |
| 90 | - Set<String> getAvailableCells() { | 87 | + private Set<String> getAvailableCells() { |
| 91 | Set<String> available = new HashSet<>(getCells()); | 88 | Set<String> available = new HashSet<>(getCells()); |
| 92 | available.removeAll(getReservedCells()); | 89 | available.removeAll(getReservedCells()); |
| 93 | return ImmutableSet.copyOf(available); | 90 | return ImmutableSet.copyOf(available); |
| ... | @@ -98,7 +95,7 @@ class Warden { | ... | @@ -98,7 +95,7 @@ class Warden { |
| 98 | * | 95 | * |
| 99 | * @return list of cell names | 96 | * @return list of cell names |
| 100 | */ | 97 | */ |
| 101 | - Set<String> getReservedCells() { | 98 | + private Set<String> getReservedCells() { |
| 102 | String[] list = reserved.list(); | 99 | String[] list = reserved.list(); |
| 103 | return list != null ? ImmutableSet.copyOf(list) : ImmutableSet.of(); | 100 | return list != null ? ImmutableSet.copyOf(list) : ImmutableSet.of(); |
| 104 | } | 101 | } |
| ... | @@ -109,7 +106,7 @@ class Warden { | ... | @@ -109,7 +106,7 @@ class Warden { |
| 109 | * @param userName user name | 106 | * @param userName user name |
| 110 | * @return cell reservation record or null if user does not have one | 107 | * @return cell reservation record or null if user does not have one |
| 111 | */ | 108 | */ |
| 112 | - Reservation currentUserReservation(String userName) { | 109 | + private Reservation currentUserReservation(String userName) { |
| 113 | checkNotNull(userName, USER_NOT_NULL); | 110 | checkNotNull(userName, USER_NOT_NULL); |
| 114 | for (String cellName : getReservedCells()) { | 111 | for (String cellName : getReservedCells()) { |
| 115 | Reservation reservation = currentCellReservation(cellName); | 112 | Reservation reservation = currentCellReservation(cellName); |
| ... | @@ -223,9 +220,10 @@ class Warden { | ... | @@ -223,9 +220,10 @@ class Warden { |
| 223 | * @param sshKey ssh key | 220 | * @param sshKey ssh key |
| 224 | */ | 221 | */ |
| 225 | private void createCell(Reservation reservation, String sshKey) { | 222 | private void createCell(Reservation reservation, String sshKey) { |
| 226 | - String cellInfo = getCellInfo(reservation.cellName); | 223 | + CellInfo cellInfo = getCellInfo(reservation.cellName); |
| 227 | - String cmd = String.format("bin/create-cell %s %s %s", | 224 | + String cmd = String.format("ssh %s warden/bin/create-cell %s %s %s", |
| 228 | - reservation.cellName, cellInfo, sshKey); | 225 | + cellInfo.hostName, cellInfo.cellName, |
| 226 | + cellInfo.ipPrefix, sshKey); | ||
| 229 | exec(cmd); | 227 | exec(cmd); |
| 230 | } | 228 | } |
| 231 | 229 | ||
| ... | @@ -235,19 +233,22 @@ class Warden { | ... | @@ -235,19 +233,22 @@ class Warden { |
| 235 | * @param reservation reservation record | 233 | * @param reservation reservation record |
| 236 | */ | 234 | */ |
| 237 | private void destroyCell(Reservation reservation) { | 235 | private void destroyCell(Reservation reservation) { |
| 238 | - exec("bin/destroy-cell " + reservation.cellName); | 236 | + CellInfo cellInfo = getCellInfo(reservation.cellName); |
| 237 | + exec(String.format("ssh %s warden/bin/destroy-cell %s", | ||
| 238 | + cellInfo.hostName, cellInfo.cellName)); | ||
| 239 | } | 239 | } |
| 240 | 240 | ||
| 241 | /** | 241 | /** |
| 242 | - * Reads the definition of the specified cell. | 242 | + * Reads the information about the specified cell. |
| 243 | * | 243 | * |
| 244 | * @param cellName cell name | 244 | * @param cellName cell name |
| 245 | - * @return cell definition | 245 | + * @return cell information |
| 246 | */ | 246 | */ |
| 247 | - String getCellInfo(String cellName) { | 247 | + private CellInfo getCellInfo(String cellName) { |
| 248 | File cellFile = new File(supported, cellName); | 248 | File cellFile = new File(supported, cellName); |
| 249 | try (InputStream stream = new FileInputStream(cellFile)) { | 249 | try (InputStream stream = new FileInputStream(cellFile)) { |
| 250 | - return new String(ByteStreams.toByteArray(stream), UTF_8); | 250 | + String[] fields = new String(ByteStreams.toByteArray(stream), UTF_8).split(" "); |
| 251 | + return new CellInfo(cellName, fields[0], fields[1]); | ||
| 251 | } catch (IOException e) { | 252 | } catch (IOException e) { |
| 252 | throw new IllegalStateException("Unable to definition for cell " + cellName, e); | 253 | throw new IllegalStateException("Unable to definition for cell " + cellName, e); |
| 253 | } | 254 | } |
| ... | @@ -266,7 +267,7 @@ class Warden { | ... | @@ -266,7 +267,7 @@ class Warden { |
| 266 | } | 267 | } |
| 267 | 268 | ||
| 268 | // Creates an audit log entry. | 269 | // Creates an audit log entry. |
| 269 | - void log(String userName, String cellName, String action) { | 270 | + private void log(String userName, String cellName, String action) { |
| 270 | try (FileOutputStream fos = new FileOutputStream(log, true); | 271 | try (FileOutputStream fos = new FileOutputStream(log, true); |
| 271 | PrintWriter pw = new PrintWriter(fos)) { | 272 | PrintWriter pw = new PrintWriter(fos)) { |
| 272 | SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); | 273 | SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); |
| ... | @@ -278,8 +279,21 @@ class Warden { | ... | @@ -278,8 +279,21 @@ class Warden { |
| 278 | } | 279 | } |
| 279 | } | 280 | } |
| 280 | 281 | ||
| 282 | + // Carrier of cell information | ||
| 283 | + private final class CellInfo { | ||
| 284 | + final String cellName; | ||
| 285 | + final String hostName; | ||
| 286 | + final String ipPrefix; | ||
| 287 | + | ||
| 288 | + private CellInfo(String cellName, String hostName, String ipPrefix) { | ||
| 289 | + this.cellName = cellName; | ||
| 290 | + this.hostName = hostName; | ||
| 291 | + this.ipPrefix = ipPrefix; | ||
| 292 | + } | ||
| 293 | + } | ||
| 294 | + | ||
| 281 | // Task for re-possessing overdue cells | 295 | // Task for re-possessing overdue cells |
| 282 | - private class Reposessor extends TimerTask { | 296 | + private final class Reposessor extends TimerTask { |
| 283 | @Override | 297 | @Override |
| 284 | public void run() { | 298 | public void run() { |
| 285 | long now = System.currentTimeMillis(); | 299 | long now = System.currentTimeMillis(); | ... | ... |
| ... | @@ -48,11 +48,13 @@ public class WardenServlet extends HttpServlet { | ... | @@ -48,11 +48,13 @@ public class WardenServlet extends HttpServlet { |
| 48 | Reservation reservation = warden.currentCellReservation(cellName); | 48 | Reservation reservation = warden.currentCellReservation(cellName); |
| 49 | if (reservation != null) { | 49 | if (reservation != null) { |
| 50 | long expiration = reservation.time + reservation.duration * 60_000; | 50 | long expiration = reservation.time + reservation.duration * 60_000; |
| 51 | - out.println(String.format("%-10s\t%-10s\t%s\t%s\t%s minutes", cellName, | 51 | + long remaining = (expiration - System.currentTimeMillis()) / 60_000; |
| 52 | + out.println(String.format("%-10s\t%-10s\t%s\t%s\t%s mins (%s remaining)", | ||
| 53 | + cellName, | ||
| 52 | reservation.userName, | 54 | reservation.userName, |
| 53 | fmt.format(new Date(reservation.time)), | 55 | fmt.format(new Date(reservation.time)), |
| 54 | fmt.format(new Date(expiration)), | 56 | fmt.format(new Date(expiration)), |
| 55 | - reservation.duration)); | 57 | + reservation.duration, remaining)); |
| 56 | } else { | 58 | } else { |
| 57 | out.println(String.format("%-10s\t%-10s", cellName, "available")); | 59 | out.println(String.format("%-10s\t%-10s", cellName, "available")); |
| 58 | } | 60 | } | ... | ... |
-
Please register or login to post a comment