[neon/backports-jammy/debuerreotype/Neon/unstable] /: 0.1-1 (patches unapplied)

git-ubuntu importer null at kde.org
Fri Aug 11 03:02:00 BST 2023


Git commit 2511d6dd36a9c0ed4d512998a890dfccb504586f by git-ubuntu importer, on behalf of Tianon Gravi.
Committed on 09/06/2017 at 18:11.
Pushed by carlosdem into branch 'Neon/unstable'.

0.1-1 (patches unapplied)

Imported using git-ubuntu import.

A  +2    -0    .dockerignore
A  +13   -0    .travis.sh
A  +13   -0    .travis.yml
A  +38   -0    Dockerfile
A  +7    -0    LICENSE
A  +123  -0    README.md
A  +1    -0    VERSION
A  +80   -0    build-all.sh
A  +102  -0    build.sh
A  +5    -0    debian/changelog
A  +1    -0    debian/compat
A  +27   -0    debian/control
A  +31   -0    debian/copyright
A  +1    -0    debian/debuerreotype.docs
A  +2    -0    debian/debuerreotype.install
A  +3    -0    debian/gbp.conf
A  +0    -0    debian/patches/series
A  +9    -0    debian/rules
A  +1    -0    debian/source/format
A  +3    -0    debian/tests/control
A  +23   -0    debian/tests/stretch
A  +3    -0    debian/watch
A  +38   -0    scripts/.constants.sh
A  +10   -0    scripts/.slimify-excludes
A  +13   -0    scripts/.snapshot-url.sh
A  +19   -0    scripts/.tar-exclude
A  +12   -0    scripts/debuerreotype-apt-get
A  +22   -0    scripts/debuerreotype-chroot
A  +23   -0    scripts/debuerreotype-fixup
A  +31   -0    scripts/debuerreotype-gen-sources-list
A  +70   -0    scripts/debuerreotype-init
A  +112  -0    scripts/debuerreotype-minimizing-config
A  +61   -0    scripts/debuerreotype-slimify
A  +27   -0    scripts/debuerreotype-tar
A  +9    -0    scripts/debuerreotype-version

https://invent.kde.org/neon/backports-jammy/debuerreotype/-/commit/2511d6dd36a9c0ed4d512998a890dfccb504586f

diff --git a/.dockerignore b/.dockerignore
new file mode 100644
index 0000000..3bedb49
--- /dev/null
+++ b/.dockerignore
@@ -0,0 +1,2 @@
+**
+!scripts/
diff --git a/.travis.sh b/.travis.sh
new file mode 100755
index 0000000..09ddc92
--- /dev/null
+++ b/.travis.sh
@@ -0,0 +1,13 @@
+#!/usr/bin/env bash
+set -Eeuo pipefail
+
+epoch="$(TZ=UTC date --date "$TIMESTAMP" +%s)"
+serial="$(TZ=UTC date --date "@$epoch" +%Y%m%d)"
+
+set -x
+
+./scripts/debuerreotype-version
+./build.sh travis "$SUITE" "@$epoch"
+
+real="$(sha256sum "travis/$serial/$SUITE-amd64.tar.xz" | cut -d' ' -f1)"
+[ -z "$SHA256" ] || [ "$SHA256" = "$real" ]
diff --git a/.travis.yml b/.travis.yml
new file mode 100644
index 0000000..ba18590
--- /dev/null
+++ b/.travis.yml
@@ -0,0 +1,13 @@
+language: bash
+services: docker
+
+env:
+    - SUITE=jessie  TIMESTAMP=2017-01-01T00:00:00Z SHA256=a674379d30cf457e49a909bb0e254ddcb1f72c27f45c68fe930668d6d9399232
+    - SUITE=stretch TIMESTAMP=2017-01-01T00:00:00Z SHA256=139ed970d52ef950c223f9ab325657eb93d0a93c7d6e2fc697fe7510e61760fa
+    - SUITE=sid     TIMESTAMP=2017-01-01T00:00:00Z SHA256=b75b4496deb4d6cee32245e4125e7ef948b09afbeb1ef3b9669e56daf3e822a7
+
+script:
+    - travis_retry ./.travis.sh
+
+after_script:
+    - docker images
diff --git a/Dockerfile b/Dockerfile
new file mode 100644
index 0000000..c20e044
--- /dev/null
+++ b/Dockerfile
@@ -0,0 +1,38 @@
+# docker run --cap-add SYS_ADMIN --tmpfs /tmp:dev,exec,suid,noatime ...
+
+# bootstrapping a new architecture?
+#   ./scripts/debuerreotype-init /tmp/docker-rootfs stretch now
+#   ./scripts/debuerreotype-minimizing-config /tmp/docker-rootfs
+#   ./scripts/debuerreotype-gen-sources-list /tmp/docker-rootfs stretch http://deb.debian.org/debian http://security.debian.org
+#   ./scripts/debuerreotype-tar /tmp/docker-rootfs - | docker import - debian:stretch-slim
+# alternate:
+#   debootstrap --variant=minbase stretch /tmp/docker-rootfs
+#   tar -cC /tmp/docker-rootfs . | docker import - debian:stretch-slim
+# (or your own favorite set of "debootstrap" commands to create a base image for building this one FROM)
+FROM debian:stretch-slim
+
+RUN apt-get update && apt-get install -y --no-install-recommends \
+		debootstrap \
+		xz-utils \
+	&& rm -rf /var/lib/apt/lists/*
+
+COPY scripts /opt/debuerreotype/scripts
+RUN set -ex; \
+	cd /opt/debuerreotype/scripts; \
+	for f in debuerreotype-*; do \
+		ln -svL "$PWD/$f" "/usr/local/bin/$f"; \
+	done
+
+WORKDIR /tmp
+
+# a few example md5sum values for amd64:
+
+# debuerreotype-init test-stretch stretch 2017-05-08T00:00:00Z
+# debuerreotype-tar test-stretch test-stretch.tar
+# md5sum test-stretch.tar
+#   6f965e84837215ac0aa375e3391392db
+
+# debuerreotype-init test-jessie jessie 2017-05-08T00:00:00Z
+# debuerreotype-tar test-jessie test-jessie.tar
+# md5sum test-jessie.tar
+#   45624a45af50f60b6b4be7203bf16c86
diff --git a/LICENSE b/LICENSE
new file mode 100644
index 0000000..7860a6b
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,7 @@
+Copyright 2017 Tianon Gravi <tianon at debian.org>
+
+Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
diff --git a/README.md b/README.md
new file mode 100644
index 0000000..6caa976
--- /dev/null
+++ b/README.md
@@ -0,0 +1,123 @@
+# Debuerreotype
+
+[![Build Status](https://travis-ci.org/debuerreotype/debuerreotype.svg?branch=master)](https://travis-ci.org/debuerreotype/debuerreotype/branches)
+
+Reproducible, [snapshot](http://snapshot.debian.org)-based Debian rootfs builds (especially for Docker).
+
+This is based on [lamby](https://github.com/lamby)'s work for reproducible `debootstrap`:
+
+- https://github.com/lamby/debootstrap/commit/66b15380814aa62ca4b5807270ac57a3c8a0558d
+- https://wiki.debian.org/ReproducibleInstalls
+
+### "Debuerreotype"?
+
+The name is an attempt at riffing off the photography basis of the word "snapshot".  The [daguerreotype](https://en.wikipedia.org/wiki/Daguerreotype) process was an early method for taking photographs, and this is a method for taking "photographs" of Debian at a given point in time.
+
+## Why?
+
+The goal is to create an auditable, reproducible process for creating rootfs tarballs (especially for use in Docker) of Debian releases, based on point-in-time snapshots from [snapshot.debian.org](http://snapshot.debian.org).
+
+However, as noted below, the only strictly Docker-specific script is `debuerreotype-minimizing-config`, which applies many configuration tweaks which are useful for Docker users and may or may not be useful outside of that context.
+
+## Usage
+
+The usage of the scripts here center around a "rootfs" directory, which is both the working directory for building the target rootfs, and contains the `debuerreotype-epoch` file, which records our snapshot.debian.org epoch value (so we can adjust timestamps using it, as it is the basis for our reproducibility).
+
+Available scripts:
+
+| *script* | *purpose* |
+| --- | --- |
+| `debuerreotype-init` | create the initial "rootfs", given a suite and a timestamp (in some format `date(1)` can parse); `sources.list` will be pointing at snapshot.debian.org |
+| `debuerreotype-chroot` | run a command in the given "rootfs" (using `unshare` to mount `/dev`, `/proc`, and `/sys` from the parent environment in a simple, safe way) |
+| `debuerreotype-apt-get` | run `apt-get` via `debuerreotype-chroot`, including `-o Acquire::Check-Valid-Until=false` to account for older snapshots with (now) invalid `Valid-Until` values |
+| `debuerreotype-minimizing-config` | apply configuration tweaks to make the rootfs minimal and keep it minimal (especially targeted at Docker images, with comments explicitly describing Docker use cases) |
+| `debuerreotype-slimify` | remove files such as documentation to create an even smaller rootfs (used for creating `slim` variants of the Docker images, for example) |
+| `debuerreotype-gen-sources-list` | generate an appropriate `sources.list` in the rootfs given a suite, mirror, and secmirror (especially for updating `sources.list` to point at deb.debian.org before generating outputs) |
+| `debuerreotype-fixup` | invoked by `debuerreotype-tar` to fixup timestamps and remove known-bad log files for determinism |
+| `debuerreotype-tar` | deterministically create a tar file of the rootfs |
+| `debuerreotype-version` | print out the version of the current `debuerreotype` installation |
+
+A simple `Dockerfile` is provided for using these scripts in a simple deterministic environment based on Docker, but given a recent enough version of `debootstrap`, they should run fine outside Docker as well (and their deterministic properties have been verified on at least a Gentoo host in addition to the provided Debian-based Docker environment).
+
+The provided `Dockerfile` also includes comments with hints for bootstrapping the environment on a new architecture (which then presumably doesn't have a `debian` Docker base image yet).
+
+Full example: (see [`build.sh`](build.sh) for this in practice)
+
+```console
+$ debuerreotype-init rootfs stretch 2017-01-01T00:00:00Z
+I: Retrieving InRelease
+I: Checking Release signature
+I: Valid Release signature (key id 126C0D24BD8A2942CC7DF8AC7638D0442B90D010)
+...
+I: Checking component main on http://snapshot.debian.org/archive/debian/20170101T000000Z...
+...
+I: Base system installed successfully.
+
+$ cat rootfs/debuerreotype-epoch
+1483228800
+
+$ debuerreotype-minimizing-config rootfs
+
+$ debuerreotype-apt-get rootfs update -qq
+$ debuerreotype-apt-get rootfs dist-upgrade -yqq
+$ debuerreotype-apt-get rootfs install -yqq --no-install-recommends inetutils-ping iproute2
+debconf: delaying package configuration, since apt-utils is not installed
+Selecting previously unselected package libelf1:amd64.
+(Reading database ... 6299 files and directories currently installed.)
+Preparing to unpack .../0-libelf1_0.166-2.2_amd64.deb ...
+Unpacking libelf1:amd64 (0.166-2.2) ...
+Selecting previously unselected package libmnl0:amd64.
+Preparing to unpack .../1-libmnl0_1.0.4-2_amd64.deb ...
+Unpacking libmnl0:amd64 (1.0.4-2) ...
+Selecting previously unselected package iproute2.
+Preparing to unpack .../2-iproute2_4.9.0-1_amd64.deb ...
+Unpacking iproute2 (4.9.0-1) ...
+Selecting previously unselected package netbase.
+Preparing to unpack .../3-netbase_5.3_all.deb ...
+Unpacking netbase (5.3) ...
+Selecting previously unselected package inetutils-ping.
+Preparing to unpack .../4-inetutils-ping_2%3a1.9.4-2+b1_amd64.deb ...
+Unpacking inetutils-ping (2:1.9.4-2+b1) ...
+Setting up libelf1:amd64 (0.166-2.2) ...
+Processing triggers for libc-bin (2.24-8) ...
+Setting up libmnl0:amd64 (1.0.4-2) ...
+Setting up netbase (5.3) ...
+Setting up inetutils-ping (2:1.9.4-2+b1) ...
+Setting up iproute2 (4.9.0-1) ...
+Processing triggers for libc-bin (2.24-8) ...
+
+$ debuerreotype-gen-sources-list rootfs stretch http://deb.debian.org/debian http://security.debian.org
+
+$ debuerreotype-tar rootfs - | sha256sum
+0542bec04135ed60ed5763f0bcf90381d4e5e33786d57aba5aa4b0fc4e43478a  -
+
+$ # try it!  you should get that same sha256sum value!
+```
+
+## Why isn't Wheezy reproducible??
+
+Wheezy is a little sad, and will have a delta similar to the following (as seen via [`diffoscope`](https://diffoscope.org/)):
+
+```
+├── etc/apt/trustdb.gpg
+│ │ @@ -1,8 +1,8 @@
+│ │ -0000000: 0167 7067 0303 0105 0102 0000 591b faa5  .gpg........Y...
+│ │ +0000000: 0167 7067 0303 0105 0102 0000 591b fc0c  .gpg........Y...
+│ │  0000010: 0000 0000 0000 0000 0000 0000 0000 0000  ................
+│ │  0000020: 0000 0000 0000 0001 0a00 0000 0000 0000  ................
+│ │  0000030: 0000 0000 0000 0000 0000 0000 0000 0000  ................
+│ │  0000040: 0000 0000 0000 0000 0000 0000 0000 0000  ................
+│ │  0000050: 0a00 0000 0000 0000 0000 0000 0000 0000  ................
+│ │  0000060: 0000 0000 0000 0000 0000 0000 0000 0000  ................
+│ │  0000070: 0000 0000 0000 0000 0a00 0000 0000 0000  ................
+```
+
+Presumably this is some sort of timestamp, but that's just a guess.  Suggestions for ways of fixing this would be most welcome!  (Otherwise, we'll just wait for Wheezy to go EOL and forget this ever happened. :trollface:)
+
+## How much have you verified this?
+
+Well, I ran the scripts across seven explicit architectures (`amd64`, `arm64`, `armel`, `armhf`, `i386`, `ppc64el`, `s390x`) and eight explicit suites (`oldstable`, `stable`, `testing`, `unstable`, `wheezy`, `jessie`, `stretch`, `sid`) for a timestamp of `2017-05-16T00:00:00Z` (where supported, since `wheezy`/`oldstable` didn't or no longer currently supports some of those architectures), and the above `wheezy` delta (a few bytes in `etc/apt/trustdb.gpg`) were the _only_ modification to any of the tarballs after several runs across several days.
+
+Additionally, Travis runs with a fixed timestamp value across several suites to verify that their checksums are reproducible, as expected.
+
+From time to time, comments in the files generated by `debuerreotype-minimizing-config` might change (for example), which would obviously result in a different checksum, but a simple [`diffoscope`](https://diffoscope.org/) should be sufficient to verify that the change is benign.
diff --git a/VERSION b/VERSION
new file mode 100644
index 0000000..49d5957
--- /dev/null
+++ b/VERSION
@@ -0,0 +1 @@
+0.1
diff --git a/build-all.sh b/build-all.sh
new file mode 100755
index 0000000..09f2a69
--- /dev/null
+++ b/build-all.sh
@@ -0,0 +1,80 @@
+#!/usr/bin/env bash
+set -Eeuo pipefail
+
+suites=(
+	oldstable
+	stable
+	testing
+	unstable
+
+	wheezy
+	jessie
+	stretch
+	sid
+)
+
+thisDir="$(dirname "$(readlink -f "$BASH_SOURCE")")"
+self="$(basename "$0")"
+
+usage() {
+	cat <<-EOU
+		usage: $self <output-dir> <timestamp>
+		   ie: $self output 2017-05-08T00:00:00Z
+	EOU
+}
+eusage() {
+	echo >&2 "error: $1"
+	usage >&2
+	exit 1
+}
+
+# a silly flag to skip "docker build" (for giggles/debugging)
+build=1
+if [ "${1:-}" = '--no-build' ]; then
+	shift
+	build=
+fi
+
+outputDir="${1:-}"; shift || eusage 'missing output-dir'
+timestamp="${1:-}"; shift || eusage 'missing timestamp'
+
+mkdir -p "$outputDir"
+outputDir="$(readlink -f "$outputDir")"
+
+dockerImage='tianon/debuerreotype'
+[ -z "$build" ] || docker build -t "$dockerImage" "$thisDir"
+
+mirror="$("$thisDir/scripts/.snapshot-url.sh" "$timestamp")"
+secmirror="$("$thisDir/scripts/.snapshot-url.sh" "$timestamp" 'debian-security')"
+
+dpkgArch="$(docker run --rm "$dockerImage" dpkg --print-architecture)"
+echo
+echo "-- BUILDING TARBALLS FOR '$dpkgArch' FROM '$mirror/' --"
+echo
+
+fetch_codename() {
+	local suite="$1"; shift
+	wget -qO- "$mirror/dists/$suite/Release" \
+		| tac|tac \
+		| awk -F ': ' 'tolower($1) == "codename" { print $2; exit }'
+}
+declare -A codenames=(
+	[testing]="$(fetch_codename 'testing')"
+	[unstable]="$(fetch_codename 'unstable')"
+)
+
+for suite in "${suites[@]}"; do
+	testUrl="$secmirror/dists/$suite/updates/main/binary-$dpkgArch/Packages.gz"
+	case "$suite" in
+		testing|unstable|"${codenames[testing]}"|"${codenames[unstable]}")
+			testUrl="$mirror/dists/$suite/main/binary-$dpkgArch/Packages.gz"
+			;;
+	esac
+	if ! wget --quiet --spider "$testUrl"; then
+		echo >&2
+		echo >&2 "warning: '$suite' not supported on '$dpkgArch' (at '$timestamp'); skipping"
+		echo >&2
+		continue
+	fi
+	"$thisDir/build.sh" --no-build "$outputDir" "$suite" "$timestamp"
+done
diff --git a/build.sh b/build.sh
new file mode 100755
index 0000000..01ce59d
--- /dev/null
+++ b/build.sh
@@ -0,0 +1,102 @@
+#!/usr/bin/env bash
+set -Eeuo pipefail
+
+thisDir="$(dirname "$(readlink -f "$BASH_SOURCE")")"
+self="$(basename "$0")"
+
+usage() {
+	cat <<-EOU
+		usage: $self <output-dir> <suite> <timestamp>
+		   ie: $self output stretch 2017-05-08T00:00:00Z
+	EOU
+}
+eusage() {
+	echo >&2 "error: $1"
+	usage >&2
+	exit 1
+}
+
+# a silly flag to skip "docker build" (for "build-all.sh")
+build=1
+if [ "${1:-}" = '--no-build' ]; then
+	shift
+	build=
+fi
+
+outputDir="${1:-}"; shift || eusage 'missing output-dir'
+suite="${1:-}"; shift || eusage 'missing suite'
+timestamp="${1:-}"; shift || eusage 'missing timestamp'
+
+mkdir -p "$outputDir"
+outputDir="$(readlink -f "$outputDir")"
+
+securityArgs=(
+	--cap-add SYS_ADMIN
+)
+if docker info | grep -q apparmor; then
+	# AppArmor blocks mount :)
+	securityArgs+=(
+		--security-opt apparmor=unconfined
+	)
+fi
+
+dockerImage='tianon/debuerreotype'
+[ -z "$build" ] || docker build -t "$dockerImage" "$thisDir"
+
+docker run \
+	--rm \
+	"${securityArgs[@]}" \
+	--tmpfs /tmp:dev,exec,suid,noatime \
+	-w /tmp \
+	-e suite="$suite" \
+	-e timestamp="$timestamp" \
+	-e TZ='UTC' -e LC_ALL='C' \
+	"$dockerImage" \
+	bash -Eeuo pipefail -c '
+		set -x
+
+		epoch="$(date --date "$timestamp" +%s)"
+		serial="$(date --date "@$epoch" +%Y%m%d)"
+		exportDir="output"
+		outputDir="$exportDir/$serial"
+		dpkgArch="$(dpkg --print-architecture)"
+
+		{
+			debuerreotype-init rootfs "$suite" "@$epoch"
+
+			debuerreotype-minimizing-config rootfs
+			debuerreotype-apt-get rootfs update -qq
+			debuerreotype-apt-get rootfs dist-upgrade -yqq
+
+			# make a copy of rootfs so we can have a "slim" output too
+			mkdir -p rootfs-slim
+			tar -cC rootfs . | tar -xC rootfs-slim
+
+			# prefer iproute2 if it exists
+			iproute=iproute2
+			if ! debuerreotype-chroot rootfs apt-cache show iproute2 > /dev/null; then
+				# poor wheezy
+				iproute=iproute
+			fi
+
+			debuerreotype-apt-get rootfs install -y --no-install-recommends inetutils-ping $iproute
+
+			debuerreotype-slimify rootfs-slim
+
+			du -hs rootfs rootfs-slim
+
+			for rootfs in rootfs*/; do
+				debuerreotype-gen-sources-list "$rootfs" "$suite" http://deb.debian.org/debian http://security.debian.org
+			done
+
+			mkdir -p "$outputDir"
+			for variant in "" -slim; do
+				targetBase="$outputDir/$suite$variant-$dpkgArch"
+				debuerreotype-tar "rootfs$variant" "$targetBase.tar.xz"
+				debuerreotype-chroot "rootfs$variant" dpkg-query -W > "$targetBase.manifest"
+				touch --no-dereference --date="@$epoch" "$targetBase.manifest"
+			done
+		} >&2
+
+		tar -cC "$exportDir" .
+	' | tar -xvC "$outputDir"
diff --git a/debian/changelog b/debian/changelog
new file mode 100644
index 0000000..38fe859
--- /dev/null
+++ b/debian/changelog
@@ -0,0 +1,5 @@
+debuerreotype (0.1-1) unstable; urgency=medium
+
+  * Initial release
+
+ -- Tianon Gravi <tianon at debian.org>  Mon, 22 May 2017 23:09:20 -0700
diff --git a/debian/compat b/debian/compat
new file mode 100644
index 0000000..ec63514
--- /dev/null
+++ b/debian/compat
@@ -0,0 +1 @@
+9
diff --git a/debian/control b/debian/control
new file mode 100644
index 0000000..4d5de55
--- /dev/null
+++ b/debian/control
@@ -0,0 +1,27 @@
+Source: debuerreotype
+Maintainer: Tianon Gravi <tianon at debian.org>
+Section: admin
+Priority: optional
+Standards-Version: 3.9.8
+Build-Depends: debhelper (>= 9)
+Homepage: https://github.com/debuerreotype/debuerreotype
+Vcs-Browser: https://github.com/debuerreotype/debian-debuerreotype
+Vcs-Git: https://github.com/debuerreotype/debian-debuerreotype.git
+
+Package: debuerreotype
+Architecture: all
+Depends: debian-archive-keyring,
+         debootstrap (>= 1.0.83~),
+         ${misc:Depends}
+Suggests: diffoscope
+Description: reproducible, snapshot-based Debian rootfs builder
+ A set of scripts for building reproducible Debian rootfs tarballs based on
+ snapshot.debian.org, especially for the purposes of Docker base images.
+ .
+ The goal is to create an auditable, reproducible process for creating rootfs
+ tarballs (especially for use in Docker) of Debian releases, based on
+ point-in-time snapshots from snapshot.debian.org.
+ .
+ The only strictly Docker-specific script is debuerreotype-minimizing-config,
+ which applies many configuration tweaks which are useful for Docker users and
+ may or may not be useful outside of that context.
diff --git a/debian/copyright b/debian/copyright
new file mode 100644
index 0000000..5e77206
--- /dev/null
+++ b/debian/copyright
@@ -0,0 +1,31 @@
+Format: http://www.debian.org/doc/packaging-manuals/copyright-format/1.0/
+Upstream-Name: debuerreotype
+Upstream-Contact: Tianon Gravi <tianon at debian.org>
+Source: https://github.com/debuerreotype/debuerreotype
+
+Files: *
+Copyright: 2017 Tianon Gravi <tianon at debian.org>
+License: Expat
+
+Files: debian/*
+Copyright: 2017 Tianon Gravi
+License: Expat
+
+License: Expat
+ Permission is hereby granted, free of charge, to any person obtaining a copy
+ of this software and associated documentation files (the "Software"), to deal
+ in the Software without restriction, including without limitation the rights
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ copies of the Software, and to permit persons to whom the Software is
+ furnished to do so, subject to the following conditions:
+ .
+ The above copyright notice and this permission notice shall be included in
+ all copies or substantial portions of the Software.
+ .
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ SOFTWARE.
diff --git a/debian/debuerreotype.docs b/debian/debuerreotype.docs
new file mode 100644
index 0000000..b43bf86
--- /dev/null
+++ b/debian/debuerreotype.docs
@@ -0,0 +1 @@
+README.md
diff --git a/debian/debuerreotype.install b/debian/debuerreotype.install
new file mode 100644
index 0000000..c9d589e
--- /dev/null
+++ b/debian/debuerreotype.install
@@ -0,0 +1,2 @@
+VERSION usr/share/debuerreotype/
+scripts usr/share/debuerreotype/
diff --git a/debian/gbp.conf b/debian/gbp.conf
new file mode 100644
index 0000000..68e4d73
--- /dev/null
+++ b/debian/gbp.conf
@@ -0,0 +1,3 @@
+[DEFAULT]
+pristine-tar = True
+merge = False
diff --git a/debian/patches/series b/debian/patches/series
new file mode 100644
index 0000000..e69de29
diff --git a/debian/rules b/debian/rules
new file mode 100755
index 0000000..3370a68
--- /dev/null
+++ b/debian/rules
@@ -0,0 +1,9 @@
+#!/usr/bin/make -f
+
+%:
+	dh $@
+
+override_dh_link:
+	set -e; for s in scripts/*; do \
+		dh_link "usr/share/debuerreotype/$$s" "usr/sbin/$$(basename "$$s")"; \
+	done
diff --git a/debian/source/format b/debian/source/format
new file mode 100644
index 0000000..163aaf8
--- /dev/null
+++ b/debian/source/format
@@ -0,0 +1 @@
+3.0 (quilt)
diff --git a/debian/tests/control b/debian/tests/control
new file mode 100644
index 0000000..bfa952a
--- /dev/null
+++ b/debian/tests/control
@@ -0,0 +1,3 @@
+Tests: stretch
+Depends: debuerreotype
+Restrictions: allow-stderr, needs-root
diff --git a/debian/tests/stretch b/debian/tests/stretch
new file mode 100755
index 0000000..271b10a
--- /dev/null
+++ b/debian/tests/stretch
@@ -0,0 +1,23 @@
+#!/usr/bin/env bash
+set -Eeuo pipefail
+
+suite='stretch'
+timestamp='2017-01-01T00:00:00Z'
+
+expectedEpoch='1483228800'
+expectedSha256='426b8ef5a40588c61084cafbb5a187e6a8e1089da34821f314ea3369f90c8931'
+
+rootfs="$(mktemp -d)"
+trap "rm -rf '$rootfs'" EXIT
+
+set -x
+
+debuerreotype-init "$rootfs" "$suite" "$timestamp"
+[ "$(< "$rootfs/debuerreotype-epoch")" = "$expectedEpoch" ]
+
+debuerreotype-chroot "$rootfs" true
+
+debuerreotype-gen-sources-list "$rootfs" "$suite" http://deb.debian.org/debian http://security.debian.org
+
+sha256="$(debuerreotype-tar "$rootfs" - | sha256sum | cut -d' ' -f1)"
+[ "$sha256" = "$expectedSha256" ]
diff --git a/debian/watch b/debian/watch
new file mode 100644
index 0000000..9f3f6ad
--- /dev/null
+++ b/debian/watch
@@ -0,0 +1,3 @@
+version=3
+opts=filenamemangle=s/.+\/v?(\d\S*)\.tar\.gz/debuerreotype-$1\.tar\.gz/ \
+  https://github.com/debuerreotype/debuerreotype/tags .*/v?(\d\S*)\.tar\.gz
diff --git a/scripts/.constants.sh b/scripts/.constants.sh
new file mode 100644
index 0000000..85cc0d5
--- /dev/null
+++ b/scripts/.constants.sh
@@ -0,0 +1,38 @@
+#!/usr/bin/env bash
+
+# constants of the universe
+export TZ='UTC' LC_ALL='C'
+umask 0002
+scriptsDir="$(dirname "$(readlink -f "$BASH_SOURCE")")"
+
+_version() {
+	local v
+	if [ -r "$scriptsDir/../VERSION" ]; then
+		v="$(< "$scriptsDir/../VERSION")"
+	else
+		v='unknown'
+	fi
+	if [ -d "$scriptsDir/../.git" ] && command -v git > /dev/null; then
+		local commit="$(git -C "$scriptsDir" rev-parse --short 'HEAD^{commit}')"
+		v="$v commit $commit"
+	fi
+	echo "$v"
+}
+
+usageStr="$1"
+usageEx="$2"
+self="$(basename "$0")"
+usage() {
+	local v="$(_version)"
+	cat <<-EOU
+		usage: $self $usageStr
+		   ie: $self $usageEx
+
+		debuerreotype version $v
+	EOU
+}
+eusage() {
+	echo >&2 "error: $1"
+	usage >&2
+	exit 1
+}
diff --git a/scripts/.slimify-excludes b/scripts/.slimify-excludes
new file mode 100644
index 0000000..919338f
--- /dev/null
+++ b/scripts/.slimify-excludes
@@ -0,0 +1,10 @@
+#   This file contains the list of files/directories which will be removed for "slim" image variants.
+#  https://github.com/tianon/docker-brew-debian/issues/48
+# https://wiki.ubuntu.com/ReducingDiskFootprint#Drop_unnecessary_files
+/usr/share/doc/*
+/usr/share/groff/*
+/usr/share/info/*
+/usr/share/linda/*
+/usr/share/lintian/*
+/usr/share/locale/*
+/usr/share/man/*
diff --git a/scripts/.snapshot-url.sh b/scripts/.snapshot-url.sh
new file mode 100755
index 0000000..a3d6013
--- /dev/null
+++ b/scripts/.snapshot-url.sh
@@ -0,0 +1,13 @@
+#!/usr/bin/env bash
+set -Eeuo pipefail
+
+thisDir="$(dirname "$(readlink -f "$BASH_SOURCE")")"
+source "$thisDir/.constants.sh" \
+	'<timestamp> [archive]' \
+	'2017-05-08T00:00:00Z debian-security'
+
+timestamp="${1:-}"; shift || eusage 'missing timestamp'
+archive="${1:-debian}"
+
+t="$(date --date "$timestamp" '+%Y%m%dT%H%M%SZ')"
+echo "http://snapshot.debian.org/archive/$archive/$t"
diff --git a/scripts/.tar-exclude b/scripts/.tar-exclude
new file mode 100644
index 0000000..26a7041
--- /dev/null
+++ b/scripts/.tar-exclude
@@ -0,0 +1,19 @@
+# the file we store the "epoch" of a given rootfs in
+./debuerreotype-epoch
+
+./dev/**
+./proc/**
+./sys/**
+
+./var/cache/apt/**
+./var/lib/apt/lists/**
+
+# ends up with host-kernel info
+./etc/apt/apt.conf.d/01autoremove-kernels
+
+# useful data in these, but includes timestamps too
+./var/log/apt/history.log
+./var/log/apt/term.log
+
+# wheezy-only file which contains host-kernel info
+./run/motd.dynamic
diff --git a/scripts/debuerreotype-apt-get b/scripts/debuerreotype-apt-get
new file mode 100755
index 0000000..42f827b
--- /dev/null
+++ b/scripts/debuerreotype-apt-get
@@ -0,0 +1,12 @@
+#!/usr/bin/env bash
+set -Eeuo pipefail
+
+thisDir="$(dirname "$(readlink -f "$BASH_SOURCE")")"
+source "$thisDir/.constants.sh" \
+	'<target-dir> arguments' \
+	'rootfs update'
+
+targetDir="${1:-}"; shift || eusage 'missing target-dir'
+[ -n "$targetDir" ]
+
+"$thisDir/debuerreotype-chroot" "$targetDir" apt-get -o Acquire::Check-Valid-Until=false "$@"
diff --git a/scripts/debuerreotype-chroot b/scripts/debuerreotype-chroot
new file mode 100755
index 0000000..d5e90b9
--- /dev/null
+++ b/scripts/debuerreotype-chroot
@@ -0,0 +1,22 @@
+#!/usr/bin/env bash
+set -Eeuo pipefail
+
+thisDir="$(dirname "$(readlink -f "$BASH_SOURCE")")"
+source "$thisDir/.constants.sh" \
+	'<target-dir> <command> [args...]' \
+	'rootfs apt-get update'
+
+targetDir="${1:-}"; shift || eusage 'missing target-dir'
+cmd="${1:-}"; shift || eusage 'missing command'
+[ -n "$targetDir" ]
+epoch="$(< "$targetDir/debuerreotype-epoch")"
+[ -n "$epoch" ]
+
+export targetDir epoch
+unshare --mount bash -Eeuo pipefail -c '
+	[ -n "$targetDir" ] # just to be safe
+	for dir in dev proc sys; do
+		mount --rbind "/$dir" "$targetDir/$dir"
+	done
+	exec chroot "$targetDir" /usr/bin/env -i PATH="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin" TZ="$TZ" LC_ALL="$LC_ALL" SOURCE_DATE_EPOCH="$epoch" "$@"
+' -- "$cmd" "$@"
diff --git a/scripts/debuerreotype-fixup b/scripts/debuerreotype-fixup
new file mode 100755
index 0000000..d85879d
--- /dev/null
+++ b/scripts/debuerreotype-fixup
@@ -0,0 +1,23 @@
+#!/usr/bin/env bash
+set -Eeuo pipefail
+
+thisDir="$(dirname "$(readlink -f "$BASH_SOURCE")")"
+source "$thisDir/.constants.sh" \
+	'<target-dir>' \
+	'rootfs'
+
+targetDir="${1:-}"; shift || eusage 'missing target-dir'
+[ -n "$targetDir" ]
+epoch="$(< "$targetDir/debuerreotype-epoch")"
+[ -n "$epoch" ]
+
+# https://github.com/lamby/debootstrap/commit/66b15380814aa62ca4b5807270ac57a3c8a0558d#diff-de4eef4ab836e5c6c9c1f820a2f624baR709
+rm -f \
+	"$targetDir/var/log/dpkg.log" \
+	"$targetDir/var/log/bootstrap.log" \
+	"$targetDir/var/log/alternatives.log" \
+	"$targetDir/var/cache/ldconfig/aux-cache"
+
+find "$targetDir" \
+	-newermt "@$epoch" \
+	-exec touch --no-dereference --date="@$epoch" '{}' +
diff --git a/scripts/debuerreotype-gen-sources-list b/scripts/debuerreotype-gen-sources-list
new file mode 100755
index 0000000..f56582e
--- /dev/null
+++ b/scripts/debuerreotype-gen-sources-list
@@ -0,0 +1,31 @@
+#!/usr/bin/env bash
+set -Eeuo pipefail
+
+thisDir="$(dirname "$(readlink -f "$BASH_SOURCE")")"
+source "$thisDir/.constants.sh" \
+	'<target-dir> <suite> <mirror> <secmirror>' \
+	'rootfs stretch http://deb.debian.org/debian http://security.debian.org'
+
+targetDir="${1:-}"; shift || eusage 'missing target-dir'
+suite="${1:-}"; shift || eusage 'missing suite'
+mirror="${1:-}"; shift || eusage 'missing mirror'
+secmirror="${1:-}"; shift || eusage 'missing secmirror'
+[ -n "$targetDir" ]
+
+comp='main'
+
+# https://github.com/tianon/go-aptsources/blob/e066ed9cd8cd9eef7198765bd00ec99679e6d0be/target.go#L16-L58
+{
+	case "$suite" in
+		sid|unstable|testing)
+			echo "deb $mirror $suite $comp"
+			;;
+
+		*)
+			echo "deb $mirror $suite $comp"
+			echo "deb $mirror $suite-updates $comp"
+			echo "deb $secmirror $suite/updates $comp"
+			;;
+	esac
+} > "$targetDir/etc/apt/sources.list"
+chmod 0644 "$targetDir/etc/apt/sources.list"
diff --git a/scripts/debuerreotype-init b/scripts/debuerreotype-init
new file mode 100755
index 0000000..17bd05e
--- /dev/null
+++ b/scripts/debuerreotype-init
@@ -0,0 +1,70 @@
+#!/usr/bin/env bash
+set -Eeuo pipefail
+
+thisDir="$(dirname "$(readlink -f "$BASH_SOURCE")")"
+source "$thisDir/.constants.sh" \
+	'<target-dir> <suite> <timestamp>' \
+	'rootfs stretch 2017-05-08T00:00:00Z'
+
+targetDir="${1:-}"; shift || eusage 'missing target-dir'
+suite="${1:-}"; shift || eusage 'missing suite'
+timestamp="${1:-}"; shift || eusage 'missing timestamp'
+[ -n "$targetDir" ] # must be non-empty
+
+if [ -e "$targetDir" ] && [ -z "$(find "$targetDir" -maxdepth 0 -empty)" ]; then
+	echo >&2 "error: '$targetDir' already exists (and isn't empty)!"
+	exit 1
+fi
+
+epoch="$(date --date "$timestamp" '+%s')"
+export SOURCE_DATE_EPOCH="$epoch"
+
+mirror="$("$thisDir/.snapshot-url.sh" "@$epoch")"
+secmirror="$("$thisDir/.snapshot-url.sh" "@$epoch" 'debian-security')"
+
+debootstrap \
+	--force-check-gpg \
+	--merged-usr \
+	--variant=minbase \
+	"$suite" "$targetDir" "$mirror"
+echo "$epoch" > "$targetDir/debuerreotype-epoch"
+
+"$thisDir/debuerreotype-gen-sources-list" "$targetDir" "$suite" "$mirror" "$secmirror"
+
+# since we're minbase, we know everything included is either essential, or a dependency of essential, so let's get clean "apt-mark showmanual" output
+"$thisDir/debuerreotype-chroot" "$targetDir" apt-mark auto '.*' > /dev/null
+
+echo 'debuerreotype' > "$targetDir/etc/hostname"
+echo "$epoch" \
+	| md5sum \
+	| cut -f1 -d' ' \
+	> "$targetDir/etc/machine-id" # TODO should we only do this if "/etc/machine-id" already exists?
+{
+	echo 'nameserver 8.8.8.8'
+	echo 'nameserver 8.8.4.4'
+} > "$targetDir/etc/resolv.conf"
+chmod 0644 \
+	"$targetDir/etc/hostname" \
+	"$targetDir/etc/machine-id" \
+	"$targetDir/etc/resolv.conf"
+
+# https://bugs.debian.org/857803
+# adjust field 3 in /etc/shadow and /etc/shadow- to $(( epoch / 60 / 60 / 24 )), if it's larger
+sp_lstchg="$(( epoch / 60 / 60 / 24 ))"
+for shadowFile in etc/shadow etc/shadow-; do
+	newShadowFile="$shadowFile.debuerreotype"
+	awk -F ':' \
+		-v OFS=':' \
+		-v sp_lstchg="$sp_lstchg" \
+		'{
+			if ($3 > sp_lstchg) {
+				$3 = sp_lstchg
+			}
+			print
+		}' "$targetDir/$shadowFile" > "$targetDir/$newShadowFile"
+	if [ "$(< "$targetDir/$shadowFile")" != "$(< "$targetDir/$newShadowFile")" ]; then
+		# use "cat" instead of "mv" so permissions don't change
+		cat "$targetDir/$newShadowFile" > "$targetDir/$shadowFile"
+	fi
+	rm -f "$targetDir/$newShadowFile"
+done
diff --git a/scripts/debuerreotype-minimizing-config b/scripts/debuerreotype-minimizing-config
new file mode 100755
index 0000000..1359cc2
--- /dev/null
+++ b/scripts/debuerreotype-minimizing-config
@@ -0,0 +1,112 @@
+#!/usr/bin/env bash
+set -Eeuo pipefail
+
+thisDir="$(dirname "$(readlink -f "$BASH_SOURCE")")"
+source "$thisDir/.constants.sh" \
+	'<target-dir>' \
+	'rootfs'
+
+targetDir="${1:-}"; shift || eusage 'missing target-dir'
+[ -n "$targetDir" ]
+
+# https://github.com/docker/docker/blob/d6f4fe9e38b60f63e429fff7ffced9c26cbf8236/contrib/mkimage/debootstrap#L63-L177
+
+# prevent init scripts from running during install/update
+cat > "$targetDir/usr/sbin/policy-rc.d" <<-'EOF'
+	#!/bin/sh
+
+	# For most Docker users, "apt-get install" only happens during "docker build",
+	# where starting services doesn't work and often fails in humorous ways. This
+	# prevents those failures by stopping the services from attempting to start.
+
+	exit 101
+EOF
+chmod 0755 "$targetDir/usr/sbin/policy-rc.d"
+
+# prevent upstart scripts from running during install/update
+"$thisDir/debuerreotype-chroot" "$targetDir" dpkg-divert --local --rename --add /sbin/initctl > /dev/null
+cp -a "$targetDir/usr/sbin/policy-rc.d" "$targetDir/sbin/initctl"
+sed -i 's/^exit.*/exit 0/' "$targetDir/sbin/initctl"
+# TODO should we only do this if "/sbin/initctl" already exists?
+
+# force dpkg not to call sync() after package extraction (speeding up installs)
+cat > "$targetDir/etc/dpkg/dpkg.cfg.d/docker-apt-speedup" <<-'EOF'
+	# For most Docker users, package installs happen during "docker build", which
+	# doesn't survive power loss and gets restarted clean afterwards anyhow, so
+	# this minor tweak gives us a nice speedup (much nicer on spinning disks,
+	# obviously).
+
+	force-unsafe-io
+EOF
+chmod 0644 "$targetDir/etc/dpkg/dpkg.cfg.d/docker-apt-speedup"
+
+# keep us lean by effectively running "apt-get clean" after every install
+aptGetClean='"rm -f /var/cache/apt/archives/*.deb /var/cache/apt/archives/partial/*.deb /var/cache/apt/*.bin || true";'
+cat > "$targetDir/etc/apt/apt.conf.d/docker-clean" <<-EOF
+	# Since for most Docker users, package installs happen in "docker build" steps,
+	# they essentially become individual layers due to the way Docker handles
+	# layering, especially using CoW filesystems.  What this means for us is that
+	# the caches that APT keeps end up just wasting space in those layers, making
+	# our layers unnecessarily large (especially since we'll normally never use
+	# these caches again and will instead just "docker build" again and make a brand
+	# new image).
+
+	# Ideally, these would just be invoking "apt-get clean", but in our testing,
+	# that ended up being cyclic and we got stuck on APT's lock, so we get this fun
+	# creation that's essentially just "apt-get clean".
+	DPkg::Post-Invoke { $aptGetClean };
+	APT::Update::Post-Invoke { $aptGetClean };
+
+	Dir::Cache::pkgcache "";
+	Dir::Cache::srcpkgcache "";
+
+	# Note that we do realize this isn't the ideal way to do this, and are always
+	# open to better suggestions (https://github.com/debuerreotype/debuerreotype/issues).
+EOF
+chmod 0644 "$targetDir/etc/apt/apt.conf.d/docker-clean"
+
+# remove apt-cache translations for faster "apt-get update"
+cat > "$targetDir/etc/apt/apt.conf.d/docker-no-languages" <<-'EOF'
+	# In Docker, we don't often need the "Translations" files, so we're just wasting
+	# time and space by downloading them, and this inhibits that.  For users that do
+	# need them, it's a simple matter to delete this file and "apt-get update". :)
+
+	Acquire::Languages "none";
+EOF
+chmod 0644 "$targetDir/etc/apt/apt.conf.d/docker-no-languages"
+
+cat > "$targetDir/etc/apt/apt.conf.d/docker-gzip-indexes" <<-'EOF'
+	# Since Docker users using "RUN apt-get update && apt-get install -y ..." in
+	# their Dockerfiles don't go delete the lists files afterwards, we want them to
+	# be as small as possible on-disk, so we explicitly request "gz" versions and
+	# tell Apt to keep them gzipped on-disk.
+
+	# For comparison, an "apt-get update" layer without this on a pristine
+	# "debian:wheezy" base image was "29.88 MB", where with this it was only
+	# "8.273 MB".
+
+	Acquire::GzipIndexes "true";
+	Acquire::CompressionTypes::Order:: "gz";
+EOF
+chmod 0644 "$targetDir/etc/apt/apt.conf.d/docker-gzip-indexes"
+
+# update "autoremove" configuration to be aggressive about removing suggests deps that weren't manually installed
+cat > "$targetDir/etc/apt/apt.conf.d/docker-autoremove-suggests" <<-'EOF'
+	# Since Docker users are looking for the smallest possible final images, the
+	# following emerges as a very common pattern:
+
+	#   RUN apt-get update \
+	#       && apt-get install -y <packages> \
+	#       && <do some compilation work> \
+	#       && apt-get purge -y --auto-remove <packages>
+
+	# By default, APT will actually _keep_ packages installed via Recommends or
+	# Depends if another package Suggests them, even and including if the package
+	# that originally caused them to be installed is removed.  Setting this to
+	# "false" ensures that APT is appropriately aggressive about removing the
+	# packages it added.
+
+	# https://aptitude.alioth.debian.org/doc/en/ch02s05s05.html#configApt-AutoRemove-SuggestsImportant
+	Apt::AutoRemove::SuggestsImportant "false";
+EOF
+chmod 0644 "$targetDir/etc/apt/apt.conf.d/docker-autoremove-suggests"
diff --git a/scripts/debuerreotype-slimify b/scripts/debuerreotype-slimify
new file mode 100755
index 0000000..ca25b2d
--- /dev/null
+++ b/scripts/debuerreotype-slimify
@@ -0,0 +1,61 @@
+#!/usr/bin/env bash
+set -Eeuo pipefail
+
+thisDir="$(dirname "$(readlink -f "$BASH_SOURCE")")"
+source "$thisDir/.constants.sh" \
+	'<target-dir>' \
+	'rootfs'
+
+targetDir="${1:-}"; shift || eusage 'missing target-dir'
+[ -n "$targetDir" ]
+
+IFS=$'\n'; set -o noglob
+slimExcludes=( $(grep -vE '^#|^$' "$thisDir/.slimify-excludes" | sort -u) )
+set +o noglob; unset IFS
+
+dpkgCfgFile="$targetDir/etc/dpkg/dpkg.cfg.d/docker"
+mkdir -p "$(dirname "$dpkgCfgFile")"
+{
+	echo '# This is the "slim" variant of the Debian base image.'
+	echo '# Many files which are normally unnecessary in containers are excluded,'
+	echo '# and this configuration file keeps them that way.'
+} > "$dpkgCfgFile"
+
+neverExclude='/usr/share/doc/*/copyright'
+for slimExclude in "${slimExcludes[@]}"; do
+	{
+		echo
+		echo "# dpkg -S '$slimExclude'"
+		if dpkgOutput="$("$thisDir/debuerreotype-chroot" "$targetDir" dpkg -S "$slimExclude" 2>&1)"; then
+			echo "$dpkgOutput" | sed 's/: .*//g; s/, /\n/g' | sort -u | xargs
+		else
+			echo "$dpkgOutput"
+		fi | fold -w 76 -s | sed 's/^/#  /'
+		echo "path-exclude $slimExclude"
+	} >> "$dpkgCfgFile"
+
+	if [[ "$slimExclude" == *'/*' ]]; then
+		if [ -d "$targetDir/$(dirname "$slimExclude")" ]; then
+			# use two passes so that we don't fail trying to remove directories from $neverExclude
+			"$thisDir/debuerreotype-chroot" "$targetDir" \
+				find "$(dirname "$slimExclude")" \
+					-mindepth 1 \
+					-not -path "$neverExclude" \
+					-not -type d \
+					-delete
+			"$thisDir/debuerreotype-chroot" "$targetDir" \
+				find "$(dirname "$slimExclude")" \
+					-mindepth 1 \
+					-empty \
+					-delete
+		fi
+	else
+		"$thisDir/debuerreotype-chroot" "$targetDir" rm -f "$slimExclude"
+	fi
+done
+{
+	echo
+	echo '# always include these files, especially for license compliance'
+	echo "path-include $neverExclude"
+} >> "$dpkgCfgFile"
+chmod 0644 "$dpkgCfgFile"
diff --git a/scripts/debuerreotype-tar b/scripts/debuerreotype-tar
new file mode 100755
index 0000000..bfc7fad
--- /dev/null
+++ b/scripts/debuerreotype-tar
@@ -0,0 +1,27 @@
+#!/usr/bin/env bash
+set -Eeuo pipefail
+
+thisDir="$(dirname "$(readlink -f "$BASH_SOURCE")")"
+source "$thisDir/.constants.sh" \
+	'<target-dir> <target-tar>' \
+	'rootfs rootfs.tar'
+
+targetDir="${1:-}"; shift || eusage 'missing target-dir'
+[ -n "$targetDir" ]
+targetTar="${1:-}"; shift || eusage 'missing target-tar'
+[ -n "$targetTar" ]
+
+epoch="$(< "$targetDir/debuerreotype-epoch")"
+[ -n "$epoch" ]
+
+"$thisDir/debuerreotype-fixup" "$targetDir"
+tar --create \
+	--file "$targetTar" \
+	--auto-compress \
+	--directory "$targetDir" \
+	--exclude-from "$thisDir/.tar-exclude" \
+	--numeric-owner \
+	--transform 's,^./,,' \
+	--sort name \
+	.
+touch --no-dereference --date="@$epoch" "$targetTar"
diff --git a/scripts/debuerreotype-version b/scripts/debuerreotype-version
new file mode 100755
index 0000000..c1fd4cc
--- /dev/null
+++ b/scripts/debuerreotype-version
@@ -0,0 +1,9 @@
+#!/usr/bin/env bash
+set -Eeuo pipefail
+
+thisDir="$(dirname "$(readlink -f "$BASH_SOURCE")")"
+source "$thisDir/.constants.sh" \
+	'' \
+	''
+
+_version



More information about the Neon-commits mailing list