-
Notifications
You must be signed in to change notification settings - Fork 153
/
rcS
executable file
·1713 lines (1511 loc) · 55.1 KB
/
rcS
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
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
#!/bin/sh
# "Check exit code directly with e.g. 'if mycmd;', not indirectly with $?"
# IIRC we did that deliberately, so suppress the warning.
# If I/we change that in the future, we can re-enable it then.
# shellcheck disable=SC2181
LOGFILE=/tmp/raspbian-ua-netinst.log
CDEBOOTSTRAP_BIN=cdebootstrap
# default options, can be overriden in installer-config.txt
preset=server
packages=
mirror=http://mirrordirector.raspbian.org/raspbian/
release=buster
init_system=systemd
hostname=pi
boot_volume_label=
domainname=
rootpw=raspbian
root_ssh_pubkey=
disable_root=
username=
userpw=
user_ssh_pubkey=
user_is_admin=
cdebootstrap_cmdline=
bootsize=+256M
bootoffset=8192
rootsize=
timeserver=time.nist.gov
timezone=Etc/UTC
locales=
system_default_locale=
disable_predictable_nin=1
ifname=eth0
ip4_addr=dhcp
ip4_prefixlength=0
ip4_gateway=0.0.0.0
ip4_nameservers=
ip6_addr=disable
ip6_prefixlength=0
ip6_gateway=auto
ip6_nameservers=auto
drivers_to_load=
online_config=
usbroot=
cmdline="dwc_otg.lpm_enable=0 console=ttyAMA0,115200 kgdboc=ttyAMA0,115200 console=tty1 elevator=deadline"
rootfstype=ext4
final_action=reboot
hardware_versions=detect
hwrng_support=1
enable_watchdog=0
enable_uart=0
gpu_mem=
fail_action=poweroff
# these shouldn't really be changed unless auto-detection fails
bootdev=/dev/mmcblk0
bootpartition=/dev/mmcblk0p1
rootdev=/dev/mmcblk0
rootpartition=
log_msg()
{
printf '%s\n' "$*"
}
log_msg_start()
{
printf '%s' "$*"
}
log_msg_inline()
{
log_msg_start "$*"
}
log_msg_end()
{
log_msg "$*"
}
fail()
{
log_msg
log_msg "Oh noes, something went wrong!"
# copy logfile to /boot/ partition to preserve it.
# test whether the sd card is still mounted on /boot and if not, mount it.
if [ ! -f /boot/bootcode.bin ] ; then
mount $bootpartition /boot
fail_boot_mounted=true
fi
cp -- $LOGFILE /boot/raspbian-ua-netinst-"$(date +%Y%m%dT%H%M%S)".log
sync
# if we mounted /boot in the fail command, unmount it.
if [ "$fail_boot_mounted" = true ] ; then
umount /boot
fi
case "$fail_action" in
"poweroff")
poweroff
;;
"reboot")
reboot
;;
"halt")
halt
;;
"shell")
sh
;;
"*")
log_msg "Invalid 'fail_action' value, falling back to default (poweroff)"
poweroff
;;
esac
exit
}
sanitize_inputfile()
{
if [ -z "$1" ]
then
log_msg "No input file specified!"
else
inputfile=$1
# convert line endings to unix
dos2unix "$inputfile"
fi
}
install_files()
{
file_to_read="$1"
log_msg "Adding files & folders listed in /bootfs/config/$file_to_read"
sanitize_inputfile "/bootfs/config/$file_to_read"
grep -v "^[[:space:]]*#\|^[[:space:]]*$" "/bootfs/config/${file_to_read}" | while read -r line; do
owner=$(printf '%s' "$line" | awk '{ print $1 }')
perms=$(printf '%s' "$line" | awk '{ print $2 }')
file=$(printf '%s' "$line" | awk '{ print $3 }')
log_msg " $file"
if [ ! -d "/bootfs/config/files$file" ]; then
mkdir -p "/rootfs$(dirname "$file")"
cp "/bootfs/config/files$file" "/rootfs$file"
else
mkdir -p "/rootfs/$file"
fi
chmod "$perms" "/rootfs$file"
chroot /rootfs chown "$owner" "$file"
done
log_msg
}
setup_chroot()
{
if [ -d "$1" ]; then
CHROOT_DIR=$1
log_msg_start "Setting up chroot in $CHROOT_DIR... "
mount --bind /proc "$CHROOT_DIR/proc"
mount --bind /sys "$CHROOT_DIR/sys"
mount --bind /dev "$CHROOT_DIR/dev"
mount --bind /dev/pts "$CHROOT_DIR/dev/pts"
log_msg_end "OK"
else
log_msg "'$1' doesn't exist or isn't a directory, so not setting up chroot."
fi
}
teardown_chroot()
{
if [ -d "$1" ]; then
CHROOT_DIR=$1
log_msg_start "Tearing down chroot in $CHROOT_DIR... "
umount "$CHROOT_DIR/dev/pts"
umount "$CHROOT_DIR/dev"
umount "$CHROOT_DIR/sys"
umount "$CHROOT_DIR/proc"
log_msg_end "OK"
else
log_msg "'$1' doesn't exist or isn't a directory, so not tearing down chroot."
fi
}
is_change_in_release()
{
changedate=$1
release=$(printf '%s' "$2" | tr '[:upper:]' '[:lower:]')
releasedate=$(awk -F "," -v releasename="$release" '{ if ($3 == releasename) print $5}' /usr/share/distro-info/debian.csv)
case $releasedate in
*[![:blank:]]*)
#valid release date
;;
*)
#invalid release date, so set it explicitly to null
releasedate="null"
;;
esac
#return 1 if there is no release date known (Sid/Testing or (now) Bullseye) OR when releasedate >= changedate
if [ "$releasedate" = "null" ] || [ "$(printf '%s' "$releasedate" | tr -d -)" -ge "$(printf '%s' "$changedate" | tr -d -)" ] ; then
log_msg 1
else
log_msg 0
fi
}
show_deprecation_notice()
{
if [ -z "$1" ]; then
exit 1
fi
log_msg "***********************************************************"
log_msg " DEPRECATION NOTICE "
log_msg "***********************************************************"
config_id=$1
case "$config_id" in
"ip_addr")
log_msg "You are using the setting 'ip_addr', but that is deprecated."
log_msg "Please use 'ip4_addr' instead."
config_change="remove"
;;
"ip_gateway")
log_msg "You are using the setting 'ip_gateway', but that is deprecated."
log_msg "Please use 'ip4_gateway' instead."
config_change="remove"
;;
"ip_nameservers")
log_msg "You are using the setting 'ip_nameservers', but that is deprecated."
log_msg "Please use 'ip4_nameservers' instead."
config_change="remove"
;;
"ip_netmask")
log_msg "You are using the setting 'ip_netmask', but that is deprecated."
log_msg "Please use 'ip4_prefixlength' instead."
config_change="remove"
;;
"preset")
log_msg "You are using an unknown 'preset', but that is deprecated."
log_msg "Please use 'base', 'minimal' or 'server' instead."
config_change="remove"
;;
"try_again")
log_msg "You are using the setting 'try_again', but that is deprecated."
log_msg "Please use 'fail_action' instead."
config_change="remove"
;;
esac
case "$config_change" in
"remove")
log_msg "In the next major release, this setting will no longer work"
log_msg "and the compatibility code will be removed."
log_msg "Consequently, the installer will probably not do"
log_msg "what you want or may fail entirely."
;;
esac
log_msg "************************************************************"
}
/bin/busybox mkdir -p /opt/busybox/bin/
/bin/busybox --install /opt/busybox/bin/
export PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/opt/busybox/bin
mkdir -p /proc
mkdir -p /sys
mkdir -p /boot
mkdir -p /usr/bin
mkdir -p /usr/sbin
mkdir -p /var/run
mkdir -p /etc/raspbian-ua-netinst
mkdir -p /rootfs/boot
mkdir -p /bootfs
mkdir -p /tmp/
# put PATH in /etc/profile so it's also available when we get a busybox shell
printf "%s\n" "export PATH=${PATH}" > /etc/profile
mount -t proc proc /proc
mount -t sysfs sysfs /sys
mount -t tmpfs -o size=64k,mode=0755 tmpfs /dev
mkdir /dev/pts
mount -t devpts devpts /dev/pts
printf "%s\n" /opt/busybox/bin/mdev > /proc/sys/kernel/hotplug
mdev -s
if [ -e /proc/mounts ] ; then
ln -s /proc/mounts /etc/mtab
else
log_msg "/proc/mounts doesn't exist (here)"
fi
klogd -c 1
# remove unused drivers from ram disk
for folder in /lib/modules/*; do
if [ "$(basename "${folder}")" != "$(uname -r)" ]; then
rm -r "${folder}"
fi
done
# set screen blank period to an hour unless consoleblank=0 on cmdline
# hopefully the install should be done by then
if grep -qv "consoleblank=0" /proc/cmdline; then
printf '\033[9;60]'
fi
# Check if there's an alternative rcS file and excute it
# instead of this file. Only do this if this isn't the
# alternative script already
if [ -z "${am_subscript}" ]; then
mkdir -p /boot
mount $bootpartition /boot
if [ -e /boot/config/installer/rcS ]; then
cp /boot/config/installer/rcS /rcS
umount /boot
log_msg "============================================="
log_msg "=== Start executing alternative rcS ========="
log_msg "---------------------------------------------"
export am_subscript=true
# shellcheck disable=SC1091 # external file
. /rcS
log_msg "---------------------------------------------"
log_msg "=== Execution of alternative rcS finished ==="
log_msg "============================================="
${final_action} || reboot || exit
else
# Clean up, so the rest of the script continues as expected
umount /boot
fi
fi
# redirect stdout and stderr also to logfile
# http://stackoverflow.com/questions/3173131/redirect-copy-of-stdout-to-log-file-from-within-bash-script-itself/6635197#6635197
mkfifo ${LOGFILE}.pipe
tee < ${LOGFILE}.pipe $LOGFILE &
exec > ${LOGFILE}.pipe 2>&1
rm ${LOGFILE}.pipe
# we should do this with bitshift operations, I think on the serial
# http://elinux.org/RPi_HardwareHistory#Board_Revision_History
# https://www.raspberrypi.org/documentation/hardware/raspberrypi/revision-codes/README.md
cpu_revision=$(grep Revision /proc/cpuinfo | cut -d " " -f 2 | sed 's/^1000//')
case $cpu_revision in
900092|900093|9000c1|920092|920093)
rpi_hardware_version="0"
;;
0002|0003|0004|0005|0006|0007|0008|0009|000d|000e|000f|0010|0012|0013|0015|900021|900032)
rpi_hardware_version="1"
;;
a01040|a01041|a21041|a22042)
rpi_hardware_version="2"
;;
9020e0|a02082|a020d3|a22082|a22083|a32082|a52082)
rpi_hardware_version="3"
;;
a03111|b03111|c03111)
rpi_hardware_version="4"
;;
*)
rpi_hardware_version="unknown"
;;
esac
log_msg ""
log_msg "================================================="
log_msg "raspbian-ua-netinst"
log_msg "================================================="
log_msg "__VERSION__"
log_msg "Built on __DATE__"
log_msg "Running on Raspberry Pi version ${rpi_hardware_version}"
log_msg "================================================="
log_msg "https://github.com/debian-pi/raspbian-ua-netinst/"
log_msg "================================================="
log_msg_start "Starting HWRNG "
modprobe bcm2835-rng
/usr/sbin/rngd -r /dev/hwrng
if [ $? -eq 0 ]; then
log_msg_end "succeeded!"
else
log_msg_end "FAILED! (continuing to use the software RNG)"
fi
log_msg_start "Copying boot files... "
# copy boot data to safety
mount $bootpartition /boot || fail
cp -r -- /boot/* /bootfs/ || fail
umount /boot || fail
log_msg_end "OK"
if [ -e /bootfs/installer-config.txt ]; then
log_msg "================================================="
log_msg "=== Start executing installer-config.txt. ==="
sanitize_inputfile /bootfs/installer-config.txt
# shellcheck disable=SC1091 # external file
. /bootfs/installer-config.txt
log_msg "=== Finished executing installer-config.txt. ==="
log_msg "================================================="
fi
if [ -e /bootfs/config/wpa_supplicant.conf ]; then
sanitize_inputfile /bootfs/config/wpa_supplicant.conf
fi
# Provide backwards compatibility for v1.0 configurations which used
# "ip_" prefix instead of "ip4_"
# shellcheck disable=SC2154 # deprecated var name
if [ -n "$ip_addr" ]; then
ip4_addr="$ip_addr"
show_deprecation_notice "ip_addr"
fi
# shellcheck disable=SC2154 # deprecated var name
if [ -n "$ip_gateway" ]; then
ip4_gateway="$ip_gateway"
show_deprecation_notice "ip_gateway"
fi
# shellcheck disable=SC2154 # deprecated var name
if [ -n "$ip_nameservers" ]; then
ip4_nameservers="$ip_nameservers"
show_deprecation_notice "ip_nameservers"
fi
# Provide backwards compatibility for v1.0 configurations which used
# "ip_netmask" instead of "ip4_prefixlength"
# shellcheck disable=SC2154 # deprecated var name
if [ -n "$ip_netmask" ]; then
ip4_prefixlength=$(ipcalc -p 255.255.255.255 "$ip_netmask" | cut -d= -f2)
show_deprecation_notice "ip_netmask"
fi
# in v1.2.x "try_again" was replaced with "fail_action"
# shellcheck disable=SC2154 # deprecated var name
if [ -n "$try_again" ]; then
if [ "$try_again" = "0" ]; then
fail_action="poweroff"
elif [ "$try_again" = "1" ]; then
fail_action="reboot"
else
fail_action="poweroff"
log_msg "ERROR: The 'try_again' variable had an invalid value, setting 'fail_action' to 'poweroff'"
fi
show_deprecation_notice "try_again"
fi
log_msg
log_msg "Network configuration:"
log_msg " ip4_addr = $ip4_addr"
if [ "$ip4_addr" = "disable" ]; then
# nothing to do, just pass
:
elif [ "$ip4_addr" != "dhcp" ]; then
log_msg " ip4_prefixlength = $ip4_prefixlength"
log_msg " ip4_gateway = $ip4_gateway"
log_msg " ip4_nameservers = $ip4_nameservers"
fi
log_msg " ip6_addr = $ip6_addr"
if [ "$ip6_addr" = "disable" ]; then
# nothing to do, just pass
:
elif [ "$ip6_addr" = "auto" ]; then
log_msg " ip6_nameservers = $ip6_nameservers"
else
log_msg " ip6_prefixlength = $ip6_prefixlength"
log_msg " ip6_gateway = $ip6_gateway"
log_msg " ip6_nameservers = $ip6_nameservers"
fi
log_msg " online_config = $online_config"
log_msg
# depmod needs to update modules.dep before using modprobe
depmod -a
# coldplug modules
log_msg "Loading drivers."
find /sys/ -name modalias -print0 | xargs -0 sort -u -z | xargs -0 modprobe -abq
log_msg "Finished loading drivers."
if [ "$drivers_to_load" != "" ] ; then
log_msg "Loading additional drivers."
for driver in $drivers_to_load
do
log_msg_start " Loading driver '$driver' ... "
modprobe "$driver" || fail
log_msg_end "OK"
done
log_msg "Finished loading additional drivers"
fi
log_msg_start "Waiting for $ifname... "
for i in $(seq 1 10); do
ifconfig $ifname 1>/dev/null 2>&1
if [ $? -eq 0 ]; then
log_msg_end "OK"
break
fi
if [ "$i" -eq 10 ]; then
log_msg_end "FAILED"
fail
fi
sleep 1
log_msg_inline "$i.. "
done
if [ "$ifname" != "eth0" ]; then
# Replace eth0 as udhcpc dns interface
sed -i "s/PEERDNS_IF=.*/PEERDNS_IF=$ifname/g" /etc/udhcpc/default.script
# if eth0 is not the chosen eth interface it is a wireless interface and wpa_supplicant must connect to wlan
log_msg "Starting wpa_supplicant... "
wpa_supplicant -B -Dnl80211 -c/bootfs/config/wpa_supplicant.conf -i$ifname
if [ $? -ne 0 ]; then
log_msg "nl80211 driver didn't work. Trying generic driver (wext)..."
wpa_supplicant -B -Dwext -c/bootfs/config/wpa_supplicant.conf -i$ifname || fail
log_msg "Connection with wext succeeded."
fi
fi
# do some IPv6 configuration which must be done before the
# network interface is brought up
if [ "$ip6_addr" != "disable" ]; then
modprobe ipv6
if [ "$ip6_addr" != "auto" ]; then
if [ "$ip6_gateway" != "auto" ]; then
# disable the acceptance of incoming Router Advertisement (RA)
# messages, otherwise the kernel might automatically add routes
printf '%d' 0 > /proc/sys/net/ipv6/conf/$ifname/accept_ra
else
# disable automatic generation of IPv6 addresses, which the kernel
# will do when it receives a suitable RA
printf '%d' 0 > /proc/sys/net/ipv6/conf/$ifname/autoconf
fi
fi
fi
ip link set lo up
ip link set $ifname up
touch /etc/resolv.conf
if [ "$ip4_addr" = "disable" ]; then
# if IPv4 is disabled, configure the DNS resolver in glibc
# to prefer IPv6 addresses (by performing AAAA lookups
# before A lookups)
printf '%s' "options inet6" >> /etc/resolv.conf
elif [ "$ip4_addr" = "dhcp" ]; then
log_msg_start "Configuring $ifname for IPv4 using DHCP... "
udhcpc -t 5 -T 20 -R -i $ifname 1>/dev/null 2>&1
if [ $? -eq 0 ]; then
have_ip4=$(ip -4 addr ls $ifname | grep 'scope global' | awk '{print $2}')
log_msg_end "$have_ip4"
else
log_msg_end "FAILED"
fi
else
log_msg_start "Configuring $ifname for IPv4 using static $ip4_addr... "
ip addr add "$ip4_addr"/"$ip4_prefixlength" dev $ifname || fail
ip route add default via "$ip4_gateway" || fail
for i in $ip4_nameservers; do
printf "nameserver %s" "$i" >> /etc/resolv.conf
done
have_ip4=$ip4_addr
log_msg_end "OK"
fi
if [ "$ip6_addr" != "disable" ]; then
log_msg_start "Waiting for IPv6 link-local address on $ifname... "
for i in $(seq 1 10); do
if ip -6 addr show dev $ifname scope link | grep -q 'scope link'; then
break
fi
if [ "$i" -eq 10 ]; then
log_msg_end "FAILED"
fail
fi
sleep 1
log_msg_inline "$i.. "
done
# ensure that the IPv6 stack is ready; race conditions are fun!
sleep 2
log_msg_end "OK"
rdisc6 $ifname > /tmp/ip6_ra
# the 'awk' usage below is to trim whitespace around the value
ip6_ra_m=$(grep 'Stateful address' /tmp/ip6_ra | cut -d: -f2- | awk '{$1=$1};1')
if [ "$ip6_ra_m" = "Yes" ]; then
log_msg "IPv6 on this network is provided by DHCPv6, but this installer does not support DHCPv6."
log_msg "IPv6 will be disabled."
ip6_addr=disable
fi
# the 'awk' usage below is to trim whitespace around the value
ip6_ra_o=$(grep 'Stateful other' /tmp/ip6_ra | cut -d: -f2- | awk '{$1=$1};1')
if [ "$ip6_ra_o" = "Yes" ]; then
log_msg "IPv6 DNS and other information on this network is provided by DHCPv6, but this installer does not support DHCPv6."
log_msg "IPv6 will be disabled."
ip6_addr=disable
fi
fi
if [ "$ip6_addr" = "disable" ]; then
# nothing to do, just pass
:
elif [ "$ip6_addr" = "auto" ]; then
log_msg_start "Configuring $ifname for IPv6 using SLAAC... "
for i in $(seq 1 10); do
ip -6 addr ls $ifname | grep -q 'scope global'
if [ $? -eq 0 ]; then
have_ip6=$(ip -6 addr ls $ifname | grep 'scope global' | awk '{print $2}')
log_msg_end "$have_ip6"
break
fi
if [ "$i" -eq 10 ]; then
log_msg_end "FAILED"
fi
sleep 1
log_msg_inline "$i.. "
done
else
log_msg_start "Configuring $ifname for IPv6 using static $ip6_addr... "
ip addr add "$ip6_addr"/"$ip6_prefixlength" dev $ifname || fail
if [ "$ip6_gateway" != "auto" ]; then
ip route add default via "$ip6_gateway" || fail
fi
have_ip6=$ip6_addr
log_msg_end "OK"
fi
if [ -n "$have_ip6" ]; then
if [ "$ip6_nameservers" = "auto" ]; then
log_msg_start "Obtaining IPv6 recursive DNS server address(es) via RDNSS... "
have_ip6_nameservers=$(grep 'Recursive DNS' /tmp/ip6_ra | cut -d: -f2-)
if [ -z "$have_ip6_nameservers" ]; then
log_msg_end "FAILED"
else
log_msg_end "$have_ip6_nameservers"
fi
elif [ "$ip6_nameservers" != "disable" ]; then
have_ip6_nameservers=$ip6_nameservers
fi
if [ -n "$have_ip6_nameservers" ]; then
for i in $have_ip6_nameservers; do
printf "nameserver %s" "$i" >> /etc/resolv.conf
done
fi
log_msg_end "OK"
fi
if [ -z "$have_ip4" ] && [ -z "$have_ip6" ]; then
log_msg "No IPv4 or IPv6 addresses were configured or obtained. Installation cannot continue."
fail
fi
# This will record the time to get to this point
PRE_NETWORK_DURATION=$(date +%s)
date_set=false
if [ "$date_set" = "false" ] ; then
# set time with ntpdate
ntpdate-debian -b 1>/dev/null 2>&1
if [ $? -eq 0 ] ; then
log_msg_start "Time set using ntpdate to... "
date
date_set=true
else
log_msg "Failed to set time using ntpdate!"
fi
if [ "$date_set" = "false" ] ; then
# failed to set time with ntpdate, fall back to rdate
# time server addresses taken from http://tf.nist.gov/tf-cgi/servers.cgi
timeservers=$timeserver
timeservers="$timeservers time.nist.gov nist1.symmetricom.com"
timeservers="$timeservers nist-time-server.eoni.com utcnist.colorado.edu"
timeservers="$timeservers nist1-pa.ustiming.org nist.expertsmi.com"
timeservers="$timeservers nist1-macon.macon.ga.us wolfnisttime.com"
timeservers="$timeservers nist.time.nosc.us nist.netservicesgroup.com"
timeservers="$timeservers nisttime.carsoncity.k12.mi.us nist1-lnk.binary.net"
timeservers="$timeservers ntp-nist.ldsbc.edu utcnist2.colorado.edu"
timeservers="$timeservers nist1-ny2.ustiming.org wwv.nist.gov"
for ts in $timeservers
do
rdate "$ts" 1>/dev/null 2>&1
if [ $? -eq 0 ]; then
log_msg_start "Time set using timeserver '$ts' to... "
date
date_set=true
break
else
log_msg "Failed to set time using timeserver '$ts'."
fi
done
fi
fi
if [ "$date_set" = "false" ] ; then
log_msg "FAILED to set the date, so things are likely to fail now ..."
log_msg "Make sure that rdate port 37 is not blocked by your firewall."
fi
# Record the time now that the time is set to a correct value
STARTTIME=$(date +%s)
# And substract the PRE_NETWORK_DURATION from STARTTIME to get the
# REAL starting time.
REAL_STARTTIME=$((STARTTIME - PRE_NETWORK_DURATION))
log_msg ""
log_msg "Installation started at $(date --date="@$REAL_STARTTIME" --utc)."
log_msg ""
if [ "$online_config" != "" ]; then
log_msg_start "Downloading online config from $online_config... "
curl -L --silent -o /online-config.txt "$online_config" 1>/dev/null 2>&1 || fail
log_msg_end "OK"
log_msg "================================================="
log_msg "=== Start executing online-config.txt. ==="
sanitize_inputfile /online-config.txt
# shellcheck disable=SC1091 # external file
. /online-config.txt
log_msg "=== Finished executing online-config.txt. ==="
log_msg "================================================="
fi
if [ "$hardware_versions" = "detect" ]; then
case $rpi_hardware_version in
0) hardware_versions="0" ;;
1) hardware_versions="1" ;;
2) hardware_versions="2" ;;
3) hardware_versions="3" ;;
4) hardware_versions="4" ;;
*)
log_msg ""
log_msg "================================================="
log_msg " No Raspberry Pi hardware detected!!"
log_msg " Value of cpu_revision variable: '${cpu_revision}'"
log_msg " Building for Pi 0, 1, 2, 3 and 4."
log_msg "================================================="
log_msg ""
hardware_versions="0 1 2 3 4"
;;
esac
fi
# prepare rootfs mount options
case "$rootfstype" in
"btrfs")
rootfs_mkfs_options=${rootfs_mkfs_options:-'-f'}
rootfs_install_mount_options=${rootfs_install_mount_options:-'noatime'}
rootfs_mount_options=${rootfs_mount_options:-'noatime'}
;;
"ext4")
rootfs_mkfs_options=${rootfs_mkfs_options:-''}
rootfs_install_mount_options=${rootfs_install_mount_options:-'noatime,data=writeback,nobarrier,noinit_itable'}
rootfs_mount_options=${rootfs_mount_options:-'errors=remount-ro,noatime'}
;;
"f2fs")
rootfs_mkfs_options=${rootfs_mkfs_options:-'-f'}
rootfs_install_mount_options=${rootfs_install_mount_options:-'noatime'}
rootfs_mount_options=${rootfs_mount_options:-'noatime'}
;;
*)
log_msg "Unknown filesystem specified: $rootfstype"
fail
;;
esac
# check if we need to install wpasupplicant package
if [ "$ifname" != "eth0" ]; then
if [ -z "$packages" ]; then
packages="wpasupplicant"
else
packages="$packages,wpasupplicant"
fi
fi
# check if we need the sudo package and add it if so
if [ "$user_is_admin" = "1" ]; then
if [ -z "$packages" ]; then
packages="sudo"
else
packages="$packages,sudo"
fi
fi
# configure different kinds of presets
if [ "$cdebootstrap_cmdline" = "" ]; then
# from small to large: base, minimal, server
# not very logical that minimal > base, but that's how it was historically defined
# base
base_packages="cpufrequtils,kmod"
for hv in ${hardware_versions}
do
case $hv in
0|1) kernel_meta_package=linux-image-rpi-rpfv ;;
2|3|4) kernel_meta_package=linux-image-rpi2-rpfv ;;
*)
log_msg ""
log_msg "================================================="
log_msg " I don't understand a hardware version of ${hv} "
log_msg " Skipping the kernel work for that hardware. "
log_msg "================================================="
log_msg ""
kernel_meta_package=none ;;
esac
# shellcheck disable=SC2086 # overkill as 'hv' is only a number 0-4
eval kernel_meta_package_${hv}=${kernel_meta_package}
if [ ${kernel_meta_package} != "none" ] ; then
base_packages="${kernel_meta_package},${base_packages}"
fi
done
if [ "$init_system" = "systemd" ] ; then
base_packages="${base_packages},systemd-sysv"
base_packages="${base_packages},libpam-systemd"
elif [ "$init_system" = "sysvinit" ] ; then
base_packages="${base_packages},sysvinit-core"
elif [ "$init_system" = "runit" ] ; then
base_packages="${base_packages},runit-init"
fi
if [ "$hwrng_support" = "1" ]; then
base_packages="${base_packages},rng-tools"
fi
filesystem_packages="dosfstools"
if [ "$rootfstype" = "ext4" ]; then
filesystem_packages="${filesystem_packages},e2fsprogs"
elif [ "$rootfstype" = "f2fs" ]; then
filesystem_packages="${filesystem_packages},f2fs-tools"
elif [ "$rootfstype" = "btrfs" ]; then
filesystem_packages="${filesystem_packages},btrfs-progs"
fi
base_packages="${base_packages},${filesystem_packages}"
# minimal
minimal_packages="fake-hwclock,ifupdown,net-tools,ntp,openssh-server,resolvconf"
if [ -n "$have_ip6" ] && [ "$ip6_nameservers" = "auto" ]; then
minimal_packages="${minimal_packages},rdnssd"
fi
# server
server_packages="vim-tiny,iputils-ping,wget,ca-certificates,rsyslog,cron,dialog,locales,less,man-db"
case $preset in
base)
cdebootstrap_cmdline="--flavour=minimal --include=${base_packages}"
;;
minimal)
cdebootstrap_cmdline="--flavour=minimal --include=${base_packages},${minimal_packages}"
;;
*)
# this should be 'server', but using '*' for backward-compatibility
cdebootstrap_cmdline="--flavour=minimal --include=${base_packages},${minimal_packages},${server_packages}"
if [ "$preset" != "server" ]; then
show_deprecation_notice "preset"
log_msg "Using 'server' as fallback preset"
fi
;;
esac
dhcp_client_package="isc-dhcp-client"
# add IPv4 DHCP client if needed
if [ "$ip4_addr" = "dhcp" ]; then
cdebootstrap_cmdline="${cdebootstrap_cmdline},${dhcp_client_package}"
fi
# add user defined packages
if [ "$packages" != "" ]; then
cdebootstrap_cmdline="${cdebootstrap_cmdline},${packages}"
fi
else
preset=none
fi
if [ "$usbroot" = "1" ]; then
rootdev=/dev/sda
log_msg_start "Loading USB modules... "
# only do modprobe if the module is NOT built into the kernel
if [ "$(grep -c "sd_mod" /lib/modules/"$(uname -r)"/modules.builtin)" -eq 0 ]; then
modprobe sd_mod 1>/dev/null 2>&1 || fail
fi
if [ "$(grep -c "usb-storage" /lib/modules/"$(uname -r)"/modules.builtin)" -eq 0 ]; then
modprobe usb-storage 1>/dev/null 2>&1 || fail
fi
log_msg_end "OK"
fi
if [ "$rootpartition" = "" ]; then
if [ "$rootdev" = "/dev/sda" ]; then
rootpartition=/dev/sda1
else
rootpartition=/dev/mmcblk0p2
fi
fi
log_msg
log_msg "Installer configuration:"
log_msg " preset = $preset"
log_msg " packages = $packages"
log_msg " mirror = $mirror"
log_msg " release = $release"
log_msg " init_system = $init_system"
log_msg " hostname = $hostname"
log_msg " domainname = $domainname"
log_msg " rootpw = $rootpw"
log_msg " root_ssh_pubkey = $root_ssh_pubkey"
log_msg " disable_root = $disable_root"
log_msg " username = $username"
log_msg " userpw = $userpw"
log_msg " user_ssh_pubkey = $user_ssh_pubkey"
log_msg " user_is_admin = $user_is_admin"
log_msg " cdebootstrap_cmdline = $cdebootstrap_cmdline"
log_msg " boot_volume_label = $boot_volume_label"
log_msg " bootsize = $bootsize"
log_msg " bootoffset = $bootoffset"
log_msg " rootsize = $rootsize"
log_msg " timeserver = $timeserver"
log_msg " timezone = $timezone"
log_msg " locales = $locales"
log_msg " system_default_locale = $system_default_locale"
log_msg " cmdline = $cmdline"
log_msg " usbroot = $usbroot"
log_msg " rootdev = $rootdev"
log_msg " rootpartition = $rootpartition"
log_msg " rootfstype = $rootfstype"
log_msg " rootfs_mkfs_options = $rootfs_mkfs_options"
log_msg " rootfs_install_mount_options = $rootfs_install_mount_options"
log_msg " rootfs_mount_options = $rootfs_mount_options"
log_msg " final_action = $final_action"
log_msg " hardware_versions = $hardware_versions"
log_msg " gpu_mem = $gpu_mem"
log_msg " fail_action = $fail_action"
log_msg
log_msg_start "Waiting 5 seconds"
for i in $(seq 1 5); do
log_msg_inline "."
sleep 1
done
log_msg_end
# fdisk's boot offset is 2048, so only handle $bootoffset is it's larger then that
if [ -n "$bootoffset" ] && [ "$bootoffset" -gt 2048 ] ; then
emptyspaceend=$((bootoffset - 1))
else
emptyspaceend=
fi
# Create a file for partitioning sd card only
FDISK_SCHEME_SD_ONLY=/etc/raspbian-ua-netinst/fdisk-sd-only.config
touch $FDISK_SCHEME_SD_ONLY
{
if [ -n "$emptyspaceend" ] ; then
# we have a custom bootoffset, so first create a temporary
# partition occupying the space before it.
# We'll remove it before committing the changes again.
printf '%s\n' "n"
printf '%s\n' "p"
printf '%s\n' "4"
printf '%s\n' ""
printf '%s\n' "$emptyspaceend"
fi
printf '%s\n' "n"