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