2 #######################################################################################
3 # Copyright ETSI Contributors and Others.
5 # Licensed under the Apache License, Version 2.0 (the "License");
6 # you may not use this file except in compliance with the License.
7 # You may obtain a copy of the License at
9 # http://www.apache.org/licenses/LICENSE-2.0
11 # Unless required by applicable law or agreed to in writing, software
12 # distributed under the License is distributed on an "AS IS" BASIS,
13 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
15 # See the License for the specific language governing permissions and
16 # limitations under the License.
17 #######################################################################################
20 DIR
="$( cd "$
( dirname "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )"
21 HTTPDDIR
="${HOME}/.osm/httpd"
23 KUBECFG
="~/.osm/microk8s-config.yaml"
25 OPENSTACKRC
="/var/snap/microstack/common/etc/microstack.rc"
26 REGISTRY
="localhost:32000"
27 ROOTDIR
="$( cd "${DIR}/..
/..
/" &> /dev/null && pwd)"
28 OSM_TESTS_IMAGE_TAG
="devel"
30 function check_arguments
(){
31 while [ $# -gt 0 ] ; do
34 --apt-proxy) APT_PROXY
="$2" && shift ;;
35 --help |
-h) show_help
&& exit 0 ;;
36 --httpddir) HTTPDDIR
="$2" && shift;;
37 --install-local-registry) 'install_local_registry' ;;
38 --install-microstack) 'install_microstack' ;;
39 --install-qhttpd) INSTALL_HTTPD
='install_qhttpd' ;;
40 --run-httpserver) INSTALL_HTTPD
='run_httpserver' ;;
41 --kubecfg) KUBECFG
="$2" && shift ;;
42 --module) TARGET_MODULE
="$2" && shift;;
43 --no-cache) NO_CACHE
="--no-cache" ;;
44 --openstackrc) OPENSTACKRC
="$2" && shift ;;
45 --registry) REGISTRY
="$2" && shift;;
46 --robot-local-mounts) ROBOT_LOCAL
=YES
;;
47 --run-tests) TESTS
=YES
;;
48 --vim-vca) VIM_VCA
="$2" && shift;;
49 --osm-tests-image-tag) OSM_TESTS_IMAGE_TAG
="$2" && shift;;
50 stage-2
) STAGE_2
='stage_2 ${TARGET_MODULE}' ;;
51 stage-3
) STAGE_3
='stage_3 ${TARGET_MODULE}' ;;
52 registry-push
) REGISTRY_PUSH
='local_registry_push ${TARGET_MODULE}' ;;
53 install-osm
) INSTALL_OSM
='install_osm' ;;
54 start-robot
) START_ROBOT
='start_robot' ;;
55 update-install
) UPDATE_INSTALL
='update_osm_module ${TARGET_MODULE}'
56 REGISTRY_PUSH
='local_registry_push ${TARGET_MODULE}' ;;
57 *) echo "Unknown option $1"
65 function show_help
() {
68 Perform a local build and potential installation of OSM from sources, using the
69 same process as Jenkins.
72 --help display this help message
73 --apt-proxy provide an apt proxy to docker build steps
74 --debug enable set -x for this script
75 --install-local-registry install and enable Microk8s local registry on port 32000
76 --install-microstack install Microstack and configure to run robot tests
77 --install-qhttpd (deprecated, use --run-httpserver instead) install QHTTPD as an HTTP server on port ${HTTPPORT}
78 --run-httpserver run HTTP server on port ${HTTPPORT}
79 --kubecfg path to kubecfg.yaml (uses Charmed OSM by default)
80 --no-cache do not use any cache when building docker images
81 --module only build this comma delimited list of modules
82 --openstackrc path to Openstack RC file (uses Microstack by default)
83 --registry use this alternate docker registry
84 --run-tests run stage 2 tests
85 --vim-vca name of the a vca registered in OSM to use in the VIM account
86 --osm-tests-image-tag tag to be used in the osm/tests docker image
87 stage-2 run the stage 2 build
88 stage-3 run the stage 3 build
89 registry-push push to the local registry
90 install-osm perform full installation of Charmed OSM from registry
91 start-robot start the Robot test container and leave you at prompt
92 update-install update Charmed OSM with new module container
94 A typical use could be the following:
96 Let's assume that we have different repos cloned in the folder workspace:
99 git clone https://osm.etsi.org/gerrit/osm/devops
100 git clone https://osm.etsi.org/gerrit/osm/NBI
101 git clone https://osm.etsi.org/gerrit/osm/LCM
102 git clone "https://osm.etsi.org/gerrit/osm/RO
103 git clone "https://osm.etsi.org/gerrit/osm/common
104 git clone "https://osm.etsi.org/gerrit/osm/IM
105 git clone "https://osm.etsi.org/gerrit/osm/N2VC
107 First we run a light HTTP server to serve the artifacts:
109 devops/tools/local-build.sh --run-httpserver
111 Then we generate the artifacts (debian packages) for the different repos: common, IM, N2VC, RO, LCM, NBI
113 devops/tools/local-build.sh --module common,IM,N2VC,RO,LCM,NBI stage-2
115 Then new docker images are generated locally with the tag "devel" (e.g.: opensourcemano/lcm:devel):
117 devops/tools/local-build.sh --module RO,LCM,NBI stage-3
119 Finally, the deployment of OSM will have to be updated to use the new docker images.
124 function print_section
() {
128 function install_local_registry
() {
129 sudo snap
install microk8s
--classic
130 microk8s status
--wait-ready
131 microk8s.
enable registry
134 function install_microstack
() {
135 sudo snap
install microstack
--devmode --edge
136 sudo snap
set microstack config.network.ports.dashboard
=8080
137 sudo microstack.init
--auto --control
139 sudo snap
alias microstack.openstack openstack
140 .
/var
/snap
/microstack
/common
/etc
/microstack.rc
142 for i
in $
(microstack.openstack security group list |
awk '/default/{ print $2 }'); do
143 microstack.openstack security group rule create
$i --protocol icmp
--remote-ip 0.0.0.0/0
144 microstack.openstack security group rule create
$i --protocol tcp
--remote-ip 0.0.0.0/0
147 microstack.openstack network create
--enable --no-share osm-ext
148 microstack.openstack subnet create osm-ext-subnet
--network osm-ext
--dns-nameserver 8.8.8.8 \
149 --subnet-range 172.30.0.0/24
150 microstack.openstack router create external-router
151 microstack.openstack router add subnet external-router osm-ext-subnet
152 microstack.openstack router
set --external-gateway external external-router
154 curl
-L https
://github.com
/cirros-dev
/cirros
/releases
/download
/0.3.5/cirros-0.3
.5-x86_64-disk.img \
155 | microstack.openstack image create
--public --container-format=bare \
156 --disk-format=qcow2 cirros-0.3
.5-x86_64-disk.img
157 curl https
://cloud-images.ubuntu.com
/xenial
/current
/xenial-server-cloudimg-amd64-disk1.img \
158 | microstack.openstack image create
--public --container-format=bare \
159 --disk-format=qcow2 ubuntu16.04
160 curl https
://cloud-images.ubuntu.com
/xenial
/current
/xenial-server-cloudimg-amd64-disk1.img \
161 | microstack.openstack image create
--public --container-format=bare \
162 --disk-format=qcow2 US1604
163 curl https
://cloud-images.ubuntu.com
/bionic
/current
/bionic-server-cloudimg-amd64.img \
164 | microstack.openstack image create
--public --container-format=bare \
165 --disk-format=qcow2 ubuntu18.04
166 curl https
://cloud-images.ubuntu.com
/focal
/current
/focal-server-cloudimg-amd64.img \
167 | microstack.openstack image create
--public --container-format=bare \
168 --disk-format=qcow2 ubuntu20.04
171 function create_httpddir
() {
175 function install_qhttpd
() {
176 sudo snap
install qhttp
177 EXISTING_PID
=$
(ps auxw |
grep "http.server $HTTPPORT" |
grep -v grep |
awk '{print $2}')
178 if [ ! -z $EXISTING_PID ] ; then
181 qhttp
-p ${HTTPPORT} &
184 function run_httpserver
() {
185 EXISTING_PID
=$
(ps auxw |
grep "http.server $HTTPPORT" |
grep -v grep |
awk '{print $2}')
186 if [ ! -z $EXISTING_PID ] ; then
189 nohup python3
-m http.server
${HTTPPORT} --directory "${HTTPDDIR}" &>/dev
/null
&
193 print_section
"Performing Stage 2"
194 MODULES
="common devops IM LCM MON N2VC NBI NG-UI NG-SA osmclient PLA POL RO tests"
195 if [ ! -z ${1} ] ; then
196 POSSIBLE_MODULES
=$
(echo ${1} |
sed "s/,/ /g")
197 for MODULE
in ${POSSIBLE_MODULES}; do
198 if ! echo "${MODULES}" |
grep -q "${MODULE}" ; then
199 echo "Unknown stage 2 module ${MODULE}"
200 echo "Must be one of ${MODULES}"
204 MODULES
=${POSSIBLE_MODULES}
206 print_section
"Cleaning HTTP Directory for full build"
207 rm -fv ${HTTPDDIR}/*.deb
210 for MODULE
in ${MODULES} ; do
212 if [ ! -d ${MODULE} ] ; then
213 echo "Directory ${ROOTDIR}/${MODULE} does not exist"
216 print_section
"Building ${MODULE}"
218 find .
-name '*.deb' -exec rm -v {} \
;
221 if [ ! -z $APT_PROXY ] ; then
222 BUILD_ARGS
="${BUILD_ARGS}--build-arg APT_PROXY=${APT_PROXY} "
224 docker build
${NO_CACHE} ${BUILD_ARGS} -t ${MODULE,,}-stage2 .
226 STAGES
="stage-build.sh"
227 if [ ! -z $TESTS ] ; then
228 STAGES
="stage-test.sh ${STAGES}"
230 for STAGE
in $STAGES ; do
235 bash
-c "groupadd -o -g $(id -g) -r $USER ;
236 useradd -o -u $(id -u) -d /build -r -g $USER $USER ;
237 runuser $USER -c devops-stages/${STAGE}"
238 if [ $?
-ne 0 ] ; then
239 print_section
"Failed to build ${MODULE}"
244 find .
-name '*.deb' -exec mv -v {} ${HTTPDDIR}/ \
;
248 function _find_module_dockerfile
() {
249 cd "${ROOTDIR}/devops/docker"
250 MODULES
=`find . -name Dockerfile -printf '%h\n' |sed 's|\./||' |sort |tr '\n' ' '`
251 if [ ! -z ${1} ] ; then
252 POSSIBLE_MODULES
=$
(echo ${1} |
sed "s/,/ /g")
253 for MODULE
in ${POSSIBLE_MODULES}; do
254 if ! echo "${MODULES}" |
grep -q "${MODULE}" ; then
255 echo "Unknown stage 3 module ${MODULE}"
256 echo "Must be one of ${MODULES}"
260 echo ${POSSIBLE_MODULES}
267 print_section
"Performing Stage 3"
268 MODULES
=$
(_find_module_dockerfile
$1)
270 if [ ! -z $APT_PROXY ] ; then
271 BUILD_ARGS
="${BUILD_ARGS}--build-arg APT_PROXY=${APT_PROXY} "
274 HOSTIP
=$
(ip
-4 addr show docker0 |
grep -Po 'inet \K[\d.]+')
275 [ -z "$DEFAULT_IF" ] && DEFAULT_IF
=$
(ip route list|
awk '$1=="default" {print $5; exit}')
276 [ -z "$DEFAULT_IF" ] && DEFAULT_IF
=$
(route
-n |
awk '$1~/^0.0.0.0/ {print $8; exit}')
277 DEFAULT_IP
=$
(ip
-o -4 a s
${DEFAULT_IF} |
awk '{split($4,a,"/"); print a[1]; exit}')
278 HOSTIP
=${HOSTIP:=${DEFAULT_IP}}
281 for file in ${HTTPDDIR}/*.deb
; do
282 file=`basename ${file}`
283 name
=`echo ${file} | cut -d_ -f1 | sed "s/-/_/g"`;
285 BUILD_ARGS
="${BUILD_ARGS}--build-arg ${name}=http://$HOSTIP:${HTTPPORT}/$file "
286 echo Added
${name} as http
://$HOSTIP:${HTTPPORT}/$file
289 for MODULE
in ${MODULES} ; do
290 cd "${ROOTDIR}/devops/docker"
291 if [ ! -d ${MODULE} ] ; then
292 echo "Directory ${ROOTDIR}/${MODULE} does not exist"
295 print_section
"Building ${MODULE}"
298 docker build
${NO_CACHE} -t opensourcemano/${MODULE}:devel ${BUILD_ARGS} .
299 if [ $?
-ne 0 ] ; then
300 print_section
"Failed to build ${MODULE}"
306 function local_registry_push
() {
307 print_section
"Pushing to local registry"
308 cd "${ROOTDIR}/devops/docker"
309 MODULES
=`find . -name Dockerfile -printf '%h\n' |sed 's|\./||' |sort |tr '\n' ' '`
310 if [ ! -z ${1} ] ; then
311 POSSIBLE_MODULES
=$
(echo ${1} |
sed "s/,/ /g")
312 for MODULE
in ${POSSIBLE_MODULES}; do
314 if ! echo "${MODULES}" |
grep -q "${MODULE}" ; then
315 echo "Unknown stage 3 module ${MODULE}"
316 echo "Must be one of ${MODULES}"
320 MODULES
=${POSSIBLE_MODULES}
322 for MODULE
in ${MODULES} ; do
324 docker tag opensourcemano
/${MODULE}:devel ${REGISTRY}/opensourcemano/${MODULE}:devel
325 docker push
${REGISTRY}/opensourcemano
/${MODULE}:devel
329 function install_osm
() {
330 cd "${ROOTDIR}/devops/installers"
332 if juju controllers
2>/dev
/null|
grep osm-vca
; then
335 .
/charmed_install.sh
--registry localhost
:32000 --tag devel
${VCA}
338 function start_robot
() {
339 mkdir
-p "${ROOTDIR}/tests/local"
340 cd "${ROOTDIR}/tests/local"
344 # Workaround for microstack auth URL
345 if [ ${OPENSTACKRC} == "/var/snap/microstack/common/etc/microstack.rc" ] ; then
346 export OS_AUTH_URL
=${OS_AUTH_URL}/v3
349 export OSM_HOSTNAME
=$
(juju config
-m osm nbi site_url |
sed "s/http.*\?:\/\///"):443
350 export PROMETHEUS_HOSTNAME
=$
(juju config
-m osm prometheus site_url |
sed "s/http.*\?:\/\///")
351 export PROMETHEUS_PORT
=80
352 export JUJU_PASSWORD
=`juju gui 2>&1 | grep password | awk '{print $2}'`
353 export HOSTIP
=$
(echo $PROMETHEUS_HOSTNAME |
sed "s/prometheus.//" |
sed "s/.nip.io//")
356 for line
in `env | grep "^OS_" | sort` ; do echo $line >> robot-systest.cfg
; done
357 cat << EOF >> robot-systest.cfg
360 ENVIRONMENTS_FOLDER=environments
361 PACKAGES_FOLDER=/robot-systest/osm-packages
367 cat << EOF > robot.etc.hosts
369 ${HOSTIP} prometheus.${HOSTIP}.nip.io nbi.${HOSTIP}.nip.io
371 cat << EOF > clouds.yaml
375 auth_url: $OS_AUTH_URL
376 project_name: $OS_PROJECT_NAME
377 username: $OS_USERNAME
378 password: $OS_PASSWORD
379 user_domain_name: $OS_USER_DOMAIN_NAME
380 project_domain_name: $OS_PROJECT_DOMAIN_NAME
383 VIM_AUTH_URL
=$
(osm vim-show osm |
grep vim_url |
awk '{print $4}' |
tr -d \")
384 if [[ ! -z ${VIM_AUTH_URL} && "$OS_AUTH_URL" != "${VIM_AUTH_URL}" ]] ; then
385 echo "Deleting existing VIM osm as auth URLs have changed"
389 if ! osm vim-show osm
&> /dev
/null
; then
390 echo "Creating VIM osm"
391 if [ -v VIM_VCA
]; then
392 VCA_OPT
="--vca $VIM_VCA"
394 osm vim-create
--name osm
$VCA_OPT --user "$OS_USERNAME" --password "$OS_PASSWORD" \
395 --auth_url "$OS_AUTH_URL" --tenant "$OS_USERNAME" --account_type openstack \
396 --config='{use_floating_ip: True,
397 management_network_name: osm-ext}'
400 if [ ! -z $ROBOT_LOCAL ] ; then
401 LOCAL_MOUNT_1
="/robot-systest/lib"
402 LOCAL_MOUNT_2
="/robot-systest/resources"
403 LOCAL_MOUNT_3
="/robot-systest/testsuite"
405 LOCAL_MOUNT_1
="/tmp/lib"
406 LOCAL_MOUNT_2
="/tmp/resources"
407 LOCAL_MOUNT_3
="/tmp/testsuite"
412 docker run
-ti --entrypoint /bin
/bash \
413 --env OSM_HOSTNAME
=${OSM_HOSTNAME} \
414 --env PROMETHEUS_HOSTNAME
=${PROMETHEUS_HOSTNAME} \
415 --env PROMETHEUS_PORT
=${PROMETHEUS_PORT} \
416 --env JUJU_PASSWORD
=${JUJU_PASSWORD} \
417 --env HOSTIP
=${HOSTIP} \
418 --env-file robot-systest.cfg \
419 -v "$(pwd)/robot.etc.hosts":/etc
/hosts \
420 -v ~
/.osm
/microk8s-config.yaml
:/root
/.kube
/config \
421 -v "$(pwd)/clouds.yaml":/etc
/openstack
/clouds.yaml \
422 -v "${HOME}/snap/qhttp/common"/robot-systest
/reports \
423 -v "${HOME}/snap/qhttp/common:"/robot-systest
/conformance-tests
/reports \
424 -v "${ROOTDIR}/tests/robot-systest/lib":${LOCAL_MOUNT_1} \
425 -v "${ROOTDIR}/tests/robot-systest/resources":${LOCAL_MOUNT_2} \
426 -v "${ROOTDIR}/tests/robot-systest/testsuite":${LOCAL_MOUNT_3} \
427 opensourcemano
/tests
:$OSM_TESTS_IMAGE_TAG
430 function update_osm_module
() {
431 MODULES
=$
(_find_module_dockerfile
$1)
432 for MODULE
in ${MODULES} ; do
434 echo "Updating ${MODULE}"
435 juju attach-resource
${MODULE} image
=localhost
:32000/opensourcemano
/${MODULE}:devel
439 if [ "$0" != "$BASH_SOURCE" ]; then
443 OPTIONS
=$
(show_help |
sed '0,/^OPTIONS:$/d' |
awk '{print $1}')
444 COMPREPLY
=($
(compgen
-W "${OPTIONS}" -- "${COMP_WORDS[-1]}"))
447 THIS_SCRIPT
="$(basename ${BASH_SOURCE[0]})"
448 echo "Setting up bash completion for ${THIS_SCRIPT}"
449 complete
-F _osm_local_build
"${THIS_SCRIPT}"
454 eval "${INSTALL_HTTPD}"
455 eval "${INSTALL_LOCAL_REGISTRY}"
456 eval "${INSTALL_MICROSTACK}"
459 eval "${REGISTRY_PUSH}"
460 eval "${INSTALL_OSM}"
461 eval "${UPDATE_INSTALL}"
462 eval "${START_ROBOT}"