forked from dnschneid/crouton
-
Notifications
You must be signed in to change notification settings - Fork 0
/
prepare
241 lines (221 loc) · 7.98 KB
/
prepare
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
#!/bin/sh -e
# Copyright (c) 2015 The crouton Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
# This is a distro-specific continuation of the prepare.sh script.
PKGEXT='deb'
DISTROAKA='debian'
# install_dist: see install() in prepare.sh for details.
install_dist() {
local pkgs='' pkgsasdeps='' params='' asdeps=''
while [ ! "$#" = 0 ]; do
if [ "$1" = "--minimal" ]; then
params='--no-install-recommends'
elif [ "$1" = "--asdeps" ]; then
asdeps='y'
else
break
fi
shift
done
while [ ! "$#" = 0 ]; do
if [ "$1" = '--' ]; then
shift
break
fi
pkgs="$pkgs $1"
shift
done
if [ -n "$asdeps" ]; then
pkgsasdeps="`list_uninstalled_dist '' $pkgs`"
fi
apt-get -y $params install $pkgs `list_uninstalled_dist - "$@"`
if [ -n "$pkgsasdeps" ]; then
apt-mark auto $pkgsasdeps
fi
}
# install_pkg_dist: see install_pkg() in prepare.sh for details.
install_pkg_dist() {
local params=''
if [ "$1" = '--minimal' ]; then
params='--no-install-recommends'
shift
fi
if [ ! "$#" = 0 ]; then
dpkg --force-depends -i "$@"
fi
apt-get -fy $params install
}
# install_dummy_dist: see install_dummy() in prepare.sh for details.
install_dummy_dist() {
if [ "$#" = 0 ]; then
return
fi
local pkgname="crouton-$1" pkgprovides="$1"
shift
while [ "$#" != 0 ]; do
if [ "$1" = '--' ]; then
shift
break
fi
pkgprovides="$pkgprovides, $1"
shift
done
local pkgdepends="$1"
if [ "$#" != 0 ]; then
shift
while [ "$#" != 0 ]; do
pkgdepends="$pkgdepends, $1"
shift
done
fi
local tmp="`mktemp -d crouton.XXXXXX --tmpdir=/tmp`"
addtrap "rm -rf '$tmp'"
cat > "$tmp/control" <<EOF
Package: $pkgname
Version: 0
Architecture: all
Maintainer: crouton
Installed-Size: 0
Provides: $pkgprovides
Depends: $pkgdepends
Section: misc
Priority: optional
Description: Provides a dummy ${pkgname#*-} for crouton
EOF
touch "$tmp/md5sums"
echo '2.0' > "$tmp/debian-binary"
tar -czf "$tmp/control.tar.gz" -C "$tmp" control md5sums
tar -cf "$tmp/data.tar" -T /dev/null
ar r "$tmp/$pkgname.deb" \
"$tmp/debian-binary" "$tmp/control.tar.gz" "$tmp/data.tar"
dpkg -i --force-depends "$tmp/$pkgname.deb"
apt-get -fy install
}
# remove_dist: see remove() in prepare.sh for details.
remove_dist() {
apt-get -y --purge remove "$@"
}
# list_uninstalled_dist: see list_uninstalled() in prepare.sh for details.
# If the package is virtual (e.g. libc-dev), we need to find the binary package
# corresponding to it (e.g. libc6-dev), so that we can remove it afterwards
# ("apt-get remove libc-dev" does not remove libc6-dev).
list_uninstalled_dist() {
local suffix="$1" pkg
shift
for pkg in "$@"; do
# If $pkg is a binary package, apt-cache returns the package name
# itself, so $pkg value stays the same.
# If $pkg is a virtual package, it returns a list of binary packages
# that are able to provide it. If there is a single match, use that.
# If there is no match, it may mean that we are checking for a package
# that we installed manually from a .deb file, so we still use $pkg.
# If there is more than one match, we use $pkg, and apt-get install
# will fail due to selection ambiguity (it is not the purpose of this
# function to pick one of the alternative).
pkg="`apt-cache search --names-only "^$pkg\$" |
awk 'x{x=""; exit} !x{x=$1} END{print x?x:"'"$pkg"'"}'`"
if ! dpkg-query -l "$pkg" 2>/dev/null | grep -q '^[ih]i'; then
echo -n "$pkg$suffix "
fi
done
}
# detect_mirror
# Detects the current mirror: Prints the first source that provides the
# "main" component.
detect_mirror() {
if ! awk '/^deb .* main( .*)?$/ { print $2; f=1; exit }; END { exit !f }' \
/etc/apt/sources.list /etc/apt/sources.list.d/*.list 2>/dev/null; then
error 1 "Cannot detect mirror."
fi
}
# install_mirror_package [--asdeps] package path [regex arch]
# Fetch and install a package directly from the mirror.
# This allows to install a package from a different release, when the current
# release does not provide the required package, or when the version it
# provides is broken or outdated.
# --asdeps: Install as dependency
# package: Package name (e.g. xserver-xephyr)
# path: Mirror path (e.g. pool/universe/x/xorg-server)
# regex: Version regex (e.g. '1\.11\.4-0ubuntu[0-9][0-9]\.[0-9]*').
# If not specified, match any version (default regex: ".*").
# The latest version that matches the regex is selected.
# If the package is a dependency of other packages (e.g. a library),
# you should select the earliest version that provides the required
# features, to prevent breakage during release upgrade.
# arch: Additional architecture to install. e.g. i386 installs both i386
# and amd64 packages. Defaults to only installing "$ARCH"
install_mirror_package() {
local asdeps=''
if [ "$1" = "--asdeps" ]; then
asdeps='y'
shift
fi
local package="$1"
# Split local and assignment to make sure -e error handling works
local mirror
mirror="`detect_mirror`"
local url="${mirror%/}/${2#/}/"
local debfiles=""
local pkgnames=""
for carch in "$ARCH" "$4"; do
if [ -z "$carch" ]; then
continue
fi
local pkgname="$package:$carch"
local regex="^${package}_${3:-.*}_(${carch}|all)\.deb$"
# Find package in directory listing:
# Filenames are HTML <a href> values, enclosed in quotes.
local xvers="`wget -O- "$url" -nv \
| awk 'BEGIN { RS="<[aA][^>]* [hH][rR][eE][fF]=\\""; FS="\\"" }
NR > 1 && $1 ~ /'"$regex"'/ { print $1 }' \
| sort -V | tail -n 1`"
if [ -z "$xvers" ]; then
error 1 "Error retrieving $pkgname."
fi
# Check if installed version is already up to date
local installed="`dpkg-query -l "$pkgname" 2>/dev/null | \
awk '/^[hi]i/ { sub(/^[0-9]+:/, "", $3); print $2 "_" $3 }'`"
if [ "${xvers%_*}" = "$installed" ]; then
echo "$pkgname is already up to date ($installed)."
continue
fi
pkgurl="$url$xvers"
# Download the package to a temporary file
local deb="`mktemp crouton.XXXXXX --tmpdir=/tmp`"
addtrap "rm -f '$deb'"
wget "$pkgurl" -O"$deb"
debfiles="$debfiles $deb"
pkgnames="$pkgnames $pkgname"
done
if [ -n "$debfiles" ]; then
# Install the package
install_pkg $debfiles
if [ -n "$asdeps" ]; then
apt-mark auto $pkgnames
fi
fi
}
# Run dpkg in non-interactive mode
export DEBIAN_FRONTEND=noninteractive
# Run debootstrap second stage if it hasn't already happened
if [ -r /debootstrap ]; then
# Debootstrap doesn't like anything mounted under /sys or /var when it runs
# We request a re-mount after bootstrapping, so these mounts will be fixed.
# We also can't detect the mounts properly due to the chroot, so we have to
# recursively find mountpoints under /sys, and hardcode /var umounts.
find /sys/* -maxdepth 2 -depth -type d \
-exec mountpoint -q {} \; -exec umount {} \;
umount '/var/run/lock' '/var/run'
# Start the bootstrap
/debootstrap/debootstrap --second-stage
# Clean contents of /var/run (since we'll always be mounting over it).
rm -rf --one-file-system /var/run/*
# Request a script restart to refresh the mount environment
relaunch_setup
else
# Do any pending configuration, in case of an unfortunately-timed Ctrl-C
dpkg --configure -a
# Fix the keyboard mode in case it got reverted to raw
fixkeyboardmode
fi