#!ipxe # I've assume IPv4 for this script, so if we need IPv6, it may need # modifications. # Require only verified images to boot imgtrust --permanent # For the "jammy" part of the URL string, in case that changes in the future. set ubuntu-variant jammy goto get_arch ################# ### This section is at the top, so it's easier to modify. :static_ip_boot_setup # Open all network interface devices, so we aren't restricted to just the first ifopen sleep 1 # Currently we just configure IP info by MAC address. So we iterate over # MAC addresses and set the variables. To ensure we use the desired # device, we iterate over all devices and simply find matches by # MAC address. set idx:int32 0 set successful f :loop isset ${net${idx}/mac} || goto loop_done ######################## SET STATIC IP INFO HERE ############################# # Just copy/paste an entire line to add more # echo Checking net${idx} for a static IP config # node1.bitmessage.at iseq ${net${idx}/mac} 40:a8:f0:31:cc:58 && set ip-dev-name eno1 && set ip-addr 93.189.28.82 && set ip-gateway 93.189.28.81 && set ip-netmask 255.255.255.248 && set ip-dns 1.1.1.1 && set successful t && goto loop_done || iseq ${net${idx}/mac} 40:a8:f0:31:cc:59 && set ip-dev-name eno2 && set ip-addr 93.189.28.82 && set ip-gateway 93.189.28.81 && set ip-netmask 255.255.255.248 && set ip-dns 1.1.1.1 && set successful t && goto loop_done || # node2.bitmessage.at iseq ${net${idx}/mac} 28:80:23:a7:52:d0 && set ip-dev-name eno1 && set ip-addr 93.189.25.250 && set ip-gateway 93.189.25.249 && set ip-netmask 255.255.255.248 && set ip-dns 1.1.1.1 && set successful t && goto loop_done || iseq ${net${idx}/mac} 28:80:23:a7:52:d1 && set ip-dev-name eno2 && set ip-addr 93.189.25.250 && set ip-gateway 93.189.25.249 && set ip-netmask 255.255.255.248 && set ip-dns 1.1.1.1 && set successful t && goto loop_done || # node1.surda.cloud iseq ${net${idx}/mac} d0:50:99:df:1d:49 && set ip-dev-name enp39s0 && set ip-addr 93.189.28.85 && set ip-gateway 93.189.28.81 && set ip-netmask 255.255.255.248 && set ip-dns 1.1.1.1 && set successful t && goto loop_done || iseq ${net${idx}/mac} d0:50:99:df:1d:4a && set ip-dev-name enp38s0 && set ip-addr 93.189.28.85 && set ip-gateway 93.189.28.81 && set ip-netmask 255.255.255.248 && set ip-dns 1.1.1.1 && set successful t && goto loop_done || # node2.surda.cloud iseq ${net${idx}/mac} c8:1f:66:b9:0b:d6 && set ip-dev-name eno1 && set ip-addr 110.4.42.77 && set ip-gateway 110.4.42.1 && set ip-netmask 255.255.255.0 && set ip-dns 1.1.1.1 && set successful t && goto loop_done || iseq ${net${idx}/mac} c8:1f:66:b9:0b:d7 && set ip-dev-name eno2 && set ip-addr 110.4.42.77 && set ip-gateway 110.4.42.1 && set ip-netmask 255.255.255.0 && set ip-dns 1.1.1.1 && set successful t && goto loop_done || iseq ${net${idx}/mac} c8:1f:66:b9:0b:d8 && set ip-dev-name eno3 && set ip-addr 110.4.42.77 && set ip-gateway 110.4.42.1 && set ip-netmask 255.255.255.0 && set ip-dns 1.1.1.1 && set successful t && goto loop_done || iseq ${net${idx}/mac} c8:1f:66:b9:0b:d9 && set ip-dev-name eno4 && set ip-addr 110.4.42.77 && set ip-gateway 110.4.42.1 && set ip-netmask 255.255.255.0 && set ip-dns 1.1.1.1 && set successful t && goto loop_done || # node3.surda.cloud iseq ${net${idx}/mac} b8:2a:72:d5:05:36 && set ip-dev-name eno1 && set ip-addr 101.99.86.54 && set ip-gateway 101.99.86.49 && set ip-netmask 255.255.255.240 && set ip-dns 1.1.1.1 && set successful t && goto loop_done || iseq ${net${idx}/mac} b8:2a:72:d5:05:37 && set ip-dev-name eno2 && set ip-addr 101.99.86.54 && set ip-gateway 101.99.86.49 && set ip-netmask 255.255.255.240 && set ip-dns 1.1.1.1 && set successful t && goto loop_done || iseq ${net${idx}/mac} b8:2a:72:d5:05:38 && set ip-dev-name eno3 && set ip-addr 101.99.86.54 && set ip-gateway 101.99.86.49 && set ip-netmask 255.255.255.240 && set ip-dns 1.1.1.1 && set successful t && goto loop_done || iseq ${net${idx}/mac} b8:2a:72:d5:05:39 && set ip-dev-name eno4 && set ip-addr 101.99.86.54 && set ip-gateway 101.99.86.49 && set ip-netmask 255.255.255.240 && set ip-dns 1.1.1.1 && set successful t && goto loop_done || # node3.sysdeploy.org iseq ${net${idx}/mac} 00:25:90:a2:9f:e9 && set ip-dev-name eno2 && set ip-addr 104.251.122.45 && set ip-gateway 104.251.122.44 && set ip-netmask 255.255.255.254 && set ip-dns 1.1.1.1 && set successful t && goto loop_done || # node4.sysdeploy.org iseq ${net${idx}/mac} 0c:c4:7a:04:ca:60 && set ip-dev-name eno1 && set ip-addr 50.2.185.50 && set ip-gateway 50.2.185.49 && set ip-netmask 255.255.255.248 && set ip-dns 1.1.1.1 && set successful t && goto loop_done || # node5.sysdeploy.org iseq ${net${idx}/mac} d8:9d:67:72:09:50 && set ip-dev-name eno1 && set ip-addr 82.118.227.210 && set ip-gateway 82.118.227.209 && set ip-netmask 255.255.255.252 && set ip-dns 1.1.1.1 && set successful t && goto loop_done || # node7.sysdeploy.org iseq ${net${idx}/mac} 34:17:eb:ea:78:b0 && set ip-dev-name eno1 && set ip-addr 162.248.7.209 && set ip-gateway 162.248.7.1 && set ip-netmask 255.255.255.0 && set ip-dns 1.1.1.1 && set successful t && goto loop_done || iseq ${net${idx}/mac} 34:17:eb:ea:78:b1 && set ip-dev-name eno2 && set ip-addr 162.248.7.209 && set ip-gateway 162.248.7.1 && set ip-netmask 255.255.255.0 && set ip-dns 1.1.1.1 && set successful t && goto loop_done || # node8.sysdeploy.org iseq ${net${idx}/mac} bc:30:5b:de:3a:9e && set ip-dev-name eno1 && set ip-addr 109.73.65.100 && set ip-gateway 109.73.65.1 && set ip-netmask 255.255.255.0 && set ip-dns 1.1.1.1 && set successful t && goto loop_done || iseq ${net${idx}/mac} bc:30:5b:de:3a:9f && set ip-dev-name eno2 && set ip-addr 109.73.65.100 && set ip-gateway 109.73.65.1 && set ip-netmask 255.255.255.0 && set ip-dns 1.1.1.1 && set successful t && goto loop_done || # if you don't know the linux interface name, use "clear ip-dev-name", then # it will use ALL interfaces ############################################################################## inc idx && goto loop :loop_done # If we have not successfully found a MAC match, then we error, because we # also failed DHCP. So there's nothing we can do but fail. iseq ${successful} f && goto error_handler || # If on the other hand we're successful, then we construct the kernel ip= line set ip-info ${ip-addr}::${ip-gateway}:${ip-netmask}::${ip-dev-name}:off:${ip-dns} && echo Static IP found echo ip-info ${ip-info} # And setup IPXE networking. # First, set device info set net${idx}/ip ${ip-addr} set net${idx}/gateway ${ip-gateway} set net${idx}/netmask ${ip-netmask} set net${idx}/dns ${ip-dns} # Now we close all net devices and enable only the one we need. # Sleep a little between, so we don't error by continuing too fast before the # device is actually ready sleep 1 ifclose sleep 1 ifopen net${idx} sleep 1 # Set settings again in case the ifdown/ifup cleared them set net${idx}/ip ${ip-addr} set net${idx}/gateway ${ip-gateway} set net${idx}/netmask ${ip-netmask} set net${idx}/dns ${ip-dns} sleep 1 # Now we have the ip= line and the IPXE network configured, so we can # download and boot. goto boot_all ### ################# :try_next_card imgfree ifclose sleep 1 # If dhcp, it will go to the static boot, which already has ifopen iseq ip-info dhcp || ifopen iseq ip-info dhcp || sleep 1 iseq ip-info dhcp && clear ip-info && goto try_static_from_dhcp_fail || goto try_next_static_card :try_static_from_dhcp_fail iseq arch-info arm64 && goto static_ip_boot_arm64 || iseq arch-info amd64 && goto static_ip_boot_amd64 || goto error_handler :try_next_static_card isset ip-dev-name && clear ip-dev-name isset ip-addr && clear ip-addr isset ip-gateway && clear ip-gateway isset ip-netmask && clear ip-netmask isset ip-dns && clear ip-dns isset successful && clear successful set successful f isset idx && inc idx || goto error_handler goto loop # In case we want to... log?? Or do something else. :error_handler echo ########################################################### echo An unspecified error has occurred. echo The system will sleep for two minutes and then reboot. echo ########################################################### sleep 60 sleep 60 reboot # Should not occur, but just in case... sleep 5 exit # Get relevant CPU arch. :get_arch iseq ${buildarch} arm32 && goto start_arm32 || iseq ${buildarch} arm64 && goto start_arm64 || iseq ${buildarch} i386 && goto start_i386 || iseq ${buildarch} x86_64 && goto start_amd64 || goto error_handler # Builds may be done on 32-bit, but machines will always be 64-bit. # Keep this section just in case we want to use 32-bit machines in the future. :start_arm32 goto start_arm64 :start_i386 goto start_amd64 # Set arch info and determine if we can use DHCP for network. # Then either boot or goto static IP setup. :start_arm64 set arch-info arm64 dhcp || goto static_ip_boot_arm64 sleep 1 set ip-info dhcp goto boot_all :start_amd64 set arch-info amd64 dhcp || goto static_ip_boot_amd64 sleep 1 set ip-info dhcp goto boot_all # This process should be the same for arm and x86, but I'll leave this section # intact in case it turns out it's not the same :static_ip_boot_arm64 goto static_ip_boot_setup :static_ip_boot_amd64 goto static_ip_boot_setup :boot_all # Get accurate time so we can set the clock in kernel boot cmdline echo Syncing time over NTP ntp pool.ntp.org || goto error_handler # check for EFI iseq ${platform} efi && goto is_efi || goto not_efi # We use HTTP because IPXE's HTTPS implementation is lacking. So we delegate # integrity and validation to imgverify. # Naming the squashfs download "/squashfs" is required, otherwise the boot # kernel fails to load it in the "root=" part of the kernel cmdline. # However, note that imgverify will fail if you refer to it as "/squashfs" # instead of "squashfs". # "--signer" validates against the subject common name field of the signing # certificate. That signing cert must have both the digital signature key # usage set and the code-signing key usage extension set. # By default, IPXE trusts the default Mozilla global root CA list, so # make sure you pick a common name with a FQDN you control, even if you're # using a custom CA that you import during build. :is_efi echo Attempting EFI boot set initrd1 initrd=initrd.cpio isset initrd2 && clear initrd2 imgfetch http://images.sysdeploy.org/${ubuntu-variant}/${arch-info}/initrd.cpio || goto try_next_card imgverify --signer images.sysdeploy.org initrd.cpio http://images.sysdeploy.org/${ubuntu-variant}/${arch-info}/initrd.cpio.sig || goto error_handler goto efi_and_not_efi :not_efi echo Attempting legacy boot set initrd1 initrd=boot-initrd set initrd2 initrd=squashfs imgfetch http://images.sysdeploy.org/${ubuntu-variant}/${arch-info}/squashfs /squashfs || goto try_next_card imgverify --signer images.sysdeploy.org squashfs http://images.sysdeploy.org/${ubuntu-variant}/${arch-info}/squashfs.sig || goto error_handler initrd http://images.sysdeploy.org/${ubuntu-variant}/${arch-info}/boot-initrd || goto try_next_card imgverify --signer images.sysdeploy.org boot-initrd http://images.sysdeploy.org/${ubuntu-variant}/${arch-info}/boot-initrd.sig || goto error_handler :efi_and_not_efi kernel http://images.sysdeploy.org/${ubuntu-variant}/${arch-info}/boot-kernel || goto try_next_card imgverify --signer images.sysdeploy.org boot-kernel http://images.sysdeploy.org/${ubuntu-variant}/${arch-info}/boot-kernel.sig || goto error_handler sleep 1 boot boot-kernel ${initrd1} ${initrd2} rootfstype=squashfs root=/squashfs ip=${ip-info} overlayroot=tmpfs:recurse=0 systemd.clock-usec=${unixtime:int32}000000 ds=nocloud-net;s=https://cloud-init.sysdeploy.org/apiv2?uuid=${uuid}&filetype= || goto error_handler # unixtime variable must be used with int32, because that's the only way it # will display as decimal digits. unit32 and string both display as hex. # Therefore this will stop working in 2038.