1include build-aux/tools.mk
2include build-aux/var.mk
3
4#
5# Utility rules
6
7# Assume that any rule ending with '.clean' is phony.
8.PHONY: %.clean
9
10# Also provide a basic *.clean implementation... well, it'd be. But
11# because of what I'm convinced is a bug in Make, it is confusing this
12# %.clean rule with the %.docker.clean rule. So I named this one
13# `%.rm`. But I'd have liked to name it `%.clean`.
14%.rm:
15 rm -f $*
16.PHONY: %.rm
17%.rm-r:
18 rm -rf $*
19.PHONY: %.rm-r
20
21# For files that should only-maybe update when the rule runs, put ".stamp" on
22# the left-side of the ":", and just go ahead and update it within the rule.
23#
24# ".stamp" should NEVER appear in a dependency list (that is, it
25# should never be on the right-side of the ":"), save for in this rule
26# itself.
27%: %.stamp $(tools/copy-ifchanged)
28 @$(tools/copy-ifchanged) $< $@
29docker/%: docker/.%.stamp $(tools/copy-ifchanged)
30 $(tools/copy-ifchanged) $< $@
31
32# Load ocibuild files in to dockerd.
33_ocibuild-images = base
34_ocibuild-images += kat-client
35_ocibuild-images += kat-server
36$(foreach img,$(_ocibuild-images),docker/.$(img).docker.stamp): docker/.%.docker.stamp: docker/%.img.tar
37 docker load < $<
38 docker inspect $$(bsdtar xfO $< manifest.json|jq -r '.[0].RepoTags[0]') --format='{{.Id}}' > $@
39clean: $(foreach img,$(_ocibuild-images),docker/$(img).img.tar.clean)
40
41%.img.tar.clean: %.docker.clean
42 rm -f $*.img.tar $(*D)/.$(*F).img.tar.stamp $(*D)/$(*F).*.layer.tar
43
44#
45# Specific rules
46
47# For images we can either write rules for
48# - `docker/.NAME.img.tar.stamp` for ocibuild-oriented images, or
49# - `docker/.NAME.docker.stamp` for `docker build`-oriented images.
50#
51# Note that there are a few images used by the test suite that are
52# defined in check.mk, rather than here.
53
54# base: Base OS; none of our specific stuff. Used for auxiliar test images
55# that don't need Emissary-specific stuff.
56docker/.base.img.tar.stamp: FORCE $(tools/crane) docker/base-python/Dockerfile
57 $(tools/crane) pull $(shell gawk '$$1 == "FROM" { print $$2; quit; }' < docker/base-python/Dockerfile) $@ || test -e $@
58clobber: docker/base.img.tar.clean
59
60# base-python: Base OS, plus some Emissary-specific setup of
61# low-level/expensive pieces of the Python environment. This does NOT
62# include the packages installed by `requirements.txt`.
63#
64# At the moment, it also includes some other stuff too (kubectl...),
65# but including those things at such an early stage should be
66# understood to be debt from a previous build system, and not
67# something we're actually happy with.
68#
69# In the long-run, this will likely always be a `docker build` rather
70# than an `ocibuild`, in order to do truly base-OS-specific setup
71# (`apk add`, libc-specific compilation...).
72docker/.base-python.docker.stamp: FORCE docker/base-python/Dockerfile docker/base-python.docker.gen
73 docker/base-python.docker.gen >$@
74clobber: docker/base-python.docker.clean
75
76# base-pip: base-python, but with requirements.txt installed.
77#
78# Mixed feelings about this one; it kinda wants to not be a separate
79# image and just be part of the main emissary Dockerfile. But that
80# would create problems for generate.mk's `pip freeze` step. Perhaps
81# it will get to go away with `ocibuild`.
82#
83# TODO(lukeshu): Figure out a `py-list-deps`-based workflow for
84# updating requirements-dev.txt.
85#python/requirements-dev.txt: $(tools/py-list-deps) $(tools/write-ifchanged) FORCE
86# $(tools/py-list-deps) --include-dev python/ | $(tools/write-ifchanged) $@
87python/requirements.in: $(tools/py-list-deps) $(tools/write-ifchanged) FORCE
88 set -o pipefail; $(tools/py-list-deps) --no-include-dev python/ | $(tools/write-ifchanged) $@
89clean: python/requirements.in.rm
90python/.requirements.txt.stamp: python/requirements.in docker/base-python.docker.tag.local
91# The --interactive is so that stdin gets passed through; otherwise Docker closes stdin.
92 set -ex -o pipefail; { \
93 docker run --platform="$(BUILD_ARCH)" --rm --interactive "$$(cat docker/base-python.docker)" sh -c 'tar xf - && pip-compile --allow-unsafe -q >&2 && cat requirements.txt' \
94 < <(bsdtar -cf - -C $(@D) requirements.in requirements.txt) \
95 > $@; }
96clean: python/.requirements.txt.stamp.rm
97python/requirements.txt: python/%: python/.%.stamp $(tools/copy-ifchanged)
98 $(tools/copy-ifchanged) $< $@
99.PRECIOUS: python/requirements.txt
100docker/base-pip/requirements.txt: python/requirements.txt $(tools/copy-ifchanged)
101 $(tools/copy-ifchanged) $< $@
102clean: docker/base-pip/requirements.txt.rm
103docker/.base-pip.docker.stamp: docker/.%.docker.stamp: docker/%/Dockerfile docker/%/requirements.txt docker/base-python.docker.tag.local
104 docker build --platform="$(BUILD_ARCH)" --build-arg=from="$$(sed -n 2p docker/base-python.docker.tag.local)" --iidfile=$@ $(<D)
105clobber: docker/base-pip.docker.clean
106
107# The Helm chart
108build-output/chart-%.d: \
109 $(shell find charts/emissary-ingress) \
110 $(var.)DEV_REGISTRY $(var.)RELEASE_REGISTRY \
111 $(tools/chart-doc-gen)
112ifeq ($(CI),)
113 rm -rf $@
114else
115 @if test -d $@; then \
116 echo 'This should not happen in CI: $@ should not need to change' >&2; \
117 echo 'Files triggering the change are: $?' >&2; \
118 exit 1; \
119 fi
120endif
121 mkdir -p $(@D)
122 cp -a $< $@
123 @PS4=; set -ex -o pipefail; { \
124 if [[ '$(word 1,$(subst _, ,$*))' =~ ^[0-9]+\.[0-9]+\.[0-9]+(-rc\.[0-9]+|-ea)?$$ ]]; then \
125 registry=$(RELEASE_REGISTRY); \
126 else \
127 registry=$(DEV_REGISTRY); \
128 fi; \
129 for file in Chart.yaml values.yaml; do \
130 sed \
131 -e 's/@version@/$(word 1,$(subst _, ,$*))/g' \
132 -e 's/@chartVersion@/$(word 2,$(subst _, ,$*))/g' \
133 -e "s,@imageRepo@,$${registry}/emissary,g" \
134 <'$<'/"$${file}.in" \
135 >'$@'/"$${file}"; \
136 done; \
137 }
138 $(tools/chart-doc-gen) -d $</doc.yaml -t $</readme.tpl -v $@/values.yaml >$@/README.md
139build-output/chart-%.tgz: build-output/chart-%.d
140 helm package --destination=$< $<
141 mv $</emissary-ingress-$(word 2,$(subst _, ,$*)).tgz $@
142
143# Convenience aliases for the Helm chart
144chart_dir = build-output/chart-$(patsubst v%,%,$(VERSION))_$(patsubst v%,%,$(CHART_VERSION)).d
145chart_tgz = $(patsubst %.d,%.tgz,$(chart_dir))
146chart: $(chart_tgz)
147PHONY: chart
148
149_major_version = $(firstword $(subst ., ,$(patsubst v%,%,$(VERSION))))
150_chart_major_version = $(firstword $(subst ., ,$(patsubst v%,%,$(CHART_VERSION))))
151boguschart_dir = build-output/chart-$(_major_version).0.0-bogus_$(_chart_major_version).0.0-bogus.d
152boguschart_tgz = $(patsubst %.d,%.tgz,$(boguschart_dir))
153
154# YAML manifests
155build-output/yaml-%: $(shell find $(CURDIR)/manifests/emissary -type d -o -name '*.yaml.in') $(var.)DEV_REGISTRY $(var.)RELEASE_REGISTRY
156ifeq ($(CI),)
157 rm -rf $@
158else
159 @if test -d $@; then \
160 echo 'This should not happen in CI: $@ should not need to change' >&2; \
161 echo 'Files triggering the change are: $?' >&2; \
162 exit 1; \
163 fi
164endif
165 mkdir -p $@
166 $(foreach src,$(filter %.yaml.in,$^),$(foreach dst,$(patsubst $(CURDIR)/manifests/emissary/%.yaml.in,$@/%.yaml,$(src)),\
167 { \
168 if [[ '$*' =~ ^[0-9]+\.[0-9]+\.[0-9]+(-rc\.[0-9]+|-ea)?$$ ]]; then \
169 registry=$(RELEASE_REGISTRY); \
170 else \
171 registry=$(DEV_REGISTRY); \
172 fi; \
173 sed -e 's/\$$version\$$/$*/g' -e 's,\$$imageRepo\$$,'"$${registry}"'/emissary,g' <$(src) >$(dst); \
174 }$(NL)))
175
176build-output/docs-yaml-%: $(shell find docs/yaml)
177ifeq ($(CI),)
178 rm -rf $@
179else
180 @if test -d $@; then \
181 echo 'This should not happen in CI: $@ should not need to change' >&2; \
182 echo 'Files triggering the change are: $?' >&2; \
183 exit 1; \
184 fi
185endif
186 $(foreach src,$(filter %.yaml,$^),$(foreach dst,$(patsubst docs/yaml/%,$@/%,$(src)),\
187 mkdir -p $(dir $(dst))$(NL)\
188 sed -e 's/\$$version\$$/$*/g' -e 's/\$$quoteVersion$$/0.4.1/g' <$(src) >$(dst)$(NL)))
189
190#
191# Destructive rules
192
193clobber: clean
194
195clean: build-output.rm-r
196
197python.clean releng.clean: %.clean: python/ambassador.egg-info.rm-r
198 find $* -name __pycache__ -exec rm -rf -- {} +
199clean: python.clean releng.clean
200
201cmd.clean pkg.clean: %.clean:
202 find $* -name '*.yaml.o' -delete
203clean: cmd.clean pkg.clean
View as plain text