CSIT-1282 Migrate from Nexus.fd.io to packagecloud.io
[csit.git] / resources / libraries / bash / function / gather.sh
1 # Copyright (c) 2018 Cisco and/or its affiliates.
2 # Licensed under the Apache License, Version 2.0 (the "License");
3 # you may not use this file except in compliance with the License.
4 # You may obtain a copy of the License at:
5 #
6 #     http://www.apache.org/licenses/LICENSE-2.0
7 #
8 # Unless required by applicable law or agreed to in writing, software
9 # distributed under the License is distributed on an "AS IS" BASIS,
10 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11 # See the License for the specific language governing permissions and
12 # limitations under the License.
13
14 set -exuo pipefail
15
16 # This library defines functions used mainly by "bootstrap" entry scripts.
17 # Generally, the functions assume "common.sh" library has been sourced already.
18
19 # Keep functions ordered alphabetically, please.
20
21 # TODO: Add a link to bash style guide.
22
23
24 function gather_build () {
25
26     set -exuo pipefail
27
28     # Variables read:
29     # - TEST_CODE - String affecting test selection, usually jenkins job name.
30     # - DOWNLOAD_DIR - Path to directory pybot takes the build to test from.
31     # Variables set:
32     # - DUT - CSIT test/ subdirectory containing suites to execute.
33     # Directories updated:
34     # - ${DOWNLOAD_DIR} - Files needed by tests are gathered here.
35     # Functions called:
36     # - die - Print to stderr and exit, defined in common.sh
37     # - gather_dpdk, gather_vpp, gather_ligato - See their definitions.
38     # Multiple other side effects are possible,
39     # see functions called from here for their current description.
40
41     # TODO: Separate DUT-from-TEST_CODE from gather-for-DUT,
42     #   when the first one becomes relevant for per_patch.
43
44     pushd "${DOWNLOAD_DIR}" || die "Pushd failed."
45     case "${TEST_CODE}" in
46         *"hc2vpp"*)
47             DUT="hc2vpp"
48             # FIXME: Avoid failing on empty ${DOWNLOAD_DIR}.
49             ;;
50         *"vpp"*)
51             DUT="vpp"
52             gather_vpp || die "The function should have died on error."
53             ;;
54         *"ligato"*)
55             DUT="kubernetes"
56             gather_ligato || die "The function should have died on error."
57             ;;
58         *"dpdk"*)
59             DUT="dpdk"
60             gather_dpdk || die "The function should have died on error."
61             ;;
62         *)
63             die "Unable to identify DUT type from: ${TEST_CODE}"
64             ;;
65     esac
66     popd || die "Popd failed."
67 }
68
69
70 function gather_dpdk () {
71
72     set -exuo pipefail
73
74     # Ensure latest DPDK archive is downloaded.
75     #
76     # Variables read:
77     # - TEST_CODE - The test selection string from environment or argument.
78     # Hardcoded:
79     # - dpdk archive name to download if TEST_CODE is not time based.
80     # Directories updated:
81     # - ./ - Assumed ${DOWNLOAD_DIR}, dpdk-*.tar.xz is downloaded if not there.
82     # Functions called:
83     # - die - Print to stderr and exit, defined in common.sh
84
85     dpdk_repo="https://fast.dpdk.org/rel"
86     # Use downloaded packages with specific version
87     if [[ "${TEST_CODE}" == *"daily"* ]] || \
88        [[ "${TEST_CODE}" == *"weekly"* ]] || \
89        [[ "${TEST_CODE}" == *"timed"* ]];
90     then
91         echo "Downloading latest DPDK packages from repo..."
92         # URL is not in quotes, calling command from variable keeps them.
93         wget_command=("wget" "--no-check-certificate" "-nv" "-O" "-")
94         wget_command+=("${dpdk_repo}")
95         dpdk_stable_ver="$("${wget_command[@]}" | grep -v "2015"\
96             | grep -Eo 'dpdk-[^\"]+xz' | tail -1)" || {
97             die "Composite piped command failed."
98         }
99     else
100         echo "Downloading DPDK packages of specific version from repo..."
101         # TODO: Can we autodetect this based on what CSIT-stable VPP uses?
102         dpdk_stable_ver="dpdk-18.08.tar.xz"
103     fi
104     # TODO: Use "wget -N" instead checking for file presence?
105     if [[ ! -f "${dpdk_stable_ver}" ]]; then
106         wget -nv --no-check-certificate "${dpdk_repo}/${dpdk_stable_ver}" || {
107             die "Failed to get DPDK package from: ${dpdk_repo}"
108         }
109     fi
110 }
111
112
113 function gather_ligato () {
114
115     set -exuo pipefail
116
117     # Build docker image (with vpp, ligato and vpp-agent),
118     # and put it to ${DOWNLOAD_DIR}/.
119     #
120     # Access rights needed for:
121     # - "wget", "git clone", "dpdk -x", "cd" above ${CSIT_DIR}.
122     # - "sudo" without password.
123     # - With sudo:
124     #   - "dpdk -i" is allowed.
125     #   - "docker" commands have everything they needs.
126     # Variables read:
127     # - DOWNLOAD_DIR - Path to directory pybot takes the build to test from.
128     # - CSIT_DIR - Path to existing root of local CSIT git repository.
129     # Files read:
130     # - ${CSIT_DIR}/VPP_AGENT_STABLE_VER - Vpp agent version to use.
131     # Directories updated:
132     # - ${DOWNLOAD_DIR} - Docker image stored, VPP *.deb stored and deleted.
133     # - /tmp/vpp - VPP is unpacked there, not cleaned afterwards.
134     # - ${CSIT_DIR}/vpp-agent - Created, vpp-agent git repo si cloned there.
135     #   - Also, various temporary files are stored there.
136     # System consequences:
137     # - Docker package is installed.
138     # - Presumably dockerd process is started.
139     # - The ligato/dev-vpp-agent docker image is downloaded.
140     # - Results of subsequent image manipulation are probably left lingering.
141     # Other hardcoded values:
142     # - Docker .deb file name to download and install.
143     # Functions called:
144     # - die - Print to stderr and exit, defined in common_functions.sh
145     # - gather_vpp - See eponymous fragment file assumend to be sourced already.
146     # TODO: What is the best order of description items?
147
148     # TODO: Many of the following comments act as abstraction.
149     #   But the abstracted blocks are mostly one-liners (plus "|| die"),
150     #   so maybe it is not worth introducing fragments/functions for the blocks.
151     # TODO: This fragment is too long anyway, split it up.
152
153     gather_vpp || die "The function should have died on error."
154
155     # Extract VPP API to specific folder
156     # FIXME: Make sure /tmp/vpp/ exists. Should we clean it?
157     dpkg -x "${DOWNLOAD_DIR}/vpp_"*".deb" "/tmp/vpp" || {
158         die "Failed to extract VPP packages for kubernetes!"
159     }
160
161     ligato_repo_url="https://github.com/ligato/"
162     vpp_agent_stable_ver="$(cat "${CSIT_DIR}/VPP_AGENT_STABLE_VER")" || {
163         die "Cat failed."
164     }
165     docker_deb="docker-ce_18.03.0~ce-0~ubuntu_amd64.deb"
166
167     # Clone & checkout stable vpp-agent
168     cd "${CSIT_DIR}" || die "Change directory failed."
169     git clone -b "${vpp_agent_stable_ver}" --single-branch \
170         "${ligato_repo_url}/vpp-agent" "vpp-agent" || {
171         die "Failed to run: git clone ${ligato_repo_url}/vpp-agent!"
172     }
173     cd "vpp-agent" || die "Change directory failed."
174
175     # Install Docker
176     url_prefix="https://download.docker.com/linux/ubuntu/dists/xenial/pool"
177     # URL is not in quotes, calling command from variable keeps them.
178     wget_command=("wget" "-nv" "${url_prefix}/stable/amd64/${docker_deb}")
179     "${wget_command[@]}" || die "Failed to download Docker package!"
180
181     sudo dpkg -i "${docker_deb}" || die "Failed to install Docker!"
182
183     # Pull ligato/dev_vpp_agent docker image and re-tag as local
184     sudo docker pull "ligato/dev-vpp-agent:${vpp_agent_stable_ver}" || {
185         die "Failed to pull Docker image!"
186     }
187
188     first_arg="ligato/dev-vpp-agent:${vpp_agent_stable_ver}"
189     sudo docker tag "${first_arg}" "dev_vpp_agent:latest" || {
190         die "Failed to tag Docker image!"
191     }
192
193     # Start dev_vpp_agent container as daemon
194     sudo docker run --rm -itd --name "agentcnt" "dev_vpp_agent" bash || {
195         die "Failed to run Docker image!"
196     }
197
198     # Copy latest vpp api into running container
199     sudo docker exec agentcnt rm -rf "agentcnt:/usr/share/vpp/api" || {
200         die "Failed to remove previous API!"
201     }
202     sudo docker cp "/tmp/vpp/usr/share/vpp/api" "agentcnt:/usr/share/vpp" || {
203         die "Failed to copy files Docker image!"
204     }
205
206     # Recompile vpp-agent
207     script_arg=". ~/.bashrc; cd /go/src/github.com/ligato/vpp-agent"
208     script_arg+=" && make generate && make install"
209     sudo docker exec -i agentcnt script -qec "${script_arg}" || {
210         die "Failed to recompile vpp-agent in Docker image!"
211     }
212     # Make sure .deb files of other version are not present.
213     rm_cmd="rm -vf /opt/vpp-agent/dev/vpp/build-root/vpp*.deb /opt/vpp/*.deb"
214     sudo docker exec agentcnt bash -c "${rm_cmd}" || {
215         die "Failed to remove VPP debian packages!"
216     }
217     for f in "${DOWNLOAD_DIR}"/*; do
218         sudo docker cp "$f" "agentcnt:/opt/vpp-agent/dev/vpp/build-root"/ || {
219             die "Failed to copy files Docker image!"
220         }
221     done
222     # Save container state
223     sudo docker commit "$(sudo docker ps -q)" "dev_vpp_agent:latest" || {
224         die "Failed to commit state of Docker image!"
225     }
226
227     # Build prod_vpp_agent docker image
228     cd "docker/prod" || die "Change directory failed."
229     sudo docker build --tag "prod_vpp_agent" --no-cache "." || {
230         die "Failed to build Docker image!"
231     }
232     # Export Docker image
233     sudo docker save "prod_vpp_agent" | gzip > "prod_vpp_agent.tar.gz" || {
234         die "Failed to save Docker image!"
235     }
236     docker_image="$(readlink -e "prod_vpp_agent.tar.gz")" || {
237         die "Readlink failed."
238     }
239     rm -r "${DOWNLOAD_DIR}/vpp"* || die "Rm failed."
240     mv "${docker_image}" "${DOWNLOAD_DIR}"/ || die "Mv failed."
241 }
242
243
244 function gather_vpp () {
245
246     set -exuo pipefail
247
248     # Variables read:
249     # - BASH_FUNCTION_DIR - Bash directory with functions.
250     # - TEST_CODE - The test selection string from environment or argument.
251     # - DOWNLOAD_DIR - Path to directory pybot takes the build to test from.
252     # - CSIT_DIR - Path to existing root of local CSIT git repository.
253     # Files read:
254     # - ${CSIT_DIR}/DPDK_STABLE_VER - DPDK version to use
255     #   by csit-vpp not-timed jobs.
256     # - ${CSIT_DIR}/VPP_STABLE_VER_UBUNTU - VPP version to use by those.
257     # - ../vpp*.deb - Relative to ${DOWNLOAD_DIR}, copied for vpp-csit jobs.
258     # Directories updated:
259     # - ${DOWNLOAD_DIR}, vpp-*.deb files are copied here for vpp-csit jobs.
260     # - ./ - Assumed ${DOWNLOAD_DIR}, vpp-*.deb files
261     #   are downloaded here for csit-vpp.
262     # Functions called:
263     # - die - Print to stderr and exit, defined in common_functions.sh
264     # Bash scripts executed:
265     # - ${CSIT_DIR}/resources/tools/scripts/download_install_vpp_pkgs.sh
266     #   - Should download and extract requested files to ./.
267
268     case "${TEST_CODE}" in
269         # Not csit-vpp as this code is re-used by ligato gathering.
270         "csit-"*)
271             # Use downloaded packages with specific version
272             if [[ "${TEST_CODE}" == *"daily"* ]] || \
273                [[ "${TEST_CODE}" == *"weekly"* ]] || \
274                [[ "${TEST_CODE}" == *"timed"* ]];
275             then
276                 warn "Downloading latest VPP packages from Packagecloud."
277             else
278                 warn "Downloading stable VPP packages from Packagecloud."
279                 DKMS_VERSION="$(<"${CSIT_DIR}/DPDK_STABLE_VER")" || {
280                     die "Read DPDK stable version failed."
281                 }
282                 VPP_VERSION="$(<"${CSIT_DIR}/VPP_STABLE_VER_UBUNTU")" || {
283                     die "Read VPP stable version failed."
284                 }
285             fi
286             source "${BASH_FUNCTION_DIR}/artifacts.sh" || die "Source failed."
287             download_artifacts || die
288             ;;
289         "vpp-csit-"*)
290             # Use local built packages.
291             mv "${DOWNLOAD_DIR}"/../"vpp"*".deb" "${DOWNLOAD_DIR}"/ || {
292                 die "Move command failed."
293             }
294             ;;
295         *)
296             die "Unable to identify job type from: ${TEST_CODE}"
297             ;;
298     esac
299 }