]> git.proxmox.com Git - ceph.git/blame - ceph/src/test/docker-test-helper.sh
bump version to 12.2.12-pve1
[ceph.git] / ceph / src / test / docker-test-helper.sh
CommitLineData
7c673cae
FG
1#!/bin/bash
2#
3# Copyright (C) 2014, 2015 Red Hat <contact@redhat.com>
4#
5# Author: Loic Dachary <loic@dachary.org>
6#
7# This program is free software; you can redistribute it and/or modify
8# it under the terms of the GNU Library Public License as published by
9# the Free Software Foundation; either version 2, or (at your option)
10# any later version.
11#
12# This program is distributed in the hope that it will be useful,
13# but WITHOUT ANY WARRANTY; without even the implied warranty of
14# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15# GNU Library Public License for more details.
16#
17function get_image_name() {
18 local os_type=$1
19 local os_version=$2
20
21 echo ceph-$os_type-$os_version-$USER
22}
23
24function setup_container() {
25 local os_type=$1
26 local os_version=$2
27 local opts="$3"
28
29 local image=$(get_image_name $os_type $os_version)
30 local build=true
31 if docker images $image | grep --quiet "^$image " ; then
32 eval touch --date=$(docker inspect $image | jq '.[0].Created') $image
33 found=$(find -L test/$os_type-$os_version/* -newer $image)
34 rm $image
35 if test -n "$found" ; then
36 docker rmi $image
37 else
38 build=false
39 fi
40 fi
41 if $build ; then
42 #
43 # In the dockerfile,
44 # replace environment variables %%FOO%% with their content
45 #
46 rm -fr dockerfile
47 cp --dereference --recursive test/$os_type-$os_version dockerfile
48 os_version=$os_version user_id=$(id -u) \
49 perl -p -e 's/%%(\w+)%%/$ENV{$1}/g' \
50 dockerfile/Dockerfile.in > dockerfile/Dockerfile
51 docker $opts build --tag=$image dockerfile
52 rm -fr dockerfile
53 fi
54}
55
56function get_upstream() {
57 git rev-parse --show-toplevel
58}
59
60function get_downstream() {
61 local os_type=$1
62 local os_version=$2
63
64 local image=$(get_image_name $os_type $os_version)
65 local upstream=$(get_upstream)
66 local dir=$(dirname $upstream)
67 echo "$dir/$image"
68}
69
70function setup_downstream() {
71 local os_type=$1
72 local os_version=$2
73 local ref=$3
74
75 local image=$(get_image_name $os_type $os_version)
76 local upstream=$(get_upstream)
77 local dir=$(dirname $upstream)
78 local downstream=$(get_downstream $os_type $os_version)
79
80 (
81 cd $dir
82 if ! test -d $downstream ; then
83 # Inspired by https://github.com/git/git/blob/master/contrib/workdir/git-new-workdir
84 mkdir -p $downstream/.git || return 1
85 for x in config refs logs/refs objects info hooks packed-refs remotes rr-cache
86 do
87 case $x in
88 */*)
89 mkdir -p "$downstream/.git/$x"
90 ;;
91 esac
92 ln -s "$upstream/.git/$x" "$downstream/.git/$x"
93 cp "$upstream/.git/HEAD" "$downstream/.git/HEAD"
94 done
95 fi
96 cd $downstream
97 git reset --hard $ref || return 1
98 git submodule sync --recursive || return 1
99 git submodule update --force --init --recursive || return 1
100 )
101}
102
103function run_in_docker() {
104 local os_type=$1
105 shift
106 local os_version=$1
107 shift
108 local ref=$1
109 shift
110 local opts="$1"
111 shift
112 local script=$1
113
114 setup_downstream $os_type $os_version $ref || return 1
115 setup_container $os_type $os_version "$opts" || return 1
116 local downstream=$(get_downstream $os_type $os_version)
117 local image=$(get_image_name $os_type $os_version)
118 local upstream=$(get_upstream)
119 local ccache
120 mkdir -p $HOME/.ccache
121 ccache="--volume $HOME/.ccache:$HOME/.ccache"
122 user="--user $USER"
123 local cmd="docker run $opts --rm --name $image --privileged $ccache"
124 cmd+=" --volume $downstream:$downstream"
125 cmd+=" --volume $upstream:$upstream"
126 local status=0
127 if test "$script" = "SHELL" ; then
128 $cmd --tty --interactive --workdir $downstream $user $image bash
129 else
130 if ! $cmd --workdir $downstream $user $image "$@" ; then
131 status=1
132 fi
133 fi
134 return $status
135}
136
137function remove_all() {
138 local os_type=$1
139 local os_version=$2
140 local image=$(get_image_name $os_type $os_version)
141
142 docker rm $image
143 docker rmi $image
144}
145
146function usage() {
147 cat <<EOF
148Run commands within Ceph sources, in a docker container
149$0 [options] command args ...
150
151 [-h|--help] display usage
152 [--verbose] trace all shell lines
153
154 [--os-type type] docker image repository (centos, ubuntu, etc.)
155 (defaults to ubuntu)
156 [--os-version version] docker image tag (7 for centos, 12.04 for ubuntu, etc.)
157 (defaults to 14.04)
158 [--ref gitref] git reset --hard gitref before running the command
159 (defaults to git rev-parse HEAD)
160 [--all types+versions] list of docker image repositories and tags
161
162 [--shell] run an interactive shell in the container
163 [--remove-all] remove the container and the image for the specified types+versions
164
165 [--opts options] run the contain with 'options'
166
167docker-test.sh must be run from a Ceph clone and it will run the
168command in a container, using a copy of the clone so that long running
169commands such as make check are not disturbed while development
170continues. Here is a sample use case including an interactive session
171and running a unit test:
172
173 $ lsb_release -d
174 Description: Ubuntu Trusty Tahr (development branch)
175 $ test/docker-test.sh --os-type centos --os-version 7 --shell
176 HEAD is now at 1caee81 autotools: add --enable-docker
177 bash-4.2$ pwd
178 /srv/ceph/ceph-centos-7
179 bash-4.2$ lsb_release -d
180 Description: CentOS Linux release 7.0.1406 (Core)
181 bash-4.2$
182 $ time test/docker-test.sh --os-type centos --os-version 7 unittest_str_map
183 HEAD is now at 1caee81 autotools: add --enable-docker
184 Running main() from gtest_main.cc
185 [==========] Running 2 tests from 1 test case.
186 [----------] Global test environment set-up.
187 [----------] 2 tests from str_map
188 [ RUN ] str_map.json
189 [ OK ] str_map.json (1 ms)
190 [ RUN ] str_map.plaintext
191 [ OK ] str_map.plaintext (0 ms)
192 [----------] 2 tests from str_map (1 ms total)
193
194 [----------] Global test environment tear-down
195 [==========] 2 tests from 1 test case ran. (1 ms total)
196 [ PASSED ] 2 tests.
197
198 real 0m3.759s
199 user 0m0.074s
200 sys 0m0.051s
201
202The --all argument is a bash associative array literal listing the
203operating system version for each operating system type. For instance
204
205 docker-test.sh --all '([ubuntu]="12.04 14.04" [centos]="6 7")'
206
207is strictly equivalent to
208
209 docker-test.sh --os-type ubuntu --os-version 12.04
210 docker-test.sh --os-type ubuntu --os-version 14.04
211 docker-test.sh --os-type centos --os-version 6
212 docker-test.sh --os-type centos --os-version 7
213
214The --os-type and --os-version must be exactly as displayed by docker images:
215
216 $ docker images
217 REPOSITORY TAG IMAGE ID ...
218 centos 7 87e5b6b3ccc1 ...
219 ubuntu 14.04 6b4e8a7373fe ...
220
221The --os-type value can be any string in the REPOSITORY column, the --os-version
222can be any string in the TAG column.
223
224The --shell and --remove actions are mutually exclusive.
225
226Run make check in centos 7
227docker-test.sh --os-type centos --os-version 7 -- make check
228
229Run make check on a giant
230docker-test.sh --ref giant -- make check
231
232Run an interactive shell and set resolv.conf to use 172.17.42.1
233docker-test.sh --opts --dns=172.17.42.1 --shell
234
235Run make check on centos 6, centos 7, ubuntu 12.04 and ubuntu 14.04
236docker-test.sh --all '([ubuntu]="12.04 14.04" [centos]="6 7")' -- make check
237EOF
238}
239
240function main_docker() {
241 if ! docker ps > /dev/null 2>&1 ; then
242 echo "docker not available: $0"
243 return 0
244 fi
245
246 local temp
247 temp=$(getopt -o scht:v:o:a:r: --long remove-all,verbose,shell,help,os-type:,os-version:,opts:,all:,ref: -n $0 -- "$@") || return 1
248
249 eval set -- "$temp"
250
251 local os_type=ubuntu
252 local os_version=14.04
253 local all
254 local remove=false
255 local shell=false
256 local opts
257 local ref=$(git rev-parse HEAD)
258
259 while true ; do
260 case "$1" in
261 --remove-all)
262 remove=true
263 shift
264 ;;
265 --verbose)
266 set -xe
267 PS4='${BASH_SOURCE[0]}:$LINENO: ${FUNCNAME[0]}: '
268 shift
269 ;;
270 -s|--shell)
271 shell=true
272 shift
273 ;;
274 -h|--help)
275 usage
276 return 0
277 ;;
278 -t|--os-type)
279 os_type=$2
280 shift 2
281 ;;
282 -v|--os-version)
283 os_version=$2
284 shift 2
285 ;;
286 -o|--opts)
287 opts="$2"
288 shift 2
289 ;;
290 -a|--all)
291 all="$2"
292 shift 2
293 ;;
294 -r|--ref)
295 ref="$2"
296 shift 2
297 ;;
298 --)
299 shift
300 break
301 ;;
302 *)
303 echo "unexpected argument $1"
304 return 1
305 ;;
306 esac
307 done
308
309 if test -z "$all" ; then
310 all="([$os_type]=\"$os_version\")"
311 fi
312
313 declare -A os_type2versions
314 eval os_type2versions="$all"
315
316 for os_type in ${!os_type2versions[@]} ; do
317 for os_version in ${os_type2versions[$os_type]} ; do
318 if $remove ; then
319 remove_all $os_type $os_version || return 1
320 elif $shell ; then
321 run_in_docker $os_type $os_version $ref "$opts" SHELL || return 1
322 else
323 run_in_docker $os_type $os_version $ref "$opts" "$@" || return 1
324 fi
325 done
326 done
327}