From a027429011d313e0d9156fef9451f5a55a588163 Mon Sep 17 00:00:00 2001 From: Ian Kelling Date: Thu, 13 Apr 2017 02:55:09 -0700 Subject: [PATCH] add http server support for maru, small bug fixes --- README | 7 +- arch-init | 4 - arch-init-remote | 2 +- chost | 2 +- devbyid | 20 +-- fai-redep | 63 ++++++-- fai-revm | 3 +- fai/config/class/DEBIAN.var | 2 +- fai/config/class/DEFAULT.var | 5 + fai/config/distro-install-common/devbyid | 19 +++ .../files/root/fai-check/VOL_STABLE_BOOTSTRAP | 2 +- fai/config/hooks/partition.DEFAULT | 7 + faiserver-disable | 10 +- faiserver-setup | 138 ++++++++++++++++-- myfai-chboot | 17 ++- myfai-chboot-local | 67 ++++++--- 16 files changed, 284 insertions(+), 84 deletions(-) mode change 100755 => 120000 devbyid create mode 100755 fai/config/distro-install-common/devbyid mode change 100644 => 100755 faiserver-disable diff --git a/README b/README index b18de94..974fcc8 100644 --- a/README +++ b/README @@ -25,7 +25,8 @@ People who use fai may find these things as useful examples: it uses dnsmasq (on a openwrt machine) for dhcp instead of the isc dhcp. fai-wrapper is a small script to use basic fai classes outside of fai. It does not use the fai partitioning tool, but the script is -inspired from it and works outside of fai. +inspired from it and works outside of fai. It supports running a fai +server on debian within android via Maru. It also automates configuration of an openwrt router after manual initial installation. @@ -54,8 +55,8 @@ fai-redep # Deploy fai configuration to host "faiserver" faiserver-revm # using pxe & preseed, create a vm which is a fai server faiserver-uninstall # uninstall fai-server faiserver-setup # install fai-server on the current machine -myfai-chboot # setup fai server for kexec, for use instead of "pxe-server" -pxe-server # disable/enable fai or arch pxe boot server +myfai-chboot # setup fai tftp and nfs. useful with pxe-kexec +pxe-server # disable/enable pxe dhcp, tfp, and nfs wrt-setup-remote # setup my router in general: dhcp, dns, etc. diff --git a/arch-init b/arch-init index 982357f..a2517ee 100755 --- a/arch-init +++ b/arch-init @@ -25,8 +25,6 @@ mirror=$2 (( $# >= 1 )) || { echo "$0: error: need 1 or 2 arguments"; exit 1; } -mv /root/devbyid /usr/bin - rm -f /etc/pacman.d/mirrorlist # https://wiki.archlinux.org/index.php/Mirrors#Sorting_mirrors @@ -88,8 +86,6 @@ fi pacstrap /mnt base cp /tmp/fai/{fstab,crypttab} /mnt/etc cp /a/bin/fai/encrypt /mnt/usr/lib/initcpio/hooks -# not needed anymore -#cp /usr/bin/devbyid /mnt/root cp -r /root/.ssh /mnt/root diff --git a/arch-init-remote b/arch-init-remote index 76e2cf2..0952543 100755 --- a/arch-init-remote +++ b/arch-init-remote @@ -48,7 +48,7 @@ fi rsync -rlpthvi --relative /a/bin/fai/ root@$host:/ rsync /a/bin/fai/ root@$host:/a/bin/fai/ -sudo scp -r /a/bin/fai/devbyid /q/root/luks /q/root/shadow root@$host: +sudo scp -r /q/root/luks /q/root/shadow root@$host: # creating shadow file string: # on debian, you can use mkpasswd -m sha-512 to generate a pass. # arch doesn't have this program. instead, you can do passwd, diff --git a/chost b/chost index 3e1acd2..6168741 100755 --- a/chost +++ b/chost @@ -7,7 +7,7 @@ set -eE -o pipefail trap 'echo "$0:$LINENO:error: \"$BASH_COMMAND\" returned $?" >&2' ERR host=$1 -addr=$(host $host | sed -rn 's/^.*has address (.*)/\1/p;T;q') +addr=$(host $host | sed -rn 's/^\S+ has address //p;T;q') h=$(host $addr) h=${h##* } echo ${h%%.*} diff --git a/devbyid b/devbyid deleted file mode 100755 index e344389..0000000 --- a/devbyid +++ /dev/null @@ -1,19 +0,0 @@ -#!/bin/bash - -# input eg: /dev/sda1 or /dev/sda -# output: /dev/disk/by-id/model+serial, or if no link exists, the same as input - -short_dev=$1 - -# devices are identified by model+serial num, -# and wwn. model+serial gives me more info, so use that. -shopt -s extglob -for id in /dev/disk/by-id/!(wwn*); do - [[ -e $id ]] || break # if we matched nothing - if [[ $(readlink -f $id) == "$short_dev" ]]; then - printf '%s\n' "$id" - exit - fi -done -# a vm may not have a by-id link. -printf '%s\n' "$short_dev" diff --git a/devbyid b/devbyid new file mode 120000 index 0000000..9a02442 --- /dev/null +++ b/devbyid @@ -0,0 +1 @@ +fai/config/distro-install-common/devbyid \ No newline at end of file diff --git a/fai-redep b/fai-redep index 68d51d5..9a455c9 100755 --- a/fai-redep +++ b/fai-redep @@ -21,8 +21,8 @@ x="$(readlink -f "$BASH_SOURCE")"; cd ${x%/*} usage() { cat <>$f +fi + +if ! modprobe nfsd &>/dev/null; then + # no apt-cache on maru debian, because we are low on space already + sed -i '/^ *APTPROXY=/d' /srv/fai/config/class/DEBIAN.var + # maru debian doesn't have loopback devs created + if ! losetup -f; then + shopt -s nullglob + x=(/dev/loop*) + minor=0 + if (( ${#x[@]} )); then + minor=$(( ${x[-1]#/dev/loop} + 1 )) + fi + mknod -m660 /dev/loop$minor b 7 $minor + losetup -f + fi + # -B boo only iso, no nfsroot, no paritial miorr, no config space. + # -f = force, for overwriting + # -S = make squash image for http booting + # -d config space url, instead of putting it in the squash.img, + # this just makes it so that we don't have to regenerate the img + # when the config changes. + cd /srv/fai/config + tar czf /var/www/faiserver/html/config.tar.gz . + if $changed || [[ ! -e /var/www/faiserver/html/squash.img ]]; then + # note, on maru, selinux needs to be disabled in android before + # this will work. + mount + export debug=true + fai-cd -d http://faiserver:8080/config.tar.gz -f -M -S /var/www/faiserver/html/squash.img + mount + fi +fi +EOF diff --git a/fai-revm b/fai-revm index 5ea9d98..68840bd 100755 --- a/fai-revm +++ b/fai-revm @@ -35,7 +35,8 @@ Note, sometimes shutting down the existing demohost vm fails. Just run again if that happens. -r Do not boot after install is complete --n Create new qcow2(s) for vm +-n Create new qcow2(s) for vm. Good for testing partitioning + script, to ensure a blank disk. -h|--help Print help and exit. Note: Uses GNU getopt options parsing style diff --git a/fai/config/class/DEBIAN.var b/fai/config/class/DEBIAN.var index 397b5ea..ae445fa 100644 --- a/fai/config/class/DEBIAN.var +++ b/fai/config/class/DEBIAN.var @@ -14,5 +14,5 @@ MODULESLIST="usbhid psmouse" FAI_RAMDISKS="$target/var/lib/dpkg $target/var/cache" # if you want to use the faiserver as APT proxy -# uncommented from upstream +# ian: uncommented APTPROXY=http://faiserver:3142 diff --git a/fai/config/class/DEFAULT.var b/fai/config/class/DEFAULT.var index eb248c0..9934bb4 100644 --- a/fai/config/class/DEFAULT.var +++ b/fai/config/class/DEFAULT.var @@ -2,3 +2,8 @@ # remotely. LOGUSER=fai + +# when downloading from https intead of nfs, this is not set, +# it is used as the default for LOGSERVER, and for calling chboot. +# My faiserver's hostname is always faiserver, so just hardcoding it. +SERVER=faiserver \ No newline at end of file diff --git a/fai/config/distro-install-common/devbyid b/fai/config/distro-install-common/devbyid new file mode 100755 index 0000000..e344389 --- /dev/null +++ b/fai/config/distro-install-common/devbyid @@ -0,0 +1,19 @@ +#!/bin/bash + +# input eg: /dev/sda1 or /dev/sda +# output: /dev/disk/by-id/model+serial, or if no link exists, the same as input + +short_dev=$1 + +# devices are identified by model+serial num, +# and wwn. model+serial gives me more info, so use that. +shopt -s extglob +for id in /dev/disk/by-id/!(wwn*); do + [[ -e $id ]] || break # if we matched nothing + if [[ $(readlink -f $id) == "$short_dev" ]]; then + printf '%s\n' "$id" + exit + fi +done +# a vm may not have a by-id link. +printf '%s\n' "$short_dev" diff --git a/fai/config/files/root/fai-check/VOL_STABLE_BOOTSTRAP b/fai/config/files/root/fai-check/VOL_STABLE_BOOTSTRAP index 7621bdf..b20e8e9 100755 --- a/fai/config/files/root/fai-check/VOL_STABLE_BOOTSTRAP +++ b/fai/config/files/root/fai-check/VOL_STABLE_BOOTSTRAP @@ -67,7 +67,7 @@ for dev in $(btrfs fi show / | sed -rn 's#^\s*devid\s.*\s([^0-9 ]+)\S+$#\1#p' \ # because it will wait for too long when we don't have a network # connection. So, we wait for 10 seconds. # ref: https://www.freedesktop.org/wiki/Software/systemd/NetworkTarget/ - try-kexec + try-kexec ||: else return 0 fi diff --git a/fai/config/hooks/partition.DEFAULT b/fai/config/hooks/partition.DEFAULT index 2db69b3..f241fd6 100755 --- a/fai/config/hooks/partition.DEFAULT +++ b/fai/config/hooks/partition.DEFAULT @@ -77,7 +77,14 @@ root-cryptdev() { crypt-dev $(rootdev $@); } swap-cryptdev() { crypt-dev $(swapdev $@); } root-cryptname() { crypt-name $(rootdev $@); } swap-cryptname() { crypt-name $(swapdev $@); } +devbyid() { + local f + for f in $FAI/distro-install-common/devbyid \ + /a/bin/fai/fai/config/distro-install-common/devbyid; do + if [[ -e $f ]]; then $f "$@"; fi + done +} ##### end function defs diff --git a/faiserver-disable b/faiserver-disable old mode 100644 new mode 100755 index a0328d7..3cb6da2 --- a/faiserver-disable +++ b/faiserver-disable @@ -15,4 +15,12 @@ if [[ $1 ]]; then usage 1 fi -ssh root@$(chost faiserver) "sed -ri --follow-symlinks '\%^/srv/fai/d' /etc/exports; exportfs -ra" +ssh root@$(chost faiserver) bash <<'EOF' +if modprobe nfsd &>/dev/null; then + sed -ri --follow-symlinks '\%^/srv/fai/d' /etc/exports + exportfs -ra +else + rm -f /etc/apache2/sites-enabled/faiserver.conf + systemctl reload apache2 +fi +EOF diff --git a/faiserver-setup b/faiserver-setup index 951ec88..f1ab4ba 100755 --- a/faiserver-setup +++ b/faiserver-setup @@ -30,6 +30,10 @@ Set's the current ip as the tftp server. I vaguely remember that using a hostname does not work. Separate from running this, faiserver needs to be setup in dns to point to whatever host this is run on. + +For running on arm, it expects Ian's fai-basefiles repository at +/a/bin/fai-basefiles + EOF exit $1 } @@ -41,18 +45,49 @@ esac e() { echo "$@"; "$@"; } # When stretch becomes stable, change this to stretch. -# I've tested this with stretch, it works, but notably, +# I\'ve tested this with stretch, it works, but notably, # the automatic basefile getting will be for stretch # instead of jessie, so if you install jessie, you need -# to setup the basefile and it's corresponding class. +# to setup the basefile and it\'s corresponding class. base=jessie sed="sed -ri --follow-symlinks" +if ! type -p wget &>/dev/null; then + apt-get install -y wget +fi + +armhf() { + [[ $(dpkg --print-architecture) == armhf ]] +} + if grep -xFq 'VERSION="9 (stretch)"' /etc/os-release; then # if we use stretch, no need for fai-project repo. # this will need to be updated when there is a codename # for stretch+1 rm -f /etc/apt/sources.list.d/fai.list +elif armhf; then + if apt-cache policy | grep o=Debian,a=testing,n=stretch &>/dev/null; then + cat >/etc/apt/sources.list.d/testing.list <<'EOF' +deb http://http.us.debian.org/debian testing main contrib non-free +deb-src http://http.us.debian.org/debian testing main contrib non-free + +deb http://security.debian.org/ testing/updates main contrib non-free +deb-src http://security.debian.org/ testing/updates main contrib non-free + +deb http://http.us.debian.org/debian testing-updates main contrib non-free +deb-src http://http.us.debian.org/debian testing-updates main contrib non-free +EOF + + cat >/etc/apt/preferences.d/fai <<'EOF' +Package: fai-server fai-client fai-doc +Pin: release a=testing +Pin-Priority: 500 + +Package: * +Pin: release a=testing +Pin-Priority: -10 +EOF + fi else wget -O - http://fai-project.org/download/074BCDE4.asc | apt-key add - cat >/etc/apt/sources.list.d/fai.list <<'EOF' @@ -69,21 +104,31 @@ fi apt-get update # Relevant packages from fai-quickstart depends and fai-server recommends. -# I especially do not wait isc-dhcp-server or an inetd -apt-get install -y fai-doc nfs-kernel-server tftpd-hpa tar reprepro squashfs-tools binutils +# I especially do not wait isc-dhcp-server or an inetd. Also excludes +# nfs-kernel-server. On an android chroot, we don\'t have nfs in the +# kernel, or the ability to install it. +pkgs=(fai-doc tftpd-hpa tar reprepro squashfs-tools binutils) +if modprobe nfsd &>/dev/null; then + pkgs+=(nfs-kernel-server) +else + pkgs+=(apache2) +fi + + +apt-get install -y ${pkgs[@]} apt-get install --no-install-recommends -y fai-server r=http://http.us.debian.org/debian # like default, but scrap httpredir, and nonfree. # All my systems should be able to get along without nonfree # for a base working system afaik. -dd of=/etc/fai/apt/sources.list </etc/fai/apt/sources.list <>/etc/fai/apt/sources.list <<'EOF' # uncommenting this from the defaults. it's got bug fixes. # repository that may contain newer fai packages for jessie deb http://fai-project.org/download jessie koeln @@ -91,7 +136,7 @@ deb http://fai-project.org/download jessie koeln deb http://ftp.debian.org/debian jessie-backports main EOF - # note, fai doesn't look at /etc/fai/apt/preferences.d + # note, fai doesn\'t look at /etc/fai/apt/preferences.d cat >/etc/fai/apt/preferences <<'EOF' Package: tar Pin: release a=jessie-backports @@ -101,8 +146,14 @@ fi # tried out a stretch base, doesn't work yet. +# $sed -f - /etc/fai/nfsroot.conf <>/srv/fai/nfsroot/root/.ssh/known_hosts # initially did the basic fai-chboot -Iv $std_arg default @@ -128,22 +238,20 @@ e fai-setup -e -vf # Add debug to -f flag for more verbose output. -# make the faiserver also the apt proxy server -apt-get -y install apt-cacher-ng # background on choosing apt-cacher-ng: # googling around a bit finds 2 main solutions: # http://askubuntu.com/questions/3503/best-way-to-cache-apt-downloads-on-a-lan -# apt-cacher-ng doesn't have zeroconf. -# It touts having minimal dependencies, but I don't care. -# The downside to squid-deb-proxy is that it's config is for specific repos, +# apt-cacher-ng doesn\'t have zeroconf. +# It touts having minimal dependencies, but I don\'t care. +# The downside to squid-deb-proxy is that it\'s config is for specific repos, # you have to add all the repos you use. # That is the main reason I use apt-cacher-ng. # It has a web portal, at http://faiserver:3142/acng-report.html # random fai note: as far as I can tell, profiles are just for putting -# in a selectable boot menu, which I don't want. +# in a selectable boot menu, which I don\'t want. # the logsave prompted because the hostname faiserver was uknown. # Here it was faiserver.lan when running from a faiserver vm. diff --git a/myfai-chboot b/myfai-chboot index 2a6e025..f732642 100755 --- a/myfai-chboot +++ b/myfai-chboot @@ -9,10 +9,19 @@ usage() { cat </dev/null || apt-get -y install dnsutils +ip=$(host $host | sed -rn 's/^\S+ has address //p;T;q') gateway_ip=$(route -n | sed -rn 's/^0\.0\.0\.0\s+(\S+).*/\1/p') -my_ip=$(host faiserver $gateway_ip | sed -rn 's/^\S+ has address //p') -k_args=$(fai-chboot -L '^default$' | \ - sed -r "s/^(\S+\s+){3}(.*root=)(.*)/\2$my_ip:\3/") -rm -f /srv/tftp/fai/pxelinux.cfg/* -e fai-chboot -k "$k_args" -v -f verbose,sshd,createvt,reboot $std_arg $kernel "$host" +my_ip=$(host faiserver $gateway_ip | sed -rn 's/^\S+ has address //p;T;q') -# fai-setup without -e sets the ip to the local_ip/local_network, eg 192.168.1.3/24 -# I restrict it to one ip as simple but imperfect access control. -sed -ri --follow-symlinks '\%^/srv/fai/%d' /etc/exports -cat >>/etc/exports </dev/null; then + std_arg="-u nfs://faiserver/srv/fai/config" + root_arg="$my_ip:/srv/fai/nfsroot" + # fai-setup without -e sets the ip to the local_ip/local_network, eg 192.168.1.3/24 + # I restrict it to one ip as simple but imperfect access control. + sed -ri --follow-symlinks '\%^/srv/fai/%d' /etc/exports + cat >>/etc/exports < + Deny from all + Allow from $ip + +EOF +fi + +rm -f /srv/tftp/fai/pxelinux.cfg/* +if [[ ! $1 ]]; then + exit 0 +fi -# todo, remove the nopxe script. adjust fai-check to reboot if it fails on the kexec. +# man page doesn't explain this, but this deletes & thus disables +# all chboot systems. +e fai-chboot -Iv $std_arg default # set it to default to get a val out of it next +kernel=$(fai-chboot -L '^default$' | awk '{print $3}') +default_k_args=$(fai-chboot -L '^default$' | \ + sed -r "s/^(\S+\s+){3}(.*)/\2/") +# example of default_k_args +# initrd=initrd.img-3.16.0-4-amd64 ip=dhcp root=192.168.1.3:/srv/fai/nfsroot aufs FAI_CONFIG_SRC=nfs://faiserver/srv/fai/config FAI_ACTION=install + +k_args=() +for arg in $default_k_args; do + case $arg in + # default root arg is /srv/fai/nfsroot + root=*) k_args+=(root=$root_arg) ;; + *) k_args+=($arg) ;; + esac +done +rm -f /srv/tftp/fai/pxelinux.cfg/* +e fai-chboot -k "${k_args[*]}" -v -f verbose,sshd,createvt,reboot $std_arg $kernel "$host" -- 2.30.2