chiark / gitweb /
Very rough work-in-progress.
[distorted-chroot] / Makefile
CommitLineData
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
27all::
28clean::
29.PHONY: all clean
30.SECONDEXPANSION: #sorry
31
32###--------------------------------------------------------------------------
33### Configuration.
34
35CONFIG_VARS =
36
37## Volume group from which to allocate chroot volumes and snapshots.
38CONFIG_VARS += VG LVPREFIX
39VG = vg-$(shell hostname)
40LVPREFIX =
41
42## Logical volume size, as an LVM option.
43CONFIG_VARS += LVSZ
44LVSZ = -L8G
45
46## Debian mirror.
47CONFIG_VARS += DEBMIRROR
48DEBMIRROR = http://deb.debian.org/debian/
49
50## APT sources configurations. (Also, $($d_APTSRC) for each $d in $(DISTS).)
51CONFIG_VARS += APTSRC
52APTSRC = 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).
57CONFIG_VARS += APTCONF
58APTCONF_DIR = etc/apt-conf.d
59APTCONF = $(notdir $(wildcard $(APTCONF_DIR)/[0-9]*[!~]))
60
61## Proxy setting.
62CONFIG_VARS += PROXY
63PROXY := $(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.
69CONFIG_VARS += PRIMARY_DIST DISTS
70PRIMARY_DIST = stretch
71DISTS = $(PRIMARY_DIST) buster bullseye sid
72
73## Host's native architecture(s).
74CONFIG_VARS += MYARCH NATIVE_ARCHS
75MYARCH = $(shell dpkg --print-architecture)
76OTHERARCHS = $(shell dpkg --print-foreign-architectures)
77NATIVE_ARCHS = $(MYARCH) $(OTHERARCHS)
78
79## Foreign (emulated) architectures to support.
80CONFIG_VARS += FOREIGN_ARCHS
81FOREIGN_ARCHS =
82
83## Master lists of chroots to build and maintain.
84NATIVE_CHROOTS = $(foreach a,$(NATIVE_ARCHS), \
85 $(foreach d,$(or $($a_DISTS) $(DISTS)), \
86 $d-$a))
87FOREIGN_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.
9532BIT_QEMUHOST = $(or $(filter i386,$(NATIVE_ARCHS)),$(TOOLSARCH))
9664BIT_QEMUHOST = $(or $(filter amd64,$(NATIVE_ARCHS)),$(TOOLSARCH))
97
98CONFIG_VARS += $(foreach a,$(FOREIGN_ARCHS), $a_QEMUHOST)
99armel_QEMUHOST = $(32BIT_QEMUHOST)
100armhf_QEMUHOST = $(32BIT_QEMUHOST)
101arm64_QEMUHOST = $(64BIT_QEMUHOST)
102i386_QEMUHOST = $(32BIT_QEMUHOST)
103amd64_QEMUHOST = $(64BIT_QEMUHOST)
104
105## Qemu architecture names. These tell us which Qemu binary to use for a
106## particular Debian architecture.
107CONFIG_VARS += $(foreach a,$(FOREIGN_ARCHS), $a_QEMUARCH)
108armel_QEMUARCH = arm
109armhf_QEMUARCH = arm
110arm64_QEMUARCH = aarch64
111i386_QEMUARCH = i386
112amd64_QEMUARCH = x86_64
113
114## Alias mapping for chroots.
115CONFIG_VARS += $(foreach d,$(DISTS), $d_ALIASES)
116stretch_ALIASES = oldstable
117buster_ALIASES = stable
118bullseye_ALIASE = testing
119sid_ALIASES = unstable
120
121## Which host architecture to use for commonly used tools in foreign chroots.
122CONFIG_VARS += TOOLSARCH
123TOOLSARCH = $(MYARCH)
124
125## A directory in which we can maintain private files and state.
126CONFIG_VARS += STATE
127STATE = 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.
131CONFIG_VARS += LOCAL
132LOCAL = local.schroot
133
134## How to run a command as a privileged user.
135ROOTLY = sudo
136
137## Files to be copied into a chroot from the host.
138SCHROOT_COPYFILES = /etc/resolv.conf
139SCHROOT_NSSDATABASES = passwd shadow group gshadow
140
141## Local configuration hook.
142-include local.mk
143
144## All chroot names.
145CONFIG_VARS += ALL_CHROOTS
146ALL_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.
155chroot-dist = $(patsubst %/,%,$(dir $(subst -,/,$1)))
156chroot-arch = $(notdir $(subst -,/,$1))
157
158## $(call native-chroot-p,D-A) -> D | <empty>
159##
160## Answer whether D-A is a native chroot.
161native-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.
166chroot-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).
173chroot-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.
179SUBSTITUTIONS := local=$(shell realpath $(LOCAL))
180SUBSTITUTIONS += primary-dist=$(PRIMARY_DIST)
181subst-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.
192V = 0
193V_AT = $(V_AT_$V)
194V_AT_0 = @
195v_print = $(call v_print_$V,$1,$2)
196v_print_0 = printf " %-8s %s\n" "$1" "$2";
197v_tag = $(V_AT)$(call v_print,$1,$@)
198v_log = $(call v_log_$V,$1)
199v_log_ = $(call v_log_1,$1)
200v_log_0 = >$1.log 2>&1
201v_log_1 = 2>&1 | tee $1.log
202CLEANFILES += *.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.
209APT_SOURCES = $(foreach d,$(DISTS), $(LOCAL)/etc/apt/sources.$d)
210CLEANFILES += $(APT_SOURCES)
211all:: $(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'.
230APT_CONFIGS = $(addprefix $(LOCAL)/etc/apt/apt.conf.d/,$(APTCONF))
231all:: $(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
240all:: schroot-config
241schroot-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} #'
248schroot-config_HASH := \
249 $(shell $(call %print-varlist,$(CONFIG_VARS)) | \
250 sha256sum | cut -c1-32)
251schroot-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
258schroot-config:: $(STATE)/config.sh
259$(STATE)/config.sh: $(schroot-config_FILE)
260 $(call v_tag,SYMLINK)ln -sf $(notdir $<) $@
261
262schroot-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
267schroot-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
275schroot-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
283schroot-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
290schroot-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
299BUILD_CHROOTS = $(addprefix chroot/,$(ALL_CHROOTS))
300CHROOT_STAMPS = $(addprefix $(STATE)/stamp/chroot.,$(ALL_CHROOTS))
301all:: setup-chroots
302setup-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
319show:; : $x
320
321clean::
322 rm -f $(CLEANFILES)
323 rm -rf $(STATE)
324
325realclean:: clean
326 rm -rf $(LOCAL)
327
328###----- That's all, folks --------------------------------------------------