summaryrefslogtreecommitdiff
path: root/src/selfstrap
diff options
context:
space:
mode:
authorAndrew Cady <d@jerkface.net>2017-09-03 23:17:54 -0400
committerAndrew Cady <d@jerkface.net>2017-09-03 23:17:54 -0400
commita569fd30c8113354dc9afd8dd44fc4f1a9ab038e (patch)
tree6f68fa8e88aa9a48b0de3cb04b2d42a734cd9b79 /src/selfstrap
parent9c9afa2abaa73c73bcb0af55b42394c54d65d710 (diff)
selfstrap: getopt-based CLI
Diffstat (limited to 'src/selfstrap')
-rwxr-xr-xsrc/selfstrap257
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
2debian_mirror=http://httpredir.debian.org/debian 2debian_mirror=http://httpredir.debian.org/debian
3 3EXTRA_PACKAGES='apt debian-archive-keyring locales'
4if [ $# = 1 ]; then
5 rootfs=$1
6else
7 echo "Usage: $0 <target directory>" >&2
8 exit 1
9fi
10 4
11die() { printf 'Error: %s\n' "$*"; exit 1; } 5die() { printf 'Error: %s\n' "$*"; exit 1; }
12 6
7usage()
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
19EOF
20 exit ${1:-1}
21}
22
23GETOPT=$(getopt -n "${0##*/}" -o t:hv --long help,target:,verbose,unpack,chroot:,packages:,real-apt -- "$@") || exit
24eval set -- "$GETOPT"
25while [ $# -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
40done
41
42[ "$TARGET" ] || usage
43
44! [ "$REAL_APT_INSTALL" -a "$UNPACK_ONLY" ] || die "option --real-apt is incompatible with option --unpack"
45
46EXTRA_PACKAGES="$EXTRA_PACKAGES $*"
47
13am_root() { [ "$(id -u)" = 0 ]; } 48am_root() { [ "$(id -u)" = 0 ]; }
14 49
15current_debian_codename() 50current_debian_codename()
@@ -21,9 +56,9 @@ current_debian_codename()
21sanity_checks() 56sanity_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
29generate_apt_config() 64generate_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
34Dir::Etc "${rootfs}/etc/apt/"; 69Dir::Etc "${TARGET}/etc/apt/";
35Dir::Etc::Parts "${rootfs}/etc/apt/apt.conf.d/"; 70Dir::Etc::Parts "${TARGET}/etc/apt/apt.conf.d/";
36Dir::Etc::PreferencesParts "${rootfs}/etc/apt/preferences.d/"; 71Dir::Etc::PreferencesParts "${TARGET}/etc/apt/preferences.d/";
37EOF 72EOF
38 export APT_CONFIG 73 export APT_CONFIG
39} 74}
40 75
41apt_get() 76apt_()
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}
122apt_get() { apt_ get "$@"; }
123apt_cache() { apt_ cache "$@"; }
84 124
85idem() { if [ ! -e "${!#}" ]; then "$@"; fi; } 125idem() { if [ ! -e "${!#}" ]; then "$@"; fi; }
86idem_mknod() { if [ ! -e "$3" ]; then mknod "$@"; fi; } 126idem_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.
89install_devices() 129install_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
115mount_virtfs() 154mount_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
125umount_virtfs() 163umount_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
141populate_rootfs() 178populate_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
159parse_apt_noact_line() 196parse_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
181dpkg_extract_with_info() 218dpkg_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'
189if [ "$TAR_FILENAME" = ./control ]; then 229set -e
190 (sed "/^Package:/a Status: install ok installed"; echo) >> "$TARGET"/var/lib/dpkg/status 230if [ "$SET_STATUS" -a "$TAR_FILENAME" = ./control ]; then
231 (sed "/^Package:/a Status: install ok $SET_STATUS"; echo) >> "$TARGET"/var/lib/dpkg/status
191else 232else
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
195fi 236fi
196EOF 237EOF
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
204apt_run_inst() 245dpkg_configure_from_apt_actions()
205{
206 apt_get -s -yqq install "$@" | dpkg_inst_from_apt
207}
208
209dpkg_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
252dpkg_extract_from_apt() 290dpkg_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
282install_etc_passwd() 318install_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
288main_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
298required_packages() 324required_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
305declare -A is_multiarch_same 331declare -A is_multiarch_same
@@ -316,9 +342,9 @@ multicheck()
316 342
317multiarch_same_packages() 343multiarch_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
324is_multiarch_same() 350is_multiarch_same()
@@ -329,48 +355,37 @@ is_multiarch_same()
329 355
330set -e 356set -e
331 357
332rootfs_arch=$(dpkg-architecture -q DEB_HOST_ARCH) || die 'dpkg-architecture failed' 358target_arch=$(dpkg-architecture -q DEB_HOST_ARCH) || die 'dpkg-architecture failed'
333release=$(current_debian_codename) && [ "$release" ] || die 'could not determine Debian release name' 359target_release=$(current_debian_codename) && [ "$target_release" ] || die 'could not determine Debian release name'
334
335if [ "$FAST_MODE" ]; then
336 SKIP_INSTALL=y
337 EXTRACT_DPKG_INFO=y
338 RUN_INST_SCRIPTS=y
339fi
340 360
341# Set things up so apt-get update works. 361# Set things up so apt-get update works.
342sanity_checks 362sanity_checks
343generate_apt_config 363generate_apt_config
344populate_rootfs 364populate_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
349packages=$(required_packages) && [ "$packages" ] || die 'failed to determine list of required packages' 367packages=$(required_packages) && [ "$packages" ] || die 'failed to determine list of required packages'
350extra_packages='apt debian-archive-keyring locales'
351 368
369export LC_ALL=C
370export DEBIAN_FRONTEND=noninteractive
352 371
353# Some files need to be present before 'apt-get install' can install anything. 372if [ "$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
363apt_extract $packages 384 install_etc_passwd
364 385
365if [ "$SKIP_INSTALL" ]; then 386 dpkg --root="$TARGET" --configure -a
366 apt_extract $extra_packages 387 apt_get install -y $EXTRA_PACKAGES
367else 388else
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
376fi 391fi