summaryrefslogtreecommitdiffstats
path: root/init.d/runtimes
blob: 4e3cc11f3519c833472f5bbc5793741fd81b9c7f (plain)
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
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
#!/sbin/runscript

# The purpose of this script is to load the Alpine runtime modules and the
# local config that belongs to.

SFIC=`which sfic 2>/dev/null`
COMMITED_TDB=/var/lib/apk/commited.tdb
TMP=/tmp/init.d-runtimes

# search for a kernel argument
get_kopt () {
	for i in `cat /proc/cmdline` ; do
		case $i in
			$1=*) echo $i | sed 's|'$1'=||'
			return 0
			;;
        	esac
	done
	return 1
}

get_pkg_list() {
	sed 's/\#.*//' $1
}

preload_users_and_groups() {
	tar -C / -zxf "$1" etc/passwd etc/group 2>/dev/null
}

# merge the unpacked config
merge_config() {
	local dev mnt ovl f ovllist ovlfile
	dev=$1
	ovlfile="$2"
	mnt=$(dirname "$2")
	ovl=$(basename "$2")

	cp -ar $TMP/* /

	# remember to remove leading /
	ovllist=`find $TMP/* | sed "s:^$TMP/::"`
	if [ "$ovllist" ] ; then
		lbu update $ovllist 2>/dev/null
		return 0
	else
		return 1
	fi
}

find_ovl() {
	local mnt="$1"
	local ovl
	local lines
	# first search kernel cmdline for "pkg_ovl"
	ovl=$( get_kopt pkg_ovl )
	if [ x"$ovl" != x ] ;then
		echo "$ovl"
		return 0
	fi

	# look for apkovl's on mounted media
	ovl=$( ls -1 "$mnt"/*.apkovl.tar.gz* 2>/dev/null ) || return 1
	lines=$(echo "$ovl" | wc -l)

	if [ $lines -gt 1 ] ; then
		echo "ERROR: More than one apkovl file was found on $(basename $mnt). None will be read." >&2
		exit 1
	fi
	echo "$ovl"
}

# read ahead so the packages are in cache when installed
readahead_pkgs() {
	local i pkgs
	for i in $* ; do
		pkgs="$pkgs $APK_PATH_MOUNTED/$i-[0-9]*"
	done
	readahead $pkgs 2>/dev/null &
}

load_pkgs_from_list() {
	local list="$1"
	local prompt="$2"
	local pkgs dummy
#	apk_fetch -u -q
	pkgs=$( sed 's/\#.*//' "$list" )
	readahead_pkgs $pkgs
	IGNORE_ERRORS=yes apk_add -v $pkgs 2>&1 | roller
}

load_pkgs() {
	local pkglist mlist pkg pkgs
	local dev=$1
	local mnt=$2
	# get kernel opt pkg_list or use /packages.list
	pkglist=`get_kopt pkg_list`
	# here we should issue a warning in future versions if found on cmdline
	pkglist=${pkglist:-/packages.list}

	# aww... we move from /mnt/packages.list to var/lib/apk/world to
	# etc/lbu/packages.list. Hopefully this code can be simplified in
	# future.
	mlist="$mnt/$pkglist"
	wlist="$TMP/var/lib/apk/world"
	plist="$TMP/etc/lbu/packages.list"

	[ -f "$plist" ] && wlist="$plist"
	if [ -f "$wlist" ] ; then
		load_pkgs_from_list "$wlist"
		# its re-generated
		rm -rf "$wlist"
	elif [ -f "$mlist" ] ; then
		#ok, we are upgrading...
		local line i
		eeinfo "
NOTE: Using packages.list from $dev. This file has moved to
etc/lbu/packages.list and will be included in the apkovl.
"
		load_pkgs_from_list "$mlist"
		# lets clean up the world file
		echo "# This file was generated by /etc/init.d/runtimes" >/etc/init.d/packages.list
		for i in $(apk_glob '*') ; do
			reqby=$(apk_info -qr $i);
			# only add the packages who has no REQUIRED_BY
			[ -z "$reqby" ] && echo $i
		done | sed 's/-[0-9].*//' >> /etc/lbu/packages.list
	fi
}

# load packages from mounted media
load_pkgs_and_config() {
	# params:
	#  $1 = device
	#  $2 = path to mounted media
	local ovlfile
	local mnt=$2
	local dev=$1
	local dest

	cd /
	# look for apk overlays.
	ovlfile=$( find_ovl "$mnt" ) || return 1

	mkdir -p "$TMP"
	ebegin "Loading setup from $dev://$(basename $ovlfile)"
	case "$ovlfile" in
	*.apkovl.tar.gz.*)
		local cipher=${ovlfile##*.}
		local count=0
		if ! openssl list-cipher-commands \
			| grep "^$cipher$" > /dev/null; then
			eend 1 "Cipher $cipher is not supported"
			return 1
		fi
		echo ""
		while true ; do
			count=$(( $count + 1 ))
			openssl enc -d -$cipher -in "$ovlfile" \
				| tar -C "$TMP" -zx 2>/dev/null
			if [ $? -eq 0 ]; then
				break
			elif [ $count -ge 3 ]; then
				eend 1
				return
			fi
		done
		;;
	*)
		# unpack the ovl
		if ! tar -C "$TMP" -zxf "$ovlfile" ; then
			eend $?
			return
		fi
	esac

	# copy the passwd file
	[ -f "$TMP/etc/passwd" ] && cp $TMP/etc/passwd /etc
	[ -f "$TMP/etc/group" ] && cp $TMP/etc/group /etc

	# install the packages
	load_pkgs $dev $mnt

	# copy the config
	merge_config
	eend $?

	# clean up
	rm -rf "$TMP"
}

# find where to install packages from
set_apk_path() {
	local dev fs mnt pref subdir
	# if pkg_path is not specified as kernel arg, look for the packages
	# on mounted cdrom
	APK_PATH=`get_kopt pkg_path`
	APK_DEV=`get_kopt pkg_dev`

	# return if pkg_dev is empty
	if [ x"$APK_DEV" = x ] ; then
		export APK_PATH
		return
	fi

	# split  dev:fs
	dev=`echo $APK_DEV | cut -d: -f1`
	fs=`echo $APK_DEV | cut -d: -f2`

	# find mountpoint in fstab
	mnt=$( awk '/^\/dev\/'$dev'/ { print $2 }' /etc/fstab )

	# remove leading '/media/'. we assume the mount is in /media
	prefix=${mnt#/media/}

	# if there is no mountpoint in /media, then append one
	if [ x"$prefix" = x"$mnt" ] || [ x"$mnt" = x ] ; then
		prefix=$dev
		echo -e "/dev/$dev\t/media/$prefix\t$fs\tnoauto\t0 0" >> /etc/fstab
		mkdir -p /media/$prefix
	fi

	# construct the URI
	subdir=`get_kopt pkg_subdir`
	APK_PATH=$prefix:/${subdir:-/apks}

	# read configs if available
	[ -f /etc/apk/apk.conf ] && . /etc/apk/apk.conf
	export APK_PATH
	export APK_PATH_MOUNTED=/media/$prefix/$subdir

}

# mount dev $2 with type $1 on /mnt
mount_dev() {
	local fs=$1
	local dev=$2
	local i mountok

	# special handling for usb devices
	case $dev in
		usb*) 	# check for attatched devices
			if grep usb-storage /sys/class/scsi_host/host*/proc_name >/dev/null 2>&1 ; then
				ebegin "Waiting for usb-storage"
				for i in $(seq 0 9); do
					if mount -t $fs -o ro /dev/$dev /mnt >/dev/null 2>&1; then
						eend 0
						return 0
					else
						echo -n "."
						sleep 2
					fi
				done
				eend 1
				return 1 # timed out...
			fi
			;;
	esac
	# not usb, just try to mount as normal
	mount -t $fs -o ro /dev/$dev /mnt >/dev/null 2>&1
	return
}

start() {
	local cfgdevs  m
	# just in case...
	modprobe usb-storage 2>/dev/null
	modprobe sd_mod 2>/dev/null
	modprobe floppy 2>/dev/null
	modprobe cdrom 2>/dev/null

	set_apk_path

	cfgdevs=$( echo $( get_kopt cfg_dev ) | tr , ' ')
	for m in ${cfgdevs:-usba1:vfat fd0:vfat cdrom:iso9660}; do
		local dev fs skip_umount mnt loaded

		# split 'dev:fs'
		dev=${m%%:*}
		fs=${m##*:}

		# try to mount device on /mnt or abort
		mnt=$( awk '$1 ~ /^\/dev\/'$dev'/ { print $2 }' /proc/mounts )
		if [ x$mnt = x ] ; then
			skip_umount=""
			mount_dev $fs $dev || continue
			mnt=/mnt
		else
			skip_umount=yes
		fi

		# look for package listings and config overlays
		load_pkgs_and_config $dev $mnt && loaded=yes

		# lazy unmount
		[ "$skip_umount" = yes ] || umount -l $mnt
		[ "$loaded" = yes ] && break
	done

	# if there are no /etc/apk/apk.conf, create one
	if ! [ -f /etc/apk/apk.conf ] ; then
		mkdir -p /etc/apk
		echo "APK_PATH=$APK_PATH" > /etc/apk/apk.conf
	fi
}