Merge "Refactor ccache config to use per-os ccache dirs."
[ci-management.git] / docker / scripts / lib_apt.sh
1 # lib_apt.sh - Docker build script apt library.
2 #              For import only.
3
4 # Copyright (c) 2021 Cisco and/or its affiliates.
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 # Don't import more than once.
18 if [ -n "$(alias lib_apt_imported 2> /dev/null)" ] ; then
19     return 0
20 fi
21 alias lib_apt_imported=true
22
23 export CIMAN_DOCKER_SCRIPTS=${CIMAN_DOCKER_SCRIPTS:-"$(dirname $BASH_SOURCE)"}
24 . "$CIMAN_DOCKER_SCRIPTS/lib_common.sh"
25 . "$CIMAN_DOCKER_SCRIPTS/lib_csit.sh"
26
27 dump_apt_package_list() {
28     branchname="$(echo $branch | sed -e 's,/,_,')"
29     dpkg -l > \
30          "$DOCKER_BUILD_LOG_DIR/$FDIOTOOLS_IMAGENAME-$branchname-apt-packages.log"
31 }
32
33 apt_install_packages() {
34     apt-get install -y --allow-downgrades --allow-remove-essential \
35             --allow-change-held-packages $@
36 }
37
38 # Used for older OS distro's which are incompatible
39 # with modern distro cmake vesrion
40 apt_override_cmake_install_with_pip3_version() {
41     local os_cmake="/usr/bin/cmake"
42     local os_cmake_ver="$($os_cmake --version | head -1)"
43     local pip3_cmake="/usr/local/bin/cmake"
44
45     python3 -m pip --disable-pip-version-check install cmake || true
46     local pip3_cmake_ver="$($pip3_cmake --version | head -1)"
47     echo_log "Overriding $OS_NAME '$os_cmake_ver' with '$pip3_cmake_ver'!"
48     apt-get remove -y cmake --autoremove || true
49     update-alternatives --quiet --remove-all cmake || true
50     update-alternatives --quiet --install "$os_cmake" cmake "$pip3_cmake" 100
51     echo_log "Default cmake ($(which cmake)) version: '$(cmake --version | head -1)'!"
52 }
53
54 generate_apt_dockerfile_common() {
55     local executor_class="$1"
56     local executor_image="$2"
57         debian_docker_inst_sed="| sed -e 's/has_rootless_extras="1"//g' | sh
58 "
59     cat <<EOF >>"$DOCKERFILE"
60
61 # Create download dir to cache external tarballs
62 WORKDIR $DOCKER_DOWNLOADS_DIR
63
64 # Copy-in temporary build tree containing
65 # ci-management, vpp, & csit git repos
66 WORKDIR $DOCKER_BUILD_DIR
67 COPY . .
68
69 # Build Environment Variables
70 ENV DEBIAN_FRONTEND="noninteractive"
71 ENV FDIOTOOLS_IMAGE="$executor_image"
72 ENV FDIOTOOLS_EXECUTOR_CLASS="$executor_class"
73 ENV CIMAN_ROOT="$DOCKER_CIMAN_ROOT"
74 ENV PATH="\$PATH:$DOCKER_CIMAN_ROOT/docker/scripts"
75
76 # Configure locales
77 RUN apt-get update -qq \\
78   && apt-get install -y \\
79         apt-utils \\
80         locales \\
81   && sed -i 's/# \(en_US\.UTF-8 .*\)/\1/' /etc/locale.gen \\
82   && locale-gen en_US.UTF-8 \\
83   && dpkg-reconfigure --frontend=noninteractive locales \\
84   && update-locale LANG=en_US.UTF-8 \\
85   && TZ=Etc/UTC && ln -snf /usr/share/zoneinfo/\$TZ /etc/localtime && echo \$TZ > /etc/timezone \\
86   && rm -r /var/lib/apt/lists/*
87 ENV LANG="en_US.UTF-8" LANGUAGE="en_US" LC_ALL="en_US.UTF-8"
88
89 # Install baseline packages (minimum build & utils).
90 #
91 # ci-management global-jjb requirements:
92 #        facter
93 #        python3-pip
94 #        python3-venv
95 #    for lftools:
96 #        xmlstarlet
97 #        libxml2-dev
98 #        libxslt-dev
99 #   from packer/provision/baseline.sh:
100 #        unzip
101 #        xz-utils
102 #        git
103 #        git-review
104 #        libxml2-dev
105 #        libxml-xpath-perl
106 #        libxslt-dev
107 #        make
108 #        wget
109 #        jq
110 #
111 # Python build from source requirements:
112 #        build-essential
113 #
114 # TODO:  Fix broken project requirement install targets
115 #        graphviz         for 'make bootstrap-doxygen' (VPP)
116 #        doxygen          for 'make doxygen' (VPP)
117 #        enchant          for 'make docs' (VPP)
118 #        libffi-dev       for python cffi install (Ubuntu20.04/VPP/aarch64)
119 #        liblapack-dev    for python numpy/scipy (CSIT/aarch64)
120 #        libopenblas-dev  for python numpy/scipy (CSIT/aarch64)
121 #        libpcap-dev      for python pypcap install (CSIT)
122 #        sshpass          for CSIT jobs
123 #
124 #        From .../csit/resources/tools/presentation/run_report_*.sh:
125 #        libxml2
126 #        libxml2-dev
127 #        libxslt-dev
128 #        build-essential
129 #        zlib1g-dev
130 #        unzip
131 #        xvrb
132 #        texlive-latex-recommended
133 #        texlive-fonts-recommended
134 #        texlive-fonts-extra
135 #        texlive-latex-extra
136 #        latexmk
137 #        wkhtmltopdf
138 #        inkscape
139 #
140 RUN apt-get update -qq \\
141   && apt-get install -y \\
142              apt-transport-https \\
143              curl \\
144              ca-certificates \\
145              default-jdk \\
146              default-jre \\
147              dnsutils \\
148              doxygen \\
149              enchant \\
150              emacs \\
151              facter \\
152              gawk \\
153              gdb \\
154              gfortran \\
155              git \\
156              git-review \\
157              gnupg-agent \\
158              graphviz \\
159              inkscape \\
160              iproute2 \\
161              iputils-clockdiff \\
162              iputils-ping \\
163              iputils-tracepath \\
164              jq \\
165              latexmk \\
166              libffi-dev \\
167              liblapack-dev \\
168              libopenblas-dev \\
169              libpcap-dev \\
170              libxml2 \\
171              libxml2-dev \\
172              libxml-xpath-perl \\
173              libxslt-dev \\
174              make \\
175              python3-pip \\
176              python3-venv \\
177              rsync \\
178              ruby-dev \\
179              software-properties-common \\
180              sshpass \\
181              sudo \\
182              texlive-fonts-extra \\
183              texlive-fonts-recommended \\
184              texlive-latex-extra \\
185              texlive-latex-recommended \\
186              traceroute \\
187              tree \\
188              unzip \\
189              vim \\
190              wget \\
191              wkhtmltopdf \\
192              xmlstarlet \\
193              xvfb \\
194              xz-utils \\
195              zlib1g-dev \\
196   && curl -L https://packagecloud.io/fdio/master/gpgkey | apt-key add - \\
197   && curl -s https://packagecloud.io/install/repositories/fdio/master/script.deb.sh | bash \\
198 EOF
199     # Hack to prevent failure on debian-9 build
200     head $DOCKERFILE
201     if grep -qe 'debian:9' "$DOCKERFILE" ; then
202         echo "  && curl -fsSL https://get.docker.com | sed -e 's/has_rootless_extras=\"1\"//g' | sh \ " >>"$DOCKERFILE"
203     else
204         echo "  && curl -fsSL https://get.docker.com | sh \ " >>"$DOCKERFILE"
205     fi
206
207     cat <<EOF >>"$DOCKERFILE"
208   && rm -r /var/lib/apt/lists/*
209
210 # Install packages for all project branches
211 #
212 RUN apt-get update -qq \\
213   && dbld_vpp_install_packages.sh \\
214   && dbld_csit_install_packages.sh \\
215   && rm -r /var/lib/apt/lists/*
216 EOF
217 }
218
219 generate_apt_dockerfile_clean() {
220     cat <<EOF >>"$DOCKERFILE"
221
222 # Clean up copy-in build tree
223 RUN dbld_dump_build_logs.sh \\
224   && rm -rf "/tmp/*" "$DOCKER_BUILD_FILES_DIR" "/root/.ccache"
225 EOF
226 }
227
228 # Generate 'builder' class apt dockerfile
229 builder_generate_apt_dockerfile() {
230     local executor_class="$1"
231     local executor_os_name="$2"
232     local executor_image="$3"
233     local vpp_install_skip_sysctl_envvar="";
234
235     if grep -q "debian-9"  <<< "$executor_os_name" ; then
236         # Workaround to VPP package installation failure on debian-9
237         vpp_install_skip_sysctl_envvar="ENV VPP_INSTALL_SKIP_SYSCTL=1"
238     fi
239     generate_apt_dockerfile_common $executor_class $executor_image
240     csit_builder_generate_docker_build_files
241     cat <<EOF >>"$DOCKERFILE"
242
243 # Install LF-IT requirements
244 ENV LF_VENV="/root/lf-venv"
245 RUN apt-get update -qq \\
246   && dbld_lfit_requirements.sh \\
247   && rm -r /var/lib/apt/lists/*
248
249 # Install packagecloud requirements
250 RUN gem install rake package_cloud \\
251   && curl -s https://packagecloud.io/install/repositories/fdio/master/script.deb.sh | bash
252
253 # Install CSIT ssh requirements
254 # TODO: Verify why badkey is required & figure out how to avoid it.
255 COPY files/badkey /root/.ssh/id_rsa
256 COPY files/sshconfig /root/.ssh/config
257
258 # CI Runtime Environment
259 WORKDIR /
260 $vpp_install_skip_sysctl_envvar
261 ENV VPP_ZOMBIE_NOCHECK="1"
262 ENV CCACHE_DIR="/scratch/ccache"
263 ENV CCACHE_MAXSIZE="10G"
264 EOF
265     generate_apt_dockerfile_clean
266 }
267
268 # Generate 'csit_dut' class apt dockerfile
269 csit_dut_generate_apt_dockerfile() {
270     local executor_class="$1"
271     local executor_os_name="$2"
272     local executor_image="$3"
273
274     csit_dut_generate_docker_build_files
275     generate_apt_dockerfile_common "$executor_class" "$executor_image"
276     cat <<EOF >>"$DOCKERFILE"
277
278 # Install csit_dut specific packages
279 RUN apt-get update -qq \\
280   && apt-get install -y \\
281              net-tools \\
282              openssh-server \\
283              pciutils \\
284              rsyslog \\
285              supervisor \\
286   && rm -r /var/lib/apt/lists/*
287
288 # Fix permissions
289 RUN chown root:syslog /var/log \\
290   && chmod 755 /etc/default
291
292 # Create directory structure
293 RUN mkdir -p /var/run/sshd
294
295 # SSH settings
296 RUN echo 'root:Csit1234' | chpasswd \\
297   && sed -i 's/#PermitRootLogin prohibit-password/PermitRootLogin yes/' /etc/ssh/sshd_config \\
298   && sed 's@session\s*required\s*pam_loginuid.so@session optional pam_loginuid.so@g' -i /etc/pam.d/sshd
299
300 EXPOSE 2222
301
302 COPY files/supervisord.conf /etc/supervisor/supervisord.conf
303
304 CMD ["sh", "-c", "rm -f /dev/shm/db /dev/shm/global_vm /dev/shm/vpe-api; /usr/bin/supervisord -c /etc/supervisor/supervisord.conf; /usr/sbin/sshd -D -p 2222"]
305 EOF
306     generate_apt_dockerfile_clean
307 }
308
309 # Generate 'csit_shim' class apt dockerfile
310 csit_shim_generate_apt_dockerfile() {
311     local executor_class="$1"
312     local executor_os_name="$2"
313     local executor_image="$3"
314
315     csit_shim_generate_docker_build_files
316     cat <<EOF >>"$DOCKERFILE"
317
318 # Copy-in temporary build tree containing
319 # ci-management, vpp, & csit git repos
320 WORKDIR $DOCKER_BUILD_DIR
321 COPY . .
322
323 # Build Environment Variables
324 ENV DEBIAN_FRONTEND="noninteractive"
325 ENV FDIOTOOLS_IMAGE="$executor_image"
326 ENV FDIOTOOLS_EXECUTOR_CLASS="$executor_class"
327 ENV CIMAN_ROOT="$DOCKER_CIMAN_ROOT"
328 ENV PATH="\$PATH:$DOCKER_CIMAN_ROOT/docker/scripts"
329
330 # Configure locales & timezone
331 RUN apt-get update -qq \\
332   && apt-get install -y \\
333              apt-utils \\
334              locales \\
335   && sed -i 's/# \(en_US\.UTF-8 .*\)/\1/' /etc/locale.gen \\
336   && locale-gen en_US.UTF-8 \\
337   && dpkg-reconfigure --frontend=noninteractive locales \\
338   && update-locale LANG=en_US.UTF-8 \\
339   && TZ=Etc/UTC && ln -snf /usr/share/zoneinfo/\$TZ /etc/localtime && echo \$TZ > /etc/timezone \\
340   && rm -r /var/lib/apt/lists/*
341 ENV LANG=en_US.UTF-8 LANGUAGE=en_US LC_ALL=en_US.UTF-8
342
343 COPY files/wrapdocker /usr/local/bin/wrapdocker
344 RUN chmod +x /usr/local/bin/wrapdocker
345
346 # Install packages and Docker
347 RUN apt-get update -qq \\
348   && apt-get install -y  \\
349              bash \\
350              curl \\
351              iproute2 \\
352              locales \\
353              ssh \\
354              sudo \\
355              tzdata \\
356              uuid-runtime \\
357   && curl -fsSL https://get.docker.com | sh \\
358   && rm -rf /var/lib/apt/lists/*
359
360 RUN mkdir /var/run/sshd
361 RUN echo 'root:Csit1234' | chpasswd
362 RUN sed -i 's/#PermitRootLogin prohibit-password/PermitRootLogin yes/' /etc/ssh/sshd_config
363
364 # SSH login fix. Otherwise user is kicked off after login
365 RUN sed 's@session\s*required\s*pam_loginuid.so@session optional pam_loginuid.so@g' -i /etc/pam.d/sshd
366
367 # Need volume for sidecar docker launches
368 VOLUME /var/lib/docker
369
370 # SSH to listen on port 6022 in shim
371 RUN echo 'Port 6022' >>/etc/ssh/sshd_config
372 RUN echo 'Port 6023' >>/etc/ssh/sshd_config
373
374 # TODO: Verify why badkeypub is required & figure out how to avoid it.
375 COPY files/badkeypub /root/.ssh/authorized_keys
376 COPY files/sshconfig /root/.ssh/config
377
378 # Clean up copy-in build tree
379 RUN rm -rf /tmp/* $DOCKER_BUILD_FILES_DIR
380
381 # Start sshd by default
382 EXPOSE 22
383 CMD ["/usr/sbin/sshd", "-D"]
384 EOF
385 }
386
387 generate_apt_dockerfile() {
388     local executor_class="$1"
389     local executor_os_name="$2"
390     local from_image="$3"
391     local executor_image="$4"
392
393     cat <<EOF  >"$DOCKERIGNOREFILE"
394 **/__pycache__
395 *.pyc
396 EOF
397     cat <<EOF  >"$DOCKERFILE"
398 FROM $from_image AS ${executor_class}-executor-image
399 LABEL Description="FD.io CI '$executor_class' executor docker image for $executor_os_name/$OS_ARCH"
400 LABEL Vendor="fd.io"
401 LABEL Version="$DOCKER_TAG"
402 EOF
403     ${executor_class}_generate_apt_dockerfile "$executor_class" \
404         "$executor_os_name" "$executor_image"
405 }