File: apt-setup

package info (click to toggle)
base-config 0.33.2
  • links: PTS
  • area: main
  • in suites: potato
  • size: 472 kB
  • ctags: 171
  • sloc: sh: 777; perl: 538; makefile: 47; ansic: 27
file content (570 lines) | stat: -rwxr-xr-x 16,539 bytes parent folder | download
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
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
#!/bin/sh -e
# Apt configurator.
# GPL 199 by Joey Hess

# Options passed from dselect
VARDIR=$1
GROUP=$2
METHOD=$3

# If this is not called from dselect, and the first parameter is "probe", it
# will do cd autoprobing on startup.
if [ "$VARDIR" = probe ]; then
	CDPROBE=1
fi

# Where is the mirrors master list?
MIRRORLIST=/usr/share/base-config/Mirrors.masterlist

. /usr/share/debconf/confmodule

# Get the configuration from /etc/apt/apt.conf
APTGET="/usr/bin/apt-get"
APTETC="/etc/apt/"
APTCDROM="/usr/bin/apt-cdrom"
RES=`apt-config shell \
	APTGET Dir::Bin::apt-get \
	APTETC Dir::Etc \
	APTCDROM Dir::Bin::apt-cdrom`
eval $RES

# Pass in a URI type; this function returns a list of countries
# that have mirrors in them that match the type.
country_list () {
	perl -ne '
		BEGIN {
			$type=shift;
			open (T, "/usr/share/zoneinfo/iso3166.tab");
			while (<T>) {
				next if /^#/;
				chomp;
				($code, $long)=split(/\t/, $_);
				$c{$code}=$long;
			}
			close T;
			$/="\n\n";
			$countries{"enter information manually"}=1;
		}
		if (/Archive-$type:/) {
			($c)=/Country: (.*?)\s*\n/;
			$countries{$c{$c}}=1 if $c;
		}
		END { print join(", ", sort(keys %countries)) if %countries }
	' $1 $MIRRORLIST
}

# Pass in a URI type and a country; this function returns a 
# list of mirrors of the correct type in the country.
# The list is ordered with push mirrors at the top.
# Other orderings can be added here.
mirror_list () {
	perl -ne '
		BEGIN {
			$type=shift;
			$country=shift;
			open (T, "/usr/share/zoneinfo/iso3166.tab");
			while (<T>) {
				next if /^#/;
				chomp;
				($code, $long)=split(/\t/, $_);
				if ($long eq $country) {
					$country=$code;
				        close T;
				}
			}
			close T;
			$/="\n\n";
		}
		if (/Archive-$type:/ && /Country: $country\s*\n/) {
			($s)=/Site: (.*?)\n/;
			($t)=/Type: (.*?)\n/;
			$rating=0;
			$rating=1 if $t=~/push/i;
			$rating=2 if $t=~/push-primary/i;
			$mirrors{$s}=$rating;
		}
		END { print join(", ",
			sort { $mirrors{$b} <=> $mirrors{$a} }
			(keys %mirrors)) }
	' $1 "$2" $MIRRORLIST
}

# Pass in the URI type and the hostname of a mirror; this returns the
# directory the debian mirror is located in on that host.
mirror_dir () {
	perl -ne '
		BEGIN { $/="\n\n"; $type=shift; $mirror=shift }
		if (/Site: $mirror/ && /Archive-$type: (.*)\n/) {
			print $1;
			exit;
		}
	' $1 $2 $MIRRORLIST
}

# After mounting a cd, call this function to scan
# it with apt-cdrom, which also adds it to the sources.list.
# The cd will then be unmounted.
scan_cd () {
	clear >/dev/tty </dev/tty
	echo "Scanning CD, this will take a minute."
	# Touch file because apt-cdrom bails if it doesn't exist.
	touch /etc/apt/sources.list
	if $APTCDROM add --no-mount </dev/tty >/dev/tty; then
		umount /cdrom 2>/dev/null || true
		clear >/dev/tty </dev/tty
		return 0
	else
		umount /cdrom 2>/dev/null || true
		clear >/dev/tty </dev/tty
		# Apt didn't like the cdrom for some reason.
		db_fset apt-setup/cd/bad isdefault true
		db_input critical apt-setup/cd/bad || true
		db_go || true
		return 1
	fi
}

# This function should be called only after one cd has been successfully
# scanned. It prompts the user if there are more cd's to scan and
# scans them. Pass in the device that is known to be the cd drive.
handle_rest_cds () {
	LOOP=1
	while [ "$LOOP" ]; do
		# Make sure the cd is unmounted, we may be prompting
		# them to change cd's.
		umount /cdrom 2>/dev/null || true

		db_set apt-setup/cd/another false
		db_fset apt-setup/cd/another isdefault true
		db_input medium apt-setup/cd/another || true
		db_go || true
		db_get apt-setup/cd/another
		if [ "$RET" = true ]; then
			while ! mount $1 /cdrom -o ro -t iso9660
			do
				db_fset apt-setup/cd/dev isdefault true
				db_input critical apt-setup/cd/dev || true
				db_go || continue 2
				db_get apt-setup/cd/dev
				CDDEV="$RET"
			done
			scan_cd || true
		else
			LOOP=''
		fi
	done
}

# This function will ask the user if they want to add another
# apt source. If so, it returns true.
add_another () {
	# Now ask them if they want to add another entry,
	# and if so, restart.
	db_set apt-setup/another false
	db_fset apt-setup/another isdefault true
	db_input medium apt-setup/another || true
	db_go || return 1
	db_get apt-setup/another
	if [ "$RET" = true ]; then
		return 0
	fi
	return 1
}

# Establish the preliminaries.
db_version 2.0
db_capb 'backup'
db_title 'Apt Configuration'

MAINLOOP=1

# First, try to do cdrom autodetection. This is so in the most common case,
# you don't have to configure anything at all. Note that /dev/cdrom is made
# by the install process if you used the cd to install.

# If /dev/cdrom exists, use it.
if [ -e /dev/cdrom ]; then
	CDDEV=/dev/cdrom
	db_set apt-setup/cd/dev "$CDDEV"
fi
# TODO: other probing here.

if [ "$CDPROBE" -a "$CDDEV" ]; then
	umount /cdrom 2>/dev/null || true
	# Try mounting the detected cd rom.
	if mount $CDDEV /cdrom -o ro -t iso9660 && scan_cd; then
		handle_rest_cds $CDDEV
		MAINLOOP=''
	else
		# Unable to mount it, or the cd was bad. Make sure that cdrom
		# is the default, and just go on to ask them where they want
		# apt to install from.
		db_set apt-setup/uri_type "cdrom"
		db_subst apt-setup/uri_type note "You probably used a CD to install the Debian base system, but it is not currently in the drive. You should probably just insert it and select \"cdrom\"."
	fi
fi

while [ "$MAINLOOP" ] || add_another; do
	# Ask what source apt should install from.
	db_fset apt-setup/uri_type isdefault true
	db_input critical apt-setup/uri_type || exit 0
	db_go || exit 1
	db_get apt-setup/uri_type
	URI="$RET"
	# Clear any note that is on the uri_type, now that they've seen it.
	db_subst apt-setup/uri_type note ""

	# If they chose to use CD, there is little point in asking
	# these questions, since the CD's they insert will answer them for us.
	# Same goes if they are entering manually.
	if [ "$URI" != "cdrom" -a "$URI" != "edit sources list by hand" ]; then
		db_beginblock
		db_fset apt-setup/distribution isdefault true
		db_input low apt-setup/distribution || true
		db_fset apt-setup/non-free isdefault true
		db_fset apt-setup/non-free isdefault true
		db_input high apt-setup/non-us || true
		db_input high apt-setup/non-free || true
		db_endblock
		db_go || continue

		# If they choose to use non-free, ask about contrib, with a
		# default of yes. Doesn't seem to make much sense to even ask,
		# otherwise.
		db_get apt-setup/non-free
		if [ "$RET" = true ]; then
			db_fset apt-setup/contrib isdefault true
			db_set apt-setup/contrib true
			db_input medium apt-setup/contrib || true
			db_go || continue
		fi
	fi

	case "$URI" in
	ftp|http)
		# Ask them which country they're in.
		db_subst apt-setup/country countries "`country_list $URI`"
		db_fset apt-setup/country isdefault true
		db_input critical apt-setup/country || true
		db_go || continue
		
		db_get apt-setup/country
		if [ "$RET" != "enter information manually" ]; then
			# Now prompt with the mirrors in the selected country.
			db_subst apt-setup/mirror mirrors "`mirror_list $URI \"$RET\"`"
			db_fset apt-setup/mirror isdefault true
			db_input critical apt-setup/mirror || true
			db_go || continue
			
			# Now shove the data about the mirror into some other
			# questions.
			db_get apt-setup/mirror
			MIRROR="$RET"
			db_set apt-setup/hostname $MIRROR
			db_set apt-setup/directory "`mirror_dir $URI $MIRROR`"
		else
			# They elected to enter info manually.
			# Prompt for hostname and directory the mirror is in.
			db_beginblock
			db_fset apt-setup/hostname isdefault true
			db_input critical apt-setup/hostname || true
			db_fset apt-setup/directory isdefault true
			db_input critical apt-setup/directory || true
			db_endblock
			db_go || continue
		fi

		# Ask about a proxy if no proxy is yet defined.
		if [ "$URI" = "http" -a -z "$http_proxy" ]; then
			if [ ! -e "$APTETC/apt.conf" ] || \
			   ! grep -iq 'Acquire::http::Proxy' $APTETC/apt.conf; then
				db_fset apt-setup/http_proxy isdefault true
				db_input high apt-setup/http_proxy || true
				db_go || continue
			fi
		fi
	;;
	cdrom)
		# We've already probed earlier to try to figure out the
		# cd device.
		LOOP=1
		while [ "$LOOP" ]; do
			# Make sure the cd is unmounted, we may be prompting
			# them to change cd's.
			umount /cdrom 2>/dev/null || true
		
			# Prompt for the cd device if it wasn't autodetected.
			# TODO: We could give them a list of likely devices..
			#       This is unfriendly right now.
			if [ -z "$CDDEV" ]; then
				db_input critical apt-setup/cd/dev || true
				db_go || continue 2
				db_get apt-setup/cd/dev
				CDDEV="$RET"
				# Make /dev/cdrom link now, with device
				# they entered. This is for later use by
				# apt.
				if [ "$CDDEV" -a "$CDDEV" != '/dev/cdrom' ]; then
					ln -sf $CDDEV /dev/cdrom
				fi
			fi
			
			# Now try to mount the cdrom.
			if mount $CDDEV /cdrom -o ro -t iso9660; then
				LOOP=""
				if scan_cd; then
					handle_rest_cds $CDDEV
					MAINLOOP=""
				fi
			else
				# Loop and prompt again for cd device.
				db_fset apt-setup/cd/dev isdefault true
				CDDEV=""
			fi
		done
		continue
	;;
	
	filesystem)
		# they need to have a mirror already mounted somewhere.
		URI=file
		LOOP=1
		while [ "$LOOP" ]; do
			db_fset apt-setup/directory isdefault true
			db_input critical apt-setup/directory || true
			db_go || continue 2
			db_get apt-setup/directory
			
			# A very simple mirror sanity check.
			if [ ! -d "$RET" ]; then
				db_fset apt-setup/baddir isdefault true
				db_input critical apt-setup/baddir || true
				db_go || true
			elif [ ! -d "$RET/dists" ]; then
				db_fset apt-setup/not-mirror isdefault true
				db_input critical apt-setup/not-mirror || true
				db_go || true
			else
				LOOP=''
			fi
		done
	;;
	*)
		touch ${APTETC}sources.list
		cp -f ${APTETC}sources.list ${APTETC}sources.list.bak
		# Just run an editor on the sources.list file, then
		# check the result. If it fails, show the problem and loop.
		if [ -z "$EDITOR" ]; then
			EDITOR=/usr/bin/editor
		fi
		EDITOK=""
		while [ ! "$EDITOK" ]; do
			touch ${APTETC}sources.list
			$EDITOR ${APTETC}sources.list >/dev/tty </dev/tty
			tempfile=`tempfile`
			clear >/dev/tty </dev/tty
			echo "Testing apt sources ..."
			if $APTGET -o APT::Get::List-Cleanup=false -o Dir::Etc::sourcelist=${APTETC}sources.list update 2>$tempfile; then
				clear >/dev/tty </dev/tty
				EDITOK=1
			else
				clear >/dev/tty </dev/tty
				db_fset apt-setup/badedit isdefault true
				db_subst apt-setup/badedit apt_error `tr '\n' ' ' < $tempfile`
				db_input critical apt-setup/badedit || true
				db_go || true
				db_get apt-setup/badedit
				if [ "$RET" != "edit" ]; then
					mv -f ${APTETC}sources.list.bak ${APTETC}sources.list
					continue 2
				fi
			fi
		done
		MAINLOOP=""
		rm -f /etc/apt/sources.list.bak
		continue
	esac

	# The temporary file to use as sources.list for testing
	# new items.
	tmpsources=`tempfile`

	db_get apt-setup/hostname
	HOST="$RET"
	db_get apt-setup/directory
	DIR="$RET"
	db_get apt-setup/distribution
	DIST="$RET"
	
	db_get apt-setup/non-free
	if [ "$RET" = true ]; then
		NONFREE="non-free"
	else
		NONFREE=""
	fi
	db_get apt-setup/contrib
	if [ "$RET" = true ]; then
		CONTRIB="contrib"
	else
		CONTRIB=""
	fi
	if [ "$URI" = ftp -o "$URI" = http ]; then
		SEP=//
	else
		SEP=""
	fi
	if [ "$URI" = file ]; then
		HOST=""
	fi

	echo "deb $URI:$SEP$HOST$DIR $DIST main $NONFREE $CONTRIB" >> $tmpsources
	SRCENTRY="deb-src $URI:$SEP$HOST$DIR $DIST main $NONFREE $CONTRIB"

	# If there is a http proxy, make apt use it temporarily.
	db_get apt-setup/http_proxy
	if [ "$RET" ]; then
		PROXY_OPTS="-o Acquire::http::Proxy=\"$RET\""
	else
		PROXY_OPTS=""
	fi

	# As a final sanity check, run apt-get update, and catch the
	# return code and errors.
	tempfile=`tempfile`
	clear >/dev/tty </dev/tty
	echo "Testing apt sources ..."
	if ! $APTGET $PROXY_OPTS -o APT::Get::List-Cleanup=false -o Dir::Etc::sourcelist=$tmpsources update 2>$tempfile; then
		clear >/dev/tty </dev/tty
		# Show the user the error message and loop.
		db_subst apt-setup/badsource apt_error `tr '\n' ' ' < $tempfile`
		db_fset apt-setup/badsource isdefault true
		db_input critical apt-setup/badsource || true
		db_go || true
		rm -f $tempfile $tmpsources
		continue
	fi
	# Success, so add the entry to the real sources.list
	touch ${APTETC}sources.list
	echo "" >> ${APTETC}sources.list
	cat $tmpsources >> ${APTETC}sources.list
	MAINLOOP=""
	
	# Success, so add proxy information if not already present.
	db_get apt-setup/http_proxy
	if [ "$RET" ]; then
		touch $APTETC/apt.conf
		if ! grep -iq 'Acquire::http::Proxy' $APTETC/apt.conf; then
			echo "Acquire::http::Proxy \"$RET\";" >> $APTETC/apt.conf
		fi
	fi
	
	# We have a deb-src line to add too. Test it, see if it works. If not,
	# don't fail, just don't add it.
	echo "$SRCENTRY" > $tmpsources
	if $APTGET -o APT::Get::List-Cleanup=false -o Dir::Etc::sourcelist=$tmpsources update 2>/dev/null; then
		echo "$SRCENTRY" >> ${APTETC}sources.list
	fi
	clear >/dev/tty </dev/tty

	# Handle non-us entries.
	db_get apt-setup/non-us
	if [ "$RET" = true ]; then
		LINE="http://non-us.debian.org/debian-non-US $DIST/non-US main"
		if [ "$CONTRIB" ]; then
			LINE="$LINE contrib"
		fi
		if [ "$NONFREE" ]; then
			LINE="$LINE non-free"
		fi
		# Test the generated line with apt.
		echo "deb $LINE" > $tmpsources
		clear >/dev/tty </dev/tty
		echo "Testing apt sources ..."
		if ! $APTGET -o APT::Get::List-Cleanup=false -o Dir::Etc::sourcelist=$tmpsources update 2>$tempfile; then
			# Display failure message.
			clear >/dev/tty </dev/tty
			echo $LINE
			db_subst apt-setup/non-us-failed apt_error `tr '\n' ' ' < $tempfile`
			db_fset apt-setup/non-us-failed isdefault true
			db_input critical apt-setup/non-us-failed || true
			db_go || true
			rm -f $tempfile $tmpsources
			continue
		fi
		# Success, add to real sources.list.
		echo "deb $LINE" >> ${APTETC}sources.list

		# Try to add a deb-src line too.
		echo "deb-src $LINE" > $tmpsources
		if $APTGET -o APT::Get::List-Cleanup=false -o Dir::Etc::sourcelist=$tmpsources update 2>/dev/null; then
			echo "deb-src $LINE" >> ${APTETC}sources.list
		fi
		clear >/dev/tty </dev/tty
	fi

	rm -f $tempfile $tmpsources
done

# Finally, see about adding a security.debian.org entry. This is a PITA. I
# have to deal with these situations:
# * installing from CD; no network connectivity: add it, commented out
# * already have it in sources.list, uncommented: don't ask about it
# * adding it when the user has picked non-free and/or contrib at least
#   some of the time: include those
# * adding it when the user has not: don't include those

# First, if it exists and is not commented out, don't ask about it.
# (Well, this isn't perfect, because they may have a bad entry that doesn't
# cover what they just added.)
if ! grep -q '^[^#]*security.debian.org' ${APTETC}sources.list; then
	# Figure out what line to add (we're definitely going to add something,
	# even if it's just a comment).
	#
	# To determine if non-free and contrib should be included, grep
	# the file to see if they are listed in it.
	DISTS="main"
	for dist in contrib non-free; do
		if grep -q '^[^#]*non-free' ${APTETC}sources.list; then
			DISTS="$DISTS $dist"
		fi
	done
	LINE="http://security.debian.org/ stable/updates $DISTS"

	COMMENT="# "

	# Now ask if they want the entry to be added.
	db_fset apt-setup/security-updates isdefault true
	db_input medium apt-setup/security-updates || true
	db_go || true
	db_get apt-setup/security-updates
	if [ "$RET" = true ]; then
		# Test it.
		tmpsources=`tempfile`
		echo "deb $LINE" > $tmpsources
		clear >/dev/tty </dev/tty
		echo "Testing apt sources ..."
		tempfile=`tempfile`
		if ! $APTGET -o APT::Get::List-Cleanup=false -o Dir::Etc::sourcelist=$tmpsources update 2>$tempfile; then
			# Display failure message
			clear >/dev/tty </dev/tty
			db_subst apt-setup/security-updates-failed apt_error `tr '\n' ' ' < $tempfile`
			db_fset apt-setup/security-updates-failed isdefault true
			db_input critical apt-setup/security-updates-failed || true
			db_go || true
		else
			# Success. Don't comment them out.
			COMMENT=""
			# TODO: test and add deb-src too.
		fi
	
		rm -f $tempfile $tmpsources
	fi

	# Now add the entry, commented out or not. (Don't add the commented
	# version if a commented version already exists.)
	if [ -z "$COMMENT" ] || ! grep -q '#.*security.debian.org' ${APTETC}sources.list; then
		echo "" >>${APTETC}sources.list
		echo "${COMMENT}deb $LINE" >>${APTETC}sources.list
	fi	
fi