updates for t11 and fsf
authorIan Kelling <iank@fsf.org>
Mon, 1 Aug 2022 13:26:06 +0000 (09:26 -0400)
committerIan Kelling <iank@fsf.org>
Mon, 1 Aug 2022 13:26:06 +0000 (09:26 -0400)
26 files changed:
fai-redep
fai/config/class/D16.var
fai/config/class/FSF.var [new file with mode: 0644]
fai/config/distro-install-common/end
fai/config/distro-install-common/libreboot_grub.cfg
fai/config/hooks/instsoft.DEFAULT
fai/config/hooks/partition.DEFAULT
fai/config/package_config/ARAMO_EXTRA.gpg
fai/config/package_config/FSF [new file with mode: 0644]
fai/config/package_config/NABIA_EXTRA.gpg
fai/config/package_config/UBUNTU.gpg [deleted file]
fai/config/package_config/UBUNTU_UP.gpg [new file with mode: 0644]
fai/config/scripts/D16/12-d16
fai/config/scripts/DEBIAN/11-iank
fai/config/scripts/FSF/11-iank
fai/config/scripts/GRUB_PC/10-setup
fai/config/scripts/IANK/11-iank
fsf/close-crypt-luks-keys-loopback [new file with mode: 0755]
fsf/create-vm-disk [new file with mode: 0755]
fsf/crypt-disks-start [new file with mode: 0755]
fsf/open-crypt-luks-keys-loopback [new file with mode: 0755]
kd-mount [new file with mode: 0644]
kd.log [new file with mode: 0644]
lk
pxe-server
wrt-setup-local

index 924e8b7e54dd6be0747699f28133394140f13640..a9742084c39bb3f743d92c6906c8b1415ea6eca0 100755 (executable)
--- a/fai-redep
+++ b/fai-redep
@@ -72,7 +72,7 @@ rsync -atL /home/iank/.ssh/authorized_keys fai/config/files/root/.ssh/authorized
 # we hssh and ssh_filter_btrbk for the initial btrbk (alternatively, I could open up the
 # permissions in authorized_keys, but that just seems lazy)
 install --owner=iank --group=iank -d fai/config/files/usr/local/bin/hssh
-rsync -atL /a/bin/ds/hssh fai/config/files/usr/local/bin/hssh/STANDARD
+rsync -atL /a/bin/ds/hssh fai/config/files/usr/local/bin/hssh/IANK
 install --owner=iank --group=iank -d fai/config/files/usr/local/bin/ssh_filter_btrbk.sh
 rsync -atL /a/opt/btrbk/ssh_filter_btrbk.sh fai/config/files/usr/local/bin/ssh_filter_btrbk.sh/STANDARD
 
index dc8d96bc9a755f70961cee6d1db099c0ea29db4c..fce2f84347ef7ce090addddb6480543143e3e594 100644 (file)
@@ -1,3 +1,10 @@
+# /a/opt/linux/Documentation/admin-guide/serial-console.rst
+# https://libreboot.org/docs/hardware/kgpe-d16.html
+
+
 # pci=realloc=off = per rubens suggestion to make a d16 more stable
-d16_cmdline="console=ttyS0,115200n8 pci=realloc=off console=tty0"
-d16_cmdline="pci=realloc=off console=tty0"
+
+# we make tty0 the last one so that it gets /dev/console and then
+# debian's cryptsetup addition askpass prompts there in the initramfs.
+# todo: file a bug to make it prompt on both.
+d16_cmdline="pci=realloc=off console=ttyS0,115200n8 console=tty0"
diff --git a/fai/config/class/FSF.var b/fai/config/class/FSF.var
new file mode 100644 (file)
index 0000000..9193bf1
--- /dev/null
@@ -0,0 +1 @@
+fsf_cmdline_extra="elevator=deadline transparent_hugepage=always numa=off"
index 602e2ba89ef378cf1e5df6a30da8bd642546b694..f8c9d5f8a4468d521985271002e86e403b8a2db7 100755 (executable)
@@ -90,6 +90,10 @@ Defaults !umask
 Defaults:root,iank !log_allowed, !pam_session
 # for just the root user, set some env vars
 Defaults>root env_file=/etc/rootsudoenv
+
+# a few commands we should be able to run with no password
+iank ALL = (root) NOPASSWD: /usr/local/bin/spend,/usr/bin/nmtui-connect
+
 EOF
 
 case $HOSTNAME in
index 7af4219a4e7ee357e93ab8e6874ce4352f29110f..9ea539022947821a1a1657d1755d50032c298e34 100644 (file)
@@ -29,7 +29,7 @@ set default=/debianbullseye_bootstrap # could use 0 here.
 set timeout=1
 
 # grub_extn
-for part in (ahci*7) (ata*7); do
+for part in (ahci*4) (ata*4); do
     envfile=$part/grubenv
     if [ -s $envfile ]; then
         load_env --file $envfile
index 9d8f0b77fbd51b1be686c97aeab206fe9d27034b..5c7be4e777a920f327931cab7d82a57050eeb2dd 100755 (executable)
@@ -37,17 +37,21 @@ if [[ ${files[0]}  ]]; then
 fi
 
 
-#### this bit is duplicated in rootsshsync, except we skip update-initramfs,
-# since I suspect its not needed. I'm not sure any of this is needed
-# since we initially embed the key, and with distro-begin, we run rootsshsync
-# around the same time as we remove it.
-d=/etc/initramfs-tools
-if [[ -e $d ]] && ! diff -q /root/.ssh/authorized_keys $d/root/.ssh/authorized_keys &>/dev/null; then
-  mkdir -p $d/root/.ssh /etc/dropbear-initramfs
-  chmod 700 $d/root $d/root/.ssh
-  cp -p /root/.ssh/authorized_keys $d/root/.ssh/authorized_keys
-  cp -p /root/.ssh/authorized_keys /etc/dropbear-initramfs
-  if [[ -e /root/.ssh/authorized_keys2 ]]; then
-    cat /root/.ssh/authorized_keys2 >>/etc/dropbear-initramfs
-  fi
+#### This bit is duplicated in rootsshsync, except we skip
+#### update-initramfs and add $target
+####
+# We generally shouldn't need this, because we don't ssh in on the 1st
+# reboot since we initially embed the luks key, and with distro-begin,
+# we run rootsshsync around the same time as we remove it. However, it
+# could be helpful in case of problems.
+
+auth_dir=$target/etc/dropbear/initramfs/
+candidate=$(apt-cache policy dropbear-initramfs | awk '$1 == "Candidate:" { print $2 }' | head -n1 ||:)
+if [[ $candidate ]] && dpkg --compare-versions "$candidate" lt 2020.81-4; then
+  auth_dir=$target/etc/dropbear-initramfs
+fi
+auth_file=$auth_dir/authorized_keys
+mkdir -p $auth_dir
+if [[ ! -e $auth_file ]] || ! diff -q /root/.ssh/authorized_keys $auth_file; then
+  cp -p /root/.ssh/authorized_keys $auth_file
 fi
index e953cf19a238381fb3b9c107396e5fe961043667..7990a19918faf90e56760428b54fce9e032f1120 100755 (executable)
@@ -122,6 +122,11 @@ if [[ $1 ]]; then
   esac
 fi
 
+if [[ ! $SPECIAL_DISK ]] && ! $mkroot2 && ! $mkroot2tab && ! $mktab \
+     && ! ifclass IANK && ! ifclass FSF; then
+  echo $0: error: need class IANK or FSF or SPECIAL_DISK for running in fai
+fi
+
 
 if [[ $SPECIAL_DISK ]]; then
   export CLASS_REPARTITION=true
@@ -289,11 +294,17 @@ $first_boot_dev  /boot  btrfs        nofail,$fstabstd,noatime,subvol=$boot_vol
 $first_efi  /boot/efi  vfat          nofail,$fstabstd  0 0
 $first_boot_dev  /mnt/boot  btrfs    nofail,$fstabstd,noatime,subvolid=0  0 0
 EOF
+    if ! fsf; then
+      cat >> /tmp/fai/fstab <<EOF
+/dev/mapper/crypt-${vgs[0]}-o  /mnt/o  btrfs       nofail,$fstabstd,noatime,subvolid=0$mopts  0 0
+EOF
+    fi
     rm -f /tmp/fai/crypttab
     for vg in ${vgs[@]}; do
       if ! fsf; then
         cat >>/tmp/fai/crypttab <<EOF
 crypt-$vg-root /dev/$vg/root  none  keyscript=/root/keyscript,discard,luks,initramfs
+crypt-$vg-o    /dev/$vg/o     none  keyscript=/root/keyscript,discard,luks,initramfs
 crypt-$vg-swap /dev/$vg/swap  /dev/urandom  swap,cipher=aes-xts-plain64,size=256,hash=ripemd160
 EOF
       fi
@@ -326,9 +337,9 @@ EOF
       # but it is safely ignorable and gets us the ability to just type our password
       # in once at boot. A downside is that they are probably needed to be plugged in to boot.
       cat >>/tmp/fai/crypttab <<EOF
-crypt_dev_ata-Samsung_SSD_870_QVO_8TB_S5VUNG0N900656V${even_bigsuf} /dev/disk/by-id/ata-Samsung_SSD_870_QVO_8TB_S5VUNG0N900656V${even_bigsuf}  none  keyscript=decrypt_keyctl,discard,luks,initramfs
-crypt_dev_ata-TOSHIBA_MD04ACA500_84R2K773FS9A-part1 /dev/disk/by-id/ata-TOSHIBA_MD04ACA500_84R2K773FS9A-part1  none  keyscript=decrypt_keyctl,discard,luks,initramfs
-crypt_dev_ata-ST6000DM001-1XY17Z_Z4D29EBL-part1 /dev/disk/by-id/ata-ST6000DM001-1XY17Z_Z4D29EBL-part1  none  keyscript=decrypt_keyctl,discard,luks,initramfs
+crypt_dev_ata-Samsung_SSD_870_QVO_8TB_S5VUNG0N900656V${even_bigsuf} /dev/disk/by-id/ata-Samsung_SSD_870_QVO_8TB_S5VUNG0N900656V${even_bigsuf}  /mnt/root/q/root/luks/iank  discard,luks
+crypt_dev_ata-TOSHIBA_MD04ACA500_84R2K773FS9A-part1 /dev/disk/by-id/ata-TOSHIBA_MD04ACA500_84R2K773FS9A-part1  /mnt/root/q/root/luks/iank  discard,luks
+crypt_dev_ata-ST6000DM001-1XY17Z_Z4D29EBL-part1 /dev/disk/by-id/ata-ST6000DM001-1XY17Z_Z4D29EBL-part1  /mnt/root/q/root/luks/iank  discard,luks
 EOF
       cat >> /tmp/fai/fstab <<EOF
 # r7 = root partition7. it isnt actually #7 anymore, not a great name, but whatever
@@ -358,7 +369,7 @@ doroot2() {
   root2_devs=()
   for vg in ${vgs[@]}; do
     root2_devs+=(/dev/mapper/crypt-$vg-root2)
-      if $mkroot2; then
+    if $mkroot2; then
       luks-setup /dev/$vg/root2 crypt-$vg-root2
     fi
     cat >>/mnt/root/root2-crypttab <<EOF
@@ -382,6 +393,8 @@ EOF
 
 
 ##### begin variable setup
+
+
 partition=false
 if ifclass REPARTITION; then
   partition=true # force a full wipe
@@ -452,24 +465,27 @@ fi
 
 pvn=1
 
+bootn=2
+
 # rootn=1
 # root2n=2
 # swapn=3
 # bootn=4
 # boot2n=5
 
-efin=2
+efin=3
 # ext partition so grub can write persistent variables,
 # so it can do a one time boot. grub can't write to
 # btrfs or any cow fs because it's more
 # more complicated to do and they don't want to.
-grub_extn=3
+grub_extn=4
 # bios boot partition,
 # https://wiki.archlinux.org/index.php/GRUB
-bios_grubn=4
+bios_grubn=5
 # for an even raid (raid 1), when one disk is bigger, this partition goes on the big disk
-even_bign=5
-lastn=$even_bign
+even_bign=6
+# even_bign only exists in some cases
+lastn=$bios_grubn
 # check if the partitions exist have the right filesystems
 #blkid="$(blkid -s TYPE)"
 for dev in ${short_devs[@]}; do
@@ -490,13 +506,18 @@ done
 
 if $partition && ifclass PARTITION_PROMPT; then
   echo "Press any key except ctrl-c to continue and partition these drives:"
-  echo "  ${short_devs[*]}"
+  if [[ $SPECIAL_DISK ]]; then
+    echo $SPECIAL_DISK
+  else
+    echo "  ${short_devs[*]}"
+  fi
   read -r
 fi
 
 devs=()
 vgs=()
 root_devs=()
+o_devs=()
 swap_devs=()
 shopt -s extglob
 partsuffix=-part
@@ -511,28 +532,33 @@ for short_dev in ${short_devs[@]}; do
 
   dname=${dev##*/}
   vg=vg$dname
+  vg=${vg//:/}
   vgs+=("$vg")
   devs+=("$dev")
   if fsf; then
     root_devs+=(/dev/$vg/root)
     swap_devs+=(/dev/$vg/swap)
   else
+    o_devs+=(/dev/mapper/crypt-$vg-o)
     root_devs+=(/dev/mapper/crypt-$vg-root)
     swap_devs+=(/dev/mapper/crypt-$vg-swap)
   fi
 done
 first_root_dev=${root_devs[0]}
-if [[ ! ${devs[0]} ]]; then
+if [[ ! $SPECIAL_DISK && ! ${devs[0]} ]]; then
   echo "$0: error: failed to detect devs" >&2
   exit 1
 fi
 
 
-
 pvsuf=$partsuffix$pvn
+bootsuf=$partsuffix$bootn
 efisuf=$partsuffix$efin
 grub_extsuf=$partsuffix$grub_extn
-bios_grubsuf=$partsuffix$bios_grubn
+# We dont do anything with this partition here, so this
+# is be unused, but left as a comment for completing the pattern
+# of all the suffixes.
+#bios_grubsuf=$partsuffix$bios_grubn
 even_bigsuf=$partsuffix$even_bign
 
 
@@ -542,6 +568,7 @@ boot_devs=()
 boot2_devs=()
 for dev in ${devs[@]}; do
   vg=vg${dev##*/}
+  vg=${vg//:/}
   # I ran into a machine (frodo) where the bios doesn't know about some disks,
   # so 1st stage of grub also doesn't know about them.
   # Also, grub does not support mounting degraded btrfs as far as
@@ -568,7 +595,7 @@ for dev in ${devs[@]}; do
   if $bad_disk; then
     continue
   fi
-  boot_devs+=(/dev/$vg/boot)
+  boot_devs+=($dev$bootsuf)
   boot2_devs+=(/dev/$vg/boot2)
   boot_space=$(( boot_space + $(parted -m $dev unit MiB print | \
                                   sed -nr "s#^/dev/[^:]+:([0-9]+).*#\1#p") - 1))
@@ -607,7 +634,7 @@ case $raid_level in
   1c3) boot_space=$(( boot_space / 3 )) ;;
 esac
 if fsf; then
-  boot_mib=4000
+  boot_mib=6000
 elif (( boot_space > 900000 )); then
   # this is larger than needed for several /boot subvols,
   # becuase I keep a minimal debian install on it for
@@ -713,16 +740,37 @@ fi
 if $partition; then
   ### begin wipefs
   if [[ ! $SPECIAL_DISK ]]; then
-    for lv in $(lvs --noheadings -o lv_path); do
-      wipefs -a $lv
+
+    # we do lvm removals just for the disks we are using
+    pv_wipes=()
+    vg_wipes=()
+    pv_devs=$(pvs --noheadings -o pvname)
+    for pv_dev in $pv_devs; do
+      pv_disk=${pv_dev%%[0-9]*}
+      for short_dev in ${short_devs[@]}; do
+        if [[ $pv_disk == "$short_dev" ]]; then
+          pv_wipes+=($pv_dev)
+          vgs=$(pvs --noheadings -o vgname $pv_dev)
+          for vg in $vgs; do
+            vg_wipes+=($vg)
+            lvs=$(vgs --noheadings -o lv_path $vg)
+            for lv in $lvs; do
+              wipefs -a $lv
+            done
+          done
+        fi
+      done
     done
-    for vg in $(vgs --noheadings -o vgname); do
+
+    for vg in ${vg_wipes[@]}; do
       vgchange -an $vg
       vgremove -ff $vg
     done
-    for pv in $(pvs --noheadings -o pvname); do
+
+    for pv in ${pv_wipes[@]}; do
       pvremove -ff $pv
     done
+
     for dev in ${devs[@]}; do
       # if we repartition to the same as an old partition,
       # we don't want any old fses hanging around.
@@ -757,11 +805,12 @@ if $partition; then
     fi
   fi
 
+  if [[ $SPECIAL_DISK ]]; then
+    devs=($(devbyid $SPECIAL_DISK))
+  fi
   for dev in ${devs[@]}; do
     vg=vg${dev##*/}
-    if [[ $SPECIAL_DISK ]]; then
-      dev=$(devbyid $SPECIAL_DISK)
-    fi
+    vg=${vg//:/}
 
     # parted will round up the disk size. Do -1 so we can have
     # fully 1MiB unit partitions for easy resizing of the last partition.
@@ -778,27 +827,47 @@ if $partition; then
     # MiB because parted complains about alignment otherwise.
     pcmd="parted -a optimal -s -- $dev"
     # main lvm partition
-    $pcmd mkpart primary ext3 524MiB ${disk_mib}MiB
+
+    pv_end=$(( disk_mib - boot_part_mib ))
+    $pcmd mkpart primary ext3 524MiB ${pv_end}MiB
     $pcmd name $pvn pv
 
-    pvcreate -y $dev$pvsuf
-    vgcreate -y $vg $dev$pvsuf
+    #   + 794 pvcreate -y /dev/disk/by-id/ata-ST4000DM000-1F2168_Z3028BKA-part1
+    # WARNING: Device /dev/sde1 not initialized in udev database even after waiting 10000000 microseconds.
+    # No device found for /dev/disk/by-id/ata-ST4000DM000-1F2168_Z3028BKA-part1.
+    # sleep 10 was not enough.
+    secs=0
+    while [[ ! -e $dev$pvsuf ]] && (( secs < 40 )); do
+      sleep 1
+      secs=$((secs +1))
+    done
+    sleep 3
+    pvcreate -y -ff $dev$pvsuf
+    vgcreate -y -ff $vg $dev$pvsuf
 
     if fsf; then
       root_mib=40000
     else
+      # This would maximize it, but we are going for a separate filesystem in /o,
+      # so use fixed sizes to allow both to grow
       # 600 = uefi 512 + grubext 8 + bios grub 3 + some extra cuz this is lvm
-      root_mib=$(( disk_mib - root2_part_mib - swap_mib - boot_part_mib - boot2_part_mib - 600 ))
+      #root_mib=$(( disk_mib - root2_part_mib - swap_mib - boot_part_mib - boot2_part_mib - 600 ))
+      root_mib=$(( 1000 * 1000 )) # * 1000 to make it in gb.
+      o_mib=$(( 120 * 1000 ))
     fi
 
-    # -L unit default mebibyte
-    lvcreate -y -L $root_mib $vg -n root
-    lvcreate -y -L $swap_mib $vg -n swap
-    # unencrypted swap needs mkswap
-    if fsf; then
-      mkswap /dev/$vg/swap
+    if [[ ! $SPECIAL_DISK ]]; then
+      # -L unit default mebibyte
+      lvcreate -y -L $root_mib $vg -n root
+      if ! fsf; then
+        lvcreate -y -L $o_mib $vg -n o
+      fi
+      lvcreate -y -L $swap_mib $vg -n swap
+      # unencrypted swap needs mkswap
+      if fsf; then
+        mkswap /dev/$vg/swap
+      fi
     fi
-    lvcreate -y -L $boot_part_mib $vg -n boot
 
     if zilap; then
       # todo: now that we are using lvm, this doesnt need to be done until mkroot2
@@ -806,6 +875,10 @@ if $partition; then
       lvcreate -y -L $boot2_part_mib $vg -n boot2
     fi
 
+    $pcmd mkpart primary "" ${pv_end}MiB ${disk_mib}MiB
+    $pcmd name $bootn boot
+    $pcmd set $bootn boot on
+
     # uefi partition, for normal bios systems, its just in case.
     $pcmd mkpart primary "fat32" 12MiB 524MiB
     $pcmd name $efin efi
@@ -844,7 +917,7 @@ if $partition; then
     # but then couldn't be found upon reboot. In that case we didn't
     # wait at all. So I've added a 3 second minimum wait.
     secs=0
-    while [[ ! -e $dev$bios_grubsuf ]] && (( secs < 10 )); do
+    while [[ ! -e $dev$efisuf ]] && (( secs < 40 )); do
       sleep 1
       secs=$((secs +1))
     done
@@ -853,8 +926,8 @@ if $partition; then
     mkfs.fat -F32 $dev$efisuf
 
     if ! fsf && $even_big_part  && [[ $dev == "$even_big_dev" ]]; then
-      luks-setup $even_big_dev ${even_big_dev##*/}
-      mkfs.btrfs -f /dev/mapper/${even_big_dev##*/}
+      luks-setup $even_big_dev$even_bigsuf ${even_big_dev##*/}$even_bigsuf
+      mkfs.btrfs -f /dev/mapper/${even_big_dev##*/}$even_bigsuf
     fi
 
     # Holds just a single file, rarely written, so
@@ -871,6 +944,7 @@ if $partition; then
     # sensitive data.
     if ! fsf; then
       luks-setup /dev/$vg/root crypt-$vg-root
+      luks-setup /dev/$vg/o crypt-$vg-o
     fi
 
     if [[ $SPECIAL_DISK ]]; then
@@ -881,9 +955,12 @@ if $partition; then
   sleep 1
 
   bpart ${root_devs[@]}
+  if ! fsf; then
+    bpart ${o_devs[@]}
+  fi
   bpart ${boot_devs[@]}
 
-else ## above: if $partition ##
+else ## end if $partition ##
 
   if ! fsf; then
     for vg in ${vgs[@]}; do
@@ -893,7 +970,9 @@ else ## above: if $partition ##
       if $rerootfs; then
         luks-setup /dev/$vg/root crypt-$vg-root
       else
-        cryptsetup luksOpen /dev/$vg/root $vg-root \
+        cryptsetup luksOpen /dev/$vg/root crypt-$vg-root \
+                   --key-file $luks_file
+        cryptsetup luksOpen /dev/$vg/o crypt-$vg-o \
                    --key-file $luks_file
       fi
     done
@@ -945,7 +1024,8 @@ btrfs subvolume set-default 0 /mnt # already default, just ensuring it.
 
 # for libreboot systems. grub2 only reads from subvolid=0
 mkdir -p /mnt/grub2
-# todo: this probably needs updating for our lvm transition
+# todo: this would need some rework if we moved boot into
+# lvm.
 cp $FAI/distro-install-common/libreboot_grub.cfg /mnt/grub2
 
 if $wipe && [[ -e /mnt/$boot_vol ]]; then
index 553a4787e5a6526ee7f218846feca9faccfa2c67..ce7b11007a717ec11a59729bc2cfef142b317fa6 120000 (symlink)
@@ -1 +1 @@
-UBUNTU.gpg
\ No newline at end of file
+UBUNTU_UP.gpg
\ No newline at end of file
diff --git a/fai/config/package_config/FSF b/fai/config/package_config/FSF
new file mode 100644 (file)
index 0000000..78498e8
--- /dev/null
@@ -0,0 +1,5 @@
+PACKAGES install
+# needed for bonding
+ifenslave
+# generating luks passwords
+apg
index 553a4787e5a6526ee7f218846feca9faccfa2c67..ce7b11007a717ec11a59729bc2cfef142b317fa6 120000 (symlink)
@@ -1 +1 @@
-UBUNTU.gpg
\ No newline at end of file
+UBUNTU_UP.gpg
\ No newline at end of file
diff --git a/fai/config/package_config/UBUNTU.gpg b/fai/config/package_config/UBUNTU.gpg
deleted file mode 100644 (file)
index 6075639..0000000
+++ /dev/null
@@ -1,626 +0,0 @@
------BEGIN PGP PUBLIC KEY BLOCK-----
-Version: GnuPG v2
-
-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
-=yMYl
------END PGP PUBLIC KEY BLOCK-----
------BEGIN PGP PUBLIC KEY BLOCK-----
-
-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
-Twx6DKLF+3rF5nf1F3Q=
-=PBAe
------END PGP PUBLIC KEY BLOCK-----
------BEGIN PGP PUBLIC KEY BLOCK-----
-
-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
-qnIlKN70FUMxdKabTsePWdIAB2DVOz1Cx6bw
-=p3ci
------END PGP PUBLIC KEY BLOCK-----
------BEGIN PGP PUBLIC KEY BLOCK-----
-
-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
-=yMYl
------END PGP PUBLIC KEY BLOCK-----
------BEGIN PGP PUBLIC KEY BLOCK-----
-
-mQINBFufwdoBEADv/Gxytx/LcSXYuM0MwKojbBye81s0G1nEx+lz6VAUpIUZnbkq
-dXBHC+dwrGS/CeeLuAjPRLU8AoxE/jjvZVp8xFGEWHYdklqXGZ/gJfP5d3fIUBtZ
-HZEJl8B8m9pMHf/AQQdsC+YzizSG5t5Mhnotw044LXtdEEkx2t6Jz0OGrh+5Ioxq
-X7pZiq6Cv19BohaUioKMdp7ES6RYfN7ol6HSLFlrMXtVfh/ijpN9j3ZhVGVeRC8k
-KHQsJ5PkIbmvxBiUh7SJmfZUx0IQhNMaDHXfdZAGNtnhzzNReb1FqNLSVkrS/Pns
-AQzMhG1BDm2VOSF64jebKXffFqM5LXRQTeqTLsjUbbrqR6s/GCO8UF7jfUj6I7ta
-LygmsHO/JD4jpKRC0gbpUBfaiJyLvuepx3kWoqL3sN0LhlMI80+fA7GTvoOx4tpq
-VlzlE6TajYu+jfW3QpOFS5ewEMdL26hzxsZg/geZvTbArcP+OsJKRmhv4kNo6Ayd
-yHQ/3ZV/f3X9mT3/SPLbJaumkgp3Yzd6t5PeBu+ZQk/mN5WNNuaihNEV7llb1Zhv
-Y0Fxu9BVd/BNl0rzuxp3rIinB2TX2SCg7wE5xXkwXuQ/2eTDE0v0HlGntkuZjGow
-DZkxHZQSxZVOzdZCRVaX/WEFLpKa2AQpw5RJrQ4oZ/OfifXyJzP27o03wQARAQAB
-tEJVYnVudHUgQXJjaGl2ZSBBdXRvbWF0aWMgU2lnbmluZyBLZXkgKDIwMTgpIDxm
-dHBtYXN0ZXJAdWJ1bnR1LmNvbT6JAjgEEwEKACIFAlufwdoCGwMGCwkIBwMCBhUI
-AgkKCwQWAgMBAh4BAheAAAoJEIcZINGZG8k8LHMQAKS2cnxz/5WaoCOWArf5g6UH
-beOCgc5DBm0hCuFDZWWv427aGei3CPuLw0DGLCXZdyc5dqE8mvjMlOmmAKKlj1uG
-g3TYCbQWjWPeMnBPZbkFgkZoXJ7/6CB7bWRht1sHzpt1LTZ+SYDwOwJ68QRp7DRa
-Zl9Y6QiUbeuhq2DUcTofVbBxbhrckN4ZteLvm+/nG9m/ciopc66LwRdkxqfJ32Cy
-q+1TS5VaIJDG7DWziG+Kbu6qCDM4QNlg3LH7p14CrRxAbc4lvohRgsV4eQqsIcdF
-kuVY5HPPj2K8TqpY6STe8Gh0aprG1RV8ZKay3KSMpnyV1fAKn4fM9byiLzQAovC0
-LZ9MMMsrAS/45AvC3IEKSShjLFn1X1dRCiO6/7jmZEoZtAp53hkf8SMBsi78hVNr
-BumZwfIdBA1v22+LY4xQK8q4XCoRcA9G+pvzU9YVW7cRnDZZGl0uwOw7z9PkQBF5
-KFKjWDz4fCk+K6+YtGpovGKekGBb8I7EA6UpvPgqA/QdI0t1IBP0N06RQcs1fUaA
-QEtz6DGy5zkRhR4pGSZn+dFET7PdAjEK84y7BdY4t+U1jcSIvBj0F2B7LwRL7xGp
-SpIKi/ekAXLs117bvFHaCvmUYN7JVp1GMmVFxhIdx6CFm3fxG8QjNb5tere/YqK+
-uOgcXny1UlwtCUzlrSaP
-=9AdM
------END PGP PUBLIC KEY BLOCK-----
diff --git a/fai/config/package_config/UBUNTU_UP.gpg b/fai/config/package_config/UBUNTU_UP.gpg
new file mode 100644 (file)
index 0000000..86214bd
Binary files /dev/null and b/fai/config/package_config/UBUNTU_UP.gpg differ
index df3cd5cea42ecf4868a1e99f23f3cd7657abe66b..062d519dda663d771ad2c6ed4da90239dd906cb9 100755 (executable)
@@ -8,6 +8,8 @@ if [[ $EUID != 0 ]]; then
   exit 1
 fi
 
+exit 0
+
 cat >$FAI_ROOT/etc/grub.d/40_custom <<EOF
 #!/bin/sh
 exec tail -n +3 \$0
@@ -18,7 +20,7 @@ exec tail -n +3 \$0
 # https://www.coreboot.org/Serial_console # tty
 # but removed unneeded stuff
 
-serial --speed=$speed
+serial --speed=115200
 terminal_input --append  serial
 terminal_output --append serial
 EOF
index 9a067b1accea5613c77f45f61d689788dd774826..119f354005ea2e17ca4b1171506470d2bfb6e7a1 100755 (executable)
@@ -8,11 +8,12 @@ if [[ $EUID != 0 ]]; then
   exit 1
 fi
 
-fcopy -riBM /root
+fcopy -riB /root
 
 
 #### misc configurations
 chroot $FAI_ROOT bash <<'EOFOUTER'
+set -x
 if getent group systemd-journal >/dev/null; then
   # makes the journal be saved to disk.
   mkdir -p /var/log/journal
@@ -30,13 +31,15 @@ sed -i '$a kernel.sysrq=1
 
 EOFOUTER
 
+cmdline_extra="$d16_cmdline $fsf_cmdline_extra"
+
 # luks options, see man systemd-cryptsetup-generator
 # all i know is that with luks.crypttab=no, swap still timed out on boot.
 # and with rd.luks.crypttab=no, it works.
 cmdline="rd.luks.crypttab=no net.ifnames=0 $cmdline_extra"
 
-
 chroot $FAI_ROOT bash <<EOF
+set -x
 set -eE -o pipefail
 # https://askubuntu.com/questions/33416/how-do-i-disable-the-boot-splash-screen-and-only-show-kernel-and-boot-text-inst
 
@@ -53,6 +56,11 @@ if grep -qF "$cmdline" /etc/default/grub; then
   # already set things, exit
   exit 0
 fi
+
+# required to show vga grub on d16, at least for t11
+echo GRUB_TERMINAL=console >>/etc/default/grub
+
+
 sed -ri 's/^ *GRUB_CMDLINE_LINUX_DEFAULT=.*/GRUB_CMDLINE_LINUX_DEFAULT="$cmdline"/' /etc/default/grub
 sed -ri 's/^ *GRUB_TIMEOUT_STYLE=.*/GRUB_TIMEOUT_STYLE=menu/' /etc/default/grub
 sed -ri 's/^ *GRUB_TIMEOUT=.*/GRUB_TIMEOUT=6/' /etc/default/grub
index 93c227f584d7b3854aad7a3035e545d17cd85bd8..8a33d6f70edd1c614089bcdb88844d755d8d01d7 100755 (executable)
@@ -23,27 +23,78 @@ iface eth0 inet6 auto
 source-directory /etc/network/interfaces.d
 EOF
 else
-  ip=$(getent ahosts $HOSTNAME |grep ^209.*RAW| sed 's/ .*//')
-  ip6=$(getent ahosts $HOSTNAME |grep ^2001.*RAW| sed 's/ .*//')
-  gateway=209.51.188.1
+  ip6=$(getent ahosts $HOSTNAME |grep ^2001.*RAW| sed 's/ .*//' ||:)
   gateway6=2001:470:142::1
-  cat > $target/etc/network/interfaces <<EOF
-# The loopback network interface
+
+  # todo: this needs adjustment per machine
+  internal_ip=10.0.0.25/16
+
+  if ip l show dev bond0 &>/dev/null; then
+    cat >$target/etc/network/interfaces <<EOF
 auto lo
 iface lo inet loopback
 
 auto eth0
-iface eth0 inet static
-  address $ip
-  gateway $gateway
-  netmask 255.255.255.0
+allow-bond eth0
+iface eth0 inet manual
+  bond-master bond0
 
-iface eth0 inet6 static
-  pre-up echo 0 > /proc/sys/net/ipv6/conf/eth0/accept_dad
+auto eth1
+allow-bond eth1
+iface eth1 inet manual
+  bond-master bond0
+
+auto bond0
+iface bond0 inet static
+  bond-slaves none
+  bond-mode 0
+  bond-miimon 100
+  address $internal_ip
+  pre-up ip link add link bond0 name macvtap-bond0 type macvtap mode bridge
+# no iptables files exist yet
+#  post-up iptables-restore < /etc/default/iptables ; ip6tables-restore < /etc/default/ip6tables || :
+
+auto macvtap-bond0
+iface macvtap-bond0 inet static
+  address $CIDR
+  gateway $GATEWAYS
+  post-up ip a add $internal_ip broadcast 10.0.255.255 dev macvtap-bond0
+
+EOF
+
+    # I'm not sure ipv6 works well with the macvtap stuff. todo: research.
+    # anyways, other kvm hosts dont have it enabled.
+    if false && [[ $ip6 ]]; then
+      cat >>$target/etc/network/interfaces <<EOF
+iface bond0 inet6 static
+  pre-up echo 0 > /proc/sys/net/ipv6/conf/bond0/accept_dad
   address $ip6
   netmask 48
   gateway $gateway6
 EOF
+    fi
+
+  else
+    cat > $target/etc/network/interfaces <<EOF
+auto lo
+iface lo inet loopback
+
+auto eth0
+iface eth0 inet static
+address $CIDR
+gateway $GATEWAYS
+EOF
+
+    if [[ $ip6 ]]; then
+      cat >>$target/etc/network/interfaces <<EOF
+iface eth0 inet6 static
+pre-up echo 0 > /proc/sys/net/ipv6/conf/eth0/accept_dad
+address $ip6
+netmask 48
+gateway $gateway6
+EOF
+    fi
+  fi
 fi
 
 # previously had an else condition after
@@ -61,10 +112,13 @@ fi
 
 ##### end network setup  #####
 
+# note: systemd-resolved + ifupdown causes networking.service to fail in t11,
+# https://bugs.launchpad.net/ubuntu/+source/ifupdown/+bug/1907878
+systemctl disable systemd-resolved
 # rm first to remove any symlink
 rm -f $target/etc/resolv.conf
 
-if ifclass demohost; then
+if ifclass demohost || [[ $GATEWAYS != 209.51.188.* ]]; then
   cat >$target/etc/resolv.conf <<'EOF'
 nameserver 8.8.8.8
 EOF
index e26aa2671180c03eccc373cac1c9845eef818688..11535f11f5b2b4df0f6943a552c020523989842d 100755 (executable)
@@ -73,14 +73,16 @@ if [[ $BOOT_DEVICE =~ '/dev/md' ]]; then
     mbrdevices=${mbrdevices%, }
 else
   for dev in $BOOT_DEVICE; do
-    mbrdevices=$(get_stable_devname $dev)
+    mbrdev=$(get_stable_devname $dev)
     if [ -z "$mbrdevices" ]; then
       # if we cannot find a persistent name (for e.g. in a VM) use old name
-      mbrdevices=$dev
+      mbrdevices+="$dev, "
     fi
-    echo "Installing grub on $dev = $mbrdevices"
-    $ROOTCMD grub-install --no-floppy "$mbrdevices"
+    echo "Installing grub on $dev = $mbrdev"
+    $ROOTCMD grub-install --no-floppy "$mbrdev"
   done
+  # remove trailing ,
+  mbrdevices=${mbrdevices%, }
 fi
 
 echo "grub-pc grub-pc/install_devices multiselect $mbrdevices" | $ROOTCMD debconf-set-selections
index 1ffb74d575cb0000e6fe836299e1994b296f9ea0..5245b35ae7a210dd1bf4733f61a86d4f2dfe417f 100755 (executable)
@@ -24,14 +24,14 @@ fi
 # -r = recursive
 # -i = ignore non-matching class warnings, always exit 0
 # -B = no backup files
-fcopy -riBM /boot
+fcopy -riB /boot
 # this is also done by FAIBASE/10-misc by default (without B)
-fcopy -riBM /usr/local/bin
+fcopy -riB /usr/local/bin
 
 # this gets done by fai, but just happens too often that
 # I add sources due to new distros, whatever.
-fcopy -riBM /etc/apt/preferences.d
-fcopy -riBM /etc/apt/sources.list.d
+fcopy -riB /etc/apt/preferences.d
+fcopy -riB /etc/apt/sources.list.d
 
 
 src=$FAI/distro-install-common/shadow
@@ -52,7 +52,7 @@ $FAI/distro-install-common/end
 tmpfile1=$(mktemp)
 # this can fail if we need an apt update
 chroot $FAI_ROOT /usr/bin/apt-cache policy >$tmpfile1 ||:
-fcopy -riBM /etc/apt
+fcopy -riB /etc/apt
 
 tmpfile2=$(mktemp)
 chroot $FAI_ROOT /usr/bin/apt-cache policy >$tmpfile2
diff --git a/fsf/close-crypt-luks-keys-loopback b/fsf/close-crypt-luks-keys-loopback
new file mode 100755 (executable)
index 0000000..6b0f80d
--- /dev/null
@@ -0,0 +1,30 @@
+#!/bin/bash
+
+# usage: $0
+# this script is idempotent
+
+# warning: changes here may affect the open version of this script
+
+if ! test "$BASH_VERSION"; then echo "error: shell is not bash" >&2; exit 1; fi
+shopt -s inherit_errexit 2>/dev/null ||: # ignore fail in bash < 4.4
+set -eE -o pipefail
+trap 'echo "$0:$LINENO:error: \"$BASH_COMMAND\" exit status: $?, PIPESTATUS: ${PIPESTATUS[*]}" >&2' ERR
+
+m() { printf "%s\n" "$*";  "$@"; }
+
+
+fs_file=/root/crypt-luks-keys-loopback
+mapper_name=crypt-luks-keys-loopback
+
+if mountpoint /mnt2 &>/dev/null; then
+  m umount /mnt2
+fi
+if cryptsetup status /dev/mapper/$mapper_name &>/dev/null; then
+  m cryptsetup luksClose /dev/mapper/$mapper_name; then
+fi
+l=$(losetup -l --noheadings | awk '$6 ~ /\/'$mapper_name'$/ {print $1}')
+if [[ $l ]]; then
+  m losetup -d $l
+else
+  echo "$0: warning: no loopback device found" >&2
+fi
diff --git a/fsf/create-vm-disk b/fsf/create-vm-disk
new file mode 100755 (executable)
index 0000000..37cc45f
--- /dev/null
@@ -0,0 +1,160 @@
+#!/bin/bash
+# Copyright (C) 2022 Ian Kelling
+# SPDX-License-Identifier: AGPL-3.0-or-later
+
+# todo: put this script and this library into ansible
+source /usr/local/lib/err
+
+#### begin arg processing ###
+usage() {
+  cat <<EOF
+Usage: ${0##*/} [mdraid] hdd|sdd size_in_GB fqdn
+create disk for vm
+
+-h|--help  Print help and exit.
+
+EOF
+  exit $1
+}
+m() { printf "%s\n" "$*";  "$@"; }
+
+
+mdraid=false
+case $1 in
+  mdraid)
+    mdraid=true
+    shift
+    ;;
+  --help)
+    usage
+    ;;
+esac
+
+if (( $# != 3 )); then
+  echo "$0: error: expected 3 arguments" >&2
+  usage 1
+fi
+
+read -r disk_type gb hostname  <<<"$@"
+#### end arg processing ###
+
+if ! type -p apg &>/dev/null; then
+  apt install -y apg
+fi
+
+if ! mountpoint -q /mnt2; then
+  echo "$0: error: expected /mnt2 to be a mountpoint, run /root/open-crypt-luks-keys-loopback" >&2
+fi
+
+case $disk_type in
+  hdd)
+    volgroups=(
+      vgata-WDC_WD4004FZWX-00GBGB0_NHG3PK4M
+      vgata-ST4000DM000-1F2168_Z3028BKA
+      vgata-WDC_WD40EZRX-00SPEB0_WD-WCC4E0304017
+    )
+    ;;
+  sdd)
+    volgroups=(
+      vgata-Samsung_SSD_850_EVO_1TB_S3PJNB0J902536K
+      vgata-Samsung_SSD_850_EVO_1TB_S3PJNF0J909382V
+      vgata-Samsung_SSD_850_EVO_1TB_S3PJNF0J909379K
+    )
+    ;;
+esac
+
+for vg in ${volgroups[@]}; do
+  lvdev=/dev/$vg/$hostname
+  if [[ -e $lvdev  ]]; then
+    echo "$0: skipping creation of existing lv: $lvdev"
+  else
+    m lvcreate -L ${gb}g -n $hostname $vg
+  fi
+done
+
+keyfile=/mnt2/$hostname
+if [[ ! -s $keyfile ]]; then
+  apg -m 25 -x 25 -n1 | tr -d '\n' >$keyfile
+  # directory is already 700, just being thorough
+  m chmod 600 $keyfile
+fi
+
+crypttab_err=false
+
+mountdir=/mnt/$hostname
+mkdir -p $mountdir
+integrity_devs=()
+if $mdraid; then
+  for vg in ${volgroups[@]}; do
+    lvdev=/dev/$vg/$hostname
+    integrity_name=integrity-$vg-$hostname
+    integrity_dev=/dev/mapper/$integrity_name
+    integrity_devs+=($integrity_dev)
+    if [[ -e $integrity_dev ]]; then
+      echo "$0: skipping creation of existing integrity dev: $integrity_dev"
+    else
+      m time integritysetup --batch-mode format $lvdev
+      m integritysetup open --allow-discards $lvdev $integrity_name
+    fi
+  done
+  mddev=/dev/md/md$hostname
+  if [[ -e $mddev ]]; then
+    echo "$0: skipping creation of existing mddev: $mddev"
+  else
+    # get stable auto-assembled names
+    # https://serverfault.com/questions/763870/raid-device-on-rename-appended-with-0
+    if ! grep -Fxq "HOMEHOST <ignore>" /etc/mdadm/mdadm.conf; then
+      sed -i '/^ *HOMEHOST/d' /etc/mdadm/mdadm.conf
+      echo "HOMEHOST <ignore>" >>/etc/mdadm/mdadm.conf
+      m update-initramfs -u -k all
+    fi
+    yes yes | m mdadm --create /dev/md/md$hostname --level 1 --raid-devices=3  ${integrity_devs[@]} || [[ $? == 141 ]]
+  fi
+  luks_name=crypt-$hostname
+  luks_dev=/dev/mapper/$luks_name
+  if [[ -e $luks_dev ]]; then
+    echo "$0: skipping creation of existing luks dev: $luks_dev"
+  else
+    yes YES | m cryptsetup luksFormat $mddev $keyfile || [[ $? == 141 ]]
+    echo appending to /etc/crypttab
+    echo "$luks_name $mddev $keyfile discard,luks" | tee -a /etc/crypttab
+    m cryptdisks_start $luks_name
+  fi
+  m mkfs.ext4 $luks_dev
+else
+
+  luks_devs=()
+  for vg in ${volgroups[@]}; do
+    lvdev=/dev/$vg/$hostname
+    # todo add apg to automatically installed packages
+    yes YES | m cryptsetup luksFormat $lvdev $keyfile  || [[ $? == 141 ]]
+    luks_name=crypt-$vg-$hostname
+    echo appending to /etc/crypttab
+    line="$luks_name $lvdev $keyfile discard,luks,noauto"
+    if grep -Fq "$lvdev" /etc/crypttab; then
+      if grep -Fx "$line" /etc/crypttab; then
+        echo "$0: crypttab line already found ^. not adding"
+      else
+        echo "$0: error: found existing lvdev: $lvdev in /etc/crypttab that is different than expected:"
+        echo "$line"
+        echo "saving exit 1 until script completes. manual intervention required"
+        crypttab_err=true
+      fi
+    else
+      echo "appending to /etc/crypttab:"
+      echo "$line" | tee -a /etc/crypttab
+    fi
+    m cryptdisks_start $luks_name
+    luks_devs+=(/dev/mapper/$luks_name)
+  done
+
+  m mkfs.btrfs -f -m raid1c3 -d raid1c3 ${luks_devs[@]}
+  m mount ${luks_devs[0]} $mountdir
+  m btrfs sub create $mountdir/root
+  m umount $mountdir
+fi
+
+if $crypttab_err; then
+  echo "$0: crypttab error, exiting 1, see above."
+  exit 1
+fi
diff --git a/fsf/crypt-disks-start b/fsf/crypt-disks-start
new file mode 100755 (executable)
index 0000000..7e310da
--- /dev/null
@@ -0,0 +1,30 @@
+#!/bin/bash
+
+# usage: $0
+# this script is idempotent
+
+if ! test "$BASH_VERSION"; then echo "error: shell is not bash" >&2; exit 1; fi
+shopt -s inherit_errexit 2>/dev/null ||: # ignore fail in bash < 4.4
+set -eE -o pipefail
+trap 'echo "$0:$LINENO:error: \"$BASH_COMMAND\" exit status: $?, PIPESTATUS: ${PIPESTATUS[*]}" >&2' ERR
+
+m() { printf "%s\n" "$*";  "$@"; }
+
+
+lvs --noheadings -o vg_name,lv_name | while read -r vg lv; do
+  if [[ ! $vg || ! $lv ]]; then
+    continue
+  fi
+  if ! integritysetup dump /dev/$vg/$lv &>/dev/null; then
+    continue
+  fi
+  int_name=integrity-$vg-$lv
+  if integritysetup status $int_name &>/dev/null; then
+    continue
+  fi
+  m integritysetup open --allow-discards /dev/$vg/$lv $int_name
+done
+
+awk '$1 !~ /^ *#/ {print $1}' /etc/crypttab | while read -r c; do
+  m cryptdisks_start $c
+done
diff --git a/fsf/open-crypt-luks-keys-loopback b/fsf/open-crypt-luks-keys-loopback
new file mode 100755 (executable)
index 0000000..09c85fd
--- /dev/null
@@ -0,0 +1,40 @@
+#!/bin/bash
+
+# usage: $0
+# this script is idempotent
+
+# warning: changes here may affect the close version of this script
+
+
+if ! test "$BASH_VERSION"; then echo "error: shell is not bash" >&2; exit 1; fi
+shopt -s inherit_errexit 2>/dev/null ||: # ignore fail in bash < 4.4
+set -eE -o pipefail
+trap 'echo "$0:$LINENO:error: \"$BASH_COMMAND\" exit status: $?, PIPESTATUS: ${PIPESTATUS[*]}" >&2' ERR
+
+m() { printf "%s\n" "$*";  "$@"; }
+
+
+fs_file=/root/crypt-luks-keys-loopback
+mapper_name=crypt-luks-keys-loopback
+
+l=$(losetup -j $fs_file | sed -rn 's/^([^ ]+): .*/\1/p' | head -n1 ||:)
+if [[ $l ]]; then
+  echo "$0: skipping losetup due to existing loopback: $l"
+else
+  l=$(losetup -f)
+  m losetup $l $fs_file
+fi
+if cryptsetup status /dev/mapper/$mapper_name &>/dev/null; then
+  echo "$0: skipping cryptsetup due to existing /dev/mapper/$mapper_name"
+else
+  if ! cryptsetup luksOpen $l $mapper_name; then
+    echo "$0: error luksOpen failed. detaching loopback" >&2
+    m losetup -d $l
+    exit 1
+  fi
+fi
+if mountpoint -q /dev/mapper/$mapper_name; then
+  echo "$0: skipping mount /dev/mapper/$mapper_name /mnt2 due to existing mount"
+else
+  m mount /dev/mapper/$mapper_name /mnt2
+fi
diff --git a/kd-mount b/kd-mount
new file mode 100644 (file)
index 0000000..ad3c7f7
--- /dev/null
+++ b/kd-mount
@@ -0,0 +1,17 @@
+#!/bin/bash
+
+cd /dev
+ls -lad vgata-Samsung_SSD_8*
+
+read -p "enter crypt pass" -r key
+printf %s "$key" >/root/key
+
+cryptsetup luksOpen /dev/vgata-Samsung_SSD_850_EVO_2TB_S2RLNX0J502123D/root crypt-vgata-Samsung_SSD_850_EVO_2TB_S2RLNX0J502123D-root --key-file /root/key
+cryptsetup luksOpen /dev/vgata-Samsung_SSD_870_QVO_8TB_S5VUNG0N900656V/root crypt-vgata-Samsung_SSD_870_QVO_8TB_S5VUNG0N900656V-root --key-file /root/key
+mount -o subvol=root_trisquelaramo /dev/mapper/crypt-vgata-Samsung_SSD_850_EVO_2TB_S2RLNX0J502123D-root /mnt
+mount -o subvol=boot_trisquelaramo /dev/sda2 /mnt/boot
+
+cryptsetup luksOpen /dev/vgata-Samsung_SSD_850_EVO_2TB_S2RLNX0J502123D/o crypt-vgata-Samsung_SSD_850_EVO_2TB_S2RLNX0J502123D-o --key-file /root/key
+cryptsetup luksOpen /dev/vgata-Samsung_SSD_870_QVO_8TB_S5VUNG0N900656V/o crypt-vgata-Samsung_SSD_870_QVO_8TB_S5VUNG0N900656V-o --key-file /root/key
+
+mount /dev/mapper/crypt-vgata-Samsung_SSD_850_EVO_2TB_S2RLNX0J502123D-o /mnt/mnt/o
diff --git a/kd.log b/kd.log
new file mode 100644 (file)
index 0000000..2106679
--- /dev/null
+++ b/kd.log
@@ -0,0 +1,6 @@
+  407 root      3204 S    /bin/sh /scripts/local-top/cryptroot
+  423 root         0 IW   [kworker/6:2-eve]
+  432 root      3064 S    /bin/sh /lib/cryptsetup/scripts/decrypt_keyctl none
+  433 root      3204 S    /bin/sh /scripts/local-top/cryptroot
+  434 root     10768 S<   /sbin/cryptsetup -T1 --allow-discards --type=luks --key-file=- ope
+  436 root      2648 S    /lib/cryptsetup/askpass Caching passphrase for crypt-vgata-Samsung
diff --git a/lk b/lk
index d3d13eab9cc8f5607aa55b30871e36ef9b997d8a..247f4ed15621b8eee48f3590d7215554151a6652 100755 (executable)
--- a/lk
+++ b/lk
@@ -60,7 +60,7 @@ if grep -q ID=ubuntu /etc/os-release; then
     sed -ri '/^\s*deb/{/universe/!s/$/ universe/}' /etc/apt/sources.list
 fi
 if ! type -p pxe-kexec >/dev/null 2>&1; then
-    apt-get update
+    apt-get update ||: # try even if we fail
     apt-get install -y debconf
     debconf-set-selections <<EOF
 kexec-tools kexec-tools/load_kexec boolean false
index 5915f96f1931da30cdf4f3ec24f4a6f10ff1f3f5..78e25a6b9fd0de1a8771d7b0c6871525be5d2532 100755 (executable)
@@ -47,7 +47,7 @@ TYPE       One of arch, parabola, plain, fai.
            after the 2nd. I can't remember exactly why this caused a
            problem, but I'm hoping the sleep will take care of it.
 -d         Don't alter dhcp config. Only make sense for fai type, and on network
-           other than home or fsf, or when using fai-cd.
+           other than home or fsf, when using fai-cd, or pxe-kexec.
 -k         Pass -k to myfai-chboot.
 -r         Don't redeploy fai config. For example, if there is a different host
            that is mid-install.
index 7efa19a66fb7d3bc4eeed3ee21155df03d9e86e6..ce6ad036e46ccaffbc289b94f9f1dd6a9933af53 100755 (executable)
@@ -1060,8 +1060,13 @@ rebind-domain-ok=b8.nz
 # It is default if dnsmasq is doing dns, otherwise, we have to specify it.
 # To see it in action, I ran this from a client machine:
 # sudo dhcpcd -o domain_name_servers -T
-dhcp-option=6,$l.1
+dhcp-option=option:dns-server,$l.1
 
+# use this when doing fai to get the right timezone, its nfsroot is
+# setup to use this dhcp option only and call ntpdate.
+# generate ips with:
+# for h in 0.ubuntu.pool.ntp.org 1.ubuntu.pool.ntp.org ntp.ubuntu.com; do host -t a $h | awk '{print $NF}'; done | while read -r l; do printf ,$l; done
+dhcp-option=option:ntp-server,188.165.3.28,202.12.97.45,91.236.251.13,50.205.244.23,78.30.254.80,31.131.0.123,202.65.114.202,94.228.220.14,185.125.190.57,185.125.190.58,91.189.91.157,185.125.190.56,91.189.94.4
 
 
 # results from googling around dnsmasq optimizations
@@ -1138,7 +1143,8 @@ dhcp-host=0a:8a:9b:cf:b5:ec,set:samsungtab,$l.32,samsungtab
 dhcp-host=b8:27:eb:78:21:1d,set:pi3b,$l.33,pi3b
 dhcp-host=e4:5f:01:07:50:3f,set:pi4,$l.38,pi4
 dhcp-host=e4:5f:01:07:50:40,set:pi4w,$l.39,pi4w
-#dhcp-host=,set:pi4,$l.33,pi4
+# server d16:
+dhcp-host=38:2c:4a:c9:33:13,set:bigs,$l.48,bigs
 
 
 # faiserver vm