Test: XOS onos integration rewrite.
Also use the existing dockerfile/makefile from xos project to build the xos related containers.

Change-Id: I8f26d0f4fe12da0698ca895186fdeb0ef0e3860a
diff --git a/src/test/setup/cord-test.py b/src/test/setup/cord-test.py
index acb1fd3..1ead698 100755
--- a/src/test/setup/cord-test.py
+++ b/src/test/setup/cord-test.py
@@ -844,57 +844,31 @@
     return 0
 
 def xosContainers(args):
-    update_map = {  'xos-base' : False, 'xos-synchronizer-openstack' : False, 'openvpn' : False, 'postgresql' :False,
-                    'xos' : False, 'syndicate-ms': False, 'xos-synchronizer-vtr' : False, 'xos-synchronizer-vsg' : False,
-                    'xos-synchronizer-onos' : False, 'xos-synchronizer-fabric' : False, 'xos-synchronizer-vtn' : False,
-                    'xos-synchronizer-onboarding' : False, }
+    update_map = {  'xos-server' : False, 'xos-synchronizer-openstack' : False, 'openvpn' : False, 'postgresql' :False,
+                    'syndicate-ms': False, 'xos-synchronizer-onboarding' : False }
 
-    if args.xosAllContainers == True or args.xosBase == True:
-        #Start xos base container. Builds container if required
-        xosBase = Xos_base(prefix = Container.IMAGE_PREFIX, update = update_map['xos-base'])
+    if args.xosAllContainers == True or args.xosServer == True:
+        xosServer = XosServer(prefix = Container.IMAGE_PREFIX, update = update_map['xos-server'])
 
-    if args.xosAllContainers == True or args.xosSynOpenstack == True:
+    if args.xosAllContainers == True or args.xosSyncOpenstack == True:
         #Start xos base container. Builds container if required
-        xosSynOpenstack = Xos_sync_openstack(prefix = Container.IMAGE_PREFIX, update = update_map['xos-synchronizer-openstack'])
+        xosSyncOpenstack = XosSynchronizerOpenstack(prefix = Container.IMAGE_PREFIX,
+                                                    update = update_map['xos-synchronizer-openstack'])
+
     if args.xosAllContainers == True or args.xosOpenvpn == True:
-        #Start xos base container. Builds container if required
-        xosOpenvpn = Xos_openvpn(prefix = Container.IMAGE_PREFIX, update = update_map['openvpn'])
+        xosOpenvpn = XosSynchronizerOpenvpn(prefix = Container.IMAGE_PREFIX, update = update_map['openvpn'])
 
     if args.xosAllContainers == True or args.xosPostgresql == True:
-        #Start xos postgresql container. Builds container if required
-        xosPostgresql = Xos_postgresql(prefix = Container.IMAGE_PREFIX, update = update_map['postgresql'])
-
-    if args.xosAllContainers == True or args.xosSynchronizer == True:
-        #Start xos synchronizer container. Builds container if required
-        xosSynchronizer = Xos_synchronizer(prefix = Container.IMAGE_PREFIX, update = update_map['xos'])
+        xosPostgresql = XosPostgresql(prefix = Container.IMAGE_PREFIX, update = update_map['postgresql'])
 
     if args.xosAllContainers == True or args.xosSyndicateMs == True:
         #Start xos syndicateMs container. Builds container if required
-        xosSyndicateMs = Xos_syndicate_ss(prefix = Container.IMAGE_PREFIX, update = update_map['syndicate-ms'])
+        xosSyndicateMs = XosSyndicateMs(prefix = Container.IMAGE_PREFIX, update = update_map['syndicate-ms'])
 
-    if args.xosAllContainers == True or args.xosSynVtr == True:
-        #Start xos synchronizer vtr container. Builds container if required
-        xosSynVtr = Xos_syn_vtr(prefix = Container.IMAGE_PREFIX, update = update_map['xos-synchronizer-vtr'])
-
-    if args.xosAllContainers == True or args.xosSynVsg == True:
-        #Start xos synchronizer vsg container. Builds container if required
-        xosSynVsg = Xos_syn_vsg(prefix = Container.IMAGE_PREFIX, update = update_map['xos-synchronizer-vsg'])
-
-    if args.xosAllContainers == True or args.xosSynOnos == True:
-        #Start xos synchronizer Onos container. Builds container if required
-        xosSynOnos = Xos_syn_onos(prefix = Container.IMAGE_PREFIX, update = update_map['xos-synchronizer-onos'])
-
-    if args.xosAllContainers == True or args.xosSynFabric == True:
-        #Start xos synchronizer fabric container. Builds container if required
-        xosSynFabric = Xos_syn_fabric(prefix = Container.IMAGE_PREFIX, update = update_map['xos-synchronizer-fabric'])
-
-    if args.xosAllContainers == True or args.xosSynVtn == True:
-        #Start xos synchronizer vtn container. Builds container if required
-        xosSynVtn = Xos_syn_vtn(prefix = Container.IMAGE_PREFIX, update = update_map['xos-synchronizer-vtn'])
-
-    if args.xosAllContainers == True or args.xosSynOnboarding == True:
+    if args.xosAllContainers == True or args.xosSyncOnboarding == True:
         #Start xos synchronizer Onboarding container. Builds container if required
-        xosSynOnboarding = Xos_syn_onboarding(prefix = Container.IMAGE_PREFIX, update = update_map['xos-synchronizer-onboarding'])
+        xosSyncOnboarding = XosSynchronizerOnboarding(prefix = Container.IMAGE_PREFIX,
+                                                      update = update_map['xos-synchronizer-onboarding'])
 
     print('Done building xos containers')
     return 0
@@ -957,17 +931,12 @@
 
     parser_xos = subparser.add_parser('xos', help='Building xos into cord tester environment')
     parser_xos.add_argument('-x', '--xosAllContainers', action='store_true',help='Provision all containers of XOS for CORD')
-    parser_xos.add_argument('-xb', '--xosBase',action='store_true',help='Provision xos base container')
+    parser_xos.add_argument('-xserver', '--xosServer',action='store_true',help='Provision xos server container')
     parser_xos.add_argument('-xsos', '--xosSyncOpenstack',action='store_true',help='Provision xos synchronizer openstack container')
     parser_xos.add_argument('-xo', '--xosOpenvpn',action='store_true',help='Provision xos openvpn container')
     parser_xos.add_argument('-xp', '--xosPostgresql',action='store_true',help='Provision xos postgresql')
     parser_xos.add_argument('-xs', '--xosSynchronizer',action='store_true',help='Provision xos synchronizer')
     parser_xos.add_argument('-xsm', '--xosSyndicateMs',action='store_true',help='Provision xos syndicate-ms')
-    parser_xos.add_argument('-xsvtr', '--xosSyncVtr',action='store_true',help='Provision xos synchronizer vtr container')
-    parser_xos.add_argument('-xsvsg', '--xosSyncVsg',action='store_true',help='Provision xos synchronizer vsg container')
-    parser_xos.add_argument('-xsonos', '--xosSyncOnos',action='store_true',help='Provision xos synchronizer onos container')
-    parser_xos.add_argument('-xsfabric', '--xosSyncFabric',action='store_true',help='Provision xos synchronizer fabric container')
-    parser_xos.add_argument('-xsvtn', '--xosSyncVtn',action='store_true',help='Provision xos synchronizer vtn container')
     parser_xos.add_argument('-xsonb', '--xosSyncOnboarding',action='store_true',help='Provision xos synchronizer onboarding container')
     parser_xos.set_defaults(func=xosContainers)
 
diff --git a/src/test/setup/onboarding_synchronizer/Dockerfile b/src/test/setup/onboarding_synchronizer/Dockerfile
new file mode 100644
index 0000000..e17cfd0
--- /dev/null
+++ b/src/test/setup/onboarding_synchronizer/Dockerfile
@@ -0,0 +1,46 @@
+FROM xosproject/xos-synchronizer-openstack
+
+# Install docker-in-docker (dind). See https://hub.docker.com/_/docker/. The docker git repo
+# currently only has 1.10 and 1.11, but it's possible to get the dockerfiles for earlier
+# versions by using:
+#        docker pull centurylink/dockerfile-from-image
+#        alias dfimage="docker run -v /var/run/docker.sock:/var/run/docker.sock --rm centurylink/dockerfile-from-image"
+#        dgimage <name of image>
+
+# This container must be started in privileged mode.
+
+# Install docker
+ENV DOCKER_URL https://get.docker.com/builds/Linux/x86_64/docker-1.10.3
+ENV DOCKER_SHA256 d0df512afa109006a450f41873634951e19ddabf8c7bd419caeb5a526032d86d
+
+RUN curl -fLsS $DOCKER_URL -o docker && \
+    echo "${DOCKER_SHA256}  docker" | sha256sum -c - && \
+    mv docker /usr/local/bin/docker && \
+    chmod +x /usr/local/bin/docker
+
+# XXX uncomment the following 6 lines to run docker-in-docker
+#     comment them out if using the docker socket in a volume instead
+#ENV DIND_COMMIT=3b5fac462d21ca164b3778647420016315289034
+#RUN wget "https://raw.githubusercontent.com/docker/docker/${DIND_COMMIT}/hack/dind" -O /usr/local/bin/dind && chmod +x /sr/local/bin/dind
+#COPY start-dockerd.sh /usr/local/bin/
+#VOLUME /var/lib/docker
+#EXPOSE 2375
+#ENTRYPOINT ["start-dockerd.sh"]
+
+# Instead of using docker-in-docker, we can just attach ourselves
+# to the docker socket via a volume in the docker-compose:
+#     - /var/run/docker.sock:/var/run/docker.sock
+# This is more convenient, allowing us to build directly into our
+# parent's docker build system, making the images available for
+# instantiation on the parent.
+
+# Install docker-compose
+ENV DOCKER_COMPOSE_URL https://github.com/docker/compose/releases/download/1.5.2/docker-compose-Linux-x86_64
+ENV DOCKER_COMPOSE_SHA256 b6b975badc5389647ef1c16fe8a33bdc5935c61f6afd5a15a28ff765427d01e3
+
+RUN curl -fLsS $DOCKER_COMPOSE_URL -o docker-compose && \
+    echo "${DOCKER_COMPOSE_SHA256}  docker-compose" | sha256sum -c - && \
+    mv docker-compose /usr/local/bin/docker-compose && \
+    chmod +x /usr/local/bin/docker-compose
+
+CMD /usr/bin/supervisord -c /etc/supervisor/conf.d/synchronizer.conf
diff --git a/src/test/setup/onboarding_synchronizer/Makefile b/src/test/setup/onboarding_synchronizer/Makefile
new file mode 100644
index 0000000..c6d2a6b
--- /dev/null
+++ b/src/test/setup/onboarding_synchronizer/Makefile
@@ -0,0 +1,23 @@
+IMAGE_NAME:=xosproject/xos-synchronizer-onboarding
+CONTAINER_NAME:=xos-synchronizer
+NO_DOCKER_CACHE?=false
+
+BUILD_ARGS =
+ifdef http_proxy
+BUILD_ARGS += --build-arg http_proxy=${http_proxy}
+endif
+ifdef https_proxy
+BUILD_ARGS += --build-arg https_proxy=${https_proxy}
+endif
+
+.PHONY: build
+build: ; sudo docker build --no-cache=${NO_DOCKER_CACHE} --rm -t ${IMAGE_NAME} ${BUILD_ARGS} .
+
+.PHONY: run
+run: ; sudo docker run -d --name ${CONTAINER_NAME} -v /usr/local/share/ca-certificates:/usr/local/share/ca-certificates:ro ${IMAGE_NAME}
+
+.PHONY: stop
+stop: ; sudo docker stop ${CONTAINER_NAME}
+
+.PHONY: rm
+rm: ; sudo docker rm ${CONTAINER_NAME}
diff --git a/src/test/setup/onboarding_synchronizer/start-dockerd.sh b/src/test/setup/onboarding_synchronizer/start-dockerd.sh
new file mode 100755
index 0000000..bb97341
--- /dev/null
+++ b/src/test/setup/onboarding_synchronizer/start-dockerd.sh
@@ -0,0 +1,3 @@
+#! /bin/bash
+
+docker daemon --host=unix:///var/run/docker.sock --host=tcp://0.0.0.0:2375 --storage-driver=aufs
diff --git a/src/test/setup/openvpn/Dockerfile b/src/test/setup/openvpn/Dockerfile
new file mode 100644
index 0000000..8ae8484
--- /dev/null
+++ b/src/test/setup/openvpn/Dockerfile
@@ -0,0 +1,12 @@
+FROM       xosproject/xos-synchronizer-openstack
+
+RUN DEBIAN_FRONTEND=noninteractive apt-get update && apt-get install -y \
+    openvpn
+
+# for OpenVPN
+RUN mkdir -p /opt/openvpn
+RUN chmod 777 /opt/openvpn
+RUN git clone https://github.com/OpenVPN/easy-rsa.git /opt/openvpn
+RUN git -C /opt/openvpn pull origin master
+RUN echo 'set_var EASYRSA	"/opt/openvpn/easyrsa3"' | tee /opt/openvpn/vars
+RUN echo 'set_var EASYRSA_BATCH	"true"' | tee -a /opt/openvpn/vars
diff --git a/src/test/setup/openvpn/Makefile b/src/test/setup/openvpn/Makefile
new file mode 100644
index 0000000..bdfb126
--- /dev/null
+++ b/src/test/setup/openvpn/Makefile
@@ -0,0 +1,18 @@
+IMAGE_NAME:=xosproject/xos-openvpn
+CONTAINER_NAME:=xos-synchronizer
+NO_DOCKER_CACHE?=true
+
+.PHONY: build
+build: ; sudo docker build --no-cache=${NO_DOCKER_CACHE} --rm -t ${IMAGE_NAME} .
+
+.PHONY: run
+run: ; sudo docker run -d --name ${CONTAINER_NAME} -v /usr/local/share/ca-certificates:/usr/local/share/ca-certificates:ro ${IMAGE_NAME}
+
+.PHONY: stop
+stop: ; sudo docker stop ${CONTAINER_NAME}
+
+.PHONY: rm
+rm: ; sudo docker rm ${CONTAINER_NAME}
+
+.PHONY: rmi
+rmi: ; docker rmi ${IMAGE_NAME}
diff --git a/src/test/setup/openvpn/conf/ansible-hosts b/src/test/setup/openvpn/conf/ansible-hosts
new file mode 100644
index 0000000..0dd74f1
--- /dev/null
+++ b/src/test/setup/openvpn/conf/ansible-hosts
@@ -0,0 +1,2 @@
+[localhost]
+127.0.0.1
diff --git a/src/test/setup/openvpn/conf/synchronizer.conf b/src/test/setup/openvpn/conf/synchronizer.conf
new file mode 100644
index 0000000..2131a25
--- /dev/null
+++ b/src/test/setup/openvpn/conf/synchronizer.conf
@@ -0,0 +1,9 @@
+[supervisord]
+logfile=/var/log/supervisord.log ; (main log file;default $CWD/supervisord.log)
+pidfile=/var/run/supervisord.pid ; (supervisord pidfile;default supervisord.pid)
+nodaemon=true
+
+[program:synchronizer]
+command=python /opt/xos/synchronizers/openstack/xos-synchronizer.py
+stderr_logfile=/var/log/supervisor/synchronizer.err.log
+stdout_logfile=/var/log/supervisor/synchronizer.out.log
diff --git a/src/test/setup/postgresql/Dockerfile b/src/test/setup/postgresql/Dockerfile
new file mode 100644
index 0000000..4d4ebfd
--- /dev/null
+++ b/src/test/setup/postgresql/Dockerfile
@@ -0,0 +1,35 @@
+FROM ubuntu
+
+RUN apt-key adv --keyserver hkp://p80.pool.sks-keyservers.net:80 --recv-keys B97B0AFCAA1A47F044F244A07FCC7D46ACCC4CF8
+
+RUN echo "deb http://apt.postgresql.org/pub/repos/apt/ precise-pgdg main" > /etc/apt/sources.list.d/pgdg.list
+
+RUN DEBIAN_FRONTEND=noninteractive apt-get update && apt-get install -y --force-yes\
+    python-software-properties \
+    software-properties-common \
+    postgresql-9.3 \
+    postgresql-client-9.3 \
+    postgresql-contrib-9.3
+
+# Workaround for AUFS issue
+# https://github.com/docker/docker/issues/783#issuecomment-56013588
+RUN mkdir /etc/ssl/private-copy; mv /etc/ssl/private/* /etc/ssl/private-copy/; rm -r /etc/ssl/private; mv /etc/ssl/private-copy /etc/ssl/private; chmod -R 0700 /etc/ssl/private; chown -R postgres /etc/ssl/private
+
+USER postgres
+
+RUN /etc/init.d/postgresql start && \
+    psql --command "ALTER USER postgres WITH SUPERUSER PASSWORD 'password' " && \
+    psql --command "CREATE DATABASE xos"
+
+# Allow remote connections. 
+RUN echo "host all  all    0.0.0.0/0  md5" >> /etc/postgresql/9.3/main/pg_hba.conf
+RUN echo "host all  all    0.0.0.0/0  password" >> /etc/postgresql/9.3/main/pg_hba.conf
+
+RUN echo "listen_addresses='*'" >> /etc/postgresql/9.3/main/postgresql.conf
+
+# Expose the PostgreSQL port
+EXPOSE 5432
+
+VOLUME  ["/etc/postgresql", "/var/log/postgresql", "/var/lib/postgresql"]
+
+CMD ["/usr/lib/postgresql/9.3/bin/postgres", "-D", "/var/lib/postgresql/9.3/main", "-c", "config_file=/etc/postgresql/9.3/main/postgresql.conf"]
diff --git a/src/test/setup/postgresql/Makefile b/src/test/setup/postgresql/Makefile
new file mode 100644
index 0000000..8f483f8
--- /dev/null
+++ b/src/test/setup/postgresql/Makefile
@@ -0,0 +1,25 @@
+IMAGE_NAME:=xosproject/xos-postgres
+CONTAINER_NAME:=xos-db-postgres
+NO_DOCKER_CACHE?=false
+
+.PHONY: build
+build: ; docker build --no-cache=${NO_DOCKER_CACHE} --rm -t ${IMAGE_NAME} .
+
+.PHONY: run
+run: ; docker run -d -p 5432:5432 --name ${CONTAINER_NAME} ${IMAGE_NAME}
+
+.PHONY: stop
+stop: ; docker stop ${CONTAINER_NAME}
+
+.PHONY: rm
+rm: ; docker rm ${CONTAINER_NAME}
+
+.PHONY: rmi
+rmi: ; docker rmi ${IMAGE_NAME}
+
+.PHONY: backup
+backupvol: ; docker run --volumes-from ${CONTAINER_NAME} -v /backup:/backup postgres tar cvf /backup/backup-postgres.tar /var/lib/postgresql
+
+.PHONY: restore
+restorevol: ; docker run --volumes-from ${CONTAINER_NAME} -v /backup:/backup postgres cd /var/lib/postgresql && tar xvf /backup/backup-postgres.tar
+
diff --git a/src/test/setup/synchronizer/Dockerfile b/src/test/setup/synchronizer/Dockerfile
new file mode 100644
index 0000000..2f1e092
--- /dev/null
+++ b/src/test/setup/synchronizer/Dockerfile
@@ -0,0 +1,6 @@
+FROM       xosproject/xos
+
+# Supervisor
+COPY conf/synchronizer.conf /etc/supervisor/conf.d/
+
+CMD /usr/bin/supervisord -c /etc/supervisor/conf.d/synchronizer.conf
diff --git a/src/test/setup/synchronizer/Makefile b/src/test/setup/synchronizer/Makefile
new file mode 100644
index 0000000..352616a
--- /dev/null
+++ b/src/test/setup/synchronizer/Makefile
@@ -0,0 +1,15 @@
+IMAGE_NAME:=xosproject/xos-synchronizer-openstack
+CONTAINER_NAME:=xos-synchronizer
+NO_DOCKER_CACHE?=false
+
+.PHONY: build
+build: ; sudo docker build --no-cache=${NO_DOCKER_CACHE} --rm -t ${IMAGE_NAME} .
+
+.PHONY: run
+run: ; sudo docker run -d --name ${CONTAINER_NAME} -v /usr/local/share/ca-certificates:/usr/local/share/ca-certificates:ro ${IMAGE_NAME}
+
+.PHONY: stop
+stop: ; sudo docker stop ${CONTAINER_NAME}
+
+.PHONY: rm
+rm: ; sudo docker rm ${CONTAINER_NAME}
diff --git a/src/test/setup/synchronizer/conf/ansible-hosts b/src/test/setup/synchronizer/conf/ansible-hosts
new file mode 100644
index 0000000..0dd74f1
--- /dev/null
+++ b/src/test/setup/synchronizer/conf/ansible-hosts
@@ -0,0 +1,2 @@
+[localhost]
+127.0.0.1
diff --git a/src/test/setup/synchronizer/conf/synchronizer.conf b/src/test/setup/synchronizer/conf/synchronizer.conf
new file mode 100644
index 0000000..2131a25
--- /dev/null
+++ b/src/test/setup/synchronizer/conf/synchronizer.conf
@@ -0,0 +1,9 @@
+[supervisord]
+logfile=/var/log/supervisord.log ; (main log file;default $CWD/supervisord.log)
+pidfile=/var/run/supervisord.pid ; (supervisord pidfile;default supervisord.pid)
+nodaemon=true
+
+[program:synchronizer]
+command=python /opt/xos/synchronizers/openstack/xos-synchronizer.py
+stderr_logfile=/var/log/supervisor/synchronizer.err.log
+stdout_logfile=/var/log/supervisor/synchronizer.out.log
diff --git a/src/test/setup/syndicate-ms/Dockerfile b/src/test/setup/syndicate-ms/Dockerfile
new file mode 100644
index 0000000..e74db92
--- /dev/null
+++ b/src/test/setup/syndicate-ms/Dockerfile
@@ -0,0 +1,51 @@
+# Syndicate Metadata Server
+# See also https://github.com/syndicate-storage/syndicate-docker
+
+FROM ubuntu:14.04.4
+MAINTAINER Zack Williams <zdw@cs.arizona.edu>
+
+# vars
+ENV APT_KEY butler_opencloud_cs_arizona_edu_pub.gpg
+ENV MS_PORT 8080
+ENV GAE_SDK google_appengine_1.9.35.zip
+
+# Prep apt to be able to download over https
+RUN DEBIAN_FRONTEND=noninteractive apt-get update && apt-get install -y --force-yes\
+    apt-transport-https
+
+# copy over and trust https cert
+COPY butler.crt /usr/local/share/ca-certificates
+RUN update-ca-certificates
+
+# Install Syndicate MS
+COPY $APT_KEY /tmp/
+RUN apt-key add /tmp/$APT_KEY
+
+RUN echo "deb https://butler.opencloud.cs.arizona.edu/repos/release/syndicate syndicate main" > /etc/apt/sources.list.d/butler.list
+
+RUN DEBIAN_FRONTEND=noninteractive apt-get update && apt-get install -y --force-yes\
+    syndicate-core \
+    syndicate-ms \
+    wget \
+    unzip
+
+# setup syndicate user
+RUN groupadd -r syndicate && useradd -m -r -g syndicate syndicate
+USER syndicate
+ENV HOME /home/syndicate
+WORKDIR $HOME
+
+# setup GAE
+RUN wget -nv https://storage.googleapis.com/appengine-sdks/featured/$GAE_SDK
+RUN unzip -q $GAE_SDK
+
+# Expose the MS port
+EXPOSE $MS_PORT
+
+# Create a storage location
+RUN mkdir $HOME/datastore
+
+# run the MS under GAE
+CMD $HOME/google_appengine/dev_appserver.py --admin_host=0.0.0.0 --host=0.0.0.0 --storage_path=$HOME/datastore --skip_sdk_update_check=true /usr/src/syndicate/ms
+
+
diff --git a/src/test/setup/syndicate-ms/Makefile b/src/test/setup/syndicate-ms/Makefile
new file mode 100644
index 0000000..2c24afc
--- /dev/null
+++ b/src/test/setup/syndicate-ms/Makefile
@@ -0,0 +1,19 @@
+IMAGE_NAME:=xosproject/syndicate-ms
+CONTAINER_NAME:=xos-syndicate-ms
+NO_DOCKER_CACHE?=false
+
+.PHONY: build
+build: ; docker build --no-cache=${NO_DOCKER_CACHE} --rm -t ${IMAGE_NAME} .
+
+.PHONY: run
+run: ; docker run -d -p 8080:8080 --name ${CONTAINER_NAME} ${IMAGE_NAME}
+
+.PHONY: stop
+stop: ; docker stop ${CONTAINER_NAME}
+
+.PHONY: rm
+rm: ; docker rm ${CONTAINER_NAME}
+
+.PHONY: rmi
+rmi: ; docker rmi ${IMAGE_NAME}
+
diff --git a/src/test/setup/syndicate-ms/butler.crt b/src/test/setup/syndicate-ms/butler.crt
new file mode 100644
index 0000000..be60161
--- /dev/null
+++ b/src/test/setup/syndicate-ms/butler.crt
@@ -0,0 +1,37 @@
+-----BEGIN CERTIFICATE-----
+MIIGgjCCBWqgAwIBAgIRAJ26ZC+oEixlqDU7+7cazpIwDQYJKoZIhvcNAQELBQAw
+djELMAkGA1UEBhMCVVMxCzAJBgNVBAgTAk1JMRIwEAYDVQQHEwlBbm4gQXJib3Ix
+EjAQBgNVBAoTCUludGVybmV0MjERMA8GA1UECxMISW5Db21tb24xHzAdBgNVBAMT
+FkluQ29tbW9uIFJTQSBTZXJ2ZXIgQ0EwHhcNMTYwMzIyMDAwMDAwWhcNMTkwMzIy
+MjM1OTU5WjCBqzELMAkGA1UEBhMCVVMxDjAMBgNVBBETBTg1NzIxMQswCQYDVQQI
+EwJBWjEPMA0GA1UEBxMGVHVjc29uMSIwIAYDVQQKExlUaGUgVW5pdmVyc2l0eSBv
+ZiBBcml6b25hMSAwHgYDVQQLExdDb21wdXRlciBTY2llbmNlICgwNDEyKTEoMCYG
+A1UEAxMfYnV0bGVyLm9wZW5jbG91ZC5jcy5hcml6b25hLmVkdTCCAiIwDQYJKoZI
+hvcNAQEBBQADggIPADCCAgoCggIBAKHUqBxVP6fvTm015n8hXfe53B2IHbMbkwCj
+6eqc2mak8PEVIoD1Ds2TlrvS6xWtFJfNdKlMTNQMh3dVjUC8xcB+OUdr1Q3qv9to
+qiUJC+kTnJNDtOqYqJzX9koH+tHD0zr5/cqyT4vLkJZJXiZ5NGKyHUeh9INTj/ZG
+yHHVrDiF5gUyNl7HrN53AMPpJAxO0rurN5tI3ozK8TE60sslVdxE5zWwnSGazS+0
+hcz7uIyDTpyuo8H6iA/F5L5/USLqAYHLTk10Hg/7vnbRMbaz6sdXPFm+gtZPm5mG
+L2P9I4GM6L/TBXL7+etUtPAgVMoYrdDGZ3wmWOrWukD6ax3BVaX+dJxFNUTju2MZ
+1By6nJIzBBezHE7j4dhjRDaGwsxmdvEjn8weoeWS8ngT3fnm6btFgzO0O2CC3QN9
+M6pk5kJGm8kyhcc8nX4gv/Tkl1gHAd9VNgEJPY3YFXWigtjK7fSYGe9GDQsploUG
+OubK5S8eelSej1u9XW/NgqdxwgQWmxeppWxSwWb4wVyunVX03UHFmk6XnSdtF54E
+iy8VIuItRYyZGni8gAyCx8z6ke2zd8+wWgzsjxQ3dHjbLFxV1O57ZyNyb8TuZ5hk
+0QoJqdR0X6EXc+z4+tV+yYQGQZ5L3vgz7REp3TnlgG8acp3JfZpH8gng05cX6sBi
+I+NbZEmPAgMBAAGjggHTMIIBzzAfBgNVHSMEGDAWgBQeBaN3j2yW4luHS6a0hqxx
+AAznODAdBgNVHQ4EFgQUDfCqsiaVDm70iLaq32jUEmKr9pIwDgYDVR0PAQH/BAQD
+AgWgMAwGA1UdEwEB/wQCMAAwHQYDVR0lBBYwFAYIKwYBBQUHAwEGCCsGAQUFBwMC
+MGcGA1UdIARgMF4wUgYMKwYBBAGuIwEEAwEBMEIwQAYIKwYBBQUHAgEWNGh0dHBz
+Oi8vd3d3LmluY29tbW9uLm9yZy9jZXJ0L3JlcG9zaXRvcnkvY3BzX3NzbC5wZGYw
+CAYGZ4EMAQICMEQGA1UdHwQ9MDswOaA3oDWGM2h0dHA6Ly9jcmwuaW5jb21tb24t
+cnNhLm9yZy9JbkNvbW1vblJTQVNlcnZlckNBLmNybDB1BggrBgEFBQcBAQRpMGcw
+PgYIKwYBBQUHMAKGMmh0dHA6Ly9jcnQudXNlcnRydXN0LmNvbS9JbkNvbW1vblJT
+QVNlcnZlckNBXzIuY3J0MCUGCCsGAQUFBzABhhlodHRwOi8vb2NzcC51c2VydHJ1
+c3QuY29tMCoGA1UdEQQjMCGCH2J1dGxlci5vcGVuY2xvdWQuY3MuYXJpem9uYS5l
+ZHUwDQYJKoZIhvcNAQELBQADggEBACUaI/yYc0pxAuwIWi0985f06MdKEMJo+qEO
+YLXENApQrJhTPdV9OaChlzI4x2ExmffPZEmhyD0q7z57mT9QkBYQwEJqwbRqfY2v
+0iQ4nLLkyXh7SJSS7J4WSG+cFEN1nFZ8/YGg/TD8spEIPeUGsUvRoJmJm9z90uqd
++ETDc+79TZHxserOY3AJtlvzPScJa1HAqgDJGzgwGdUn82+bKZF5WGsGbfwUS6uS
+Ua2SsOxVZOn5ukF2g9vYs3dcO8u5ITAWrR1s6ACg/wGxvfvXwazpeiFx/RxilpcV
+6W7mTwbE76ZbkafrXbnZ6ihhIPARsVJhJsnClnf5OM7IqrX5g80=
+-----END CERTIFICATE-----
diff --git a/src/test/setup/syndicate-ms/butler_opencloud_cs_arizona_edu_pub.gpg b/src/test/setup/syndicate-ms/butler_opencloud_cs_arizona_edu_pub.gpg
new file mode 100644
index 0000000..92a2ae4
--- /dev/null
+++ b/src/test/setup/syndicate-ms/butler_opencloud_cs_arizona_edu_pub.gpg
@@ -0,0 +1,29 @@
+-----BEGIN PGP PUBLIC KEY BLOCK-----
+Version: GnuPG v1
+
+mQINBFb+uuwBEADgmbb2CPnQ2LofLdx5rJN4O75TAjYjJAPyyyIZL2bKmhhuRYwK
+a/gZAlOy5Y/4o5pRgG5s1BFkrSvWRIP+Y3D+PHz7wppjlo31NGm4+34stzlzGu4K
+EEUZpCiUiD1tCxX/H9jZTo5Dm2YvdLxnkWSkbf1ZkIzwNjM3bnYily2a/1NwMmqt
+18Hsy+3ivvUEZO0FmO2reP1l7Eb0hLR2QPxSA4/PxQ81+EJ3CObRYaUZ9KjgIRah
+eyP+PsXaFnxkoikGHod9ll2iWPzpkOUh+xXAu73YK4ikCrIUZ5Oe98Euja8h856H
+xiRRLGVL3iqzgAQJxG/0cXbiobN7bNYGlvLLyp+qRNbmgSYonsJxON4aVG+wjiLi
+gYCOQ/FQT0tYGeDprPBWRj6iGiic6K7W9BDXkxPqlYIYomMrjrqW5kX0YGMp+V7c
+2QG3yfh4+3pfpM+ZYfrAtCdgklYmCYBhoaieMrjIYw31PWqMuzxeb3xBS6++6ksH
+d9TlJKLgJ1UPiKLgDOEyIbYVWhPs2sQoRRstuKfPF9Gdv0UUAnqlyA8siVrvZfB2
+7D05PM4mv83GshoZ8ZAkV7uS6PFJIg6JM11dUM50LTfvHe7ig93CBvbFzm+RqxjQ
+JYf1XWd19912TW7NcNz6lg5jxEYLh8WYJin2xC2aLLb+hpy5NHE/Ien2aQARAQAB
+tCVPcGVuQ2xvdWQgQnV0bGVyIDxzaXRlc0BvcGVuY2xvdWQudXM+iQI9BBMBCgAn
+BQJW/rrsAhsDBQkDwmcABQsJCAcDBRUKCQgLBRYDAgEAAh4BAheAAAoJELvMx3QD
+/Cyyc2UQAIw2A8qrNMQt4skrR/87uKQjfJ/OXC7MEBDTLSL0Ed0VIuRrA/E1s1D/
+YJpdsFfKJyDbZ2Id25L+1QclvEjnsEDCIiURGcRmXLLsqjHCw4N2C16P2JasQVWo
+i1lkqUHC8kCzvR75u+agzpn16Qhb8FqLQxBSxd8vhMEw2LnrjRsjHGwErKhpYfOg
+LFXyurKKBb4KYOLortICgcE3Wz6eqgbNInrTMrSOSf5P7nsPINCFTyemzUyT53IU
+07RmJwTOrcgqJR5klghHQnFXJBkB55EMvFLjUrL4dpnAmlbkKhyFX8aRsBD5Frt2
+93LkHWDa35SELEzfIQznIsfok1rHgDR8kAh7m+tEbmn/Qk3llJ7c/r4JqG0RVGfe
+OfYZDT4I12H6ZWIoLjktnAP4QlDf+olILEYAD0PvKEQU7sQpMmex5QBMt6vvGAj6
+RfPn1iFhUZdOPB7GyWtUn8hmBCEfLAoAAntgoW9NC+PI/chFrm6Nugjz60TbMMOd
+i4s5J998AuJeF2RJogIi61a4VYcprSMTkF5b8kxBhV4N4J5jJQEQxo3ztdw7USvj
+ce8/3/69mBT7rIXgk39FvqnSIz9SmyQ+wgLb94Gcpy1id64yab2P1LNm3pORafSN
+F59uVqgEv5W2g/frt5QMSBO06dvzNjStIV7/uxlOHuSNooIClr//
+=JFDF
+-----END PGP PUBLIC KEY BLOCK-----
diff --git a/src/test/setup/xos/Dockerfile b/src/test/setup/xos/Dockerfile
new file mode 100644
index 0000000..e19b40c
--- /dev/null
+++ b/src/test/setup/xos/Dockerfile
@@ -0,0 +1,36 @@
+FROM xosproject/xos-base
+
+# Include certificates from Openstack
+ADD local_certs.crt /usr/local/share/ca-certificates/local_certs.crt
+RUN update-ca-certificates
+
+# Install and boostrap XOS and Tosca
+ENV XOS_GIT_REPO https://github.com/opencord/xos.git
+ENV XOS_GIT_BRANCH master
+
+RUN git clone $XOS_GIT_REPO -b $XOS_GIT_BRANCH /tmp/xos && \
+    mv /tmp/xos/xos /opt/ && \
+    chmod +x /opt/xos/tools/xos-manage && \
+    /opt/xos/tools/xos-manage genkeys
+
+# ng-xos-lib download
+
+ENV NG_XOS_LIB_URL https://github.com/opencord/ng-xos-lib.git
+ENV NG_XOS_LIB_VERSION 1.0.0
+
+RUN git clone $NG_XOS_LIB_URL /tmp/ng-xos-lib 
+RUN cd /tmp/ng-xos-lib && git checkout tags/$NG_XOS_LIB_VERSION
+RUN cp /tmp/ng-xos-lib/dist/ngXosHelpers.min.js /opt/xos/core/xoslib/static/vendor/ 
+RUN cp /tmp/ng-xos-lib/dist/ngXosVendor.min.js /opt/xos/core/xoslib/static/vendor/
+
+EXPOSE 8000
+
+# Set environment variables
+ENV HOME /root
+
+# Define working directory
+WORKDIR /opt/xos
+
+# Define default command
+CMD python /opt/xos/manage.py runserver 0.0.0.0:8000 --insecure --makemigrations
+
diff --git a/src/test/setup/xos/Dockerfile.base b/src/test/setup/xos/Dockerfile.base
new file mode 100644
index 0000000..a511986
--- /dev/null
+++ b/src/test/setup/xos/Dockerfile.base
@@ -0,0 +1,84 @@
+# Dockerfile.base
+# This image isn't used, but installs the prereqs for the other XOS images
+
+FROM ubuntu:14.04.5
+MAINTAINER Zack Williams <zdw@cs.arizona.edu>
+
+# Install apt packages
+RUN DEBIAN_FRONTEND=noninteractive apt-get update && apt-get install -y \
+    apt-transport-https \
+    curl \
+    gcc \
+    geoip-database \
+    git \
+    graphviz \
+    graphviz-dev \
+    libcurl4-gnutls-dev \
+    libffi-dev \
+    libgeoip1 \
+    libpq-dev \
+    libxslt1-dev \
+    libxslt1.1 \
+    libyaml-dev \
+    m4 \
+    openssh-client \
+    pkg-config \
+    python-dev \
+    python-pip \
+    rsync \
+    software-properties-common \
+    supervisor \
+    unzip \
+    wget \
+ && rm -rf /var/lib/apt/lists/* \
+ && mkdir /var/xos \
+ && pip freeze > /var/xos/pip_freeze_apt_`date -u +%Y%m%dT%H%M%S`
+
+# Install python packages with pip
+COPY pip_requirements.txt /tmp/pip_requirements.txt
+
+RUN pip install --no-deps -r /tmp/pip_requirements.txt \
+ && pip freeze > /var/xos/pip_freeze_pip_up_`date -u +%Y%m%dT%H%M%S`
+
+# Copy over ansible hosts
+COPY ansible-hosts /etc/ansible/hosts
+
+# Install jQuery
+ENV JQUERY_DL_URL http://code.jquery.com/jquery-1.12.4.min.js
+ENV JQUERY_SHA256 668b046d12db350ccba6728890476b3efee53b2f42dbb84743e5e9f1ae0cc404
+
+RUN curl -fLsS $JQUERY_DL_URL -o jquery.min.js && \
+    echo "$JQUERY_SHA256  jquery.min.js" | sha256sum -c - && \
+    mv jquery.min.js /usr/local/lib/python2.7/dist-packages/suit/static/suit/js/
+
+# Install jQueryUI
+ENV JQUERYUI_DL_URL https://jqueryui.com/resources/download/jquery-ui-1.11.4.zip
+ENV JQUERYUI_SHA256 503e4c0f109bf627aff87a424edc760608ec15e4a6e37f217a083ca682543e32
+
+RUN curl -fLsS $JQUERYUI_DL_URL -o jquery-ui.zip && \
+    echo "$JQUERYUI_SHA256  jquery-ui.zip" | sha256sum -c - && \
+    unzip jquery-ui.zip && \
+    mv jquery-ui-*/jquery-ui.min.js /usr/local/lib/python2.7/dist-packages/suit/static/suit/js/ && \
+    rm -rf jquery-ui.zip jquery-ui-*
+
+ENV JQUERYUI_THEMES_DL_URL http://jqueryui.com/resources/download/jquery-ui-themes-1.11.4.zip
+ENV JQUERYUI_THEMES_SHA256 df2b9cb084095ea24129a6a54587a1d9d7ae4bcd68bf5ea2957eb3d4d18fe884
+
+RUN curl -fLsS $JQUERYUI_THEMES_DL_URL -o jquery-ui-themes.zip && \
+    echo "$JQUERYUI_THEMES_SHA256  jquery-ui-themes.zip" | sha256sum -c - && \
+    unzip jquery-ui-themes.zip && \
+    mv jquery-ui-themes-*/themes/smoothness/jquery-ui.min.css /usr/local/lib/python2.7/dist-packages/suit/static/suit/css/ && \
+    rm -rf jquery-ui-themes.zip jquery-ui-themes-*
+
+# Install heat-translator for TOSCA support
+ENV HT_REPO_URL https://github.com/openstack/heat-translator.git
+ENV HT_REF a951b93c16e54046ed2d233d814860181c772e30
+
+RUN git clone $HT_REPO_URL /tmp/heat-translator && \
+    cd /tmp/heat-translator && \
+    git checkout $HT_REF && \
+    mkdir -p /opt/tosca && \
+    mv /tmp/heat-translator/translator /opt/tosca/translator && \
+    echo > /opt/tosca/translator/__init__.py && \
+    rm -rf /tmp/heat-translator
+
diff --git a/src/test/setup/xos/Dockerfile.devel b/src/test/setup/xos/Dockerfile.devel
new file mode 100644
index 0000000..21b4452
--- /dev/null
+++ b/src/test/setup/xos/Dockerfile.devel
@@ -0,0 +1,40 @@
+FROM xosproject/xos-base
+
+ARG XOS_GIT_COMMIT_HASH=unknown
+ARG XOS_GIT_COMMIT_DATE=unknown
+
+LABEL XOS_GIT_COMMIT_HASH=$XOS_GIT_COMMIT_HASH
+LABEL XOS_GIT_COMMIT_DATE=$XOS_GIT_COMMIT_DATE
+
+# Include certificates from Openstack
+ADD containers/xos/local_certs.crt /usr/local/share/ca-certificates/local_certs.crt
+RUN update-ca-certificates
+
+# Install XOS
+ADD xos /opt/xos
+
+# ng-xos-lib download
+ENV NG_XOS_LIB_URL https://github.com/opencord/ng-xos-lib.git
+ENV NG_XOS_LIB_VERSION 1.0.0
+
+RUN git clone $NG_XOS_LIB_URL /tmp/ng-xos-lib \
+ && cd /tmp/ng-xos-lib  \
+ && git checkout tags/$NG_XOS_LIB_VERSION \
+ && cp /tmp/ng-xos-lib/dist/ngXosHelpers.min.js /opt/xos/core/xoslib/static/vendor/ \
+ && cp /tmp/ng-xos-lib/dist/ngXosVendor.min.js /opt/xos/core/xoslib/static/vendor/
+
+RUN chmod +x /opt/xos/tools/xos-manage \
+ && sync \
+ && /opt/xos/tools/xos-manage genkeys
+
+EXPOSE 8000
+
+# Set environment variables
+ENV HOME /root
+
+# Define working directory
+WORKDIR /opt/xos
+
+# Define default command
+CMD python /opt/xos/manage.py runserver 0.0.0.0:8000 --insecure --makemigrations
+
diff --git a/src/test/setup/xos/Dockerfile.test b/src/test/setup/xos/Dockerfile.test
new file mode 100644
index 0000000..3d74883
--- /dev/null
+++ b/src/test/setup/xos/Dockerfile.test
@@ -0,0 +1,20 @@
+FROM xosproject/xos
+
+# install nodejs
+COPY containers/xos/nodesource.gpg.key /tmp/nodesource.gpg.key
+
+RUN apt-key add /tmp/nodesource.gpg.key \
+ && echo "deb https://deb.nodesource.com/node_4.x trusty main" \
+    > /etc/apt/sources.list.d/nodesource.list
+
+RUN apt-get update \
+ && apt-get install -y --force-yes \
+    nodejs \
+ && rm -rf /var/lib/apt/lists/*
+
+RUN node -v
+
+RUN pip install selenium
+
+RUN npm install -g phantomjs
+
diff --git a/src/test/setup/xos/Makefile b/src/test/setup/xos/Makefile
new file mode 100644
index 0000000..d7be421
--- /dev/null
+++ b/src/test/setup/xos/Makefile
@@ -0,0 +1,76 @@
+# Docker container Makefile for XOS
+#
+# Targets:
+#
+#  `base`   - XOS prerequistie files, no XOS code, builds xosproject/xos-base
+#  `build`  - base + XOS code, git pulled in Dockerfile from main repo,
+#             builds xosproject/xos
+#  `custom` - base + XOS code, git pulled in Dockerfile from selectable repo,
+#             builds xosproject/xos
+#  `devel`  - base + XOS code from local directory, builds xosproject/xos
+#  `test`   - xosproject/xos + nodejs testing frameworks, builds
+#             xosproject/xos-test
+#
+
+NO_DOCKER_CACHE    ?= false
+
+CONTAINER_NAME     ?= xos-server
+IMAGE_NAME         ?= xosproject/xos
+
+XOS_GIT_REPO       ?= https://github.com/opencord/xos.git
+XOS_GIT_BRANCH     ?= master
+
+XOS_GIT_COMMIT_HASH     ?= $(shell git log --pretty=format:'%H' -n 1 || echo -n "unknown" )
+XOS_GIT_COMMIT_DATE     ?= $(shell git log --pretty=format:'%ad' -n 1 || echo -n "unknown" )
+
+TOSCA_CONFIG_PATH  ?= /opt/xos/configurations/opencloud/opencloud.yaml
+
+BUILD_ARGS =
+ifdef http_proxy
+BUILD_ARGS += --build-arg http_proxy=${http_proxy}
+endif
+ifdef https_proxy
+BUILD_ARGS += --build-arg https_proxy=${https_proxy}
+endif
+
+base:
+	sudo docker build --no-cache=${NO_DOCKER_CACHE} --rm \
+	-f Dockerfile.base -t xosproject/xos-base ${BUILD_ARGS} .
+
+build:
+	sudo docker build --no-cache=${NO_DOCKER_CACHE} --rm \
+	-f Dockerfile -t ${IMAGE_NAME} ${BUILD_ARGS} .
+
+custom:
+	docker build --no-cache=${NO_DOCKER_CACHE} --rm \
+	--build-arg XOS_GIT_REPO=${XOS_GIT_REPO} \
+	--build-arg XOS_GIT_BRANCH=${XOS_GIT_BRANCH} \
+	-f Dockerfile -t ${IMAGE_NAME} ${BUILD_ARGS} .
+
+devel:
+	sudo docker build --no-cache=${NO_DOCKER_CACHE} --rm \
+	--build-arg XOS_GIT_COMMIT_HASH="${XOS_GIT_COMMIT_HASH}" \
+	--build-arg XOS_GIT_COMMIT_DATE="${XOS_GIT_COMMIT_DATE}" \
+	-f Dockerfile.devel -t ${IMAGE_NAME} ${BUILD_ARGS} ../..
+
+test:
+	sudo docker build --no-cache=${NO_DOCKER_CACHE} --rm \
+	-f Dockerfile.test -t xosproject/xos-test ${BUILD_ARGS} ../..
+
+run:
+	sudo docker run -d --name ${CONTAINER_NAME} -p 80:8000 \
+	${IMAGE_NAME}
+
+runtosca:
+	sudo docker exec -it ${CONTAINER_NAME} \
+  /usr/bin/python /opt/xos/tosca/run.py padmin@vicci.org ${TOSCA_CONFIG_PATH}
+
+stop:
+	sudo docker stop ${CONTAINER_NAME}
+
+rm:
+	sudo docker rm ${CONTAINER_NAME}
+
+rmi:
+	sudo docker rmi `docker images | grep "^<none>" | awk '{print $$3}'`
+
diff --git a/src/test/setup/xos/ansible-hosts b/src/test/setup/xos/ansible-hosts
new file mode 100644
index 0000000..0dd74f1
--- /dev/null
+++ b/src/test/setup/xos/ansible-hosts
@@ -0,0 +1,2 @@
+[localhost]
+127.0.0.1
diff --git a/src/test/setup/xos/initdb b/src/test/setup/xos/initdb
new file mode 100755
index 0000000..b90a570
--- /dev/null
+++ b/src/test/setup/xos/initdb
@@ -0,0 +1,16 @@
+#!/bin/bash
+
+IMAGE_NAME=xosproject/xos
+CONTAINER_NAME=xos_build_helper_$$
+DB_HOST=$(wget http://ipinfo.io/ip -qO -)
+
+# configure db host
+docker run -it --name=$CONTAINER_NAME $IMAGE_NAME sed -i '0,/host/{s/host=localhost/host='$DB_HOST'/}' /opt/xos/xos_configuration/xos_common_config
+docker commit $CONTAINER_NAME $IMAGE_NAME
+docker rm $CONTAINER_NAME
+
+# init db schema
+docker run -it --name=$CONTAINER_NAME $IMAGE_NAME /opt/xos/tools/xos-manage makemigrations
+# run overrides the CMD specifed in the Dockerfile, so we re-set the CMD in the final commit"
+docker commit --change="CMD python /opt/xos/manage.py runserver 0.0.0.0:8000 --insecure" $CONTAINER_NAME $IMAGE_NAME
+docker rm $CONTAINER_NAME
diff --git a/src/test/setup/xos/local_certs.crt b/src/test/setup/xos/local_certs.crt
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/src/test/setup/xos/local_certs.crt
diff --git a/src/test/setup/xos/nodesource.gpg.key b/src/test/setup/xos/nodesource.gpg.key
new file mode 100644
index 0000000..1dc1d10
--- /dev/null
+++ b/src/test/setup/xos/nodesource.gpg.key
@@ -0,0 +1,52 @@
+-----BEGIN PGP PUBLIC KEY BLOCK-----
+Version: GnuPG v1
+Comment: GPGTools - https://gpgtools.org
+
+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
+=CLGF
+-----END PGP PUBLIC KEY BLOCK-----
diff --git a/src/test/setup/xos/pip_requirements.txt b/src/test/setup/xos/pip_requirements.txt
new file mode 100644
index 0000000..ae66fbe
--- /dev/null
+++ b/src/test/setup/xos/pip_requirements.txt
@@ -0,0 +1,135 @@
+pytz==2016.6.1
+Babel==2.3.4
+Django==1.8.14
+Jinja2==2.8
+Markdown==2.6.6
+MarkupSafe==0.23
+Paste==2.0.3
+PasteDeploy==1.5.2
+PyYAML==3.12
+Routes==2.3.1
+WebOb==1.6.1
+amqp==1.4.9
+ansible==2.1.1.0
+anyjson==0.3.3
+appdirs==1.4.0
+argparse==1.2.1
+ca-certs-locater==1.0
+cachetools==1.1.6
+cffi==1.7.0
+chardet==2.0.1
+cliff==2.2.0
+cmd2==0.6.8
+colorama==0.2.5
+contextlib2==0.5.4
+coreapi==1.32.3
+debtcollector==1.8.0
+decorator==4.0.10
+django-bitfield==1.8.0
+django-crispy-forms==1.6.0
+django-encrypted-fields==1.1.2
+django-extensions==1.7.3
+django-filter==0.14.0
+django-ipware==1.1.5
+django-rest-swagger==2.0.5
+django-suit==0.3a3
+django-timezones==0.2
+djangorestframework==3.3.3
+dnslib==0.9.6
+dogpile.cache==0.6.2
+enum34==1.1.6
+eventlet==0.19.0
+fasteners==0.14.1
+funcsigs==1.0.2
+functools32==3.2.3-2
+futures==3.0.5
+futurist==0.18.0
+google-api-python-client==1.5.3
+greenlet==0.4.10
+html5lib==0.999
+httplib2==0.9.2
+idna==2.1
+ipaddress==1.0.16
+iso8601==0.1.11
+itypes==1.1.0
+jsonpatch==1.14
+jsonpointer==1.10
+jsonschema==2.5.1
+keystoneauth1==2.12.1
+kombu==3.0.35
+lxml==3.6.4
+meld3==0.6.10
+monotonic==1.2
+msgpack-python==0.4.8
+munch==2.0.4
+ndg-httpsclient==0.4.2
+netaddr==0.7.18
+netifaces==0.10.5
+oauth2client==3.0.0
+openapi-codec==1.0.0
+openstacksdk==0.9.4
+os-client-config==1.21.0
+osc-lib==1.1.0
+oslo.concurrency==3.14.0
+oslo.config==3.17.0
+oslo.context==2.9.0
+oslo.i18n==3.9.0
+oslo.log==3.16.0
+oslo.messaging==5.10.0
+oslo.middleware==3.19.0
+oslo.serialization==2.13.0
+oslo.service==1.16.0
+oslo.utils==3.16.0
+osprofiler==1.4.0
+paramiko==2.0.2
+pbr==1.10.0
+pika==0.10.0
+pika-pool==0.1.3
+positional==1.1.1
+prettytable==0.7.2
+psycopg2==2.6.2
+pyOpenSSL==16.1.0
+pyasn1==0.1.9
+pyasn1-modules==0.0.8
+pycparser==2.14
+pycrypto==2.6.1
+pycurl==7.43.0
+pygraphviz==1.3.1
+pyinotify==0.9.6
+pyparsing==2.1.8
+python-cinderclient==1.8.0
+python-dateutil==2.5.3
+python-designateclient==2.3.0
+python-gflags==3.0.6
+python-glanceclient==2.5.0
+python-heatclient==1.4.0
+python-ironicclient==1.6.0
+python-keyczar==0.716
+python-keystoneclient==3.5.0
+python-logstash==0.4.6
+python-magnumclient==2.3.0
+python-mistralclient==2.1.0
+python-neutronclient==5.1.0
+python-novaclient==5.1.0
+python-openstackclient==3.1.0
+python-swiftclient==3.0.0
+python-troveclient==2.5.0
+repoze.lru==0.6
+requests==2.11.1
+requestsexceptions==1.1.3
+retrying==1.3.3
+rfc3986==0.4.1
+rsa==3.4.2
+shade==1.9.0
+simplejson==3.8.2
+six==1.10.0
+stevedore==1.17.1
+supervisor==3.0b2
+unicodecsv==0.14.1
+uritemplate==0.6
+urllib3==1.7.1
+warlock==1.2.0
+wheel==0.24.0
+wrapt==1.10.8
+wsgiref==0.1.2
+redis==2.10.5