Skip to content
install_osm.sh 37.8 KiB
Newer Older
#!/bin/bash
#   Copyright 2016 Telefónica Investigación y Desarrollo S.A.U.
#
#   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.

function usage(){
    echo -e "usage: $0 [OPTIONS]"
    echo -e "Install OSM from binaries or source code (by default, from binaries)"
    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 "     -r <repo>:      use specified repository name for osm packages"
    echo -e "     -R <release>:   use specified release for osm binaries (deb packages, lxd images, ...)"
    echo -e "     -u <repo base>: use specified repository url for osm packages"
    echo -e "     -k <repo key>:  use specified repository public key url"
    echo -e "     -b <refspec>:   install OSM from source code using a specific branch (master, v2.0, ...) or tag"
    echo -e "                     -b master          (main dev branch)"
    echo -e "                     -b v2.0            (v2.0 branch)"
    echo -e "                     -b tags/v1.1.0     (a specific tag)"
    echo -e "                     ..."
    echo -e "     --lxdimages:    download lxd images from OSM repository instead of creating them from scratch"
    echo -e "     -l <lxd_repo>:  use specified repository url for lxd images"
    echo -e "     -p <path>:      use specified repository path for lxd images"
    echo -e "     --lightweight:  install lightweight build of OSM"
    echo -e "     --vimemu:       additionally fetch, build, and deploy the VIM emulator as a docker container"
    echo -e "     --develop:      (deprecated, use '-b master') install OSM from source code using the master branch"
#    echo -e "     --reconfigure:  reconfigure the modules (DO NOT change NAT rules)"
    echo -e "     --nat:          install only NAT rules"
    echo -e "     --noconfigure:  DO NOT install osmclient, DO NOT install NAT rules, DO NOT configure modules"
#    echo -e "     --update:       update to the latest stable release or to the latest commit if using a specific branch"
    echo -e "     --showopts:     print chosen options and exit (only for debugging)"
    echo -e "     -y:             do not prompt for confirmation, assumes yes"
    echo -e "     -D <devops path> use local devops installation path"
    echo -e "     -h / --help:    print this help"
#Uninstall OSM: remove containers
function uninstall(){
    if [ $RC_CLONE ] || [ -n "$TEST_INSTALLER" ]; then
        $OSM_DEVOPS/jenkins/host/clean_container RO
        $OSM_DEVOPS/jenkins/host/clean_container VCA
        $OSM_DEVOPS/jenkins/host/clean_container MON
        $OSM_DEVOPS/jenkins/host/clean_container SO
        #$OSM_DEVOPS/jenkins/host/clean_container UI
    else
        lxc stop RO && lxc delete RO
        lxc stop VCA && lxc delete VCA
        lxc stop MON && lxc delete MON
    echo -e "\nDeleting imported lxd images if they exist"
    lxc image show osm-ro &>/dev/null && lxc image delete osm-ro
    lxc image show osm-vca &>/dev/null && lxc image delete osm-vca
    lxc image show osm-soui &>/dev/null && lxc image delete osm-soui
#Uninstall lightweight OSM: remove dockers
function uninstall_lightweight(){
    echo -e "\nUninstalling lightweight OSM"
    docker stack rm osm
    COUNTER=0
    result=11
    while [ ${COUNTER} -lt 30 ]; do
        sleep 1
        result=$(docker stack ps osm | wc -l)
        #echo "Dockers running: $result"
        if [ "${result}" == "0" ]; then
            break
        fi
        let COUNTER=COUNTER+1
    done
    if [ "${result}" == "0" ]; then
        echo "All dockers of the stack osm were removed"
    else
        FATAL "Some dockers of the stack osm could not be removed. Could not uninstall OSM in single shot. Try to uninstall again"
    fi
    sleep 5
    docker image rm osm/ro
    docker image rm osm/lcm
    docker image rm osm/light-ui
    docker image rm osm/nbi
    docker image rm osm/mon
    docker image rm osm/pm
    return 0
}

#Configure NAT rules, based on the current IP addresses of containers
function nat(){
    echo -e "\nChecking required packages: iptables-persistent"
    dpkg -l iptables-persistent &>/dev/null || ! echo -e "    Not installed.\nInstalling iptables-persistent requires root privileges" || \
    sudo DEBIAN_FRONTEND=noninteractive apt-get -yq install iptables-persistent
    echo -e "\nConfiguring NAT rules"
    echo -e "   Required root privileges"
    sudo $OSM_DEVOPS/installers/nat_osm
}

function FATAL(){
    echo "FATAL error: Cannot install OSM due to \"$1\""
    exit 1
}

#Update RO, SO and UI:
function update(){
    echo -e "\nUpdating components"

    echo -e "     Updating RO"
    CONTAINER="RO"
    MDG="RO"
    INSTALL_FOLDER="/opt/openmano"
    echo -e "     Fetching the repo"
    lxc exec $CONTAINER -- git -C $INSTALL_FOLDER fetch --all
    BRANCH=""
    BRANCH=`lxc exec $CONTAINER -- git -C $INSTALL_FOLDER status -sb | head -n1 | sed -n 's/^## \(.*\).*/\1/p'|awk '{print $1}' |sed 's/\(.*\)\.\.\..*/\1/'`
Jokin Garay's avatar
Jokin Garay committed
    [ -z "$BRANCH" ] && FATAL "Could not find the current branch in use in the '$MDG'"
    CURRENT=`lxc exec $CONTAINER -- git -C $INSTALL_FOLDER status |head -n1`
    CURRENT_COMMIT_ID=`lxc exec $CONTAINER -- git -C $INSTALL_FOLDER rev-parse HEAD`
    echo "         FROM: $CURRENT ($CURRENT_COMMIT_ID)"
    # COMMIT_ID either was  previously set with -b option, or is an empty string
    CHECKOUT_ID=$COMMIT_ID
    [ -z "$CHECKOUT_ID" ] && [ "$BRANCH" == "HEAD" ] && CHECKOUT_ID="tags/$LATEST_STABLE_DEVOPS"
    [ -z "$CHECKOUT_ID" ] && [ "$BRANCH" != "HEAD" ] && CHECKOUT_ID="$BRANCH"
    if [[ $CHECKOUT_ID == "tags/"* ]]; then
        REMOTE_COMMIT_ID=`lxc exec $CONTAINER -- git -C $INSTALL_FOLDER rev-list -n 1 $CHECKOUT_ID`
    else
        REMOTE_COMMIT_ID=`lxc exec $CONTAINER -- git -C $INSTALL_FOLDER rev-parse origin/$CHECKOUT_ID`
    fi
    echo "         TO: $CHECKOUT_ID ($REMOTE_COMMIT_ID)"
    if [ "$CURRENT_COMMIT_ID" == "$REMOTE_COMMIT_ID" ]; then
        echo "         Nothing to be done."
    else
        echo "         Update required."
        lxc exec $CONTAINER -- service osm-ro stop
        lxc exec $CONTAINER -- git -C /opt/openmano stash
        lxc exec $CONTAINER -- git -C /opt/openmano pull --rebase
        lxc exec $CONTAINER -- git -C /opt/openmano checkout $CHECKOUT_ID
        lxc exec $CONTAINER -- git -C /opt/openmano stash pop
        lxc exec $CONTAINER -- /opt/openmano/database_utils/migrate_mano_db.sh
        lxc exec $CONTAINER -- service osm-ro start
    fi
    echo

    echo -e "     Updating SO and UI"
    CONTAINER="SO-ub"
    MDG="SO"
    INSTALL_FOLDER=""   # To be filled in
    echo -e "     Fetching the repo"
    lxc exec $CONTAINER -- git -C $INSTALL_FOLDER fetch --all
    BRANCH=""
    BRANCH=`lxc exec $CONTAINER -- git -C $INSTALL_FOLDER status -sb | head -n1 | sed -n 's/^## \(.*\).*/\1/p'|awk '{print $1}' |sed 's/\(.*\)\.\.\..*/\1/'`
Jokin Garay's avatar
Jokin Garay committed
    [ -z "$BRANCH" ] && FATAL "Could not find the current branch in use in the '$MDG'"
    CURRENT=`lxc exec $CONTAINER -- git -C $INSTALL_FOLDER status |head -n1`
    CURRENT_COMMIT_ID=`lxc exec $CONTAINER -- git -C $INSTALL_FOLDER rev-parse HEAD`
    echo "         FROM: $CURRENT ($CURRENT_COMMIT_ID)"
    # COMMIT_ID either was  previously set with -b option, or is an empty string
    CHECKOUT_ID=$COMMIT_ID
    [ -z "$CHECKOUT_ID" ] && [ "$BRANCH" == "HEAD" ] && CHECKOUT_ID="tags/$LATEST_STABLE_DEVOPS"
    [ -z "$CHECKOUT_ID" ] && [ "$BRANCH" != "HEAD" ] && CHECKOUT_ID="$BRANCH"
    if [[ $CHECKOUT_ID == "tags/"* ]]; then
        REMOTE_COMMIT_ID=`lxc exec $CONTAINER -- git -C $INSTALL_FOLDER rev-list -n 1 $CHECKOUT_ID`
    else
        REMOTE_COMMIT_ID=`lxc exec $CONTAINER -- git -C $INSTALL_FOLDER rev-parse origin/$CHECKOUT_ID`
    fi
    echo "         TO: $CHECKOUT_ID ($REMOTE_COMMIT_ID)"
    if [ "$CURRENT_COMMIT_ID" == "$REMOTE_COMMIT_ID" ]; then
        echo "         Nothing to be done."
    else
        echo "         Update required."
        # Instructions to be added
        # lxc exec SO-ub -- ...
    fi
    echo
    echo -e "Updating MON Container"
    CONTAINER="MON"
    MDG="MON"
    INSTALL_FOLDER="/root/MON"
    echo -e "     Fetching the repo"
    lxc exec $CONTAINER -- git -C $INSTALL_FOLDER fetch --all
    BRANCH=""
    BRANCH=`lxc exec $CONTAINER -- git -C $INSTALL_FOLDER status -sb | head -n1 | sed -n 's/^## \(.*\).*/\1/p'|awk '{print $1}' |sed 's/\(.*\)\.\.\..*/\1/'`
    [ -z "$BRANCH" ] && FATAL "Could not find the current branch in use in the '$MDG'"
    CURRENT=`lxc exec $CONTAINER -- git -C $INSTALL_FOLDER status |head -n1`
    CURRENT_COMMIT_ID=`lxc exec $CONTAINER -- git -C $INSTALL_FOLDER rev-parse HEAD`
    echo "         FROM: $CURRENT ($CURRENT_COMMIT_ID)"
    # COMMIT_ID either was  previously set with -b option, or is an empty string
    CHECKOUT_ID=$COMMIT_ID
    [ -z "$CHECKOUT_ID" ] && [ "$BRANCH" == "HEAD" ] && CHECKOUT_ID="tags/$LATEST_STABLE_DEVOPS"
    [ -z "$CHECKOUT_ID" ] && [ "$BRANCH" != "HEAD" ] && CHECKOUT_ID="$BRANCH"
    if [[ $CHECKOUT_ID == "tags/"* ]]; then
        REMOTE_COMMIT_ID=`lxc exec $CONTAINER -- git -C $INSTALL_FOLDER rev-list -n 1 $CHECKOUT_ID`
    else
        REMOTE_COMMIT_ID=`lxc exec $CONTAINER -- git -C $INSTALL_FOLDER rev-parse origin/$CHECKOUT_ID`
    fi
    echo "         TO: $CHECKOUT_ID ($REMOTE_COMMIT_ID)"
    if [ "$CURRENT_COMMIT_ID" == "$REMOTE_COMMIT_ID" ]; then
        echo "         Nothing to be done."
    else
        echo "         Update required."
    fi
    echo
function so_is_up() {
    if [ -n "$1" ]; then
        SO_IP=$1
    else
        SO_IP=`lxc list SO-ub -c 4|grep eth0 |awk '{print $2}'`
    fi
Mike Marchetti's avatar
Mike Marchetti committed
    time=0
    step=5
    timelength=300
    while [ $time -le $timelength ]
    do
        if [[ `curl -k -X GET   https://$SO_IP:8008/api/operational/vcs/info \
                -H 'accept: application/vnd.yang.data+json' \
                -H 'authorization: Basic YWRtaW46YWRtaW4=' \
                -H 'cache-control: no-cache' 2> /dev/null | jq  '.[].components.component_info[] | select(.component_name=="RW.Restconf")' 2>/dev/null | grep "RUNNING" | wc -l` -eq 1 ]]
        then
            echo "RW.Restconf running....SO is up"
            return 0
Mike Marchetti's avatar
Mike Marchetti committed
        sleep $step
        echo -n "."
        time=$((time+step))
    done
    FATAL "OSM Failed to startup. SO failed to startup"
}

function vca_is_up() {
    if [[ `lxc exec VCA -- juju status | grep "osm" | wc -l` -eq 1 ]]; then
            echo "VCA is up and running"
            return 0
    fi

    FATAL "OSM Failed to startup. VCA failed to startup"
}

function mon_is_up() {
    if [[ `curl http://$RO_IP:9090/openmano/ | grep "works" | wc -l` -eq 1 ]]; then
            echo "MON is up and running"
            return 0
    fi

    FATAL "OSM Failed to startup. MON failed to startup"
}

function ro_is_up() {
    if [ -n "$1" ]; then
        RO_IP=$1
    else
        RO_IP=`lxc list RO -c 4|grep eth0 |awk '{print $2}'`
    fi
    time=0
    step=2
    timelength=20
    while [ $time -le $timelength ]; do
        if [[ `curl http://$RO_IP:9090/openmano/ | grep "works" | wc -l` -eq 1 ]]; then
            echo "RO is up and running"
            return 0
        fi
        sleep $step
        echo -n "."
        time=$((time+step))
    done

    FATAL "OSM Failed to startup. RO failed to startup"
function configure_RO(){
    . $OSM_DEVOPS/installers/export_ips
    lxc exec RO -- sed -i -e "s/^\#\?log_socket_host:.*/log_socket_host: $SO_CONTAINER_IP/g" /etc/osm/openmanod.cfg
    lxc exec RO -- service osm-ro restart
    ro_is_up
    lxc exec RO -- openmano tenant-delete -f osm >/dev/null
    lxc exec RO -- openmano tenant-create osm > /dev/null
    lxc exec RO -- sed -i '/export OPENMANO_TENANT=osm/d' .bashrc
    lxc exec RO -- sed -i '$ i export OPENMANO_TENANT=osm' .bashrc
    lxc exec RO -- sh -c 'echo "export OPENMANO_TENANT=osm" >> .bashrc'
function configure_VCA(){
    echo -e "       Configuring VCA"
    JUJU_PASSWD=`date +%s | sha256sum | base64 | head -c 32`
    echo -e "$JUJU_PASSWD\n$JUJU_PASSWD" | lxc exec VCA -- juju change-user-password
}

function configure_SOUI(){
    . $OSM_DEVOPS/installers/export_ips
    JUJU_CONTROLLER_IP=`lxc exec VCA -- lxc list -c 4 |grep eth0 |awk '{print $2}'`
    RO_TENANT_ID=`lxc exec RO -- openmano tenant-list osm |awk '{print $1}'`
    echo -e " Configuring MON"
    #Information to be added about SO socket for logging

    echo -e "       Configuring SO"
    sudo route add -host $JUJU_CONTROLLER_IP gw $VCA_CONTAINER_IP
    sudo sed -i "$ i route add -host $JUJU_CONTROLLER_IP gw $VCA_CONTAINER_IP" /etc/rc.local
Jeremy Mordkoff's avatar
Jeremy Mordkoff committed
    # make journaling persistent
    lxc exec SO-ub -- mkdir -p /var/log/journal
    lxc exec SO-ub -- systemd-tmpfiles --create --prefix /var/log/journal
    lxc exec SO-ub -- systemctl restart systemd-journald

    echo RIFT_EXTERNAL_ADDRESS=$DEFAULT_IP | lxc exec SO-ub -- tee -a /usr/rift/etc/default/launchpad

Mike Marchetti's avatar
Mike Marchetti committed
    lxc exec SO-ub -- systemctl restart launchpad
Mike Marchetti's avatar
Mike Marchetti committed
    so_is_up $SO_CONTAINER_IP

    #delete existing config agent (could be there on reconfigure)
    curl -k --request DELETE \
      --url https://$SO_CONTAINER_IP:8008/api/config/config-agent/account/osmjuju \
      --header 'accept: application/vnd.yang.data+json' \
      --header 'authorization: Basic YWRtaW46YWRtaW4=' \
      --header 'cache-control: no-cache' \
      --header 'content-type: application/vnd.yang.data+json' &> /dev/null

    result=$(curl -k --request POST \
      --url https://$SO_CONTAINER_IP:8008/api/config/config-agent \
      --header 'accept: application/vnd.yang.data+json' \
      --header 'authorization: Basic YWRtaW46YWRtaW4=' \
      --header 'cache-control: no-cache' \
      --header 'content-type: application/vnd.yang.data+json' \
Mike Marchetti's avatar
Mike Marchetti committed
      --data '{"account": [ { "name": "osmjuju", "account-type": "juju", "juju": { "ip-address": "'$JUJU_CONTROLLER_IP'", "port": "17070", "user": "admin", "secret": "'$JUJU_PASSWD'" }  }  ]}')
    [[ $result =~ .*success.* ]] || FATAL "Failed config-agent configuration: $result"
    #R1/R2 config line
    #result=$(curl -k --request PUT \
    #  --url https://$SO_CONTAINER_IP:8008/api/config/resource-orchestrator \
    #  --header 'accept: application/vnd.yang.data+json' \
    #  --header 'authorization: Basic YWRtaW46YWRtaW4=' \
    #  --header 'cache-control: no-cache' \
    #  --header 'content-type: application/vnd.yang.data+json' \
    #  --data '{ "openmano": { "host": "'$RO_CONTAINER_IP'", "port": "9090", "tenant-id": "'$RO_TENANT_ID'" }, "name": "osmopenmano", "account-type": "openmano" }')

Mike Marchetti's avatar
Mike Marchetti committed
    result=$(curl -k --request PUT \
      --url https://$SO_CONTAINER_IP:8008/api/config/project/default/ro-account/account \
      --header 'accept: application/vnd.yang.data+json' \
      --header 'authorization: Basic YWRtaW46YWRtaW4=' \
      --header 'cache-control: no-cache'   \
      --header 'content-type: application/vnd.yang.data+json' \
      --data '{"rw-ro-account:account": [ { "openmano": { "host": "'$RO_CONTAINER_IP'", "port": "9090", "tenant-id": "'$RO_TENANT_ID'"}, "name": "osmopenmano", "ro-account-type": "openmano" }]}')
Mike Marchetti's avatar
Mike Marchetti committed
    [[ $result =~ .*success.* ]] || FATAL "Failed resource-orchestrator configuration: $result"
    result=$(curl -k --request PATCH \
      --url https://$SO_CONTAINER_IP:8008/v2/api/config/openidc-provider-config/rw-ui-client/redirect-uri \
      --header 'accept: application/vnd.yang.data+json' \
      --header 'authorization: Basic YWRtaW46YWRtaW4=' \
      --header 'cache-control: no-cache'   \
      --header 'content-type: application/vnd.yang.data+json' \
      --data '{"redirect-uri": "https://'$DEFAULT_IP':8443/callback" }')
    [[ $result =~ .*success.* ]] || FATAL "Failed redirect-uri configuration: $result"

    result=$(curl -k --request PATCH \
      --url https://$SO_CONTAINER_IP:8008/v2/api/config/openidc-provider-config/rw-ui-client/post-logout-redirect-uri \
      --header 'accept: application/vnd.yang.data+json' \
      --header 'authorization: Basic YWRtaW46YWRtaW4=' \
      --header 'cache-control: no-cache'   \
      --header 'content-type: application/vnd.yang.data+json' \
      --data '{"post-logout-redirect-uri": "https://'$DEFAULT_IP':8443/?api_server=https://'$DEFAULT_IP'" }')
    [[ $result =~ .*success.* ]] || FATAL "Failed post-logout-redirect-uri configuration: $result"

    lxc exec SO-ub -- tee /etc/network/interfaces.d/60-rift.cfg <<EOF
auto lo:1
iface lo:1 inet static
        address  $DEFAULT_IP
        netmask 255.255.255.255
EOF
    lxc exec SO-ub ifup lo:1
#Configure RO, VCA, and SO with the initial configuration:
#  RO -> tenant:osm, logs to be sent to SO
#  VCA -> juju-password
#  SO -> route to Juju Controller, add RO account, add VCA account
function configure(){
    #Configure components
    echo -e "\nConfiguring components"
    configure_RO
    configure_VCA
    configure_SOUI
    sudo apt-get update
    sudo apt-get install -y lxd
    newgrp lxd
    lxc network create lxdbr0 ipv4.address=auto ipv4.nat=true ipv6.address=none ipv6.nat=false
    DEFAULT_INTERFACE=$(route -n | awk '$1~/^0.0.0.0/ {print $8}')
    DEFAULT_MTU=$(ip addr show $DEFAULT_INTERFACE | perl -ne 'if (/mtu\s(\d+)/) {print $1;}')
    lxc profile device set default eth0 mtu $DEFAULT_MTU
    #sudo systemctl stop lxd-bridge
    #sudo systemctl --system daemon-reload
    #sudo systemctl enable lxd-bridge
    #sudo systemctl start lxd-bridge
function ask_user(){
    # ask to the user and parse a response among 'y', 'yes', 'n' or 'no'. Case insensitive
    # Params: $1 text to ask;   $2 Action by default, can be 'y' for yes, 'n' for no, other or empty for not allowed
    # Return: true(0) if user type 'yes'; false (1) if user type 'no'
    read -e -p "$1" USER_CONFIRMATION
    while true ; do
        [ -z "$USER_CONFIRMATION" ] && [ "$2" == 'y' ] && return 0
        [ -z "$USER_CONFIRMATION" ] && [ "$2" == 'n' ] && return 1
        [ "${USER_CONFIRMATION,,}" == "yes" ] || [ "${USER_CONFIRMATION,,}" == "y" ] && return 0
        [ "${USER_CONFIRMATION,,}" == "no" ]  || [ "${USER_CONFIRMATION,,}" == "n" ] && return 1
        read -e -p "Please type 'yes' or 'no': " USER_CONFIRMATION
    done
}
function launch_container_from_lxd(){
    export OSM_MDG=$1
    OSM_load_config
    export OSM_BASE_IMAGE=$2
    if ! container_exists $OSM_BUILD_CONTAINER; then
        CONTAINER_OPTS=""
        [[ "$OSM_BUILD_CONTAINER_PRIVILEGED" == yes ]] && CONTAINER_OPTS="$CONTAINER_OPTS -c security.privileged=true"
        [[ "$OSM_BUILD_CONTAINER_ALLOW_NESTED" == yes ]] && CONTAINER_OPTS="$CONTAINER_OPTS -c security.nesting=true"
        create_container $OSM_BASE_IMAGE $OSM_BUILD_CONTAINER $CONTAINER_OPTS
        wait_container_up $OSM_BUILD_CONTAINER
    fi
}

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 -
    sudo add-apt-repository -y "deb [arch=amd64] $CLIENT_REPOSITORY_BASE/$CLIENT_RELEASE $CLIENT_REPOSITORY osmclient"
    sudo apt-get update
    sudo apt-get install -y python-pip
    sudo -H pip install pip==9.0.3
    sudo -H pip install python-magic
    sudo apt-get install -y python-osmclient
    #sed 's,OSM_SOL005=[^$]*,OSM_SOL005=True,' -i ${HOME}/.bashrc
    #echo 'export OSM_HOSTNAME=localhost' >> ${HOME}/.bashrc
    #echo 'export OSM_SOL005=True' >> ${HOME}/.bashrc
    [ -z "$INSTALL_LIGHTWEIGHT" ] && export OSM_HOSTNAME=`lxc list | awk '($2=="SO-ub"){print $6}'`
    [ -z "$INSTALL_LIGHTWEIGHT" ] && export OSM_RO_HOSTNAME=`lxc list | awk '($2=="RO"){print $6}'`
    [ -n "$INSTALL_LIGHTWEIGHT" ] && export OSM_HOSTNAME=localhost
    echo -e "\nOSM client installed"
    echo -e "You might be interested in adding the following OSM client env variables to your .bashrc file:"
    echo "     export OSM_HOSTNAME=${OSM_HOSTNAME}"
    [ -n "$INSTALL_LIGHTWEIGHT" ] && echo "     export OSM_SOL005=True"
    [ -z "$INSTALL_LIGHTWEIGHT" ] && echo "     export OSM_RO_HOSTNAME=${OSM_RO_HOSTNAME}"
    return 0
}

function install_from_lxdimages(){
    LXD_RELEASE=${RELEASE#"-R "}
    if [ -n "$LXD_REPOSITORY_PATH" ]; then
        LXD_IMAGE_DIR="$LXD_REPOSITORY_PATH"
    else
        LXD_IMAGE_DIR="$(mktemp -d -q --tmpdir "osmimages.XXXXXX")"
        trap 'rm -rf "$LXD_IMAGE_DIR"' EXIT
    fi
    echo -e "\nDeleting previous lxd images if they exist"
    lxc image show osm-ro &>/dev/null && lxc image delete osm-ro
    lxc image show osm-vca &>/dev/null && lxc image delete osm-vca
    lxc image show osm-soui &>/dev/null && lxc image delete osm-soui
    echo -e "\nImporting osm-ro"
    [ -z "$LXD_REPOSITORY_PATH" ] && wget -O $LXD_IMAGE_DIR/osm-ro.tar.gz $LXD_REPOSITORY_BASE/$LXD_RELEASE/osm-ro.tar.gz
    lxc image import $LXD_IMAGE_DIR/osm-ro.tar.gz --alias osm-ro
    rm -f $LXD_IMAGE_DIR/osm-ro.tar.gz
    echo -e "\nImporting osm-vca"
    [ -z "$LXD_REPOSITORY_PATH" ] && wget -O $LXD_IMAGE_DIR/osm-vca.tar.gz $LXD_REPOSITORY_BASE/$LXD_RELEASE/osm-vca.tar.gz
    lxc image import $LXD_IMAGE_DIR/osm-vca.tar.gz --alias osm-vca
    rm -f $LXD_IMAGE_DIR/osm-vca.tar.gz
    echo -e "\nImporting osm-soui"
    [ -z "$LXD_REPOSITORY_PATH" ] && wget -O $LXD_IMAGE_DIR/osm-soui.tar.gz $LXD_REPOSITORY_BASE/$LXD_RELEASE/osm-soui.tar.gz
    lxc image import $LXD_IMAGE_DIR/osm-soui.tar.gz --alias osm-soui
    rm -f $LXD_IMAGE_DIR/osm-soui.tar.gz
    launch_container_from_lxd RO osm-ro
    ro_is_up && track RO
    launch_container_from_lxd VCA osm-vca
    vca_is_up && track VCA
    launch_container_from_lxd MON osm-mon
    mon_is_up && track MON
    launch_container_from_lxd SO osm-soui
    #so_is_up && track SOUI
    track SOUI
}

function install_docker_ce() {
    # installs and configures Docker CE
    echo "Installing Docker CE ..."
    sudo apt-get -qq update
    sudo apt-get install -y apt-transport-https ca-certificates software-properties-common
    curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -
    sudo add-apt-repository "deb [arch=amd64] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable"
    sudo apt-get -qq update
    sudo apt-get install -y docker-ce
    echo "Adding user to group 'docker'"
    sudo groupadd -f docker
    sudo usermod -aG docker $USER
    echo "... Docker CE installation done"
    sleep 2
    sudo service docker restart
    echo "... restarted Docker service"
function install_docker_compose() {
    # installs and configures docker-compose
    echo "Installing Docker Compose ..."
    sudo curl -L https://github.com/docker/compose/releases/download/1.18.0/docker-compose-`uname -s`-`uname -m` -o /usr/local/bin/docker-compose
    sudo chmod +x /usr/local/bin/docker-compose
    echo "... Docker Compose installation done"
}

function install_juju() {
    echo "Installing juju"
    sudo snap install juju --classic
    sudo dpkg-reconfigure -p medium lxd
    juju bootstrap localhost osm
    echo "Finished installation of juju"
}

function generate_docker_images() {
    echo "Pulling and generating docker images"
    newgrp docker << EONG
    docker pull wurstmeister/kafka
    docker pull wurstmeister/zookeeper
    docker pull mongo
    git -C ${LWTEMPDIR} clone https://osm.etsi.org/gerrit/osm/MON
    docker build ${LWTEMPDIR}/MON -f ${LWTEMPDIR}/MON/docker/Dockerfile -t osm/mon || ! echo "cannot build MON docker image" >&2
    docker build ${LWTEMPDIR}/MON/policy_module -f ${LWTEMPDIR}/MON/policy_module/Dockerfile -t osm/pm || ! echo "cannot build PM docker image" >&2
    git -C ${LWTEMPDIR} clone https://osm.etsi.org/gerrit/osm/NBI
    docker build ${LWTEMPDIR}/NBI -f ${LWTEMPDIR}/NBI/Dockerfile.local -t osm/nbi || ! echo "cannot build NBI docker image" >&2
    git -C ${LWTEMPDIR} clone https://osm.etsi.org/gerrit/osm/RO
    docker build ${LWTEMPDIR}/RO -f ${LWTEMPDIR}/RO/docker/Dockerfile-local -t osm/ro || ! echo "cannot build RO docker image" >&2
    docker build ${LWTEMPDIR}/RO/lcm -t osm/lcm || ! echo "cannot build LCM docker image" >&2
    git -C ${LWTEMPDIR} clone https://github.com/superfluidity/osm-light-ui.git
    docker build ${LWTEMPDIR}/osm-light-ui -t osm/light-ui -f ${LWTEMPDIR}/osm-light-ui/code/docker/Dockerfile
EONG
    echo "Finished generation of docker images"
}

function generate_docker_env_files() {
    echo "Generating docker env files"
    OSMLCM_VCA_HOST=`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}'`
    MYSQL_ROOT_PASSWORD=`date +%s | sha256sum | base64 | head -c 32`
    echo "OSMLCM_VCA_HOST=${OSMLCM_VCA_HOST}" |sudo tee ${OSM_DEVOPS}/installers/docker/lcm.env
    echo "OSMLCM_VCA_SECRET=${OSMLCM_VCA_SECRET}" |sudo tee -a ${OSM_DEVOPS}/installers/docker/lcm.env
    echo "MYSQL_ROOT_PASSWORD=${MYSQL_ROOT_PASSWORD}" |sudo tee ${OSM_DEVOPS}/installers/docker/ro-db.env
    echo "RO_DB_ROOT_PASSWORD=${MYSQL_ROOT_PASSWORD}" |sudo tee ${OSM_DEVOPS}/installers/docker/ro.env
    echo "OS_NOTIFIER_URI=http://${DEFAULT_IP}:8662" |sudo tee ${OSM_DEVOPS}/installers/docker/mon.env
    echo "Finished generation of docker env files"
}

function deploy_lightweight() {
    echo "Deploying lightweight build"
    newgrp docker << EONG
    docker swarm init --advertise-addr ${DEFAULT_IP}
    docker network create --driver=overlay --attachable --opt com.docker.network.driver.mtu=${DEFAULT_MTU} netOSM
    docker stack deploy -c ${OSM_DEVOPS}/installers/docker/docker-compose.yaml osm
    #docker-compose -f /usr/share/osm-devops/installers/docker/docker-compose.yaml up -d
EONG
    echo "Finished deployment of lightweight build"
}

function install_lightweight() {
    echo "Installing lightweight build of OSM"
    LWTEMPDIR="$(mktemp -d -q --tmpdir "installosmlight.XXXXXX")"
    trap 'rm -rf "${LWTEMPDIR}"' EXIT
    DEFAULT_IF=`route -n |awk '$1~/^0.0.0.0/ {print $8}'`
    DEFAULT_IP=`ip -o -4 a |grep ${DEFAULT_IF}|awk '{split($4,a,"/"); print a[1]}'`
    DEFAULT_MTU=$(ip addr show ${DEFAULT_IF} | perl -ne 'if (/mtu\s(\d+)/) {print $1;}')
    need_packages_lw="lxd"
    echo -e "Checking required packages: $need_packages_lw"
    dpkg -l $need_packages_lw &>/dev/null \
      || ! echo -e "One or several required packages are not installed. Updating apt cache requires root privileges." \
      || sudo apt-get update \
      || FATAL "failed to run apt-get update"
    dpkg -l $need_packages_lw &>/dev/null \
      || ! echo -e "Installing $need_packages_lw requires root privileges." \
      || sudo apt-get install -y $need_packages_lw \
      || FATAL "failed to install $need_packages_lw"
    install_juju
    install_docker_ce
    generate_docker_images
    generate_docker_env_files
    deploy_lightweight
function install_vimemu() {
    # install Docker
    install_docker_ce
    # clone vim-emu repository (attention: branch is currently master only)
    echo "Cloning vim-emu repository ..."
    git clone https://osm.etsi.org/gerrit/osm/vim-emu.git
    # build vim-emu docker
    echo "Building vim-emu Docker container..."
    sudo docker build -t vim-emu-img -f vim-emu/Dockerfile vim-emu/
    # start vim-emu container as daemon
    echo "Starting vim-emu Docker container 'vim-emu' ..."
    sudo docker run --name vim-emu -t -d --rm --privileged --pid='host' -v /var/run/docker.sock:/var/run/docker.sock vim-emu-img python examples/osm_default_daemon_topology_2_pop.py
    echo "Waiting for 'vim-emu' container to start ..."
    sleep 5
    export VIMEMU_HOSTNAME=$(sudo docker inspect -f '{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' vim-emu)
    echo "vim-emu running at ${VIMEMU_HOSTNAME} ..."
    echo -e "You might be interested in adding the following OSM client env variables to your .bashrc file:"
    echo "     export OSM_HOSTNAME=${OSM_HOSTNAME}"
    echo "     export OSM_RO_HOSTNAME=${OSM_RO_HOSTNAME}"
    echo -e "You might be interested in adding the following vim-emu env variables to your .bashrc file:"
    echo "     export VIMEMU_HOSTNAME=${VIMEMU_HOSTNAME}"
    echo -e "\nTo add the emulated VIM to OSM you should do:"
    echo "     osm vim-create --name emu-vim1 --user username --password password --auth_url http://${VIMEMU_HOSTNAME}:6001/v2.0 --tenant tenantName --account_type openstack"
function dump_vars(){
    echo "DEVELOP=$DEVELOP"
    echo "INSTALL_FROM_SOURCE=$INSTALL_FROM_SOURCE"
    echo "UNINSTALL=$UNINSTALL"
    echo "NAT=$NAT"
    echo "UPDATE=$UPDATE"
    echo "RECONFIGURE=$RECONFIGURE"
    echo "TEST_INSTALLER=$TEST_INSTALLER"
    echo "INSTALL_VIMEMU=$INSTALL_VIMEMU"
    echo "INSTALL_LXD=$INSTALL_LXD"
    echo "INSTALL_FROM_LXDIMAGES=$INSTALL_FROM_LXDIMAGES"
    echo "LXD_REPOSITORY_BASE=$LXD_REPOSITORY_BASE"
    echo "LXD_REPOSITORY_PATH=$LXD_REPOSITORY_PATH"
    echo "INSTALL_LIGHTWEIGHT=$INSTALL_LIGHTWEIGHT"
    echo "RELEASE=$RELEASE"
    echo "REPOSITORY=$REPOSITORY"
    echo "REPOSITORY_BASE=$REPOSITORY_BASE"
    echo "REPOSITORY_KEY=$REPOSITORY_KEY"
    echo "NOCONFIGURE=$NOCONFIGURE"
    echo "SHOWOPTS=$SHOWOPTS"
    echo "Install from specific refspec (-b): $COMMIT_ID"
}

function track(){
    ctime=`date +%s`
    duration=$((ctime - SESSION_ID))
    url="http://www.woopra.com/track/ce?project=osm.etsi.org&cookie=${SESSION_ID}"
    #url="${url}&ce_campaign_name=${CAMPAIGN_NAME}"
    event_name="bin"
    [ -n "$INSTALL_FROM_SOURCE" ] && event_name="src"
    [ -n "$INSTALL_FROM_LXDIMAGES" ] && event_name="lxd"
    event_name="${event_name}_$1"
    url="${url}&event=${event_name}&ce_duration=${duration}"
    wget -q -O /dev/null $url
}

INSTALL_LXD=""
RELEASE="-R ReleaseTHREE"
REPOSITORY="-r stable"
INSTALL_VIMEMU=""
INSTALL_FROM_LXDIMAGES=""
LXD_REPOSITORY_BASE="https://osm-download.etsi.org/repository/osm/lxd"
INSTALL_LIGHTWEIGHT=""
NOCONFIGURE=""
RELEASE_DAILY=""
SESSION_ID=`date +%s`
while getopts ":hy-:b:r:k:u:R:l:p:D:" o; do
        r)
            REPOSITORY="-r ${OPTARG}"
            ;;
        R)
            RELEASE="-R ${OPTARG}"
            ;;
        k)
            REPOSITORY_KEY="-k ${OPTARG}"
            ;;
        u)
            REPOSITORY_BASE="-u ${OPTARG}"
            ;;
        l)
            LXD_REPOSITORY_BASE="${OPTARG}"
            ;;
        p)
            LXD_REPOSITORY_PATH="${OPTARG}"
            ;;
        -)
            [ "${OPTARG}" == "help" ] && usage && exit 0
            [ "${OPTARG}" == "source" ] && INSTALL_FROM_SOURCE="y" && continue
            [ "${OPTARG}" == "develop" ] && DEVELOP="y" && continue
            [ "${OPTARG}" == "uninstall" ] && UNINSTALL="y" && continue
            [ "${OPTARG}" == "nat" ] && NAT="y" && continue
            [ "${OPTARG}" == "update" ] && UPDATE="y" && continue
            [ "${OPTARG}" == "reconfigure" ] && RECONFIGURE="y" && continue
            [ "${OPTARG}" == "test" ] && TEST_INSTALLER="y" && continue
            [ "${OPTARG}" == "lxdinstall" ] && INSTALL_LXD="y" && continue
            [ "${OPTARG}" == "lxdimages" ] && INSTALL_FROM_LXDIMAGES="y" && continue
            [ "${OPTARG}" == "lightweight" ] && INSTALL_LIGHTWEIGHT="y" && continue
            [ "${OPTARG}" == "vimemu" ] && INSTALL_VIMEMU="y" && continue
            [ "${OPTARG}" == "noconfigure" ] && NOCONFIGURE="y" && continue
            [ "${OPTARG}" == "showopts" ] && SHOWOPTS="y" && continue
            [ "${OPTARG}" == "daily" ] && RELEASE_DAILY="y" && continue
            echo -e "Invalid option: '--$OPTARG'\n" >&2
            usage && exit 1
            ;;
        \?)
            echo -e "Invalid option: '-$OPTARG'\n" >&2
            usage && exit 1
            ;;
if [ -n "$SHOWOPTS" ]; then
    dump_vars
[ -n "$RELEASE_DAILY" ] && echo -e "\nInstalling from daily build repo" && RELEASE="-R ReleaseTHREE-daily" && REPOSITORY="-r testing" && COMMIT_ID="master"

Mike Marchetti's avatar
Mike Marchetti committed
# if develop, we force master
[ -z "$COMMIT_ID" ] && [ -n "$DEVELOP" ] && COMMIT_ID="master"
# forcing source from master removed. Now only install from source when explicit
# [ -n "$COMMIT_ID" ] && [ "$COMMIT_ID" == "master" ] && INSTALL_FROM_SOURCE="y"
if [ -z "$OSM_DEVOPS" ]; then
    if [ -n "$TEST_INSTALLER" ]; then
        echo -e "\nUsing local devops repo for OSM installation"
        TEMPDIR="$(dirname $(realpath $(dirname $0)))"
    else
        echo -e "\nCreating temporary dir for OSM installation"
        TEMPDIR="$(mktemp -d -q --tmpdir "installosm.XXXXXX")"
        trap 'rm -rf "$TEMPDIR"' EXIT
    fi
need_packages="git jq wget curl tar"
echo -e "Checking required packages: $need_packages"
dpkg -l $need_packages &>/dev/null \
  || ! echo -e "One or several required packages are not installed. Updating apt cache requires root privileges." \
  || sudo apt-get update \
  || FATAL "failed to run apt-get update"
dpkg -l $need_packages &>/dev/null \
  || ! echo -e "Installing $need_packages requires root privileges." \
  || sudo apt-get install -y $need_packages \
  || FATAL "failed to install $need_packages"
if [ -z "$OSM_DEVOPS" ]; then
    if [ -z "$TEST_INSTALLER" ]; then
        echo -e "\nCloning devops repo temporarily"
        git clone https://osm.etsi.org/gerrit/osm/devops.git $TEMPDIR
        RC_CLONE=$?
    fi
    echo -e "\nGuessing the current stable release"
    LATEST_STABLE_DEVOPS=`git -C $TEMPDIR tag -l v[0-9].* | sort -V | tail -n1`
    [ -z "$COMMIT_ID" ] && [ -z "$LATEST_STABLE_DEVOPS" ] && echo "Could not find the current latest stable release" && exit 0
    echo "Latest tag in devops repo: $LATEST_STABLE_DEVOPS"
    [ -z "$COMMIT_ID" ] && [ -n "$LATEST_STABLE_DEVOPS" ] && COMMIT_ID="tags/$LATEST_STABLE_DEVOPS"

    if [ -n "$RELEASE_DAILY" ]; then
        echo "Using master/HEAD devops"
        git -C $TEMPDIR checkout master
    elif [ -z "$TEST_INSTALLER" ]; then
        git -C $TEMPDIR checkout tags/$LATEST_STABLE_DEVOPS
    fi
    OSM_DEVOPS=$TEMPDIR
OSM_JENKINS="$OSM_DEVOPS/jenkins"
. $OSM_JENKINS/common/all_funcs
[ -n "$INSTALL_LIGHTWEIGHT" ] && [ -n "$UNINSTALL" ] && uninstall_lightweight && echo -e "\nDONE" && exit 0
[ -n "$UNINSTALL" ] && uninstall && echo -e "\nDONE" && exit 0
[ -n "$NAT" ] && nat && echo -e "\nDONE" && exit 0
[ -n "$UPDATE" ] && update && echo -e "\nDONE" && exit 0
[ -n "$RECONFIGURE" ] && configure && echo -e "\nDONE" && exit 0
[ -n "$INSTALL_LIGHTWEIGHT" ] && install_lightweight && echo -e "\nDONE" && exit 0
echo -e "\nInstalling OSM from refspec: $COMMIT_ID"
if [ -n "$INSTALL_FROM_SOURCE" ] && [ -z "$ASSUME_YES" ]; then
    ! ask_user "The installation will take about 75-90 minutes. Continue (Y/n)? " y && echo "Cancelled!" && exit 1
echo -e "Checking required packages: lxd"
lxd --version &>/dev/null || FATAL "lxd not present, exiting."
[ -n "$INSTALL_LXD" ] && echo -e "\nInstalling and configuring lxd" && install_lxd
wget -q -O- https://osm-download.etsi.org/ftp/osm-4.0-four/README.txt &> /dev/null
track start
# use local devops for containers
export OSM_USE_LOCAL_DEVOPS=true
if [ -n "$INSTALL_FROM_SOURCE" ]; then #install from source
    echo -e "\nCreating the containers and building from source ..."
    $OSM_DEVOPS/jenkins/host/start_build RO --notest checkout $COMMIT_ID || FATAL "RO container build failed (refspec: '$COMMIT_ID')"
    ro_is_up && track RO
    $OSM_DEVOPS/jenkins/host/start_build VCA || FATAL "VCA container build failed"
    vca_is_up && track VCA
    $OSM_DEVOPS/jenkins/host/start_build MON || FATAL "MON install failed"
    mon_is_up && track MON
    $OSM_DEVOPS/jenkins/host/start_build SO checkout $COMMIT_ID || FATAL "SO container build failed (refspec: '$COMMIT_ID')"
    $OSM_DEVOPS/jenkins/host/start_build UI checkout $COMMIT_ID || FATAL "UI container build failed (refspec: '$COMMIT_ID')"
    #so_is_up && track SOUI
    track SOUI
elif [ -n "$INSTALL_FROM_LXDIMAGES" ]; then #install from LXD images stored in OSM repo
    echo -e "\nInstalling from lxd images ..."
    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"
    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"
    #so_is_up && track SOUI
    track SOUI
#Install iptables-persistent and configure NAT rules
[ -z "$NOCONFIGURE" ] && nat
[ -z "$NOCONFIGURE" ] && configure

#Install osmclient
[ -z "$NOCONFIGURE" ] && install_osmclient
#Install vim-emu (optional)
if [ -n "$INSTALL_VIMEMU" ]; then
    echo -e "\nInstalling vim-emu ..."
    install_vimemu
fi

wget -q -O- https://osm-download.etsi.org/ftp/osm-4.0-four/README2.txt &> /dev/null
track end
echo -e "\nDONE"