Makefile 9.0 KB
Newer Older
1 2 3
# -*- makefile -*-
# vim: filetype=make

4 5 6 7 8
# The root directory of the libvirt.git checkout
CI_GIT_ROOT = $(shell git rev-parse --show-toplevel)

# The root directory for all CI-related contents
CI_ROOTDIR = $(CI_GIT_ROOT)/ci
9 10 11

# The directory holding content on the host that we will
# expose to the container.
12
CI_SCRATCHDIR = $(CI_ROOTDIR)/scratch
13 14 15 16 17 18

# The directory holding the clone of the git repo that
# we will expose to the container
CI_HOST_SRCDIR = $(CI_SCRATCHDIR)/src

# The directory holding the source inside the
19
# container, i.e. where we want to expose
20
# the $(CI_HOST_SRCDIR) directory from the host
21
CI_CONT_SRCDIR = $(CI_USER_HOME)/libvirt
22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43

# Relative directory to perform the build in. This
# defaults to using a separate build dir, but can be
# set to empty string for an in-source tree build.
CI_VPATH = build

# The directory holding the build output inside the
# container.
CI_CONT_BUILDDIR = $(CI_CONT_SRCDIR)/$(CI_VPATH)

# Can be overridden with mingw{32,64}-configure if desired
CI_CONFIGURE = $(CI_CONT_SRCDIR)/configure

# Default to using all possible CPUs
CI_SMP = $(shell getconf _NPROCESSORS_ONLN)

# Any extra arguments to pass to make
CI_MAKE_ARGS =

# Any extra arguments to pass to configure
CI_CONFIGURE_ARGS =

44 45 46
# Script containing environment preparation steps
CI_PREPARE_SCRIPT = $(CI_ROOTDIR)/prepare.sh

47 48 49
# Script containing build instructions
CI_BUILD_SCRIPT = $(CI_ROOTDIR)/build.sh

50
# Location of the container images we're going to pull
51 52
# Can be useful to overridde to use a locally built
# image instead
53
CI_IMAGE_PREFIX = quay.io/libvirt/buildenv-libvirt-
54

55 56
# The default tag is ':latest' but if the container
# repo above uses different conventions this can override it
57
CI_IMAGE_TAG = :latest
58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73

# We delete the virtual root after completion, set
# to 0 if you need to keep it around for debugging
CI_CLEAN = 1

# We'll always freshly clone the virtual root each
# time in case it was not cleaned up before. Set
# to 1 if you want to try restarting a previously
# preserved env
CI_REUSE = 0

# We need the container process to run with current host IDs
# so that it can access the passed in build directory
CI_UID = $(shell id -u)
CI_GID = $(shell id -g)

74 75 76 77 78
# We also need the user's login and home directory to prepare the
# environment the way some programs expect it
CI_USER_LOGIN = $(shell echo "$$USER")
CI_USER_HOME = $(shell echo "$$HOME")

79 80 81 82 83 84 85 86
CI_ENGINE = auto
# Container engine we are going to use, can be overridden per make
# invocation, if it is not we try podman and then default to docker.
ifeq ($(CI_ENGINE),auto)
	override CI_ENGINE = $(shell podman version >/dev/null 2>&1 && echo podman || echo docker)
endif

# IDs you run as do not need to exist in
87
# the container's /etc/passwd & /etc/group files, but
88
# if they do not, then libvirt's 'make check' will fail
89
# many tests.
90

91 92
# We do not directly mount /etc/{passwd,group} as Docker
# is liable to mess with SELinux labelling which will
93 94
# then prevent the host accessing them. And podman cannot
# relabel the files due to it running rootless. So
E
Eric Blake 已提交
95
# copying them first is safer and less error-prone.
96 97 98 99 100
CI_PWDB_MOUNTS = \
	--volume $(CI_SCRATCHDIR)/group:/etc/group:ro,z \
	--volume $(CI_SCRATCHDIR)/passwd:/etc/passwd:ro,z \
	$(NULL)

101 102 103 104
CI_HOME_MOUNTS = \
	--volume $(CI_SCRATCHDIR)/home:$(CI_USER_HOME):z \
	$(NULL)

105
CI_SCRIPT_MOUNTS = \
106
	--volume $(CI_SCRATCHDIR)/prepare:$(CI_USER_HOME)/prepare:z \
107 108 109
	--volume $(CI_SCRATCHDIR)/build:$(CI_USER_HOME)/build:z \
	$(NULL)

110 111 112 113 114
# Docker containers can have very large ulimits
# for nofiles - as much as 1048576. This makes
# libvirt very slow at exec'ing programs.
CI_ULIMIT_FILES = 1024

115
ifeq ($(CI_ENGINE),podman)
E
Eric Blake 已提交
116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135
	# Podman cannot reuse host namespace when running non-root
	# containers.  Until support for --keep-uid is added we can
	# just create another mapping that will do that for us.
	# Beware, that in {uid,git}map=container_id:host_id:range, the
	# host_id does actually refer to the uid in the first mapping
	# where 0 (root) is mapped to the current user and rest is
	# offset.
	#
	# In order to set up this mapping, we need to keep all the
	# user IDs to prevent possible errors as some images might
	# expect UIDs up to 90000 (looking at you fedora), so we don't
	# want the overflowuid to be used for them.  For mapping all
	# the other users properly, some math needs to be done.
	# Don't worry, it's just addition and subtraction.
	#
	# 65536 ought to be enough (tm), but for really rare cases the
	# maximums might need to be higher, but that only happens when
	# your /etc/sub{u,g}id allow users to have more IDs.  Unless
	# --keep-uid is supported, let's do this in a way that should
	# work for everyone.
136 137
	CI_MAX_UID = $(shell sed -n "s/^$(CI_USER_LOGIN):[^:]\+://p" /etc/subuid)
	CI_MAX_GID = $(shell sed -n "s/^$(CI_USER_LOGIN):[^:]\+://p" /etc/subgid)
138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158
	ifeq ($(CI_MAX_UID),)
		CI_MAX_UID = 65536
	endif
	ifeq ($(CI_MAX_GID),)
		CI_MAX_GID = 65536
	endif
	CI_UID_OTHER = $(shell echo $$(($(CI_UID)+1)))
	CI_GID_OTHER = $(shell echo $$(($(CI_GID)+1)))
	CI_UID_OTHER_RANGE = $(shell echo $$(($(CI_MAX_UID)-$(CI_UID))))
	CI_GID_OTHER_RANGE = $(shell echo $$(($(CI_MAX_GID)-$(CI_GID))))

	CI_PODMAN_ARGS = \
		--uidmap 0:1:$(CI_UID) \
		--uidmap $(CI_UID):0:1 \
		--uidmap $(CI_UID_OTHER):$(CI_UID_OTHER):$(CI_UID_OTHER_RANGE) \
		--gidmap 0:1:$(CI_GID) \
		--gidmap $(CI_GID):0:1 \
		--gidmap $(CI_GID_OTHER):$(CI_GID_OTHER):$(CI_GID_OTHER_RANGE) \
		$(NULL)
endif

159 160 161 162 163 164 165 166 167 168
# Args to use when cloning a git repo.
#  -c  stop it complaining about checking out a random hash
#  -q  stop it displaying progress info for local clone
#  --local ensure we don't actually copy files
CI_GIT_ARGS = \
	-c advice.detachedHead=false \
	-q \
	--local  \
	$(NULL)

169
# Args to use when running the container
170 171 172 173 174 175 176 177
#   --rm      stop inactive containers getting left behind
#   --user    we execute as the same user & group account
#             as dev so that file ownership matches host
#             instead of root:root
#   --volume  to pass in the cloned git repo & config
#   --ulimit  lower files limit for performance reasons
#   --interactive
#   --tty     Ensure we have ability to Ctrl-C the build
178
CI_ENGINE_ARGS = \
179 180 181
	--rm \
	--interactive \
	--tty \
182
	$(CI_PODMAN_ARGS) \
183
	$(CI_PWDB_MOUNTS) \
184
	$(CI_HOME_MOUNTS) \
185
	$(CI_SCRIPT_MOUNTS) \
186 187
	--volume $(CI_HOST_SRCDIR):$(CI_CONT_SRCDIR):z \
	--ulimit nofile=$(CI_ULIMIT_FILES):$(CI_ULIMIT_FILES) \
M
Michal Privoznik 已提交
188
	--cap-add=SYS_PTRACE \
189 190
	$(NULL)

191 192 193
ci-check-engine:
	@echo -n "Checking if $(CI_ENGINE) is available..." && \
	$(CI_ENGINE) version 1>/dev/null && echo "yes"
194

195
ci-prepare-tree: ci-check-engine
196 197 198 199 200
	@test "$(CI_REUSE)" != "1" && rm -rf $(CI_SCRATCHDIR) || :
	@if ! test -d $(CI_SCRATCHDIR) ; then \
		mkdir -p $(CI_SCRATCHDIR); \
		cp /etc/passwd $(CI_SCRATCHDIR); \
		cp /etc/group $(CI_SCRATCHDIR); \
201
		mkdir -p $(CI_SCRATCHDIR)/home; \
202
		cp "$(CI_PREPARE_SCRIPT)" $(CI_SCRATCHDIR)/prepare; \
203
		cp "$(CI_BUILD_SCRIPT)" $(CI_SCRATCHDIR)/build; \
204
		chmod +x "$(CI_SCRATCHDIR)/prepare" "$(CI_SCRATCHDIR)/build"; \
205 206
		echo "Cloning $(CI_GIT_ROOT) to $(CI_HOST_SRCDIR)"; \
		git clone $(CI_GIT_ARGS) $(CI_GIT_ROOT) $(CI_HOST_SRCDIR) || exit 1; \
207
		for mod in $$(git submodule | awk '{ print $$2 }' | sed -E 's,^../,,g') ; \
208 209 210 211 212 213 214
		do \
			test -f $(CI_GIT_ROOT)/$$mod/.git || continue ; \
			echo "Cloning $(CI_GIT_ROOT)/$$mod to $(CI_HOST_SRCDIR)/$$mod"; \
			git clone $(CI_GIT_ARGS) $(CI_GIT_ROOT)/$$mod $(CI_HOST_SRCDIR)/$$mod || exit 1; \
		done ; \
	fi

215
ci-run-command@%: ci-prepare-tree
216
	$(CI_ENGINE) run $(CI_ENGINE_ARGS) $(CI_IMAGE_PREFIX)$*$(CI_IMAGE_TAG) \
217
		/bin/bash -c ' \
218
		$(CI_USER_HOME)/prepare || exit 1; \
219 220 221 222
		sudo \
		  --login \
		  --user="#$(CI_UID)" \
		  --group="#$(CI_GID)" \
223
		  CONFIGURE_OPTS="$$CONFIGURE_OPTS" \
224 225 226 227 228 229 230
		  CI_CONT_SRCDIR="$(CI_CONT_SRCDIR)" \
		  CI_CONT_BUILDDIR="$(CI_CONT_BUILDDIR)" \
		  CI_SMP="$(CI_SMP)" \
		  CI_CONFIGURE="$(CI_CONFIGURE)" \
		  CI_CONFIGURE_ARGS="$(CI_CONFIGURE_ARGS)" \
		  CI_MAKE_ARGS="$(CI_MAKE_ARGS)" \
		  $(CI_COMMAND) || exit 1'
231 232
	@test "$(CI_CLEAN)" = "1" && rm -rf $(CI_SCRATCHDIR) || :

233 234 235 236 237 238
ci-shell@%:
	$(MAKE) -C $(CI_ROOTDIR) ci-run-command@$* CI_COMMAND="/bin/bash"

ci-build@%:
	$(MAKE) -C $(CI_ROOTDIR) ci-run-command@$* CI_COMMAND="$(CI_USER_HOME)/build"

239
ci-check@%:
240
	$(MAKE) -C $(CI_ROOTDIR) ci-build@$* CI_MAKE_ARGS="check"
241

242 243 244 245 246 247 248 249 250 251 252
ci-list-images:
	@echo
	@echo "Available x86 container images:"
	@echo
	@sh list-images.sh "$(CI_ENGINE)" "$(CI_IMAGE_PREFIX)" | grep -v cross
	@echo
	@echo "Available cross-compiler container images:"
	@echo
	@sh list-images.sh "$(CI_ENGINE)" "$(CI_IMAGE_PREFIX)" | grep cross
	@echo

253
ci-help:
254
	@echo "Build libvirt inside containers used for CI"
255 256 257 258 259 260
	@echo
	@echo "Available targets:"
	@echo
	@echo "    ci-build@\$$IMAGE - run a default 'make'"
	@echo "    ci-check@\$$IMAGE - run a 'make check'"
	@echo "    ci-shell@\$$IMAGE - run an interactive shell"
261 262
	@echo "    ci-list-images  - list available images"
	@echo "    ci-help         - show this help message"
263 264 265
	@echo
	@echo "Available make variables:"
	@echo
266 267 268
	@echo "    CI_CLEAN=0     - do not delete '$(CI_SCRATCHDIR)' after completion"
	@echo "    CI_REUSE=1     - re-use existing '$(CI_SCRATCHDIR)' content"
	@echo "    CI_ENGINE=auto - container engine to use (podman, docker)"
269
	@echo