-
Notifications
You must be signed in to change notification settings - Fork 0
/
cli-armvuan.sh
789 lines (640 loc) · 28.6 KB
/
cli-armvuan.sh
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
#!/usr/bin/env bash
#
# SPDX-License-Identifier: GPL-2.0
#
# Experimental Devuan on Armbian using only debootstrap+apt+tweaks without any compilation parties.
# In the bright future if it ever comes: drop all this shit in favor of native support
# either in Armbian Linux Build Framework or in Devuan’s Simple Distro Kit.
#
# Resulting images are primarily intended for headless boards, root password is disabled,
# so a few manual tweaks are required before inserting your SD card in:
# * add public key to /root/.ssh/authorized_keys
# * configure /etc/network/interfaces
#
# After successful boot:
# * convert necessary systemd services to ones of init system of your flavor
# (e.g. hardware optimizations - you can dissect armbian-bsp package for clues)
#
# -- Axy, [email protected]
# armvuan does not resize filesystem, thus it needs some extra space for logs and other stuff
# XXX use command line options instead?
EXTRA_ROOTFS_MIB_SIZE=128
COMPRESS_OUTPUTIMAGE=sha,xz
# XXX use command line options instead
NAMESERVER=1.1.1.1
# set for release candidate
RC_SUFFIX=-rc1
# XXX move to config?
DEVUAN_MIRROR=http://deb.devuan.org/merged/
DEVUAN_KEY_IDS=(0022D0AB5275F140 94532124541922FB)
FLAVOR_INCLUDE=runit,runit-init,nano
FLAVOR_EXCLUDE=sysvinit-core
# notes:
# * apt-utils, dialog are needed to avoid debconf errors
# * bc is needed by armbianmonitor
# * initramfs-tools is needed to properly install linux-image later on
# * procps is needed because it provides /etc/sysctl.conf
# * udev is needed, otherwise Armbian's udev wil be installed,
# it's a transitional package in Devuan, but eudev is explicitly specified just in case
REQUIRED_PACKAGES=apt-utils,bc,console-setup,cron,dialog,fping,initramfs-tools-core,initramfs-tools,\
iw,libc-l10n,locales,lsb-release,netbase,procps,tzdata,udev,eudev,u-boot-tools,zstd
DISTRO_INCLUDE=bsdextrautils,cpufrequtils,cryptsetup,chrony,dosfstools,ethtool,fdisk,findutils,less,\
ifupdown,inetutils-ping,logrotate,lsof,man-db,mmc-utils,mtd-utils,openssh-server,openssh-sftp-server,\
parted,psmisc,psutils,rsync,rsyslog,screen,sysfsutils,tmux,usbutils,wireless-tools,wpasupplicant
DEBOOTSTRAP_INCLUDE=${FLAVOR_INCLUDE},${DISTRO_INCLUDE},${REQUIRED_PACKAGES}
# XXX on which boards dmidecode can run? (neither of mine -- axy)
DEBOOTSTRAP_EXCLUDE=${FLAVOR_EXCLUDE},dmidecode
# for debugging and/or running functions separately
# XXX use command line options instead
#PRESERVE_SDCARD_MOUNT=yes
#PRESERVE_WORKDIR=yes
#ARMBIAN_BUILD_UUID=840e2ed5-473b-453c-b050-10f2cbdbe976
# Devuan-Armbian release map
declare -A ARMBIAN_RELEASE=(
["daedalus"]="bookworm"
)
function cli_armvuan_run() {
prepare_armvuan_env
local functions
case "${ARMBIAN_COMMAND}" in
armvuan-build)
# the whole build process
functions=(
armvuan_prebuild
armvuan_stage1
armvuan_stage2
armvuan_add_armbian_repos
armvuan_tweaks
armvuan_blend
armvuan_final_tweaks
armvuan_make_image
)
;;
*)
# invoke specific function only
# XXX armvuan_tweaks has side effects, don't run subsequent functions separately
functions=("${ARMBIAN_COMMAND//-/_}")
;;
esac
local fn
for fn in ${functions[@]}; do
LOG_SECTION=${fn} $fn
done
}
function prepare_armvuan_env() {
# XXX what is correct way to init minimal environment to build a simple bsp deb?
skip_host_config=yes use_board=yes prep_conf_main_minimal_ni
# use cache directory for tools and keyring
declare -g DEBOOTSTRAP_DIR="${SRC}/cache/tools/devuan/debootstrap"
declare -g DEVUAN_CACHE_DIR="${SRC}/cache/devuan"
declare -g DEVUAN_KEYRING="${DEVUAN_CACHE_DIR}/devuan-keyring.gpg"
mkdir -p ${DEVUAN_CACHE_DIR}
# XXX not cleaned on exit, add to traps somehow
mkdir -p "${WORKDIR}" # this is normally done in prepare_host_init but it depends
# on obtain_and_check_host_release_and_arch and pulls too much crap
if [[ -n ${RC_SUFFIX} ]] ; then
EXTRA_IMAGE_SUFFIXES+=${RC_SUFFIX}
fi
}
function armvuan_prebuild() {
# get debootstrap from Devuan
if [[ ! -d ${DEBOOTSTRAP_DIR} ]] ; then
mkdir -p ${DEBOOTSTRAP_DIR}
pushd `dirname ${DEBOOTSTRAP_DIR}`
git clone https://git.devuan.org/devuan/debootstrap.git
popd
fi
# get keys
gpg --no-default-keyring --keyserver keyring.devuan.org --keyring ${DEVUAN_KEYRING} --recv-keys ${DEVUAN_KEY_IDS[@]}
}
function armvuan_stage1() {
# Devuan debootstrap stage 1
export DEBOOTSTRAP_DIR
mkdir -p ${DEVUAN_CACHE_DIR}/apt
do_with_retries 3 run_host_command_logged_raw debootstrap --foreign --arch=${ARCH} \
--variant=minbase \
--keyring=${DEVUAN_KEYRING} \
--include=${DEBOOTSTRAP_INCLUDE} \
--exclude=${DEBOOTSTRAP_EXCLUDE} \
--cache-dir=${DEVUAN_CACHE_DIR}/apt \
${RELEASE} ${SDCARD} ${DEVUAN_MIRROR}
}
function armvuan_stage2() {
# Devuan debootstrap stage 2
unset DEBOOTSTRAP_DIR
chroot_sdcard /debootstrap/debootstrap --second-stage
}
function armvuan_add_armbian_repos() {
# Add Armbian repos
# add armbian key
mkdir -p ${SDCARD}/usr/share/keyrings
# change to binary form
gpg --dearmor < "${SRC}"/config/armbian.key > ${SDCARD}/usr/share/keyrings/armbian.gpg
SIGNED_BY="[signed-by=/usr/share/keyrings/armbian.gpg] "
declare -a components=()
components+=("main")
components+=("${ARMBIAN_RELEASE[$RELEASE]}-utils") # utils contains packages Igor picks from other repos
components+=("${ARMBIAN_RELEASE[$RELEASE]}-desktop") # desktop contains packages Igor picks from other repos
# stage: add armbian repository and install key
if [[ $DOWNLOAD_MIRROR == "china" ]]; then
echo "deb ${SIGNED_BY}https://mirrors.tuna.tsinghua.edu.cn/armbian $RELEASE ${components[*]}" > "${SDCARD}"/etc/apt/sources.list.d/armbian.list
elif [[ $DOWNLOAD_MIRROR == "bfsu" ]]; then
echo "deb ${SIGNED_BY}http://mirrors.bfsu.edu.cn/armbian $RELEASE ${components[*]}" > "${SDCARD}"/etc/apt/sources.list.d/armbian.list
else
echo "deb ${SIGNED_BY}http://$([[ $BETA == yes ]] && echo "beta" || echo "apt").armbian.com ${ARMBIAN_RELEASE[$RELEASE]} ${components[*]}" > "${SDCARD}"/etc/apt/sources.list.d/armbian.list
fi
# optionally add armhf arhitecture to arm64, if asked to do so.
if [[ "a${ARMHF_ARCH}" == "ayes" ]]; then
[[ $ARCH == arm64 ]] && chroot_sdcard LC_ALL=C LANG=C dpkg --add-architecture armhf
fi
# Add external / PPAs to apt sources; decides internally based on minimal/cli/desktop dir/file structure
add_apt_sources
# stage: update packages list
display_alert "Updating package list" "$RELEASE" "info"
do_with_retries 3 chroot_sdcard_apt_get_update
}
function armvuan_tweaks() {
# Armbian is locked to systemd, we need fake systemctl
cat <<- EOF > "${SDCARD}"/usr/bin/systemctl
#!/bin/sh
exit 0
EOF
chmod +x "${SDCARD}"/usr/bin/systemctl
# from function create_new_rootfs_cache_via_debootstrap:
# stage: configure language and locales.
# this _requires_ DEST_LANG, otherwise, bomb: if it's not here _all_ locales will be generated which is very slow.
display_alert "Configuring locales" "DEST_LANG: ${DEST_LANG}" "info"
[[ "x${DEST_LANG}x" == "xx" ]] && exit_with_error "Bug: got to config locales without DEST_LANG set"
[[ -f ${SDCARD}/etc/locale.gen ]] && sed -i "s/^# ${DEST_LANG}/${DEST_LANG}/" ${SDCARD}/etc/locale.gen
chroot_sdcard LC_ALL=C LANG=C locale-gen "${DEST_LANG}"
chroot_sdcard LC_ALL=C LANG=C update-locale "LANG=${DEST_LANG}" "LANGUAGE=${DEST_LANG}" "LC_MESSAGES=${DEST_LANG}"
if [[ -f ${SDCARD}/etc/default/console-setup ]]; then
# @TODO: Should be configurable.
sed -e 's/CHARMAP=.*/CHARMAP="UTF-8"/' -e 's/FONTSIZE=.*/FONTSIZE="8x16"/' \
-e 's/CODESET=.*/CODESET="guess"/' -i "${SDCARD}/etc/default/console-setup"
chroot_sdcard LC_ALL=C LANG=C setupcon --save --force
fi
####################################################
# from function install_distribution_specific:
# remove doubled uname from motd
[[ -f "${SDCARD}"/etc/update-motd.d/10-uname ]] && rm "${SDCARD}"/etc/update-motd.d/10-uname
# use list modules INITRAMFS
if [ -f "${SRC}"/config/modules/"${MODULES_INITRD}" ]; then
display_alert "Use file list modules MODULES_INITRD" "${MODULES_INITRD}"
sed -i "s/^MODULES=.*/MODULES=list/" "${SDCARD}"/etc/initramfs-tools/initramfs.conf
cat "${SRC}"/config/modules/"${MODULES_INITRD}" >> "${SDCARD}"/etc/initramfs-tools/modules
fi
####################################################
# from function install_distribution_agnostic:
# Bail if $ROOTFS_TYPE not set
[[ -z $ROOTFS_TYPE ]] && exit_with_error "ROOTFS_TYPE not set" "install_distribution_agnostic"
# get linux-image deb file and get kernel version from it
chroot_sdcard_apt_get_install_download_only linux-image-${BRANCH}-${LINUXFAMILY}
IMAGE_INSTALLED_KERNEL_VERSION=$(dpkg --info ${SDCARD}/var/cache/apt/archives/linux-image-${BRANCH}-${LINUXFAMILY}* | grep "^ Source:" | sed -e 's/ Source: linux-//')
display_alert "Parsed kernel version from local package" "${IMAGE_INSTALLED_KERNEL_VERSION}" "debug"
# add dummy fstab entry to make mkinitramfs happy
echo "/dev/mmcblk0p1 / $ROOTFS_TYPE defaults 0 1" >> "${SDCARD}"/etc/fstab
# required for initramfs-tools-core on Stretch since it ignores the / fstab entry
echo "/dev/mmcblk0p2 /usr $ROOTFS_TYPE defaults 0 2" >> "${SDCARD}"/etc/fstab
# remove default interfaces file if present
# before installing board support package
rm -f "${SDCARD}"/etc/network/interfaces
# create modules file
local modules=MODULES_${BRANCH^^}
if [[ -n "${!modules}" ]]; then
tr ' ' '\n' <<< "${!modules}" > "${SDCARD}"/etc/modules
elif [[ -n "${MODULES}" ]]; then
tr ' ' '\n' <<< "${MODULES}" > "${SDCARD}"/etc/modules
fi
# create blacklist files
local blacklist=MODULES_BLACKLIST_${BRANCH^^}
if [[ -n "${!blacklist}" ]]; then
tr ' ' '\n' <<< "${!blacklist}" | sed -e 's/^/blacklist /' > "${SDCARD}/etc/modprobe.d/blacklist-${BOARD}.conf"
elif [[ -n "${MODULES_BLACKLIST}" ]]; then
tr ' ' '\n' <<< "${MODULES_BLACKLIST}" | sed -e 's/^/blacklist /' > "${SDCARD}/etc/modprobe.d/blacklist-${BOARD}.conf"
fi
# configure MIN / MAX speed for cpufrequtils
cat <<- EOF > "${SDCARD}"/etc/default/cpufrequtils
ENABLE=${CPUFREQUTILS_ENABLE:-false}
MIN_SPEED=$CPUMIN
MAX_SPEED=$CPUMAX
GOVERNOR=$GOVERNOR
EOF
# disable selinux by default
mkdir -p "${SDCARD}"/selinux
[[ -f "${SDCARD}"/etc/selinux/config ]] && sed "s/^SELINUX=.*/SELINUX=disabled/" -i "${SDCARD}"/etc/selinux/config
# Prevent loading paralel printer port drivers which we don't need here.
# Suppress boot error if kernel modules are absent
if [[ -f "${SDCARD}"/etc/modules-load.d/cups-filters.conf ]]; then
sed "s/^lp/#lp/" -i "${SDCARD}"/etc/modules-load.d/cups-filters.conf
sed "s/^ppdev/#ppdev/" -i "${SDCARD}"/etc/modules-load.d/cups-filters.conf
sed "s/^parport_pc/#parport_pc/" -i "${SDCARD}"/etc/modules-load.d/cups-filters.conf
fi
# console fix due to Debian bug # @TODO: rpardini: still needed?
sed -e 's/CHARMAP=".*"/CHARMAP="'$CONSOLE_CHAR'"/g' -i "${SDCARD}"/etc/default/console-setup
# add the /dev/urandom path to the rng config file
echo "HRNGDEVICE=/dev/urandom" >> "${SDCARD}"/etc/default/rng-tools
# @TODO: security problem?
# ping needs privileged action to be able to create raw network socket
# this is working properly but not with (at least) Debian Buster
chroot_sdcard chmod u+s /bin/ping
# change time zone data
echo "${TZDATA}" > "${SDCARD}"/etc/timezone
chroot_sdcard dpkg-reconfigure -f noninteractive tzdata
# change console welcome text
echo -e "${VENDOR} ${IMAGE_VERSION:-"${REVISION}"} ${RELEASE^} \\l \n" > "${SDCARD}"/etc/issue
echo "${VENDOR} ${IMAGE_VERSION:-"${REVISION}"} ${RELEASE^}" > "${SDCARD}"/etc/issue.net
# root user is already there. Copy bashrc there as well
cp "${SDCARD}"/etc/skel/.bashrc "${SDCARD}"/root
if [[ ${DESKTOP_AUTOLOGIN} == yes ]]; then
# set desktop autologin
touch "${SDCARD}"/root/.desktop_autologin
fi
# NOTE: this needs to be executed before family_tweaks
local bootscript_src=${BOOTSCRIPT%%:*}
local bootscript_dst=${BOOTSCRIPT##*:}
# create extlinux config file @TODO: refactor into extensions u-boot, extlinux
if [[ $SRC_EXTLINUX == yes ]]; then
display_alert "Using extlinux, SRC_EXTLINUX: ${SRC_EXTLINUX}" "$NAME_KERNEL - $NAME_INITRD" "info"
mkdir -p "$SDCARD"/boot/extlinux
local bootpart_prefix
if [[ -n $BOOTFS_TYPE ]]; then
bootpart_prefix=/
else
bootpart_prefix=/boot/
fi
cat <<- EOF > "$SDCARD/boot/extlinux/extlinux.conf"
label ${VENDOR}
kernel ${bootpart_prefix}$NAME_KERNEL
initrd ${bootpart_prefix}$NAME_INITRD
EOF
if [[ -n $BOOT_FDT_FILE ]]; then
if [[ $BOOT_FDT_FILE != "none" ]]; then
echo " fdt ${bootpart_prefix}dtb/$BOOT_FDT_FILE" >> "$SDCARD/boot/extlinux/extlinux.conf"
fi
else
echo " fdtdir ${bootpart_prefix}dtb/" >> "$SDCARD/boot/extlinux/extlinux.conf"
fi
else # ... not extlinux ...
if [[ -n "${BOOTSCRIPT}" ]]; then # @TODO: && "${BOOTCONFIG}" != "none"
display_alert "Deploying boot script" "$bootscript_src" "info"
if [ -f "${USERPATCHES_PATH}/bootscripts/${bootscript_src}" ]; then
run_host_command_logged cp -pv "${USERPATCHES_PATH}/bootscripts/${bootscript_src}" "${SDCARD}/boot/${bootscript_dst}"
else
run_host_command_logged cp -pv "${SRC}/config/bootscripts/${bootscript_src}" "${SDCARD}/boot/${bootscript_dst}"
fi
fi
if [[ -n $BOOTENV_FILE ]]; then
if [[ -f $USERPATCHES_PATH/bootenv/$BOOTENV_FILE ]]; then
run_host_command_logged cp -pv "$USERPATCHES_PATH/bootenv/${BOOTENV_FILE}" "${SDCARD}"/boot/armbianEnv.txt
elif [[ -f $SRC/config/bootenv/$BOOTENV_FILE ]]; then
run_host_command_logged cp -pv "${SRC}/config/bootenv/${BOOTENV_FILE}" "${SDCARD}"/boot/armbianEnv.txt
fi
fi
# TODO: modify $bootscript_dst or armbianEnv.txt to make NFS boot universal
# instead of copying sunxi-specific template
if [[ $ROOTFS_TYPE == nfs ]]; then
display_alert "Copying NFS boot script template"
if [[ -f $USERPATCHES_PATH/nfs-boot.cmd ]]; then
run_host_command_logged cp -pv "$USERPATCHES_PATH"/nfs-boot.cmd "${SDCARD}"/boot/boot.cmd
else
run_host_command_logged cp -pv "${SRC}"/config/templates/nfs-boot.cmd.template "${SDCARD}"/boot/boot.cmd
fi
fi
if [[ -n $OVERLAY_PREFIX && -f "${SDCARD}"/boot/armbianEnv.txt ]]; then
display_alert "Adding to armbianEnv.txt" "overlay_prefix=$OVERLAY_PREFIX" "debug"
run_host_command_logged echo "overlay_prefix=$OVERLAY_PREFIX" ">>" "${SDCARD}"/boot/armbianEnv.txt
fi
if [[ -n $DEFAULT_OVERLAYS && -f "${SDCARD}"/boot/armbianEnv.txt ]]; then
display_alert "Adding to armbianEnv.txt" "overlays=${DEFAULT_OVERLAYS//,/ }" "debug"
run_host_command_logged echo "overlays=${DEFAULT_OVERLAYS//,/ }" ">>" "${SDCARD}"/boot/armbianEnv.txt
fi
if [[ -n $BOOT_FDT_FILE && -f "${SDCARD}"/boot/armbianEnv.txt ]]; then
display_alert "Adding to armbianEnv.txt" "fdtfile=${BOOT_FDT_FILE}" "debug"
run_host_command_logged echo "fdtfile=${BOOT_FDT_FILE}" ">>" "${SDCARD}/boot/armbianEnv.txt"
fi
fi
# initial date for fake-hwclock
date -u '+%Y-%m-%d %H:%M:%S' > "${SDCARD}"/etc/fake-hwclock.data
echo "${HOST}" > "${SDCARD}"/etc/hostname
# set hostname in hosts file
cat <<- EOF > "${SDCARD}"/etc/hosts
127.0.0.1 localhost
127.0.1.1 $HOST
::1 localhost $HOST ip6-localhost ip6-loopback
fe00::0 ip6-localnet
ff00::0 ip6-mcastprefix
ff02::1 ip6-allnodes
ff02::2 ip6-allrouters
EOF
cd "${SRC}" || exit_with_error "cray-cray about ${SRC}"
# LOGGING: we're running under the logger framework here.
# LOGGING: so we just log directly to stdout and let it handle it.
# LOGGING: redirect commands' stderr to stdout so it goes into the log, not screen.
# XXX for what exactly need this? family_tweaks? to avoid re-building initrd when installing linux-u-boot? anything else?
# BTW chroot_sdcard looks too much for simple chmod
display_alert "Temporarily disabling" "initramfs-tools hook for kernel"
chroot_sdcard chmod -v -x /etc/kernel/postinst.d/initramfs-tools
# execute $LINUXFAMILY-specific tweaks
if [[ $(type -t family_tweaks) == function ]]; then
display_alert "Applying family" " tweaks: $BOARD :: $LINUXFAMILY"
family_tweaks
display_alert "Done with family_tweaks" "$BOARD :: $LINUXFAMILY" "debug"
fi
# disable repeated messages due to xconsole not being installed.
[[ -f "${SDCARD}"/etc/rsyslog.d/50-default.conf ]] &&
sed '/daemon\.\*\;mail.*/,/xconsole/ s/.*/#&/' -i "${SDCARD}"/etc/rsyslog.d/50-default.conf
[[ $LINUXFAMILY == sun*i ]] && mkdir -p "${SDCARD}"/boot/overlay-user
if [ -n "$NAMESERVER" ]; then
if [ -d "${SDCARD}"/etc/resolvconf/resolv.conf.d ] ; then
# DNS fix. package resolvconf is not available everywhere
echo "nameserver $NAMESERVER" > "${SDCARD}"/etc/resolvconf/resolv.conf.d/head
else
# debootstrap takes resolv.conf from the host system, replace it
echo "nameserver $NAMESERVER" > "${SDCARD}"/etc/resolv.conf
fi
fi
# permit root login via SSH
sed -i 's/#\?PermitRootLogin .*/PermitRootLogin yes/' "${SDCARD}"/etc/ssh/sshd_config
# enable PubkeyAuthentication
sed -i 's/#\?PubkeyAuthentication .*/PubkeyAuthentication yes/' "${SDCARD}"/etc/ssh/sshd_config
# disable password authentication
sed -i 's/#\?PasswordAuthentication .*/PasswordAuthentication no/' "${SDCARD}"/etc/ssh/sshd_config
mkdir -p "${SDCARD}"/root/.ssh
chmod 700 "${SDCARD}"/root/.ssh
touch "${SDCARD}"/root/.ssh/authorized_keys
}
function armvuan_blend() {
# Blend with Armbian
# stage: upgrade base packages from xxx-updates and xxx-backports repository branches
display_alert "Upgrading base packages" "Armbian" "info"
do_with_retries 3 chroot_sdcard_apt_get upgrade
do_with_retries 3 chroot_sdcard_apt_get_install \
armbian-firmware \
linux-dtb-${BRANCH}-${LINUXFAMILY} \
linux-image-${BRANCH}-${LINUXFAMILY} \
linux-u-boot-${BOARD}-${BRANCH}
# no need for fake systemctl anymore
rm -f "${SDCARD}"/usr/bin/systemctl
display_alert "Re-enabling" "initramfs-tools hook for kernel"
chroot_sdcard chmod -v +x "/etc/kernel/postinst.d/initramfs-tools"
}
function armvuan_final_tweaks() {
# Pull stuff from armbian-bsp-cli package
BSP=armbian-bsp-cli-${BOARD}-${BRANCH}
chroot_sdcard_apt_get download ${BSP}
chroot_sdcard mkdir /root/${BSP}
chroot_sdcard dpkg-deb -R ${BSP}*.deb /root/${BSP}
chroot_sdcard cp -a /root/${BSP}/etc/{apt,armbian-release,initramfs,kernel,modprobe.d,sysfs.d,udev} /etc/
chroot_sdcard cp /root/${BSP}/etc/default/armbian-ramlog.dpkg-dist /etc/default/armbian-ramlog
chroot_sdcard cp -a /root/${BSP}/usr/bin /usr/
chroot_sdcard cp -a /root/${BSP}/usr/lib/armbian /usr/lib/
chroot_sdcard rm -rf ${BSP}*.deb /root/${BSP}
# sans systemctl version of armbian-ram-logging
cat <<- EOF > "${SDCARD}"/etc/cron.daily/armbian-ram-logging
#!/bin/sh
# Only run on systems where logrotate is a cron job
/usr/lib/armbian/armbian-ramlog write >/dev/null 2>&1
EOF
# networking defaults
cat <<- EOF > "${SDCARD}"/etc/network/interfaces
auto lo
iface lo inet loopback
auto end0
iface end0 inet static
address 192.168.0.100
netmask 255.255.255.0
gateway 192.168.0.1
EOF
# armbian-hardware-optimization service
cat <<- EOF > "${SDCARD}"/etc/init.d/armbian-hardware-optimization
#!/bin/sh
### BEGIN INIT INFO
# Provides: armbian-hardware-optimization
# Required-Start: \$local_fs
# Required-Stop:
# Default-Start: S
# Default-Stop:
# Short-Description: Armbian hardware optimization
# Description: Armbian hardware optimization
### END INIT INFO
case "\$1" in
start)
/usr/lib/armbian/armbian-hardware-optimization start
# tweaks for armbianmonitor:
. /usr/bin/armbian/armbian-hardware-monitor
prepare_temp_monitoring
;;
*)
;;
esac
EOF
chmod +x "${SDCARD}"/etc/init.d/armbian-hardware-optimization
chroot_sdcard update-rc.d armbian-hardware-optimization defaults
# armbian-ramlog service
cat <<- EOF > "${SDCARD}"/etc/init.d/armbian-ramlog
#!/bin/sh
### BEGIN INIT INFO
# Provides: armbian-ramlog
# Required-Start: \$local_fs
# Required-Stop:
# X-Start-Before: rsyslog
# X-Stop-After: rsyslog
# Default-Start: S
# Default-Stop:
# Short-Description: Armbian memory supported logging
# Description: Armbian memory supported logging
### END INIT INFO
. /lib/lsb/init-functions
case "\$1" in
start)
/usr/lib/armbian/armbian-ramlog start
;;
stop)
/usr/lib/armbian/armbian-ramlog stop
;;
reload)
/usr/lib/armbian/armbian-ramlog write
;;
*)
log_failure_msg "Usage: $0 {start|stop|reload}"
exit 1
;;
esac
EOF
chmod +x "${SDCARD}"/etc/init.d/armbian-ramlog
chroot_sdcard update-rc.d armbian-ramlog defaults
case ${BOARDFAMILY} in
sun8i)
sun8i_tweaks
;;
sun50iw6)
sun50iw6_tweaks
;;
rockchip64)
rockchip64_tweaks
;;
esac
}
function sun8i_tweaks() {
add-dwmac-sun8i-udev-rule
}
function sun50iw6_tweaks() {
add-dwmac-sun8i-udev-rule
}
function add-dwmac-sun8i-udev-rule() {
# predictable interface name for soc ethernet
cat <<- EOF > "${SDCARD}"/etc/udev/rules.d/70-dwmac-sun8i.rules
SUBSYSTEM=="net", ACTION=="add", DRIVERS=="dwmac-sun8i", NAME="end0"
EOF
}
function rockchip64_tweaks() {
# predictable interface name for soc ethernet
cat <<- EOF > "${SDCARD}"/etc/udev/rules.d/70-dwmac-rockchip64.rules
SUBSYSTEM=="net", ACTION=="add", DRIVERS=="rk_gmac-dwmac", NAME="end0"
EOF
}
function armvuan_make_image() {
# XXX what is the right way?
mkdir -p ${MOUNT}
# Only clean if not using local cache. Otherwise it would be cleaning the cache, not the chroot.
if [[ "${USE_LOCAL_APT_DEB_CACHE}" != "yes" ]]; then
display_alert "Cleaning" "package lists and apt cache" "warn"
chroot_sdcard_apt_get clean
fi
# from function build_rootfs_and_image:
LOG_SECTION="prepare_partitions" do_with_logging prepare_partitions
LOG_SECTION="create_image_from_sdcard_rootfs" do_with_logging armvuan_create_image_from_sdcard_rootfs
}
function armvuan_create_image_from_sdcard_rootfs() {
# based on function create_image_from_sdcard_rootfs
# create DESTIMG, hooks might put stuff there early.
mkdir -p "${DESTIMG}"
# add a cleanup trap hook do make sure we don't leak it if stuff fails
add_cleanup_handler trap_handler_cleanup_destimg
# calculate image filename, and store it in readonly global variable "version", for legacy reasons.
declare calculated_image_version="undetermined"
calculate_image_version
declare -r -g version="${calculated_image_version}" # global readonly from here
declare rsync_ea=" -X "
# nilfs2 fs does not have extended attributes support, and have to be ignored on copy
if [[ $ROOTFS_TYPE == nilfs2 ]]; then rsync_ea=""; fi
if [[ $ROOTFS_TYPE != nfs ]]; then
display_alert "Copying files via rsync to" "/ (MOUNT root)"
run_host_command_logged rsync -aHWh $rsync_ea \
--exclude="/boot" \
--exclude="/dev/*" \
--exclude="/proc/*" \
--exclude="/run/*" \
--exclude="/tmp/*" \
--exclude="/sys/*" \
--info=progress0,stats1 $SDCARD/ $MOUNT/
else
display_alert "Creating rootfs archive" "rootfs.tgz" "info"
tar cp --xattrs --directory=$SDCARD/ --exclude='./boot/*' --exclude='./dev/*' --exclude='./proc/*' --exclude='./run/*' --exclude='./tmp/*' \
--exclude='./sys/*' . |
pv -p -b -r -s "$(du -sb "$SDCARD"/ | cut -f1)" \
-N "$(logging_echo_prefix_for_pv "create_rootfs_archive") rootfs.tgz" |
gzip -c > "$DEST/images/${version}-rootfs.tgz"
fi
# stage: rsync /boot
display_alert "Copying files to" "/boot (MOUNT /boot)"
if [[ $(findmnt --noheadings --output FSTYPE --target "$MOUNT/boot" --uniq) == vfat ]]; then
# FAT filesystems can't have symlinks; rsync, below, will replace them with copies (-L)...
# ... unless they're dangling symlinks, in which case rsync will fail.
# Find dangling symlinks in "$MOUNT/boot", warn, and remove them.
display_alert "Checking for dangling symlinks" "in FAT32 /boot" "info"
declare -a dangling_symlinks=()
while IFS= read -r -d '' symlink; do
dangling_symlinks+=("$symlink")
done < <(find "$SDCARD/boot" -xtype l -print0)
if [[ ${#dangling_symlinks[@]} -gt 0 ]]; then
display_alert "Dangling symlinks in /boot" "$(printf '%s ' "${dangling_symlinks[@]}")" "warning"
run_host_command_logged rm -fv "${dangling_symlinks[@]}"
fi
run_host_command_logged rsync -rLtWh --info=progress0,stats1 "$SDCARD/boot" "$MOUNT" # fat32
else
run_host_command_logged rsync -aHWXh --info=progress0,stats1 "$SDCARD/boot" "$MOUNT" # ext4
fi
call_extension_method "pre_update_initramfs" "config_pre_update_initramfs" <<- 'PRE_UPDATE_INITRAMFS'
*allow config to hack into the initramfs create process*
Called after rsync has synced both `/root` and `/root` on the target, but before calling `update_initramfs`.
PRE_UPDATE_INITRAMFS
# stage: create final initramfs
[[ -n $KERNELSOURCE ]] && {
update_initramfs "$MOUNT"
}
# DEBUG: print free space @TODO this needs work, grepping might not be ideal here
local freespace
freespace=$(LC_ALL=C df -h || true) # don't break on failures
display_alert "Free SD cache" "$(echo -e "$freespace" | awk -v mp="${SDCARD}" '$6==mp {print $5}')" "info"
display_alert "Mount point" "$(echo -e "$freespace" | awk -v mp="${MOUNT}" '$6==mp {print $5}')" "info"
# stage: write u-boot, unless BOOTCONFIG=none
declare -g -A image_artifacts_debs_reversioned
if [[ "${BOOTCONFIG}" != "none" ]]; then
armvuan_write_uboot_to_loop_image
fi
# fix wrong / permissions
chmod 755 "${MOUNT}"
call_extension_method "pre_umount_final_image" "config_pre_umount_final_image" <<- 'PRE_UMOUNT_FINAL_IMAGE'
*allow config to hack into the image before the unmount*
Called before unmounting both `/root` and `/boot`.
PRE_UMOUNT_FINAL_IMAGE
if [[ "${SHOW_DEBUG}" == "yes" ]]; then
# Check the partition table after the uboot code has been written
display_alert "Partition table after write_uboot" "$LOOP" "debug"
run_host_command_logged sfdisk -l "${LOOP}" # @TODO: use asset..
fi
wait_for_disk_sync "before umount MOUNT"
umount_chroot_recursive "${MOUNT}" "MOUNT"
[[ $CRYPTROOT_ENABLE == yes ]] && cryptsetup luksClose "$ROOT_MAPPER"
call_extension_method "post_umount_final_image" "config_post_umount_final_image" <<- 'POST_UMOUNT_FINAL_IMAGE'
*allow config to hack into the image after the unmount*
Called after unmounting both `/root` and `/boot`.
POST_UMOUNT_FINAL_IMAGE
free_loop_device_insistent "${LOOP}"
unset LOOP # unset so cleanup handler does not try it again
# We're done with ${MOUNT} by now, remove it.
rm -rf --one-file-system "${MOUNT}"
# unset MOUNT # don't unset, it's readonly now
mkdir -p "${DESTIMG}"
# @TODO: misterious cwd, who sets it?
run_host_command_logged mv -v "${SDCARD}.raw" "${DESTIMG}/${version}.img"
# custom post_build_image_modify hook to run before fingerprinting and compression
[[ $(type -t post_build_image_modify) == function ]] && display_alert "Custom Hook Detected" "post_build_image_modify" "info" && post_build_image_modify "${DESTIMG}/${version}.img"
# Previously, post_build_image passed the .img path as an argument to the hook. Now its an ENV var.
declare -g FINAL_IMAGE_FILE="${DESTIMG}/${version}.img"
call_extension_method "post_build_image" <<- 'POST_BUILD_IMAGE'
*custom post build hook*
Called after the final .img file is built, before it is (possibly) written to an SD writer.
- *NOTE*: this hook used to take an argument ($1) for the final image produced.
- Now it is passed as an environment variable `${FINAL_IMAGE_FILE}`
It is the last possible chance to modify `$CARD_DEVICE`.
POST_BUILD_IMAGE
# Before compressing or moving, write it to SD card if such was requested and image was produced.
if [[ -f "${DESTIMG}/${version}.img" ]]; then
display_alert "Done building" "${version}.img" "info"
fingerprint_image "${DESTIMG}/${version}.img.txt" "${version}"
write_image_to_device_and_run_hooks "${DESTIMG}/${version}.img"
fi
declare compression_type # set by image_compress_and_checksum
output_images_compress_and_checksum "${DESTIMG}/${version}" # this compressed on-disk, and removes the originals.
# XXX normally they do this somewhere, go try to find
mkdir -p "${FINALDEST}"
# Move all files matching the prefix from source to dest. Custom hooks might generate more than one img.
declare source_dir="${DESTIMG}"
declare destination_dir="${FINALDEST}"
declare source_files_prefix="${version}"
move_images_to_final_destination
}
function armvuan_write_uboot_to_loop_image() {
# uboot_deb is already in, here's a simplified version of write_uboot_to_loop_image which makes changes in place:
if [[ ! -f "${MOUNT}/usr/lib/u-boot/platform_install.sh" ]]; then
exit_with_error "Missing ${MOUNT}/usr/lib/u-boot/platform_install.sh"
fi
display_alert "Sourcing u-boot install functions" "${MOUNT}" "info"
source "${MOUNT}"/usr/lib/u-boot/platform_install.sh
set -e # make sure, we just included something that might disable it
display_alert "Writing u-boot bootloader" "${LOOP}" "info"
write_uboot_platform "${MOUNT}${DIR}" "${LOOP}" # important: DIR is set in platform_install.sh sourced above.
}