various minor fixes and improvements
authorIan Kelling <iank@fsf.org>
Sun, 17 Feb 2019 17:03:28 +0000 (12:03 -0500)
committerIan Kelling <iank@fsf.org>
Sun, 17 Feb 2019 17:03:28 +0000 (12:03 -0500)
README
archlike-iso-init [moved from arch-iso-init with 93% similarity]
archlike-pxe [moved from arch-pxe with 78% similarity]
fai-revm
fai/config/class/50-host-classes
fai/config/files/etc/apt/preferences.d/flidas-xenial/FLIDAS [deleted file]
fai/config/files/etc/apt/sources.list.d/flidas.list/FLIDAS
faiserver-setup
myfai-chboot
pxe-server
wrt-setup-local

diff --git a/README b/README
index 07b54a803af60796ebb4ef67e6a316532c3ea54b..c61f18908f4f65e5e2e8a3fd2f7955b8cd6bd967 100644 (file)
--- a/README
+++ b/README
@@ -6,10 +6,11 @@ scripts which can run post boot so I use them on vps distributed image
 as well.
 
 Features people may find useful: installs encrypted trisquel, debian,
-ubuntu, and arch (havne't done recently, probably a bit broken), in a
-multi-boot setup using multiple subvolumes of a single btrfs filesystem.
-Utilizes multiple disks, with scripts to automatically decrypt on
-intentional reboots, but not after shutdown or power loss.
+ubuntu, arch, and parabola (archlike install is likely broken, I've only
+done pxe boots recently), in a multi-boot setup using multiple
+subvolumes of a single btrfs filesystem.  Utilizes multiple disks, with
+scripts to automatically decrypt on intentional reboots, but not after
+shutdown or power loss.
 
 Normal install mode for fai is using pxe, but on a libreboot system,
 there is no pxe. The pxe in a normal computer is nonfree
@@ -63,6 +64,10 @@ Some of the scripts have dependencies for some simple obvious utility
 scripts from https://iankelling.org/git, and of course there are some
 hostnames that are specific to my network.
 
+Before doing a fai install, you will need to populate a class file.  I
+use one called 5-multi-boot, which you can see example of in
+fai/config/class/50-host-classes.
+
 
 
 All scripts meant to be used directly are listed here:
@@ -72,7 +77,7 @@ All scripts meant to be used directly are listed here:
 
 sudo fai-cd -g grub.cfg.autodiscover -f -A $BASEFILE_DIR/autodiscover.iso # create autodiscover cd
 mymk-basefile # Create basefiles for various distros
-arch-pxe # Setup arch pxe boot server from an arch base image
+archlike-pxe # Setup pxe boot server from an archlike base image
 fai-redep # Deploy fai configuration to host "faiserver"
 faiserver-uninstall # uninstall fai-server
 faiserver-setup # install fai-server on the current machine
@@ -111,6 +116,7 @@ fresize # resize swap or boot partitions in a host
 pxe-server -S HOST fai
 ssh root@HOST
 cat >p
+for x in /target/*; do umount $x; done
 PASSWORD HERE(ctrl-d ctrl-d)
 for d in /dev/disk/by-id/ata*part1; do cryptsetup luksOpen --key-file p $d crypt_dev_${d##*/}; done
 # btrfs replace disk # i forget the actual command
@@ -137,6 +143,9 @@ addgroup: The group `systemd-journal' already exists as a system group. Exiting.
 Operation failed: No such file or directory
 
 
+# TODO
+Change arch to archlike and to support arch and parabola
+
 
 # License
 
similarity index 93%
rename from arch-iso-init
rename to archlike-iso-init
index e0118f220cd4275e80406f7d824368b2c3b12b98..25b9f86c51910dfcd12022e525d1b2bdce13cc38 100644 (file)
@@ -1,5 +1,5 @@
 #!/bin/bash
-echo $(date) > /tmp/myarchinit.log
+echo $(date) > /tmp/myarchlikeinit.log
 if ! ip a | grep '^ *inet ' | grep -vF 127.0.0.1; then
     cat <<'eof'
 We don't have an ipv4 address. Maybe arch doesn't do that for us,
similarity index 78%
rename from arch-pxe
rename to archlike-pxe
index 78205442c62e4b3fe9f1623e43ce6f3c6cf1d31d..ba39c456d4d4a18bb5c1fbd26f22df27be3cd7d1 100755 (executable)
--- a/arch-pxe
@@ -1,4 +1,4 @@
-#!/bin/bash -lx
+#!/bin/bash -l
 # Copyright (C) 2016 Ian Kelling
 
 # This program is free software; you can redistribute it and/or
@@ -42,20 +42,19 @@ esac
 
 x="$(readlink -f "$BASH_SOURCE")"
 script_dir="${x%/*}"
-cd /a/opt
-iso="parabola-systemd-cli-x86_64-netinstall-2017.10.18-00.07-alpha"
-rm -rf $iso
-ex $iso.iso
-n=parabola
-if [[ ! -e $iso/parabola ]]; then
-    n=arch
-fi
-sfs=$iso/$n/x86_64/*.sfs
-
-sed -i --follow-symlinks -f - $iso/$n/boot/syslinux/${n}iso_pxe64.cfg <<EOF
+cd /a/opt/roms
+iso="parabola-systemd-cli-x86_64-netinstall-2018.06.02.iso"
+idir=${iso%.iso}
+rm -rf $idir
+ex $iso
+# should be parabola or arch
+n=${iso%%-*}
+sfs=$idir/$n/x86_64/*.sfs
+
+sed -i --follow-symlinks -f - $idir/$n/boot/syslinux/${n}iso_pxe64.cfg <<EOF
 1itotaltimeout 1
 /^LABEL arch64_nfs/a menu default
-s/^APPEND .*/\0 script=arch-iso-init/
+s/^APPEND .*/\0 script=archlike-iso-init/
 EOF
 # based on https://blog.chendry.org/2015/02/06/automating-arch-linux-installation.html
 # and https://wiki.archlinux.org/index.php/Remastering_the_Install_ISO
@@ -66,20 +65,22 @@ s mkdir -p squashfs-root/root/.ssh
 s chmod 755 squashfs-root/root/.ssh
 s cp ~/.ssh/home.pub squashfs-root/root/.ssh/authorized_keys
 
-s cp $script_dir/arch-iso-init squashfs-root/root
+s cp $script_dir/archlike-iso-init squashfs-root/root
 s rm $sfs
 s mksquashfs squashfs-root $sfs -comp xz
 # file transfer to wrt is slow, so remove some useless files
-rm -f $iso/$n/i686/airootfs.sfs $iso/$n/boot/i686/${n}iso.img
+rm -f $idir/$n/i686/airootfs.sfs $idir/$n/boot/i686/${n}iso.img
 pushd $(dirname $sfs); md5sum ${sfs##*/} > airootfs.md5; popd
 
 # seems if you've done a pxe boot, mounted the nfs,
 # then shutdown, it's still busy.
 ssh wrt "/etc/init.d/nfsd stop; \
-{ ! mount | grep /run/archiso/bootmnt || umount /run/archiso/bootmnt; } && \
-rm -rf /mnt/usb/$iso"
-scp -r $iso wrt:/mnt/usb
-ssh wrt "cd /mnt/usb && rm -f tftpboot && ln -s $iso tftpboot"
+umount /run/archiso/bootmnt; \
+umount /run/parabolaiso/bootmnt; \
+rm -rf /mnt/usb/$idir"
+
+scp -r $idir wrt:/mnt/usb
+ssh wrt "cd /mnt/usb && rm -f tftpboot && ln -s $idir tftpboot"
 
 # The default settings in the installer expect to find the NFS at /run/archiso/bootmnt
 
@@ -88,5 +89,5 @@ ssh wrt "cd /mnt/usb && rm -f tftpboot && ln -s $iso tftpboot"
 # arch can do netboot like ubuntu etc, but the docs look a little
 # complicated, so fuck it, we use nfs cuz it's easy
 
-rm -rf $iso
+rm -rf $idir
 s rm -rf squashfs-root
index 880a91c5e0d10a3bcd6ffb8c96df36f5a9624fa8..d09bbcc7a986552dccd53dee09a7f8b55dfcc76c 100755 (executable)
--- a/fai-revm
+++ b/fai-revm
@@ -100,12 +100,15 @@ else
     e ./pxe-server $dhcp_arg demohost fai
     sleep 2
   else
+    killall fai-monitor &>/dev/null ||:
     fai-monitor &
     if [[ ! $BASEFILE_DIR ]]; then
       BASEFILE_DIR=/tmp
     fi
-    if [[ ! -e $BASEFILE_DIR/autodiscover.iso ]]; then
-      fai-cd -g $(readlink -f grub.cfg.autodiscover) -f -A $BASEFILE_DIR/autodiscover.iso
+    a=$BASEFILE_DIR/autodiscover.iso
+    b=$BASEFILE_DIR/STRETCH64.tar.gz
+    if [[ ! -e $a || $(stat -c %Y $a) -lt $(stat -c %Y $b) ]]; then
+      e s fai-cd -g $(readlink -f grub.cfg.autodiscover) -f -A $BASEFILE_DIR/autodiscover.iso
     fi
     boot_arg="--cdrom $BASEFILE_DIR/autodiscover.iso"
     e fai-redep
index 356b642db16322e285fbac5841483ba89b00f25b..ed1d3522a32f2822fd629a8ca650da895215ed65 100755 (executable)
 # RAID0: Use raid 0 even if there are >= 4 disks with boot partititions.
 #
 #
-# Code in 51-multi-boot, with reasonable combinations of above
-# uncommented for easier editing, and runs as a noop until
-# we replace _ with host names.
-if [[ ! -e /a/bin/fai/fai-wrapper ]]; then
+
+###### begin Template for 51-multi-boot ######
+#
+# It has reasonable combinations of above classes.
+# It's a noop until we replace _ with host names.
+
+#!/bin/bash
+if [[ ! -e /a/bin/fai/fai-wrapper || $FAI_ACTION == dirinstall ]]; then
     case $HOSTNAME in
         # stretch based minimal recovery / bootstraping os:
-        _) echo DEBIAN STRETCH64 VOL_STRETCH_BOOTSTRAP STRETCH_NONFREE ;;
+        _) echo DEBIAN STRETCH64 VOL_STRETCH_BOOTSTRAP STRETCH_FREE ;;
         # flidas
         _) echo UBUNTU FLIDAS64 VOL_FLIDAS FLIDAS ;;
         # stretch
@@ -85,6 +89,7 @@ if [[ ! -e /a/bin/fai/fai-wrapper ]]; then
         _) echo UBUNTU XENIAL64 VOL_XENIAL XENIAL_FREE ;;
     esac
 fi
+###### end Template for 51-multi-boot ######
 
 if [[ -e /a/bin/fai/fai-wrapper ]]; then
     source /a/bin/distro-functions/src/identify-distros
diff --git a/fai/config/files/etc/apt/preferences.d/flidas-xenial/FLIDAS b/fai/config/files/etc/apt/preferences.d/flidas-xenial/FLIDAS
deleted file mode 100644 (file)
index dba92d1..0000000
+++ /dev/null
@@ -1,3 +0,0 @@
-Package: *
-Pin: release a=xenial
-Pin-Priority: -100
index 9de9a51a8adf8a8f8f77cae3c78df2ca98f1333b..faec0dade2095e0e01bf9eb7419e45690f8daba0 100644 (file)
@@ -10,6 +10,3 @@ deb-src http://mirror.fsf.org/trisquel/ flidas-security main
 # Uncomment this lines to enable the backports optional repository
 deb http://mirror.fsf.org/trisquel/ flidas-backports main
 deb-src http://mirror.fsf.org/trisquel/ flidas-backports main
-
-# needed for debootstrap scripts
-deb http://us.archive.ubuntu.com/ubuntu/ xenial main
\ No newline at end of file
index 2348db02a4c08d26cc2c84c3e95edd44bb0cff72..cf0da93e24d49b00eadba6e267ee7b1cce4c6d18 100755 (executable)
@@ -30,7 +30,9 @@ 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.
 
-It expects $BASEFILE_DIR/STRETCH64.tar.gz to exist.
+It expects $BASEFILE_DIR/STRETCH64.tar.gz to exist, and it
+must have been generated around the same time as the nfsroot,
+at least so it has the same kernel version.
 
 EOF
   exit $1
index 7991542d75e1ca717da1cde0edaf0004a51ebdd4..2d6b527523239fc55f9cb7e2ac1f2e7c95b228c7 100755 (executable)
@@ -40,5 +40,6 @@ host=$(./chost faiserver)
 if [[ $host == $(./chost $HOSTNAME) ]]; then
   ./myfai-chboot-local "$@"
 else
-  ssh root@$host bash -s "$@" <myfai-chboot-local
+  ssh root@$host bash -s --
+  "$@" <myfai-chboot-local
 fi
index a59e71c5d48676fd61a6cfc78954f01c8de623fe..944620ecc6647a2b20295b3d28c6576c1deafc9a 100755 (executable)
@@ -21,14 +21,14 @@ x="$(readlink -f "$BASH_SOURCE")"; source "${x%/*}/bash-trace"
 
 
 usage() {
-    cat <<EOF
+  cat <<EOF
 Usage: ${0##*/} [OPTIONS] [HOST TYPE]
 Configure dnsmasq boot options and fai-chboot if appropriate.
 
 Without HOST TYPE, disable  server and fai server.
 
 HOST       A hostname known to the dhcp server, or default for all.
-TYPE       One of arch, plain, fai.
+TYPE       One of arch, parabola, plain, fai.
 
 -d         Don't alter dhcp config. Only make sense for fai type, and on network
            other than home network.
@@ -46,17 +46,17 @@ TYPE       One of arch, plain, fai.
 -h|--help  Print help and exit
 
 
-Note, when switching between plain and arch, you will need to
+Note, when switching between plain and arch or parabola, you will need to
 do something like:
 ssh wrt
 cd /mnt/usb
 rm tftpboot
-ln -s <arch/debian iso dir> tftpboot
+ln -s <arch/parabola/debian iso dir> tftpboot
 
 
 Note: Uses GNU getopt options parsing style
 EOF
-    exit $1
+  exit $1
 }
 
 ##### begin command line parsing ########
@@ -69,126 +69,138 @@ chboot_args=()
 temp=$(getopt -l help adrSkwh "$@") || usage 1
 eval set -- "$temp"
 while true; do
-    case $1 in
-        -a) wait=true; set=false; shift ;;
-        -d) dhcp=false; shift ;;
-        -r) redep=false; shift ;;
-        -S) chboot_args+=(-S); shift ;;
-        -k) chboot_args+=(-k); shift ;;
-        -w) wait=true; set=true; shift ;;
-        -h|--help) usage ;;
-        --) shift; break ;;
-        *) echo "$0: Internal error!" ; exit 1 ;;
-    esac
+  case $1 in
+    -a) wait=true; set=false; shift ;;
+    -d) dhcp=false; shift ;;
+    -r) redep=false; shift ;;
+    -S) chboot_args+=(-S); shift ;;
+    -k) chboot_args+=(-k); shift ;;
+    -w) wait=true; set=true; shift ;;
+    -h|--help) usage ;;
+    --) shift; break ;;
+    *) echo "$0: Internal error!" ; exit 1 ;;
+  esac
 done
 
 read -r host type <<<"$@"
 
 case $# in
-    0|2);;
-    *)
-        echo "$0: error: expected 0 or 2 arguments"
+  0);;
+  2)
+    case $type in
+      arch|parabola) cmd=archlike ;;
+      fai) cmd=fai ;;
+      *)
+        echo "$0: error expected type of arch|parabola|fai"
         echo
         usage 1
         ;;
+    esac
+    ;;
+  *)
+    echo "$0: error: expected 0 or 2 arguments"
+    echo
+    usage 1
+    ;;
 esac
 
+
 if $wait && ! $dhcp; then
-    echo "$0: error -w conflicts with -d, choose one or other"
-    exit 1
+  echo "$0: error -w conflicts with -d, choose one or other"
+  exit 1
 fi
 
 
 if [[ $host && $host != default ]]; then
-    host_tag="tag:$host,"
+  host_tag="tag:$host,"
 fi
 
 ##### end command line parsing ########
 
 e() {
-    echo "$@"
-    "$@"
+  echo "$@"
+  "$@"
 }
 
-arch() {
-    cat <<EOF
-dhcp-option-force=209,boot/syslinux/archiso.cfg
-dhcp-option-force=210,/arch/
-dhcp-boot=${host_tag}/arch/boot/syslinux/lpxelinux.0
+archlike() {
+  cat <<EOF
+dhcp-option-force=209,boot/syslinux/${type}iso.cfg
+dhcp-option-force=210,/${type}/
+dhcp-boot=${host_tag}/${type}/boot/syslinux/lpxelinux.0
 EOF
 }
 
 plain() {
-    # if arch was used before, this additionally needs
-    # the tftp link in /mnt/usb to be changed.
-    cat <<EOF
+  # if arch based was used before, this additionally needs
+  # the tftp link in /mnt/usb to be changed.
+  cat <<EOF
 dhcp-boot=${host_tag}pxelinux.0
 EOF
 }
 
 fai() {
-    cat <<EOF
+  cat <<EOF
 dhcp-boot=${host_tag}pxelinux.0,faiserver.b8.nz,faiserver.b8.nz
 EOF
 }
 
 ack-wait() {
-    wait_count=$1
-    if [[ $host ]]; then
-        host_regex=" $host"
+  wait_count=$1
+  if [[ $host ]]; then
+    host_regex=" $host"
+  fi
+  regex=".*DHCPACK.*$host_regex$"
+  i=0
+  while (( i != wait_count )) && read -r line; do
+    if [[ $line =~ $regex ]]; then
+      i=$((i+1))
+      echo $line
     fi
-    regex=".*DHCPACK.*$host_regex$"
-    i=0
-    while (( i != wait_count )) && read -r line; do
-        if [[ $line =~ $regex ]]; then
-            i=$((i+1))
-            echo $line
-        fi
-    done < <(ssh wrt logread -f)
-    e sleep 20
+  done < <(ssh wrt logread -f)
+  e sleep 20
 }
 
 set-pxe() {
-    $dhcp || return 0
-    echo "$0: updating dnsmasq.conf:"
-    $type
-    ${type:-:}|ssh wrt "cedit pxe /etc/dnsmasq.conf || /etc/init.d/dnsmasq restart
-$([[ $type == arch ]] && echo arch-pxe-mount)"
+  $dhcp || return 0
+  echo "$0: updating dnsmasq.conf:"
+  $cmd
+  ${cmd:-:}|ssh wrt "cedit pxe /etc/dnsmasq.conf || /etc/init.d/dnsmasq restart
+$([[ $type == arch || $type == parabola ]] && echo archlike-pxe-mount)"
 }
 
 
 if $set; then
-    set-pxe
-    if [[ $type == fai ]]; then
-        e myfai-chboot ${chboot_args[@]} $host
-        if $redep; then
-            e fai-redep
-        fi
-    else
-        # This will fail if faiserver is not setup, so ignore any
-        # failure and don't bother us about it.
-        myfai-chboot &>/dev/null ||:
+  set-pxe
+  if [[ $type == fai ]]; then
+    e myfai-chboot ${chboot_args[@]} $host
+    if $redep; then
+      e fai-redep
     fi
+  else
+    # This will fail if faiserver is not setup, so ignore any
+    # failure and don't bother us about it.
+    myfai-chboot &>/dev/null ||:
+  fi
 fi
 
 if $wait; then
-    # fai's debian jessie 8.5ish does 2 dhcp requests when booting,
-    # roughly 4 seconds apart. Earlier
-    # versions did just 1. Now testing on a vm, it does 1.
-    # bleh.
-    echo "waiting for $acks dhcp acks then disabling pxe"
-    ack-wait $acks
-    type=
-    set-pxe
-
-    # previously tried waiting for one more ack then disabling faiserver,
-    # since it can contain sensitive info, so turn it off when not in use,
-    # but disabling that for now as it's inconvenient to clean this
-    # up and run it in the background etc.
-
-    # if [[ $type == fai ]]; then
-    #     echo "waiting for 1 dhcp ack then disabling fai server"
-    #     ack-wait 1
-    #     faiserver-disable
-    # fi
+  # fai's debian jessie 8.5ish does 2 dhcp requests when booting,
+  # roughly 4 seconds apart. Earlier
+  # versions did just 1. Now testing on a vm, it does 1.
+  # bleh.
+  echo "waiting for $acks dhcp acks then disabling pxe"
+  ack-wait $acks
+  type=
+  set-pxe
+
+  # previously tried waiting for one more ack then disabling faiserver,
+  # since it can contain sensitive info, so turn it off when not in use,
+  # but disabling that for now as it's inconvenient to clean this
+  # up and run it in the background etc.
+
+  # if [[ $type == fai ]]; then
+  #     echo "waiting for 1 dhcp ack then disabling fai server"
+  #     ack-wait 1
+  #     faiserver-disable
+  # fi
 fi
index 2dbc0cebca523518da314d488ebc3d90965c479d..43628bc8bee6f049a19807c2fc0c549ad45ab01c 100755 (executable)
@@ -51,20 +51,22 @@ l=${lan%.0}
 
 passwd -l root ||: #already locked fails
 
-cat >/usr/bin/arch-pxe-mount <<'EOFOUTER'
+cat >/usr/bin/archlike-pxe-mount <<'EOFOUTER'
 #!/bin/bash
 # symlinks are collapsed for nfs mount points, so use a bind mount.
 # tried putting this in /etc/config/fstab,
-# then doig block mount, it didn't work. This doesn't persist across reboots,
+# then doing block mount, it didn't work. This doesn't persist across reboots,
 # todo: figure that out
-d=/run/archiso/bootmnt
-cat > /etc/fstab <<EOF
+rm -f /etc/fstab
+for d in /run/{arch,parabola}iso/bootmnt; do
+cat >>/etc/fstab <<EOF
 /mnt/usb/tftpboot $d none bind 0 0
 EOF
 mount | grep $d &>/dev/null || mount $d
+done
 /etc/init.d/nfsd restart
 EOFOUTER
-chmod +x /usr/bin/arch-pxe-mount
+chmod +x /usr/bin/archlike-pxe-mount
 
 cat >.profile <<'EOF'
 # changing login shell emits spam on ssh single commands & scp
@@ -86,9 +88,10 @@ v /etc/init.d/fstab enable ||:
 # 255 == module already loaded
 for mod in scsi_mod sd_mod; do v modprobe $mod || [[ $? == 255 ]]; done
 
-# for arch pxe. The default settings in the installer expect to find
-# the NFS at /run/archiso/bootmnt
+# for archlike pxe. The default settings in the installer expect to find
+# the NFS at one of these dirs
 mkdir -p /run/archiso/bootmnt
+mkdir -p /run/parabolaiso/bootmnt
 
 # todo: at some later time, i found /mnt/usb not mounted, watch to see if
 # that is the case after running this or rebooting.
@@ -127,6 +130,7 @@ cedit /etc/exports <<EOF || v /etc/init.d/nfsd restart ||:
 /mnt/usb  $lan/$netmask(rw,no_root_squash,insecure,sync,no_subtree_check)
 # for arch pxe
 /run/archiso/bootmnt   $lan/$netmask(rw,no_root_squash,insecure,sync,no_subtree_check)
+/run/parabolaiso/bootmnt       $lan/$netmask(rw,no_root_squash,insecure,sync,no_subtree_check)
 EOF
 
 
@@ -152,7 +156,7 @@ v /etc/init.d/nfsd enable
 # fi
 
 
-wireless_restart=true
+wireless_restart=false
 key=pictionary49
 for x in 0 1; do
   if [[ $(uci get wireless.default_radio$x.ssid) != "$ssid" ]]; then
@@ -163,8 +167,8 @@ for x in 0 1; do
     v uci set wireless.default_radio$x.key=$key
     wireless_restart=true
   fi
-  if [[ $(uci get wireless.default_radio$x.encryption) != $key ]]; then
-    v uci set wireless.default_radio$x.encryption=$key
+  if [[ $(uci get wireless.default_radio$x.encryption) != psk2 ]]; then
+    v uci set wireless.default_radio$x.encryption=psk2
     wireless_restart=true
   fi
   if [[ $(uci get wireless.default_radio$x.disabled 2>/dev/null) ]]; then
@@ -211,6 +215,7 @@ config 'route' 'transmission'
         option 'gateway' '$l.3'
 EOF
 
+firewall_restart=false
 v cedit /etc/config/firewall <<EOF || firewall_restart=true
 config redirect
     option name ssh
@@ -332,7 +337,7 @@ if [[ $(uci get dhcp.@dnsmasq[0].domain) != b8.nz ]]; then
   uci commit dhcp
   dnsmasq_restart=true
 fi
-if [[ $(uci get dhcp.@dnsmasq[0].local) != b8.nz ]]; then
+if [[ $(uci get dhcp.@dnsmasq[0].local) != /b8.nz/ ]]; then
   v uci set dhcp.@dnsmasq[0].local=/b8.nz/
   uci commit dhcp
   dnsmasq_restart=true