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