diff options
Diffstat (limited to 'src')
-rwxr-xr-x | src/selfstrap | 257 |
1 files changed, 136 insertions, 121 deletions
diff --git a/src/selfstrap b/src/selfstrap index 165a921..fc2ae5d 100755 --- a/src/selfstrap +++ b/src/selfstrap | |||
@@ -1,15 +1,50 @@ | |||
1 | #!/bin/bash | 1 | #!/bin/bash |
2 | debian_mirror=http://httpredir.debian.org/debian | 2 | debian_mirror=http://httpredir.debian.org/debian |
3 | 3 | EXTRA_PACKAGES='apt debian-archive-keyring locales' | |
4 | if [ $# = 1 ]; then | ||
5 | rootfs=$1 | ||
6 | else | ||
7 | echo "Usage: $0 <target directory>" >&2 | ||
8 | exit 1 | ||
9 | fi | ||
10 | 4 | ||
11 | die() { printf 'Error: %s\n' "$*"; exit 1; } | 5 | die() { printf 'Error: %s\n' "$*"; exit 1; } |
12 | 6 | ||
7 | usage() | ||
8 | { | ||
9 | echo "Usage: $0 -t <target directory> [options] [packages]" >&2 | ||
10 | cat <<EOF | ||
11 | Options: | ||
12 | --target|-t (Mandatory) Target directory | ||
13 | --help|-h | ||
14 | --verbose|-v | ||
15 | --unpack Only unpack; do not configure | ||
16 | --chroot=<prog> Use prog for chroot command | ||
17 | --packages=<file> Text file contains names of packages to install | ||
18 | --real-apt Use 'apt-get install' to install packages | ||
19 | EOF | ||
20 | exit ${1:-1} | ||
21 | } | ||
22 | |||
23 | GETOPT=$(getopt -n "${0##*/}" -o t:hv --long help,target:,verbose,unpack,chroot:,packages:,real-apt -- "$@") || exit | ||
24 | eval set -- "$GETOPT" | ||
25 | while [ $# -gt 0 ]; do | ||
26 | case "$1" in | ||
27 | -t|--target) TARGET=$2; shift ;; | ||
28 | -h|--help) usage 0 ;; | ||
29 | -v|--verbose) VERBOSE=y ;; | ||
30 | --unpack) UNPACK_ONLY=y; die 'unimplemented' ;; | ||
31 | --packages) x=$(cat < "$2") || die "could not read file '$2'" | ||
32 | EXTRA_PACKAGES="$EXTRA_PACKAGES $x" | ||
33 | shift ;; | ||
34 | --chroot) CHROOT_PROG=$2; shift ;; | ||
35 | --real-apt) REAL_APT_INSTALL=y ;; | ||
36 | --) shift; break ;; | ||
37 | *) usage 1 ;; | ||
38 | esac | ||
39 | shift | ||
40 | done | ||
41 | |||
42 | [ "$TARGET" ] || usage | ||
43 | |||
44 | ! [ "$REAL_APT_INSTALL" -a "$UNPACK_ONLY" ] || die "option --real-apt is incompatible with option --unpack" | ||
45 | |||
46 | EXTRA_PACKAGES="$EXTRA_PACKAGES $*" | ||
47 | |||
13 | am_root() { [ "$(id -u)" = 0 ]; } | 48 | am_root() { [ "$(id -u)" = 0 ]; } |
14 | 49 | ||
15 | current_debian_codename() | 50 | current_debian_codename() |
@@ -21,9 +56,9 @@ current_debian_codename() | |||
21 | sanity_checks() | 56 | sanity_checks() |
22 | { | 57 | { |
23 | am_root || die 'you are not root' | 58 | am_root || die 'you are not root' |
24 | rootfs=$(realpath "$rootfs") || die 'realpath failed' | 59 | TARGET=$(realpath "$TARGET") || die 'realpath failed' |
25 | [ "$rootfs" ] || die 'no $rootfs' | 60 | [ "$TARGET" ] || die 'no $TARGET' |
26 | [ -d "$rootfs" ] || mkdir "$rootfs" || die 'could not mkdir($rootfs)' | 61 | [ -d "$TARGET" ] || mkdir "$TARGET" || die 'could not mkdir($TARGET)' |
27 | } | 62 | } |
28 | 63 | ||
29 | generate_apt_config() | 64 | generate_apt_config() |
@@ -31,32 +66,37 @@ generate_apt_config() | |||
31 | APT_CONFIG=$(mktemp) || exit | 66 | APT_CONFIG=$(mktemp) || exit |
32 | chmod 644 "$APT_CONFIG" | 67 | chmod 644 "$APT_CONFIG" |
33 | cat > "$APT_CONFIG" <<EOF | 68 | cat > "$APT_CONFIG" <<EOF |
34 | Dir::Etc "${rootfs}/etc/apt/"; | 69 | Dir::Etc "${TARGET}/etc/apt/"; |
35 | Dir::Etc::Parts "${rootfs}/etc/apt/apt.conf.d/"; | 70 | Dir::Etc::Parts "${TARGET}/etc/apt/apt.conf.d/"; |
36 | Dir::Etc::PreferencesParts "${rootfs}/etc/apt/preferences.d/"; | 71 | Dir::Etc::PreferencesParts "${TARGET}/etc/apt/preferences.d/"; |
37 | EOF | 72 | EOF |
38 | export APT_CONFIG | 73 | export APT_CONFIG |
39 | } | 74 | } |
40 | 75 | ||
41 | apt_get() | 76 | apt_() |
42 | { | 77 | { |
43 | [ "$rootfs" ] || die 'no $rootfs' | 78 | local apt_cmd="$1" |
79 | shift | ||
80 | |||
81 | [ "$TARGET" ] || die 'no $TARGET' | ||
44 | [ "$APT_CONFIG" ] || die 'no $APT_CONFIG' | 82 | [ "$APT_CONFIG" ] || die 'no $APT_CONFIG' |
45 | 83 | ||
46 | visible_args="$*" | 84 | if [ "$VERBOSE" ]; then |
85 | printf "+ apt-${apt_cmd} %s\n" "$*" >&2 | ||
86 | fi | ||
47 | 87 | ||
48 | set -- -o Apt::Install-Recommends=false "$@" | 88 | set -- -o Apt::Install-Recommends=false "$@" |
49 | 89 | ||
50 | # Set various paths to within the created system. | 90 | # Set various paths to within the created system. |
51 | set -- -o Apt::Architecture="$rootfs_arch" "$@" | 91 | set -- -o Apt::Architecture="$target_arch" "$@" |
52 | set -- -o Apt::Default-Release="$release" "$@" | 92 | set -- -o Apt::Default-Release="$target_release" "$@" |
53 | set -- -o Dir="$rootfs" "$@" | 93 | set -- -o Dir="$TARGET" "$@" |
54 | set -- -o Dir::Cache="$rootfs"/var/cache/apt/ "$@" | 94 | set -- -o Dir::Cache="$TARGET"/var/cache/apt/ "$@" |
55 | set -- -o Dir::Etc::Parts="$rootfs"/etc/apt/apt.conf.d/ "$@" | 95 | set -- -o Dir::Etc::Parts="$TARGET"/etc/apt/apt.conf.d/ "$@" |
56 | set -- -o Dir::Etc::PreferencesParts="$rootfs"/etc/apt/preferences.d/ "$@" | 96 | set -- -o Dir::Etc::PreferencesParts="$TARGET"/etc/apt/preferences.d/ "$@" |
57 | set -- -o Dir::Etc="$rootfs"/etc/apt/ "$@" | 97 | set -- -o Dir::Etc="$TARGET"/etc/apt/ "$@" |
58 | set -- -o Dir::State="$rootfs"/var/lib/apt/ "$@" | 98 | set -- -o Dir::State="$TARGET"/var/lib/apt/ "$@" |
59 | set -- -o Dir::State::Status="$rootfs"/var/lib/dpkg/status "$@" | 99 | set -- -o Dir::State::Status="$TARGET"/var/lib/dpkg/status "$@" |
60 | 100 | ||
61 | # We must also set dpkg to use the created system. | 101 | # We must also set dpkg to use the created system. |
62 | # Dpkg::options requires undocumented apt CLI magic. | 102 | # Dpkg::options requires undocumented apt CLI magic. |
@@ -65,7 +105,7 @@ apt_get() | |||
65 | set -- -o DPkg::options::arg0=--debug="${DEBUG_DPKG}" "$@" | 105 | set -- -o DPkg::options::arg0=--debug="${DEBUG_DPKG}" "$@" |
66 | fi | 106 | fi |
67 | # This is the important one: | 107 | # This is the important one: |
68 | set -- -o DPkg::options::arg1=--root="$rootfs" "$@" | 108 | set -- -o DPkg::options::arg1=--root="$TARGET" "$@" |
69 | set -- -o DPkg::options::arg2=--force-unsafe-io "$@" | 109 | set -- -o DPkg::options::arg2=--force-unsafe-io "$@" |
70 | 110 | ||
71 | # Use the calling system for these. This is an optimization. | 111 | # Use the calling system for these. This is an optimization. |
@@ -77,10 +117,10 @@ apt_get() | |||
77 | # Avoid deleting lists on the calling system. | 117 | # Avoid deleting lists on the calling system. |
78 | set -- -o APT::Get::List-Cleanup=false "$@" | 118 | set -- -o APT::Get::List-Cleanup=false "$@" |
79 | 119 | ||
80 | [ "$VERBOSE" ] && printf '+ apt-get %s\n' "$visible_args" >&2 || true | 120 | apt-"${apt_cmd}" "$@" |
81 | |||
82 | apt-get "$@" | ||
83 | } | 121 | } |
122 | apt_get() { apt_ get "$@"; } | ||
123 | apt_cache() { apt_ cache "$@"; } | ||
84 | 124 | ||
85 | idem() { if [ ! -e "${!#}" ]; then "$@"; fi; } | 125 | idem() { if [ ! -e "${!#}" ]; then "$@"; fi; } |
86 | idem_mknod() { if [ ! -e "$3" ]; then mknod "$@"; fi; } | 126 | idem_mknod() { if [ ! -e "$3" ]; then mknod "$@"; fi; } |
@@ -88,7 +128,6 @@ idem_mknod() { if [ ! -e "$3" ]; then mknod "$@"; fi; } | |||
88 | # This function is copied (with modifications) from debootstrap. | 128 | # This function is copied (with modifications) from debootstrap. |
89 | install_devices() | 129 | install_devices() |
90 | { | 130 | { |
91 | local TARGET="$rootfs" | ||
92 | [ "$TARGET" -a -d "$TARGET" ] || die 'no $TARGET' | 131 | [ "$TARGET" -a -d "$TARGET" ] || die 'no $TARGET' |
93 | idem mkdir "$TARGET"/dev | 132 | idem mkdir "$TARGET"/dev |
94 | # The list of devices that can be created in a container comes from | 133 | # The list of devices that can be created in a container comes from |
@@ -114,7 +153,6 @@ install_devices() | |||
114 | 153 | ||
115 | mount_virtfs() | 154 | mount_virtfs() |
116 | { | 155 | { |
117 | local TARGET="$1" | ||
118 | [ "$TARGET" ] || die 'no $TARGET' | 156 | [ "$TARGET" ] || die 'no $TARGET' |
119 | [ -d "$TARGET"/proc ] || mkdir "$TARGET"/proc | 157 | [ -d "$TARGET"/proc ] || mkdir "$TARGET"/proc |
120 | [ -d "$TARGET"/sys ] || mkdir "$TARGET"/sys | 158 | [ -d "$TARGET"/sys ] || mkdir "$TARGET"/sys |
@@ -124,7 +162,6 @@ mount_virtfs() | |||
124 | 162 | ||
125 | umount_virtfs() | 163 | umount_virtfs() |
126 | { | 164 | { |
127 | local TARGET="$1" fail= | ||
128 | [ "$TARGET" ] || die 'no $TARGET' | 165 | [ "$TARGET" ] || die 'no $TARGET' |
129 | umount "$TARGET"/proc || fail=y | 166 | umount "$TARGET"/proc || fail=y |
130 | umount "$TARGET"/sys || fail=y | 167 | umount "$TARGET"/sys || fail=y |
@@ -140,23 +177,23 @@ write_lines_once() | |||
140 | 177 | ||
141 | populate_rootfs() | 178 | populate_rootfs() |
142 | { | 179 | { |
143 | [ "$rootfs" ] || die 'no $rootfs' | 180 | [ "$TARGET" ] || die 'no $TARGET' |
144 | set -B | 181 | set -B |
145 | mkdir -p \ | 182 | mkdir -p \ |
146 | "$rootfs"/etc/apt/{preferences.d,apt.conf.d,trusted.gpg.d,sources.list.d} \ | 183 | "$TARGET"/etc/apt/{preferences.d,apt.conf.d,trusted.gpg.d,sources.list.d} \ |
147 | "$rootfs"/var/{lib/{apt/lists/partial,dpkg/{info,parts,triggers,alternatives,updates}},cache/apt} \ | 184 | "$TARGET"/var/{lib/{apt/lists/partial,dpkg/{info,parts,triggers,alternatives,updates}},cache/apt} \ |
148 | "$rootfs"/var/log/apt | 185 | "$TARGET"/var/log/apt |
149 | 186 | ||
150 | touch "$rootfs"/var/lib/dpkg/status | 187 | touch "$TARGET"/var/lib/dpkg/status |
151 | 188 | ||
152 | write_lines_once "$rootfs"/var/lib/dpkg/arch "$rootfs_arch" | 189 | write_lines_once "$TARGET"/var/lib/dpkg/arch "$target_arch" |
153 | write_lines_once "$rootfs"/etc/apt/sources.list \ | 190 | write_lines_once "$TARGET"/etc/apt/sources.list \ |
154 | "deb $debian_mirror $release main contrib non-free" \ | 191 | "deb $debian_mirror $target_release main contrib non-free" \ |
155 | "deb http://security.debian.org $release/updates main contrib non-free" | 192 | "deb http://security.debian.org $target_release/updates main contrib non-free" |
156 | install_devices | 193 | install_devices |
157 | } | 194 | } |
158 | 195 | ||
159 | parse_apt_noact_line() | 196 | parse_apt_simul_line() |
160 | { | 197 | { |
161 | set -- $* | 198 | set -- $* |
162 | action=$1 | 199 | action=$1 |
@@ -178,16 +215,20 @@ parse_apt_noact_line() | |||
178 | return 1 | 215 | return 1 |
179 | } | 216 | } |
180 | 217 | ||
181 | dpkg_extract_with_info() | 218 | dpkg_unpack() |
182 | { | 219 | { |
183 | local deb="$1" TARGET="$2" multiarch="$3" command PKG | 220 | [ "$TARGET" -a -d "$TARGET" ] || die 'no $TARGET' |
221 | local deb="$1" multiarch="$2" SET_STATUS="$3" command PKG | ||
184 | PKG=${deb##*/} | 222 | PKG=${deb##*/} |
185 | PKG=${PKG%%_*} | 223 | PKG=${PKG%%_*} |
186 | PKG=$PKG$multiarch | 224 | PKG=$PKG$multiarch |
187 | 225 | ||
226 | # TODO: always set status=installed if there is no preinst or postinst script | ||
227 | |||
188 | command=$(cat <<'EOF' | 228 | command=$(cat <<'EOF' |
189 | if [ "$TAR_FILENAME" = ./control ]; then | 229 | set -e |
190 | (sed "/^Package:/a Status: install ok installed"; echo) >> "$TARGET"/var/lib/dpkg/status | 230 | if [ "$SET_STATUS" -a "$TAR_FILENAME" = ./control ]; then |
231 | (sed "/^Package:/a Status: install ok $SET_STATUS"; echo) >> "$TARGET"/var/lib/dpkg/status | ||
191 | else | 232 | else |
192 | f=$TARGET/var/lib/dpkg/info/$PKG.${TAR_FILENAME#./} | 233 | f=$TARGET/var/lib/dpkg/info/$PKG.${TAR_FILENAME#./} |
193 | cat > "$f" | 234 | cat > "$f" |
@@ -195,21 +236,16 @@ else | |||
195 | fi | 236 | fi |
196 | EOF | 237 | EOF |
197 | ) | 238 | ) |
198 | (export PKG TARGET; dpkg --ctrl-tarfile "$deb" | tar -x --to-command "$command") | 239 | (export PKG TARGET SET_STATUS; dpkg --ctrl-tarfile "$deb" | tar -x --to-command "$command") || die 'tar' |
199 | dpkg --fsys-tarfile "$deb" | | 240 | dpkg --fsys-tarfile "$deb" | |
200 | (cd "$TARGET" && tar -xv) | | 241 | (cd "$TARGET" && tar -xv) | |
201 | sed 's?^\.??; s?^/$?/.?; s?/$??' > "$TARGET/var/lib/dpkg/info/$PKG.list" | 242 | sed 's?^\.??; s?^/$?/.?; s?/$??' > "$TARGET/var/lib/dpkg/info/$PKG.list" |
202 | } | 243 | } |
203 | 244 | ||
204 | apt_run_inst() | 245 | dpkg_configure_from_apt_actions() |
205 | { | ||
206 | apt_get -s -yqq install "$@" | dpkg_inst_from_apt | ||
207 | } | ||
208 | |||
209 | dpkg_inst_from_apt() | ||
210 | { | 246 | { |
211 | while read line; do | 247 | while read line; do |
212 | parse_apt_noact_line "$line" || die "unexpected output from apt-get: $line" | 248 | parse_apt_simul_line "$line" || die "unexpected output from apt-get: $line" |
213 | export LC_ALL=C | 249 | export LC_ALL=C |
214 | export DEBIAN_FRONTEND=noninteractive | 250 | export DEBIAN_FRONTEND=noninteractive |
215 | export DPKG_MAINTSCRIPT_PACKAGE="$package" DPKG_MAINTSCRIPT_ARCH="$arch" | 251 | export DPKG_MAINTSCRIPT_PACKAGE="$package" DPKG_MAINTSCRIPT_ARCH="$arch" |
@@ -218,19 +254,19 @@ dpkg_inst_from_apt() | |||
218 | Inst) | 254 | Inst) |
219 | export DPKG_MAINTSCRIPT_NAME=preinst | 255 | export DPKG_MAINTSCRIPT_NAME=preinst |
220 | preinst=/var/lib/dpkg/info/${package}${multiarch}.preinst | 256 | preinst=/var/lib/dpkg/info/${package}${multiarch}.preinst |
221 | if [ -x "$rootfs"/"$preinst" ]; then | 257 | if [ -x "$TARGET"/"$preinst" ]; then |
222 | (set -x; chroot "$rootfs" "$preinst" install) | 258 | ${CHROOT_PROG:-chroot} "$TARGET" "$preinst" install |
223 | fi | 259 | fi |
224 | ;; | 260 | ;; |
225 | Conf) | 261 | Conf) |
226 | export DPKG_MAINTSCRIPT_NAME=postinst | 262 | export DPKG_MAINTSCRIPT_NAME=postinst |
227 | postinst=/var/lib/dpkg/info/${package}${multiarch}.postinst | 263 | postinst=/var/lib/dpkg/info/${package}${multiarch}.postinst |
228 | if [ -x "$rootfs"/"$postinst" ]; then | 264 | if [ -x "$TARGET"/"$postinst" ]; then |
229 | (set -x; chroot "$rootfs" "$postinst" configure) | 265 | ${CHROOT_PROG:-chroot} "$TARGET" "$postinst" configure |
230 | fi | 266 | fi |
231 | ;; | 267 | ;; |
232 | Remv) ;; | 268 | Remv) ;; |
233 | *) die "impossible" ;; | 269 | *) die "unexpected output from 'apt-get -s'" ;; |
234 | esac | 270 | esac |
235 | done | 271 | done |
236 | } | 272 | } |
@@ -239,21 +275,23 @@ apt_extract() | |||
239 | { | 275 | { |
240 | apt_get -d -yqq install "$@" | 276 | apt_get -d -yqq install "$@" |
241 | actions=$(mktemp) || die 'mktemp failed' | 277 | actions=$(mktemp) || die 'mktemp failed' |
242 | apt_get -s -yqq install "$@" | tee "$actions" | dpkg_extract_from_apt | 278 | apt_get -s -yqq install "$@" > "$actions" || die 'apt-get failed' |
243 | 279 | ||
244 | if [ "$EXTRACT_DPKG_INFO" ]; then | 280 | dpkg_unpack_from_apt_actions < "$actions" || die 'dpkg unpack (using internal dpkg) failed' |
281 | |||
282 | if [ ! "$UNPACK_ONLY" ]; then | ||
245 | install_etc_passwd | 283 | install_etc_passwd |
246 | dpkg_inst_from_apt < "$actions" | 284 | dpkg_configure_from_apt_actions < "$actions" || die 'dpkg configure (using internal dpkg) failed' |
247 | fi | 285 | fi |
248 | 286 | ||
249 | rm "$actions" | 287 | rm "$actions" |
250 | } | 288 | } |
251 | 289 | ||
252 | dpkg_extract_from_apt() | 290 | dpkg_unpack_from_apt_actions() |
253 | { | 291 | { |
254 | while read line; do | 292 | while read line; do |
255 | 293 | ||
256 | parse_apt_noact_line "$line" || die "unexpected output from apt-get: $line" | 294 | parse_apt_simul_line "$line" || die "unexpected output from apt-get: $line" |
257 | 295 | ||
258 | deb=/var/cache/apt/archives/${package}_${version//:/%3a}_${arch}.deb | 296 | deb=/var/cache/apt/archives/${package}_${version//:/%3a}_${arch}.deb |
259 | [ -f "$deb" ] || { | 297 | [ -f "$deb" ] || { |
@@ -263,43 +301,31 @@ dpkg_extract_from_apt() | |||
263 | } | 301 | } |
264 | case "$action" in | 302 | case "$action" in |
265 | Inst) | 303 | Inst) |
266 | printf 'Extracting %s\n' "${deb##*/}" >&2 | 304 | printf 'Unpacking %s\n' "${deb##*/}" >&2 |
305 | |||
306 | is_multiarch_same "$package" && multiarch=":$arch" || multiarch= | ||
307 | [ "$UNPACK_ONLY" ] && set_status=unpacked || set_status=installed | ||
308 | dpkg_unpack "$deb" "$multiarch" "$set_status" || die "dpkg_unpack" | ||
267 | 309 | ||
268 | if [ "$EXTRACT_DPKG_INFO" ]; then | ||
269 | is_multiarch_same "$package" && multiarch=":$arch" || multiarch= | ||
270 | dpkg_extract_with_info "$deb" "$rootfs" "$multiarch" | ||
271 | else | ||
272 | dpkg-deb --extract "$deb" "$rootfs" | ||
273 | fi | ||
274 | ;; | 310 | ;; |
275 | Conf) ;; | 311 | Conf) ;; |
276 | Remv) ;; | 312 | Remv) ;; |
277 | *) die "impossible" ;; | 313 | *) die "unexpected output from 'apt-get -s'" ;; |
278 | esac | 314 | esac |
279 | done | 315 | done |
280 | } | 316 | } |
281 | 317 | ||
282 | install_etc_passwd() | 318 | install_etc_passwd() |
283 | { | 319 | { |
284 | [ -e "$rootfs"/etc/passwd ] || cp "$rootfs"/usr/share/base-passwd/passwd.master "$rootfs"/etc/passwd | 320 | [ -e "$TARGET"/etc/passwd ] || cp "$TARGET"/usr/share/base-passwd/passwd.master "$TARGET"/etc/passwd |
285 | [ -e "$rootfs"/etc/group ] || cp "$rootfs"/usr/share/base-passwd/group.master "$rootfs"/etc/group | 321 | [ -e "$TARGET"/etc/group ] || cp "$TARGET"/usr/share/base-passwd/group.master "$TARGET"/etc/group |
286 | } | ||
287 | |||
288 | main_packages_file() | ||
289 | { | ||
290 | local uri_part="${debian_mirror#*/}" | ||
291 | while [ "${uri_part:0:1}" = / ]; do | ||
292 | uri_part=${uri_part#?} | ||
293 | done | ||
294 | uri_part=${uri_part//\//_} | ||
295 | printf '/var/lib/apt/lists/%s_dists_%s_main_binary-%s_Packages\n' "$uri_part" "$release" "$rootfs_arch" | ||
296 | } | 322 | } |
297 | 323 | ||
298 | required_packages() | 324 | required_packages() |
299 | { | 325 | { |
300 | perl -00 -ne \ | 326 | apt_cache dumpavail | |
301 | '/^Priority: required/m || next; /^Package: (.*)$/m && print "$1\n"' \ | 327 | perl -00 -ne '/^Priority: required/m || next; /^Package: (.*)$/m && print "$1\n"' | |
302 | "$(main_packages_file)" | sort -u | 328 | sort -u |
303 | } | 329 | } |
304 | 330 | ||
305 | declare -A is_multiarch_same | 331 | declare -A is_multiarch_same |
@@ -316,9 +342,9 @@ multicheck() | |||
316 | 342 | ||
317 | multiarch_same_packages() | 343 | multiarch_same_packages() |
318 | { | 344 | { |
319 | perl -00 -ne \ | 345 | apt_cache dumpavail | |
320 | '/^Multi-Arch: same/mi || next; /^Package: (.*)$/m && print "$1\n"' \ | 346 | perl -00 -ne '/^Multi-Arch: same/mi || next; /^Package: (.*)$/m && print "$1\n"' | |
321 | "$(main_packages_file)" | sort -u | 347 | sort -u |
322 | } | 348 | } |
323 | 349 | ||
324 | is_multiarch_same() | 350 | is_multiarch_same() |
@@ -329,48 +355,37 @@ is_multiarch_same() | |||
329 | 355 | ||
330 | set -e | 356 | set -e |
331 | 357 | ||
332 | rootfs_arch=$(dpkg-architecture -q DEB_HOST_ARCH) || die 'dpkg-architecture failed' | 358 | target_arch=$(dpkg-architecture -q DEB_HOST_ARCH) || die 'dpkg-architecture failed' |
333 | release=$(current_debian_codename) && [ "$release" ] || die 'could not determine Debian release name' | 359 | target_release=$(current_debian_codename) && [ "$target_release" ] || die 'could not determine Debian release name' |
334 | |||
335 | if [ "$FAST_MODE" ]; then | ||
336 | SKIP_INSTALL=y | ||
337 | EXTRACT_DPKG_INFO=y | ||
338 | RUN_INST_SCRIPTS=y | ||
339 | fi | ||
340 | 360 | ||
341 | # Set things up so apt-get update works. | 361 | # Set things up so apt-get update works. |
342 | sanity_checks | 362 | sanity_checks |
343 | generate_apt_config | 363 | generate_apt_config |
344 | populate_rootfs | 364 | populate_rootfs |
345 | |||
346 | |||
347 | # Initial apt-get update will determine what we shall install. | ||
348 | [ "$SKIP_UPDATE" ] || apt_get update | 365 | [ "$SKIP_UPDATE" ] || apt_get update |
366 | |||
349 | packages=$(required_packages) && [ "$packages" ] || die 'failed to determine list of required packages' | 367 | packages=$(required_packages) && [ "$packages" ] || die 'failed to determine list of required packages' |
350 | extra_packages='apt debian-archive-keyring locales' | ||
351 | 368 | ||
369 | export LC_ALL=C | ||
370 | export DEBIAN_FRONTEND=noninteractive | ||
352 | 371 | ||
353 | # Some files need to be present before 'apt-get install' can install anything. | 372 | if [ "$REAL_APT_INSTALL" ]; then |
354 | # In particular: | 373 | # Some files need to be present before 'apt-get install' can install anything. |
355 | # | 374 | # In particular: |
356 | # 1. binaries used by dpkg 'inst' scripts. | 375 | # |
357 | # 2. /etc/passwd and /etc/group so that 'chown' works | 376 | # 1. binaries used by dpkg 'inst' scripts. |
377 | # 2. /etc/passwd and /etc/group so that 'chown' works | ||
358 | 378 | ||
359 | # Rather than fuss about (1), extract everything from all packages. | 379 | # Unpack required packages. Handles (1) |
380 | UNPACK_ONLY=y apt_extract $packages | ||
360 | 381 | ||
361 | # Note: apt_extract() runs preinst and postinst scripts itself when | 382 | # This handles (2). |
362 | # $EXTRACT_DPKG_INFO is true. | 383 | # An alternative (used by debootstrap) is to configure base-passwd |
363 | apt_extract $packages | 384 | install_etc_passwd |
364 | 385 | ||
365 | if [ "$SKIP_INSTALL" ]; then | 386 | dpkg --root="$TARGET" --configure -a |
366 | apt_extract $extra_packages | 387 | apt_get install -y $EXTRA_PACKAGES |
367 | else | 388 | else |
368 | export LC_ALL=C | 389 | apt_extract $packages |
369 | export DEBIAN_FRONTEND=noninteractive | 390 | apt_extract $EXTRA_PACKAGES |
370 | |||
371 | install_etc_passwd # This handles (2). | ||
372 | if [ "$FIX_BROKEN" ]; then | ||
373 | dpkg --root="$rootfs" --configure -a | ||
374 | fi | ||
375 | apt_get install -y $packages $extra_packages | ||
376 | fi | 391 | fi |