Skip to content

Commit 173f47c

Browse files
committed
ci: cache and rework Travis setup
We can cache the umoci/ci image using Travis's built-in caching support, as well as reduce duplication between our test runs by moving the unit and validation tests to separate stages. This change does mean that code coverage checks are no longer done in Travis, but this will be cleaned up in a follow-up commit where we add support for Codecov (though hack/ci-coverage.sh will still be used for the stock "make ci"). Signed-off-by: Aleksa Sarai <[email protected]>
1 parent 0421874 commit 173f47c

File tree

6 files changed

+160
-52
lines changed

6 files changed

+160
-52
lines changed

.dockerignore

+4
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
/umoci
2+
/umoci.cov*
3+
/.cache
4+
/release

.gitignore

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
11
/umoci
2-
/cache
32
/umoci.cov*
3+
/.cache
44
/release

.travis.yml

+75-24
Original file line numberDiff line numberDiff line change
@@ -30,36 +30,36 @@ notifications:
3030
addons:
3131
apt:
3232
packages:
33+
- bc
3334
- gcc-multilib
35+
- zstd
3436
homebrew:
3537
packages:
3638
# Needed for sponge.
3739
# NOTE: This conflicts with gnu_parallel so we'll need to work
3840
# around that when we enable integration testing.
3941
- moreutils
4042

41-
before_install:
42-
# Need to set GO111MODULE=off here because Travis runs inside our source repo
43-
# (which is a Go module) and thus 'go get' will actually add dependencies to
44-
# our go.mod file. Annoyingly this means we cannot require v2 of go-md2man
45-
# because that requires Go module support.
46-
- GO111MODULE=off go get -u -v github.com/cpuguy83/go-md2man
43+
_docker: &docker
44+
|-
45+
# Install a modern version of Docker which supports BuildKit.
46+
./hack/resilient-curl.sh -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -
47+
sudo add-apt-repository "deb [arch=amd64] https://download.docker.com/linux/ubuntu $(lsb_release -cs) edge"
48+
sudo apt-get update
49+
sudo apt-get -y -o Dpkg::Options::="--force-confnew" install docker-ce
4750

48-
env:
49-
- DOCKER_IMAGE="opensuse/leap:latest"
50-
- DOCKER_IMAGE="centos:latest"
51-
- DOCKER_IMAGE="debian:latest"
52-
- DOCKER_IMAGE="ubuntu:latest"
53-
- DOCKER_IMAGE="fedora:latest"
51+
_cache: &cache
52+
cache:
53+
directories:
54+
- .cache
55+
before_script:
56+
- make ci-cache
5457

55-
script:
56-
# Necessary to make Travis co-operate with Docker.
57-
- chmod a+rwx .
58-
# Make sure 32-bit builds work. I'm not sure why GO111MODULE breaks here, but
59-
# disable it since we just care about whether you get compiler errors.
60-
- make GO111MODULE=off GOARCH=386 local-validate-build
61-
# Run the actual CI.
62-
- make DOCKER_IMAGE=$DOCKER_IMAGE ci
58+
_matrix_integration: &matrix_integration
59+
<<: *cache
60+
before_install: *docker
61+
script:
62+
- make DOCKER_IMAGE=$DOCKER_IMAGE ci-integration
6363

6464
matrix:
6565
fast_finish: true
@@ -70,13 +70,64 @@ matrix:
7070
# (~40 minutes on some days).
7171
- env: DOCKER_IMAGE="fedora:latest"
7272
include:
73-
- os: osx
74-
osx_image: xcode12
73+
- name: "validate"
74+
before_install:
75+
# Install basic Go tooling.
76+
- |-
77+
# Need to set GO111MODULE=off here because Travis runs inside our
78+
# source repo (which is a Go module) and thus 'go get' will actually
79+
# add dependencies to our go.mod file. Annoyingly this means we
80+
# cannot require v2 of go-md2man because that requires Go module
81+
# support.
82+
GO111MODULE=off go get -u github.com/cpuguy83/go-md2man
83+
GO111MODULE=off go get -u golang.org/x/lint/golint
84+
GO111MODULE=off go get -u github.com/securego/gosec/cmd/gosec
85+
GO111MODULE=off go get -u github.com/client9/misspell/cmd/misspell
86+
script:
87+
# Make sure 32-bit builds work. I'm not sure why GO111MODULE breaks here, but
88+
# disable it since we just care about whether you get compiler errors.
89+
- make GO111MODULE=off GOARCH=386 local-validate-build
90+
- make ci-validate
91+
- |-
92+
make umoci
93+
./umoci help
94+
95+
# Unit tests.
96+
- name: "unit"
97+
<<: *cache
98+
before_install: *docker
99+
script:
100+
# Necessary to make Travis co-operate with Docker.
101+
- chmod a+rwx .
102+
- make ci-unit
103+
- <<: *matrix_integration
104+
name: "integration (opensuse/leap)"
105+
env:
106+
- DOCKER_IMAGE="opensuse/leap:latest"
107+
- <<: *matrix_integration
108+
name: "integration (centos)"
75109
env:
76-
# Clear DOCKER_IMAGE since we don't use it.
77-
- DOCKER_IMAGE=""
110+
- DOCKER_IMAGE="centos:latest"
111+
- <<: *matrix_integration
112+
name: "integration (debian)"
113+
env:
114+
- DOCKER_IMAGE="debian:latest"
115+
- <<: *matrix_integration
116+
name: "integration (ubuntu)"
117+
env:
118+
- DOCKER_IMAGE="ubuntu:latest"
119+
- <<: *matrix_integration
120+
name: "integration (fedora)"
121+
env:
122+
- DOCKER_IMAGE="fedora:latest"
123+
- name: "macos-unit"
124+
os: osx
125+
osx_image: xcode12
78126
script:
79127
# TODO: Run the integration tests and rest of the CI, so we don't need
80128
# to special-case MacOS here.
81129
- make local-validate-build
82130
- make local-test-unit
131+
- |-
132+
make umoci
133+
./umoci help

Dockerfile

+4-2
Original file line numberDiff line numberDiff line change
@@ -18,14 +18,17 @@ MAINTAINER "Aleksa Sarai <[email protected]>"
1818

1919
# We have to use out-of-tree repos because several packages haven't been merged
2020
# into openSUSE Leap yet, or are out of date in Leap.
21-
RUN zypper ar -f -p 10 -g obs://Virtualization:containers obs-vc && \
21+
RUN zypper mr -d repo-non-oss repo-update-non-oss && \
22+
zypper ar -f -p 10 -g obs://Virtualization:containers obs-vc && \
2223
zypper ar -f -p 10 -g obs://devel:tools obs-tools && \
2324
zypper ar -f -p 10 -g obs://devel:languages:go obs-go && \
2425
zypper --gpg-auto-import-keys -n ref && \
2526
zypper -n up
2627
RUN zypper -n in \
2728
attr \
2829
bats \
30+
bc \
31+
curl \
2932
git \
3033
gnu_parallel \
3134
go1.14 \
@@ -55,4 +58,3 @@ RUN skopeo copy docker://$DOCKER_IMAGE oci:$SOURCE_IMAGE:$SOURCE_TAG
5558

5659
VOLUME ["/go/src/github.com/opencontainers/umoci"]
5760
WORKDIR /go/src/github.com/opencontainers/umoci
58-
COPY . /go/src/github.com/opencontainers/umoci

Makefile

+49-25
Original file line numberDiff line numberDiff line change
@@ -26,24 +26,20 @@ PROJECT := github.com/opencontainers/umoci
2626
CMD := ${PROJECT}/cmd/umoci
2727

2828
# We use Docker because Go is just horrific to deal with.
29-
UMOCI_IMAGE := umoci_dev
29+
UMOCI_IMAGE := umoci/ci:latest
3030

3131
# TODO: We should test umoci with all of the security options disabled so that
3232
# we can make sure umoci inside containers works fine (all of these
3333
# security options are necessary for the test code to run, not umoci
3434
# itself). The AppArmor/SELinux settings are needed because of the
3535
# mount-related tests, and the seccomp/systempaths settings are required
3636
# for the runc tests for rootless containers.
37-
# XXX: Ideally we'd use --security-opt systempaths=unconfined, but the version
38-
# of Docker in Travis-CI doesn't support that. Bind-mounting the host's
39-
# proc into the container is more dangerous but has the same effect on the
40-
# in-kernel mnt_too_revealing() checks and works on old Docker.
41-
DOCKER_RUN := docker run --rm -it \
37+
DOCKER_RUN := docker run --rm \
4238
-v ${PWD}:/go/src/${PROJECT} \
43-
--security-opt seccomp=unconfined \
4439
--security-opt apparmor=unconfined \
4540
--security-opt label=disable \
46-
-v /proc:/tmp/.HOTFIX-stashed-proc
41+
--security-opt seccomp=unconfined \
42+
--security-opt systempaths=unconfined
4743
DOCKER_ROOTPRIV_RUN := $(DOCKER_RUN) --privileged --cap-add=SYS_ADMIN
4844
DOCKER_ROOTLESS_RUN := $(DOCKER_RUN) -u 1000:1000 --cap-drop=all
4945

@@ -113,11 +109,11 @@ uninstall:
113109

114110
.PHONY: clean
115111
clean:
116-
rm -f umoci umoci.static umoci.cov*
112+
rm -f umoci umoci.static umoci-ci.tar umoci.cov*
117113
rm -f $(MANPAGES)
118114

119115
.PHONY: validate
120-
validate: umociimage
116+
validate: ci-image
121117
$(DOCKER_RUN) $(UMOCI_IMAGE) make local-validate
122118

123119
.PHONY: local-validate
@@ -170,19 +166,15 @@ doc/man/%.1: doc/man/%.1.md
170166
docs: $(MANPAGES)
171167

172168
# Used for tests.
173-
DOCKER_IMAGE :=opensuse/amd64:tumbleweed
174-
175-
.PHONY: umociimage
176-
umociimage:
177-
docker build -t $(UMOCI_IMAGE) --build-arg DOCKER_IMAGE=$(DOCKER_IMAGE) .
169+
DOCKER_IMAGE ?=opensuse/amd64:tumbleweed
178170

179171
ifndef COVERAGE
180172
COVERAGE := $(notdir $(shell mktemp -u umoci.cov.XXXXXX))
181-
export COVERAGE
182173
endif
174+
export COVERAGE
183175

184176
.PHONY: test-unit
185-
test-unit: umociimage
177+
test-unit: ci-image
186178
touch $(COVERAGE) && chmod a+rw $(COVERAGE)
187179
$(DOCKER_ROOTPRIV_RUN) -e COVERAGE $(UMOCI_IMAGE) make local-test-unit
188180
$(DOCKER_ROOTLESS_RUN) -e COVERAGE $(UMOCI_IMAGE) make local-test-unit
@@ -192,7 +184,7 @@ local-test-unit:
192184
GO=$(GO) hack/test-unit.sh
193185

194186
.PHONY: test-integration
195-
test-integration: umociimage
187+
test-integration: ci-image
196188
touch $(COVERAGE) && chmod a+rw $(COVERAGE)
197189
$(DOCKER_ROOTPRIV_RUN) -e COVERAGE -e TESTS $(UMOCI_IMAGE) make local-test-integration
198190
$(DOCKER_ROOTLESS_RUN) -e COVERAGE -e TESTS $(UMOCI_IMAGE) make local-test-integration
@@ -202,17 +194,49 @@ local-test-integration: umoci.cover
202194
TESTS="${TESTS}" hack/test-integration.sh
203195

204196
.PHONY: shell
205-
shell: umociimage
206-
$(DOCKER_RUN) $(UMOCI_IMAGE) bash
197+
shell: ci-image
198+
$(DOCKER_RUN) -it $(UMOCI_IMAGE) bash
207199

208200
.PHONY: root-shell
209-
root-shell: umociimage
210-
$(DOCKER_ROOTPRIV_RUN) $(UMOCI_IMAGE) bash
201+
root-shell: ci-image
202+
$(DOCKER_ROOTPRIV_RUN) -it $(UMOCI_IMAGE) bash
211203

212204
.PHONY: rootless-shell
213-
rootless-shell: umociimage
214-
$(DOCKER_ROOTLESS_RUN) $(UMOCI_IMAGE) bash
205+
rootless-shell: ci-image
206+
$(DOCKER_ROOTLESS_RUN) -it $(UMOCI_IMAGE) bash
207+
208+
CACHE := .cache
209+
CACHE_IMAGE := $(CACHE)/ci-image.tar.zst
210+
211+
.PHONY: ci-image
212+
ci-image:
213+
docker pull opensuse/leap:latest
214+
! [ -f "$(CACHE_IMAGE)" ] || unzstd < "$(CACHE_IMAGE)" | docker load
215+
DOCKER_BUILDKIT=1 docker build -t $(UMOCI_IMAGE) \
216+
--progress plain \
217+
--cache-from $(UMOCI_IMAGE) \
218+
--build-arg DOCKER_IMAGE=$(DOCKER_IMAGE) \
219+
--build-arg BUILDKIT_INLINE_CACHE=1 .
220+
221+
.PHONY: ci-cache
222+
ci-cache: ci-image
223+
rm -rf $(CACHE) && mkdir -p $(CACHE)
224+
docker save $(UMOCI_IMAGE) | zstd > $(CACHE_IMAGE)
225+
226+
.PHONY: ci-validate
227+
ci-validate: umoci umoci.static
228+
make docs local-validate
229+
230+
.PHONY: ci-unit
231+
ci-unit: umoci.cover
232+
make test-unit
233+
234+
.PHONY: ci-integration
235+
ci-integration: umoci.cover
236+
make test-integration
215237

216238
.PHONY: ci
217-
ci: umoci umoci.static umoci.cover validate docs test-unit test-integration
239+
ci:
240+
@echo "NOTE: This is not identical to the upstream CI, but the tests are the same."
241+
make ci-validate ci-unit ci-integration
218242
hack/ci-coverage.sh $(COVERAGE)

hack/resilient-curl.sh

+27
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
#!/bin/bash
2+
# umoci: Umoci Modifies Open Containers' Images
3+
# Copyright (C) 2016-2020 SUSE LLC
4+
#
5+
# Licensed under the Apache License, Version 2.0 (the "License");
6+
# you may not use this file except in compliance with the License.
7+
# You may obtain a copy of the License at
8+
#
9+
# http://www.apache.org/licenses/LICENSE-2.0
10+
#
11+
# Unless required by applicable law or agreed to in writing, software
12+
# distributed under the License is distributed on an "AS IS" BASIS,
13+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
# See the License for the specific language governing permissions and
15+
# limitations under the License.
16+
17+
set -Eeuo pipefail
18+
19+
ATTEMPT=0
20+
MAX_ATTEMPTS=10
21+
BACKOFF=0.2
22+
23+
until ( timeout 5s curl "$@" )
24+
do
25+
[[ "$((++ATTEMPT))" -lt "$MAX_ATTEMPTS" ]] || exit 1
26+
sleep "$(bc <<<"$BACKOFF * 2*$ATTEMPT")"
27+
done

0 commit comments

Comments
 (0)