Update stage_3 to use multi-stack install 00/6500/2
authorMike Marchetti <mmarchetti@sandvine.com>
Thu, 13 Sep 2018 17:45:06 +0000 (13:45 -0400)
committerMike Marchetti <mmarchetti@sandvine.com>
Mon, 17 Sep 2018 15:56:54 +0000 (11:56 -0400)
Add support for multi-stack installation

Cleanup use of sudo for copying files. Apply docker specific
configuration inside user directory.

Utilize multiple juju controllers utilizing the stack name.

Create stack with no exposed host ports via '-nohostports' for creating
multiple instances of osm (useful in CI)

Add osmclient container for stack: This allows user to run osmclient
inside a container, that matches the release of osm, that has internal
access to all services.

Added options:
    --nolxd for CI osm installation
    --nojuju for CI osm installation
    --nodockerbuild
    --nohostports
    --nohostclient
    -s <stack name>

Change-Id: I4a2c1b09854e61ebb52d83f9f1ecebed8a17674d
Signed-off-by: Mike Marchetti <mmarchetti@sandvine.com>
docker/osmclient/Dockerfile [new file with mode: 0644]
installers/docker/docker-compose.yaml
installers/docker/osm_elk/docker-compose.yml
installers/docker/osm_metrics/docker-compose.yml
installers/full_install_osm.sh
jenkins/ci-pipelines/ci_stage_3.groovy

diff --git a/docker/osmclient/Dockerfile b/docker/osmclient/Dockerfile
new file mode 100644 (file)
index 0000000..a2cd547
--- /dev/null
@@ -0,0 +1,21 @@
+FROM ubuntu:16.04
+
+LABEL authors="Michael Marchetti"
+
+RUN apt-get update && apt-get -y install curl software-properties-common
+
+ARG REPOSITORY_BASE=http://osm-download.etsi.org/repository/osm/debian
+ARG RELEASE=ReleaseFOUR-daily
+ARG REPOSITORY_KEY=OSM%20ETSI%20Release%20Key.gpg
+ARG REPOSITORY=testing
+
+RUN curl ${REPOSITORY_BASE}/${RELEASE}/${REPOSITORY_KEY} | apt-key add -
+RUN add-apt-repository -y "deb ${REPOSITORY_BASE}/${RELEASE} ${REPOSITORY} devops osmclient" && apt update
+
+RUN apt-get update && apt-get -y install python \
+    libcurl4-gnutls-dev libgnutls-dev osm-devops python-osmclient iputils-ping python-pip
+RUN pip install python-magic pytest
+
+ENV OSM_SOL005=True
+ENV OSM_HOSTNAME=nbi:9999
+ENV OSM_RO_HOSTNAME=ro:9090
index a1e88bc..6924314 100644 (file)
@@ -6,7 +6,8 @@ volumes:
   osm_packages:
 networks:
   netOSM:
-    external: true
+    external:
+      name: ${OSM_NETWORK:-netOSM}
     #driver: overlay
     #driver_opts:
     #  com.docker.network.driver.mtu: "1446"
@@ -20,7 +21,7 @@ services:
   kafka:
     image: wurstmeister/kafka
     ports:
-      - "9092:9092"
+      - "9092"
     networks:
       - netOSM
     environment:
@@ -49,7 +50,7 @@ services:
       OSMNBI_DATABASE_HOST: mongo
       OSMNBI_MESSAGE_HOST: kafka
     ports:
-      - "9999:9999"
+      - "${OSM_NBI_PORTS:-9999:9999}"
     #depends_on:
     #  - kafka
     #  - mongo
@@ -90,7 +91,7 @@ services:
     #depends_on:
     #  - ro-db
     ports:
-      - "9090:9090"
+      - "${OSM_RO_PORTS:-9090:9090}"
   mon:
     image: osm/mon
     networks:
@@ -105,7 +106,7 @@ services:
     #depends_on:
     #  - kafka
     ports:
-      - "8662:8662"
+      - "8662"
   pm:
     image: osm/pm
     networks:
@@ -124,5 +125,4 @@ services:
     #depends_on:
     #  - nbi
     ports:
-      - "80:80"
-
+      - "${OSM_UI_PORTS:-80:80}"
index 222a1d0..c74eb67 100644 (file)
@@ -37,4 +37,4 @@ services:
 networks:
   elk:
     external:
-      name: netOSM
+      name: ${OSM_NETWORK:-netOSM}
index c6832a2..e2ba5c9 100644 (file)
@@ -1,7 +1,8 @@
 version: '3'
 networks:
   netOSM:
-    external: true
+    external:
+       name: ${OSM_NETWORK:-netOSM}
 services:
   kafka-exporter:
     image: osm/kafka-exporter
@@ -32,4 +33,3 @@ services:
       - netOSM
     depends_on:
       - prometheus
-
index a92e1ba..fa1c9ef 100755 (executable)
@@ -26,14 +26,22 @@ function usage(){
     echo -e "                     -b v2.0            (v2.0 branch)"
     echo -e "                     -b tags/v1.1.0     (a specific tag)"
     echo -e "                     ..."
+    echo -e "     -s <stack name> user defined stack name, default is osm"
+    echo -e "     -H <VCA host>   use specific juju host controller IP"
+    echo -e "     -S <VCA secret> use VCA/juju secret key"
     echo -e "     --vimemu:       additionally deploy the VIM emulator as a docker container"
     echo -e "     --elk_stack:    additionally deploy an ELK docker stack for event logging"
     echo -e "     --pm_stack:     additionally deploy a Prometheus+Grafana stack for performance monitoring (PM)"
     echo -e "     -m <MODULE>:    install OSM but only rebuild the specified docker images (RO, LCM, NBI, LW-UI, MON, KAFKA, MONGO, NONE)"
     echo -e "     -o <ADDON>:     ONLY (un)installs one of the addons (vimemu, elk_stack, pm_stack)"
     echo -e "     -D <devops path> use local devops installation path"
+    echo -e "     -w <work dir>   Location to store runtime installation"
     echo -e "     --nolxd:        do not install and configure LXD, allowing unattended installations (assumes LXD is already installed and confifured)"
     echo -e "     --nodocker:     do not install docker, do not initialize a swarm (assumes docker is already installed and a swarm has been initialized)"
+    echo -e "     --nojuju:       do not juju, assumes already installed"
+    echo -e "     --nodockerbuild:do not build docker images (use existing locally cached images)"
+    echo -e "     --nohostports:  do not expose docker ports to host (useful for creating multiple instances of osm on the same host)"
+    echo -e "     --nohostclient: do not install the osmclient"
     echo -e "     --uninstall:    uninstall OSM: remove the containers and delete NAT rules"
     echo -e "     --source:       install OSM from source code using the latest stable tag"
     echo -e "     --develop:      (deprecated, use '-b master') install OSM from source code using the master branch"
@@ -72,6 +80,42 @@ function uninstall(){
     return 0
 }
 
+# takes a juju/accounts.yaml file and returns the password specific
+# for a controller. I wrote this using only bash tools to minimize 
+# additions of other packages
+function parse_juju_password {
+   password_file="${HOME}/.local/share/juju/accounts.yaml"
+   local controller_name=$1
+   local s='[[:space:]]*' w='[a-zA-Z0-9_-]*' fs=$(echo @|tr @ '\034')
+   sed -ne "s|^\($s\):|\1|" \
+        -e "s|^\($s\)\($w\)$s:$s[\"']\(.*\)[\"']$s\$|\1$fs\2$fs\3|p" \
+        -e "s|^\($s\)\($w\)$s:$s\(.*\)$s\$|\1$fs\2$fs\3|p" $password_file |
+   awk -F$fs -v controller=$controller_name '{
+      indent = length($1)/2;
+      vname[indent] = $2;
+      for (i in vname) {if (i > indent) {delete vname[i]}}
+      if (length($3) > 0) {
+         vn=""; for (i=0; i<indent; i++) {vn=(vn)(vname[i])("_")}
+         if (match(vn,controller) && match($2,"password")) {
+             printf("%s",$3);
+         }
+      }
+   }'
+}
+
+function remove_volumes() {
+    stack=$1
+    volumes="mongo_db mon_db osm_packages ro_db"
+    for volume in $volumes; do
+        sg docker -c "docker volume rm ${stack}_${volume}"
+    done
+}
+
+function remove_network() {
+    stack=$1
+    sg docker -c "docker network rm net${stack}"
+}
+
 function remove_stack() {
     stack=$1
     if sg docker -c "docker stack ps ${stack}" ; then
@@ -102,17 +146,17 @@ function uninstall_lightweight() {
         if [ -n "$INSTALL_ELK" ]; then
             echo -e "\nUninstalling OSM ELK stack"
             remove_stack osm_elk
-            sudo rm -rf /etc/osm/docker/osm_elk
+            $WORKDIR_SUDO rm -rf $OSM_DOCKER_WORK_DIR/osm_elk
         fi
         if [ -n "$INSTALL_PERFMON" ]; then
             echo -e "\nUninstalling OSM Performance Monitoring stack"
             remove_stack osm_metrics
             sg docker -c "docker image rm osm/kafka-exporter"
-            sudo rm -rf /etc/osm/docker/osm_metrics
+            $WORKDIR_SUDO rm -rf $OSM_DOCKER_WORK_DIR/osm_metrics
         fi
     else
         echo -e "\nUninstalling OSM"
-        remove_stack osm
+        remove_stack $OSM_STACK_NAME
         remove_stack osm_elk
         remove_stack osm_metrics
         echo "Now osm docker images and volumes will be deleted"
@@ -124,14 +168,12 @@ function uninstall_lightweight() {
         docker image rm osm/mon
         docker image rm osm/pm
         docker image rm osm/kafka-exporter
-        docker volume rm osm_mon_db
-        docker volume rm osm_mongo_db
-        docker volume rm osm_osm_packages
-        docker volume rm osm_ro_db
 EONG
-        echo "Removing /etc/osm and /var/log/osm files"
-        sudo rm -rf /etc/osm
-        sudo rm -rf /var/log/osm
+        remove_volumes $OSM_STACK_NAME
+        remove_network $OSM_STACK_NAME
+        echo "Removing $OSM_DOCKER_WORK_DIR"
+        $WORKDIR_SUDO rm -rf $OSM_DOCKER_WORK_DIR
+        sg lxd -c "juju destroy-controller --yes $OSM_STACK_NAME"
     fi
     echo "Some docker images will be kept in case they are used by other docker stacks"
     echo "To remove them, just run 'docker image prune' in a terminal"
@@ -488,7 +530,6 @@ function install_osmclient(){
     CLIENT_RELEASE=${RELEASE#"-R "}
     CLIENT_REPOSITORY_KEY="OSM%20ETSI%20Release%20Key.gpg"
     CLIENT_REPOSITORY=${REPOSITORY#"-r "}
-    [ -z "$REPOSITORY_BASE" ] && REPOSITORY_BASE="-u https://osm-download.etsi.org/repository/osm/debian"
     CLIENT_REPOSITORY_BASE=${REPOSITORY_BASE#"-u "}
     key_location=$CLIENT_REPOSITORY_BASE/$CLIENT_RELEASE/$CLIENT_REPOSITORY_KEY
     curl $key_location | sudo apt-key add -
@@ -579,9 +620,16 @@ function install_juju() {
     echo "Installing juju"
     sudo snap install juju --classic
     [ -z "$INSTALL_NOLXD" ] && sudo dpkg-reconfigure -p medium lxd
-    sg lxd -c "juju bootstrap --bootstrap-series=xenial localhost osm"
-    [ $(sg lxd -c "juju status" |grep "osm" |wc -l) -eq 1 ] || FATAL "Juju installation failed"
     echo "Finished installation of juju"
+    return 0
+}
+
+function juju_createcontroller() {
+    if ! sg lxd -c "juju show-controller $OSM_STACK_NAME &> /dev/null"; then
+        # Not found created, create the controller
+        sg lxd -c "juju bootstrap --bootstrap-series=xenial localhost $OSM_STACK_NAME"
+    fi
+    [ $(sg lxd -c "juju controllers" |grep "$OSM_STACK_NAME" |wc -l) -eq 1 ] || FATAL "Juju installation failed"
 }
 
 function generate_docker_images() {
@@ -591,6 +639,11 @@ function generate_docker_images() {
 
     echo "OSM Docker images generated from $_build_from"
 
+    BUILD_ARGS+=(--build-arg REPOSITORY="$REPOSITORY")
+    BUILD_ARGS+=(--build-arg RELEASE="$RELEASE")
+    BUILD_ARGS+=(--build-arg REPOSITORY_KEY="$REPOSITORY_KEY")
+    BUILD_ARGS+=(--build-arg REPOSITORY_BASE="$REPOSITORY_BASE")
+    
     if [ -z "$TO_REBUILD" ] || echo $TO_REBUILD | grep -q KAFKA ; then
         sg docker -c "docker pull wurstmeister/zookeeper" || FATAL "cannot get zookeeper docker image"
         sg docker -c "docker pull wurstmeister/kafka" || FATAL "cannot get kafka docker image"
@@ -625,6 +678,9 @@ function generate_docker_images() {
         git -C ${LWTEMPDIR}/LW-UI checkout ${COMMIT_ID}
         sg docker -c "docker build ${LWTEMPDIR}/LW-UI -t osm/light-ui -f ${LWTEMPDIR}/LW-UI/Dockerfile --no-cache" || FATAL "cannot build LW-UI docker image"
     fi
+    if [ -z "$TO_REBUILD" ] || echo $TO_REBUILD | grep -q LW-osmclient; then
+        sg docker -c "docker build -t osm/osmclient ${BUILD_ARGS[@]} -f $OSM_DEVOPS/docker/osmclient ."
+    fi
     echo "Finished generation of docker images"
 }
 
@@ -633,37 +689,42 @@ function cmp_overwrite() {
     file2="$2"
     if ! $(cmp "${file1}" "${file2}" >/dev/null 2>&1); then
         if [ -f "${file2}" ]; then
-            ask_user "The file ${file2} already exists. Overwrite (y/N)? " n && sudo cp -b ${file1} ${file2}
+            ask_user "The file ${file2} already exists. Overwrite (y/N)? " n && cp -b ${file1} ${file2}
         else
-            sudo cp -b ${file1} ${file2}
+            cp -b ${file1} ${file2}
         fi
     fi
 }
 
 function generate_config_log_folders() {
     echo "Generating config and log folders"
-    sudo mkdir -p /etc/osm/docker
-    sudo cp -b ${OSM_DEVOPS}/installers/docker/docker-compose.yaml /etc/osm/docker/docker-compose.yaml
-    sudo mkdir -p /var/log/osm
+    $WORKDIR_SUDO cp -b ${OSM_DEVOPS}/installers/docker/docker-compose.yaml $OSM_DOCKER_WORK_DIR/docker-compose.yaml
     echo "Finished generation of config and log folders"
 }
 
 function generate_docker_env_files() {
     echo "Generating docker env files"
-    echo "OSMLCM_VCA_HOST=${OSMLCM_VCA_HOST}" |sudo tee /etc/osm/docker/lcm.env
-    echo "OSMLCM_VCA_SECRET=${OSMLCM_VCA_SECRET}" |sudo tee -a /etc/osm/docker/lcm.env
+    echo "OSMLCM_VCA_HOST=${OSMLCM_VCA_HOST}" | $WORKDIR_SUDO tee $OSM_DOCKER_WORK_DIR/lcm.env
+    echo "OSMLCM_VCA_SECRET=${OSMLCM_VCA_SECRET}" | $WORKDIR_SUDO tee -a $OSM_DOCKER_WORK_DIR/lcm.env
+
     MYSQL_ROOT_PASSWORD=`date +%s | sha256sum | base64 | head -c 32`
-    if [ ! -f /etc/osm/docker/ro-db.env ]; then
-        echo "MYSQL_ROOT_PASSWORD=${MYSQL_ROOT_PASSWORD}" |sudo tee /etc/osm/docker/ro-db.env
+    if [ ! -f $OSM_DOCKER_WORK_DIR/ro-db.env ]; then
+        echo "MYSQL_ROOT_PASSWORD=${MYSQL_ROOT_PASSWORD}" |$WORKDIR_SUDO tee $OSM_DOCKER_WORK_DIR/ro-db.env
     fi
-    if [ ! -f /etc/osm/docker/ro.env ]; then
-        echo "RO_DB_ROOT_PASSWORD=${MYSQL_ROOT_PASSWORD}" |sudo tee /etc/osm/docker/ro.env
+    if [ ! -f $OSM_DOCKER_WORK_DIR/ro.env ]; then
+        echo "RO_DB_ROOT_PASSWORD=${MYSQL_ROOT_PASSWORD}" |$WORKDIR_SUDO tee $OSM_DOCKER_WORK_DIR/ro.env
     fi
-    echo "OS_NOTIFIER_URI=http://${DEFAULT_IP}:8662" |tee /tmp/mon.env
-    cmp_overwrite /tmp/mon.env /etc/osm/docker/mon.env
+    echo "OS_NOTIFIER_URI=http://${DEFAULT_IP}:8662" |$WORKDIR_SUDO tee $OSM_DOCKER_WORK_DIR/mon.env
+
     echo "Finished generation of docker env files"
 }
 
+function generate_osmclient_script () {
+    echo "docker run -ti --network net${OSM_STACK_NAME} osm/osmclient" | $WORKDIR_SUDO tee $OSM_DOCKER_WORK_DIR/osm
+    $WORKDIR_SUDO chmod +x "$OSM_DOCKER_WORK_DIR/osm"
+    echo "osmclient sidecar container can be found at: $OSM_DOCKER_WORK_DIR/osm"
+}
+
 function init_docker_swarm() {
     if [ "${DEFAULT_MTU}" != "1500" ]; then
       DOCKER_NETS=`sg docker -c "docker network list" | awk '{print $2}' | egrep -v "^ID$" | paste -d " " -s`
@@ -671,16 +732,38 @@ function init_docker_swarm() {
       sg docker -c "docker network create --subnet ${DOCKER_GW_NET} --opt com.docker.network.bridge.name=docker_gwbridge --opt com.docker.network.bridge.enable_icc=false --opt com.docker.network.bridge.enable_ip_masquerade=true --opt com.docker.network.driver.mtu=${DEFAULT_MTU} docker_gwbridge"
     fi
     sg docker -c "docker swarm init --advertise-addr ${DEFAULT_IP}"
-    sg docker -c "docker network create --driver=overlay --attachable --opt com.docker.network.driver.mtu=${DEFAULT_MTU} netOSM"
     return 0
 }
 
+function create_docker_network() {
+    echo "creating network"
+    sg docker -c "docker network create --driver=overlay --attachable --opt com.docker.network.driver.mtu=${DEFAULT_MTU} net${OSM_STACK_NAME}"
+    echo "creating network DONE"
+}
+
 function deploy_lightweight() {
+
     echo "Deploying lightweight build"
-    [ -n "$INSTALL_NODOCKER" ] || init_docker_swarm
-    remove_stack osm
-    sg docker -c "docker stack deploy -c /etc/osm/docker/docker-compose.yaml osm"
-    #docker-compose -f /etc/osm/docker/docker-compose.yaml up -d
+    OSM_NBI_PORT=9999
+    OSM_RO_PORT=9090
+    OSM_UI_PORT=80
+
+    if [ -n "$NO_HOST_PORTS" ]; then
+        OSM_PORTS+=(OSM_NBI_PORTS=$OSM_NBI_PORT)
+        OSM_PORTS+=(OSM_RO_PORTS=$OSM_RO_PORT)
+        OSM_PORTS+=(OSM_UI_PORTS=$OSM_UI_PORT)
+    else
+        OSM_PORTS+=(OSM_NBI_PORTS=$OSM_NBI_PORT:$OSM_NBI_PORT)
+        OSM_PORTS+=(OSM_RO_PORTS=$OSM_RO_PORT:$OSM_RO_PORT)
+        OSM_PORTS+=(OSM_UI_PORTS=$OSM_UI_PORT:$OSM_UI_PORT)
+    fi
+    echo "export ${OSM_PORTS[@]}" | $WORKDIR_SUDO tee $OSM_DOCKER_WORK_DIR/osm_ports.sh
+    echo "export OSM_NETWORK=net${OSM_STACK_NAME}" | $WORKDIR_SUDO tee --append $OSM_DOCKER_WORK_DIR/osm_ports.sh
+
+    pushd $OSM_DOCKER_WORK_DIR
+    sg docker -c "source ./osm_ports.sh; docker stack deploy -c $OSM_DOCKER_WORK_DIR/docker-compose.yaml $OSM_STACK_NAME"
+    popd
+
     echo "Finished deployment of lightweight build"
 }
 
@@ -690,11 +773,11 @@ function deploy_elk() {
     sg docker -c "docker pull docker.elastic.co/logstash/logstash-oss:6.2.3" || FATAL "cannot get logstash docker image"
     sg docker -c "docker pull docker.elastic.co/kibana/kibana-oss:6.2.3" || FATAL "cannot get kibana docker image"
     echo "Finished pulling elk docker images"
-    sudo mkdir -p /etc/osm/docker/osm_elk
-    sudo cp -b ${OSM_DEVOPS}/installers/docker/osm_elk/* /etc/osm/docker/osm_elk
+    $WORKDIR_SUDO mkdir -p "$OSM_DOCKER_WORK_DIR/osm_elk"
+    $WORKDIR_SUDO cp -b ${OSM_DEVOPS}/installers/docker/osm_elk/* $OSM_DOCKER_WORK_DIR/osm_elk
     remove_stack osm_elk
     echo "Deploying ELK stack"
-    sg docker -c "docker stack deploy -c /etc/osm/docker/osm_elk/docker-compose.yml osm_elk"
+    sg docker -c "OSM_NETWORK=net${OSM_STACK_NAME} docker stack deploy -c $OSM_DOCKER_WORK_DIR/osm_elk/docker-compose.yml osm_elk"
     echo "Waiting for ELK stack to be up and running"
     time=0
     step=5
@@ -740,17 +823,20 @@ function deploy_perfmon() {
     echo "Generating osm/kafka-exporter docker image"
     sg docker -c "docker build ${OSM_DEVOPS}/installers/docker/osm_metrics/kafka-exporter -f ${OSM_DEVOPS}/installers/docker/osm_metrics/kafka-exporter/Dockerfile -t osm/kafka-exporter --no-cache" || FATAL "cannot build kafka-exporter docker image"
     echo "Finished generation of osm/kafka-exporter docker image"
-    sudo mkdir -p /etc/osm/docker/osm_metrics
-    sudo cp -b ${OSM_DEVOPS}/installers/docker/osm_metrics/*.yml /etc/osm/docker/osm_metrics
-    sudo cp -b ${OSM_DEVOPS}/installers/docker/osm_metrics/*.json /etc/osm/docker/osm_metrics
+    $WORKDIR_SUDO mkdir -p $OSM_DOCKER_WORK_DIR/osm_metrics
+    $WORKDIR_SUDO cp -b ${OSM_DEVOPS}/installers/docker/osm_metrics/*.yml $OSM_DOCKER_WORK_DIR/osm_metrics
+    $WORKDIR_SUDO cp -b ${OSM_DEVOPS}/installers/docker/osm_metrics/*.json $OSM_DOCKER_WORK_DIR/osm_metrics
     remove_stack osm_metrics
     echo "Deploying PM stack (Kafka exporter + Prometheus + Grafana)"
-    sg docker -c "docker stack deploy -c /etc/osm/docker/osm_metrics/docker-compose.yml osm_metrics"
+    sg docker -c "OSM_NETWORK=net${OSM_STACK_NAME} docker stack deploy -c $OSM_DOCKER_WORK_DIR/osm_metrics/docker-compose.yml osm_metrics"
     echo "Finished deployment of PM stack"
     return 0
 }
 
 function install_lightweight() {
+    OSM_DOCKER_WORK_DIR="$OSM_WORK_DIR/stack/$OSM_STACK_NAME"
+    [ ! -d "$OSM_DOCKER_WORK_DIR" ] && $WORKDIR_SUDO mkdir -p $OSM_DOCKER_WORK_DIR
+
     [ "$USER" == "root" ] && FATAL "You are running the installer as root. The installer is prepared to be executed as a normal user with sudo privileges."
     [ -z "$ASSUME_YES" ] && ! ask_user "The installation will configure LXD, install juju, install docker CE and init a docker swarm, as pre-requirements. Do you want to proceed (Y/n)? " y && echo "Cancelled!" && exit 1
     track proceed
@@ -762,7 +848,9 @@ function install_lightweight() {
     DEFAULT_IP=`ip -o -4 a |grep ${DEFAULT_IF}|awk '{split($4,a,"/"); print a[1]}'`
     [ -z "$DEFAULT_IP" ] && FATAL "Not possible to determine the IP address of the interface with the default route"
     DEFAULT_MTU=$(ip addr show ${DEFAULT_IF} | perl -ne 'if (/mtu\s(\d+)/) {print $1;}')
-    if [ -z "$INSTALL_NOLXD" ]; then
+
+    # if no host is passed in, we need to install lxd/juju, unless explicilty asked not to
+    if [ -z "$OSMLCM_VCA_HOST" ] && [ -z "$INSTALL_NOLXD" ]; then
         need_packages_lw="lxd"
         echo -e "Checking required packages: $need_packages_lw"
         dpkg -l $need_packages_lw &>/dev/null \
@@ -775,25 +863,38 @@ function install_lightweight() {
           || FATAL "failed to install $need_packages_lw"
     fi
     track prereqok
-    install_juju
-    OSMLCM_VCA_HOST=`sg lxd -c "juju show-controller"|grep api-endpoints|awk -F\' '{print $2}'|awk -F\: '{print $1}'`
-    OSMLCM_VCA_SECRET=`grep password ${HOME}/.local/share/juju/accounts.yaml |awk '{print $2}'`
-    [ -z "$OSMLCM_VCA_HOST" ] && FATAL "Cannot obtain juju controller IP address"
-    [ -z "$OSMLCM_VCA_SECRET" ] && FATAL "Cannot obtain juju secret"
+    [ -z "$INSTALL_NOJUJU" ] && install_juju
+
+    if [ -z "$OSMLCM_VCA_HOST" ]; then
+        juju_createcontroller
+        OSMLCM_VCA_HOST=`sg lxd -c "juju show-controller $OSM_STACK_NAME"|grep api-endpoints|awk -F\' '{print $2}'|awk -F\: '{print $1}'`
+        [ -z "$OSMLCM_VCA_HOST" ] && FATAL "Cannot obtain juju controller IP address"
+    fi
+    if [ -z "$OSMLCM_VCA_SECRET" ]; then
+        OSMLCM_VCA_SECRET=$(parse_juju_password $OSM_STACK_NAME)
+        [ -z "$OSMLCM_VCA_SECRET" ] && FATAL "Cannot obtain juju secret"
+    fi
+
     track juju
     [ -n "$INSTALL_NODOCKER" ] || install_docker_ce
     track docker_ce
     #install_docker_compose
-    generate_docker_images
+    [ -z "$DOCKER_NOBUILD" ] && generate_docker_images
     track docker_build
-    generate_config_log_folders
     generate_docker_env_files
+    generate_config_log_folders
+
+    [ -n "$INSTALL_NODOCKER" ] || init_docker_swarm
+    # remove old stack
+    remove_stack $OSM_STACK_NAME
+    create_docker_network
     deploy_lightweight
+    generate_osmclient_script
     track docker_deploy
     [ -n "$INSTALL_VIMEMU" ] && install_vimemu && track vimemu
     [ -n "$INSTALL_ELK" ] && deploy_elk && track elk
     [ -n "$INSTALL_PERFMON" ] && deploy_perfmon && track perfmon
-    install_osmclient
+    [ -z "$INSTALL_NOHOSTCLIENT" ] && install_osmclient
     track osmclient
     wget -q -O- https://osm-download.etsi.org/ftp/osm-4.0-four/README2.txt &> /dev/null
     track end
@@ -809,19 +910,20 @@ function install_vimemu() {
     git clone https://osm.etsi.org/gerrit/osm/vim-emu.git $EMUTEMPDIR
     # build vim-emu docker
     echo "Building vim-emu Docker container..."
-    sudo docker build -t vim-emu-img -f $EMUTEMPDIR/Dockerfile --no-cache $EMUTEMPDIR/ || FATAL "cannot build vim-emu-img docker image"
+
+    sg docker -c "docker build -t vim-emu-img -f $EMUTEMPDIR/Dockerfile --no-cache $EMUTEMPDIR/" || FATAL "cannot build vim-emu-img docker image"
     # start vim-emu container as daemon
     echo "Starting vim-emu Docker container 'vim-emu' ..."
     if [ -n "$INSTALL_LIGHTWEIGHT" ]; then
         # in lightweight mode, the emulator needs to be attached to netOSM
-        sudo docker run --name vim-emu -t -d --restart always --privileged --pid='host' --network=netOSM -v /var/run/docker.sock:/var/run/docker.sock vim-emu-img python examples/osm_default_daemon_topology_2_pop.py
+        sg docker -c "docker run --name vim-emu -t -d --restart always --privileged --pid='host' --network=net${OSM_STACK_NAME} -v /var/run/docker.sock:/var/run/docker.sock vim-emu-img python examples/osm_default_daemon_topology_2_pop.py"
     else
         # classic build mode
-        sudo docker run --name vim-emu -t -d --restart always --privileged --pid='host' -v /var/run/docker.sock:/var/run/docker.sock vim-emu-img python examples/osm_default_daemon_topology_2_pop.py
+        sg docker -c "docker run --name vim-emu -t -d --restart always --privileged --pid='host' -v /var/run/docker.sock:/var/run/docker.sock vim-emu-img python examples/osm_default_daemon_topology_2_pop.py"
     fi
     echo "Waiting for 'vim-emu' container to start ..."
     sleep 5
-    export VIMEMU_HOSTNAME=$(sudo docker inspect -f '{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' vim-emu)
+    export VIMEMU_HOSTNAME=$(sg docker -c "docker inspect -f '{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' vim-emu")
     echo "vim-emu running at ${VIMEMU_HOSTNAME} ..."
     # print vim-emu connection info
     echo -e "\nYou might be interested in adding the following vim-emu env variables to your .bashrc file:"
@@ -884,8 +986,8 @@ SHOWOPTS=""
 COMMIT_ID=""
 ASSUME_YES=""
 INSTALL_FROM_SOURCE=""
-RELEASE="-R ReleaseFOUR"
-REPOSITORY="-r stable"
+RELEASE="ReleaseFOUR"
+REPOSITORY="stable"
 INSTALL_VIMEMU=""
 INSTALL_FROM_LXDIMAGES=""
 LXD_REPOSITORY_BASE="https://osm-download.etsi.org/repository/osm/lxd"
@@ -897,12 +999,22 @@ INSTALL_PERFMON=""
 TO_REBUILD=""
 INSTALL_NOLXD=""
 INSTALL_NODOCKER=""
+INSTALL_NOJUJU=""
 NOCONFIGURE=""
 RELEASE_DAILY=""
 SESSION_ID=`date +%s`
 OSM_DEVOPS=
-
-while getopts ":hy-:b:r:k:u:R:l:p:D:o:m:" o; do
+OSMLCM_VCA_HOST=
+OSMLCM_VCA_SECRET=
+OSM_STACK_NAME=osm
+NO_HOST_PORTS=""
+DOCKER_NOBUILD=""
+REPOSITORY_KEY="OSM%20ETSI%20Release%20Key.gpg"
+REPOSITORY_BASE="http://osm-download.etsi.org/repository/osm/debian"
+WORKDIR_SUDO=sudo
+OSM_WORK_DIR="/etc/osm"
+
+while getopts ":hy-:b:r:k:u:R:l:p:D:o:m:H:S:s:w:" o; do
     case "${o}" in
         h)
             usage && exit 0
@@ -911,16 +1023,20 @@ while getopts ":hy-:b:r:k:u:R:l:p:D:o:m:" o; do
             COMMIT_ID=${OPTARG}
             ;;
         r)
-            REPOSITORY="-r ${OPTARG}"
+            REPOSITORY="${OPTARG}"
+            REPO_ARGS+=(-r "$REPOSITORY")
             ;;
         R)
-            RELEASE="-R ${OPTARG}"
+            RELEASE="${OPTARG}"
+            REPO_ARGS+=(-R "$RELEASE")
             ;;
         k)
-            REPOSITORY_KEY="-k ${OPTARG}"
+            REPOSITORY_KEY="${OPTARG}"
+            REPO_ARGS+=(-k "$REPOSITORY_KEY")
             ;;
         u)
-            REPOSITORY_BASE="-u ${OPTARG}"
+            REPOSITORY_BASE="${OPTARG}"
+            REPO_ARGS+=(-u "$REPOSITORY_BASE")
             ;;
         l)
             LXD_REPOSITORY_BASE="${OPTARG}"
@@ -931,6 +1047,20 @@ while getopts ":hy-:b:r:k:u:R:l:p:D:o:m:" o; do
         D)
             OSM_DEVOPS="${OPTARG}"
             ;;
+        s)
+            OSM_STACK_NAME="${OPTARG}"
+            ;;
+        H)
+            OSMLCM_VCA_HOST="${OPTARG}"
+            ;;
+        S)
+            OSMLCM_VCA_SECRET="${OPTARG}"
+            ;;
+        w)
+            # when specifying workdir, do not use sudo for access
+            WORKDIR_SUDO=
+            OSM_WORK_DIR="${OPTARG}"
+            ;;
         o)
             INSTALL_ONLY="y"
             [ "${OPTARG}" == "vimemu" ] && INSTALL_VIMEMU="y" && continue
@@ -968,6 +1098,10 @@ while getopts ":hy-:b:r:k:u:R:l:p:D:o:m:" o; do
             [ "${OPTARG}" == "noconfigure" ] && NOCONFIGURE="y" && continue
             [ "${OPTARG}" == "showopts" ] && SHOWOPTS="y" && continue
             [ "${OPTARG}" == "daily" ] && RELEASE_DAILY="y" && continue
+            [ "${OPTARG}" == "nohostports" ] && NO_HOST_PORTS="y" && continue
+            [ "${OPTARG}" == "nojuju" ] && INSTALL_NOJUJU="y" && continue
+            [ "${OPTARG}" == "nodockerbuild" ] && DOCKER_NOBUILD="y" && continue
+            [ "${OPTARG}" == "nohostclient" ] && INSTALL_NOHOSTCLIENT="y" && continue
             echo -e "Invalid option: '--$OPTARG'\n" >&2
             usage && exit 1
             ;;
@@ -1085,14 +1219,14 @@ elif [ -n "$INSTALL_FROM_LXDIMAGES" ]; then #install from LXD images stored in O
     install_from_lxdimages
 else #install from binaries
     echo -e "\nCreating the containers and installing from binaries ..."
-    $OSM_DEVOPS/jenkins/host/install RO $REPOSITORY $RELEASE $REPOSITORY_KEY $REPOSITORY_BASE || FATAL "RO install failed"
+    $OSM_DEVOPS/jenkins/host/install RO ${REPO_ARGS[@]} || FATAL "RO install failed"
     ro_is_up && track RO
     $OSM_DEVOPS/jenkins/host/start_build VCA || FATAL "VCA install failed"
     vca_is_up && track VCA
     $OSM_DEVOPS/jenkins/host/install MON || FATAL "MON build failed"
     mon_is_up && track MON
-    $OSM_DEVOPS/jenkins/host/install SO $REPOSITORY $RELEASE $REPOSITORY_KEY $REPOSITORY_BASE || FATAL "SO install failed"
-    $OSM_DEVOPS/jenkins/host/install UI $REPOSITORY $RELEASE $REPOSITORY_KEY $REPOSITORY_BASE || FATAL "UI install failed"
+    $OSM_DEVOPS/jenkins/host/install SO ${REPO_ARGS[@]} || FATAL "SO install failed"
+    $OSM_DEVOPS/jenkins/host/install UI ${REPO_ARGS[@]} || FATAL "UI install failed"
     #so_is_up && track SOUI
     track SOUI
 fi
index 2e2bf08..44b8d76 100644 (file)
@@ -40,6 +40,14 @@ properties([
     ])
 ])
 
+def uninstall_osm(stackName) {
+    sh """
+         export OSM_USE_LOCAL_DEVOPS=true
+         export PATH=$PATH:/snap/bin
+         installers/full_install_osm.sh -y -s ${stackName} --test --nolxd --nodocker --nojuju --nohostports --nohostclient --uninstall
+       """
+}
+
 node("${params.NODE}") {
 
     sh 'env'
@@ -179,8 +187,8 @@ node("${params.NODE}") {
                 }
          
                 sh """
-                    export OSM_USE_LOCAL_DEVOPS=true
-                    jenkins/host/start_build system --build-container ${container_name} \
+                    export PATH=$PATH:/snap/bin
+                    installers/full_install_osm.sh -y -s ${container_name} --test --nolxd --nodocker --nojuju --nohostports --nohostclient \
                                                     ${commit_id} \
                                                     ${repo_distro} \
                                                     ${repo_base_url} \
@@ -234,17 +242,18 @@ node("${params.NODE}") {
     }
     finally {
         sh "docker stop ${http_server_name}"
+        sh "docker rm ${http_server_name}"
 
         if ( params.DO_INSTALL ) {
             if (error) {
                 if ( !params.SAVE_CONTAINER_ON_FAIL ) {
-                    sh "lxc delete ${container_name} --force"
+                    uninstall_osm container_name
                 }
                 throw error 
             }
             else {
                 if ( !params.SAVE_CONTAINER_ON_PASS ) {
-                    sh "lxc delete ${container_name} --force"
+                    uninstall_osm container_name
                 }
             }
         }