Browse code

Add a ton of simple improvements to contrib/mkimage/debootstrap, especially comments in the extra files put inside the image

This also adds support for squeeze-lts. :)

Docker-DCO-1.1-Signed-off-by: Andrew Page <admwiggin@gmail.com> (github: tianon)

Tianon Gravi authored on 2014/06/21 01:04:48
Showing 2 changed files
... ...
@@ -6,7 +6,7 @@ mkimg="$(basename "$0")"
6 6
 usage() {
7 7
 	echo >&2 "usage: $mkimg [-d dir] [-t tag] script [script-args]"
8 8
 	echo >&2 "   ie: $mkimg -t someuser/debian debootstrap --variant=minbase jessie"
9
-	echo >&2 "       $mkimg -t someuser/ubuntu debootstrap --include=ubuntu-minimal trusty"
9
+	echo >&2 "       $mkimg -t someuser/ubuntu debootstrap --include=ubuntu-minimal --components main,universe trusty"
10 10
 	echo >&2 "       $mkimg -t someuser/busybox busybox-static"
11 11
 	echo >&2 "       $mkimg -t someuser/centos:5 rinse --distribution centos-5"
12 12
 	exit 1
... ...
@@ -23,9 +23,14 @@ shift
23 23
 # now for some Docker-specific tweaks
24 24
 
25 25
 # prevent init scripts from running during install/update
26
-echo >&2 "+ cat > '$rootfsDir/usr/sbin/policy-rc.d'"
26
+echo >&2 "+ echo exit 101 > '$rootfsDir/usr/sbin/policy-rc.d'"
27 27
 cat > "$rootfsDir/usr/sbin/policy-rc.d" <<'EOF'
28 28
 #!/bin/sh
29
+
30
+# For most Docker users, "apt-get install" only happens during "docker build",
31
+# where starting services doesn't work and often fails in humorous ways. This
32
+# prevents those failures by stopping the services from attempting to start.
33
+
29 34
 exit 101
30 35
 EOF
31 36
 chmod +x "$rootfsDir/usr/sbin/policy-rc.d"
... ...
@@ -34,17 +39,25 @@ chmod +x "$rootfsDir/usr/sbin/policy-rc.d"
34 34
 (
35 35
 	set -x
36 36
 	chroot "$rootfsDir" dpkg-divert --local --rename --add /sbin/initctl
37
-	ln -sf /bin/true "$rootfsDir/sbin/initctl"
37
+	cp -a "$rootfsDir/usr/sbin/policy-rc.d" "$rootfsDir/sbin/initctl"
38
+	sed -i 's/^exit.*/exit 0/' "$rootfsDir/sbin/initctl"
38 39
 )
39 40
 
40
-# shrink the image, since apt makes us fat (wheezy: ~157.5MB vs ~120MB)
41
+# shrink a little, since apt makes us cache-fat (wheezy: ~157.5MB vs ~120MB)
41 42
 ( set -x; chroot "$rootfsDir" apt-get clean )
42 43
 
43 44
 # Ubuntu 10.04 sucks... :)
44 45
 if strings "$rootfsDir/usr/bin/dpkg" | grep -q unsafe-io; then
45 46
 	# force dpkg not to call sync() after package extraction (speeding up installs)
46 47
 	echo >&2 "+ echo force-unsafe-io > '$rootfsDir/etc/dpkg/dpkg.cfg.d/docker-apt-speedup'"
47
-	echo 'force-unsafe-io' > "$rootfsDir/etc/dpkg/dpkg.cfg.d/docker-apt-speedup"
48
+	cat > "$rootfsDir/etc/dpkg/dpkg.cfg.d/docker-apt-speedup" <<-'EOF'
49
+	# For most Docker users, package installs happen during "docker build", which
50
+	# doesn't survive power loss and gets restarted clean afterwards anyhow, so
51
+	# this minor tweak gives us a nice speedup (much nicer on spinning disks,
52
+	# obviously).
53
+
54
+	force-unsafe-io
55
+	EOF
48 56
 fi
49 57
 
50 58
 if [ -d "$rootfsDir/etc/apt/apt.conf.d" ]; then
... ...
@@ -52,16 +65,36 @@ if [ -d "$rootfsDir/etc/apt/apt.conf.d" ]; then
52 52
 	aptGetClean='"rm -f /var/cache/apt/archives/*.deb /var/cache/apt/archives/partial/*.deb /var/cache/apt/*.bin || true";'
53 53
 	echo >&2 "+ cat > '$rootfsDir/etc/apt/apt.conf.d/docker-clean'"
54 54
 	cat > "$rootfsDir/etc/apt/apt.conf.d/docker-clean" <<-EOF
55
+		# Since for most Docker users, package installs happen in "docker build" steps,
56
+		# they essentially become individual layers due to the way Docker handles
57
+		# layering, especially using CoW filesystems.  What this means for us is that
58
+		# the caches that APT keeps end up just wasting space in those layers, making
59
+		# our layers unnecessarily large (especially since we'll normally never use
60
+		# these caches again and will instead just "docker build" again and make a brand
61
+		# new image).
62
+
63
+		# Ideally, these would just be invoking "apt-get clean", but in our testing,
64
+		# that ended up being cyclic and we got stuck on APT's lock, so we get this fun
65
+		# creation that's essentially just "apt-get clean".
55 66
 		DPkg::Post-Invoke { ${aptGetClean} };
56 67
 		APT::Update::Post-Invoke { ${aptGetClean} };
57 68
 
58 69
 		Dir::Cache::pkgcache "";
59 70
 		Dir::Cache::srcpkgcache "";
71
+
72
+		# Note that we do realize this isn't the ideal way to do this, and are always
73
+		# open to better suggestions (https://github.com/dotcloud/docker/issues).
60 74
 	EOF
61 75
 
62 76
 	# remove apt-cache translations for fast "apt-get update"
63
-	echo >&2 "+ cat > '$rootfsDir/etc/apt/apt.conf.d/docker-no-languages'"
64
-	echo 'Acquire::Languages "none";' > "$rootfsDir/etc/apt/apt.conf.d/docker-no-languages"
77
+	echo >&2 "+ echo Acquire::Languages 'none' > '$rootfsDir/etc/apt/apt.conf.d/docker-no-languages'"
78
+	cat > "$rootfsDir/etc/apt/apt.conf.d/docker-no-languages" <<-'EOF'
79
+	# In Docker, we don't often need the "Translations" files, so we're just wasting
80
+	# time and space by downloading them, and this inhibits that.  For users that do
81
+	# need them, it's a simple matter to delete this file and "apt-get update". :)
82
+
83
+	Acquire::Languages "none";
84
+	EOF
65 85
 fi
66 86
 
67 87
 if [ -z "$DONT_TOUCH_SOURCES_LIST" ]; then
... ...
@@ -76,39 +109,53 @@ if [ -z "$DONT_TOUCH_SOURCES_LIST" ]; then
76 76
 	if [ -z "$lsbDist" -a -r "$rootfsDir/etc/debian_version" ]; then
77 77
 		lsbDist='Debian'
78 78
 	fi
79
+	# normalize to lowercase for easier matching
80
+	lsbDist="$(echo "$lsbDist" | tr '[:upper:]' '[:lower:]')"
79 81
 	case "$lsbDist" in
80
-		debian|Debian)
82
+		debian)
81 83
 			# updates and security!
82 84
 			if [ "$suite" != 'sid' -a "$suite" != 'unstable' ]; then
83 85
 				(
84 86
 					set -x
85
-					sed -i "p; s/ $suite main$/ ${suite}-updates main/" "$rootfsDir/etc/apt/sources.list"
87
+					sed -i "
88
+						p;
89
+						s/ $suite / ${suite}-updates /
90
+					" "$rootfsDir/etc/apt/sources.list"
86 91
 					echo "deb http://security.debian.org $suite/updates main" >> "$rootfsDir/etc/apt/sources.list"
92
+					# LTS
93
+					if [ "$suite" = 'squeeze' ]; then
94
+						head -1 "$rootfsDir/etc/apt/sources.list" \
95
+							| sed "s/ $suite / ${suite}-lts /" \
96
+								>> "$rootfsDir/etc/apt/sources.list"
97
+					fi
87 98
 				)
88 99
 			fi
89 100
 			;;
90
-		ubuntu|Ubuntu)
91
-			# add the universe, updates, and security repositories
101
+		ubuntu)
102
+			# add the updates and security repositories
92 103
 			(
93 104
 				set -x
94 105
 				sed -i "
95
-					s/ $suite main$/ $suite main universe/; p;
96
-					s/ $suite main/ ${suite}-updates main/; p;
97
-					s/ $suite-updates main/ ${suite}-security main/
106
+					p;
107
+					s/ $suite / ${suite}-updates /; p;
108
+					s/ $suite-updates / ${suite}-security /
98 109
 				" "$rootfsDir/etc/apt/sources.list"
99 110
 			)
100 111
 			;;
101
-		tanglu|Tanglu)
112
+		tanglu)
102 113
 			# add the updates repository
103 114
 			if [ "$suite" != 'devel' ]; then
104 115
 				(
105 116
 					set -x
106
-					sed -i "p; s/ $suite main$/ ${suite}-updates main/" "$rootfsDir/etc/apt/sources.list"
117
+					sed -i "
118
+						p;
119
+						s/ $suite / ${suite}-updates /
120
+					" "$rootfsDir/etc/apt/sources.list"
107 121
 				)
108 122
 			fi
109 123
 			;;
110
-		steamos|SteamOS)
111
-			# add contrib and non-free
124
+		steamos)
125
+			# add contrib and non-free if "main" is the only component
112 126
 			(
113 127
 				set -x
114 128
 				sed -i "s/ $suite main$/ $suite main contrib non-free/" "$rootfsDir/etc/apt/sources.list"