From: Mark Wooding Date: Mon, 9 Sep 2019 12:51:56 +0000 (+0100) Subject: More work in progress. X-Git-Url: https://git.distorted.org.uk/~mdw/distorted-chroot/commitdiff_plain/3e5b03e2c0f0a3ddf3a56136f475e99d44432f18 More work in progress. I think it can make native chroots now. We're most of the way towards foreign chroots, but the work's not finished yet. --- diff --git a/.gitignore b/.gitignore index 2706c7e..d9f3627 100644 --- a/.gitignore +++ b/.gitignore @@ -3,4 +3,6 @@ /etc/aptsrc.local.conf /local.mk /local.schroot/ +/log/ +/mnt/ /state/ diff --git a/Makefile b/Makefile index dd96989..08906ba 100644 --- a/Makefile +++ b/Makefile @@ -26,7 +26,8 @@ all:: clean:: -.PHONY: all clean +check:: +.PHONY: all clean check .SECONDEXPANSION: #sorry ###-------------------------------------------------------------------------- @@ -34,14 +35,22 @@ clean:: CONFIG_VARS = +## Level of pickiness to aspire to. +NOTIFY_FATAL = 1 + +## Path to this working tree. +CONFIG_VARS += HERE +HERE = $(abspath .) + ## Volume group from which to allocate chroot volumes and snapshots. CONFIG_VARS += VG LVPREFIX VG = vg-$(shell hostname) LVPREFIX = ## Logical volume size, as an LVM option. -CONFIG_VARS += LVSZ +CONFIG_VARS += LVSZ SNAPOPT LVSZ = -L8G +SNAPOPT = -L8G ## Debian mirror. CONFIG_VARS += DEBMIRROR @@ -88,6 +97,19 @@ FOREIGN_CHROOTS = $(foreach a,$(FOREIGN_ARCHS), \ $(foreach d,$(or $($a_DISTS) $(DISTS)), \ $d-$a)) +## Extra packages to be installed in chroots. +CONFIG_VARS += BASE_PACKAGES NATIVE_BASE_PACKAGES FOREIGN_BASE_PACKAGES +BASE_PACKAGES = ccache +BASE_PACKAGES += eatmydata fakeroot +BASE_PACKAGES += locales tzdata +BASE_PACKAGES += libfile-fcntllock-perl +NATIVE_BASE_PACKAGES = build-essential +FOREIGN_BASE_PACKAGES = + +## Local packages to be compiled and installed in chroots. Archives can be +## found in `pkg/'. +LOCALPKGS = mLib checkpath + ## Which host architecture to use for foreign architectures. It turns out ## that it's best to use a Qemu with the same host bitness as the target ## architecture; otherwise it has to do a difficult job of converting @@ -142,12 +164,51 @@ SCHROOT_NSSDATABASES = passwd shadow group gshadow -include local.mk ## All chroot names. -CONFIG_VARS += ALL_CHROOTS +CONFIG_VARS += ALL_ARCHS ALL_CHROOTS +ALL_ARCHS = $(NATIVE_ARCHS) $(FOREIGN_ARCHS) ALL_CHROOTS = $(NATIVE_CHROOTS) $(FOREIGN_CHROOTS) ###-------------------------------------------------------------------------- ### Utilities. +## Hack to force rebuilding. +_force: +.PHONY: _force + +## Hack to not delimit function arguments. (Ugh!) +comma = , + +## Silent-rules machinery. +V = 0 +V_AT = $(V_AT_$V) +V_AT_0 = @ +v_print = $(call v_print_$V,$1,$2) +v_print_0 = printf " %-8s %s\n" "$1" $(call squote,$2); +v_tag = $(V_AT)$(call v_print,$1,$@) +v_log = $(call v_log_$V,$1,$2) +v_log_ = $(call v_log_1,$1,$2) +v_log_0 = $2 >log/$1.log 2>&1 +v_log_1 = $(call catchrc,$(call throwrc,$2) 2>&1 | tee log/$1.log) +v_echo = $(call v_echo_$V,$1) +v_echo_0 = : +v_echo_1 = printf "%s\n" $1 +CLEANFILES += log/*.log + +## Oh, shut up. +SILENCE_LVM = \ + LVM_SUPPRESS_FD_WARNINGS=1; export LVM_SUPPRESS_FD_WARNINGS + +## $(call catchrc,...$(call throwrc,CMD)...) +## +## Catch the exit status of some subpart of a complicated shell rune. +catchrc = (exec 3>&1; exit $$({ $1; } 4>&1 >&3 3>&-)) +throwrc = { $1; echo $$? >&4; } + +## $(call squote,TXT) +## +## Single-quote TXT. +squote = '$(subst ','\\'',$1)' + ## $(call chroot-dist,D-A) -> D ## $(call chroot-arch,D-A) -> A ## @@ -155,24 +216,42 @@ ALL_CHROOTS = $(NATIVE_CHROOTS) $(FOREIGN_CHROOTS) chroot-dist = $(patsubst %/,%,$(dir $(subst -,/,$1))) chroot-arch = $(notdir $(subst -,/,$1)) +## $(call package-dir-name,P-V) -> P +## $(call package-dir-version,P-V) -> V +## +## Parse (source) package directory names. +package-dir-name = $(sort $(foreach p,$(LOCALPKGS),$(if $(filter $p-$($p_VERSION),$1),$p))) +package-dir-version = $($(call package-dir-name,$1)_VERSION) + +## $(call package-dir,P-V.A) -> P-V +## $(call package-name,P-V.A) -> P +## $(call package-version,P-V.A) -> V +## $(call package-arch,P-V.A) -> A +## +## Parse package stamp names. +package-dir = $(basename $1) +package-name = $(call package-dir-name,$(call package-dir,$1)) +package-version = $(call package-dir-version,$(call package-dir,$1)) +package-arch = $(patsubst .%,%,$(suffix $1)) + ## $(call native-chroot-p,D-A) -> D | ## ## Answer whether D-A is a native chroot. -native-chroot-p = $(filter $(call chroot-arch,$1), $(NATIVE_ARCHS)) +native-chroot-p = $(filter $(call chroot-arch,$1),$(NATIVE_ARCHS)) ## $(call chroot-qemuhost,D-A) -> AA ## ## Answer the apporopriate Qemu host architecture for foreign chroot D-A. chroot-qemuhost = $($(call chroot-arch,$1)_QEMUHOST) -## $(call chroot-deps,PRE,D-A) -> PRE/DD-AA ... | +## $(call chroot-deps,PRE,D-A) -> PREDD-AA ... | ## ## Answer a list of additional dependencies for the chroot D-A: specifically, ## if D-A is foreign then include PRE/DD-AA entries for the tools ## architecture, and Qemu host architecture (if that's different). chroot-deps = $(if $(call native-chroot-p,$2),, \ - $(addprefix $1/$(call chroot-dist,$2)-,\ - $(sort $(call chroot-toolsarch,$2) \ + $(addprefix $1$(call chroot-dist,$2)-,\ + $(sort $(TOOLSARCH) \ $(call chroot-qemuhost,$2)))) ## Substituting placeholders in files. @@ -188,18 +267,73 @@ subst-file = { \ sed "$$substs"; \ } -## Silent-rules machinery. -V = 0 -V_AT = $(V_AT_$V) -V_AT_0 = @ -v_print = $(call v_print_$V,$1,$2) -v_print_0 = printf " %-8s %s\n" "$1" "$2"; -v_tag = $(V_AT)$(call v_print,$1,$@) -v_log = $(call v_log_$V,$1) -v_log_ = $(call v_log_1,$1) -v_log_0 = >$1.log 2>&1 -v_log_1 = 2>&1 | tee $1.log -CLEANFILES += *.log +### $(call symlink-ok-p,LINK,DEST) +### +### Expand to `t' if LINK is a symbolic link to DEST, and empty otherwise. +symlink-ok-p = $(shell \ + case $$(readlink 2>/dev/null $(patsubst %/,%,$1)) in ($2) echo t ;; esac) + +### $(call general-notify,SEV,COLOUR,PREFIX,MSG) +### +### Report a message, highlighted in the right way, and maybe fail +general-notify = { \ + echo "$$(tput bold; tput setaf $2)$3 "$4"$$(tput sgr0; tput op)"; \ + if [ "$1" -le "$(NOTIFY_FATAL)" ]; then exit 2; fi; \ +} + +### $(call report/SEV,MSG) +### +### Report a notification of a particular severity. +notify/INFO = $(call general-notify,3,6,---,$1) +notify/WARN = $(call general-notify,2,5,???,$1) +notify/ERR = $(call general-notify,1,1,!!!,$1) + +## $(call check,SEV,MSG,UNLESS) +## +## If UNLESS completes successfully, all is OK; otherwise print MSG to stderr +## and fail. +check = @{ \ + $(call v_echo,'check: '$(call squote,$3)''); \ + if ! { $3; }; then $(call notify/$1,$2); fi; \ +} + +## $(call check-executable,SEV,PATH) +## +## Verify that PATH is an executable program. +check-executable = $(call check,$1,"\`$2' is not an executable", \ + [ -x "$2" ]) + +## $(call check-mountpoint,SEV,DIR) +## +## Verify that DIR is a mountpoint. +check-mountpoint = $(call check,$1,"\`$2' is not a mount point", \ + mountpoint -q "$2") + +## $(call check-symlink,SEV,LINK,DEST) +## +## Verify that LINK is a symbolic link pointing to DEST. +check-symlink = $(call check,$1,"\`$2' is not a link to \`$3'", \ + [ -L "$2" ] && [ "$$(readlink "$2")" = "$3" ]) + +###-------------------------------------------------------------------------- +### Scripts. + +SCRIPTS += mkbuildchroot +SCRIPTS += mkchrootconf +SCRIPTS += install-cross-tools update-cross-tools + +SUBST_SCRIPTS = $(addprefix $(STATE)/bin/,$(SCRIPTS)) +all:: $(SUBST_SCRIPTS) +$(SUBST_SCRIPTS): $(STATE)/bin/%: bin/% $(STATE)/config.sh + $(V_AT)mkdir -p $(dir $@) + $(call v_tag,SUBST){ \ + sed \ + -e '2i### GENERATED by distorted-chroot: do not edit' \ + -e '/@@@config@@@/ {' \ + -e 'r $(STATE)/config.sh' \ + -e 'd'\ + -e '}' $<; \ + } >$@.new && chmod +x $@.new && mv $@.new $@ ###-------------------------------------------------------------------------- ### APT configuration. @@ -233,6 +367,29 @@ $(APT_CONFIGS): $(LOCAL)/etc/apt/apt.conf.d/%: \ $$(or $$($$*_APTCONFSRC) $$(APTCONF_DIR)/$$*) $(V_AT)mkdir -p $(dir $@) $(call v_tag,COPY)cp $< $@.new && mv $@.new $@ +clean::; rm -f $(APT_CONFIGS) + +###-------------------------------------------------------------------------- +### Build hacks. + +check::; $(call check-executable,ERR,/usr/bin/eatmydata) + +EATMYDATA_HACKS += apt-get aptitude dpkg +SYMLINK_EATMYDATA_HACKS = $(addprefix $(LOCAL)/hacks/,$(EATMYDATA_HACKS)) +all:: $(SYMLINK_EATMYDATA_HACKS) +$(SYMLINK_EATMYDATA_HACKS): $(LOCAL)/hacks/%: \ + $$(if $$(call symlink-ok-p,$$@,/usr/bin/eatmydata),,_force) + $(V_AT)mkdir -p $(dir $@) + $(call v_tag,SYMLINK)ln -sf /usr/bin/eatmydata $@.new && mv $@.new $@ +clean::; rm -f $(SYMLINK_EATMYDATA_HACKS) + +SCRIPT_HACKS += buildwrap +COPY_SCRIPT_HACKS = $(addprefix $(LOCAL)/hacks/,$(SCRIPT_HACKS)) +all:: $(COPY_SCRIPT_HACKS) +$(COPY_SCRIPT_HACKS): $(LOCAL)/hacks/%: bin/% + $(V_AT)mkdir -p $(dir $@) + $(call v_tag,COPY)cp $< $@.new && mv $@.new $@ +clean::; rm -f $(COPY_SCRIPT_HACKS) ###-------------------------------------------------------------------------- ### `schroot' and `sbuild' configuration. @@ -241,6 +398,10 @@ all:: schroot-config schroot-config:: .PHONY: schroot-config +check::; $(call check-mountpoint,WARN,/var/lib/sbuild/build) +check::; $(call check-symlink,WARN,/build,/var/lib/sbuild/build) +check::; $(call check-symlink,ERR,/schroot,/run/schroot/mount) + %print-varlist = { \ echo "\#\#\# -*-sh-*- GENERATED by distorted-chroot: do not edit"; \ $(foreach v,$1, echo $v=\''$(subst ','\'\\\'\'',$($v))'\';) \ @@ -260,9 +421,11 @@ $(STATE)/config.sh: $(schroot-config_FILE) $(call v_tag,SYMLINK)ln -sf $(notdir $<) $@ schroot-config:: $(STATE)/etc/schroot/sbuild.schroot -$(STATE)/etc/schroot/sbuild.schroot: $(STATE)/config.sh bin/mkchrootconf +$(STATE)/etc/schroot/sbuild.schroot: $(STATE)/bin/mkchrootconf $(V_AT)mkdir -p $(dir $@) - $(call v_tag,GEN)bin/mkchrootconf >$@.new && mv $@.new $@ + $(call v_tag,GEN)$(STATE)/bin/mkchrootconf >$@.new && \ + $(ROOTLY) chown root:root $@.new && mv $@.new $@ +check::; $(call check-symlink,WARN,/etc/schroot/chroot.d/sbuild,$(HERE)/$(STATE)/etc/schroot/sbuild.schroot) schroot-config:: $(STATE)/etc/schroot/sbuild.profile/copyfiles $(STATE)/etc/schroot/sbuild.profile/copyfiles: $(schroot-config_STAMP) @@ -287,31 +450,199 @@ $(STATE)/etc/schroot/sbuild.profile/fstab: \ $(call v_tag,SUBST)$(call subst-file,### -*-conf-*-) \ <$< >$@.new && mv $@.new $@ +check::; $(call check-symlink,WARN,/etc/schroot/sbuild,$(HERE)/$(STATE)/etc/schroot/sbuild.profile) + schroot-config:: $(STATE)/etc/sbuild.conf $(STATE)/etc/sbuild.conf: etc/sbuild.conf.in $(schroot-config_STAMP) $(V_AT)mkdir -p $(dir $@) $(call v_tag,SUBST)$(call subst-file,### -*-perl-*-) \ <$< >$@.new && mv $@.new $@ +SCHROOT_SCRIPTS += 11private +SCHROOT_SCRIPTS += 15binfmt +SCHROOT_SCRIPTS += 51chrootenv +COPY_SCHROOT_SCRIPTS = $(addprefix $(STATE)/etc/schroot/setup.d/,$(SCHROOT_SCRIPTS)) +schroot-config:: $(COPY_SCHROOT_SCRIPTS) +$(COPY_SCHROOT_SCRIPTS): \ + $(STATE)/etc/schroot/setup.d/%: etc/schroot-scripts/% + $(V_AT)mkdir -p $(dir $@) + $(call v_tag,COPY)cp $< $@.new && mv $@.new $@ + +CHECK_SCHROOT_SCRIPTS = $(addprefix check-script/,$(SCHROOT_SCRIPTS)) +check:: $(CHECK_SCHROOT_SCRIPTS) +$(CHECK_SCHROOT_SCRIPTS): check-script/%: + $(call check-symlink,WARN,/etc/schroot/setup.d/$*,$(HERE)/$(STATE)/etc/schroot/setup.d/$*) +.PHONY: $(addprefix check-script/,$(SCHROOT_SCRIPTS)) + +###-------------------------------------------------------------------------- +### `/usr/local/' structure. + +LOCAL_COMMON_DIRS = share/ src/ +all:: $(foreach d,$(LOCAL_COMMON_DIRS),$(LOCAL)/$d) +$(foreach d,$(LOCAL_COMMON_DIRS),$(LOCAL)/$d): + $(V_AT)mkdir -p $(dir $(patsubst %/,%,$@)) + $(call v_tag,MKDIR)mkdir $@ + +LOCAL_ARCH_DIRS = bin/ etc/ games/ include/ lib/ libexec/ sbin/ +LOCAL_ARCH_LINKS = man +man_LINKDEST = share/man +all:: $(foreach a,$(ALL_ARCHS),\ + $(LOCAL)/$a/ \ + $(foreach d,$(LOCAL_ARCH_DIRS),$(LOCAL)/$a/$d) \ + $(foreach d,$(LOCAL_ARCH_LINKS),$(LOCAL)/$a/$d) \ + $(foreach d,$(LOCAL_COMMON_DIRS),$(LOCAL)/$a/$d)) + +$(foreach a,$(ALL_ARCHS),$(LOCAL)/$a/): + $(call v_tag,MKDIR)mkdir $@ +$(foreach a,$(ALL_ARCHS),\ + $(foreach d,$(LOCAL_ARCH_DIRS),$(LOCAL)/$a/$d)): + $(V_AT)mkdir -p $(dir $(patsubst %/,%,$@)) + $(call v_tag,MKDIR)mkdir $@ +$(foreach a,$(ALL_ARCHS),\ + $(foreach d,$(LOCAL_ARCH_LINKS),$(LOCAL)/$a/$d)): \ + $$(if $$(call symlink-ok-p,$$@,$$($$(notdir $$@)_LINKDEST)),,_force) + $(V_AT)mkdir -p $(notdir $@) + $(call v_tag,SYMLINK)ln -sf $($(notdir $@)_LINKDEST) $@ +$(foreach a,$(ALL_ARCHS),\ + $(foreach d,$(LOCAL_COMMON_DIRS),$(LOCAL)/$a/$d)): \ + $$(if $$(call symlink-ok-p,$$@,../$$(notdir $$(patsubst %/,%,$$@))),,_force) + $(V_AT)mkdir -p $(dir $(patsubst %/,%,$@)) + $(call v_tag,SYMLINK)ln -sf ../$(notdir $(patsubst %/,%,$@)) $(patsubst %/,%,$@) + ###-------------------------------------------------------------------------- ### Constructing chroots. +chroot-stamp = $(addprefix $(STATE)/stamp/chroot.,$1) BUILD_CHROOTS = $(addprefix chroot/,$(ALL_CHROOTS)) -CHROOT_STAMPS = $(addprefix $(STATE)/stamp/chroot.,$(ALL_CHROOTS)) -all:: setup-chroots +CHROOT_STAMPS = $(call chroot-stamp,$(ALL_CHROOTS)) setup-chroots: $(BUILD_CHROOTS) $(BUILD_CHROOTS): chroot/%: $(STATE)/stamp/chroot.% .PHONY: setup-chroots $(BUILD_CHROOTS) -$(CHROOT_STAMPS): $(STATE)/stamp/chroot.%: $(STATE)/config.sh bin/mkbuildchroot - $(call v_tag,CHROOT)bin/mkbuildchroot \ - $(call chroot-dist,$*) $(call chroot-arch,$*) \ - $(call v_log,setup-chroot.$*) +$(CHROOT_STAMPS): $(STATE)/stamp/chroot.%: \ + $$(call chroot-deps,$(STATE)/stamp/cross-tools.,$$*) + $(V_AT)mkdir -p $(dir $@) log/ + $(MAKE) \ + $(STATE)/bin/mkbuildchroot $(STATE)/bin/install-cross-tools \ + $(STATE)/etc/schroot/sbuild.schroot + $(call v_tag,CHROOT)$(call v_log,setup-chroot.$*, \ + $(SILENCE_LVM); \ + $(ROOTLY) $(STATE)/bin/mkbuildchroot \ + $(call chroot-dist,$*) $(call chroot-arch,$*)) + $(V_AT)touch $@ + +UPDATE_CHROOTS = $(addprefix update/,$(ALL_CHROOTS)) +update-chroots: $(UPDATE_CHROOTS) +$(UPDATE_CHROOTS): update/%: $(STATE)/stamp/chroot.% + $(V_AT)mkdir -p log/ + $(MAKE) $(STATE)/bin/install-cross-tools + $(call v_tag,UPDATE)$(call v_log,update-chroot.$*, { \ + schroot -uroot -csource:$(LVPREFIX)$* -- \ + apt-get update && \ + schroot -uroot -csource:$(LVPREFIX)$* -- \ + apt-get -y dist-upgrade && \ + schroot -uroot -csource:$(LVPREFIX)$* -- \ + apt-get -y autoremove && \ + schroot -uroot -csource:$(LVPREFIX)$* -- \ + apt-get -y clean && \ + $(if $(filter $*,$(FOREIGN_CHROOTS)), \ + $(ROOTLY) $(STATE)/bin/install-cross-tools \ + $(call chroot-dist,$*) \ + $(call chroot-arch,$*), \ + :); \ + }) +.PHONY: update-chroots $(UPDATE_CHROOTS) + +cross-tools-stamp = $(addprefix $(STATE)/stamp/cross-tools.,$1) +CROSS_TOOLS = $(addprefix cross-tools/,$(NATIVE_CHROOTS)) +UPDATE_CROSS_TOOLS = $(addprefix update-cross-tools/,$(NATIVE_CHROOTS)) +cross-tools: $(CROSS_TOOLS) +update-cross-tools: $(UPDATE_CROSS_TOOLS) +$(CROSS_TOOLS): cross-tools/%: $(STATE)/stamp/cross-tools.% +define updcross + $(V_AT)mkdir -p log/ + $(MAKE) $(STATE)/bin/update-cross-tools + $(call v_tag,UPDCROSS)$(call v_log,update-cross-tools.$*, \ + $(STATE)/bin/update-cross-tools \ + $(call chroot-dist,$*) \ + $(call chroot-arch,$*)) + $(V_AT)touch $(call cross-tools-stamp,$*) +endef +$(call cross-tools-stamp,$(NATIVE_CHROOTS)): $(STATE)/stamp/cross-tools.%: \ + $$(call chroot-stamp,$$*) + $(V_AT)mkdir -p $(dir $@) + $(updcross) +$(UPDATE_CROSS_TOOLS): update-cross-tools/%: \ + $$(call chroot-stamp,$$*) _force + $(updcross) +.PHONY: cross-tools update-cross-tools $(CROSS_TOOLS) $(UPDATE_CROSS_TOOLS) ###-------------------------------------------------------------------------- ### Installing basic custom software. - +$(foreach p,$(LOCALPKGS), $(eval $p_VERSION := $(shell \ + set -- pkg/$p-[0-9]*.tar.gz; \ + case $$#,$$1 in \ + (1,*\**) echo "NOT-FOUND"; exit 2 ;; \ + (1,*) v=$${1#pkg/$p-}; v=$${v%.tar.gz}; echo "$$v" ;; \ + (*) echo "AMBIGUOUS"; exit 2 ;; \ + esac))) + +pkg-stamp = \ + $(foreach p,$1,$(STATE)/stamp/package.$p-$($p_VERSION).$2) +unpack-pkg-stamp = \ + $(foreach p,$1,$(STATE)/stamp/unpack.$p-$($p_VERSION)) +PACKAGE_STAMPS = \ + $(foreach a,$(ALL_ARCHS),$(call pkg-stamp,$(LOCALPKGS),$a)) +INSTALL_PACKAGES = $(addprefix install/,$(LOCALPKGS)) +install-packages: $(INSTALL_PACKAGES) +$(INSTALL_PACKAGES): install/%: \ + $$(foreach a,$$(ALL_ARCHS),$$(call pkg-stamp,$$*,$$a)) + +$(foreach p,$(LOCALPKGS),$(call unpack-pkg-stamp,$p)): \ + $(STATE)/stamp/unpack.%: pkg/%.tar.gz + $(V_AT)mkdir -p $(dir $@) $(LOCAL)/src/ + $(call v_tag,UNPACK){ \ + set -e; \ + p=$(call package-dir-name,$*); \ + v=$(call package-dir-version,$*); \ + cd $(LOCAL)/src/; \ + $(ROOTLY) rm -rf $$p-*; \ + mkdir $$p-$$v.unpack; \ + (cd $$p-$$v.unpack && tar xf $(HERE)/$<); \ + mv $$p-$$v.unpack/$$p-$$v $$p-$$v; \ + rmdir $$p-$$v.unpack/; \ + cd $(HERE); \ + touch $@; \ + } + +$(PACKAGE_STAMPS): $(STATE)/stamp/package.%: \ + $$(call unpack-pkg-stamp,$$(call package-name,$$*)) \ + $$(call chroot-stamp,$$(PRIMARY_DIST)-$$(call package-arch,$$*)) + $(V_AT)mkdir -p $(dir $@) log/ + $(call v_tag,BUILD)$(call v_log,install-package.$*, { \ + $(SILENCE_LVM); \ + schroot -uroot -c$(LVPREFIX)$(PRIMARY_DIST)-$(call package-arch,$*) -- \ + sh -exc ' \ + mount -oremount$(comma)rw /usr/local.schroot; \ + eatmydata apt-get update; \ + eatmydata apt-get -y install pkg-config; \ + p=$(call package-name,$*); \ + v=$(call package-version,$*); \ + a=$(call package-arch,$*); \ + cd /usr/local/src/$$p-$$v/; \ + rm -rf build.$$a/; \ + mkdir build.$$a/; \ + cd build.$$a/; \ + ../configure PKG_CONFIG_PATH=/usr/local/lib/pkgconfig.hidden; \ + make -j4; \ + make install; \ + mkdir -p /usr/local/lib/pkgconfig.hidden; \ + mv /usr/local/lib/pkgconfig/*.pc /usr/local/lib/pkgconfig.hidden || :' && \ + schroot -uroot -csource:$(LVPREFIX)$(PRIMARY_DIST)-$(call package-arch,$*) -- \ + ldconfig; \ + }) + $(V_AT)touch $@ ###-------------------------------------------------------------------------- ### Other maintenance targets. diff --git a/bin/buildwrap b/bin/buildwrap new file mode 100755 index 0000000..e367b1b --- /dev/null +++ b/bin/buildwrap @@ -0,0 +1,60 @@ +#! /bin/sh -e +### +### Wrapper around `sbuild' builds +### +### (c) 2018 Mark Wooding +### + +###----- Licensing notice --------------------------------------------------- +### +### This file is part of the distorted.org.uk chroot maintenance tools. +### +### distorted-chroot is free software: you can redistribute it and/or +### modify it under the terms of the GNU General Public License as +### published by the Free Software Foundation; either version 2 of the +### License, or (at your option) any later version. +### +### distorted-chroot is distributed in the hope that it will be useful, +### but WITHOUT ANY WARRANTY; without even the implied warranty of +### MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +### General Public License for more details. +### +### You should have received a copy of the GNU General Public License +### along with distorted-chroot. If not, write to the Free Software +### Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, +### USA. + +## Set up compiler caching. This makes a big difference to build times. +PATH=/usr/lib/ccache:$PATH; export PATH +CCACHE_DIR=/build/.ccache; export CCACHE_DIR +unset CCACHE_HARDLINK +CCACHE_COMPRESS=t; export CCACHE_COMPRESS +CCACHE_UMASK=002; export CCACHE_UMASK + +## Hack the build options. `sbuild' tries to turn off testing for +## cross-builds, which is exactly wrong. Turn them back on unless I really +## want them off. +old=$DEB_BUILD_OPTIONS new= force_nocheck=nil +for o in $old; do + case $o in x-mdw-nocheck) force_nocheck=t ;; esac +done +for o in $old; do + include=t + case $o in + x-mdw-nocheck) include=nil ;; + nocheck) include=$force_nocheck ;; + esac + case $include in + t) new=${new:+$new }$o ;; + esac +done +DEB_BUILD_OPTIONS=$new; export DEB_BUILD_OPTIONS + +## Preset the library search path to find the tools version of `fakeroot'. +for i in /usr/lib/*/libfakeroot; do + LD_LIBRARY_PATH=${LD_LIBRARY_PATH+$LD_LIBRARY_PATH:}$i +done +export LD_LIBRARY_PATH + +## We're ready to go. +exec "$@" diff --git a/bin/install-cross-tools b/bin/install-cross-tools new file mode 100755 index 0000000..7673229 --- /dev/null +++ b/bin/install-cross-tools @@ -0,0 +1,202 @@ +#! /bin/sh -e +### +### Replace common tools in foreign chroots with native versions +### +### (c) 2018 Mark Wooding +### + +###----- Licensing notice --------------------------------------------------- +### +### This file is part of the distorted.org.uk chroot maintenance tools. +### +### distorted-chroot is free software: you can redistribute it and/or +### modify it under the terms of the GNU General Public License as +### published by the Free Software Foundation; either version 2 of the +### License, or (at your option) any later version. +### +### distorted-chroot is distributed in the hope that it will be useful, +### but WITHOUT ANY WARRANTY; without even the implied warranty of +### MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +### General Public License for more details. +### +### You should have received a copy of the GNU General Public License +### along with distorted-chroot. If not, write to the Free Software +### Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, +### USA. + +. state/config.sh # @@@config@@@ + +## Parse the command-line. +badp=nil +case $# in 2) ;; *) badp=t ;; esac +case $badp in t) echo >&2 "usage: $0 DIST ARCH"; exit 2 ;; esac +d=$1 a=$2 + +## Figure out of all the architecture names. +mymulti=$(dpkg-architecture -a$TOOLSARCH -qDEB_HOST_MULTIARCH) +gnuarch=$(dpkg-architecture -A$a -qDEB_TARGET_GNU_TYPE) +qarch=nil qhost=nil +for fa in $FOREIGN_ARCHS; do + case $fa in + "$a") + eval qarch=\$${a}_QEMUARCH qhost=\$${a}_QEMUHOST + break ;; + esac +done +case $qarch,$qhost in + nil,* | *,nil) echo >&2 "$0: not a foreign architecture"; exit 2 ;; +esac + +## Make sure we have the tools we need. +crossdir=/usr/local.schroot/cross/$d-$TOOLSARCH +my_crossdir=$LOCAL/${crossdir#/usr/local.schroot/} +qemudir=/usr/local.schroot/cross/$d-$qhost/QEMU +my_qemudir=$LOCAL/${qemudir#/usr/local.schroot/} +if ! [ -d $my_crossdir ]; then + echo 2>&1 "$0: no tree for \`$d-$TOOLSARCH'"; exit 2 +fi +if ! [ -d $my_qemudir ]; then + echo 2>&1 "$0: no tree for \`$d-$qhost'"; exit 2 +fi + +## Open a session to the target chroot. +sess=$(schroot -bcsource:$LVPREFIX$d-$a) +root=/schroot/$sess/fs + +## Abuse `/mnt/' as a temporary staging area. This saves us from clobbering +## the chroot with weird directories. +schroot -uroot -rc$sess -- sh -ec ' + if ! mountpoint -q /mnt; then + mount -ttmpfs -omode=700,uid=0,gid=0 private /mnt + fi' + +## Work through all of the tools we're interested in, to decide what we need +## to do with it. Make lists: +## +## * `DIVERT.want' lists all of the filenames which need dpkg diversions to +## prevent foreign versions of the tools from clobbering our native +## versions. +## +## * `LINK'.want' lists all of the paths which need symbolic links into the +## cross-tools trees, together with the link destinations. +{ echo $qemudir/qemu-$qarch-static + echo $crossdir/lib/$mymulti + echo $crossdir/usr/lib/$mymulti + echo $crossdir/usr/lib/gcc-cross + find $my_crossdir $my_crossdir/TOOLCHAIN/$gnuarch \ + \( \( -path "*/QEMU" -o -path "*/TOOLCHAIN" -o \ + -path "*/lib/$mymulti" -o \ + -path "*/lib/gcc-cross" \) -prune \) -o \ + \( ! -type d -print \) +} | sed "s^$LOCAL//usr/local.schroot/" | while read t; do + case $t in + $qemudir/*) + s=/usr/bin/${t#$qemudir/} ;; + $crossdir/TOOLCHAIN/$gnuarch/*) + s=/usr/bin/${t#$crossdir/TOOLCHAIN/$gnuarch/} ;; + *) + s=${t#$crossdir} ;; + esac + if [ -L $t ]; then t=$(readlink $t); fi + if [ -d $t ]; then act=LINK; else act=DIVERT; fi + echo $act $s $t +done >$root/mnt/ALL.want +sed -n '/^DIVERT \(.*\) .*$/s//\1/p' $root/mnt/ALL.want | \ + sort >$root/mnt/DIVERT.want +sed -n '/^\(DIVERT\|LINK\) /s///p' $root/mnt/ALL.want | \ + sort >$root/mnt/LINK.want + +## Make a list, `DIVERT.have', of paths which already have diversions, and a +## list `LINK.have' of symbolic links into the cross-tools trees. The +## layouts of these files match the `.want' files we just made. +schroot -uroot -rc$sess -- sh -ec ' + dpkg-divert --list | + sed -n "/^diversion of \(.*\) to .* by install-cross-tools\$/s//\1/p" | \ + sort >/mnt/DIVERT.have + { find / -xdev -lname "/usr/local.schroot/cross/*" -printf "%p %l\n" + while read s _; do + if ! [ -L "$s" ]; then continue; fi + t=$(readlink $s) + case $t in /usr/local.schroot/cross/*) continue ;; esac + echo "$s $t" + done /mnt/LINK.have' + +## Add diversions for the paths which need one, but don't have one. There's +## a hack here because the `--no-rename' option was required in the same +## version in which is was introduced, so there's no single incantation that +## will work across the boundary. +schroot -uroot -rc$sess -- sh -ec ' + a=$1 + + if dpkg-divert >/dev/null 2>&1 --no-rename --help + then no_rename=--no-rename + else no_rename= + fi + + comm -13 /mnt/DIVERT.have /mnt/DIVERT.want | while read i; do + dpkg-divert --package "install-cross-tools" $no_rename \ + --divert "$i.$a" --add "$i" + done' - $a + +## Go through each diverted tool, and, if it hasn't been moved aside, then +## /link/ it across now. If we rename it, then the chroot will stop working +## -- which is why we didn't allow `dpkg-divert' to do the rename. We can +## tell a tool that hasn't been moved, because it's a symlink into one of the +## cross trees. +while read i; do + if [ -e $root$i ] && ! [ -e $root$i.$a ]; then + if [ -L $root$i ]; then + t=$(readlink $root$i) + case $t in + $crossdir/* | $qemudir/* | /usr/local.schroot/qemu/*) continue ;; + esac + if [ -L $crossdir$i ]; then + u=$(readlink $crossdir$i) + case $t in "$u") continue ;; esac + fi + fi + echo >&2 "$0: preserve old $i" + ln $root$i $root$i.$a + fi +done <$root/mnt/DIVERT.want + +## Update all of the symbolic links which are currently wrong: add links +## which are missing, delete ones which are obsolete, and update ones which +## have the wrong target. +join -j1 -a1 -a2 -e- -o"0 1.2 2.2" \ + $root/mnt/LINK.have $root/mnt/LINK.want | + while read s t0 t1; do + case $t1 in + "$t0") + continue + ;; + -) + echo >&2 "$0: remove obsolete link $s -> $t0" + rm -f $root$s + ;; + *) + case $s in */*) mkdir -p $root${s%/*} ;; esac + rm -f $root$s.new + ln -s $t1 $root$s.new + echo >&2 "$0: link $s -> $t1" + mv -T $root$s.new $root$s + ;; + esac + done + +## Remove diversions from paths which don't need them any more. Here it's +## safe to rename, because either the tool isn't there, in which case it +## obviously wasn't important, or it is, and `dpkg-divert' will atomically +## replace our link with the foreign version. +schroot -uroot -rc$sess -- sh -ec ' + a=$1 + comm -23 /mnt/DIVERT.have /mnt/DIVERT.want | while read i; do + dpkg-divert --package "install-cross-tools" --rename \ + --divert "$i.$a" --remove "$i" + done' - $a + +## Close the session. +schroot -ec$sess + +###----- That's all, folks -------------------------------------------------- diff --git a/bin/mkbuildchroot b/bin/mkbuildchroot index 40f925b..58dc7c6 100755 --- a/bin/mkbuildchroot +++ b/bin/mkbuildchroot @@ -26,8 +26,11 @@ . state/config.sh # @@@config@@@ +## Convert the PROXY configuration setting into something that will affect +## `debootstrap'. case $PROXY in nil) ;; *) http_proxy=$PROXY; export PROXY ;; esac +## Parse the command-line. badp=nil forcep=nil while getopts "f" opt; do case $opt in @@ -43,19 +46,22 @@ d=$1 a=$2 case $d-$a in *-*-*) echo >&2 "$0: bad chroot name \`$arg'"; exit 2 ;; esac if [ ! -d /dev/$VG/ ]; then echo >&2 "$0: no volume group \`$VG'"; exit 2; fi +## Decide whether we need to do special things for installing a foreign +## architecture. qemup=nil dbsopts= for fa in $FOREIGN_ARCHS; do case $fa in "$a") - qemup=t qbsopts=--foreign - eval qhost=\$${a}_QEMUARCH qhost=\$${a}_QEMUHOST + qemup=t dbsopts=--foreign + eval qarch=\$${a}_QEMUARCH qhost=\$${a}_QEMUHOST break ;; esac done +## Construct the logical volume and lay a filesystem onto it. lv=$LVPREFIX$d-$a -mnt=mnt/$lv +mnt=$HERE/mnt/$lv mkdir -p $mnt if mountpoint -q $mnt; then umount $mnt; fi if [ -b /dev/$VG/$lv ]; then @@ -69,10 +75,19 @@ mkfs -j -L$d-$a /dev/$VG/$lv mount -orelatime,data=writeback,commit=3600,barrier=0 /dev/$VG/$lv $mnt/ mkdir -m755 $mnt/fs/ chmod 750 $mnt/ -pkgs=ccache,eatmydata,fakeroot,libfile-fcntllock-perl,locales,tzdata + +## Install the base system. +want=$BASE_PACKAGES +case $qemup in + t) want="$want $FOREIGN_BASE_PACKAGES" ;; + nil) want="$want $NATIVE_BASE_PACKAGES" ;; +esac +pkgs=; for p in $want; do pkgs=${pkgs:+$pkgs,}$p; done eatmydata debootstrap $dbsopts --arch=$a --variant=minbase \ --include=$pkgs $d $mnt/fs/ $DEBMIRROR +## If this is a cross-installation, then install the necessary `qemu' and +## complete the installation. case $qemup in t) install $LOCAL/cross/$d-$qhost/QEMU/qemu-$qarch-static \ @@ -83,16 +98,17 @@ case $qemup in ;; esac -cd $mnt/fs/usr/ -rm -rf local/; ln -s local.schroot/$a local +## Set up `/usr/local'. +rm -rf $mnt/fs/usr/local/; ln -s local.schroot/$a $mnt/fs/usr/local -cd $mnt/fs/etc/apt/ -rm -rf apt.conf sources.list -ln -s /usr/local.schroot/config/apt/conf.d/10sbuild apt.conf.d/ -ln -s /usr/local.schroot/config/apt/conf.d/90local apt.conf.d/ -ln -s /usr/local.schroot/config/apt/sources.$d sources.list +## Install the `apt' configuration. +rm -rf $mnt/fs/etc/apt/apt.conf $mnt/fs/etc/apt/sources.list +for c in $LOCAL/etc/apt/apt.conf.d/*; do + ln -s /usr/local.schroot/${c#$LOCAL/} $mnt/fs/etc/apt/apt.conf.d/ +done +ln -s /usr/local.schroot/etc/apt/sources.$d $mnt/fs/etc/apt/sources.list -cat >apt.conf.d/20arch <$mnt/fs/etc/apt/apt.conf.d/20arch <policy-rc.d <$mnt/fs/usr/sbin/policy-rc.d <&2 "policy-rc.d: Services disabled by policy." exit 101 EOF -chmod +x policy-rc.d +chmod +x $mnt/fs/usr/sbin/policy-rc.d -cd $mnt/fs/etc/ld.so.conf.d/ -cat >libc.conf <$mnt/fs/etc/ld.so.conf.d/libc.conf <zzz-local.conf <$mnt/fs/etc/ld.so.conf.d/zzz-local.conf </dev/null 2>&1 --no-rename --help then no_rename=--no-rename @@ -138,11 +159,18 @@ case $qemup in fi dpkg-divert --package install-cross-tools \$no_rename \ - --divert /usr/bin/$qemu.$a --add /usr/bin/$qemu" + --divert /usr/bin/qemu-$qarch-static.$a --add /usr/bin/qemu-$qarch-static" + + ## Install faster native tools. $STATE/bin/install-cross-tools $d $a + + ## Install `build-essential', which had been delayed from earlier. + schroot -uroot -csource:$LVPREFIX$d-$a -- \ + eatmydata apt-get -y install build-essential ;; esac +## Set the chroot's package state up properly. schroot -uroot -csource:$LVPREFIX$d-$a -- eatmydata sh -e -c ' apt-get update apt-get -y upgrade diff --git a/bin/mkchrootconf b/bin/mkchrootconf index 9aff2a6..642fb37 100755 --- a/bin/mkchrootconf +++ b/bin/mkchrootconf @@ -96,7 +96,7 @@ EOF type=lvm-snapshot description=Debian $dist/$arch autobuilder device=/dev/$VG/$LVPREFIX$dist-$arch -lvm-snapshot-options=$snapopt +lvm-snapshot-options=$SNAPOPT mount-options=-onosuid,data=writeback,barrier=0,commit=3600,noatime location=/fs groups=root,sbuild diff --git a/bin/update-cross-tools b/bin/update-cross-tools new file mode 100755 index 0000000..a738af0 --- /dev/null +++ b/bin/update-cross-tools @@ -0,0 +1,277 @@ +#! /bin/sh -e +### +### Fetch native versions of tools for insertion into foreign chroots +### +### (c) 2018 Mark Wooding +### + +###----- Licensing notice --------------------------------------------------- +### +### This file is part of the distorted.org.uk chroot maintenance tools. +### +### distorted-chroot is free software: you can redistribute it and/or +### modify it under the terms of the GNU General Public License as +### published by the Free Software Foundation; either version 2 of the +### License, or (at your option) any later version. +### +### distorted-chroot is distributed in the hope that it will be useful, +### but WITHOUT ANY WARRANTY; without even the implied warranty of +### MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +### General Public License for more details. +### +### You should have received a copy of the GNU General Public License +### along with distorted-chroot. If not, write to the Free Software +### Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, +### USA. + +. state/config.sh # @@@config@@@ + +###-------------------------------------------------------------------------- +### Utilities. + +chase_link () { + p=$1 d= + ## Copy an absolute path P from the donor tree `$root/' into the + ## cross-tools tree `$crossnew/'. If resolving P involves traversing a + ## symbolic link, then ensure that the pieces of filesystem it directs us + ## to are also copied. + + ## Work through the remaining components of the path. + while :; do + + ## Analyse the first remaining component of the path P. + case $p in + + ## It's empty. We're done. + "") break ;; + + ## A redundant `/' or `./'. Skip it. + "/"*) p=${p#/} ;; + "./"*) p=${p#./} ;; + + ## A `../'. Strip off the trailing component of D. + "../"*) + p=${p#../} + case $d in */*) d=${d%/*} ;; *) d= ;; esac + ;; + + ## Something else. Transfer the component name to D. + *) + case $p in */*) f=${p%%/*} p=${p#*/} ;; *) f=$p p="" ;; esac + d=${d:+$d/}$f + ;; + esac + + ## If D doesn't refer to a file in the cross-tools tree, then maybe it + ## refers to something in the donor tree. Find out what, and copy it + ## into the cross-tools tree. + if ! [ -e "$crossnew$d" ] && ! [ -L "$crossnew$d" ]; then + if [ -d "$root/$d" ] && ! [ -L "$root/$d" ]; then + mkdir "$crossnew$d" + else + echo >&2 "$0: copy /$d to satisfy symlinks" + rsync -aHR $root/./$d $crossnew + fi + fi + + ## If D refers to a symbolic link, then append the link target to P, so + ## that we can make sure we copy the target. + if [ -L "$crossnew$d" ]; then + t=$(readlink "$crossnew$d") + case $t in /*) t=${t#/} d= ;; esac + case $d in */*) d=${d%/*} ;; *) d= ;; esac + p=$t${p:+/$p} + fi + done +} + +###-------------------------------------------------------------------------- +### Main program. + +## Parse the command line. +badp=nil +case $# in 2) ;; *) badp=t ;; esac +case $badp in t) echo >&2 "usage: $0 DIST MYARCH"; exit 2 ;; esac +d=$1 myarch=$2 + +## Keep track of our original stdout. +exec 3>&1 + +## Figure out derived architecture names. +mymulti=$(dpkg-architecture -a$myarch -qDEB_HOST_MULTIARCH) + +## First, set `cross_archs' as a list of GNUish names for our supported +## foreign architectures. +cross_archs="arm-linux-gnueabi arm-linux-gnueabihf aarch64-linux-gnu" + +## Make a list of extra packages we'll need to install to obtain our tools. +cross_pkgs=" + apt bash ccache coreutils dash eatmydata fakeroot findutils + gnupg gpgv gzip m4 make mawk qemu-user-static sed tar xz-utils" +for a in $cross_archs; do + for i in gcc g++ binutils; do + cross_pkgs="$cross_pkgs $i-$a" + done +done +cross_pkgs=$(echo $cross_pkgs) + +## Make an enormous shopping list of paths. +## +## The `wanted' list consists of two kinds of items: an absolute path names a +## prefix (not necessarily a directory name) to be attached to the following +## relative names, up to the end of the list or the next absolute path. +wanted=" + /usr/bin/ apt apt-cache apt-config apt-get apt-key apt-mark + /usr/lib/apt/ methods/ solvers/ + + /bin/ cat chgrp chown cp date dd df dir echo false ln ls mkdir + mknod mktemp mv pwd readlink rm rmdir sleep stty sync touch + true uname vdir + /usr/bin/ [ arch b2sum base32 base64 basename chcon cksum comm + csplit cut dircolors dirname du env expand expr factor fmt + fold groups head hostid id install join link logname md5sum + mkfifo nice nl nohup nproc numfmt od paste pathchk pinky pr + printenv printf ptx realpath runcon seq sha1sum sha224sum + sha256sum sha384sum sha512sum shred shuf sort split stat + stdbuf sum tac tail tee test timeout tr truncate tsort tty + unexpand uniq unlink users wc who whoami yes + /usr/lib/$mymulti/ coreutils/ + + /lib/$mymulti/ libnss_*.so.* + + /usr/bin/ gpg gpgv gpgconf kbxutil watchgnupg + + /usr/bin/ qemu-*-static + + /bin/ bash dash gzip sed tar + /usr/bin/ ccache find m4 make mawk xargs xz + /usr/lib/$mymulti/ libeatmydata.so* libfakeroot/ + + /etc/ld.so.conf.d/ $mymulti.conf fakeroot*.conf" + +for a in $cross_archs; do + wanted="$wanted + + /usr/bin/$a- addr2line ar as c++filt dwp elfedit gprof ld ld.* + nm objcopy objdump ranlib readelf size strings strip + + /usr/bin/$a- cpp gcc g++ gcov gcov-dump gcov-tool gprof + gcc-ar gcc-nm gcc-ranlib + /usr/lib/gcc-cross/$a/ ..." +done +wanted=$(echo $wanted) + +## Figure out how to recognize dynamic executables. +case $myarch in + i386) elfsig=7f454c46010101??0000000000000000????0300 ;; + amd64) elfsig=7f454c46020101??0000000000000000????3e00 ;; + *) echo >&2 "$0: unsupported local arch \`$myarch'"; exit 2 ;; +esac + +## Open a session to the donor chroot. +echo >&2 "$0: create $d snapshot" +sess=$(schroot -bc$LVPREFIX$d-$myarch 3>&-) + +## Make sure the donor tree is up-to-date, and install the extra packages we +## need. +schroot -uroot -rc$sess -- eatmydata sh -ec " + apt-get update + apt-get -y upgrade + apt-get -y install $cross_pkgs" + +## Establish some pathnames. Prepare a place for our cross-tools tree. +crossdir=$LOCAL/cross/$d-$myarch/ +crossold=${crossdir%/}.old/ crossnew=${crossdir%/}.new/ +root=/schroot/$sess/fs +rm -rf $crossnew; mkdir -p $crossnew + +## Work through the shopping list, copying the things it names into the +## cross-tools tree. +dir=/ +for i in $wanted; do + case $i in + /*) + dir=$i + ;; + *) + case $i in ...) f=$dir ;; *) f=$dir$i ;; esac + echo >&2 "$0: copy $f" + rsync -aHR $root/.$f $crossnew + ;; + esac +done + +## Chase links in the new tree, copying extra stuff that we'll need. +find $crossnew -xtype l -print | while read i; do + chase_link ${i#$crossnew} +done + +## Search the new tree for ELF binaries, and build a list of them in +## `QUEUE.in'. +find $crossnew -type f -print | while read i; do + sig=$(head -c20 "$i" | bincode -e -m0 -flowerc hex) + case $sig in $elfsig) echo "$i" ;; esac +done >$root/private/QUEUE.in + +while [ -s $root/private/QUEUE.in ]; do + ## Work through the ELF binaries in `QUEUE.in', determining which shared + ## libraries they'll need. Write the list of dependencies to `QUEUE.out' + schroot -uroot -rc$sess -- eatmydata sh -ec ' + prog=$1 + while read i; do + echo >&2 "$prog: scanning binary $i" + ldd "$i" | while read a b c d; do + case $a:$b:$c:$d in + not:a:dynamic:executable) ;; + statically:linked::) ;; + /*) echo "$a" ;; + *:=\>:/*) echo "$c" ;; + linux-*) ;; + *) echo >&2 "$i: unable to find $a"; exit 2 ;; + esac + done + done /private/QUEUE.out' - "$0" + + ## Work through the shared libraries in `QUEUE.out', copying them to the + ## cross-tools tree if they're not there already. Add the new ones to a + ## new `QUEUE.in' file to scan them in turn. + while read i; do + if [ -e "$crossnew$i" ] || [ -L "$crossnew$i" ] + then continue; fi + if [ -d "$root$i" ]; then continue; fi + echo >&2 "$0: copy $i" + rsync -aHR $root/.$i $crossnew >&3 + chase_link $i >&3 + sig=$(head -c20 $crossnew$i | bincode -e -m0 -flowerc hex) + case $sig in $elfsig) echo "$i" ;; esac + done <$root/private/QUEUE.out >$root/private/QUEUE.in +done + +## Set up the cross-compiler. This is rather hairy. +echo >&2 "$0: establish TOOLCHAIN" +for a in $cross_archs; do + tooldir=$crossnew/TOOLCHAIN/$a + mkdir -p $tooldir + for i in $crossnew/usr/bin/$a-*; do + t=${i#$crossnew/usr/bin/} + mv $i $tooldir/$t + ln -s $t $tooldir/${t#$a-} + done +done +mkdir $crossnew/TOOLCHAIN/lib +ln -s ../../usr/lib/gcc-cross $crossnew/TOOLCHAIN/lib/ + +## Set up the emulator. +echo >&2 "$0: establish QEMU" +mkdir $crossnew/QEMU +mv $crossnew/usr/bin/qemu-*-static $crossnew/QEMU/ + +## We're done. Remove the snapshot, and replace the old cross-tools tree +## with our new one. +echo >&2 "$0: remove snapshot" +schroot -ec$sess 3>&- +if [ -d $crossdir ]; then mv $crossdir $crossold; fi +mv $crossnew $crossdir; rm -rf $crossold +echo >&2 "$0: committed $crossdir" + +###----- That's all, folkd -------------------------------------------------- diff --git a/etc/schroot-scripts/11private b/etc/schroot-scripts/11private new file mode 100755 index 0000000..c477ddf --- /dev/null +++ b/etc/schroot-scripts/11private @@ -0,0 +1,53 @@ +#! /bin/sh -e +### +### Make build trees private to the invoking group +### +### (c) 2018 Mark Wooding +### + +###----- Licensing notice --------------------------------------------------- +### +### This file is part of the distorted.org.uk chroot maintenance tools. +### +### distorted-chroot is free software: you can redistribute it and/or +### modify it under the terms of the GNU General Public License as +### published by the Free Software Foundation; either version 2 of the +### License, or (at your option) any later version. +### +### distorted-chroot is distributed in the hope that it will be useful, +### but WITHOUT ANY WARRANTY; without even the implied warranty of +### MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +### General Public License for more details. +### +### You should have received a copy of the GNU General Public License +### along with distorted-chroot. If not, write to the Free Software +### Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, +### USA. + +### Make a build tree private to the invoking user. Also, make a `/private' +### directory in the chroot which is exclusive to the creating user. + +## Make sure everything is good. +case $1 in setup-start) ;; *) exit 0 ;; esac +case $CHROOT_SESSION_PURGE in true) ;; *) exit 0 ;; esac +case $CHROOT_PROFILE in sbuild | scratchbox) ;; *) exit 0 ;; esac +case $CHROOT_TYPE in *-snapshot) ;; *) exit 0 ;; esac +case $CHROOT_MOUNT_LOCATION in + "" | /) echo >&2 "$0: not clobbering root dir"; exit 127 ;; +esac + +## Make the directory private to the invoking user's group. This is a +## somewhat troublesome compromise between keeping the chroot tree private +## from other system users on the one hand, and maintaining system security +## on the other. +## +## This assumes that the device root directory's permissions are already +## restricted to privileged users only. +cd $CHROOT_MOUNT_LOCATION +chown root:$AUTH_RGROUP . +chmod 750 . + +## Make an actually-private place for temporary things to be stored. +mkdir -p $CHROOT_PATH/private +mount -ttmpfs -omode=700,uid=$AUTH_RUID,gid=$AUTH_RGID \ + private $CHROOT_PATH/private diff --git a/etc/schroot-scripts/15binfmt b/etc/schroot-scripts/15binfmt new file mode 100755 index 0000000..892f046 --- /dev/null +++ b/etc/schroot-scripts/15binfmt @@ -0,0 +1,4 @@ +#!/bin/sh + +## We've already handled this. +: diff --git a/etc/schroot-scripts/51chrootenv b/etc/schroot-scripts/51chrootenv new file mode 100755 index 0000000..797b5d3 --- /dev/null +++ b/etc/schroot-scripts/51chrootenv @@ -0,0 +1,33 @@ +#! /bin/sh -e +### +### Write the chroot environment variables to a file. +### +### (c) 2018 Mark Wooding +### + +###----- Licensing notice --------------------------------------------------- +### +### This file is part of the distorted.org.uk chroot maintenance tools. +### +### distorted-chroot is free software: you can redistribute it and/or +### modify it under the terms of the GNU General Public License as +### published by the Free Software Foundation; either version 2 of the +### License, or (at your option) any later version. +### +### distorted-chroot is distributed in the hope that it will be useful, +### but WITHOUT ANY WARRANTY; without even the implied warranty of +### MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +### General Public License for more details. +### +### You should have received a copy of the GNU General Public License +### along with distorted-chroot. If not, write to the Free Software +### Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, +### USA. + +### Otherwise this useful information gets lost. + +case "$1" in + setup-start) + env | sed -n '/^CHROOT_/s///p' | sort >"$CHROOT_PATH/etc/schroot.info" + ;; +esac diff --git a/pkg/checkpath-1.2.4.1.tar.gz b/pkg/checkpath-1.2.4.1.tar.gz new file mode 100644 index 0000000..9619830 Binary files /dev/null and b/pkg/checkpath-1.2.4.1.tar.gz differ diff --git a/pkg/mLib-2.3.3.1.tar.gz b/pkg/mLib-2.3.3.1.tar.gz new file mode 100644 index 0000000..63ba286 Binary files /dev/null and b/pkg/mLib-2.3.3.1.tar.gz differ