Gracefully stop the remote-installer container
[ci-management.git] / jjb / shell / ta-install.sh
1 #!/bin/bash -e
2
3 # Copyright 2019 AT&T
4 # Copyright 2020 ENEA
5
6 # Licensed under the Apache License, Version 2.0 (the "License");
7 # you may not use this file except in compliance with the License.
8 # You may obtain a copy of the License at
9 #
10 #     http://www.apache.org/licenses/LICENSE-2.0
11 #
12 # Unless required by applicable law or agreed to in writing, software
13 # distributed under the License is distributed on an "AS IS" BASIS,
14 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 # See the License for the specific language governing permissions and
16 # limitations under the License.
17 #
18
19 _yaml2json() {
20     python -c 'import json,sys,yaml; json.dump(yaml.safe_load(sys.stdin.read()), sys.stdout)'
21 }
22
23 #Work-flow:
24
25 #0. Get values for the environment variables
26
27 # The following must be provided.
28     REC_ISO_IMAGE_NAME="${REC_ISO_IMAGE_NAME:?'Must be defined!'}"
29     REC_PROVISIONING_ISO_NAME="${REC_PROVISIONING_ISO_NAME:?'Must be defined!'}"
30     REC_USER_CONFIG="${REC_USER_CONFIG:?'Must be defined!'}"
31
32 # The next set may be modified if necessary but are best left as-is
33     ADMIN_PASSWD="admin"
34     POD_NAME="REC-$BUILD_ID"
35     HTTPS_PORT=8443
36     API_PORT=15101
37     # Max time (in minutes) to wait for the remote-installer to return completed
38     # Currently 4 hours
39     MAX_TIME=240
40
41     # These should probably not be changed
42     WORKDIR="$(pwd)"
43     BASEDIR="$WORKDIR/rec_basedir"
44
45
46 cat <<EOF
47     --------------------------------------------
48     WORKDIR is $WORKDIR
49     BASEDIR is $BASEDIR
50     POD_NAME is $POD_NAME
51     REC_ISO_IMAGE_NAME is $REC_ISO_IMAGE_NAME
52     REC_PROVISIONING_ISO_NAME is $REC_PROVISIONING_ISO_NAME
53     REC_USER_CONFIG is $REC_USER_CONFIG
54     --------------------------------------------
55 EOF
56
57 # Create cleanup hook
58 _cleanup() {
59     exit_status=$?
60     set +e
61     sudo chown -R jenkins:jenkins "$WORKDIR"
62     docker cp 'remote-installer':/var/log/remote-installer.log "$BASEDIR/"
63     docker stop 'remote-installer'
64     docker rm -f 'remote-installer'
65     trap - EXIT ERR HUP INT QUIT TERM
66     exit $exit_status
67 }
68 trap _cleanup EXIT ERR HUP INT QUIT TERM
69
70 # Enable debugging
71     set -x
72
73 #1. Create a new directory to be used for holding the installation artifacts.
74
75     # Clean workspace from previous run
76     sudo chown -R jenkins:jenkins "$WORKDIR"
77     rm -rf "$BASEDIR"
78
79     # Create the base directory structure
80     mkdir -p "$BASEDIR/images" \
81              "$BASEDIR/certificates" \
82              "$BASEDIR/installations" \
83              "$BASEDIR/user-configs/$POD_NAME"
84
85 #2. Get REC golden and bootcd images from REC Nexus artifacts
86
87     cd "$BASEDIR/images/"
88     curl -sL "$REC_ISO_IMAGE_NAME"        > "$(basename "$REC_ISO_IMAGE_NAME")"
89     curl -sL "$REC_PROVISIONING_ISO_NAME" > "$(basename "$REC_PROVISIONING_ISO_NAME")"
90
91 #3. Get the user-config.yaml file and admin_password file for the CD environment from the
92 #   cd-environments repo and copy it to the user-configs sub-directory under the directory
93 #   created in (1). Copy the files to a cloud-specific directory identified by the cloudname.
94
95     cd "$BASEDIR/user-configs/$POD_NAME"
96     curl -sL "$REC_USER_CONFIG" > user_config.yaml
97     echo "$ADMIN_PASSWD" > admin_passwd
98
99     FIRST_CONTROLLER_IP="$(_yaml2json < user_config.yaml | \
100         jq -r '.hosts[]|select(.service_profiles[]|contains("caas_master", "controller"))|.hwmgmt.address' | \
101         sort | head -1 )"
102     HOST_IP="$(ip route get "$FIRST_CONTROLLER_IP" | grep -Pzo 'src\s+\K([^\s]*)' )"
103
104 #4. Copy the sever certificates, the client certificates in addition to CA certificate to
105 #  the certificates sub-directory under the directory created in (1).
106 #   The following certificates are expected to be available in the directory:
107 #
108 #   cacert.pem: The CA certificate
109 #   servercert.pem: The server certificate signed by the CA
110 #   serverkey.pem: The server key
111 #   clientcert.pem: The client certificate signed by the CA
112 #   clientkey.pem: The client key
113 #
114
115     cd "$WORKDIR/git/remote-installer/test/certificates"
116     ./create.sh
117     cp -a {ca,client,server}{cert,key}.pem "${BASEDIR}/certificates/"
118
119 #5. Build the remote installer docker-image.
120     cd "$WORKDIR/git/remote-installer/scripts/"
121     ./build.sh "$HTTPS_PORT" "$API_PORT"
122
123 #6. Start the remote installer
124
125     cd "$WORKDIR/git/remote-installer/scripts/"
126     if ! ./start.sh -b "$BASEDIR" -e "$HOST_IP" -s "$HTTPS_PORT" -a "$API_PORT" -p "$ADMIN_PASSWD"
127     then
128         echo 'Failed to run workflow.'
129         exit 1
130     fi
131
132 #7. Wait for the remote installer to become running.
133 #   check every 30 seconds to see if it has it has a status of "running"
134
135     DOCKER_STATUS=""
136
137     while [ ${#DOCKER_STATUS} -eq 0 ]; do
138         sleep 30
139         DOCKER_ID=$(docker ps | grep 'remote-installer' | awk '{print $1}')
140         DOCKER_STATUS=$(docker ps -f status=running | grep "$DOCKER_ID")
141     done
142
143 #8. Start the installation by sending the following http request to the installer API
144
145 #    POST url: https://localhost:$API_PORT/v1/installations
146 #    REQ body json- encoded
147 #    {
148 #        'cloudname': $POD_NAME,
149 #        'iso': $REC_ISO_IMAGE_NAME,
150 #        'provisioning-iso': $REC_PROVISIONING_ISO_NAME
151 #    }
152 #    REP body json-encoded
153 #    {
154 #        'uuid': $INSTALLATION_UUID
155 #    }
156
157 INSTALL_ISO="$(basename "$REC_ISO_IMAGE_NAME")"
158 BOOT_ISO="$(basename "$REC_PROVISIONING_ISO_NAME")"
159 cat >rec_request.json <<EOF
160 {
161     "cloud-name": "$POD_NAME",
162     "iso": "$INSTALL_ISO",
163     "provisioning-iso": "$BOOT_ISO"
164 }
165 EOF
166
167     # Get the IP address of the remote installer container
168     RI_IP=$HOST_IP
169
170     RESPONSE=$(curl -k --silent \
171                     --header "Content-Type: application/json" \
172                     -d "@rec_request.json" \
173                     --cert "$BASEDIR/certificates/clientcert.pem" \
174                     --key  "$BASEDIR/certificates/clientkey.pem" \
175                     "https://${RI_IP}:${API_PORT}/v1/installations")
176     echo "$0: RESPONSE IS $RESPONSE"
177
178     INSTALLATION_UUID="$(echo "$RESPONSE" | jq -r ".uuid")"
179
180 #9. Follow the progress of the installation by sending the following http request to the installer API
181
182 #    GET url: https://localhost:$API_PORT/v1/installations/$INSTALLATION_UUID
183 #
184 #    REP body json-encoded
185 #    {
186 #        'status': <ongoing|completed|failed>,
187 #        'description': <description>,
188 #        'percentage': <the progess precentage>
189 #    }
190 #
191 #
192
193 # check the status every minute until it has become "completed"
194 # (for a maximum of MAX_TIME minutes)
195
196     STATUS="ongoing"
197     NTIMES=$MAX_TIME
198     while [ "$STATUS" == "ongoing" -a $NTIMES -gt 0 ]; do
199         sleep 60
200         NTIMES=$((NTIMES - 1))
201         RESPONSE=$(curl -k --silent \
202                         --cert "$BASEDIR/certificates/clientcert.pem" \
203                         --key  "$BASEDIR/certificates/clientkey.pem" \
204                         "https://${RI_IP}:${API_PORT}/v1/installations/$INSTALLATION_UUID/state")
205         STATUS="$(echo "$RESPONSE" | jq -r ".status")"
206         PCT="$(   echo "$RESPONSE" | jq -r ".percentage")"
207         DESCR="$( echo "$RESPONSE" | jq -r ".description")"
208         echo "$(date): Status is $STATUS ($PCT) $DESCR"
209     done
210
211     if [ "$STATUS" == "ongoing" -a $NTIMES -le 0 ]; then
212         echo "Installation failed after $MAX_TIME minutes."
213         echo "RESPONSE: $RESPONSE"
214         exit 1
215     elif [ "$STATUS" != "completed" ]; then
216         echo "Installation failed."
217         echo "RESPONSE: $RESPONSE"
218         exit 1
219     fi
220
221     echo "Installation complete!"
222
223 #10. Done
224     exit 0