Thomas Vachuska
Committed by Gerrit Code Review

Modified warden to create borrowed cells on-demand and to scrap returned ones.

Change-Id: If32a0da18ff9d4c05645017e5cc7481bbd1ab0cd
...@@ -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\""
......
...@@ -4,7 +4,8 @@ ...@@ -4,7 +4,8 @@
4 base="$1" 4 base="$1"
5 ip="$2" 5 ip="$2"
6 name="$3" 6 name="$3"
7 -key="$4" 7 +shift 3
8 +key="$@"
8 9
9 sudo lxc-clone -o $base -n $name 10 sudo lxc-clone -o $base -n $name
10 11
......
...@@ -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"
......
...@@ -5,7 +5,7 @@ name=$1 ...@@ -5,7 +5,7 @@ name=$1
5 5
6 cd $(dirname $0) 6 cd $(dirname $0)
7 7
8 -./destroy-node $name-mn 8 +./destroy-node $name-n
9 9
10 for n in {1..3}; do 10 for n in {1..3}; do
11 ./destroy-node $name-$n 11 ./destroy-node $name-$n
......
...@@ -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
......