Thomas Vachuska

Removed warden; moved to separate repo.

Change-Id: I76ae777891ad3256f1bb30f11c17c0aebfc1ed5d
#!/bin/bash
# Creates a cell definition from the given name and LXC info
name="$1"
apps="${2:-drivers,openflow,proxyarp,mobility,pathpainter}"
echo "export ONOS_CELL=borrow"
echo "export ONOS_NIC=\"10.128.11.*\""
sudo lxc-ls -F "name,ipv4" --fancy | grep $name | \
sed "s/^$name-/OC/" | tr "[:lower:]" "[:upper:]" | \
sed -r 's/[ ]+/\=/;s/^/export /'
echo "export OCT=\"10.128.11.1\""
echo "export ONOS_USER=sdn"
echo "export ONOS_USE_SSH=true"
echo "export ONOS_APPS=${apps}"
echo "export ONOS_WEB_USER=onos"
echo "export ONOS_WEB_PASS=rocks"
#!/bin/bash
# Creates a new node from the base image.
base="$1"
ip="$2"
name="$3"
shift 3
key="$@"
sudo lxc-clone -o $base -n $name
sudo chmod 777 /var/lib/lxc
sudo chmod 777 /var/lib/lxc/$name
sudo chmod 666 /var/lib/lxc/$name/config
sudo cat >>/var/lib/lxc/$name/config <<EOF
lxc.network.ipv4 = ${ip}/16
lxc.network.ipv4.gateway = 10.128.0.1
EOF
sudo chmod 644 /var/lib/lxc/$name/config
sudo chmod 750 /var/lib/lxc/$name
sudo chmod 700 /var/lib/lxc
sudo lxc-start -d -n $name
sudo lxc-attach -n $name -- ping -c1 8.8.8.8
sudo lxc-attach -n $name -- bash -c "echo $key >> /home/sdn/.ssh/authorized_keys"
sudo lxc-attach -n $name -- bash -c "sed -i \"s/127.0.1.1.*/127.0.1.1 $name/\" /etc/hosts"
#!/bin/bash
# Creates a new cell.
name="$1"
ipx="$2"
spec="$3"
shift 3
key="$@"
cd $(dirname $0)
nodes=${spec%+*}
mininet=${spec#*+}
sudo lxc-attach -n bit-proxy -- bash -c "grep -qF \"$key\" /home/sdn/.ssh/authorized_keys || echo $key >> /home/sdn/.ssh/authorized_keys"
if [ $mininet -ge 1 ]; then
./clone-node base-mininet ${ipx/x/0} $name-n "$key"
fi
let n=1
while [ $n -le $nodes ]; do
./clone-node base-onos ${ipx/x/$n} $name-$n "$key"
let n=n+1
done
#!/bin/bash
# Destroys an LXC cell with the specified name.
name=$1
spec=$2
nodes=${spec%+*}
mininet=${spec#*+}
cd $(dirname $0)
if [ $mininet -ge 1 ]; then
./destroy-node $name-n
fi
let n=1
while [ $n -le $nodes ]; do
./destroy-node $name-$n
let n=n+1
done
#!/bin/bash
# Destroys an LXC node with the specified name.
name=$1
[ "$name" = "onos-base" ] && echo "Don't do that!" && exit 1
[ "$name" = "mininet-base" ] && echo "Don't do that!" && exit 1
sudo lxc-stop -n $name
sudo lxc-destroy -n $name
<?xml version="1.0" encoding="UTF-8"?>
<!--
~ Copyright 2015-present Open Networking Laboratory
~
~ Licensed under the Apache License, Version 2.0 (the "License");
~ you may not use this file except in compliance with the License.
~ You may obtain a copy of the License at
~
~ http://www.apache.org/licenses/LICENSE-2.0
~
~ Unless required by applicable law or agreed to in writing, software
~ distributed under the License is distributed on an "AS IS" BASIS,
~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
~ See the License for the specific language governing permissions and
~ limitations under the License.
-->
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.onosproject</groupId>
<artifactId>onlab-utils</artifactId>
<version>1.6.0-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>
<artifactId>onlab-warden</artifactId>
<packaging>jar</packaging>
<description>System Test Cell Warden</description>
<dependencies>
<dependency>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-server</artifactId>
<version>8.1.18.v20150929</version>
</dependency>
<dependency>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-servlet</artifactId>
<version>8.1.18.v20150929</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.onosproject</groupId>
<artifactId>onlab-misc</artifactId>
<version>${project.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.onosproject</groupId>
<artifactId>onlab-junit</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>2.4.3</version>
<configuration>
<transformers>
<transformer
implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
<mainClass>org.onlab.warden.Main</mainClass>
</transformer>
</transformers>
<filters>
<filter>
<artifact>*:*</artifact>
<excludes>
<exclude>META-INF/*.SF</exclude>
<exclude>META-INF/*.DSA</exclude>
<exclude>META-INF/*.RSA</exclude>
</excludes>
</filter>
</filters>
</configuration>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
/*
* Copyright 2016 Open Networking Laboratory
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.onlab.warden;
import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.servlet.ServletHandler;
import org.eclipse.jetty.util.log.Logger;
/**
* Main program for executing scenario test warden.
*/
public final class Main {
// Public construction forbidden
private Main(String[] args) {
}
/**
* Main entry point for the cell warden.
*
* @param args command-line arguments
*/
public static void main(String[] args) {
Main main = new Main(args);
main.run();
}
// Runs the warden processing
private void run() {
startWebServer();
}
// Initiates a web-server.
private static void startWebServer() {
WardenServlet.warden = new Warden();
org.eclipse.jetty.util.log.Log.setLog(new NullLogger());
Server server = new Server(4321);
ServletHandler handler = new ServletHandler();
server.setHandler(handler);
handler.addServletWithMapping(WardenServlet.class, "/*");
try {
server.start();
} catch (Exception e) {
print("Warden already active...");
}
}
private static void print(String s) {
System.out.println(s);
}
// Logger to quiet Jetty down
private static class NullLogger implements Logger {
@Override
public String getName() {
return "quiet";
}
@Override
public void warn(String msg, Object... args) {
}
@Override
public void warn(Throwable thrown) {
}
@Override
public void warn(String msg, Throwable thrown) {
}
@Override
public void info(String msg, Object... args) {
}
@Override
public void info(Throwable thrown) {
}
@Override
public void info(String msg, Throwable thrown) {
}
@Override
public boolean isDebugEnabled() {
return false;
}
@Override
public void setDebugEnabled(boolean enabled) {
}
@Override
public void debug(String msg, Object... args) {
}
@Override
public void debug(Throwable thrown) {
}
@Override
public void debug(String msg, Throwable thrown) {
}
@Override
public Logger getLogger(String name) {
return this;
}
@Override
public void ignore(Throwable ignored) {
}
}
}
/*
* Copyright 2016 Open Networking Laboratory
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.onlab.warden;
import static com.google.common.base.Preconditions.checkState;
/**
* Cell reservation record.
*/
final class Reservation {
final String cellName;
final String userName;
final long time;
final int duration;
final String cellSpec;
// Creates a new reservation record
Reservation(String cellName, String userName, long time, int duration, String cellSpec) {
this.cellName = cellName;
this.userName = userName;
this.time = time;
this.duration = duration;
this.cellSpec = cellSpec;
}
/**
* Decodes reservation record from the specified line.
*
* @param line string line
*/
Reservation(String line) {
String[] fields = line.trim().split("\t");
checkState(fields.length == 5, "Incorrect reservation encoding");
this.cellName = fields[0];
this.userName = fields[1];
this.time = Long.parseLong(fields[2]);
this.duration = Integer.parseInt(fields[3]);
this.cellSpec = fields[4];
}
/**
* Encodes reservation record into a string line.
*
* @return encoded string
*/
String encode() {
return String.format("%s\t%s\t%s\t%s\t%s\n", cellName, userName, time, duration, cellSpec);
}
}
This diff is collapsed. Click to expand it.
/*
* Copyright 2016 Open Networking Laboratory
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.onlab.warden;
import com.google.common.io.ByteStreams;
import org.eclipse.jetty.server.Response;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import static com.google.common.base.Strings.isNullOrEmpty;
/**
* Web socket servlet capable of creating web sockets for the STC monitor.
*/
public class WardenServlet extends HttpServlet {
static Warden warden;
private SimpleDateFormat fmt = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
resp.setContentType("text/plain; charset=UTF-8");
try (PrintWriter out = resp.getWriter()) {
if (req.getPathInfo().endsWith("data")) {
String userName = req.getParameter("user");
if (userName != null) {
printUserInfo(out, userName);
} else {
printAvailability(out);
}
} else {
printAvailabilityText(out);
}
} catch (Exception e) {
resp.setStatus(Response.SC_INTERNAL_SERVER_ERROR);
e.printStackTrace();
}
}
private void printUserInfo(PrintWriter out, String userName) {
Reservation reservation = warden.currentUserReservation(userName);
out.println(getCellStatus(null, reservation));
}
private void printAvailability(PrintWriter out) {
List<String> list = new ArrayList<>(warden.getCells());
list.sort(String::compareTo);
for (String cellName : list) {
Reservation reservation = warden.currentCellReservation(cellName);
out.println(getCellStatus(cellName, reservation));
}
}
private String getCellStatus(String cellName, Reservation reservation) {
if (reservation != null) {
long expiration = reservation.time + reservation.duration * 60_000;
long remaining = (expiration - System.currentTimeMillis()) / 60_000;
return String.format("%s,%s,%s,%s", reservation.cellName,
reservation.cellSpec, reservation.userName, remaining);
} else if (cellName != null) {
return String.format("%s", cellName);
}
return null;
}
private void printAvailabilityText(PrintWriter out) {
List<String> list = new ArrayList<>(warden.getCells());
list.sort(String::compareTo);
for (String cellName : list) {
Reservation reservation = warden.currentCellReservation(cellName);
if (reservation != null) {
long expiration = reservation.time + reservation.duration * 60_000;
long remaining = (expiration - System.currentTimeMillis()) / 60_000;
out.println(String.format("%-14s\t%-10s\t%s\t%s\t%s mins (%s remaining)",
cellName + "-" + reservation.cellSpec,
reservation.userName,
fmt.format(new Date(reservation.time)),
fmt.format(new Date(expiration)),
reservation.duration, remaining));
} else {
out.println(String.format("%-10s\t%-10s", cellName, "available"));
}
}
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
try (PrintWriter out = resp.getWriter()) {
String sshKey = new String(ByteStreams.toByteArray(req.getInputStream()), "UTF-8");
String userName = req.getParameter("user");
String sd = req.getParameter("duration");
String spec = req.getParameter("spec");
int duration = isNullOrEmpty(sd) ? 0 : Integer.parseInt(sd);
String cellDefinition = warden.borrowCell(userName, sshKey, duration, spec);
out.println(cellDefinition);
} catch (Exception e) {
resp.setStatus(Response.SC_INTERNAL_SERVER_ERROR);
e.printStackTrace();
}
}
@Override
protected void doDelete(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
try (PrintWriter out = resp.getWriter()) {
String userName = req.getParameter("user");
warden.returnCell(userName);
} catch (Exception e) {
resp.setStatus(Response.SC_INTERNAL_SERVER_ERROR);
e.printStackTrace();
}
}
}
/*
* Copyright 2016 Open Networking Laboratory
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/**
* Cell warden to coordinate borrowing and returning test cells.
*/
package org.onlab.warden;
\ No newline at end of file
/*
* Copyright 2016 Open Networking Laboratory
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.onlab.warden;
import com.google.common.io.Files;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.onlab.util.Tools;
import java.io.File;
import java.io.IOException;
import java.util.Objects;
import static org.junit.Assert.*;
/**
* Suite of tests for the cell warden.
*/
public class WardenTest {
private Warden warden;
private File cells;
private File supportedCells;
@Before
public void setUp() throws IOException {
// Setup warden to be tested
Warden.root = Files.createTempDir();
Warden.cmdPrefix = "echo ";
cells = new File(Warden.root, "cells");
supportedCells = new File(cells, "supported");
warden = new Warden();
// Setup test cell information
createCell("alpha", "foo");
createCell("bravo", "foo");
createCell("charlie", "foo");
createCell("delta", "bar");
createCell("echo", "bar");
createCell("foxtrot", "bar");
new File("warden.log").deleteOnExit();
}
private void createCell(String cellName, String hostName) throws IOException {
File cellFile = new File(supportedCells, cellName);
Files.createParentDirs(cellFile);
Files.write((hostName + " " + cellName).getBytes(), cellFile);
}
@After
public void tearDown() throws IOException {
Tools.removeDirectory(Warden.root);
}
@Test
public void basics() {
assertEquals("incorrect number of cells", 6, warden.getCells().size());
validateSizes(6, 0);
String cellDefinition = warden.borrowCell("dude", "the-key", 0, null);
assertTrue("incorrect definition", cellDefinition.contains("cell-def"));
validateSizes(5, 1);
Reservation dudeCell = warden.currentUserReservation("dude");
validateCellState(dudeCell);
warden.borrowCell("dolt", "a-key", 0, "4+1");
Reservation doltCell = warden.currentUserReservation("dolt");
validateCellState(doltCell);
validateSizes(4, 2);
assertFalse("cells should not be on the same host",
Objects.equals(warden.getCellHost(dudeCell.cellName),
warden.getCellHost(doltCell.cellName)));
warden.returnCell("dude");
validateSizes(5, 1);
warden.borrowCell("dolt", "a-key", 30, null);
validateSizes(5, 1);
warden.returnCell("dolt");
validateSizes(6, 0);
}
private void validateSizes(int available, int reserved) {
assertEquals("incorrect number of available cells", available,
warden.getAvailableCells().size());
assertEquals("incorrect number of reserved cells", reserved,
warden.getReservedCells().size());
}
private void validateCellState(Reservation reservation) {
assertFalse("cell should not be available",
warden.getAvailableCells().contains(reservation.cellName));
assertTrue("cell should be reserved",
warden.getReservedCells().contains(reservation.cellName));
}
}
\ No newline at end of file
#! /bin/bash
# -----------------------------------------------------------------------------
# init.d script to run ON.Lab test cell warden
## -----------------------------------------------------------------------------
### BEGIN INIT INFO
# Provides: warden
# Required-Start: $network $remote_fs $syslog
# Required-Stop: $network $remote_fs $syslog
# Default-Start: 2 3 4 5
# Default-Stop: 0 1 6
# Short-Description: ON.Lab Test Cell Warden
# Description: Warden is a broker for sharing test cell infrastructure among ON.Lab developers.
### END INIT INFO
WARDEN_USER="sdn"
WARDEN_HOME="/home/$WARDEN_USER/warden"
WARDEN_VERSION="1.6.0-SNAPSHOT"
DEBUG="-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=n,address=5005"
cd $WARDEN_HOME
start () {
# Start warden if it's not already running
if ! status >/dev/null; then
echo "Starting Warden"
startwarden
else
echo "Warden is already running"
fi
}
startwarden () {
start-stop-daemon --signal INT --start --chuid $WARDEN_USER \
--pidfile $WARDEN_HOME/warden.pid --make-pidfile \
--background --chdir $WARDEN_HOME \
--exec /usr/bin/java -- -jar onlab-warden-$WARDEN_VERSION.jar \
&>$WARDEN_HOME/std.log
}
stop () {
if status >/dev/null; then
echo "Stopping Warden"
start-stop-daemon --signal INT --stop --chuid $WARDEN_USER \
--pidfile $WARDEN_HOME/warden.pid
rm warden.pid
else
echo "Warden is not running"
fi
}
restart () {
stop
start
}
status () {
start-stop-daemon --signal INT --status --chuid $WARDEN_USER \
--pidfile $WARDEN_HOME/warden.pid
}
case $1 in
start)
start
;;
stop | force-stop)
stop
;;
restart)
shift
restart "$@"
;;
status)
status && echo "Warden is running" || echo "Warden is stopped"
exit $?
;;
*)
echo "Usage: $0 {start|stop|restart|status}" >&2
exit 1
;;
esac
exit 0