f92c4ef897e31b805dc91f62f232b8949e775ccf
[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 package of specific version from repo ..."
101         # Downloading DPDK version based on what VPP is using. Currently
102         # it is not easy way to detect from VPP version automatically.
103         dpdk_stable_ver="$(< "${CSIT_DIR}/DPDK_VPP_VER")".tar.xz || {
104             die "Failed to read DPDK VPP version!"
105         }
106     fi
107     # TODO: Use "wget -N" instead checking for file presence?
108     if [[ ! -f "${dpdk_stable_ver}" ]]; then
109         wget -nv --no-check-certificate "${dpdk_repo}/${dpdk_stable_ver}" || {
110             die "Failed to get DPDK package from: ${dpdk_repo}"
111         }
112     fi
113 }
114
115
116 function gather_ligato () {
117
118     set -exuo pipefail
119
120     # Build docker image (with vpp, ligato and vpp-agent),
121     # and put it to ${DOWNLOAD_DIR}/.
122     #
123     # Access rights needed for:
124     # - "wget", "git clone", "dpdk -x", "cd" above ${CSIT_DIR}.
125     # - "sudo" without password.
126     # - With sudo:
127     #   - "dpdk -i" is allowed.
128     #   - "docker" commands have everything they needs.
129     # Variables read:
130     # - DOWNLOAD_DIR - Path to directory pybot takes the build to test from.
131     # - CSIT_DIR - Path to existing root of local CSIT git repository.
132     # Files read:
133     # - ${CSIT_DIR}/VPP_AGENT_STABLE_VER - Vpp agent version to use.
134     # Directories updated:
135     # - ${DOWNLOAD_DIR} - Docker image stored, VPP *.deb stored and deleted.
136     # - /tmp/vpp - VPP is unpacked there, not cleaned afterwards.
137     # - ${CSIT_DIR}/vpp-agent - Created, vpp-agent git repo si cloned there.
138     #   - Also, various temporary files are stored there.
139     # System consequences:
140     # - Docker package is installed.
141     # - Presumably dockerd process is started.
142     # - The ligato/dev-vpp-agent docker image is downloaded.
143     # - Results of subsequent image manipulation are probably left lingering.
144     # Other hardcoded values:
145     # - Docker .deb file name to download and install.
146     # Functions called:
147     # - die - Print to stderr and exit, defined in common_functions.sh
148     # - gather_vpp - See eponymous fragment file assumend to be sourced already.
149     # TODO: What is the best order of description items?
150
151     # TODO: Many of the following comments act as abstraction.
152     #   But the abstracted blocks are mostly one-liners (plus "|| die"),
153     #   so maybe it is not worth introducing fragments/functions for the blocks.
154     # TODO: This fragment is too long anyway, split it up.
155
156     gather_vpp || die "The function should have died on error."
157
158     mkdir -p /tmp/vpp && rm -f /tmp/vpp/* || {
159         die "Failed to create temporary directory!"
160     }
161     dpkg -x "${DOWNLOAD_DIR}/vpp_"*".deb" "/tmp/vpp" || {
162         die "Failed to extract VPP packages for kubernetes!"
163     }
164
165     ligato_repo_url="https://github.com/ligato/"
166     vpp_agent_stable_ver="$(< "${CSIT_DIR}/VPP_AGENT_STABLE_VER")" || {
167         die "Failed to read vpp-agent stable version!"
168     }
169
170     # Clone & checkout stable vpp-agent.
171     cd "${CSIT_DIR}" || die "Change directory failed!"
172     git clone -b master --single-branch \
173         "${ligato_repo_url}/vpp-agent" "vpp-agent" || {
174         die "Failed to run: git clone ${ligato_repo_url}/vpp-agent!"
175     }
176     cd "vpp-agent" || die "Change directory failed!"
177
178     # Install Docker.
179     curl -fsSL https://get.docker.com | sudo bash || {
180         die "Failed to install Docker package!"
181     }
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     params=(ligato/dev-vpp-agent:${vpp_agent_stable_ver} dev_vpp_agent:latest)
188     sudo docker tag "${params[@]}" || {
189         die "Failed to tag Docker image!"
190     }
191
192     # Start dev_vpp_agent container as daemon.
193     sudo docker run --rm -itd --name "agentcnt" "dev_vpp_agent" bash || {
194         die "Failed to run Docker image!"
195     }
196
197     # Copy latest vpp api into running container.
198     sudo docker exec agentcnt rm -rf "agentcnt:/usr/share/vpp/api" || {
199         die "Failed to remove previous API!"
200     }
201     sudo docker cp "/tmp/vpp/usr/share/vpp/api" "agentcnt:/usr/share/vpp" || {
202         die "Failed to copy files Docker image!"
203     }
204
205     # Recompile vpp-agent.
206     script_arg=". ~/.bashrc; cd /go/src/github.com/ligato/vpp-agent"
207     script_arg+=" && make generate && make install"
208     sudo docker exec -i agentcnt script -qec "${script_arg}" || {
209         die "Failed to recompile vpp-agent in Docker image!"
210     }
211     # Make sure .deb files of other version are not present.
212     rm_cmd="rm -vf /opt/vpp-agent/dev/vpp/build-root/vpp*.deb /opt/vpp/*.deb"
213     sudo docker exec agentcnt bash -c "${rm_cmd}" || {
214         die "Failed to remove VPP debian packages!"
215     }
216     for f in "${DOWNLOAD_DIR}"/*; do
217         sudo docker cp "$f" "agentcnt:/opt/vpp-agent/dev/vpp/build-root"/ || {
218             die "Failed to copy files to Docker image!"
219         }
220     done
221     # Save container state.
222     sudo docker commit "$(sudo docker ps -q)" "dev_vpp_agent:latest" || {
223         die "Failed to commit state of Docker image!"
224     }
225
226     # Build prod_vpp_agent docker image.
227     cd "docker/prod" || die "Change directory failed."
228     sudo docker build --tag "prod_vpp_agent" --no-cache "." || {
229         die "Failed to build Docker image!"
230     }
231     # Export Docker image.
232     sudo docker save "prod_vpp_agent" | gzip > "prod_vpp_agent.tar.gz" || {
233         die "Failed to save Docker image!"
234     }
235     docker_image="$(readlink -e "prod_vpp_agent.tar.gz")" || {
236         die "Failed to get Docker image path!"
237     }
238     rm -r "${DOWNLOAD_DIR}/vpp"* || die "Failed to remove VPP packages!"
239     mv "${docker_image}" "${DOWNLOAD_DIR}"/ || die "Failed to move image!"
240 }
241
242
243 function gather_vpp () {
244
245     set -exuo pipefail
246
247     # Variables read:
248     # - BASH_FUNCTION_DIR - Bash directory with functions.
249     # - TEST_CODE - The test selection string from environment or argument.
250     # - DOWNLOAD_DIR - Path to directory pybot takes the build to test from.
251     # - CSIT_DIR - Path to existing root of local CSIT git repository.
252     # Files read:
253     # - ${CSIT_DIR}/DPDK_STABLE_VER - DPDK version to use
254     #   by csit-vpp not-timed jobs.
255     # - ${CSIT_DIR}/VPP_STABLE_VER_UBUNTU - VPP version to use by those.
256     # - ../vpp*.deb - Relative to ${DOWNLOAD_DIR}, copied for vpp-csit jobs.
257     # Directories updated:
258     # - ${DOWNLOAD_DIR}, vpp-*.deb files are copied here for vpp-csit jobs.
259     # - ./ - Assumed ${DOWNLOAD_DIR}, vpp-*.deb files
260     #   are downloaded here for csit-vpp.
261     # Functions called:
262     # - die - Print to stderr and exit, defined in common_functions.sh
263     # Bash scripts executed:
264     # - ${CSIT_DIR}/resources/tools/scripts/download_install_vpp_pkgs.sh
265     #   - Should download and extract requested files to ./.
266
267     case "${TEST_CODE}" in
268         # Not csit-vpp as this code is re-used by ligato gathering.
269         "csit-"*)
270             # Use downloaded packages with specific version.
271             if [[ "${TEST_CODE}" == *"daily"* ]] || \
272                ([[ "${TEST_CODE}" == *"weekly"* ]] && \
273                 [[ "${TEST_CODE}" != *"device"* ]]) || \
274                [[ "${TEST_CODE}" == *"semiweekly"* ]];
275             then
276                 warn "Downloading latest VPP packages from Packagecloud."
277             else
278                 warn "Downloading stable VPP packages from Packagecloud."
279                 VPP_VERSION="$(<"${CSIT_DIR}/VPP_STABLE_VER_UBUNTU_BIONIC")" || {
280                     die "Read VPP stable version failed."
281                 }
282             fi
283             source "${BASH_FUNCTION_DIR}/artifacts.sh" || die "Source failed."
284             download_artifacts || die
285             ;;
286         "vpp-csit-"*)
287             # Use locally built packages.
288             mv "${DOWNLOAD_DIR}"/../"vpp"*".deb" "${DOWNLOAD_DIR}"/ || {
289                 die "Move command failed."
290             }
291             ;;
292         *)
293             die "Unable to identify job type from: ${TEST_CODE}"
294             ;;
295     esac
296 }