#!/bin/sh PROGRAM=setup-alpine VERSION=3.16.2-r0 PREFIX= : ${LIBDIR=$PREFIX/lib} . "$LIBDIR/libalpine.sh" is_kvm_clock() { grep -q "kvm-clock" "$ROOT"sys/devices/system/clocksource/clocksource0/current_clocksource 2>/dev/null } is_virtual_console() { case "$(readlink "$ROOT"/proc/self/fd/0)" in /dev/tty[0-9]*) return 0;; esac return 1 } usage() { cat <<-__EOF__ usage: setup-alpine [-ahq] [-c FILE | -f FILE] Setup Alpine Linux options: -a Create Alpine Linux overlay file -c Create answer file (do not install anything) -e Empty root password -f Answer file to use installation -h Show this help -q Quick mode. Ask fewer questions. __EOF__ exit $1 } while getopts "aef:c:hq" opt ; do case $opt in a) ARCHIVE=yes;; f) USEANSWERFILE="$OPTARG";; c) CREATEANSWERFILE="$OPTARG";; e) empty_root_password=1;; h) usage 0;; q) empty_root_password=1; quick=1; APKREPOSOPTS="-1"; HOSTNAMEOPTS="alpine";; '?') usage "1" >&2;; esac done shift $(expr $OPTIND - 1) rc_sys=$(openrc --sys) # mount xenfs so we can detect xen dom0 if [ "$rc_sys" = "XENU" ] && ! grep -q '^xenfs' /proc/mounts; then modprobe xenfs mount -t xenfs xenfs /proc/xen fi case "$USEANSWERFILE" in http*://*|ftp://*) # dynamically download answer file from URL (supports HTTP(S) and FTP) # ensure the network is up, otherwise setup a temporary interface config if ! rc-service networking --quiet status; then setup-interfaces -ar fi temp="$(mktemp)" wget -qO "$temp" "$USEANSWERFILE" || die "Failed to download '$USEANSWERFILE'" USEANSWERFILE="$temp" ;; *) [ -n "$USEANSWERFILE" ] && USEANSWERFILE=$(realpath "$USEANSWERFILE") ;; esac if [ -n "$USEANSWERFILE" ] && [ -e "$USEANSWERFILE" ]; then . "$USEANSWERFILE" fi if [ -n "$CREATEANSWERFILE" ]; then touch "$CREATEANSWERFILE" || echo "Cannot touch file $CREATEANSWERFILE" cat > "$CREATEANSWERFILE" <<-__EOF__ # Example answer file for setup-alpine script # If you don't want to use a certain option, then comment it out # Use US layout with US variant # KEYMAPOPTS="us us" KEYMAPOPTS=none # Set hostname to 'alpine' HOSTNAMEOPTS=alpine # Set device manager to mdev DEVDOPTS=mdev # Contents of /etc/network/interfaces INTERFACESOPTS="auto lo iface lo inet loopback auto eth0 iface eth0 inet dhcp hostname alpine-test " # Search domain of example.com, Google public nameserver # DNSOPTS="-d example.com 8.8.8.8" # Set timezone to UTC #TIMEZONEOPTS="UTC" TIMEZONEOPTS=none # set http/ftp proxy #PROXYOPTS="http://webproxy:8080" PROXYOPTS=none # Add first mirror (CDN) APKREPOSOPTS="-1" # Create admin user USEROPTS="-a -u -g audio,video,netdev juser" #USERSSHKEY="ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIOIiHcbg/7ytfLFHUNLRgEAubFz/13SwXBOM/05GNZe4 juser@example.com" #USERSSHKEY="https://example.com/juser.keys" # Install Openssh SSHDOPTS=openssh #ROOTSSHKEY="ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIOIiHcbg/7ytfLFHUNLRgEAubFz/13SwXBOM/05GNZe4 juser@example.com" #ROOTSSHKEY="https://example.com/juser.keys" # Use openntpd # NTPOPTS="openntpd" NTPOPTS=none # Use /dev/sda as a sys disk # DISKOPTS="-m sys /dev/sda" DISKOPTS=none # Setup storage with label APKOVL for config storage #LBUOPTS="LABEL=APKOVL" LBUOPTS=none #APKCACHEOPTS="/media/LABEL=APKOVL/cache" APKCACHEOPTS=none __EOF__ echo "Answer file $CREATEANSWERFILE has been created. Please add or remove options as desired in that file" exit 0 fi if [ "$ARCHIVE" ] ; then echo "Creating an Alpine overlay" init_tmpdir ROOT else PKGADD="apk add" fi if [ "$rc_sys" != LXC ]; then if is_virtual_console || [ -n "$KEYMAPOPTS" ]; then setup-keymap ${KEYMAPOPTS} fi setup-hostname ${HOSTNAMEOPTS} && [ -z "$SSH_CONNECTION" ] && rc-service hostname --quiet restart setup-devd -C mdev # just to bootstrap fi [ -z "$SSH_CONNECTION" ] && rst_if=1 if [ -n "$INTERFACESOPTS" ]; then if [ "$INTERFACESOPTS" != none ]; then printf "$INTERFACESOPTS" | setup-interfaces -i ${rst_if:+-r} fi else setup-interfaces ${quick:+-a} ${rst_if:+-r} fi # setup up dns if no dhcp was configured if [ -f "$ROOT"/etc/network/interfaces ] && ! grep -q '^iface.*dhcp' "$ROOT"/etc/network/interfaces; then setup-dns ${DNSOPTS} fi # set root password if [ -z "$empty_root_password" ]; then while ! $MOCK passwd ; do echo "Please retry." done fi if [ -z "$quick" ]; then # pick timezone setup-timezone ${TIMEZONEOPTS} fi rc-update --quiet add networking boot rc-update --quiet add seedrng boot || rc-update --quiet add urandom boot svc_list="cron crond" if [ -e /dev/input/event0 ]; then # Only enable acpid for systems with input events entries # https://gitlab.alpinelinux.org/alpine/aports/-/issues/12290 svc_list="$svc_list acpid" fi for svc in $svc_list; do if rc-service --exists $svc; then rc-update --quiet add $svc fi done # start up the services $MOCK openrc ${SSH_CONNECTION:+-n} boot $MOCK openrc ${SSH_CONNECTION:+-n} default # update /etc/hosts - after we have got dhcp address # Get default fully qualified domain name from *first* domain # given on *last* search or domain statement. _dn=$(sed -n \ -e '/^domain[[:space:]][[:space:]]*/{s///;s/\([^[:space:]]*\).*$/\1/;h;}' \ -e '/^search[[:space:]][[:space:]]*/{s///;s/\([^[:space:]]*\).*$/\1/;h;}' \ -e '${g;p;}' "$ROOT"/etc/resolv.conf 2>/dev/null) _hn=$(hostname) _hn=${_hn%%.*} sed -i -e "s/^127\.0\.0\.1.*/127.0.0.1\t${_hn}.${_dn:-$(get_fqdn my.domain)} ${_hn} localhost.localdomain localhost/" \ "$ROOT"/etc/hosts 2>/dev/null if [ -z "$quick" ]; then setup-proxy -q ${PROXYOPTS} fi # activate the proxy if configured if [ -r "$ROOT/etc/profile" ]; then . "$ROOT/etc/profile" fi if ! is_kvm_clock && [ "$rc_sys" != "LXC" ] && [ "$quick" != 1 ]; then setup-ntp ${NTPOPTS} fi setup-apkrepos ${APKREPOSOPTS} # Now that network and apk are operational we can install another device manager if [ "$rc_sys" != LXC ] && [ -n "$DEVDOPTS" -a "$DEVDOPTS" != mdev ]; then setup-devd ${DEVDOPTS} fi # lets stop here if in "quick mode" if [ "$quick" = 1 ]; then exit 0 fi setup-user ${USERSSHKEY+-k "$USERSSHKEY"} ${USEROPTS:--a -g 'audio video netdev'} for i in "$ROOT"home/*; do if [ -d "$i" ]; then lbu add $i fi done setup-sshd ${ROOTSSHKEY+-k "$ROOTSSHKEY"} ${SSHDOPTS} root_keys="$ROOT"/root/.ssh/authorized_keys if [ -f "$root_keys" ]; then lbu add "$ROOT"/root fi if is_xen_dom0; then setup-xen-dom0 fi if [ "$rc_sys" = "LXC" ]; then exit 0 fi DEFAULT_DISK=none \ setup-disk -w /tmp/alpine-install-diskmode.out -q ${DISKOPTS} || exit diskmode=$(cat /tmp/alpine-install-diskmode.out 2>/dev/null) # setup lbu and apk cache unless installed sys on disk if [ "$diskmode" != "sys" ]; then setup-lbu ${LBUOPTS} setup-apkcache ${APKCACHEOPTS} if [ -L "$ROOT"/etc/apk/cache ]; then apk cache sync fi fi