These new scripts are streamlined such that, for example, "contrib/mkimage/debootstrap" is _only_ responsible for filling a directory with the results of running debootstrap, and it can accept any arbitrary arguments.
Docker-DCO-1.1-Signed-off-by: Andrew Page <admwiggin@gmail.com> (github: tianon)
| 1 | 1 |
new file mode 100755 |
| ... | ... |
@@ -0,0 +1,105 @@ |
| 0 |
+#!/usr/bin/env bash |
|
| 1 |
+set -e |
|
| 2 |
+ |
|
| 3 |
+mkimg="$(basename "$0")" |
|
| 4 |
+ |
|
| 5 |
+usage() {
|
|
| 6 |
+ echo >&2 "usage: $mkimg [-d dir] [-t tag] script [script-args]" |
|
| 7 |
+ echo >&2 " ie: $mkimg -t someuser/debian debootstrap --variant=minbase jessie" |
|
| 8 |
+ echo >&2 " $mkimg -t someuser/ubuntu debootstrap --include=ubuntu-minimal trusty" |
|
| 9 |
+ echo >&2 " $mkimg -t someuser/busybox busybox-static" |
|
| 10 |
+ echo >&2 " $mkimg -t someuser/centos:5 rinse --distribution centos-5" |
|
| 11 |
+ exit 1 |
|
| 12 |
+} |
|
| 13 |
+ |
|
| 14 |
+scriptDir="$(dirname "$(readlink -f "$BASH_SOURCE")")/mkimage" |
|
| 15 |
+ |
|
| 16 |
+optTemp=$(getopt --options '+d:t:h' --longoptions 'dir:,tag:,help' --name "$mkimg" -- "$@") |
|
| 17 |
+eval set -- "$optTemp" |
|
| 18 |
+unset optTemp |
|
| 19 |
+ |
|
| 20 |
+dir= |
|
| 21 |
+tag= |
|
| 22 |
+while true; do |
|
| 23 |
+ case "$1" in |
|
| 24 |
+ -d|--dir) dir="$2" ; shift 2 ;; |
|
| 25 |
+ -t|--tag) tag="$2" ; shift 2 ;; |
|
| 26 |
+ -h|--help) usage ;; |
|
| 27 |
+ --) shift ; break ;; |
|
| 28 |
+ esac |
|
| 29 |
+done |
|
| 30 |
+ |
|
| 31 |
+script="$1" |
|
| 32 |
+[ "$script" ] || usage |
|
| 33 |
+shift |
|
| 34 |
+ |
|
| 35 |
+if [ ! -x "$scriptDir/$script" ]; then |
|
| 36 |
+ echo >&2 "error: $script does not exist or is not executable" |
|
| 37 |
+ echo >&2 " see $scriptDir for possible scripts" |
|
| 38 |
+ exit 1 |
|
| 39 |
+fi |
|
| 40 |
+ |
|
| 41 |
+# don't mistake common scripts like .febootstrap-minimize as image-creators |
|
| 42 |
+if [[ "$script" == .* ]]; then |
|
| 43 |
+ echo >&2 "error: $script is a script helper, not a script" |
|
| 44 |
+ echo >&2 " see $scriptDir for possible scripts" |
|
| 45 |
+ exit 1 |
|
| 46 |
+fi |
|
| 47 |
+ |
|
| 48 |
+delDir= |
|
| 49 |
+if [ -z "$dir" ]; then |
|
| 50 |
+ dir="$(mktemp -d ${TMPDIR:-/tmp}/docker-mkimage.XXXXXXXXXX)"
|
|
| 51 |
+ delDir=1 |
|
| 52 |
+fi |
|
| 53 |
+ |
|
| 54 |
+rootfsDir="$dir/rootfs" |
|
| 55 |
+( set -x; mkdir -p "$rootfsDir" ) |
|
| 56 |
+ |
|
| 57 |
+# pass all remaining arguments to $script |
|
| 58 |
+"$scriptDir/$script" "$rootfsDir" "$@" |
|
| 59 |
+ |
|
| 60 |
+# Docker mounts tmpfs at /dev and procfs at /proc so we can remove them |
|
| 61 |
+rm -rf "$rootfsDir/dev" "$rootfsDir/proc" |
|
| 62 |
+mkdir -p "$rootfsDir/dev" "$rootfsDir/proc" |
|
| 63 |
+ |
|
| 64 |
+# make sure /etc/resolv.conf has something useful in it |
|
| 65 |
+mkdir -p "$rootfsDir/etc" |
|
| 66 |
+cat > "$rootfsDir/etc/resolv.conf" <<'EOF' |
|
| 67 |
+nameserver 8.8.8.8 |
|
| 68 |
+nameserver 8.8.4.4 |
|
| 69 |
+EOF |
|
| 70 |
+ |
|
| 71 |
+tarFile="$dir/rootfs.tar.xz" |
|
| 72 |
+touch "$tarFile" |
|
| 73 |
+ |
|
| 74 |
+( |
|
| 75 |
+ set -x |
|
| 76 |
+ tar --numeric-owner -caf "$tarFile" -C "$rootfsDir" --transform='s,^./,,' . |
|
| 77 |
+) |
|
| 78 |
+ |
|
| 79 |
+echo >&2 "+ cat > '$dir/Dockerfile'" |
|
| 80 |
+cat > "$dir/Dockerfile" <<'EOF' |
|
| 81 |
+FROM scratch |
|
| 82 |
+ADD rootfs.tar.xz / |
|
| 83 |
+EOF |
|
| 84 |
+ |
|
| 85 |
+# if our generated image has a decent shell, let's set a default command |
|
| 86 |
+for shell in /bin/bash /usr/bin/fish /usr/bin/zsh /bin/sh; do |
|
| 87 |
+ if [ -x "$rootfsDir/$shell" ]; then |
|
| 88 |
+ ( set -x; echo 'CMD ["'"$shell"'"]' >> "$dir/Dockerfile" ) |
|
| 89 |
+ break |
|
| 90 |
+ fi |
|
| 91 |
+done |
|
| 92 |
+ |
|
| 93 |
+( set -x; rm -rf "$rootfsDir" ) |
|
| 94 |
+ |
|
| 95 |
+if [ "$tag" ]; then |
|
| 96 |
+ ( set -x; docker build -t "$tag" "$dir" ) |
|
| 97 |
+elif [ "$delDir" ]; then |
|
| 98 |
+ # if we didn't specify a tag and we're going to delete our dir, let's just build an untagged image so that we did _something_ |
|
| 99 |
+ ( set -x; docker build "$dir" ) |
|
| 100 |
+fi |
|
| 101 |
+ |
|
| 102 |
+if [ "$delDir" ]; then |
|
| 103 |
+ ( set -x; rm -rf "$dir" ) |
|
| 104 |
+fi |
| 0 | 105 |
new file mode 100755 |
| ... | ... |
@@ -0,0 +1,28 @@ |
| 0 |
+#!/usr/bin/env bash |
|
| 1 |
+set -e |
|
| 2 |
+ |
|
| 3 |
+rootfsDir="$1" |
|
| 4 |
+shift |
|
| 5 |
+ |
|
| 6 |
+( |
|
| 7 |
+ cd "$rootfsDir" |
|
| 8 |
+ |
|
| 9 |
+ # effectively: febootstrap-minimize --keep-zoneinfo --keep-rpmdb --keep-services "$target" |
|
| 10 |
+ # locales |
|
| 11 |
+ rm -rf usr/{{lib,share}/locale,{lib,lib64}/gconv,bin/localedef,sbin/build-locale-archive}
|
|
| 12 |
+ # docs |
|
| 13 |
+ rm -rf usr/share/{man,doc,info,gnome/help}
|
|
| 14 |
+ # cracklib |
|
| 15 |
+ #rm -rf usr/share/cracklib |
|
| 16 |
+ # i18n |
|
| 17 |
+ rm -rf usr/share/i18n |
|
| 18 |
+ # yum cache |
|
| 19 |
+ rm -rf var/cache/yum |
|
| 20 |
+ mkdir -p --mode=0755 var/cache/yum |
|
| 21 |
+ # sln |
|
| 22 |
+ rm -rf sbin/sln |
|
| 23 |
+ # ldconfig |
|
| 24 |
+ #rm -rf sbin/ldconfig |
|
| 25 |
+ rm -rf etc/ld.so.cache var/cache/ldconfig |
|
| 26 |
+ mkdir -p --mode=0755 var/cache/ldconfig |
|
| 27 |
+) |
| 0 | 28 |
new file mode 100755 |
| ... | ... |
@@ -0,0 +1,34 @@ |
| 0 |
+#!/usr/bin/env bash |
|
| 1 |
+set -e |
|
| 2 |
+ |
|
| 3 |
+rootfsDir="$1" |
|
| 4 |
+shift |
|
| 5 |
+ |
|
| 6 |
+busybox="$(which busybox 2>/dev/null || true)" |
|
| 7 |
+if [ -z "$busybox" ]; then |
|
| 8 |
+ echo >&2 'error: busybox: not found' |
|
| 9 |
+ echo >&2 ' install it with your distribution "busybox-static" package' |
|
| 10 |
+ exit 1 |
|
| 11 |
+fi |
|
| 12 |
+if ! ldd "$busybox" 2>&1 | grep -q 'not a dynamic executable'; then |
|
| 13 |
+ echo >&2 "error: '$busybox' appears to be a dynamic executable" |
|
| 14 |
+ echo >&2 ' you should install your distribution "busybox-static" package instead' |
|
| 15 |
+ exit 1 |
|
| 16 |
+fi |
|
| 17 |
+ |
|
| 18 |
+mkdir -p "$rootfsDir/bin" |
|
| 19 |
+rm -f "$rootfsDir/bin/busybox" # just in case |
|
| 20 |
+cp "$busybox" "$rootfsDir/bin/busybox" |
|
| 21 |
+ |
|
| 22 |
+( |
|
| 23 |
+ cd "$rootfsDir" |
|
| 24 |
+ |
|
| 25 |
+ IFS=$'\n' |
|
| 26 |
+ modules=( $(bin/busybox --list-modules) ) |
|
| 27 |
+ unset IFS |
|
| 28 |
+ |
|
| 29 |
+ for module in "${modules[@]}"; do
|
|
| 30 |
+ mkdir -p "$(dirname "$module")" |
|
| 31 |
+ ln -sf /bin/busybox "$module" |
|
| 32 |
+ done |
|
| 33 |
+) |
| 0 | 34 |
new file mode 100755 |
| ... | ... |
@@ -0,0 +1,125 @@ |
| 0 |
+#!/usr/bin/env bash |
|
| 1 |
+set -e |
|
| 2 |
+ |
|
| 3 |
+rootfsDir="$1" |
|
| 4 |
+shift |
|
| 5 |
+ |
|
| 6 |
+# we have to do a little fancy footwork to make sure "rootfsDir" becomes the second non-option argument to debootstrap |
|
| 7 |
+ |
|
| 8 |
+before=() |
|
| 9 |
+while [ $# -gt 0 ] && [[ "$1" == -* ]]; do |
|
| 10 |
+ before+=( "$1" ) |
|
| 11 |
+ shift |
|
| 12 |
+done |
|
| 13 |
+ |
|
| 14 |
+suite="$1" |
|
| 15 |
+shift |
|
| 16 |
+ |
|
| 17 |
+( |
|
| 18 |
+ set -x |
|
| 19 |
+ debootstrap "${before[@]}" "$suite" "$rootfsDir" "$@"
|
|
| 20 |
+) |
|
| 21 |
+ |
|
| 22 |
+# now for some Docker-specific tweaks |
|
| 23 |
+ |
|
| 24 |
+# prevent init scripts from running during install/update |
|
| 25 |
+echo >&2 "+ cat > '$rootfsDir/usr/sbin/policy-rc.d'" |
|
| 26 |
+cat > "$rootfsDir/usr/sbin/policy-rc.d" <<'EOF' |
|
| 27 |
+#!/bin/sh |
|
| 28 |
+exit 101 |
|
| 29 |
+EOF |
|
| 30 |
+chmod +x "$rootfsDir/usr/sbin/policy-rc.d" |
|
| 31 |
+ |
|
| 32 |
+# prevent upstart scripts from running during install/update |
|
| 33 |
+( |
|
| 34 |
+ set -x |
|
| 35 |
+ chroot "$rootfsDir" dpkg-divert --local --rename --add /sbin/initctl |
|
| 36 |
+ ln -sf /bin/true "$rootfsDir/sbin/initctl" |
|
| 37 |
+) |
|
| 38 |
+ |
|
| 39 |
+# shrink the image, since apt makes us fat (wheezy: ~157.5MB vs ~120MB) |
|
| 40 |
+( set -x; chroot "$rootfsDir" apt-get clean ) |
|
| 41 |
+ |
|
| 42 |
+# Ubuntu 10.04 sucks... :) |
|
| 43 |
+if strings "$rootfsDir/usr/bin/dpkg" | grep -q unsafe-io; then |
|
| 44 |
+ # force dpkg not to call sync() after package extraction (speeding up installs) |
|
| 45 |
+ echo >&2 "+ echo force-unsafe-io > '$rootfsDir/etc/dpkg/dpkg.cfg.d/docker-apt-speedup'" |
|
| 46 |
+ echo 'force-unsafe-io' > "$rootfsDir/etc/dpkg/dpkg.cfg.d/docker-apt-speedup" |
|
| 47 |
+fi |
|
| 48 |
+ |
|
| 49 |
+if [ -d /etc/apt/apt.conf.d ]; then |
|
| 50 |
+ # _keep_ us lean by effectively running "apt-get clean" after every install |
|
| 51 |
+ aptGetClean='"rm -f /var/cache/apt/archives/*.deb /var/cache/apt/archives/partial/*.deb /var/cache/apt/*.bin || true";' |
|
| 52 |
+ echo >&2 "+ cat > '$rootfsDir/etc/apt/apt.conf.d/docker-clean'" |
|
| 53 |
+ cat > "$rootfsDir/etc/apt/apt.conf.d/docker-clean" <<-EOF |
|
| 54 |
+ DPkg::Post-Invoke { ${aptGetClean} };
|
|
| 55 |
+ APT::Update::Post-Invoke { ${aptGetClean} };
|
|
| 56 |
+ |
|
| 57 |
+ Dir::Cache::pkgcache ""; |
|
| 58 |
+ Dir::Cache::srcpkgcache ""; |
|
| 59 |
+ EOF |
|
| 60 |
+ |
|
| 61 |
+ # remove apt-cache translations for fast "apt-get update" |
|
| 62 |
+ echo >&2 "+ cat > '$rootfsDir/etc/apt/apt.conf.d/docker-no-languages'" |
|
| 63 |
+ echo 'Acquire::Languages "none";' > "$rootfsDir/etc/apt/apt.conf.d/docker-no-languages" |
|
| 64 |
+fi |
|
| 65 |
+ |
|
| 66 |
+if [ -z "$DONT_TOUCH_SOURCES_LIST" ]; then |
|
| 67 |
+ # tweak sources.list, where appropriate |
|
| 68 |
+ lsbDist= |
|
| 69 |
+ if [ -z "$lsbDist" -a -r "$rootfsDir/etc/os-release" ]; then |
|
| 70 |
+ lsbDist="$(. "$rootfsDir/etc/os-release" && echo "$ID")" |
|
| 71 |
+ fi |
|
| 72 |
+ if [ -z "$lsbDist" -a -r "$rootfsDir/etc/lsb-release" ]; then |
|
| 73 |
+ lsbDist="$(. "$rootfsDir/etc/lsb-release" && echo "$DISTRIB_ID")" |
|
| 74 |
+ fi |
|
| 75 |
+ if [ -z "$lsbDist" -a -r "$rootfsDir/etc/debian_version" ]; then |
|
| 76 |
+ lsbDist='Debian' |
|
| 77 |
+ fi |
|
| 78 |
+ case "$lsbDist" in |
|
| 79 |
+ debian|Debian) |
|
| 80 |
+ # updates and security! |
|
| 81 |
+ if [ "$suite" != 'sid' -a "$suite" != 'unstable' ]; then |
|
| 82 |
+ ( |
|
| 83 |
+ set -x |
|
| 84 |
+ sed -i "p; s/ $suite main$/ ${suite}-updates main/" "$rootfsDir/etc/apt/sources.list"
|
|
| 85 |
+ echo "deb http://security.debian.org $suite/updates main" >> "$rootfsDir/etc/apt/sources.list" |
|
| 86 |
+ ) |
|
| 87 |
+ fi |
|
| 88 |
+ ;; |
|
| 89 |
+ ubuntu|Ubuntu) |
|
| 90 |
+ # add the universe, updates, and security repositories |
|
| 91 |
+ ( |
|
| 92 |
+ set -x |
|
| 93 |
+ sed -i " |
|
| 94 |
+ s/ $suite main$/ $suite main universe/; p; |
|
| 95 |
+ s/ $suite main/ ${suite}-updates main/; p;
|
|
| 96 |
+ s/ $suite-updates main/ ${suite}-security main/
|
|
| 97 |
+ " "$rootfsDir/etc/apt/sources.list" |
|
| 98 |
+ ) |
|
| 99 |
+ ;; |
|
| 100 |
+ tanglu|Tanglu) |
|
| 101 |
+ # add the updates repository |
|
| 102 |
+ if [ "$suite" != 'devel' ]; then |
|
| 103 |
+ ( |
|
| 104 |
+ set -x |
|
| 105 |
+ sed -i "p; s/ $suite main$/ ${suite}-updates main/" "$rootfsDir/etc/apt/sources.list"
|
|
| 106 |
+ ) |
|
| 107 |
+ fi |
|
| 108 |
+ ;; |
|
| 109 |
+ steamos|SteamOS) |
|
| 110 |
+ # add contrib and non-free |
|
| 111 |
+ ( |
|
| 112 |
+ set -x |
|
| 113 |
+ sed -i "s/ $suite main$/ $suite main contrib non-free/" "$rootfsDir/etc/apt/sources.list" |
|
| 114 |
+ ) |
|
| 115 |
+ ;; |
|
| 116 |
+ esac |
|
| 117 |
+fi |
|
| 118 |
+ |
|
| 119 |
+# make sure we're fully up-to-date, too |
|
| 120 |
+( |
|
| 121 |
+ set -x |
|
| 122 |
+ chroot "$rootfsDir" apt-get update |
|
| 123 |
+ chroot "$rootfsDir" apt-get dist-upgrade -y |
|
| 124 |
+) |
| 0 | 125 |
new file mode 100755 |
| ... | ... |
@@ -0,0 +1,25 @@ |
| 0 |
+#!/usr/bin/env bash |
|
| 1 |
+set -e |
|
| 2 |
+ |
|
| 3 |
+rootfsDir="$1" |
|
| 4 |
+shift |
|
| 5 |
+ |
|
| 6 |
+# specifying --arch below is safe because "$@" can override it and the "latest" one wins :) |
|
| 7 |
+ |
|
| 8 |
+( |
|
| 9 |
+ set -x |
|
| 10 |
+ rinse --directory "$rootfsDir" --arch amd64 "$@" |
|
| 11 |
+) |
|
| 12 |
+ |
|
| 13 |
+"$(dirname "$BASH_SOURCE")/.febootstrap-minimize" "$rootfsDir" |
|
| 14 |
+ |
|
| 15 |
+if [ -d "$rootfsDir/etc/sysconfig" ]; then |
|
| 16 |
+ # allow networking init scripts inside the container to work without extra steps |
|
| 17 |
+ echo 'NETWORKING=yes' > "$rootfsDir/etc/sysconfig/network" |
|
| 18 |
+fi |
|
| 19 |
+ |
|
| 20 |
+# make sure we're fully up-to-date, too |
|
| 21 |
+( |
|
| 22 |
+ set -x |
|
| 23 |
+ chroot "$rootfsDir" yum update -y |
|
| 24 |
+) |