bdcf1c46a8b63e067b846f4f8da7f59e91aaadc8
[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     mkdir -p /tmp/vpp && rm -f /tmp/vpp/* || {
156         die "Failed to create temporary directory!"
157     }
158     dpkg -x "${DOWNLOAD_DIR}/vpp_"*".deb" "/tmp/vpp" || {
159         die "Failed to extract VPP packages for kubernetes!"
160     }
161
162     ligato_repo_url="https://github.com/ligato/"
163     vpp_agent_stable_ver="$(< "${CSIT_DIR}/VPP_AGENT_STABLE_VER")" || {
164         die "Failed to read vpp-agent stable version!"
165     }
166
167     # Clone & checkout stable vpp-agent.
168     cd "${CSIT_DIR}" || die "Change directory failed!"
169     git clone -b master --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     curl -fsSL https://get.docker.com | sudo bash || {
177         die "Failed to install Docker package!"
178     }
179
180     # Pull ligato/dev_vpp_agent docker image and re-tag as local.
181     sudo docker pull "ligato/dev-vpp-agent:${vpp_agent_stable_ver}" || {
182         die "Failed to pull Docker image!"
183     }
184     params=(ligato/dev-vpp-agent:${vpp_agent_stable_ver} dev_vpp_agent:latest)
185     sudo docker tag "${params[@]}" || {
186         die "Failed to tag Docker image!"
187     }
188
189     # Start dev_vpp_agent container as daemon.
190     sudo docker run --rm -itd --name "agentcnt" "dev_vpp_agent" bash || {
191         die "Failed to run Docker image!"
192     }
193
194     # Copy latest vpp api into running container.
195     sudo docker exec agentcnt rm -rf "agentcnt:/usr/share/vpp/api" || {
196         die "Failed to remove previous API!"
197     }
198     sudo docker cp "/tmp/vpp/usr/share/vpp/api" "agentcnt:/usr/share/vpp" || {
199         die "Failed to copy files Docker image!"
200     }
201
202     # Recompile vpp-agent.
203     script_arg=". ~/.bashrc; cd /go/src/github.com/ligato/vpp-agent"
204     script_arg+=" && make generate && make install"
205     sudo docker exec -i agentcnt script -qec "${script_arg}" || {
206         die "Failed to recompile vpp-agent in Docker image!"
207     }
208     # Make sure .deb files of other version are not present.
209     rm_cmd="rm -vf /opt/vpp-agent/dev/vpp/build-root/vpp*.deb /opt/vpp/*.deb"
210     sudo docker exec agentcnt bash -c "${rm_cmd}" || {
211         die "Failed to remove VPP debian packages!"
212     }
213     for f in "${DOWNLOAD_DIR}"/*; do
214         sudo docker cp "$f" "agentcnt:/opt/vpp-agent/dev/vpp/build-root"/ || {
215             die "Failed to copy files to Docker image!"
216         }
217     done
218     # Save container state.
219     sudo docker commit "$(sudo docker ps -q)" "dev_vpp_agent:latest" || {
220         die "Failed to commit state of Docker image!"
221     }
222
223     # Build prod_vpp_agent docker image.
224     cd "docker/prod" || die "Change directory failed."
225     sudo docker build --tag "prod_vpp_agent" --no-cache "." || {
226         die "Failed to build Docker image!"
227     }
228     # Export Docker image.
229     sudo docker save "prod_vpp_agent" | gzip > "prod_vpp_agent.tar.gz" || {
230         die "Failed to save Docker image!"
231     }
232     docker_image="$(readlink -e "prod_vpp_agent.tar.gz")" || {
233         die "Failed to get Docker image path!"
234     }
235     rm -r "${DOWNLOAD_DIR}/vpp"* || die "Failed to remove VPP packages!"
236     mv "${docker_image}" "${DOWNLOAD_DIR}"/ || die "Failed to move image!"
237 }
238
239
240 function gather_vpp () {
241
242     set -exuo pipefail
243
244     # Variables read:
245     # - BASH_FUNCTION_DIR - Bash directory with functions.
246     # - TEST_CODE - The test selection string from environment or argument.
247     # - DOWNLOAD_DIR - Path to directory pybot takes the build to test from.
248     # - CSIT_DIR - Path to existing root of local CSIT git repository.
249     # Files read:
250     # - ${CSIT_DIR}/DPDK_STABLE_VER - DPDK version to use
251     #   by csit-vpp not-timed jobs.
252     # - ${CSIT_DIR}/VPP_STABLE_VER_UBUNTU - VPP version to use by those.
253     # - ../vpp*.deb - Relative to ${DOWNLOAD_DIR}, copied for vpp-csit jobs.
254     # Directories updated:
255     # - ${DOWNLOAD_DIR}, vpp-*.deb files are copied here for vpp-csit jobs.
256     # - ./ - Assumed ${DOWNLOAD_DIR}, vpp-*.deb files
257     #   are downloaded here for csit-vpp.
258     # Functions called:
259     # - die - Print to stderr and exit, defined in common_functions.sh
260     # Bash scripts executed:
261     # - ${CSIT_DIR}/resources/tools/scripts/download_install_vpp_pkgs.sh
262     #   - Should download and extract requested files to ./.
263
264     case "${TEST_CODE}" in
265         # Not csit-vpp as this code is re-used by ligato gathering.
266         "csit-"*)
267             # Use downloaded packages with specific version
268             if [[ "${TEST_CODE}" == *"daily"* ]] || \
269                [[ "${TEST_CODE}" == *"weekly"* ]] || \
270                [[ "${TEST_CODE}" == *"timed"* ]];
271             then
272                 warn "Downloading latest VPP packages from Packagecloud."
273             else
274                 warn "Downloading stable VPP packages from Packagecloud."
275                 if [[ "${TEST_CODE}" == *"device"* ]];
276                 then
277                     VPP_VERSION="$(<"${CSIT_DIR}/VPP_STABLE_VER_UBUNTU_BIONIC")" || {
278                         die "Read VPP stable version failed."
279                     }
280                 else
281                     VPP_VERSION="$(<"${CSIT_DIR}/VPP_STABLE_VER_UBUNTU")" || {
282                         die "Read VPP stable version failed."
283                     }
284                 fi
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 }