Committed by
Gerrit Code Review
Modified warden to create borrowed cells on-demand and to scrap returned ones.
Change-Id: If32a0da18ff9d4c05645017e5cc7481bbd1ab0cd
Showing
7 changed files
with
68 additions
and
83 deletions
... | @@ -113,17 +113,16 @@ function cell { | ... | @@ -113,17 +113,16 @@ function cell { |
113 | case "$cell" in | 113 | case "$cell" in |
114 | "borrow") | 114 | "borrow") |
115 | aux="/tmp/cell-$$" | 115 | aux="/tmp/cell-$$" |
116 | - curl -sS -X POST "http://$CELL_WARDEN:4321/?user=$(id -un)&duration=${2:-0}" \ | 116 | + curl -sS -X POST "http://$CELL_WARDEN:4321/?duration=${2:-0}&user=${3:-$(id -un)}" \ |
117 | -d "$(cat ~/.ssh/id_rsa.pub)" > $aux | 117 | -d "$(cat ~/.ssh/id_rsa.pub)" > $aux |
118 | . $aux | 118 | . $aux |
119 | rm -f $aux | 119 | rm -f $aux |
120 | export ONOS_INSTANCES=$(env | grep 'OC[0-9]*=' | sort | cut -d= -f2) | 120 | export ONOS_INSTANCES=$(env | grep 'OC[0-9]*=' | sort | cut -d= -f2) |
121 | setPrimaryInstance 1 >/dev/null | 121 | setPrimaryInstance 1 >/dev/null |
122 | - cell | ||
123 | onos-verify-cell | 122 | onos-verify-cell |
124 | ;; | 123 | ;; |
125 | "return") | 124 | "return") |
126 | - curl -sS -X DELETE "http://$CELL_WARDEN:4321/?user=$(id -un)" | 125 | + curl -sS -X DELETE "http://$CELL_WARDEN:4321/?user=${2:-$(id -un)}" |
127 | unset ONOS_CELL ONOS_NIC ONOS_IP ONOS_APPS ONOS_BOOT_FEATURES | 126 | unset ONOS_CELL ONOS_NIC ONOS_IP ONOS_APPS ONOS_BOOT_FEATURES |
128 | unset OCI OCN OCT ONOS_INSTANCES ONOS_FEATURES | 127 | unset OCI OCN OCT ONOS_INSTANCES ONOS_FEATURES |
129 | unset $(env | sed -n 's:\(^OC[0-9]\{1,\}\)=.*:\1 :g p') | 128 | unset $(env | sed -n 's:\(^OC[0-9]\{1,\}\)=.*:\1 :g p') | ... | ... |
... | @@ -6,6 +6,6 @@ | ... | @@ -6,6 +6,6 @@ |
6 | [ ! -d "$ONOS_ROOT" ] && echo "ONOS_ROOT is not defined" >&2 && exit 1 | 6 | [ ! -d "$ONOS_ROOT" ] && echo "ONOS_ROOT is not defined" >&2 && exit 1 |
7 | . $ONOS_ROOT/tools/build/envDefaults | 7 | . $ONOS_ROOT/tools/build/envDefaults |
8 | 8 | ||
9 | -for node in $(env | sort | egrep "OC[0-9N]+" | cut -d= -f2); do | 9 | +for node in $OCN $(env | sort | egrep "OC[0-9]+" | cut -d= -f2); do |
10 | - printf "%s: " $node; ssh -n -o PasswordAuthentication=no $ONOS_USER@$node date | 10 | + printf "%s: " $node; ssh -n -o StrictHostKeyChecking=no -o PasswordAuthentication=no $ONOS_USER@$node hostname |
11 | done | 11 | done | ... | ... |
... | @@ -8,7 +8,7 @@ echo "export ONOS_CELL=borrow" | ... | @@ -8,7 +8,7 @@ echo "export ONOS_CELL=borrow" |
8 | echo "export ONOS_NIC=\"10.128.11.*\"" | 8 | echo "export ONOS_NIC=\"10.128.11.*\"" |
9 | 9 | ||
10 | sudo lxc-ls -F "name,ipv4" --fancy | grep $name | \ | 10 | sudo lxc-ls -F "name,ipv4" --fancy | grep $name | \ |
11 | - sed "s/^$name/OC/" | tr "[:lower:]" "[:upper:]" | \ | 11 | + sed "s/^$name-/OC/" | tr "[:lower:]" "[:upper:]" | \ |
12 | sed -r 's/[ ]+/\=/;s/^/export /' | 12 | sed -r 's/[ ]+/\=/;s/^/export /' |
13 | 13 | ||
14 | echo "export OCT=\"\$OC1\"" | 14 | echo "export OCT=\"\$OC1\"" | ... | ... |
... | @@ -3,11 +3,12 @@ | ... | @@ -3,11 +3,12 @@ |
3 | 3 | ||
4 | name="$1" | 4 | name="$1" |
5 | ipx="$2" | 5 | ipx="$2" |
6 | -key="$3" | 6 | +shift 2 |
7 | +key="$@" | ||
7 | 8 | ||
8 | cd $(dirname $0) | 9 | cd $(dirname $0) |
9 | 10 | ||
10 | -./clone-node base-mininet ${ipx/x/0} $name-mn "$key" | 11 | +./clone-node base-mininet ${ipx/x/0} $name-n "$key" |
11 | 12 | ||
12 | for n in {1..3}; do | 13 | for n in {1..3}; do |
13 | ./clone-node base-onos ${ipx/x/$n} $name-$n "$key" | 14 | ./clone-node base-onos ${ipx/x/$n} $name-$n "$key" | ... | ... |
... | @@ -29,14 +29,11 @@ import java.io.PrintWriter; | ... | @@ -29,14 +29,11 @@ import java.io.PrintWriter; |
29 | import java.text.SimpleDateFormat; | 29 | import java.text.SimpleDateFormat; |
30 | import java.util.Date; | 30 | import java.util.Date; |
31 | import java.util.HashSet; | 31 | import java.util.HashSet; |
32 | -import java.util.List; | ||
33 | import java.util.Random; | 32 | import java.util.Random; |
34 | import java.util.Set; | 33 | import java.util.Set; |
35 | import java.util.Timer; | 34 | import java.util.Timer; |
36 | import java.util.TimerTask; | 35 | import java.util.TimerTask; |
37 | import java.util.concurrent.TimeUnit; | 36 | import java.util.concurrent.TimeUnit; |
38 | -import java.util.regex.Matcher; | ||
39 | -import java.util.regex.Pattern; | ||
40 | 37 | ||
41 | import static com.google.common.base.Preconditions.*; | 38 | import static com.google.common.base.Preconditions.*; |
42 | 39 | ||
... | @@ -106,7 +103,6 @@ class Warden { | ... | @@ -106,7 +103,6 @@ class Warden { |
106 | return list != null ? ImmutableSet.copyOf(list) : ImmutableSet.of(); | 103 | return list != null ? ImmutableSet.copyOf(list) : ImmutableSet.of(); |
107 | } | 104 | } |
108 | 105 | ||
109 | - | ||
110 | /** | 106 | /** |
111 | * Returns reservation for the specified user. | 107 | * Returns reservation for the specified user. |
112 | * | 108 | * |
... | @@ -170,40 +166,76 @@ class Warden { | ... | @@ -170,40 +166,76 @@ class Warden { |
170 | reservation = new Reservation(reservation.cellName, userName, now, minutes); | 166 | reservation = new Reservation(reservation.cellName, userName, now, minutes); |
171 | } | 167 | } |
172 | 168 | ||
173 | - reserveCell(reservation.cellName, reservation); | 169 | + reserveCell(reservation); |
174 | - installUserKeys(reservation.cellName, userName, sshKey); | 170 | + createCell(reservation, sshKey); |
175 | log(userName, reservation.cellName, "borrowed for " + reservation.duration + " minutes"); | 171 | log(userName, reservation.cellName, "borrowed for " + reservation.duration + " minutes"); |
176 | return getCellDefinition(reservation.cellName); | 172 | return getCellDefinition(reservation.cellName); |
177 | } | 173 | } |
178 | 174 | ||
179 | /** | 175 | /** |
176 | + * Returns the specified cell for the specified user and their public access key. | ||
177 | + * | ||
178 | + * @param userName user name | ||
179 | + */ | ||
180 | + synchronized void returnCell(String userName) { | ||
181 | + checkNotNull(userName, USER_NOT_NULL); | ||
182 | + Reservation reservation = currentUserReservation(userName); | ||
183 | + checkState(reservation != null, "User %s has no cell reservations", userName); | ||
184 | + | ||
185 | + unreserveCell(reservation); | ||
186 | + destroyCell(reservation); | ||
187 | + log(userName, reservation.cellName, "returned"); | ||
188 | + } | ||
189 | + | ||
190 | + /** | ||
180 | * Reserves the specified cell for the user the source file and writes the | 191 | * Reserves the specified cell for the user the source file and writes the |
181 | * specified content to the target file. | 192 | * specified content to the target file. |
182 | * | 193 | * |
183 | - * @param cellName cell name | ||
184 | * @param reservation cell reservation record | 194 | * @param reservation cell reservation record |
185 | */ | 195 | */ |
186 | - private void reserveCell(String cellName, Reservation reservation) { | 196 | + private void reserveCell(Reservation reservation) { |
187 | - try (FileOutputStream stream = new FileOutputStream(new File(reserved, cellName))) { | 197 | + File cellFile = new File(reserved, reservation.cellName); |
198 | + try (FileOutputStream stream = new FileOutputStream(cellFile)) { | ||
188 | stream.write(reservation.encode().getBytes(UTF_8)); | 199 | stream.write(reservation.encode().getBytes(UTF_8)); |
189 | } catch (IOException e) { | 200 | } catch (IOException e) { |
190 | - throw new IllegalStateException("Unable to reserve cell " + cellName, e); | 201 | + throw new IllegalStateException("Unable to reserve cell " + reservation.cellName, e); |
191 | } | 202 | } |
192 | } | 203 | } |
193 | 204 | ||
205 | + private String getCellDefinition(String cellName) { | ||
206 | + return exec("bin/cell-def " + cellName); | ||
207 | + } | ||
208 | + | ||
194 | /** | 209 | /** |
195 | - * Returns the specified cell for the specified user and their public access key. | 210 | + * Cancels the specified reservation. |
196 | * | 211 | * |
197 | - * @param userName user name | 212 | + * @param reservation reservation record |
198 | */ | 213 | */ |
199 | - synchronized void returnCell(String userName) { | 214 | + private void unreserveCell(Reservation reservation) { |
200 | - checkNotNull(userName, USER_NOT_NULL); | ||
201 | - Reservation reservation = currentUserReservation(userName); | ||
202 | - checkState(reservation != null, "User %s has no cell reservations", userName); | ||
203 | checkState(new File(reserved, reservation.cellName).delete(), | 215 | checkState(new File(reserved, reservation.cellName).delete(), |
204 | "Unable to return cell %s", reservation.cellName); | 216 | "Unable to return cell %s", reservation.cellName); |
205 | - uninstallUserKeys(reservation.cellName); | 217 | + } |
206 | - log(userName, reservation.cellName, "returned"); | 218 | + |
219 | + /** | ||
220 | + * Creates the cell for the specified user SSH key. | ||
221 | + * | ||
222 | + * @param reservation cell reservation | ||
223 | + * @param sshKey ssh key | ||
224 | + */ | ||
225 | + private void createCell(Reservation reservation, String sshKey) { | ||
226 | + String cellInfo = getCellInfo(reservation.cellName); | ||
227 | + String cmd = String.format("bin/create-cell %s %s %s", | ||
228 | + reservation.cellName, cellInfo, sshKey); | ||
229 | + exec(cmd); | ||
230 | + } | ||
231 | + | ||
232 | + /** | ||
233 | + * Destroys the specified cell. | ||
234 | + * | ||
235 | + * @param reservation reservation record | ||
236 | + */ | ||
237 | + private void destroyCell(Reservation reservation) { | ||
238 | + exec("bin/destroy-cell " + reservation.cellName); | ||
207 | } | 239 | } |
208 | 240 | ||
209 | /** | 241 | /** |
... | @@ -212,7 +244,7 @@ class Warden { | ... | @@ -212,7 +244,7 @@ class Warden { |
212 | * @param cellName cell name | 244 | * @param cellName cell name |
213 | * @return cell definition | 245 | * @return cell definition |
214 | */ | 246 | */ |
215 | - String getCellDefinition(String cellName) { | 247 | + String getCellInfo(String cellName) { |
216 | File cellFile = new File(supported, cellName); | 248 | File cellFile = new File(supported, cellName); |
217 | try (InputStream stream = new FileInputStream(cellFile)) { | 249 | try (InputStream stream = new FileInputStream(cellFile)) { |
218 | return new String(ByteStreams.toByteArray(stream), UTF_8); | 250 | return new String(ByteStreams.toByteArray(stream), UTF_8); |
... | @@ -221,63 +253,15 @@ class Warden { | ... | @@ -221,63 +253,15 @@ class Warden { |
221 | } | 253 | } |
222 | } | 254 | } |
223 | 255 | ||
224 | - // Returns list of cell hosts, i.e. OC#, OCN | 256 | + // Executes the specified command. |
225 | - private List<String> cellHosts(String cellName) { | 257 | + private String exec(String command) { |
226 | - ImmutableList.Builder<String> builder = ImmutableList.builder(); | ||
227 | - Pattern pattern = Pattern.compile("export OC[0-9N]=(.*)"); | ||
228 | - for (String line : getCellDefinition(cellName).split("\n")) { | ||
229 | - Matcher matcher = pattern.matcher(line); | ||
230 | - if (matcher.matches()) { | ||
231 | - builder.add(matcher.group(1).replaceAll("[\"']", "")); | ||
232 | - } | ||
233 | - } | ||
234 | - return builder.build(); | ||
235 | - } | ||
236 | - | ||
237 | - // Installs the specified user's key on all hosts of the given cell. | ||
238 | - private void installUserKeys(String cellName, String userName, String sshKey) { | ||
239 | - File authKeysFile = authKeys(sshKey); | ||
240 | - for (String host : cellHosts(cellName)) { | ||
241 | - installAuthorizedKey(host, authKeysFile.getPath()); | ||
242 | - } | ||
243 | - checkState(authKeysFile.delete(), "Unable to install user keys"); | ||
244 | - } | ||
245 | - | ||
246 | - // Uninstalls the user keys on the specified cell | ||
247 | - private void uninstallUserKeys(String cellName) { | ||
248 | - for (String host : cellHosts(cellName)) { | ||
249 | - installAuthorizedKey(host, AUTHORIZED_KEYS); | ||
250 | - } | ||
251 | - } | ||
252 | - | ||
253 | - // Installs the authorized keys on the specified host. | ||
254 | - private void installAuthorizedKey(String host, String authorizedKeysFile) { | ||
255 | - String cmd = "scp " + authorizedKeysFile + " sdn@" + host + ":.ssh/authorized_keys"; | ||
256 | try { | 258 | try { |
257 | - Process process = Runtime.getRuntime().exec(cmd); | 259 | + Process process = Runtime.getRuntime().exec(command); |
260 | + String output = new String(ByteStreams.toByteArray(process.getInputStream()), UTF_8); | ||
258 | process.waitFor(TIMEOUT, TimeUnit.SECONDS); | 261 | process.waitFor(TIMEOUT, TimeUnit.SECONDS); |
262 | + return process.exitValue() == 0 ? output : null; | ||
259 | } catch (Exception e) { | 263 | } catch (Exception e) { |
260 | - throw new IllegalStateException("Unable to set authorized keys for host " + host); | 264 | + throw new IllegalStateException("Unable to execute " + command); |
261 | - } | ||
262 | - } | ||
263 | - | ||
264 | - // Returns the file containing authorized keys that incudes the specified key. | ||
265 | - private File authKeys(String sshKey) { | ||
266 | - File keysFile = new File(AUTHORIZED_KEYS); | ||
267 | - try { | ||
268 | - File tmp = File.createTempFile("warden-", ".auth"); | ||
269 | - tmp.deleteOnExit(); | ||
270 | - try (InputStream stream = new FileInputStream(keysFile); | ||
271 | - PrintWriter output = new PrintWriter(tmp)) { | ||
272 | - String baseKeys = new String(ByteStreams.toByteArray(stream), UTF_8); | ||
273 | - output.println(baseKeys); | ||
274 | - output.println(sshKey); | ||
275 | - return tmp; | ||
276 | - } catch (IOException e) { | ||
277 | - throw new IllegalStateException("Unable to generate authorized keys", e); | ||
278 | - } | ||
279 | - } catch (IOException e) { | ||
280 | - throw new IllegalStateException("Unable to generate authorized keys", e); | ||
281 | } | 265 | } |
282 | } | 266 | } |
283 | 267 | ... | ... |
-
Please register or login to post a comment