Feature 8583 66/8666/14
authorDominik Fleischmann <dominik.fleischmann@canonical.com>
Fri, 6 Mar 2020 13:05:06 +0000 (14:05 +0100)
committerDominik Fleischmann <dominik.fleischmann@canonical.com>
Tue, 21 Apr 2020 10:17:48 +0000 (12:17 +0200)
This feature will enable the installation of OSM with
charms on top of Kubernetes (microk8s by default).

Instructions to test this before Merge:

Change path to local full_install_osm.sh in
line 145 in install_osm.sh

Change path to local charmed_install.sh and
charmed_uninstall.sh in line 1285 and 1287 in
full_install_osm.sh

Afterwards, just execute:
./install_osm.sh --charmed

For uninstall
./install_osm.sh --uninstall

Change-Id: I6dfe0831ea5e2c265a365b41638e807106076346
Signed-off-by: Dominik Fleischmann <dominik.fleischmann@canonical.com>
installers/charmed_install.sh [new file with mode: 0755]
installers/charmed_uninstall.sh [new file with mode: 0755]
installers/full_install_osm.sh
installers/install_osm.sh

diff --git a/installers/charmed_install.sh b/installers/charmed_install.sh
new file mode 100755 (executable)
index 0000000..731282b
--- /dev/null
@@ -0,0 +1,241 @@
+#! /bin/bash
+#
+#   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 check_arguments(){
+    while [ $# -gt 0 ] ; do
+      case $1 in
+        --bundle) BUNDLE="$2" ;;
+        --kubeconfig) KUBECFG="$2" ;;
+        --lxd-endpoint) LXDENDPOINT="$2" ;;
+        --lxd-cert) LXDCERT="$2" ;;
+       --microstack) MICROSTACK=y
+      esac
+      shift
+    done
+
+    echo $BUNDLE $KUBECONFIG $LXDENDPOINT
+}
+function install_snaps(){
+    sudo snap install juju --classic
+    if [ -z "$KUBECFG" ]; then sudo snap install microk8s --classic; fi
+}
+
+function bootstrap_k8s_lxd(){
+    if [ -n "$KUBECFG" ]; then
+        echo "Using specified K8s"
+        cat $KUBECFG | juju add-k8s k8s-cluster --client
+        juju bootstrap k8s-cluster controller
+    else
+        sudo microk8s.enable storage dns
+        sudo usermod -a -G microk8s ubuntu
+        sg microk8s -c "juju bootstrap microk8s controller"
+    fi
+
+    if [ -n "$LXDENDPOINT" ]; then
+        if [ -n "$LXDCERT" ]; then
+
+            local server_cert=`cat $LXDCERT | sed 's/^/        /'`
+        else
+            echo "The installer needs the LXD server certificate if the LXD is external"
+            exit 1
+        fi
+    else
+        LXDENDPOINT=$DEFAULT_IP
+        lxd init --auto --network-address $LXDENDPOINT
+        lxc network set lxdbr0 ipv6.address none
+
+        local server_cert=`cat /var/lib/lxd/server.crt | sed 's/^/        /'`
+    fi
+
+    sudo cat << EOF > ~/.osm/lxd-cloud.yaml
+clouds:
+  lxd-cloud:
+    type: lxd
+    auth-types: [certificate]
+    endpoint: "https://$LXDENDPOINT:8443"
+    config:
+      ssl-hostname-verification: false
+EOF
+    openssl req -nodes -new -x509 -keyout ~/.osm/private.key -out ~/.osm/publickey.crt -days 365 -subj "/C=FR/ST=Nice/L=Nice/O=ETSI/OU=OSM/CN=osm.etsi.org"
+
+
+    local client_cert=`cat ~/.osm/publickey.crt | sed 's/^/        /'`
+    local client_key=`cat ~/.osm/private.key | sed 's/^/        /'`
+
+    sudo cat << EOF > ~/.osm/lxd-credentials.yaml
+credentials:
+  lxd-cloud:
+    admin:
+      auth-type: certificate
+      server-cert: |
+$server_cert
+      client-cert: |
+$client_cert
+      client-key: |
+$client_key
+EOF
+
+   lxc config trust add local: ~/.osm/publickey.crt
+   juju add-cloud -c controller lxd-cloud ~/.osm/lxd-cloud.yaml --force
+   juju add-credential -c controller lxd-cloud -f ~/.osm/lxd-credentials.yaml
+   juju add-model test lxd-cloud
+
+}
+
+function deploy_charmed_osm(){
+    create_overlay
+    echo "Creating OSM model"
+    if [ -n "$KUBECFG" ]; then
+        juju add-model osm-on-k8s k8s-cluster
+    else
+        sg microk8s -c "juju add-model osm-on-k8s microk8s"
+    fi
+    echo "Deploying OSM with charms"
+    echo $BUNDLE
+    if [ -n "$BUNDLE" ]; then
+        juju deploy $BUNDLE --overlay ~/.osm/vca-overlay.yaml
+    else
+        juju deploy osm --overlay ~/.osm/vca-overlay.yaml
+    fi
+    echo "Waiting for deployment to finish..."
+    check_osm_deployed &> /dev/null
+    echo "OSM with charms deployed"
+    sudo microk8s.enable ingress
+    juju config ui-k8s juju-external-hostname=osm.$DEFAULT_IP.xip.io
+    juju expose ui-k8s
+}
+
+function check_osm_deployed() {
+    while true
+    do
+        pod_name=`sg microk8s -c "microk8s.kubectl -n osm-on-k8s get pods | grep ui-k8s | grep -v operator" | awk '{print $1}'
+`
+
+        if [[ `sg microk8s -c "microk8s.kubectl -n osm-on-k8s wait pod $pod_name --for condition=Ready"` ]]; then
+             if [[ `sg microk8s -c "microk8s.kubectl -n osm-on-k8s wait pod lcm-k8s-0 --for condition=Ready"` ]]; then
+                break
+            fi
+        fi
+        sleep 10
+    done
+}
+
+function create_overlay() {
+    sudo snap install yq
+
+    local YQ="$SNAP/bin/yq"
+    local HOME=/home/$USER
+    local vca_user=$(cat $HOME/.local/share/juju/accounts.yaml | yq  r - controllers.controller.user)
+    local vca_password=$(cat $HOME/.local/share/juju/accounts.yaml | yq  r - controllers.controller.password)
+    local vca_host=$(cat $HOME/.local/share/juju/controllers.yaml | yq  r - controllers.controller.api-endpoints[0] | cut -d ":" -f 1)
+    local vca_port=$(cat $HOME/.local/share/juju/controllers.yaml | yq  r - controllers.controller.api-endpoints[0] | cut -d ":" -f 2)
+    local vca_pubkey=\"$(cat $HOME/.local/share/juju/ssh/juju_id_rsa.pub)\"
+    local vca_cloud="lxd-cloud"
+    # Get the VCA Certificate
+    local vca_cacert=$(cat $HOME/.local/share/juju/controllers.yaml | yq  r - controllers.controller.ca-cert | base64 | tr -d \\n)
+
+    # Calculate the default route of this machine
+    local DEFAULT_IF=`route -n |awk '$1~/^0.0.0.0/ {print $8}'`
+    local vca_apiproxy=`ip -o -4 a |grep ${DEFAULT_IF}|awk '{split($4,a,"/"); print a[1]}'`
+
+    # Generate a new overlay.yaml, overriding any existing one
+    sudo cat << EOF > /tmp/vca-overlay.yaml
+applications:
+  lcm-k8s:
+    options:
+      vca_user: $vca_user
+      vca_password: $vca_password
+      vca_host: $vca_host
+      vca_port: $vca_port
+      vca_pubkey: $vca_pubkey
+      vca_cacert: $vca_cacert
+      vca_apiproxy: $vca_apiproxy
+      vca_cloud: $vca_cloud
+  mon-k8s:
+    options:
+      vca_user: $vca_user
+      vca_password: $vca_password
+      vca_host: $vca_host
+      vca_cacert: $vca_cacert
+EOF
+   sudo cp /tmp/vca-overlay.yaml ~/.osm/
+   OSM_VCA_HOST=$vca_host
+}
+
+function install_osmclient() {
+    sudo snap install osmclient
+    sudo snap alias osmclient.osm osm
+}
+
+function create_iptables() {
+    check_install_iptables_persistent
+
+    if ! sudo iptables -t nat -C PREROUTING -p tcp -m tcp -d $DEFAULT_IP --dport 17070 -j DNAT --to-destination $OSM_VCA_HOST; then
+        sudo iptables -t nat -A PREROUTING -p tcp -m tcp -d $DEFAULT_IP --dport 17070 -j DNAT --to-destination $OSM_VCA_HOST
+        sudo netfilter-persistent save
+    fi
+}
+
+function check_install_iptables_persistent(){
+    echo -e "\nChecking required packages: iptables-persistent"
+    if ! dpkg -l iptables-persistent &>/dev/null; then
+        echo -e "    Not installed.\nInstalling iptables-persistent requires root privileges"
+        echo iptables-persistent iptables-persistent/autosave_v4 boolean true | sudo debconf-set-selections
+        echo iptables-persistent iptables-persistent/autosave_v6 boolean true | sudo debconf-set-selections
+        sudo apt-get -yq install iptables-persistent
+    fi
+}
+
+function install_microstack() {
+    sudo snap install microstack --classic --beta
+    sudo microstack.init --auto
+    wget https://cloud-images.ubuntu.com/releases/16.04/release/ubuntu-16.04-server-cloudimg-amd64-disk1.img -P ~/.osm/
+    microstack.openstack image create \
+                         --public \
+                         --disk-format qcow2 \
+                         --container-format bare \
+                         --file ~/.osm/ubuntu-16.04-server-cloudimg-amd64-disk1.img \
+                         ubuntu1604
+    ssh-keygen -t rsa -N "" -f ~/.ssh/microstack
+    microstack.openstack keypair create --public-key ~/.ssh/microstack.pub microstack
+    export OSM_HOSTNAME=`juju status --format yaml | yq r - applications.nbi-k8s.address`
+    osm vim-create --name microstack-site \
+        --user admin \
+        --password keystone \
+        --auth_url http://10.20.20.1:5000/v3 \
+        --tenant admin \
+        --account_type openstack \
+        --config='{security_groups: default,
+                   keypair: microstack,
+                   project_name: admin,
+                   user_domain_name: default,
+                   region_name: microstack,
+                   insecure: True,
+                   availability_zone: nova,
+                   version: 3}'
+}
+
+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]}'`
+
+check_arguments $@
+mkdir ~/.osm
+install_snaps
+bootstrap_k8s_lxd
+deploy_charmed_osm
+create_iptables
+install_osmclient
+if [ -n "$MICROSTACK" ]; then
+    install_microstack
+fi
diff --git a/installers/charmed_uninstall.sh b/installers/charmed_uninstall.sh
new file mode 100755 (executable)
index 0000000..6cee999
--- /dev/null
@@ -0,0 +1,39 @@
+#! /bin/bash
+#
+#   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 remove_iptables() {
+    stack=$1
+    if [ -z "$OSM_VCA_HOST" ]; then
+        OSM_VCA_HOST=`sg lxd -c "juju show-controller controller"|grep api-endpoints|awk -F\' '{print $2}'|awk -F\: '{print $1}'`
+        [ -z "$OSM_VCA_HOST" ] && FATAL "Cannot obtain juju controller IP address"
+    fi
+
+    if [ -z "$DEFAULT_IP" ]; then
+        DEFAULT_IF=`route -n |awk '$1~/^0.0.0.0/ {print $8}'`
+        [ -z "$DEFAULT_IF" ] && FATAL "Not possible to determine the interface with the default route 0.0.0.0"
+        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"
+    fi
+
+    if sudo iptables -t nat -C PREROUTING -p tcp -m tcp -d $DEFAULT_IP --dport 17070 -j DNAT --to-destination $OSM_VCA_HOST; then
+        sudo iptables -t nat -D PREROUTING -p tcp -m tcp -d $DEFAULT_IP --dport 17070 -j DNAT --to-destination $OSM_VCA_HOST
+        sudo netfilter-persistent save
+    fi
+}
+
+remove_iptables
+juju destroy-model osm-on-k8s --destroy-storage
+juju destroy-model test --destroy-storage
+sudo snap unalias osm
+sudo snap remove osmclient
index 9e4132c..72f3190 100755 (executable)
@@ -56,6 +56,13 @@ function usage(){
     echo -e "     --showopts:     print chosen options and exit (only for debugging)"
     echo -e "     -y:             do not prompt for confirmation, assumes yes"
     echo -e "     -h / --help:    print this help"
+    echo -e "     --charmed:                       install OSM with charms"
+    echo -e "     --bundle <bundle path>:          Specify with which bundle to deploy OSM with charms (--charmed option)"
+    echo -e "     --kubeconfig <kubeconfig path>:  Specify with which kubernetes to deploy OSM with charms (--charmed option)"
+    echo -e "     --lxdendpoint <lxd endpoint ip>: Specify with which LXD to deploy OSM with charms (--charmed option)"
+    echo -e "     --lxdcert <lxd cert path>:       Specify external LXD cert to deploy OSM with charms (--charmed option)"
+    echo -e "     --microstack:                    Installs microstack as a vim. (--charmed option)"
+
 }
 
 # takes a juju/accounts.yaml file and returns the password specific
@@ -1237,6 +1244,12 @@ while getopts ":b:r:c:k:u:R:D:o:m:H:S:s:w:t:U:P:A:-: hy" o; do
             [ "${OPTARG}" == "nohostclient" ] && INSTALL_NOHOSTCLIENT="y" && continue
             [ "${OPTARG}" == "pullimages" ] && continue
             [ "${OPTARG}" == "k8s_monitor" ] && INSTALL_K8S_MONITOR="y" && continue
+            [ "${OPTARG}" == "charmed" ] && CHARMED="y" && continue
+            [ "${OPTARG}" == "bundle" ] && continue
+            [ "${OPTARG}" == "kubeconfig" ] && continue
+            [ "${OPTARG}" == "lxdendpoint" ] && continue
+            [ "${OPTARG}" == "lxdcert" ] && continue
+            [ "${OPTARG}" == "microstack" ] && continue
             echo -e "Invalid option: '--$OPTARG'\n" >&2
             usage && exit 1
             ;;
@@ -1267,6 +1280,32 @@ if [ -n "$SHOWOPTS" ]; then
     exit 0
 fi
 
+if [ -n "$CHARMED" ]; then
+     if [ -n "$UNINSTALL" ]; then
+        /usr/share/osm-devops/installers/charmed_uninstall.sh -R $RELEASE -r $REPOSITORY -u $REPOSITORY_BASE -D /usr/share/osm-devops -t $DOCKER_TAG "$@"
+     else
+        /usr/share/osm-devops/installers/charmed_install.sh -R $RELEASE -r $REPOSITORY -u $REPOSITORY_BASE -D /usr/share/osm-devops -t $DOCKER_TAG "$@"
+     fi
+
+     echo "Your installation is now complete, follow these steps for configuring the osmclient:"
+     echo
+     echo "1. Get the NBI IP with the following command:"
+     echo
+     echo "juju status --format yaml | yq r - applications.nbi-k8s.address"
+     echo
+     echo "2. Create the OSM_HOSTNAME environment variable with the NBI IP"
+     echo
+     echo "export OSM_HOSTNAME=<NBI-IP>"
+     echo
+     echo "3. Add the previous command to your .bashrc for other Shell sessions"
+     echo
+     echo "export OSM_HOSTNAME=<previous-IP> >> ~/.bashrc"
+     echo
+     echo "DONE"
+
+     exit 0
+fi
+
 # if develop, we force master
 [ -z "$COMMIT_ID" ] && [ -n "$DEVELOP" ] && COMMIT_ID="master"
 
@@ -1340,3 +1379,4 @@ export OSM_USE_LOCAL_DEVOPS=true
 wget -q -O- https://osm-download.etsi.org/ftp/osm-7.0-seven/README2.txt &> /dev/null
 track end
 echo -e "\nDONE"
+
index 01d96e9..77bca85 100755 (executable)
@@ -64,6 +64,12 @@ function usage(){
     #echo -e "     --clean_volumes To clear all the mounted volumes from docker swarm"
     echo -e "     -y:             do not prompt for confirmation, assumes yes"
     echo -e "     -h / --help:    print this help"
+    echo -e "     --charmed:                       install OSM with charms"
+    echo -e "     --bundle <bundle path>:          Specify with which bundle to deploy OSM with charms (--charmed option)"
+    echo -e "     --kubeconfig <kubeconfig path>:  Specify with which kubernetes to deploy OSM with charms (--charmed option)"
+    echo -e "     --lxdendpoint <lxd endpoint ip>: Specify with which LXD to deploy OSM with charms (--charmed option)"
+    echo -e "     --lxdcert <lxd cert path>:       Specify external LXD cert to deploy OSM with charms (--charmed option)"
+
 }
 
 add_repo() {
@@ -115,7 +121,7 @@ while getopts ":b:r:c:k:u:R:l:p:D:o:m:H:S:s:w:t:U:P:A:-: hy" o; do
             ;;
         -)
             [ "${OPTARG}" == "help" ] && usage && exit 0
-           ;;
+            ;;
         :)
             echo "Option -$OPTARG requires an argument" >&2
             usage && exit 1