forked from cilium/cilium
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Makefile.buildkit
105 lines (87 loc) · 4.15 KB
/
Makefile.buildkit
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
# Copyright 2020 Authors of Cilium
# SPDX-License-Identifier: Apache-2.0
ifdef DOCKER_BUILDKIT
BUILD_DIR := _build
# Export with value expected by docker
export DOCKER_BUILDKIT=1
# Clean the build directory and cache
clean-build:
-$(QUIET) rm -rf _build
-$(QUIET) docker builder prune --filter type=exec.cachemount -f
veryclean: clean-build
BUILDKIT_DOCKERFILE_FILTER := | sed -e "1s|^\#.*|\# syntax = docker/dockerfile:experimental|" -e "s|^RUN\(.*\)make|RUN --mount=type=cache,target=/root/.cache/go-build\1make|"
# Check that files needed for git-less build are up-to-date
build-context-update: GIT_VERSION
# Generic rule for augmented .dockerignore files. For 'Dockerfile' the stem ('%') matches just the 'D'.
# '.git' can not be ignored in the top level '.dockerignore' as builds directly from the Dockerfiles
# (e.g., on Docker hub and Quay) depend on '.git' for the git SHA.
.PRECIOUS: _build/%ockerfile.dockerignore
GIT_IGNORE_FILES := $(shell find . -not -path "./_build*" -not -path "./vendor*" -name .gitignore -print)
_build/%ockerfile.dockerignore: $(GIT_IGNORE_FILES) Makefile.buildkit
@-mkdir -p $(dir $@)
@echo "/hack" > $@
@echo ".git" >> $@
echo $(dir $(GIT_IGNORE_FILES)) | tr ' ' '\n' | xargs -P1 -n1 -I {DIR} sed \
-e '# Remove lines with white space, comments and files that must be passed to docker, "$$" due to make. #' \
-e '/^[[:space:]]*$$/d' -e '/^#/d' -e '/GIT_VERSION/d' \
-e '# Apply pattern in all directories if it contains no "/", keep "!" up front. #' \
-e '/^[^!/][^/]*$$/s<^<**/<' -e '/^![^/]*$$/s<^!<!**/<' \
-e '# Prepend with the directory name, keep "!" up front. #' \
-e '/^[^!]/s<^<{DIR}<' -e '/^!/s<^!<!{DIR}<'\
-e '# Remove leading "./", keep "!" up front. #' \
-e 's<^\./<<' -e 's<^!\./<!<' \
-e '# Append newline to the last line if missing. GNU sed does not do this automatically. #' \
-e '$$a\' \
{DIR}.gitignore >> $@
# Generic rule for Dockerfiles. For 'Dockerfile' the stem ('%') matches just the 'D'.
_build/%ockerfile: %ockerfile _build/%ockerfile.dockerignore force
@-mkdir -p $(dir $@)
@cat $< $(BUILDKIT_DOCKERFILE_FILTER) > $@
@-grep "^FROM " $@ | cut -d ' ' -f2 | grep -v -e "scratch" -e "[$$_{}]" | xargs -P4 -n1 docker pull
#
# Optionally make a shallow clone of the repo to explicitly exclude
# all files not in git from the build.
#
ifdef BUILD_ONLY_COMMITTED
DOCKER_BUILD_DIR := $(BUILD_DIR)/context
# _build/.git is a shallow bare clone of the main repo
# - mkdir can fail if the directory exists already
# - git clone will fail if _build.git already exists.
# In this case the following 'build-context-update' will update it
# If the _build directory gets into bad shape 'make veryclean' will nuke it.
_build/.git:
-mkdir -p _build
-git clone --bare --no-local --depth 1 . _build/.git && cd _build && git remote set-url origin ..
#
# Create _build context:
# _build/context/.git will be a file (rather than directory) that contains git specific
# symbolic link to _build/.git (--separate-git-dir)
#
_build/context: _build/.git
git init --separate-git-dir=$< $@
@echo "gitdir: ../.git" > _build/context/.git
#
# Update the docker build context by:
# 1. shallow fetch from the main repo to _build/.git
# 2. check out FETCH_HEAD into _build/context. Hard reset seems to be a best way of doing this.
# 3. remove the .git file from _build/context/.git so that make running in docker knows this is
# no a git repo (as _build/.git is NOT part of the docker context)
#
# Dependencies:
# - check that git status is clean
# - make sure docker build context exists
# - update GIT_VERSION in the build context if needed
#
build-context-update: check-status _build/context _build/context/GIT_VERSION
cd _build && git fetch --depth=1 --no-tags
cd _build/context && git reset --hard FETCH_HEAD && git clean -fd
#
# Docker build context does not contain the actual git repo, so we need to pass
# GIT_VERSION to the build context separately.
#
_build/context/GIT_VERSION: GIT_VERSION _build/context
cp $< $@
check-status:
@if [ -n "`git status --porcelain`" ] ; then git status && echo "These changes will not be included in build, aborting. Define IGNORE_GIT_STATUS to build anyway." && test $(IGNORE_GIT_STATUS); fi
endif
endif