Modified warden to create borrowed cells on-demand and to scrap returned ones.
Change-Id: If32a0da18ff9d4c05645017e5cc7481bbd1ab0cd
diff --git a/tools/dev/bash_profile b/tools/dev/bash_profile
index 1825264..3034375 100644
--- a/tools/dev/bash_profile
+++ b/tools/dev/bash_profile
@@ -113,17 +113,16 @@
case "$cell" in
"borrow")
aux="/tmp/cell-$$"
- curl -sS -X POST "http://$CELL_WARDEN:4321/?user=$(id -un)&duration=${2:-0}" \
+ curl -sS -X POST "http://$CELL_WARDEN:4321/?duration=${2:-0}&user=${3:-$(id -un)}" \
-d "$(cat ~/.ssh/id_rsa.pub)" > $aux
. $aux
rm -f $aux
export ONOS_INSTANCES=$(env | grep 'OC[0-9]*=' | sort | cut -d= -f2)
setPrimaryInstance 1 >/dev/null
- cell
onos-verify-cell
;;
"return")
- curl -sS -X DELETE "http://$CELL_WARDEN:4321/?user=$(id -un)"
+ curl -sS -X DELETE "http://$CELL_WARDEN:4321/?user=${2:-$(id -un)}"
unset ONOS_CELL ONOS_NIC ONOS_IP ONOS_APPS ONOS_BOOT_FEATURES
unset OCI OCN OCT ONOS_INSTANCES ONOS_FEATURES
unset $(env | sed -n 's:\(^OC[0-9]\{1,\}\)=.*:\1 :g p')
diff --git a/tools/test/bin/onos-verify-cell b/tools/test/bin/onos-verify-cell
index 4b3a0ee..ec34cab 100755
--- a/tools/test/bin/onos-verify-cell
+++ b/tools/test/bin/onos-verify-cell
@@ -6,6 +6,6 @@
[ ! -d "$ONOS_ROOT" ] && echo "ONOS_ROOT is not defined" >&2 && exit 1
. $ONOS_ROOT/tools/build/envDefaults
-for node in $(env | sort | egrep "OC[0-9N]+" | cut -d= -f2); do
- printf "%s: " $node; ssh -n -o PasswordAuthentication=no $ONOS_USER@$node date
+for node in $OCN $(env | sort | egrep "OC[0-9]+" | cut -d= -f2); do
+ printf "%s: " $node; ssh -n -o StrictHostKeyChecking=no -o PasswordAuthentication=no $ONOS_USER@$node hostname
done
diff --git a/utils/warden/bin/cell-def b/utils/warden/bin/cell-def
index 12fd284..c7c7116 100755
--- a/utils/warden/bin/cell-def
+++ b/utils/warden/bin/cell-def
@@ -8,7 +8,7 @@
echo "export ONOS_NIC=\"10.128.11.*\""
sudo lxc-ls -F "name,ipv4" --fancy | grep $name | \
- sed "s/^$name/OC/" | tr "[:lower:]" "[:upper:]" | \
+ sed "s/^$name-/OC/" | tr "[:lower:]" "[:upper:]" | \
sed -r 's/[ ]+/\=/;s/^/export /'
echo "export OCT=\"\$OC1\""
diff --git a/utils/warden/bin/clone-node b/utils/warden/bin/clone-node
index 8e60d40..2a3465a 100755
--- a/utils/warden/bin/clone-node
+++ b/utils/warden/bin/clone-node
@@ -4,7 +4,8 @@
base="$1"
ip="$2"
name="$3"
-key="$4"
+shift 3
+key="$@"
sudo lxc-clone -o $base -n $name
diff --git a/utils/warden/bin/create-cell b/utils/warden/bin/create-cell
index f24a386..59ccb96 100755
--- a/utils/warden/bin/create-cell
+++ b/utils/warden/bin/create-cell
@@ -3,11 +3,12 @@
name="$1"
ipx="$2"
-key="$3"
+shift 2
+key="$@"
cd $(dirname $0)
-./clone-node base-mininet ${ipx/x/0} $name-mn "$key"
+./clone-node base-mininet ${ipx/x/0} $name-n "$key"
for n in {1..3}; do
./clone-node base-onos ${ipx/x/$n} $name-$n "$key"
diff --git a/utils/warden/bin/destroy-cell b/utils/warden/bin/destroy-cell
index c39d5fe..0af757e 100755
--- a/utils/warden/bin/destroy-cell
+++ b/utils/warden/bin/destroy-cell
@@ -5,7 +5,7 @@
cd $(dirname $0)
-./destroy-node $name-mn
+./destroy-node $name-n
for n in {1..3}; do
./destroy-node $name-$n
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 6f6ada5..f6c091a 100644
--- a/utils/warden/src/main/java/org/onlab/warden/Warden.java
+++ b/utils/warden/src/main/java/org/onlab/warden/Warden.java
@@ -29,14 +29,11 @@
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashSet;
-import java.util.List;
import java.util.Random;
import java.util.Set;
import java.util.Timer;
import java.util.TimerTask;
import java.util.concurrent.TimeUnit;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
import static com.google.common.base.Preconditions.*;
@@ -106,7 +103,6 @@
return list != null ? ImmutableSet.copyOf(list) : ImmutableSet.of();
}
-
/**
* Returns reservation for the specified user.
*
@@ -170,28 +166,13 @@
reservation = new Reservation(reservation.cellName, userName, now, minutes);
}
- reserveCell(reservation.cellName, reservation);
- installUserKeys(reservation.cellName, userName, sshKey);
+ reserveCell(reservation);
+ createCell(reservation, sshKey);
log(userName, reservation.cellName, "borrowed for " + reservation.duration + " minutes");
return getCellDefinition(reservation.cellName);
}
/**
- * Reserves the specified cell for the user the source file and writes the
- * specified content to the target file.
- *
- * @param cellName cell name
- * @param reservation cell reservation record
- */
- private void reserveCell(String cellName, Reservation reservation) {
- try (FileOutputStream stream = new FileOutputStream(new File(reserved, cellName))) {
- stream.write(reservation.encode().getBytes(UTF_8));
- } catch (IOException e) {
- throw new IllegalStateException("Unable to reserve cell " + cellName, e);
- }
- }
-
- /**
* Returns the specified cell for the specified user and their public access key.
*
* @param userName user name
@@ -200,10 +181,61 @@
checkNotNull(userName, USER_NOT_NULL);
Reservation reservation = currentUserReservation(userName);
checkState(reservation != null, "User %s has no cell reservations", userName);
+
+ unreserveCell(reservation);
+ destroyCell(reservation);
+ log(userName, reservation.cellName, "returned");
+ }
+
+ /**
+ * Reserves the specified cell for the user the source file and writes the
+ * specified content to the target file.
+ *
+ * @param reservation cell reservation record
+ */
+ private void reserveCell(Reservation reservation) {
+ File cellFile = new File(reserved, reservation.cellName);
+ try (FileOutputStream stream = new FileOutputStream(cellFile)) {
+ stream.write(reservation.encode().getBytes(UTF_8));
+ } catch (IOException e) {
+ throw new IllegalStateException("Unable to reserve cell " + reservation.cellName, e);
+ }
+ }
+
+ private String getCellDefinition(String cellName) {
+ return exec("bin/cell-def " + cellName);
+ }
+
+ /**
+ * Cancels the specified reservation.
+ *
+ * @param reservation reservation record
+ */
+ private void unreserveCell(Reservation reservation) {
checkState(new File(reserved, reservation.cellName).delete(),
"Unable to return cell %s", reservation.cellName);
- uninstallUserKeys(reservation.cellName);
- log(userName, reservation.cellName, "returned");
+ }
+
+ /**
+ * Creates the cell for the specified user SSH key.
+ *
+ * @param reservation cell reservation
+ * @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);
+ exec(cmd);
+ }
+
+ /**
+ * Destroys the specified cell.
+ *
+ * @param reservation reservation record
+ */
+ private void destroyCell(Reservation reservation) {
+ exec("bin/destroy-cell " + reservation.cellName);
}
/**
@@ -212,7 +244,7 @@
* @param cellName cell name
* @return cell definition
*/
- String getCellDefinition(String cellName) {
+ String getCellInfo(String cellName) {
File cellFile = new File(supported, cellName);
try (InputStream stream = new FileInputStream(cellFile)) {
return new String(ByteStreams.toByteArray(stream), UTF_8);
@@ -221,63 +253,15 @@
}
}
- // Returns list of cell hosts, i.e. OC#, OCN
- private List<String> cellHosts(String cellName) {
- ImmutableList.Builder<String> builder = ImmutableList.builder();
- Pattern pattern = Pattern.compile("export OC[0-9N]=(.*)");
- for (String line : getCellDefinition(cellName).split("\n")) {
- Matcher matcher = pattern.matcher(line);
- if (matcher.matches()) {
- builder.add(matcher.group(1).replaceAll("[\"']", ""));
- }
- }
- return builder.build();
- }
-
- // Installs the specified user's key on all hosts of the given cell.
- private void installUserKeys(String cellName, String userName, String sshKey) {
- File authKeysFile = authKeys(sshKey);
- for (String host : cellHosts(cellName)) {
- installAuthorizedKey(host, authKeysFile.getPath());
- }
- checkState(authKeysFile.delete(), "Unable to install user keys");
- }
-
- // Uninstalls the user keys on the specified cell
- private void uninstallUserKeys(String cellName) {
- for (String host : cellHosts(cellName)) {
- installAuthorizedKey(host, AUTHORIZED_KEYS);
- }
- }
-
- // Installs the authorized keys on the specified host.
- private void installAuthorizedKey(String host, String authorizedKeysFile) {
- String cmd = "scp " + authorizedKeysFile + " sdn@" + host + ":.ssh/authorized_keys";
+ // Executes the specified command.
+ private String exec(String command) {
try {
- Process process = Runtime.getRuntime().exec(cmd);
+ Process process = Runtime.getRuntime().exec(command);
+ String output = new String(ByteStreams.toByteArray(process.getInputStream()), UTF_8);
process.waitFor(TIMEOUT, TimeUnit.SECONDS);
+ return process.exitValue() == 0 ? output : null;
} catch (Exception e) {
- throw new IllegalStateException("Unable to set authorized keys for host " + host);
- }
- }
-
- // Returns the file containing authorized keys that incudes the specified key.
- private File authKeys(String sshKey) {
- File keysFile = new File(AUTHORIZED_KEYS);
- try {
- File tmp = File.createTempFile("warden-", ".auth");
- tmp.deleteOnExit();
- try (InputStream stream = new FileInputStream(keysFile);
- PrintWriter output = new PrintWriter(tmp)) {
- String baseKeys = new String(ByteStreams.toByteArray(stream), UTF_8);
- output.println(baseKeys);
- output.println(sshKey);
- return tmp;
- } catch (IOException e) {
- throw new IllegalStateException("Unable to generate authorized keys", e);
- }
- } catch (IOException e) {
- throw new IllegalStateException("Unable to generate authorized keys", e);
+ throw new IllegalStateException("Unable to execute " + command);
}
}