-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathMakefile
More file actions
222 lines (176 loc) · 6.35 KB
/
Makefile
File metadata and controls
222 lines (176 loc) · 6.35 KB
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
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
.POSIX:
.DEFAULT_GOAL := all
all: images operator manifest
.PHONY: all
# Use this empty target to force execution of a rule
FORCE:
include VERSION
VERSION_FULL = \
$(VERSION_MAJOR).$(VERSION_MINOR).$(VERSION_PATCH)$(VERSION_SUFFIX)
PWD := $(shell pwd)
GIT_REVISION := $(shell git describe --long --always --tags --dirty)
BUILD_TIMESTAMP := $(shell date -u +"%Y-%m-%dT%H:%M:%SZ")
BUILD_HOST := $(shell hostname)
ifeq '$(VERSION_SUFFIX)' 'dev'
DEVELOPMENT_RELEASE = 1
else
DEVELOPMENT_RELEASE = 0
endif
PRODUCT_NAME ?= Example Solution
PRODUCT_LOWERNAME ?= example-solution
# Destination paths
BUILD_ROOT ?= $(PWD)/_build
ISO_ROOT ?= $(BUILD_ROOT)/root
IMAGES_ROOT = $(ISO_ROOT)/images
ISO ?= $(BUILD_ROOT)/$(PRODUCT_LOWERNAME)-$(VERSION_FULL).iso
# Source paths
IMAGES_SRC ?= $(PWD)/images
OPERATOR_SRC ?= $(PWD)/operator
# Binary paths and options
DOCKER ?= docker
DOCKER_OPTS ?=
DOCKER_SOCKET ?= unix:///var/run/docker.sock
HARDLINK ?= hardlink
SKOPEO ?= skopeo
SKOPEO_OPTS ?= --override-os linux --insecure-policy
REGISTRY_SCRIPT ?= \
$(PWD)/static-container-registry/static-container-registry.py
# Container images {{{
BUILD_ARGS ?= \
--build-arg VERSION=$(VERSION_FULL) \
--build-arg BUILD_DATE=$(BUILD_TIMESTAMP) \
--build-arg VCS_REF=$(GIT_REVISION) \
--build-arg PROJECT_VERSION=$(VERSION_FULL)
# Images are either defined under `images/<name>/`, or in the Operator
# sources.
# Operator image deserve special treatment and is thus handled separately.
STD_IMAGES := $(notdir $(wildcard $(IMAGES_SRC)/*))
# Image targets and their order of execution is controlled using indicator
# files stored in `_build/images/<image_name>/`.
# A `.built` file is touched on time of build, and `.saved` on time of save.
_built_tgt = $(BUILD_ROOT)/images/$(1)/.built
_saved_tgt = $(BUILD_ROOT)/images/$(1)/.saved
images: build_images save_images dedup_images gen_registry_config
.PHONY: images
# Build container images
build_images: build_operator build_std_images
.PHONY: build_images
# Build Operator image
OPERATOR_IMG_NAME ?= $(PRODUCT_LOWERNAME)-operator
OPERATOR_BUILD_TARGET = $(call _built_tgt,$(OPERATOR_IMG_NAME))
build_operator: $(OPERATOR_BUILD_TARGET)
.PHONY: build_operator
OPERATOR_BUILD_ARGS ?= \
--build-arg VERSION=$(VERSION_FULL)
$(OPERATOR_BUILD_TARGET):
@echo Building Operator image "$(OPERATOR_IMG_NAME):$(VERSION_FULL)"...
@mkdir -p $(@D)
$(DOCKER) $(DOCKER_OPTS) build -t $(OPERATOR_IMG_NAME):$(VERSION_FULL) $(OPERATOR_BUILD_ARGS) $(OPERATOR_SRC)
@touch $@
@echo Built Operator image.
# Build other images
STD_BUILD_TARGETS = $(foreach img,$(STD_IMAGES),$(call _built_tgt,$(img)))
build_std_images: $(STD_BUILD_TARGETS)
.PHONY: build_std_images
$(BUILD_ROOT)/images/%/.built: $(IMAGES_SRC)/%/*
@echo Building component image "$*:$(VERSION_FULL)"
@echo All preprequisites for this component: $^
@mkdir -p $(@D)
$(DOCKER) $(DOCKER_OPTS) build -t $*:$(VERSION_FULL) $(BUILD_ARGS) $(<D)
@touch $@
@echo Built all component images.
# Save images as layers with skopeo
ALL_IMG_NAMES = $(STD_IMAGES) $(OPERATOR_IMG_NAME)
IMG_SAVE_TARGETS = $(foreach img,$(ALL_IMG_NAMES),$(call _saved_tgt,$(img)))
save_images: $(IMG_SAVE_TARGETS) | build_images
.PHONY: save_images
$(IMAGES_ROOT)/%:
mkdir -p $@
$(BUILD_ROOT)/images/%/.saved: $(BUILD_ROOT)/images/%/.built | $(IMAGES_ROOT)/%
@echo Saving image "$*:$(VERSION_FULL)"...
@mkdir -p $(@D)
$(SKOPEO) $(SKOPEO_OPTS) copy \
--format v2s2 --dest-compress \
--src-daemon-host $(DOCKER_SOCKET) \
docker-daemon:$*:$(VERSION_FULL) \
dir:$(IMAGES_ROOT)/$*/$(VERSION_FULL)
@touch $@
@echo Saved all images.
# Deduplicate image layers with hardlink
dedup_images: $(BUILD_ROOT)/images/.deduplicated | save_images
.PHONY: dedup_images
$(BUILD_ROOT)/images/.deduplicated: $(IMG_SAVE_TARGETS)
@echo Deduplicating image layers...
$(HARDLINK) -c $(IMAGES_ROOT)
@touch $@
@echo Deduplicated image layers.
# Generate image registry config for NGINX with a custom script
gen_registry_config: $(ISO_ROOT)/registry-config.inc.j2 | dedup_images
.PHONY: gen_registry_config
$(ISO_ROOT)/registry-config.inc.j2: $(BUILD_ROOT)/images/.deduplicated
@echo Generating NGINX registry configuration...
$(REGISTRY_SCRIPT) \
--name-prefix '{{ repository }}' \
--server-root '{{ registry_root }}' \
--omit-constants \
$(IMAGES_ROOT) > $@
@echo Generated NGINX registry configuration.
# }}}
# Files to copy into the build tree {{{
# Operator manifests
CRD_DEST := $(ISO_ROOT)/operator/deploy/crds
generate_crds:
@mkdir -p $(CRD_DEST)
@rm -f $(CRD_DEST)/*.yaml
kustomize build $(OPERATOR_SRC)/config/crd -o $(CRD_DEST)
@for f in $(CRD_DEST)/*.yaml; do \
mv "$$f" "$${f%.yaml}_crd.yaml"; \
done
.PHONY: generate_crds
$(ISO_ROOT)/operator/deploy/role.yaml:
@mkdir -p $(@D)
@rm -f $@
kustomize build $(OPERATOR_SRC)/config/rbac | yq -y 'select(.kind == "Role" or .kind == "ClusterRole")' > $@
operator: generate_crds $(ISO_ROOT)/operator/deploy/role.yaml
.PHONY: operator
# Solution manifest
manifest: $(ISO_ROOT)/manifest.yaml
.PHONY: manifest
$(ISO_ROOT)/manifest.yaml: $(PWD)/manifest.py $(PWD)/VERSION FORCE
@echo Write Solution info to "manifest.yaml".
@rm -f $@
@mkdir -p $(@D)
$< --name "$(PRODUCT_LOWERNAME)" \
--annotation "solutions.metalk8s.scality.com/build-timestamp" "$(BUILD_TIMESTAMP)" \
--annotation "solutions.metalk8s.scality.com/build-host" "$(BUILD_HOST)" \
--annotation "solutions.metalk8s.scality.com/development-release" "$(DEVELOPMENT_RELEASE)" \
--annotation "solutions.metalk8s.scality.com/display-name" "$(PRODUCT_NAME)" \
--annotation "solutions.metalk8s.scality.com/git-revision" "$(GIT_REVISION)" \
--extra-image "base-server" "$(VERSION_FULL)" \
--extra-image "$(UI_IMG_NAME)" "$(VERSION_FULL)" \
--operator-image "$(OPERATOR_IMG_NAME)" "$(VERSION_FULL)" \
--version "$(VERSION_FULL)" \
> $@ || (rm -f $@; false)
# }}}
# Generate ISO archive {{{
iso: $(ISO)
.PHONY: iso
# Since manifest.yaml is generated every time, we don't need explicit
# requisites for this ISO generation - it will happen every time.
# We leave the `all` target handle generation of the ISO contents.
$(ISO): all
mkisofs -output $@ \
-quiet \
-rock \
-joliet \
-joliet-long \
-full-iso9660-filenames \
-volid "$(PRODUCT_NAME) $(VERSION_FULL)" \
--iso-level 3 \
-gid 0 \
-uid 0 \
-input-charset iso8859-1 \
-output-charset iso8859-1 \
$(ISO_ROOT)
cd $$(dirname $@) && sha256sum $(notdir $@) > SHA256SUM
# }}}