github.com/opencontainers/umoci@v0.4.8-0.20240508124516-656e4836fb0d/Makefile (about) 1 # umoci: Umoci Modifies Open Containers' Images 2 # Copyright (C) 2016-2020 SUSE LLC 3 # 4 # Licensed under the Apache License, Version 2.0 (the "License"); 5 # you may not use this file except in compliance with the License. 6 # You may obtain a copy of the License at 7 # 8 # http://www.apache.org/licenses/LICENSE-2.0 9 # 10 # Unless required by applicable law or agreed to in writing, software 11 # distributed under the License is distributed on an "AS IS" BASIS, 12 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 # See the License for the specific language governing permissions and 14 # limitations under the License. 15 16 # Use bash, so that we can do process substitution. 17 SHELL := bash 18 19 # Go tools. 20 GO ?= go 21 GO_MD2MAN ?= go-md2man 22 GOOS ?= $(shell go env GOOS) 23 GOARCH ?= $(shell go env GOARCH) 24 export GO111MODULE=on 25 26 # Set up the ... lovely ... GOPATH hacks. 27 PROJECT := github.com/opencontainers/umoci 28 CMD := ${PROJECT}/cmd/umoci 29 30 # We use Docker because Go is just horrific to deal with. 31 UMOCI_IMAGE := umoci/ci:latest 32 33 # TODO: We should test umoci with all of the security options disabled so that 34 # we can make sure umoci inside containers works fine (all of these 35 # security options are necessary for the test code to run, not umoci 36 # itself). The AppArmor/SELinux settings are needed because of the 37 # mount-related tests, and the seccomp/systempaths settings are required 38 # for the runc tests for rootless containers. 39 DOCKER_RUN = docker run --rm -v ${PWD}:/go/src/${PROJECT} \ 40 --security-opt apparmor=unconfined \ 41 --security-opt label=disable \ 42 --security-opt seccomp=unconfined \ 43 --security-opt systempaths=unconfined 44 45 # We only add the CodeCov environment (and ping codecov) if we're running in 46 # Travis, to avoid pinging third-party servers for local builds. 47 ifdef TRAVIS 48 $(shell echo "WARNING: This make invocation will fetch and run code from https://codecov.io/." >&2) 49 DOCKER_RUN += $(shell echo "+ Running https://codecov.io/env." >&2) \ 50 $(shell ./hack/ci-codecov.sh env) 51 endif 52 53 DOCKER_ROOTPRIV_RUN = $(DOCKER_RUN) --privileged --cap-add=SYS_ADMIN 54 DOCKER_ROOTLESS_RUN = $(DOCKER_RUN) -u 1000:1000 --cap-drop=all 55 56 # Output directory. 57 BUILD_DIR ?= . 58 59 # Release information. 60 GPG_KEYID ?= 61 62 # Version information. 63 VERSION := $(shell cat ./VERSION) 64 COMMIT_NO := $(shell git rev-parse HEAD 2> /dev/null || true) 65 COMMIT := $(if $(shell git status --porcelain --untracked-files=no),"${COMMIT_NO}-dirty","${COMMIT_NO}") 66 67 # Basic build flags. 68 BUILD_FLAGS ?= 69 BASE_FLAGS := ${BUILD_FLAGS} -tags "${BUILDTAGS}" -buildvcs=false 70 BASE_LDFLAGS := -s -w -X ${PROJECT}.gitCommit=${COMMIT} -X ${PROJECT}.version=${VERSION} 71 72 # Specific build flags for build type. 73 ifeq ($(GOOS), linux) 74 DYN_BUILD_FLAGS := ${BASE_FLAGS} -buildmode=pie -ldflags "${BASE_LDFLAGS}" 75 TEST_BUILD_FLAGS := ${BASE_FLAGS} -buildmode=pie -ldflags "${BASE_LDFLAGS} -X ${PROJECT}/pkg/testutils.binaryType=test" 76 else 77 DYN_BUILD_FLAGS := ${BASE_FLAGS} -ldflags "${BASE_LDFLAGS}" 78 TEST_BUILD_FLAGS := ${BASE_FLAGS} -ldflags "${BASE_LDFLAGS} -X ${PROJECT}/pkg/testutils.binaryType=test" 79 endif 80 81 82 STATIC_BUILD_FLAGS := ${BASE_FLAGS} -ldflags "${BASE_LDFLAGS} -extldflags '-static'" 83 84 # Installation directories. 85 DESTDIR ?= 86 PREFIX ?=/usr/local 87 BINDIR ?=$(PREFIX)/bin 88 MANDIR ?=$(PREFIX)/share/man 89 90 .DEFAULT: umoci 91 92 GO_SRC = $(shell find . -type f -name '*.go') 93 94 # NOTE: If you change these make sure you also update local-validate-build. 95 96 umoci: $(GO_SRC) 97 GOOS=$(GOOS) GOARCH=$(GOARCH) $(GO) build ${DYN_BUILD_FLAGS} -o $(BUILD_DIR)/$@ ${CMD} 98 99 umoci.static: $(GO_SRC) 100 env CGO_ENABLED=0 $(GO) build ${STATIC_BUILD_FLAGS} -o $(BUILD_DIR)/$@ ${CMD} 101 102 .PHONY: static 103 static: umoci.static 104 105 umoci.cover: $(GO_SRC) 106 $(GO) test -c -cover -covermode=count -coverpkg=./... ${TEST_BUILD_FLAGS} -o $(BUILD_DIR)/$@ ${CMD} 107 108 .PHONY: release 109 release: 110 hack/release.sh \ 111 -a 386 -a amd64 -a arm64 -a ppc64le -a riscv64 -a s390x \ 112 -v $(VERSION) -S "$(GPG_KEYID)" 113 114 .PHONY: install 115 install: umoci docs 116 install -D -m0755 umoci $(DESTDIR)/$(BINDIR)/umoci 117 -for man in $(MANPAGES); do \ 118 filename="$$(basename -- "$$man")"; \ 119 target="$(DESTDIR)/$(MANDIR)/man$${filename##*.}/$$filename"; \ 120 install -D -m0644 "$$man" "$$target"; \ 121 gzip -9f "$$target"; \ 122 done 123 124 .PHONY: uninstall 125 uninstall: 126 rm -f $(DESTDIR)/$(BINDIR)/umoci 127 -rm -f $(DESTDIR)/$(MANDIR)/man*/umoci* 128 129 .PHONY: clean 130 clean: 131 rm -f umoci umoci.static umoci-ci.tar umoci.cov* 132 rm -f $(MANPAGES) 133 134 .PHONY: validate 135 validate: ci-image 136 $(DOCKER_RUN) $(UMOCI_IMAGE) make local-validate 137 138 .PHONY: local-validate 139 local-validate: local-validate-go local-validate-spell local-validate-reproducible local-validate-build 140 141 .PHONY: local-validate-go 142 local-validate-go: 143 @type gofmt >/dev/null 2>/dev/null || (echo "ERROR: gofmt not found." && false) 144 test -z "$$(gofmt -s -l . | grep -vE '^vendor/|^third_party/' | tee /dev/stderr)" 145 @type golint >/dev/null 2>/dev/null || (echo "ERROR: golint not found." && false) 146 test -z "$$(golint $(PROJECT)/... | grep -vE '/vendor/|/third_party/' | tee /dev/stderr)" 147 @go doc cmd/vet >/dev/null 2>/dev/null || (echo "ERROR: go vet not found." && false) 148 test -z "$$($(GO) vet $$($(GO) list $(PROJECT)/... | grep -vE '/vendor/|/third_party/') 2>&1 | tee /dev/stderr)" 149 @type gosec >/dev/null 2>/dev/null || (echo "ERROR: gosec not found." && false) 150 test -z "$$(gosec -quiet -exclude=G301,G302,G304 $$GOPATH/$(PROJECT)/... | tee /dev/stderr)" 151 ./hack/test-vendor.sh 152 153 .PHONY: local-validate-spell 154 local-validate-spell: 155 make clean 156 @type misspell >/dev/null 2>/dev/null || (echo "ERROR: misspell not found." && false) 157 test -z "$$(find . -type f -print0 | xargs -0 misspell | grep -vE '/(vendor|third_party|\.site)/' | tee /dev/stderr)" 158 159 # Make sure that our builds are reproducible even if you wait between them and 160 # the modified time of the files is different. 161 .PHONY: local-validate-reproducible 162 local-validate-reproducible: 163 mkdir -p .tmp-validate 164 make -B umoci && cp umoci .tmp-validate/umoci.a 165 @echo sleep 10s 166 @sleep 10s && touch $(GO_SRC) 167 make -B umoci && cp umoci .tmp-validate/umoci.b 168 diff -s .tmp-validate/umoci.{a,b} 169 sha256sum .tmp-validate/umoci.{a,b} 170 rm -r .tmp-validate/umoci.{a,b} 171 172 .PHONY: local-validate-build 173 local-validate-build: 174 $(GO) build ${DYN_BUILD_FLAGS} -o /dev/null ${CMD} 175 env CGO_ENABLED=0 $(GO) build ${STATIC_BUILD_FLAGS} -o /dev/null ${CMD} 176 $(GO) test -run nothing ${DYN_BUILD_FLAGS} $(PROJECT)/... 177 178 MANPAGES_MD := $(wildcard doc/man/*.md) 179 MANPAGES := $(MANPAGES_MD:%.md=%) 180 181 doc/man/%.1: doc/man/%.1.md 182 $(GO_MD2MAN) -in $< -out $@ 183 184 .PHONY: docs 185 docs: $(MANPAGES) 186 187 CI_DOCKER_IMAGE ?=$(shell sed -En 's/^FROM\s+(.*)/\1/p' Dockerfile) 188 TEST_DOCKER_IMAGE ?=$(shell sed -En 's/^ARG\s+TEST_DOCKER_IMAGE=(.*)/\1/p' Dockerfile) 189 190 ifndef COVERAGE 191 COVERAGE := $(notdir $(shell mktemp -u umoci.cov.XXXXXX)) 192 endif 193 export COVERAGE 194 195 .PHONY: test-unit 196 test-unit: ci-image 197 touch $(COVERAGE) && chmod a+rw $(COVERAGE) 198 $(DOCKER_ROOTPRIV_RUN) -e COVERAGE $(UMOCI_IMAGE) make local-test-unit 199 $(DOCKER_ROOTLESS_RUN) -e COVERAGE $(UMOCI_IMAGE) make local-test-unit 200 201 .PHONY: local-test-unit 202 local-test-unit: 203 GO=$(GO) hack/test-unit.sh 204 205 .PHONY: test-integration 206 test-integration: ci-image 207 touch $(COVERAGE) && chmod a+rw $(COVERAGE) 208 $(DOCKER_ROOTPRIV_RUN) -e COVERAGE -e TESTS $(UMOCI_IMAGE) make local-test-integration 209 $(DOCKER_ROOTLESS_RUN) -e COVERAGE -e TESTS $(UMOCI_IMAGE) make local-test-integration 210 211 .PHONY: local-test-integration 212 local-test-integration: umoci.cover 213 TESTS="${TESTS}" hack/test-integration.sh 214 215 .PHONY: shell 216 shell: ci-image 217 $(DOCKER_RUN) -it $(UMOCI_IMAGE) bash 218 219 .PHONY: root-shell 220 root-shell: ci-image 221 $(DOCKER_ROOTPRIV_RUN) -it $(UMOCI_IMAGE) bash 222 223 .PHONY: rootless-shell 224 rootless-shell: ci-image 225 $(DOCKER_ROOTLESS_RUN) -it $(UMOCI_IMAGE) bash 226 227 CACHE := .cache 228 CACHE_IMAGE := $(CACHE)/ci-image.tar.zst 229 230 .PHONY: ci-image 231 ci-image: 232 docker pull $(CI_DOCKER_IMAGE) 233 ! [ -f "$(CACHE_IMAGE)" ] || unzstd < "$(CACHE_IMAGE)" | docker load 234 DOCKER_BUILDKIT=1 docker build -t $(UMOCI_IMAGE) \ 235 --progress plain \ 236 --cache-from $(UMOCI_IMAGE) \ 237 --build-arg TEST_DOCKER_IMAGE=$(TEST_DOCKER_IMAGE) \ 238 --build-arg BUILDKIT_INLINE_CACHE=1 . 239 240 .PHONY: ci-cache 241 ci-cache: ci-image 242 rm -rf $(CACHE) && mkdir -p $(CACHE) 243 docker save $(UMOCI_IMAGE) | zstd > $(CACHE_IMAGE) 244 245 .PHONY: ci-validate 246 ci-validate: umoci umoci.static 247 make docs local-validate 248 249 .PHONY: ci-unit 250 ci-unit: umoci.cover 251 make test-unit 252 253 .PHONY: ci-integration 254 ci-integration: umoci.cover 255 make test-integration 256 257 .PHONY: ci 258 ci: 259 @echo "NOTE: This is not identical to the upstream CI, but the tests are the same." 260 make ci-validate ci-unit ci-integration 261 hack/ci-coverage.sh $(COVERAGE)