docker-brew-devuan/update.sh

257 lines
6.7 KiB
Bash
Executable File

#!/bin/bash
set -x
set -eo pipefail
cd "$(readlink -f "$(dirname "$BASH_SOURCE")")"
declare -A codenameCache=()
codename() {
local suite="$1"; shift
if [ -z "${codenameCache[$suite]}" ]; then
local ret="$(curl -fsSL "http://pkgmaster.devuan.org/merged/dists/$suite/Release" | awk -F ': ' '$1 == "Codename" { print $2 }' || true)"
codenameCache[$suite]="${ret:-$suite}"
fi
echo "${codenameCache[$suite]}"
}
declare -A backports=(
[stable]=1
[oldstable]=1
[$(codename stable)]=1
[$(codename oldstable)]=1
)
declare -A unstableSuites=(
[unstable]=1
[testing]=1
[$(codename unstable)]=1
[$(codename testing)]=1
)
declare -A stableSuites=(
[stable]=1
[$(codename stable)]=1
)
versions=( "$@" )
if [ ${#versions[@]} -eq 0 ]; then
branch="$(git describe --contains --all HEAD)"
case "$branch" in
dist-oldstable)
for suite in */; do
suite="${suite%/}"
[ -z "${stableSuites[$suite]}" ] || continue
[ -z "${unstableSuites[$suite]}" ] || continue
versions+=( "$suite" )
done
;;
dist-stable)
for suite in "${!stableSuites[@]}"; do
if [ -d "$suite" ]; then
versions+=( "$suite" )
fi
done
;;
dist-unstable)
for suite in "${!unstableSuites[@]}"; do
if [ -d "$suite" ]; then
versions+=( "$suite" )
fi
done
;;
*)
versions=( */ )
;;
esac
fi
versions=( "${versions[@]%/}" )
get_part() {
dir="$1"
shift
part="$1"
shift
if [ -f "$dir/$part" ]; then
cat "$dir/$part"
return 0
fi
if [ -f "$part" ]; then
cat "$part"
return 0
fi
if [ $# -gt 0 ]; then
echo "$1"
return 0
fi
return 1
}
repo="$(get_part . repo '')"
if [ "$repo" ]; then
origRepo="$repo"
if [[ "$repo" != */* ]]; then
user="$(docker info | awk '/^Username:/ { print $2 }')"
if [ "$user" ]; then
repo="$user/$repo"
fi
fi
fi
latest="$(get_part . latest '')"
for version in "${versions[@]}"; do
dir="$(readlink -f "$version")"
variant="$(get_part "$dir" variant 'minbase')"
components="$(get_part "$dir" components 'main')"
include="$(get_part "$dir" include '')"
arch="$(get_part "$dir" arch '')"
mergedUsr="$(get_part "$dir" merged-usr '')"
suite="$(get_part "$dir" suite "$version")"
mirror="$(get_part "$dir" mirror '')"
script="$(get_part "$dir" script '')"
args=( --dir "$dir" --compression 'xz' debootstrap )
[ -z "$variant" ] || args+=( --variant="$variant" )
[ -z "$components" ] || args+=( --components="$components" )
[ -z "$include" ] || args+=( --include="$include" )
[ -z "$arch" ] || args+=( --arch="$arch" )
[ -z "$mergedUsr" ] || args+=( --merged-usr )
debootstrapVersion="$(debootstrap --version)"
debootstrapVersion="${debootstrapVersion##* }"
if dpkg --compare-versions "$debootstrapVersion" '>=' '1.0.69'; then
args+=( --force-check-gpg )
fi
args+=( "$suite" )
if [ "$mirror" ]; then
args+=( "$mirror" )
if [ "$script" ]; then
args+=( "$script" )
fi
fi
mkimage="$(readlink -f "${MKIMAGE:-"mkimage.sh"}")"
{
echo "$(basename "$mkimage") ${args[*]/"$dir"/.}"
echo
echo 'https://github.com/docker/docker/blob/master/contrib/mkimage.sh'
} > "$dir/build-command.txt"
sudo rm -rf "$dir/rootfs"
sudo nice ionice -c 3 "$mkimage" "${args[@]}" 2>&1 | tee "$dir/build.log"
sudo chown -R "$(id -u):$(id -g)" "$dir"
if [ "$repo" ]; then
( set -x && docker build -t "${repo}:${suite}" "$dir" )
if [ "$suite" != "$version" ]; then
( set -x && docker tag "${repo}:${suite}" "${repo}:${version}" )
fi
if [ "$suite" = "$latest" ]; then
( set -x && docker tag "$repo:$suite" "$repo:latest" )
fi
docker run --rm "${repo}:${suite}" bash -xc '
cat /etc/apt/sources.list
echo
cat /etc/os-release 2>/dev/null
echo
cat /etc/lsb-release 2>/dev/null
echo
cat /etc/debian_version 2>/dev/null
true
'
docker run --rm "${repo}:${suite}" dpkg-query -f '${Package}\t${Version}\n' -W > "$dir/build.manifest"
fi
if [ "${backports[$suite]}" ]; then
mkdir -p "$dir/backports"
echo "FROM $origRepo:$suite" > "$dir/backports/Dockerfile"
cat >> "$dir/backports/Dockerfile" <<-'EOF'
RUN awk '$1 ~ "^deb" { $3 = $3 "-backports"; print; exit }' /etc/apt/sources.list > /etc/apt/sources.list.d/backports.list
EOF
if [ "$repo" ]; then
( set -x && docker build -t "${repo}:${suite}-backports" "$dir/backports" )
fi
fi
IFS=$'\n'
set -o noglob
slimExcludes=( $(get_part "$dir" slim-excludes '' | grep -vE '^#|^$') )
set +o noglob
unset IFS
if [ "${#slimExcludes[@]}" -gt 0 ]; then
sudo rm -rf "$dir/slim/rootfs"
mkdir -p "$dir/slim/rootfs"
sudo tar --extract --file "$dir/rootfs.tar.xz" --directory "$dir/slim/rootfs"
dpkgCfgFile="$dir/slim/rootfs/etc/dpkg/dpkg.cfg.d/docker"
sudo 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.'
} | sudo tee -a "$dpkgCfgFile"
neverExclude='/usr/share/doc/*/copyright'
for slimExclude in "${slimExcludes[@]}"; do
{
echo
echo "# dpkg -S '$slimExclude'"
if dpkgOutput="$(sudo chroot "$dir/slim/rootfs" 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"
} | sudo tee -a "$dpkgCfgFile"
if [[ "$slimExclude" == *'/*' ]]; then
if [ -d "$dir/slim/rootfs/$(dirname "$slimExclude")" ]; then
# use two passes so that we don't fail trying to remove directories from $neverExclude
sudo chroot "$dir/slim/rootfs" \
find "$(dirname "$slimExclude")" \
-mindepth 1 \
-not -path "$neverExclude" \
-not -type d \
-delete
sudo chroot "$dir/slim/rootfs" \
find "$(dirname "$slimExclude")" \
-mindepth 1 \
-empty \
-delete
fi
else
sudo chroot "$dir/slim/rootfs" rm -f "$slimExclude"
fi
done
{
echo
echo '# always include these files, especially for license compliance'
echo "path-include $neverExclude"
} | sudo tee -a "$dpkgCfgFile"
sudo tar --numeric-owner --create --auto-compress --file "$dir/slim/rootfs.tar.xz" --directory "$dir/slim/rootfs" --transform='s,^./,,' .
sudo rm -rf "$dir/slim/rootfs"
cp "$dir/Dockerfile" "$dir/slim/"
sudo chown -R "$(id -u):$(id -g)" "$dir/slim"
ls -lh "$dir/rootfs.tar.xz" "$dir/slim/rootfs.tar.xz"
if [ "$repo" ]; then
( set -x && docker build -t "${repo}:${suite}-slim" "$dir/slim" )
docker images "${repo}:${suite}" | tail -1
docker images "${repo}:${suite}-slim" | tail -1
fi
fi
find "$dir" \
\( \
-name '*.txt' \
-or -name '*.log' \
\) \
-exec sed -i \
-e 's!'"$PWD"'!/«BREWDIR»!g' \
-e 's!'"$(dirname "$mkimage")"'!/«MKIMAGEDIR»!g' \
'{}' +
done