chiark / gitweb /
Very rough work-in-progress.
[distorted-chroot] / Makefile
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 --------------------------------------------------