File: chroot-setup.sh

package info (click to toggle)
debian-installer-utils 1.156
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 944 kB
  • sloc: sh: 1,001; ansic: 160; makefile: 62
file content (243 lines) | stat: -rw-r--r-- 7,346 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
# Setup for using apt to install packages in /target.

mountpoints () {
	cut -d" " -f2 /proc/mounts | sort | uniq
}

# Make sure mtab in the chroot reflects the currently mounted partitions.
update_mtab() {
	mtab=/target/etc/mtab

	if [ -h "$mtab" ]; then
		logger -t $0 "warning: $mtab won't be updated since it is a symlink."
		return 0
	fi

	egrep '^[^ ]+ /target' /proc/mounts | (
	while read devpath mountpoint fstype options n1 n2 ; do
		devpath=`mapdevfs $devpath || echo $devpath`
		mountpoint="${mountpoint#/target}"
		# mountpoint for root will be empty
		if [ -z "$mountpoint" ] ; then
			mountpoint="/"
		fi
		echo $devpath $mountpoint $fstype $options $n1 $n2
	done ) > $mtab
}

divert () {
	# begin-remove-after: released:trixie
	# As long as the installer supports installing bookworm, we need to
	# take diversions of aliased files into account. They need to be
	# duplicated and cannot use --rename. DEP17 P3 M18
	case "$1" in
		/usr/bin/*|/usr/lib/*|/usr/lib32/*|/usr/lib64/*|/usr/libx32/*|/usr/sbin/*)
			if chroot /target dpkg -S "${1#/usr}" >/dev/null 2>&1; then
				mv "/target/${1#/usr}" "/target/${1#/usr}.REAL.usr-is-merged"
			else
				mv "/target/$1" "/target/$1.REAL"
			fi
			chroot /target dpkg-divert --quiet --add --divert "${1#/usr}.REAL.usr-is-merged" --no-rename "${1#/usr}"
			chroot /target dpkg-divert --quiet --add --divert "$1.REAL" --no-rename "$1"
		;;
		*)
	# end-remove-after
	chroot /target dpkg-divert --quiet --add --divert "$1.REAL" --rename "$1"
	# begin-remove-after: released:trixie
		;;
	esac
	# end-remove-after
}

undivert () {
	rm -f "/target$1"
	# begin-remove-after: released:trixie
	case "$1" in
		/usr/bin/*|/usr/lib/*|/usr/lib32/*|/usr/lib64/*|/usr/libx32/*|/usr/sbin/*)
			rm -f "/target${1#/usr}"
			chroot /target dpkg-divert --quiet --remove --no-rename "${1#/usr}"
			chroot /target dpkg-divert --quiet --remove --no-rename "$1"
			if chroot /target dpkg -S "${1#/usr}" >/dev/null 2>&1; then
				mv "/target/${1#/usr}.REAL.usr-is-merged" "/target/${1#/usr}"
			else
				mv "/target/$1.REAL" "/target/$1"
			fi
		;;
		*)
	# end-remove-after
	chroot /target dpkg-divert --quiet --remove --rename "$1"
	# begin-remove-after: released:trixie
		;;
	esac
	# end-remove-after
}

chroot_setup () {
	# Bail out if directories we need are not there
	if [ ! -d /target/sbin ] || [ ! -d /target/usr/sbin ] || \
	   [ ! -d /target/proc ]; then
		return 1
	fi
	if [ -d /sys/devices ] && [ ! -d /target/sys ]; then
		return 1
	fi

	if [ -e /var/run/chroot-setup.lock ]; then
		cat >&2 <<EOF
apt-install or in-target is already running, so you cannot run either of
them again until the other instance finishes. You may be able to use
'chroot /target ...' instead.
EOF
		return 1
	fi
	touch /var/run/chroot-setup.lock

	# Create a policy-rc.d to stop maintainer scripts using invoke-rc.d 
	# from running init scripts. In case of maintainer scripts that don't
	# use invoke-rc.d, add a dummy start-stop-daemon.
	cat > /target/usr/sbin/policy-rc.d <<EOF
#!/bin/sh
exit 101
EOF
	chmod a+rx /target/usr/sbin/policy-rc.d
	
	if [ -e /target/usr/sbin/start-stop-daemon ]; then
		divert /usr/sbin/start-stop-daemon
	fi
	cat > /target/usr/sbin/start-stop-daemon <<EOF
#!/bin/sh
echo 1>&2
echo 'Warning: Fake start-stop-daemon called, doing nothing.' 1>&2
exit 0
EOF
	chmod a+rx /target/usr/sbin/start-stop-daemon
	
	# Record the current mounts
	mountpoints > /tmp/mount.pre

	case `udpkg --print-os` in
	        "linux")
			# Some packages (eg. the kernel-image package) require a mounted
			# /proc/. Only mount it if not mounted already
			if [ ! -f /target/proc/cmdline ]; then
				mount -t proc proc /target/proc
			fi

			# For installing >=2.6.14 kernels we also need sysfs mounted
			# Only mount it if not mounted already
			if [ ! -d /target/sys/devices ]; then
				mount -t sysfs sysfs /target/sys
			fi

			# If available mount efivarfs, needed to install systemd-boot
			if mountpoints | grep -q '^/sys/firmware/efi/efivars$' && ! mountpoints | grep -q '^/target/sys/firmware/efi/efivars$'; then
				mount -t efivarfs efivarfs /target/sys/firmware/efi/efivars
			fi

			# In Lenny, /dev/ lacks the pty devices, so we need devpts mounted
			if [ ! -e /target/dev/pts/0 ]; then
				mkdir -p /target/dev/pts
				mount -t devpts devpts -o noexec,nosuid,gid=5,mode=620 \
					/target/dev/pts
			fi

			if ! mountpoints | grep -q '^/target/run$'; then
				mount --bind /run /target/run
			fi
		;;
	        "kfreebsd")
			# Some packages (eg. the kernel-image package) require a mounted
			# /proc/. Only mount it if not mounted already
			if [ ! -f /target/proc/cmdline ]; then
				mount -t linprocfs proc /target/proc
			fi
			# Some package might need sysfs mounted
			# Only mount it if not mounted already
			if [ ! -d /target/sys/devices ]; then
				mount -t linsysfs sysfs /target/sys
			fi
		;;
	esac

	mountpoints > /tmp/mount.post

	update_mtab

	# Try to enable proxy when using HTTP.
	# What about using ftp_proxy for FTP sources?
	RET=$(debconf-get mirror/protocol || true)
	if [ "$RET" = "http" ]; then
		RET=$(debconf-get mirror/http/proxy || true)
		if [ "$RET" ]; then
			http_proxy="$RET"
			export http_proxy
		fi
	fi

	# Pass debconf priority through.
	DEBIAN_PRIORITY=$(debconf-get debconf/priority || true)
	export DEBIAN_PRIORITY

	LANG=${IT_LANG_OVERRIDE:-$(debconf-get debian-installer/locale || true)}
	export LANG
	export PERL_BADLANG=0

	# Unset variables that would make scripts in the target think
	# that debconf is already running there.
	unset DEBIAN_HAS_FRONTEND
	unset DEBIAN_FRONTEND
	unset DEBCONF_FRONTEND
	unset DEBCONF_REDIR
	# Avoid debconf mailing notes.
	DEBCONF_ADMIN_EMAIL=""
	export DEBCONF_ADMIN_EMAIL
	# Avoid apt-listchanges doing anything.
	APT_LISTCHANGES_FRONTEND=none
	export APT_LISTCHANGES_FRONTEND
	# Sometimes sudo may need to be removed (e.g. when installing
	# sudo-ldap).  There's no situation in which doing this during d-i
	# is a problem, so unconditionally override the guard in sudo.prerm.
	SUDO_FORCE_REMOVE=yes
	export SUDO_FORCE_REMOVE

	return 0
}

chroot_cleanup () {
	rm -f /target/usr/sbin/policy-rc.d
	undivert /usr/sbin/start-stop-daemon

	# Undo the mounts done by the packages during installation.
	# Reverse sorting to umount the deepest mount points first.
	# Items with count of 1 are new.
	for dir in $( (cat /tmp/mount.pre /tmp/mount.pre; mountpoints ) | \
		     sort -r | uniq -c | grep "^[[:space:]]*1[[:space:]]" | \
		     sed "s/^[[:space:]]*[0-9][[:space:]]//"); do
		if ! umount $dir; then
			logger -t $0 "warning: Unable to umount '$dir'"
		fi
	done
	rm -f /tmp/mount.pre /tmp/mount.post

	rm -f /var/run/chroot-setup.lock
}

# Variant of chroot_cleanup that only cleans up chroot_setup's mounts.
chroot_cleanup_localmounts () {
	rm -f /target/usr/sbin/policy-rc.d
	undivert /usr/sbin/start-stop-daemon

	# Undo the mounts done by the packages during installation.
	# Reverse sorting to umount the deepest mount points first.
	# Items with count of 1 are new.
	for dir in $( (cat /tmp/mount.pre /tmp/mount.pre /tmp/mount.post ) | \
		     sort -r | uniq -c | grep "^[[:space:]]*1[[:space:]]" | \
		     sed "s/^[[:space:]]*[0-9][[:space:]]//"); do
		if ! umount $dir; then
			logger -t $0 "warning: Unable to umount '$dir'"
		fi
	done
	rm -f /tmp/mount.pre /tmp/mount.post

	rm -f /var/run/chroot-setup.lock
}