Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add CoreDHCP (and Tftp) Container(s) to Quickstart #78

Merged
merged 19 commits into from
Nov 7, 2024
Merged
Show file tree
Hide file tree
Changes from 10 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 14 additions & 9 deletions quickstart/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -33,10 +33,23 @@ This quickstart makes a few assumptions about the target operating system and is
grep LOCAL_IP .env
```
If you have problems with this step, check to make sure that the main IP address of your host is in `.env` as `LOCAL_IP`.

**DHCP NOTE:** The `generate-configs.sh` script supports customization of CoreDHCP, including:

- Lease time
- Server IP
- Gateway IP
- Subnet mask
- DNS servers
- Alternative base URL for fetching boot scripts (e.g. without TLS)
- Cache update interval (for updating from SMD)
- IP range for "catch-all" address pool

If any of these are needed, use the `-h` option of the script to set them.
1. Update your /etc/hosts to point your system name to your local ip (this is important for valid certs)
1. Start the main services
```bash
docker compose -f base.yml -f postgres.yml -f jwt-security.yml -f haproxy-api-gateway.yml -f openchami-svcs.yml -f autocert.yml up -d
docker compose -f base.yml -f postgres.yml -f jwt-security.yml -f haproxy-api-gateway.yml -f openchami-svcs.yml -f autocert.yml -f tftp.yml -f coredhcp.yml up -d
```
__If this step produces an error like: `Error response from daemon: invalid IP address in add-host: ""` it means you're missing the LOCAL_IP in step 2.__
You can fix it by destroying everything, editing `.env` manually and starting over. The command to destroy is the same as the command to create, just replace `up -d` with `down --volumes`
Expand All @@ -54,14 +67,6 @@ This quickstart makes a few assumptions about the target operating system and is
curl --cacert cacert.pem -H "Authorization: Bearer $ACCESS_TOKEN" https://foobar.openchami.cluster/hsm/v2/State/Components
# This should respond with an empty set of Components: {"Components":[]}
```
1. Create a token that can be used by the dnsmasq-loader which reads from smd. This activates our automatic dns/dhcp system. The command automatically adds it to .env
```bash
echo "DNSMASQ_ACCESS_TOKEN=$(gen_access_token)" >> .env
```
1. Use docker-compose to bring up your dnsmasq contianers. The only difference between this command and the one above is the addition of the `dnsmasq.yml` file. Docker compose needs to know about all the files to follow dependencies.
```bash
docker compose -f base.yml -f postgres.yml -f jwt-security.yml -f haproxy-api-gateway.yml -f openchami-svcs.yml -f autocert.yml -f dnsmasq.yml up -d
```


## cloud-init Server Setup
Expand Down
1 change: 1 addition & 0 deletions quickstart/configs/.gitignore
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
opaal.yaml
coredhcp.yaml
12 changes: 12 additions & 0 deletions quickstart/configs/coredhcp-template.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
server4:
plugins:
- server_id: <SERVER_IP>
- dns: <DNS_SERVERS>
- router: <GATEWAY_IP>
- netmask: <DHCP_NETMASK>
- coresmd: <BASE_URL> <SCRIPT_URL> /root_ca/root_ca.crt <CACHE_VALIDITY> <LONG_LEASE_TIME>
# Optionally include the file plugin here if it matters which IPs get assigned to which
# MACs. Otherwise, unknown MACs get passed to the bootloop "catch-all" plugin below.
#
#- file /etc/coredhcp/hostsfile
- bootloop: /tmp/coredhcp.db <SHORT_LEASE_TIME> <IP_POOL_START> <IP_POOL_END>
22 changes: 22 additions & 0 deletions quickstart/coredhcp.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
services:
coredhcp:
image: ghcr.io/openchami/coresmd:v0.0.1
container_name: coredhcp
hostname: coredhcp
network_mode: host
cap_add:
- NET_ADMIN
volumes:
- ./configs/coredhcp.yaml:/etc/coredhcp/config.yaml:ro
- step-root-ca:/root_ca/:ro
command:
- "-L"
- "debug"
healthcheck:
test: pgrep coredhcp
interval: 5s
timeout: 10s
retries: 60
depends_on:
smd:
condition: service_healthy
156 changes: 136 additions & 20 deletions quickstart/generate-configs.sh
alexlovelltroy marked this conversation as resolved.
Show resolved Hide resolved
alexlovelltroy marked this conversation as resolved.
Show resolved Hide resolved
Original file line number Diff line number Diff line change
Expand Up @@ -2,34 +2,134 @@

set -euo pipefail

if [ -f .env ]
then
echo "A config file (.env) exists. Delete to generate a new one"
exit 1
fi

if [ -f configs/opaal.yaml ]
then
echo "An OPAAL config (configs/opaal.yaml) exists. Delete to generate a new one"
fi

usage() {
echo "Usage: $0 system-name [system-domain]"
echo "Usage: [options] $0 system-name [system-domain]"
echo "Example: $0 foobar openchami.cluster"
echo "Example: $0 foobar"
echo "Example: $0 \\"
echo " -c 30s \\"
echo " -d 1.1.1.1,8.8.8.8 \\"
echo " -g 172.16.0.254 \\"
echo " -i 172.16.0.1 \\"
echo " -j 172.16.0.252 \\"
echo " -l 1h \\"
echo " -m 5m \\"
echo " -m 255.255.255.0 \\"
echo " -s 172.16.0.253 \\"
echo " -u http://172.16.0.253:8081 \\"
echo " foobar \\"
echo " openchami.cluster"
echo ""
echo "Generate configuration for OpenCHAMI quickstart."
echo ""
echo "OPTIONS:"
echo " -c Duration of DHCP cache validity. Defaults to 30s."
echo " -d Comma-separated list of DNS servers to use for DHCP. Defaults"
echo " to 8.8.8.8."
echo " -f Force overwriting config files."
echo " -g DHCP gateway IP. Defaults of value of LOCAL_IP in generated"
echo " .env file."
echo " -h Print this usage message to stdout."
echo " -k DHCP long lease time. 1 hour by default."
echo " -l DHCP short lease time. 5 minutes by default."
echo " -m DHCP netmask. Defaults to 255.255.255.0."
echo " -s DHCP server IP. Defaults to value of LOCAL_IP in generated"
echo " .env file."
echo " -u Base URL for fetching boot scripts. Defaults to"
echo ' http://${LOCAL_IP}:8081.'
echo ""
echo "ARGUMENTS:"
echo " system-name Subdomain of system to use in certificate and config"
echo " generation. E.g. <system-name>.openchami.cluster"
echo " system-domain (OPTIONAL) Domain of system to use in certificate and"
echo " config generation. Defaults to openchami.cluster"
}

get_eth0_ipv4() {
local ipv4
local first_eth=$(ip -j addr | jq -c '.[]' | grep UP |grep -v veth | grep -v LOOPBACK |grep -v br- |grep -v NO-CARRIER | grep -E '[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}' | head -n 1 | jq -rc '.ifname')
ipv4=$(ip -o -4 addr show $first_eth | awk '{print $4}')
echo "${ipv4%/*}"
}

CACHE_VALIDITY=30s
LONG_LEASE_TIME=1h
SHORT_LEASE_TIME=5m
GATEWAY_IP=$(get_eth0_ipv4)
IP_POOL_START=172.16.0.1
IP_POOL_END=172.16.0.252
DNS_SERVERS=8.8.8.8
DHCP_NETMASK=255.255.255.0
DHCP_SERVER_IP=$(get_eth0_ipv4)
while getopts "c:d:fg:hi:j:k:l:m:s:u:" opt; do
case "${opt}" in
c)
CACHE_VALIDITY="${OPTARG}"
;;
d)
DNS_SERVERS="${OPTARG}"
;;
f)
FORCE_OVERWRITE=true
;;
g)
GATEWAY_IP="${OPTARG}"
;;
h)
usage
;;
i)
IP_POOL_START="${OPTARG}"
;;
j)
IP_POOL_END="${OPTARG}"
;;
k)
LONG_LEASE_TIME="${OPTARG}"
;;
l)
SHORT_LEASE_TIME="${OPTARG}"
;;
m)
DHCP_NETMASK="${OPTARG}"
;;
s)
DHCP_SERVER_IP="${OPTARG}"
;;
u)
SCRIPT_URL="${OPTARG}"
;;
*)
usage >&2
;;
esac
done
shift $((OPTIND-1))

if [ -f .env ] && [ -z "${FORCE_OVERWRITE+x}" ]
then
echo "A config file (.env) exists. Delete to generate a new one or -f to overwrite."
file_exists=true
fi

if [ -f configs/opaal.yaml ] && [ -z "${FORCE_OVERWRITE+x}" ]
then
echo "An OPAAL config (configs/opaal.yaml) exists. Delete to generate a new one or -f to overwrite."
file_exists=true
fi

if [ -f configs/coredhcp.yaml ] && [ -z "${FORCE_OVERWRITE+x}" ]
then
echo "A CoreDHCP config (configs/coredhcp.yaml) exists. Delete to generate a new one or -f to overwrite."
file_exists=true
fi

if [ -n "${file_exists+x}" ]; then exit 1; fi

# Parse system name (required arg).
if [ -z "${1+x}" ]
then
echo 'System name required.' >&2
usage >&2
exit 1
fi
Expand All @@ -42,6 +142,12 @@ then
SYSDOMAIN="$2"
fi

# If script URL was not set with -u, set it to default value here.
if [ -z "${SCRIPT_URL+x}" ]
then
SCRIPT_URL="http://$(get_eth0_ipv4):8081"
fi

if [[ ! -x $(command -v jq) ]]
then
echo "Command \"jq\" not found"
Expand All @@ -54,13 +160,6 @@ then
exit 1
fi

get_eth0_ipv4() {
local ipv4
local first_eth=$(ip -j addr | jq -c '.[]' | grep UP |grep -v veth | grep -v LOOPBACK |grep -v br- |grep -v NO-CARRIER | grep -E '[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}' | head -n 1 | jq -rc '.ifname')
ipv4=$(ip -o -4 addr show $first_eth | awk '{print $4}')
echo "${ipv4%/*}"
}

generate_random_alphanumeric() {
local num_chars=${1:-32}
dd bs=512 if=/dev/urandom count=1 2>/dev/null | tr -dc '[:alnum:]' | fold -w "${num_chars}" | head -n 1
Expand All @@ -73,7 +172,24 @@ generate_random_alphanumeric() {
sed \
-e "s/<your-subdomain-here>/${SYSNAME}/g" \
-e "s/<your-domain-here>/${SYSDOMAIN}/g" \
configs/opaal-template.yaml > configs/opaal.yaml
configs/opaal-template.yaml > configs/opaal.yaml

DNS_SERVERS="${DNS_SERVERS//,/ }"

# Generate CoreDHCP configuration from configs/coredhcp-template.yaml.
sed \
-e "s/<CACHE_VALIDITY>/${CACHE_VALIDITY}/g" \
-e "s/<IP_POOL_START>/${IP_POOL_START}/g" \
-e "s/<IP_POOL_END>/${IP_POOL_END}/g" \
-e "s/<LONG_LEASE_TIME>/${LONG_LEASE_TIME}/g" \
-e "s/<SHORT_LEASE_TIME>/${SHORT_LEASE_TIME}/g" \
-e "s|<SCRIPT_URL>|${SCRIPT_URL}|g" \
-e "s|<BASE_URL>|https://${SYSNAME}.${SYSDOMAIN}|g" \
-e "s/<DNS_SERVERS>/${DNS_SERVERS}/g" \
-e "s/<SERVER_IP>/${DHCP_SERVER_IP}/g" \
-e "s/<GATEWAY_IP>/${GATEWAY_IP}/g" \
-e "s/<DHCP_NETMASK>/${DHCP_NETMASK}/g" \
configs/coredhcp-template.yaml > configs/coredhcp.yaml

# Set the system name
cat > .env <<EOF
Expand Down
Binary file added quickstart/ipxe/ipxe.efi
Binary file not shown.
2 changes: 2 additions & 0 deletions quickstart/ipxe/reboot.ipxe
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
#!ipxe
reboot
Binary file added quickstart/ipxe/undionly.kpxe
Binary file not shown.
26 changes: 26 additions & 0 deletions quickstart/tftp.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
services:
tftp:
image: docker.io/aguslr/atftpd:latest
container_name: tftp
hostname: tftp
network_mode: host
volumes:
- ./ipxe:/data
cap_add:
- NET_ADMIN
command:
- "--daemon"
- "--no-fork"
- "--user"
- "nobody.nogroup"
- "--logfile"
- "-"
- "--port"
- "69"
- "--verbose"
- "/data"
healthcheck:
test: pgrep tftp
interval: 5s
timeout: 10s
retries: 60