Add in the mess from the original symbiosisware version.
authorMark Wooding <mdw@distorted.org.uk>
Sun, 8 Sep 2019 19:49:01 +0000 (20:49 +0100)
committerMark Wooding <mdw@distorted.org.uk>
Wed, 11 Sep 2019 11:05:56 +0000 (12:05 +0100)
27 files changed:
mess/.rsync-filter [new file with mode: 0644]
mess/config/apt/Makefile [new file with mode: 0644]
mess/config/apt/aptsrc.buster [new file with mode: 0644]
mess/config/apt/aptsrc.conf [new symlink]
mess/config/apt/aptsrc.jessie [new file with mode: 0644]
mess/config/apt/aptsrc.sid [new file with mode: 0644]
mess/config/apt/aptsrc.stretch [new file with mode: 0644]
mess/config/apt/aptsrc.wheezy [new file with mode: 0644]
mess/config/apt/conf.d/10sbuild [new file with mode: 0644]
mess/config/apt/mkaptsrc [new symlink]
mess/config/sbuild.conf [new file with mode: 0644]
mess/config/schroot/profiles/sbuild/copyfiles [new file with mode: 0644]
mess/config/schroot/profiles/sbuild/fstab [new file with mode: 0644]
mess/config/schroot/profiles/sbuild/nssdatabases [new file with mode: 0644]
mess/config/schroot/scripts/11private [new file with mode: 0755]
mess/config/schroot/scripts/15binfmt [new file with mode: 0755]
mess/config/schroot/scripts/51chrootenv [new file with mode: 0755]
mess/hacks/apt-get [new symlink]
mess/hacks/aptitude [new symlink]
mess/hacks/buildwrap [new file with mode: 0755]
mess/hacks/dpkg [new symlink]
mess/maint/Makefile [new file with mode: 0644]
mess/maint/install-cross-tools [new file with mode: 0755]
mess/maint/mkbuildchroot [new file with mode: 0755]
mess/maint/mkchrootconf [new file with mode: 0755]
mess/maint/sync [new file with mode: 0755]
mess/maint/update-cross-tools [new file with mode: 0755]

diff --git a/mess/.rsync-filter b/mess/.rsync-filter
new file mode 100644 (file)
index 0000000..25e76f0
--- /dev/null
@@ -0,0 +1,12 @@
+### -*-conf-*-
+
+## Don't overwrite our local configuration.
+- /config/apt/conf.d/9*
+- /config/apt/aptsrc.local.conf
+- /config/apt/sources.*
+- /maint/local.mk
+
+## Local state and suchlike.
+- /cross/
+- /maint/chroot-stamps/
+- /qemu/
diff --git a/mess/config/apt/Makefile b/mess/config/apt/Makefile
new file mode 100644 (file)
index 0000000..2ef5827
--- /dev/null
@@ -0,0 +1,15 @@
+### -*-makefile-*-
+
+all::
+clean::
+.PHONY: all clean
+
+.SECONDEXPANSION: #sorry
+
+DISTS = wheezy jessie stretch buster sid
+SOURCES = $(addprefix sources., $(DISTS))
+APTSRC_CONF_BASE = aptsrc.conf $(wildcard aptsrc.local.conf)
+all:: $(SOURCES)
+$(SOURCES): sources.%: mkaptsrc $(APTSRC_CONF_BASE) aptsrc.$$*
+       ./mkaptsrc $(APTSRC_CONF_BASE) aptsrc.$* >$@.new && mv $@.new $@
+clean::; rm -f $(SOURCES)
diff --git a/mess/config/apt/aptsrc.buster b/mess/config/apt/aptsrc.buster
new file mode 100644 (file)
index 0000000..be6a128
--- /dev/null
@@ -0,0 +1,4 @@
+### -*-conf-*-
+subscribe
+       debian : buster
+       distorted : experimental
diff --git a/mess/config/apt/aptsrc.conf b/mess/config/apt/aptsrc.conf
new file mode 120000 (symlink)
index 0000000..96d10a9
--- /dev/null
@@ -0,0 +1 @@
+/etc/apt/aptsrc.conf
\ No newline at end of file
diff --git a/mess/config/apt/aptsrc.jessie b/mess/config/apt/aptsrc.jessie
new file mode 100644 (file)
index 0000000..861269f
--- /dev/null
@@ -0,0 +1,4 @@
+### -*-conf-*-
+subscribe
+       debian : jessie
+       distorted : experimental
diff --git a/mess/config/apt/aptsrc.sid b/mess/config/apt/aptsrc.sid
new file mode 100644 (file)
index 0000000..ab1e564
--- /dev/null
@@ -0,0 +1,4 @@
+### -*-conf-*-
+subscribe
+       debian : sid
+       distorted : experimental
diff --git a/mess/config/apt/aptsrc.stretch b/mess/config/apt/aptsrc.stretch
new file mode 100644 (file)
index 0000000..3b695ee
--- /dev/null
@@ -0,0 +1,4 @@
+### -*-conf-*-
+subscribe
+       debian : stretch
+       distorted : experimental
diff --git a/mess/config/apt/aptsrc.wheezy b/mess/config/apt/aptsrc.wheezy
new file mode 100644 (file)
index 0000000..5659b4e
--- /dev/null
@@ -0,0 +1,4 @@
+### -*-conf-*-
+subscribe
+       debian : wheezy
+       distorted : experimental
diff --git a/mess/config/apt/conf.d/10sbuild b/mess/config/apt/conf.d/10sbuild
new file mode 100644 (file)
index 0000000..8eecc7f
--- /dev/null
@@ -0,0 +1,5 @@
+### -*-conf-*-
+
+APT {
+       Install-Recommends "false";
+};
diff --git a/mess/config/apt/mkaptsrc b/mess/config/apt/mkaptsrc
new file mode 120000 (symlink)
index 0000000..f54174b
--- /dev/null
@@ -0,0 +1 @@
+/etc/apt/mkaptsrc
\ No newline at end of file
diff --git a/mess/config/sbuild.conf b/mess/config/sbuild.conf
new file mode 100644 (file)
index 0000000..a314bae
--- /dev/null
@@ -0,0 +1,49 @@
+### -*-perl-*-
+
+my $hackdir = "/usr/local.schroot/hacks";
+
+## Default distribution.
+$distribution = "stretch";
+
+## Force an update before trying the build so that we get just-now built
+## versions of our dependencies.
+$apt_update = 1;
+
+## Don't try to upgrade the chroot.  That's left for the administator to do.
+$apt_upgrade = 0;
+
+## Wrap the build command up.
+$build_env_cmnd = "$hackdir/buildwrap";
+
+## Use hacked versions of some tools.
+$aptitude = "$hackdir/aptitude";
+$apt_get = "$hackdir/apt-get";
+
+## Make sure Scratchbox can find its configuration while we're in the
+## chroot, even after `HOME' has been swizzled.
+$environment_filter = [
+  '^PATH$',
+  '^DEB(IAN|SIGN)?_[A-Z_]+$',
+  '^(C(PP|XX)?|LD|F)FLAGS(_APPEND)?$',
+  '^USER(NAME)?$',
+  '^LOGNAME$',
+  '^HOME$',
+  '^TERM$',
+  '^SBOX_HOME$',
+  '^SHELL$'
+];
+
+## Use the `/private' space constructed by the `sbuild' profile.
+$build_environment = {
+  "TMPDIR" => "/private",
+};
+
+## Actually resolve alternatives properly.
+$resolve_alternatives = 1;
+
+## Don't do anything clever if the build dependencies fail.  The clever thing
+## doesn't work on older distributions.  Also, it takes extra time, and
+## that's not desirable.
+$bd_uninstallable_explainer = "apt";
+
+1;
diff --git a/mess/config/schroot/profiles/sbuild/copyfiles b/mess/config/schroot/profiles/sbuild/copyfiles
new file mode 100644 (file)
index 0000000..8bca83f
--- /dev/null
@@ -0,0 +1,5 @@
+# Files to copy into the chroot from the host system.
+#
+# <source and destination>
+/etc/resolv.conf
+/etc/apt/trusted.gpg.d/distorted.gpg
diff --git a/mess/config/schroot/profiles/sbuild/fstab b/mess/config/schroot/profiles/sbuild/fstab
new file mode 100644 (file)
index 0000000..e3c0715
--- /dev/null
@@ -0,0 +1,17 @@
+# fstab: static file system information for chroots.
+# Note that the mount point will be prefixed by the chroot path
+# (CHROOT_PATH)
+#
+# <file system>        <mount point>   <type>  <options>       <dump>  <pass>
+/proc          /proc           none    rw,bind         0       0
+/sys           /sys            none    rw,bind         0       0
+/dev/pts       /dev/pts        none    rw,bind         0       0
+tmpfs          /dev/shm        tmpfs   defaults        0       0
+/tmp           /tmp            none    rw,bind         0       0
+/home          /home           none    rw,bind         0       0
+/usr/local.schroot /usr/local.schroot none rw,bind     0       0
+/usr/local.schroot /usr/local.schroot none remount,ro,bind 0   0
+
+# Mount a large scratch space for the build, so we don't use up
+# space on an LVM snapshot of the chroot itself.
+/var/lib/sbuild/build /build   none    rw,bind         0       0
diff --git a/mess/config/schroot/profiles/sbuild/nssdatabases b/mess/config/schroot/profiles/sbuild/nssdatabases
new file mode 100644 (file)
index 0000000..42fa310
--- /dev/null
@@ -0,0 +1,7 @@
+# System databases to copy into the chroot from the host system.
+#
+# <database name>
+passwd
+shadow
+group
+gshadow
diff --git a/mess/config/schroot/scripts/11private b/mess/config/schroot/scripts/11private
new file mode 100755 (executable)
index 0000000..e80ebf3
--- /dev/null
@@ -0,0 +1,29 @@
+#! /bin/sh -e
+###
+### 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/mess/config/schroot/scripts/15binfmt b/mess/config/schroot/scripts/15binfmt
new file mode 100755 (executable)
index 0000000..70bb7ad
--- /dev/null
@@ -0,0 +1,53 @@
+#!/bin/sh
+# Copyright © 2011 Julian Andres Klode <jak@debian.org>
+#
+# schroot 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 3 of the License, or
+# (at your option) any later version.
+#
+# schroot 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 this program.  If not, see
+# <http://www.gnu.org/licenses/>.
+#
+#####################################################################
+
+set -e
+
+. "$SETUP_DATA_DIR/common-data"
+. "$SETUP_DATA_DIR/common-functions"
+. "$SETUP_DATA_DIR/common-config"
+
+
+if [ "$STAGE" != "setup-start" ] && \
+   [ "$STAGE" != "setup-stop"  ] && \
+   [ "$STAGE" != "setup-recover" ]; then
+    exit 0
+elif ! which update-binfmts > /dev/null 2>&1; then
+    info "Missing update-binfmts; not enabling binfmt support"
+    exit 0
+fi
+
+shell="${CHROOT_PATH}/bin/sh"
+
+for emulator in $(update-binfmts --find "$shell"); do
+    dst="${CHROOT_PATH}$emulator"
+    if [ ! -e "$emulator" ]; then
+       info "Missing emulator: $emulator; not enabling binfmt support"
+    elif [ ! -e "$dst" ]; then
+       ## [mdw] don't bind over an existing qemu.  Two things go wrong:
+       ## firstly, and more obviously, this forces the use of the host qemu,
+       ## which may be too old to run more bleeding-edge code; and secondly,
+       ## if the chroot's emulator is a symlink to a file in the host
+       ## filesystem to be bound into the chroot, then this bind mount is
+       ## never cleaned up.  It's just a bad idea.
+       touch "$dst"
+       mount --bind "$emulator" "$dst"
+       mount -o remount,ro,bind "$dst"
+    fi
+done
diff --git a/mess/config/schroot/scripts/51chrootenv b/mess/config/schroot/scripts/51chrootenv
new file mode 100755 (executable)
index 0000000..7235dd4
--- /dev/null
@@ -0,0 +1,7 @@
+#! /bin/sh -e
+
+case "$1" in
+  setup-start)
+    env | sed -n '/CHROOT_/s///p' | sort >"$CHROOT_PATH/etc/schroot.info"
+    ;;
+esac
diff --git a/mess/hacks/apt-get b/mess/hacks/apt-get
new file mode 120000 (symlink)
index 0000000..8a7b1b4
--- /dev/null
@@ -0,0 +1 @@
+/usr/bin/eatmydata
\ No newline at end of file
diff --git a/mess/hacks/aptitude b/mess/hacks/aptitude
new file mode 120000 (symlink)
index 0000000..8a7b1b4
--- /dev/null
@@ -0,0 +1 @@
+/usr/bin/eatmydata
\ No newline at end of file
diff --git a/mess/hacks/buildwrap b/mess/hacks/buildwrap
new file mode 100755 (executable)
index 0000000..30348a2
--- /dev/null
@@ -0,0 +1,36 @@
+#! /bin/sh -ex
+
+## 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/mess/hacks/dpkg b/mess/hacks/dpkg
new file mode 120000 (symlink)
index 0000000..8a7b1b4
--- /dev/null
@@ -0,0 +1 @@
+/usr/bin/eatmydata
\ No newline at end of file
diff --git a/mess/maint/Makefile b/mess/maint/Makefile
new file mode 100644 (file)
index 0000000..996f4b0
--- /dev/null
@@ -0,0 +1,97 @@
+### -*-makefile-*-
+
+all:
+clean::
+.PHONY: all clean
+.SECONDEXPANSION: #sorry
+
+confdir = /etc/schroot/chroot.d
+
+DISTS = stretch buster sid
+
+MYARCH = $(shell dpkg --print-architecture)
+OTHERARCHS = $(shell dpkg --print-foreign-architectures)
+TOOLSARCH = $(MYARCH)
+NATIVE_ARCHS = $(MYARCH) $(OTHERARCHS)
+FOREIGN_ARCHS =
+ARCHS = $(NATIVE_ARCHS) $(FOREIGN_ARCHS)
+
+cross = $(foreach i,$1, $(foreach j,$2, $i-$j))
+NATIVE_CHROOTS = $(call cross,$(DISTS),$(NATIVE_ARCHS))
+FOREIGN_CHROOTS = $(call cross,$(DISTS),$(FOREIGN_ARCHS))
+CHROOTS = $(NATIVE_CHROOTS) $(FOREIGN_CHROOTS)
+
+chroot-dist = $(patsubst %/,%,$(dir $(subst -,/,$1)))
+chroot-arch = $(notdir $(subst -,/,$1))
+
+native-chroot-p = $(findstring $(call chroot-arch,$1), $(NATIVE_ARCHS))
+
+qemuarch/armel = i386
+qemuarch/armhf = i386
+qemuarch/arm64 = amd64
+chroot-toolsarch = $(TOOLSARCH)
+chroot-qemuarch = $(qemuarch/$(call chroot-arch,$1))
+chroot-deps = $(if $(call native-chroot-p,$2),,$(addprefix $1/$(call chroot-dist,$2)-,\
+       $(sort $(call chroot-toolsarch,$2) $(call chroot-qemuarch,$2))))
+
+VG = vg-$(shell hostname)
+mkbuildchroot_OPTS = -a$(TOOLSARCH) -f -v$(VG)
+mkchrootconf_OPTS = -v$(VG)
+install-cross-tools_OPTS =
+update-cross-tools_OPTS =
+
+-include local.mk
+
+all: config
+CONFIG = $(confdir)/sbuild
+config:; locking -w Makefile make $(CONFIG)
+$(CONFIG): Makefile $(wildcard local.mk) mkchrootconf
+       ./mkchrootconf $(mkchrootconf_OPTS) $(CHROOTS) >$@.new && \
+               mv $@.new $@
+clean::; rm -f $(CONFIG)
+.PHONY: config
+
+UPDATE_CROSS = $(addprefix update-cross/, $(NATIVE_CHROOTS))
+update-cross: $(UPDATE_CROSS)
+$(UPDATE_CROSS): update-cross/%: update/%
+       ./update-cross-tools $(update-cross-tools_OPTS) \
+               -a$(call chroot-arch,$*) $(call chroot-dist,$*)
+.PHONY: update-cross $(UPDATE_CROSS)
+
+UPDATE = $(addprefix update/, $(CHROOTS))
+update: $(UPDATE)
+$(UPDATE): update/%: chroot-stamps/% $$(call chroot-deps,update-cross,$$*)
+       $(if $(call native-chroot-p,$*),,\
+               ./install-cross-tools $(install-cross-tools_OPTS) \
+                       -a$(call chroot-toolsarch,$*) \
+                       -q$(call chroot-qemuarch,$*) \
+                       $*)
+       schroot -uroot -csource:$* -- apt-get update
+       schroot -uroot -csource:$* -- apt-get -y dist-upgrade
+       schroot -uroot -csource:$* -- apt-get -y autoremove
+       schroot -uroot -csource:$* -- apt-get -y clean
+.PHONY: update $(UPDATE)
+
+all: create
+CREATESTAMPS = $(addprefix chroot-stamps/, $(CHROOTS))
+create: $(CREATESTAMPS)
+$(CREATESTAMPS): chroot-stamps/%: $$(call chroot-deps,chroot-stamps,$$*)
+       make config
+       mkdir -p $(dir $@)
+       ./mkbuildchroot $(mkbuildchroot_OPTS) \
+               $(if $(call native-chroot-p,$*),,\
+                       -Q -a$(call chroot-toolsarch,$*) \
+                       -q$(call chroot-qemuarch,$*)) \
+               $*
+       echo done >$@
+clean::; rm -f chroot-stamps/*
+.PHONY: create
+
+all: prune
+PRUNESTAMPS = $(patsubst chroot-stamps/%,prune/%, \
+       $(filter-out $(CREATESTAMPS),$(wildcard chroot-stamps/*)))
+prune: $(PRUNESTAMPS)
+$(PRUNESTAMPS): prune/%:
+       lvremove -f $(VG)/$*
+       rm -f chroot-stamps/$*
+.PHONY: prune $(PRUNESTAMPS)
diff --git a/mess/maint/install-cross-tools b/mess/maint/install-cross-tools
new file mode 100755 (executable)
index 0000000..1ee0ec8
--- /dev/null
@@ -0,0 +1,151 @@
+#! /bin/sh -e
+
+badp=nil
+myarch=$(dpkg-architecture -qDEB_HOST_ARCH); unset myqarch
+while getopts "a:q:" opt; do
+  case $opt in
+    a) myarch=$OPTARG ;;
+    q) myqarch=$OPTARG ;;
+    *) badp=t ;;
+  esac
+done
+shift $(( $OPTIND - 1 ))
+case $# in 0) badp=t ;; esac
+case $badp in
+  t)
+    cat >&2 <<EOF
+usage: $0 [-a MYARCH] [-q MYQARCH] DIST-ARCH ...
+EOF
+    exit 1
+    ;;
+esac
+case ${myqarch+t} in t) ;; *) myqarch=$myarch ;; esac
+mymulti=$(dpkg-architecture -a$myarch -qDEB_HOST_MULTIARCH)
+
+for arg in "$@"; do
+  d=${arg%-*} a=${arg#*-}
+
+  if ! [ -d /usr/local.schroot/cross/$d-$myarch ]; then
+    echo 2>&1 "$0: no tree for \`$d-$myarch'"; exit 1
+  fi
+
+  gnuarch=$(dpkg-architecture -A$a -qDEB_TARGET_GNU_TYPE)
+
+  case $a in
+    armel | armhf) qarch=arm ;;
+    arm64) qarch=aarch64 ;;
+    amd64) qarch=x86_64 ;;
+    i386) qarch=i386 ;;
+    *) echo >&2 "$0: no qemu arch for $a"; exit 1 ;;
+  esac
+
+  sess=$(schroot -bcsource:$d-$a)
+  root=/schroot/$sess/fs
+  qemudir=/usr/local.schroot/cross/$d-$myqarch/QEMU
+  crossdir=/usr/local.schroot/cross/$d-$myarch
+
+  schroot -uroot -rc$sess -- sh -ec '
+       if ! mountpoint -q /mnt; then
+         mount -ttmpfs -omode=700,uid=0,gid=0 private /mnt
+       fi'
+
+  { echo $qemudir/qemu-$qarch-static
+    echo $crossdir/lib/$mymulti
+    echo $crossdir/usr/lib/$mymulti
+    echo $crossdir/usr/lib/gcc-cross
+    find $crossdir $crossdir/TOOLCHAIN/$gnuarch \
+        \( \(  -path "*/QEMU" -o -path "*/TOOLCHAIN" -o \
+        -path "*/lib/$mymulti" -o \
+        -path "*/lib/gcc-cross" \) -prune \) -o \
+        \( ! -type d -print \)
+  } | 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
+
+  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.want
+       } | sort >/mnt/LINK.have'
+
+  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
+
+  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
+
+  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
+
+  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
+
+  schroot -ec$sess
+done
diff --git a/mess/maint/mkbuildchroot b/mess/maint/mkbuildchroot
new file mode 100755 (executable)
index 0000000..81c811f
--- /dev/null
@@ -0,0 +1,135 @@
+#! /bin/sh -e
+
+vg=vg-$(hostname)
+lvsz=-L8g
+mirror=http://deb.debian.org/debian/
+myarch=$(dpkg-architecture -qDEB_HOST_ARCH) qemup=nil; unset myqarch
+eval $(apt-config -c /usr/local.schroot/config/apt/conf.d/90local \
+  shell http_proxy Acquire::http::proxy)
+case ${http_proxy+t} in t) export http_proxy ;; esac
+
+badp=nil forcep=nil dbsopts= crossp=nil; unset qemu
+while getopts "a:e:fm:q:Qv:z:x" opt; do
+  case $opt in
+    a) myarch=$OPTARG ;;
+    f) forcep=t ;;
+    m) mirror=$OPTARG ;;
+    q) myqarch=$OPTARG ;;
+    Q) qemup=t dbsopts=--foreign ;;
+    v) vg=$OPTARG ;;
+    x) crossp=t ;;
+    z) lvsz=-$OPTARG ;;
+    *) badp=t ;;
+  esac
+done
+shift $(( $OPTIND - 1 ))
+case $# in 0) badp=t ;; esac
+case $badp in
+  t)
+    cat >&2 <<EOF
+usage: $0 [-fxQ] [-a MYARCH] [-m MIRROR] [-q MYQARCH] [-v VG] [-z LVSZ]
+       DIST-ARCH ...
+EOF
+    exit 1
+    ;;
+esac
+case ${myqarch+t} in t) ;; *) myqarch=$myarch ;; esac
+for arg in "$@"; do
+  case $arg in *-*-*) echo >&2 "$0: bad chroot name \`$arg'"; exit 1 ;; esac
+done
+if [ ! -d /dev/$vg/ ]; then echo >&2 "$0: no volume group \`$vg'"; exit 1; fi
+
+for arg in "$@"; do
+  d=${arg%-*} a=${arg#*-}
+  mnt=/mnt/chroot/$d-$a
+  mkdir -p $mnt
+  if mountpoint -q $mnt; then umount $mnt; fi
+  if [ -b /dev/$vg/$d-$a ]; then
+    case $forcep in
+      nil) echo >&2 "$0: volume \`$d-$a' already exists"; exit 1 ;;
+      t) lvremove -f $vg/$d-$a ;;
+    esac
+  fi
+  lvcreate --yes $lvsz -n$arg $vg
+  mkfs -j -L$arg /dev/$vg/$arg
+  mount -orelatime,data=writeback,commit=3600,barrier=0 /dev/$vg/$arg $mnt/
+  mkdir -m755 $mnt/fs/
+  chmod 750 $mnt/
+  pkgs=ccache,eatmydata,fakeroot,libfile-fcntllock-perl,locales,tzdata
+  case $crossp in nil) pkgs=$pkgs,build-essential ;; esac
+  eatmydata debootstrap $dbsopts --arch=$a --variant=minbase --include=$pkgs \
+    $d $mnt/fs/ $mirror
+  case $qemup in
+    t)
+      case $a in
+       armel | armhf) qarch=arm ;;
+       arm64) qarch=aarch64 ;;
+       amd64) qarch=x86_64 ;;
+       i386) qarch=i386 ;;
+       *) echo >&2 "$0: no qemu arch for $a"; exit 1 ;;
+      esac
+      qemu=qemu-$qarch-static
+      install /usr/local.schroot/cross/$d-$myqarch/QEMU/$qemu $mnt/fs/usr/bin/
+      chroot $mnt/fs/ /debootstrap/debootstrap --second-stage
+      ln -sf /usr/local.schroot/cross/$d-$myqarch/QEMU/$qemu $mnt/fs/usr/bin/
+      ;;
+  esac
+  cd $mnt/fs/usr/
+  rm -rf local/; ln -s local.schroot/$a 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
+  cat >apt.conf.d/20arch <<EOF
+### -*-conf-*-
+
+APT {
+       Architecture "$a";
+};
+EOF
+  cd $mnt/fs/etc/
+  cp /etc/locale.gen /etc/timezone ./
+  tz=$(cat timezone); ln -sf /usr/share/zoneinfo/$tz localtime
+  ln -sf /proc/mounts mtab
+  cd $mnt/fs/etc/default/
+  cp /etc/default/locale .
+  cd $mnt/fs/usr/sbin/
+  cat >policy-rc.d <<EOF
+#! /bin/sh
+echo >&2 "policy-rc.d: Services disabled by policy."
+exit 101
+EOF
+  chmod +x policy-rc.d
+  cd $mnt/fs/etc/ld.so.conf.d/
+  cat >libc.conf <<EOF
+# libc default configuration
+EOF
+  cat >zzz-local.conf <<EOF
+### -*-conf-*-
+### Local hack to make /usr/local/ late.
+/usr/local/lib
+EOF
+  cd /
+  umount $mnt/
+  case $qemup in
+    t)
+      schroot -uroot -csource:$d-$a -- eatmydata sh -e -c "
+       if dpkg-divert >/dev/null 2>&1 --no-rename --help
+       then no_rename=--no-rename
+       else no_rename=
+       fi
+
+       dpkg-divert --package install-cross-tools \$no_rename \
+         --divert /usr/bin/$qemu.$a --add /usr/bin/$qemu"
+      /usr/local.schroot/maint/install-cross-tools -a$myarch -q$myqarch $d-$a
+      ;;
+  esac
+  schroot -uroot -csource:$d-$a -- eatmydata sh -e -c '
+       apt-get update
+       apt-get -y upgrade
+       locale-gen
+       ldconfig
+       apt-get -y autoremove
+       apt-get clean'
+done
diff --git a/mess/maint/mkchrootconf b/mess/maint/mkchrootconf
new file mode 100755 (executable)
index 0000000..f1ebaca
--- /dev/null
@@ -0,0 +1,101 @@
+#! /bin/sh -e
+
+unset vg snapopt defdist defarch mirror scratchbase
+badp=nil
+while getopts "a:d:l:v:" opt; do
+  case $opt in
+    a) defarch=$OPTARG ;;
+    d) defdist=$OPTARG ;;
+    l) snapopt=$OPTARG ;;
+    v) vg=$OPTARG ;;
+    *) badp=t ;;
+  esac
+done
+shift $(( $OPTIND - 1 ))
+case $# in 0) badp=t ;; esac
+case $badp in
+  t)
+    cat >&2 <<EOF
+usage: $0 [-a ARCH] [-d DIST] [-l SNAPOPT] [-v VG]
+       DIST-ARCH ...
+EOF
+    exit 1
+    ;;
+esac
+for arg in "$@"; do
+  case $arg in *-*-*) echo >&2 "$0: bad chroot name \`$arg'"; exit 1 ;; esac
+done
+if [ ! -d /dev/$vg/ ]; then echo >&2 "$0: no volume group \`$vg'"; exit 1; fi
+
+: ${vg=vg-$(hostname)} ${snapopt=-L4g}
+: ${defdist=$(apt-config dump |
+    sed -n '/^APT::Default-Release "\(.*\)";$/s//\1/p')}
+: ${defarch=$(dpkg-architecture -qDEB_HOST_ARCH_CPU)}
+
+for i in $(set | sed -n '/^nickmap_/s/=.*//p'); do unset $i; done
+while read canon aliases; do
+  for alias in $aliases; do
+    eval "nickmap_$canon=\"\${nickmap_$canon+\$nickmap_$canon }$alias\""
+  done
+done <<EOF
+jessie         oldstable
+stretch                stable
+buster         testing
+sid            unstable
+EOF
+
+cat <<EOF
+### -*-conf-*- GENERATED by mkchrootconf
+EOF
+for arg in "$@"; do
+  dist=${arg%-*} arch=${arg#*-}
+  eval "nick=\$nickmap_$dist"
+
+  cat <<EOF
+
+[$arg]
+EOF
+
+  unset alias
+  for n in $nick; do alias=${alias+$alias,}$n-$arch; done
+  case $arch in
+    $defarch) for n in $dist $nick; do alias=${alias+$alias,}$n; done ;;
+  esac
+  case $dist in
+    $defdist) alias=${alias+$alias,}$arch ;;
+  esac
+  case ${alias+t} in
+    t)
+      cat <<EOF
+aliases=$alias
+EOF
+      ;;
+  esac
+
+  case $arch in
+    i386)
+      cat <<EOF
+personality=linux32
+EOF
+      ;;
+    amd64)
+      cat <<EOF
+personality=linux
+EOF
+      ;;
+  esac
+
+  cat <<EOF
+type=lvm-snapshot
+description=Debian $dist/$arch autobuilder
+device=/dev/$vg/$dist-$arch
+lvm-snapshot-options=$snapopt
+mount-options=-onosuid,data=writeback,barrier=0,commit=3600,noatime
+location=/fs
+groups=root,sbuild
+root-groups=root,sbuild
+source-groups=root
+source-root-groups=root
+profile=sbuild
+EOF
+done
diff --git a/mess/maint/sync b/mess/maint/sync
new file mode 100755 (executable)
index 0000000..33c35fc
--- /dev/null
@@ -0,0 +1,10 @@
+#! /bin/sh -e
+
+root=/usr/local.schroot/
+master=universe.distorted.org.uk
+case $1 in
+  +back) from=$root to=$master:$root; shift ;;
+  *) from=$master:$root to=$root ;;
+esac
+cd $root/
+rsync -avH --del --filter=". $root/.rsync-filter" "$@" $from $to
diff --git a/mess/maint/update-cross-tools b/mess/maint/update-cross-tools
new file mode 100755 (executable)
index 0000000..f29893e
--- /dev/null
@@ -0,0 +1,212 @@
+#! /bin/sh -e
+
+badp=nil
+myarch=$(dpkg-architecture -qDEB_HOST_ARCH)
+while getopts "a:" opt; do
+  case $opt in
+    a) myarch=$OPTARG ;;
+    *) badp=t ;;
+  esac
+done
+shift $(( $OPTIND - 1 ))
+case $# in 0) badp=t ;; esac
+case $badp in
+  t)
+    cat >&2 <<EOF
+usage: $0 [-a MYARCH] DIST ...
+EOF
+    exit 1
+    ;;
+esac
+for arg in "$@"; do
+  case $arg in *-*) echo >&2 "$0: bad arch name \`$arg'"; exit 1 ;; esac
+done
+mymulti=$(dpkg-architecture -a$myarch -qDEB_HOST_MULTIARCH)
+
+cross_archs="arm-linux-gnueabi arm-linux-gnueabihf aarch64-linux-gnu"
+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)
+
+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)
+
+case $myarch in
+  i386) elfsig=7f454c46010101??0000000000000000????0300 ;;
+  amd64) elfsig=7f454c46020101??0000000000000000????3e00 ;;
+  *) echo >&2 "$0: unsupported local arch \`$myarch'"; exit 1 ;;
+esac
+
+chase_link () {
+  p=$1 d=
+  while :; do
+    case $p in
+      "") break ;;
+      "/"*) p=${p#/} ;;
+      "./"*) p=${p#./} ;;
+      "../"*)
+       p=${p#../}
+       case $d in */*) d=${d%/*} ;; *) d= ;; esac
+       ;;
+      *)
+       case $p in */*) f=${p%%/*} p=${p#*/} ;; *) f=$p p="" ;; esac
+       d=${d:+$d/}$f
+       ;;
+    esac
+    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 [ -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
+}
+
+exec 3>&1
+for d in "$@"; do
+  echo >&2 "$0: create $d snapshot"
+  sess=$(schroot -bc$d-$myarch 3>&-)
+  schroot -uroot -rc$sess -- eatmydata sh -ec "
+       apt-get update
+       apt-get -y upgrade
+       apt-get -y install $cross_pkgs"
+  crossdir=/usr/local.schroot/cross/$d-$myarch/
+  crossold=${crossdir%/}.old/ crossnew=${crossdir%/}.new/
+  rm -rf $crossnew; mkdir -p $crossnew
+
+  root=/schroot/$sess/fs; 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
+
+  find $crossnew -xtype l -print | while read i; do
+    chase_link ${i#$crossnew}
+  done
+
+  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
+
+  counter=0
+  cp $root/private/QUEUE.in /tmp/mdw/queue.in.$counter
+
+  while [ -s $root/private/QUEUE.in ]; do
+    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.in >/private/QUEUE.out' - "$0"
+
+    cp $root/private/QUEUE.out /tmp/mdw/queue.out.$counter
+    counter=$(( $counter + 1 ))
+
+    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
+
+    cp $root/private/QUEUE.in /tmp/mdw/queue.in.$counter
+
+  done
+
+  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/
+
+  echo >&2 "$0: establish QEMU"
+  mkdir $crossnew/QEMU
+  mv $crossnew/usr/bin/qemu-*-static $crossnew/QEMU/
+
+  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"
+done