257 lines
6.7 KiB
Bash
Executable File
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
|