Commit | Line | Data |
---|---|---|
e36b4f25 MW |
1 | ### -*-makefile-*- |
2 | ### | |
3 | ### Main maintenance script for chroots | |
4 | ### | |
5 | ### (c) 2018 Mark Wooding | |
6 | ### | |
7 | ||
8 | ###----- Licensing notice --------------------------------------------------- | |
9 | ### | |
10 | ### This file is part of the distorted.org.uk chroot maintenance tools. | |
11 | ### | |
12 | ### distorted-chroot is free software: you can redistribute it and/or | |
13 | ### modify it under the terms of the GNU General Public License as | |
14 | ### published by the Free Software Foundation; either version 2 of the | |
15 | ### License, or (at your option) any later version. | |
16 | ### | |
17 | ### distorted-chroot is distributed in the hope that it will be useful, | |
18 | ### but WITHOUT ANY WARRANTY; without even the implied warranty of | |
19 | ### MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
20 | ### General Public License for more details. | |
21 | ### | |
22 | ### You should have received a copy of the GNU General Public License | |
23 | ### along with distorted-chroot. If not, write to the Free Software | |
24 | ### Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, | |
25 | ### USA. | |
26 | ||
27 | all:: | |
28 | clean:: | |
29 | .PHONY: all clean | |
30 | .SECONDEXPANSION: #sorry | |
31 | ||
32 | ###-------------------------------------------------------------------------- | |
33 | ### Configuration. | |
34 | ||
35 | CONFIG_VARS = | |
36 | ||
37 | ## Volume group from which to allocate chroot volumes and snapshots. | |
38 | CONFIG_VARS += VG LVPREFIX | |
39 | VG = vg-$(shell hostname) | |
40 | LVPREFIX = | |
41 | ||
42 | ## Logical volume size, as an LVM option. | |
43 | CONFIG_VARS += LVSZ | |
44 | LVSZ = -L8G | |
45 | ||
46 | ## Debian mirror. | |
47 | CONFIG_VARS += DEBMIRROR | |
48 | DEBMIRROR = http://deb.debian.org/debian/ | |
49 | ||
50 | ## APT sources configurations. (Also, $($d_APTSRC) for each $d in $(DISTS).) | |
51 | CONFIG_VARS += APTSRC | |
52 | APTSRC = etc/aptsrc.conf $(wildcard etc/aptsrc.local.conf) | |
53 | ||
54 | ## APT configuration fragment names. These will be linked into | |
55 | ## `/etc/apt/apt.conf.d' in each chroot. To put a fragment f in a surprising | |
56 | ## place, set $($f_APTCONFSRC). | |
57 | CONFIG_VARS += APTCONF | |
58 | APTCONF_DIR = etc/apt-conf.d | |
59 | APTCONF = $(notdir $(wildcard $(APTCONF_DIR)/[0-9]*[!~])) | |
60 | ||
61 | ## Proxy setting. | |
62 | CONFIG_VARS += PROXY | |
63 | PROXY := $(shell \ | |
64 | eval $$(apt-config $(foreach a,$(APTCONF), -c$(APTCONF_DIR)/$a) \ | |
65 | shell proxy Acquire::http::proxy); \ | |
66 | case $${proxy+t} in (t) echo "$$proxy" ;; (*) echo nil ;; esac) | |
67 | ||
68 | ## Debian distributions to support. | |
69 | CONFIG_VARS += PRIMARY_DIST DISTS | |
70 | PRIMARY_DIST = stretch | |
71 | DISTS = $(PRIMARY_DIST) buster bullseye sid | |
72 | ||
73 | ## Host's native architecture(s). | |
74 | CONFIG_VARS += MYARCH NATIVE_ARCHS | |
75 | MYARCH = $(shell dpkg --print-architecture) | |
76 | OTHERARCHS = $(shell dpkg --print-foreign-architectures) | |
77 | NATIVE_ARCHS = $(MYARCH) $(OTHERARCHS) | |
78 | ||
79 | ## Foreign (emulated) architectures to support. | |
80 | CONFIG_VARS += FOREIGN_ARCHS | |
81 | FOREIGN_ARCHS = | |
82 | ||
83 | ## Master lists of chroots to build and maintain. | |
84 | NATIVE_CHROOTS = $(foreach a,$(NATIVE_ARCHS), \ | |
85 | $(foreach d,$(or $($a_DISTS) $(DISTS)), \ | |
86 | $d-$a)) | |
87 | FOREIGN_CHROOTS = $(foreach a,$(FOREIGN_ARCHS), \ | |
88 | $(foreach d,$(or $($a_DISTS) $(DISTS)), \ | |
89 | $d-$a)) | |
90 | ||
91 | ## Which host architecture to use for foreign architectures. It turns out | |
92 | ## that it's best to use a Qemu with the same host bitness as the target | |
93 | ## architecture; otherwise it has to do a difficult job of converting | |
94 | ## arguments and results between kernel ABI flavours. | |
95 | 32BIT_QEMUHOST = $(or $(filter i386,$(NATIVE_ARCHS)),$(TOOLSARCH)) | |
96 | 64BIT_QEMUHOST = $(or $(filter amd64,$(NATIVE_ARCHS)),$(TOOLSARCH)) | |
97 | ||
98 | CONFIG_VARS += $(foreach a,$(FOREIGN_ARCHS), $a_QEMUHOST) | |
99 | armel_QEMUHOST = $(32BIT_QEMUHOST) | |
100 | armhf_QEMUHOST = $(32BIT_QEMUHOST) | |
101 | arm64_QEMUHOST = $(64BIT_QEMUHOST) | |
102 | i386_QEMUHOST = $(32BIT_QEMUHOST) | |
103 | amd64_QEMUHOST = $(64BIT_QEMUHOST) | |
104 | ||
105 | ## Qemu architecture names. These tell us which Qemu binary to use for a | |
106 | ## particular Debian architecture. | |
107 | CONFIG_VARS += $(foreach a,$(FOREIGN_ARCHS), $a_QEMUARCH) | |
108 | armel_QEMUARCH = arm | |
109 | armhf_QEMUARCH = arm | |
110 | arm64_QEMUARCH = aarch64 | |
111 | i386_QEMUARCH = i386 | |
112 | amd64_QEMUARCH = x86_64 | |
113 | ||
114 | ## Alias mapping for chroots. | |
115 | CONFIG_VARS += $(foreach d,$(DISTS), $d_ALIASES) | |
116 | stretch_ALIASES = oldstable | |
117 | buster_ALIASES = stable | |
118 | bullseye_ALIASE = testing | |
119 | sid_ALIASES = unstable | |
120 | ||
121 | ## Which host architecture to use for commonly used tools in foreign chroots. | |
122 | CONFIG_VARS += TOOLSARCH | |
123 | TOOLSARCH = $(MYARCH) | |
124 | ||
125 | ## A directory in which we can maintain private files and state. | |
126 | CONFIG_VARS += STATE | |
127 | STATE = state | |
128 | ||
129 | ## A directory which will be spliced into chroots as `/usr/local.schroot/'. | |
130 | ## This will be our primary point of contact with the chroot. | |
131 | CONFIG_VARS += LOCAL | |
132 | LOCAL = local.schroot | |
133 | ||
134 | ## How to run a command as a privileged user. | |
135 | ROOTLY = sudo | |
136 | ||
137 | ## Files to be copied into a chroot from the host. | |
138 | SCHROOT_COPYFILES = /etc/resolv.conf | |
139 | SCHROOT_NSSDATABASES = passwd shadow group gshadow | |
140 | ||
141 | ## Local configuration hook. | |
142 | -include local.mk | |
143 | ||
144 | ## All chroot names. | |
145 | CONFIG_VARS += ALL_CHROOTS | |
146 | ALL_CHROOTS = $(NATIVE_CHROOTS) $(FOREIGN_CHROOTS) | |
147 | ||
148 | ###-------------------------------------------------------------------------- | |
149 | ### Utilities. | |
150 | ||
151 | ## $(call chroot-dist,D-A) -> D | |
152 | ## $(call chroot-arch,D-A) -> A | |
153 | ## | |
154 | ## Parse chroot descriptions. | |
155 | chroot-dist = $(patsubst %/,%,$(dir $(subst -,/,$1))) | |
156 | chroot-arch = $(notdir $(subst -,/,$1)) | |
157 | ||
158 | ## $(call native-chroot-p,D-A) -> D | <empty> | |
159 | ## | |
160 | ## Answer whether D-A is a native chroot. | |
161 | native-chroot-p = $(filter $(call chroot-arch,$1), $(NATIVE_ARCHS)) | |
162 | ||
163 | ## $(call chroot-qemuhost,D-A) -> AA | |
164 | ## | |
165 | ## Answer the apporopriate Qemu host architecture for foreign chroot D-A. | |
166 | chroot-qemuhost = $($(call chroot-arch,$1)_QEMUHOST) | |
167 | ||
168 | ## $(call chroot-deps,PRE,D-A) -> PRE/DD-AA ... | <empty> | |
169 | ## | |
170 | ## Answer a list of additional dependencies for the chroot D-A: specifically, | |
171 | ## if D-A is foreign then include PRE/DD-AA entries for the tools | |
172 | ## architecture, and Qemu host architecture (if that's different). | |
173 | chroot-deps = $(if $(call native-chroot-p,$2),, \ | |
174 | $(addprefix $1/$(call chroot-dist,$2)-,\ | |
175 | $(sort $(call chroot-toolsarch,$2) \ | |
176 | $(call chroot-qemuhost,$2)))) | |
177 | ||
178 | ## Substituting placeholders in files. | |
179 | SUBSTITUTIONS := local=$(shell realpath $(LOCAL)) | |
180 | SUBSTITUTIONS += primary-dist=$(PRIMARY_DIST) | |
181 | subst-file = { \ | |
182 | echo "$1 GENERATED by distorted-chroot: do not edit"; \ | |
183 | substs=""; \ | |
184 | for v in $(SUBSTITUTIONS); do \ | |
185 | var=$${v%%=*} value=$${v\#*=}; \ | |
186 | substs="$$substs s\a@$$var@\a$$value\ag;"; \ | |
187 | done; \ | |
188 | sed "$$substs"; \ | |
189 | } | |
190 | ||
191 | ## Silent-rules machinery. | |
192 | V = 0 | |
193 | V_AT = $(V_AT_$V) | |
194 | V_AT_0 = @ | |
195 | v_print = $(call v_print_$V,$1,$2) | |
196 | v_print_0 = printf " %-8s %s\n" "$1" "$2"; | |
197 | v_tag = $(V_AT)$(call v_print,$1,$@) | |
198 | v_log = $(call v_log_$V,$1) | |
199 | v_log_ = $(call v_log_1,$1) | |
200 | v_log_0 = >$1.log 2>&1 | |
201 | v_log_1 = 2>&1 | tee $1.log | |
202 | CLEANFILES += *.log | |
203 | ||
204 | ###-------------------------------------------------------------------------- | |
205 | ### APT configuration. | |
206 | ||
207 | ## In a chroot, `/etc/apt/sources.list' links to | |
208 | ## `/usr/local.schroot/etc/apt/sources.$d' for the appropriate distribution. | |
209 | APT_SOURCES = $(foreach d,$(DISTS), $(LOCAL)/etc/apt/sources.$d) | |
210 | CLEANFILES += $(APT_SOURCES) | |
211 | all:: $(APT_SOURCES) | |
212 | ||
213 | $(foreach d,$(DISTS), $(STATE)/etc/apt/aptsrc.$d): $(STATE)/etc/apt/aptsrc.%: | |
214 | $(V_AT)mkdir -p $(dir $@) | |
215 | $(call v_tag,GEN){ \ | |
216 | echo "### -*-conf-*- GENERATED by distorted-chroot: do not edit"; \ | |
217 | echo "subscribe"; \ | |
218 | echo " debian : $*"; \ | |
219 | } >$@.new && mv $@.new $@ | |
220 | ||
221 | $(APT_SOURCES): $(LOCAL)/etc/apt/sources.%: \ | |
222 | $$(APTSRC) $$($$*_APTSRC) $$(STATE)/etc/apt/aptsrc.$$* | |
223 | $(V_AT)mkdir -p $(dir $@) | |
224 | $(call v_tag,GEN)bin/mkaptsrc \ | |
225 | $(APTSRC) $($*_APTSRC) $(STATE)/etc/apt/aptsrc.$* \ | |
226 | >$@.new && mv $@.new $@ | |
227 | ||
228 | ## In a chroot, a link `/etc/apt/apt.conf.d/FOO' is created for each file in | |
229 | ## `/usr/local.schroot/etc/apt/apt.conf.d/FOO'. | |
230 | APT_CONFIGS = $(addprefix $(LOCAL)/etc/apt/apt.conf.d/,$(APTCONF)) | |
231 | all:: $(APT_CONFIGS) | |
232 | $(APT_CONFIGS): $(LOCAL)/etc/apt/apt.conf.d/%: \ | |
233 | $$(or $$($$*_APTCONFSRC) $$(APTCONF_DIR)/$$*) | |
234 | $(V_AT)mkdir -p $(dir $@) | |
235 | $(call v_tag,COPY)cp $< $@.new && mv $@.new $@ | |
236 | ||
237 | ###-------------------------------------------------------------------------- | |
238 | ### `schroot' and `sbuild' configuration. | |
239 | ||
240 | all:: schroot-config | |
241 | schroot-config:: | |
242 | .PHONY: schroot-config | |
243 | ||
244 | %print-varlist = { \ | |
245 | echo "\#\#\# -*-sh-*- GENERATED by distorted-chroot: do not edit"; \ | |
246 | $(foreach v,$1, echo $v=\''$(subst ','\'\\\'\'',$($v))'\';) \ | |
247 | } #' | |
248 | schroot-config_HASH := \ | |
249 | $(shell $(call %print-varlist,$(CONFIG_VARS)) | \ | |
250 | sha256sum | cut -c1-32) | |
251 | schroot-config_FILE = $(STATE)/config.sh-$(schroot-config_HASH) | |
252 | $(schroot-config_FILE): | |
253 | $(V_AT)mkdir -p $(STATE) | |
254 | $(V_AT)rm -f $(STATE)/config.sh-* | |
255 | $(call v_tag,STAMP)$(call %print-varlist,$(CONFIG_VARS)) \ | |
256 | >$@.new && mv $@.new $@ | |
257 | ||
258 | schroot-config:: $(STATE)/config.sh | |
259 | $(STATE)/config.sh: $(schroot-config_FILE) | |
260 | $(call v_tag,SYMLINK)ln -sf $(notdir $<) $@ | |
261 | ||
262 | schroot-config:: $(STATE)/etc/schroot/sbuild.schroot | |
263 | $(STATE)/etc/schroot/sbuild.schroot: $(STATE)/config.sh bin/mkchrootconf | |
264 | $(V_AT)mkdir -p $(dir $@) | |
265 | $(call v_tag,GEN)bin/mkchrootconf >$@.new && mv $@.new $@ | |
266 | ||
267 | schroot-config:: $(STATE)/etc/schroot/sbuild.profile/copyfiles | |
268 | $(STATE)/etc/schroot/sbuild.profile/copyfiles: $(schroot-config_STAMP) | |
269 | $(V_AT)mkdir -p $(dir $@) | |
270 | $(call v_tag,GEN){ \ | |
271 | echo "### -*-conf-*- GENERATED by distorted-chroot: do not edit"; \ | |
272 | for i in $(SCHROOT_COPYFILES); do echo "$$i"; done; \ | |
273 | } >$@.new && mv $@.new $@ | |
274 | ||
275 | schroot-config:: $(STATE)/etc/schroot/sbuild.profile/nssdatabases | |
276 | $(STATE)/etc/schroot/sbuild.profile/nssdatabases: $(schroot-config_STAMP) | |
277 | $(V_AT)mkdir -p $(dir $@) | |
278 | $(call v_tag,GEN){ \ | |
279 | echo "### -*-conf-*- GENERATED by distorted-chroot: do not edit"; \ | |
280 | for i in $(SCHROOT_NSSDATABASES); do echo "$$i"; done; \ | |
281 | } >$@.new && mv $@.new $@ | |
282 | ||
283 | schroot-config:: $(STATE)/etc/schroot/sbuild.profile/fstab | |
284 | $(STATE)/etc/schroot/sbuild.profile/fstab: \ | |
285 | etc/sbuild.fstab.in $(schroot-config_STAMP) | |
286 | $(V_AT)mkdir -p $(dir $@) | |
287 | $(call v_tag,SUBST)$(call subst-file,### -*-conf-*-) \ | |
288 | <$< >$@.new && mv $@.new $@ | |
289 | ||
290 | schroot-config:: $(STATE)/etc/sbuild.conf | |
291 | $(STATE)/etc/sbuild.conf: etc/sbuild.conf.in $(schroot-config_STAMP) | |
292 | $(V_AT)mkdir -p $(dir $@) | |
293 | $(call v_tag,SUBST)$(call subst-file,### -*-perl-*-) \ | |
294 | <$< >$@.new && mv $@.new $@ | |
295 | ||
296 | ###-------------------------------------------------------------------------- | |
297 | ### Constructing chroots. | |
298 | ||
299 | BUILD_CHROOTS = $(addprefix chroot/,$(ALL_CHROOTS)) | |
300 | CHROOT_STAMPS = $(addprefix $(STATE)/stamp/chroot.,$(ALL_CHROOTS)) | |
301 | all:: setup-chroots | |
302 | setup-chroots: $(BUILD_CHROOTS) | |
303 | $(BUILD_CHROOTS): chroot/%: $(STATE)/stamp/chroot.% | |
304 | .PHONY: setup-chroots $(BUILD_CHROOTS) | |
305 | ||
306 | $(CHROOT_STAMPS): $(STATE)/stamp/chroot.%: $(STATE)/config.sh bin/mkbuildchroot | |
307 | $(call v_tag,CHROOT)bin/mkbuildchroot \ | |
308 | $(call chroot-dist,$*) $(call chroot-arch,$*) \ | |
309 | $(call v_log,setup-chroot.$*) | |
310 | ||
311 | ###-------------------------------------------------------------------------- | |
312 | ### Installing basic custom software. | |
313 | ||
314 | ||
315 | ||
316 | ###-------------------------------------------------------------------------- | |
317 | ### Other maintenance targets. | |
318 | ||
319 | show:; : $x | |
320 | ||
321 | clean:: | |
322 | rm -f $(CLEANFILES) | |
323 | rm -rf $(STATE) | |
324 | ||
325 | realclean:: clean | |
326 | rm -rf $(LOCAL) | |
327 | ||
328 | ###----- That's all, folks -------------------------------------------------- |