diff --git a/.github/workflows/build-test-push.yml b/.github/workflows/build-test-push.yml
index 5e80ef1..0d72168 100644
--- a/.github/workflows/build-test-push.yml
+++ b/.github/workflows/build-test-push.yml
@@ -57,7 +57,7 @@ jobs:
id: test
run: |
docker run --rm ${{ env.TEST_TAG }} -h
- docker run --rm ${{ env.TEST_TAG }} -d 192.168.1.1/24 -t
+ docker run --rm ${{ env.TEST_TAG }} -n 192.168.1.0/24 -t
- name: Build and push
id: push
diff --git a/README.md b/README.md
index 3b84617..448aad7 100644
--- a/README.md
+++ b/README.md
@@ -50,9 +50,9 @@
## 🛠️ Get Started
-To start a PXE server using the default options:
+To start a PXE server using the default options in your `192.168.1.0/24` subnet:
```bash
-docker run -it --rm --cap-add=NET_ADMIN --net=host ghcr.io/feenx-lab/flint-pxe
+docker run -it --rm --cap-add=NET_ADMIN --net=host ghcr.io/feenx-lab/flint-pxe --network 192.168.1.0/24
```
> [!IMPORTANT]
@@ -86,7 +86,7 @@ It’s meant to be a fast, ephemeral, local PXE boot solution to stand up Talos
| Flag | Description |
|----------------------------------|--------------------------------------------------------------------|
-| `--dhcp-server`, `-d` | Upstream DHCP server IP in CIDR notation (e.g: `192.168.1.1/24`) |
+| `--network`, `-n` | Subnet in CIDR notation (e.g: `192.168.1.0/24`) |
### Optional
@@ -95,12 +95,12 @@ It’s meant to be a fast, ephemeral, local PXE boot solution to stand up Talos
|----------------------------------|---------------------------------------------------------------------------------------------------------------------------------|
| `--arch`, `-a` | Architecture to use from the Image Factory (default: `amd64`) |
| `--base-url`, `-b` | Base URL to fetch the iPXE script from (default: `https://pxe.factory.talos.dev/pxe`) |
+| `--dry-run`, `-d` | Enables test mode (dry-run, no changes applied) (default: `false`) |
+| `--help`, `-h` | Prints help message |
| `--mac-address`, `-m` | MAC address for Wake-on-LAN. Can be used multiple times (default: none) |
| `--ipxe-url-override`, `-o` | Override the full URL for the iPXE script (default: none) |
| `--schematic-id`, `-s` | The Talos Image Factory schematic ID to boot from (default: `376567988ad370138ad8b2698212367b8edcb69b5fd68c80be1f2ec7d603b4ba`) |
| `--talos-version`, `-v` | Talos version number to use (default: `1.10.4`) |
-| `--test`, `-t` | Enables test mode (dry-run, no changes applied) (default: `false`) |
-| `--help`, `-h` | Prints help message |
## 🧪 Examples
@@ -110,7 +110,7 @@ It’s meant to be a fast, ephemeral, local PXE boot solution to stand up Talos
```bash
docker run -it --rm --cap-add=NET_ADMIN --net=host \
ghcr.io/feenx-lab/flint-pxe \
- --dhcp-server 192.168.1.1/24
+ --network 192.168.1.0/24
```
### 2. Run flint-pxe + Wake target machines
@@ -118,7 +118,7 @@ docker run -it --rm --cap-add=NET_ADMIN --net=host \
```bash
docker run -it --rm --cap-add=NET_ADMIN --net=host \
ghcr.io/feenx-lab/flint-pxe \
- --dhcp-server 192.168.1.1/24 \
+ --network 192.168.1.0/24 \
--mac-address aa:bb:cc:dd:ee:ff \
--mac-address a1:b2:c3:d4:e5:f6
```
@@ -128,7 +128,7 @@ docker run -it --rm --cap-add=NET_ADMIN --net=host \
```bash
docker run -it --rm --cap-add=NET_ADMIN --net=host \
ghcr.io/feenx-lab/flint-pxe \
- --dhcp-server 192.168.1.1/24 \
+ --network 192.168.1.0/24 \
--arch arm64 \
--schematic-id 09dbcadc567d93b02a1610c70d651fadbe56aeac3aaca36bc488a38f3fffe99d
```
diff --git a/src/flint-pxe.sh b/src/flint-pxe.sh
index 002315d..513bd3a 100755
--- a/src/flint-pxe.sh
+++ b/src/flint-pxe.sh
@@ -4,13 +4,14 @@
P_ARGS=()
ARCH="amd64"
BASE_URL="https://pxe.factory.talos.dev/pxe"
-DHCP_SERVER=""
+CIDR_SUBNET=""
MAC_ADDRESSES=()
IPXE_URL_OVERRIDE=""
SCHEMATIC_ID="376567988ad370138ad8b2698212367b8edcb69b5fd68c80be1f2ec7d603b4ba"
TEST_MODE=false
TALOS_VERSION="1.10.4"
PLATFORM="metal"
+WAIT_TIME=-1
help(){
echo "Usage:"
@@ -19,19 +20,20 @@ help(){
echo "Options:"
echo -e "\t\t-a,--arch \t\tArchitecture to use from the Image Factory"
echo -e "\t\t-b,--base-url \t\tBase url to get the ipxe script from"
- echo -e "\t\t-d,--dhcp-server \t\tSpecifies the upstream dhcp server IP address using CIDR notation"
+ echo -e "\t\t-d,--dry-run\t\tEnables dry-run mode"
+ echo -e "\t\t-h,--help\t\tPrints help message"
+ echo -e "\t\t-n,--network \t\tSpecifies the subnet address using CIDR notation"
echo -e "\t\t-m,--mac-address \t\tMAC address to wake on lan, can be used multiple times"
echo -e "\t\t-o,--ipxe-url-override \t\tOverride the full url for the iPXE script."
echo -e "\t\t-s,--schematic-id \t\tSchematic ID from Talos Image factory"
- echo -e "\t\t-t,--test\t\tEnables test mode, basically dry-runs the script"
echo -e "\t\t-v,--talos-version \t\tTalos version number to use"
- echo -e "\t\t-h,--help\t\tPrints help message"
+ echo -e "\t\t-w,--wait \t\tRun as daemon and wait for number-of-seconds before terminating dnsmasq"
echo
echo "Examples:"
echo -e "\t docker run -it --rm ghcr.io/feenx-lab/fint-pxe"
echo -e "\t docker run -it --rm ghcr.io/feenx-lab/fint-pxe --schematic-id 376567988ad370138ad8b2698212367b8edcb69b5fd68c80be1f2ec7d603b4ba"
- echo -e "\t docker run -it --rm ghcr.io/feenx-lab/fint-pxe --dhcp-server 192.168.1.1/24 --schematic-id 376567988ad370138ad8b2698212367b8edcb69b5fd68c80be1f2ec7d603b4ba --talos-version 1.10.4"
- echo -e "\t docker run -it --rm ghcr.io/feenx-lab/fint-pxe -d 192.168.1.1/24 --s 376567988ad370138ad8b2698212367b8edcb69b5fd68c80be1f2ec7d603b4ba -v 1.10.4"
+ echo -e "\t docker run -it --rm ghcr.io/feenx-lab/fint-pxe --network 192.168.1.0/24 --schematic-id 376567988ad370138ad8b2698212367b8edcb69b5fd68c80be1f2ec7d603b4ba --talos-version 1.10.4"
+ echo -e "\t docker run -it --rm ghcr.io/feenx-lab/fint-pxe -n 192.168.1.1/24 --s 376567988ad370138ad8b2698212367b8edcb69b5fd68c80be1f2ec7d603b4ba -v 1.10.4"
}
# Print help if no args are given
@@ -53,9 +55,9 @@ while [[ $# -gt 0 ]]; do
shift # skip argument
shift # skip value
;;
- -d|--dhcp-server)
+ -n|--network)
if ipcalc -cs $2; then
- DHCP_SERVER=$2
+ CIDR_SUBNET=$2
else
echo "Invalid IP."
exit 1
@@ -102,6 +104,16 @@ while [[ $# -gt 0 ]]; do
shift # skip argument
shift # skip value
;;
+ -w|--wait)
+ if [[ $2 =~ ^[0-9]+$ ]]; then
+ WAIT_TIME=$2
+ else
+ echo "Invalid wait time, only specify number of seconds"
+ exit 1
+ fi
+ shift # skip argument
+ shift # skip value
+ ;;
-*|--*)
echo "Unknown option $1"
exit 1
@@ -116,14 +128,14 @@ done
# Reset positional args
set -- "${P_ARGS[@]}"
-if [[ -z "$DHCP_SERVER" ]]; then
+if [[ -z "$CIDR_SUBNET" ]]; then
echo "Error: No DHCP server specified"
exit 1
fi
# Split up the dhcp server IP and netmask
-DHCP_SERVER_IP=$(ipcalc $DHCP_SERVER | grep Address: | awk '{print $2}')
-NETMASK=$(ipcalc $DHCP_SERVER | grep Netmask | sed 's/ =.*//' | awk '{print $2}')
+SUBNET=$(ipcalc $CIDR_SUBNET | grep Address: | awk '{print $2}')
+NETMASK=$(ipcalc $CIDR_SUBNET | grep Netmask | sed 's/ =.*//' | awk '{print $2}')
# Send magic packtes to given mac addresses
for m in "${MAC_ADDRESSES[@]}"; do
@@ -136,30 +148,36 @@ if [[ -n "$IPXE_URL_OVERRIDE" ]]; then
IPXE_SCRIPT_URL="${IPXE_URL_OVERRIDE}"
fi
-if [[ "${TEST_MODE}" = true ]]; then
- cat << EOF
-/usr/sbin/dnsmasq -d -q \\
- --port=0 \\
- --dhcp-range=${DHCP_SERVER_IP},proxy,${NETMASK} \\
- --enable-tftp --tftp-root=/var/lib/tftpboot \\
- --dhcp-userclass=set:ipxe,iPXE \\
- --pxe-service=tag:#ipxe,x86PC,"PXE chainload to iPXE",undionly.kpxe \\
- --pxe-service=tag:ipxe,x86PC,"iPXE",$IPXE_SCRIPT_URL \\
- --pxe-service=tag:#ipxe,X86-64_EFI,"PXE chainload to iPXE UEFI",ipxe.efi \\
- --pxe-service=tag:ipxe,X86-64_EFI,"iPXE UEFI",$IPXE_SCRIPT_URL \\
- --log-queries \\
+command=$(cat << EOF
+/usr/sbin/dnsmasq -d -q
+ --port=0
+ --dhcp-range=${SUBNET},proxy,${NETMASK}
+ --enable-tftp --tftp-root=/var/lib/tftpboot
+ --dhcp-userclass=set:ipxe,iPXE
+ --pxe-service=tag:#ipxe,x86PC,"PXE chainload to iPXE",undionly.kpxe
+ --pxe-service=tag:ipxe,x86PC,"iPXE",$IPXE_SCRIPT_URL
+ --pxe-service=tag:#ipxe,X86-64_EFI,"PXE chainload to iPXE UEFI",ipxe.efi
+ --pxe-service=tag:ipxe,X86-64_EFI,"iPXE UEFI",$IPXE_SCRIPT_URL
+ --log-queries
--log-dhcp
EOF
+)
+
+if [[ "${TEST_MODE}" = true ]]; then
+ echo "$command"
+elif [[ $WAIT_TIME -ge 0 ]]; then
+ # Create a job for the command to run
+ eval $command &
+ command_pid=$!
+
+ # Create a sleep job
+ sleep $WAIT_TIME &
+ sleep_pid=$!
+
+ # Wait on both jobs, first one to finish will return its exit code.
+ wait -n $command_pid $sleep_pid
+ exit $?
else
- /usr/sbin/dnsmasq -d -q \
- --port=0 \
- --dhcp-range=${DHCP_SERVER_IP},proxy,${NETMASK} \
- --enable-tftp --tftp-root=/var/lib/tftpboot \
- --dhcp-userclass=set:ipxe,iPXE \
- --pxe-service=tag:#ipxe,x86PC,"PXE chainload to iPXE",undionly.kpxe \
- --pxe-service=tag:ipxe,x86PC,"iPXE",$IPXE_SCRIPT_URL \
- --pxe-service=tag:#ipxe,X86-64_EFI,"PXE chainload to iPXE UEFI",ipxe.efi \
- --pxe-service=tag:ipxe,X86-64_EFI,"iPXE UEFI",$IPXE_SCRIPT_URL \
- --log-queries \
- --log-dhcp
+ eval $command &
+ wait -n
fi
\ No newline at end of file