build_inf_debian.sh: add parallel option
[pti/rtp.git] / scripts / build_inf_debian / build_inf_debian.sh
1 #!/bin/bash
2 #
3 # Copyright (C) 2022 Wind River Systems, Inc.
4 #
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
8 #
9 #      http://www.apache.org/licenses/LICENSE-2.0
10 #
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 implied.
14 #  See the License for the specific language governing permissions and
15 #  limitations under the License.
16
17 # Ensure we fail the job if any steps fail.
18 set -e -o pipefail
19
20 #########################################################################
21 # Variables
22 #########################################################################
23
24 SRC_ORAN_BRANCH="master"
25
26 SRC_ORAN_URL="https://gerrit.o-ran-sc.org/r/pti/rtp"
27
28 STX_VER="8.0"
29 ORAN_REL="ORAN G-Release (${STX_VER})"
30
31 SCRIPTS_DIR=$(dirname $(readlink -f $0))
32 SCRIPTS_NAME=$(basename $0)
33 TIMESTAMP=`date +"%Y%m%d_%H%M%S"`
34
35 #########################################################################
36 # Common Functions
37 #########################################################################
38
39 help_info () {
40 cat << ENDHELP
41 Usage:
42 ${SCRIPTS_NAME} [-w WORKSPACE_DIR] [-p PARALLEL_BUILD] [-m] [-n] [-u] [-h]
43 where:
44     -w WORKSPACE_DIR is the path for the project
45     -p PARALLEL_BUILD is the num of paralle build, default is 2
46     -m use mirror for src and deb pkgs
47     -n dry-run only for bitbake
48     -h this help info
49 examples:
50 $0
51 $0 -w workspace_1234
52 ENDHELP
53 }
54
55 echo_step_start() {
56     [ -n "$1" ] && msg_step=$1
57     echo "#########################################################################################"
58     echo "## ${SCRIPTS_NAME} - STEP START: ${msg_step}"
59     echo "#########################################################################################"
60 }
61
62 echo_step_end() {
63     [ -n "$1" ] && msg_step=$1
64     echo "#########################################################################################"
65     echo "## ${SCRIPTS_NAME} - STEP END: ${msg_step}"
66     echo "#########################################################################################"
67     echo
68 }
69
70 echo_info () {
71     echo "INFO: $1"
72 }
73
74 echo_error () {
75     echo "ERROR: $1"
76 }
77
78 run_cmd () {
79     echo
80     echo_info "$1"
81     echo "CMD: ${RUN_CMD}"
82     ${RUN_CMD}
83 }
84
85 #########################################################################
86 # Parse cmd options
87 #########################################################################
88
89 DRYRUN=""
90 USE_MIRROR="No"
91 REUSE_APTLY=""
92 STX_PARALLEL="2"
93
94 while getopts "w:p:mnh" OPTION; do
95     case ${OPTION} in
96         w)
97             WORKSPACE=`readlink -f ${OPTARG}`
98             ;;
99         p)
100             STX_PARALLEL="${OPTARG}"
101             ;;
102         n)
103             DRYRUN="-n"
104             ;;
105         m)
106             USE_MIRROR="Yes"
107             REUSE_APTLY="--reuse"
108             ;;
109         h)
110             help_info
111             exit
112             ;;
113     esac
114 done
115
116 if [ -z ${WORKSPACE} ]; then
117     echo_info "No workspace specified, a directory 'workspace' will be created in current directory as the workspace"
118     WORKSPACE=`readlink -f workspace`
119 fi
120
121 #########################################################################
122 # Functions for each step
123 #########################################################################
124
125 # "_" can't be used in project name
126 PRJ_NAME=prj-oran-stx-deb
127
128 # stx 8.0 is not released yet
129 #STX_SRC_BRANCH="r/stx.${STX_VER}"
130
131 # Temporary for master
132 STX_TAG="master-1ba0db8"
133 STX_SRC_BRANCH="master"
134
135 STX_LOCAL_DIR=${WORKSPACE}/localdisk
136 STX_LOCAL_SRC_DIR=${STX_LOCAL_DIR}/designer/${USER}/${PRJ_NAME}
137 STX_LOCAL_PRJ_DIR=${STX_LOCAL_DIR}/loadbuild/${USER}/${PRJ_NAME}
138 STX_SRC_DIR=${WORKSPACE}/src
139 STX_PRJ_DIR=${WORKSPACE}/${PRJ_NAME}
140 STX_PRJ_OUTPUT=${WORKSPACE}/prj_output
141 STX_MIRROR_DIR=${WORKSPACE}/mirrors
142 STX_APTLY_DIR=${WORKSPACE}/aptly
143 STX_MINIKUBE_HOME=${WORKSPACE}/minikube_home
144 STX_MANIFEST_URL="https://opendev.org/starlingx/manifest"
145
146 #MIRROR_SRC_STX=infbuilder/inf-src-stx:${STX_VER}
147 MIRROR_SRC_STX=infbuilder/inf-src-stx:${STX_TAG}
148 MIRROR_CONTAINER_IMG=infbuilder/inf-debian-mirror:2022.11-stx-${STX_VER}
149 MIRROR_APTLY_IMG=infbuilder/inf-debian-aptly:2022.11-stx-${STX_VER}
150
151 STX_SHARED_REPO=http://mirror.starlingx.cengn.ca/mirror/starlingx/master/debian/monolithic/20221123T070000Z/outputs/aptly/deb-local-build/
152 STX_SHARED_SOURCE=http://mirror.starlingx.cengn.ca/mirror/starlingx/master/debian/monolithic/20221123T070000Z/outputs/aptly/deb-local-source/
153
154 SRC_ORAN_DIR=${STX_SRC_DIR}/rtp
155 SRC_META_PATCHES=${SRC_ORAN_DIR}/scripts/build_inf_debian/meta-patches
156
157 ISO_INF_DEB=inf-image-debian-all-x86-64.iso
158
159 prepare_workspace () {
160     msg_step="Create workspace for the Debian build"
161     echo_step_start
162
163     mkdir -p ${STX_LOCAL_SRC_DIR} ${STX_LOCAL_PRJ_DIR} ${STX_MIRROR_DIR} \
164         ${STX_APTLY_DIR} ${STX_PRJ_OUTPUT} ${STX_MINIKUBE_HOME}
165     rm -f ${STX_SRC_DIR} ${STX_PRJ_DIR}
166     ln -sf $(realpath --relative-to=${WORKSPACE} ${STX_LOCAL_SRC_DIR}) ${STX_SRC_DIR}
167     ln -sf $(realpath --relative-to=${WORKSPACE} ${STX_LOCAL_PRJ_DIR}) ${STX_PRJ_DIR}
168
169     echo_info "The following directories are created in your workspace(${WORKSPACE}):"
170     echo_info "For all source repos: ${STX_SRC_DIR}"
171     echo_info "For StarlingX deb pkgs mirror: ${STX_MIRROR_DIR}"
172     echo_info "For StarlingX build project: ${STX_PRJ_DIR}"
173
174     echo_step_end
175 }
176
177 create_env () {
178     msg_step="Create env file for the Debian build"
179     echo_step_start
180
181     ENV_FILENAME=env.${PRJ_NAME}
182
183     cat <<EOF > ${WORKSPACE}/${ENV_FILENAME}
184
185 export STX_BUILD_HOME=${WORKSPACE}
186 export PROJECT=${PRJ_NAME}
187 export STX_MIRROR_DIR=${STX_MIRROR_DIR}
188 export STX_REPO_ROOT=${STX_SRC_DIR}
189 #export STX_REPO_ROOT_SUBDIR="localdisk/designer/${USER}/${PRJ_NAME}"
190
191 export USER_NAME=${USER}
192 export USER_EMAIL=${USER}@windriver.com
193
194 # MINIKUBE
195 export STX_PLATFORM="minikube"
196 export STX_MINIKUBENAME="minikube-${USER}"
197 export MINIKUBE_HOME=${STX_MINIKUBE_HOME}
198
199 # Manifest/Repo Options:
200 export STX_MANIFEST_URL="${STX_MANIFEST_URL}"
201 export STX_MANIFEST_BRANCH="master"
202 export STX_MANIFEST="default.xml"
203
204 EOF
205
206     echo_info "Env file created at ${WORKSPACE}/$ENV_FILENAME"
207     cat ${WORKSPACE}/$ENV_FILENAME
208
209     source ${WORKSPACE}/${ENV_FILENAME}
210
211     git config --global user.email "${USER_EMAIL}"
212     git config --global user.name "${USER_NAME}"
213     git config --global color.ui false
214
215     echo_step_end
216 }
217
218 repo_init_sync () {
219     msg_step="Init the repo and sync"
220     echo_step_start
221
222     # Avoid the colorization prompt
223     git config --global color.ui false
224
225     if [ -d ${STX_REPO_ROOT}/.repo ]; then
226         echo_info "the src repos already exists, skipping"
227     else
228         cd ${STX_REPO_ROOT}
229
230         RUN_CMD="repo init -u ${STX_MANIFEST_URL} -b ${STX_SRC_BRANCH} -m ${STX_MANIFEST}"
231         run_cmd "Init the repo from manifest"
232
233         RUN_CMD="repo sync --force-sync"
234         run_cmd "repo sync"
235
236         touch .repo-init-done
237     fi
238
239     echo_step_end
240 }
241
242 get_mirror_src () {
243     msg_step="Get src mirror from dockerhub image"
244     echo_step_start
245
246     if [ -d ${STX_REPO_ROOT}/.repo ]; then
247         echo_info "the src repos already exists, skipping"
248     else
249         docker pull ${MIRROR_SRC_STX}
250         docker create -ti --name inf-src-stx ${MIRROR_SRC_STX} sh
251         #docker cp inf-src-stx:/stx-${STX_VER}.tar.bz2 ${STX_REPO_ROOT}
252         docker cp inf-src-stx:/stx-${STX_TAG}.tar.bz2 ${STX_REPO_ROOT}
253         docker rm inf-src-stx
254
255         cd ${STX_REPO_ROOT}
256         #tar xf stx-${STX_VER}.tar.bz2
257         #mv stx-${STX_VER}/* stx-${STX_VER}/.repo .
258         #rm -rf stx-${STX_VER} stx-${STX_VER}.tar.bz2
259         tar xf stx-${STX_TAG}.tar.bz2
260         mv stx-${STX_SRC_BRANCH}/* stx-${STX_SRC_BRANCH}/.repo .
261         rm -rf stx-${STX_SRC_BRANCH} stx-${STX_TAG}.tar.bz2
262         touch .repo-init-done
263
264     fi
265
266     echo_step_end
267 }
268
269 get_mirror_pkg () {
270     msg_step="Get deb mirror from dockerhub image"
271     echo_step_start
272
273     if [ -d ${STX_MIRROR_DIR}/starlingx ]; then
274         echo_info "The deb mirror already exists, skipping"
275     else
276         docker pull ${MIRROR_CONTAINER_IMG}
277         docker create -ti --name inf-debian-mirror ${MIRROR_CONTAINER_IMG} sh
278         docker cp inf-debian-mirror:/mirror-stx-${STX_VER}/. ${STX_MIRROR_DIR}
279         docker rm inf-debian-mirror
280     fi
281
282     echo_step_end
283 }
284
285 get_mirror_aptly () {
286     msg_step="Get deb mirror aptly from dockerhub image"
287     echo_step_start
288
289     if [ -f ${STX_APTLY_DIR}/aptly.conf ]; then
290         echo_info "The deb aptly already exists, skipping"
291     else
292         docker pull ${MIRROR_APTLY_IMG}
293         docker create -ti --name inf-debian-aptly ${MIRROR_APTLY_IMG} sh
294         docker cp inf-debian-aptly:/aptly-stx-${STX_VER}/. ${STX_APTLY_DIR}
295         docker rm inf-debian-aptly
296     fi
297
298     echo_step_end
299 }
300
301 clone_update_repo () {
302     REPO_BRANCH=$1
303     REPO_URL=$2
304     REPO_NAME=$3
305     REPO_COMMIT=$4
306
307     if [ -d ${REPO_NAME}/.git ]; then
308         if [ "${SKIP_UPDATE}" == "Yes" ]; then
309             echo_info "The repo ${REPO_NAME} exists, skip updating for the branch ${REPO_BRANCH}"
310         else
311             echo_info "The repo ${REPO_NAME} exists, updating for the branch ${REPO_BRANCH}"
312             cd ${REPO_NAME}
313             git checkout ${REPO_BRANCH}
314             git pull
315             cd -
316         fi
317     else
318         RUN_CMD="git clone --branch ${REPO_BRANCH} ${REPO_URL} ${REPO_NAME}"
319         run_cmd "Cloning the source of repo '${REPO_NAME}':"
320
321         if [ -n "${REPO_COMMIT}" ]; then
322             cd ${REPO_NAME}
323             RUN_CMD="git checkout -b ${REPO_BRANCH}-${REPO_COMMIT} ${REPO_COMMIT}"
324             run_cmd "Checkout the repo ${REPO_NAME} to specific commit: ${REPO_COMMIT}"
325             cd -
326         fi
327     fi
328 }
329
330
331 prepare_src () {
332     msg_step="Get the source code repos"
333     echo_step_start
334
335     # Clone the oran inf source if it's not already cloned
336     # Check if the script is inside the repo
337     if cd ${SCRIPTS_DIR} && git rev-parse --is-inside-work-tree > /dev/null 2>&1; then
338         CLONED_ORAN_REPO=`git rev-parse --show-toplevel`
339         echo_info "Use the cloned oran repo: ${CLONED_ORAN_REPO}"
340         mkdir -p ${SRC_ORAN_DIR}
341         cd ${SRC_ORAN_DIR}
342         rm -rf scripts
343         ln -sf ${CLONED_ORAN_REPO}/scripts scripts
344     else
345         echo_info "Cloning oran layer:"
346         cd ${STX_SRC_DIR}
347         clone_update_repo ${SRC_ORAN_BRANCH} ${SRC_ORAN_URL} rtp
348     fi
349
350     if [ "${USE_MIRROR}" == "Yes" ]; then
351         get_mirror_src
352         get_mirror_pkg
353         get_mirror_aptly
354     else
355         repo_init_sync
356     fi
357     patch_src
358
359     echo_step_end
360 }
361
362
363 patch_src () {
364     echo_step_start "Patching source codes for INF project"
365
366     STX_ISSUE_DIR="${STX_REPO_ROOT}/cgcs-root/stx/config-files/debian-release-config/files"
367     echo_info "Patching for the ${STX_ISSUE_DIR}"
368     grep -q "${ORAN_REL}" ${STX_ISSUE_DIR}/issue* \
369         || sed -i "s/\(@PLATFORM_RELEASE@\)/\1 - ${ORAN_REL}/" ${STX_ISSUE_DIR}/issue*
370
371     STX_BUILDER="${STX_REPO_ROOT}/stx-tools/stx/lib/stx/stx_build.py"
372     echo_info "Patching for the ${STX_BUILDER}"
373     grep -q "\-\-parallel" ${STX_BUILDER} \
374         || sed -i "s/\(build-pkgs -a \)/\1 --parallel ${STX_PARALLEL} ${REUSE_APTLY}/" \
375         ${STX_BUILDER}
376
377     STX_LOCALRC="${STX_REPO_ROOT}/stx-tools/stx/stx-build-tools-chart/stx-builder/configmap/localrc.sample"
378     echo_info "Patching for the localrc file"
379     echo "export STX_SHARED_REPO=${STX_SHARED_REPO}" >> ${STX_LOCALRC}
380     echo "export STX_SHARED_SOURCE=${STX_SHARED_SOURCE}" >> ${STX_LOCALRC}
381
382     # Apply meta patches
383     if [ -d ${SRC_META_PATCHES} ]; then
384         cd ${SRC_META_PATCHES}
385         src_dirs=$(find . -type f -printf "%h\n"|uniq)
386         for d in ${src_dirs}; do
387             cd ${STX_REPO_ROOT}/${d}
388
389             # backup current branch
390             local_branch=$(git rev-parse --abbrev-ref HEAD)
391             if [ "${local_branch}" = "HEAD" ]; then
392                 git checkout ${STX_SRC_BRANCH}
393                 local_branch=$(git rev-parse --abbrev-ref HEAD)
394             fi
395             git branch -m "${local_branch}_${TIMESTAMP}"
396             git checkout ${STX_SRC_BRANCH}
397
398             for p in $(ls -1 ${SRC_META_PATCHES}/${d}); do
399                 echo_info "Apllying patch: ${SRC_META_PATCHES}/${d}/${p}"
400                 git am ${SRC_META_PATCHES}/${d}/${p}
401             done
402         done
403     fi
404
405     echo_step_end
406 }
407
408 init_stx_tool () {
409     echo_step_start "Init stx tool"
410
411     cd ${STX_REPO_ROOT}
412     cd stx-tools
413     cp stx.conf.sample stx.conf
414     source import-stx
415
416     # Update stx config
417     # Align the builder container to use your user/UID
418     stx config --add builder.myuname $(id -un)
419     stx config --add builder.uid $(id -u)
420
421     # Embedded in ~/localrc of the build container
422     stx config --add project.gituser ${USER_NAME}
423     stx config --add project.gitemail ${USER_EMAIL}
424
425     # This will be included in the name of your build container and the basename for $STX_REPO_ROOT
426     stx config --add project.name ${PRJ_NAME}
427
428     #stx config --add project.proxy true
429     #stx config --add project.proxyserver 147.11.252.42
430     #stx config --add project.proxyport 9090
431
432     stx config --show
433
434     echo_step_end
435 }
436
437 build_image () {
438     echo_step_start "Build Debian images"
439
440     cd ${STX_REPO_ROOT}/stx-tools
441     RUN_CMD="./stx-init-env"
442     run_cmd "Run stx-init-env script"
443
444     stx control status
445
446     # wait for all the pods running
447     sleep 600
448     stx control status
449
450     RUN_CMD="stx build prepare"
451     run_cmd "Build prepare"
452
453     RUN_CMD="stx build download"
454     run_cmd "Download packges"
455
456     RUN_CMD="stx repomgr list"
457     run_cmd "repomgr list"
458
459     RUN_CMD="stx build world"
460     run_cmd "Build-pkgs"
461
462     RUN_CMD="stx build image"
463     run_cmd "Build ISO image"
464
465     cp -f ${STX_LOCAL_DIR}/deploy/starlingx-intel-x86-64-cd.iso ${STX_PRJ_OUTPUT}/${ISO_INF_DEB}
466
467     echo_step_end
468
469     echo_info "Build succeeded, you can get the image in ${STX_PRJ_OUTPUT}/${ISO_INF_DEB}"
470 }
471
472 #########################################################################
473 # Main process
474 #########################################################################
475
476 prepare_workspace
477 create_env
478 prepare_src
479 init_stx_tool
480 build_image