Skip to content
Merged
Show file tree
Hide file tree
Changes from all 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
1 change: 0 additions & 1 deletion bash/hook-lk-containers.sh
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ function build_all_hook_linuxkit_containers() {
# when adding new container builds here you'll also want to add them to the
# `linuxkit_build` function in the linuxkit.sh file.
# # NOTE: linuxkit containers must be in the images/ directory
build_hook_linuxkit_container hook-ip HOOK_CONTAINER_IP_IMAGE
build_hook_linuxkit_container hook-bootkit HOOK_CONTAINER_BOOTKIT_IMAGE
build_hook_linuxkit_container hook-docker HOOK_CONTAINER_DOCKER_IMAGE
build_hook_linuxkit_container hook-mdev HOOK_CONTAINER_MDEV_IMAGE
Expand Down
5 changes: 2 additions & 3 deletions bash/linuxkit.sh
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ function linuxkit_build() {
fi

# Build the containers in this repo used in the LinuxKit YAML;
build_all_hook_linuxkit_containers # sets HOOK_CONTAINER_IP_IMAGE, HOOK_CONTAINER_BOOTKIT_IMAGE, HOOK_CONTAINER_DOCKER_IMAGE, HOOK_CONTAINER_MDEV_IMAGE, HOOK_CONTAINER_CONTAINERD_IMAGE
build_all_hook_linuxkit_containers # sets HOOK_CONTAINER_BOOTKIT_IMAGE, HOOK_CONTAINER_DOCKER_IMAGE, HOOK_CONTAINER_MDEV_IMAGE, HOOK_CONTAINER_CONTAINERD_IMAGE

# Template the linuxkit configuration file.
# - You'd think linuxkit would take --build-args or something by now, but no.
Expand All @@ -64,14 +64,13 @@ function linuxkit_build() {
# shellcheck disable=SC2016 # I'm using single quotes to avoid shell expansion, envsubst wants the dollar signs.
cat "linuxkit-templates/${kernel_info['TEMPLATE']}.template.yaml" |
HOOK_KERNEL_IMAGE="${kernel_oci_image}" HOOK_KERNEL_ID="${inventory_id}" HOOK_KERNEL_VERSION="${kernel_oci_version}" \
HOOK_CONTAINER_IP_IMAGE="${HOOK_CONTAINER_IP_IMAGE}" \
HOOK_CONTAINER_BOOTKIT_IMAGE="${HOOK_CONTAINER_BOOTKIT_IMAGE}" \
HOOK_CONTAINER_DOCKER_IMAGE="${HOOK_CONTAINER_DOCKER_IMAGE}" \
HOOK_CONTAINER_MDEV_IMAGE="${HOOK_CONTAINER_MDEV_IMAGE}" \
HOOK_CONTAINER_CONTAINERD_IMAGE="${HOOK_CONTAINER_CONTAINERD_IMAGE}" \
HOOK_CONTAINER_RUNC_IMAGE="${HOOK_CONTAINER_RUNC_IMAGE}" \
HOOK_CONTAINER_EMBEDDED_IMAGE="${HOOK_CONTAINER_EMBEDDED_IMAGE}" \
envsubst '$HOOK_VERSION $HOOK_KERNEL_IMAGE $HOOK_KERNEL_ID $HOOK_KERNEL_VERSION $HOOK_CONTAINER_IP_IMAGE $HOOK_CONTAINER_BOOTKIT_IMAGE $HOOK_CONTAINER_DOCKER_IMAGE $HOOK_CONTAINER_MDEV_IMAGE $HOOK_CONTAINER_CONTAINERD_IMAGE $HOOK_CONTAINER_RUNC_IMAGE $HOOK_CONTAINER_EMBEDDED_IMAGE' \
envsubst '$HOOK_VERSION $HOOK_KERNEL_IMAGE $HOOK_KERNEL_ID $HOOK_KERNEL_VERSION $HOOK_CONTAINER_BOOTKIT_IMAGE $HOOK_CONTAINER_DOCKER_IMAGE $HOOK_CONTAINER_MDEV_IMAGE $HOOK_CONTAINER_CONTAINERD_IMAGE $HOOK_CONTAINER_RUNC_IMAGE $HOOK_CONTAINER_EMBEDDED_IMAGE' \
> "hook.${inventory_id}.yaml"

declare -g linuxkit_bin=""
Expand Down
9 changes: 8 additions & 1 deletion files/dhcp.sh
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,9 @@ run_dhcp_client() {

if [ "$one_shot" = "true" ]; then
# always return true for the one shot dhcp call so it doesn't block Hook from starting up.
/sbin/dhcpcd --nobackground -f /dhcpcd.conf --allowinterfaces "${al}" -1 || true
# the --nobackground is not used here because when it is used, dhcpcd doesn't honor the --timeout option
# and waits indefinitely for a response. For one shot, we want to timeout after the 30 second default.
/sbin/dhcpcd -f /dhcpcd.conf --allowinterfaces "${al}" -1 || true
# use busybox's ntpd to set the time after getting an IP address; don't fail
echo 'sleep 1 second before calling ntpd' && sleep 1
/usr/sbin/ntpd -n -q -dd -p pool.ntp.org || true
Expand All @@ -28,6 +30,11 @@ run_dhcp_client() {

}

if [ -f /run/network/interfaces ]; then
echo "the /run/network/interfaces file exists, so static IP's are in use. we will not be running the dhcp client."
exit 0
fi

# we always return true so that a failure here doesn't block the next container service from starting. Ideally, we always
# want the getty service to start so we can debug failures.
run_dhcp_client "$1" || true
50 changes: 50 additions & 0 deletions files/setup-dns.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
#!/bin/sh

# This script is intended to be run on the HookOS/Linuxkit host so it must use /bin/sh.
# No other shells are available on the host.

# modified from alpine setup-dns
# apk add alpine-conf

exec 3>&1 4>&2
trap 'exec 2>&4 1>&3' 0 1 2 3
exec 1>/var/log/setup-dns.log 2>&1

while getopts "d:n:h" opt; do
case $opt in
d) DOMAINNAME="$OPTARG";;
n) NAMESERVERS="$OPTARG";;
esac
done
shift $(($OPTIND - 1))


conf="${ROOT}resolv.conf"

if [ -f "$conf" ] ; then
domain=$(awk '/^domain/ {print $2}' $conf)
dns=$(awk '/^nameserver/ {printf "%s ",$2}' $conf)
elif fqdn="$(get_fqdn)" && [ -n "$fqdn" ]; then
domain="$fqdn"
fi

if [ -n "$DOMAINNAME" ]; then
domain="$DOMAINNAME"
fi

if [ -n "$NAMESERVERS" ] || [ $# -gt 0 ];then
dns="$NAMESERVERS"
fi

if [ -n "$domain" ]; then
mkdir -p "${conf%/*}"
echo "search $domain" > $conf
fi

if [ -n "$dns" ] || [ $# -gt 0 ] && [ -f "$conf" ]; then
sed -i -e '/^nameserver/d' $conf
fi
for i in $dns $@; do
mkdir -p "${conf%/*}"
echo "nameserver $i" >> $conf
done
138 changes: 138 additions & 0 deletions files/static-network.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,138 @@
#!/bin/sh

# This script is intended to be run on the HookOS/Linuxkit host so it must use /bin/sh.
# No other shells are available on the host.

# this script will statically configure a single network interface based on the ipam= parameter
# passed in the kernel command line. The ipam parameter is a colon separated string with the following fields:
# ipam=<mac-address>:<vlan-id>:<ip-address>:<netmask>:<gateway>:<hostname>:<dns>:<search-domains>:<ntp>
# Example: ipam=de-ad-be-ef-fe-ed::192.168.2.193:255.255.255.0:192.168.2.1:myserver:1.1.1.1,8.8.8.8::132.163.97.1,132.163.96.1
# the mac address format requires it to be hyphen separated.

exec 3>&1 4>&2
trap 'exec 2>&4 1>&3' 0 1 2 3
exec 1>/var/log/network_config.log 2>&1

set -xeuo pipefail

# Define the location of the interfaces file
INTERFACES_FILE="/var/run/network/interfaces"

parse_ipam_from_cmdline() {
local cmdline
local ipam_value

# Read the contents of /proc/cmdline
cmdline=$(cat /proc/cmdline)

# Use grep to find the ipam= parameter and awk to extract its value
ipam_value=$(echo "$cmdline" | grep -o 'ipam=[^ ]*' | awk -F= '{print $2}')

# Check if ipam= parameter was found
if [ -n "$ipam_value" ]; then
echo "$ipam_value"
return 0
else
echo "ipam= parameter not found in /proc/cmdline" >&2
return 1
fi
}

# Function to get interface name from MAC address
# TODO(jacobweinstock): if a vlan id is provided we should match for the vlan interface
get_interface_name() {
local mac=$1
for interface in /sys/class/net/*; do
if [ -f "$interface/address" ]; then
if [ "$(cat "$interface/address")" == "$mac" ]; then
echo "$(basename "$interface")"
return 0
fi
fi
done
return 1
}

convert_hyphen_to_colon() {
echo "$1" | tr '-' ':'
}

ipam=$(parse_ipam_from_cmdline)
if [ $? -ne 0 ]; then
echo "Failed to get IPAM value, not statically configuring network"
cat /proc/cmdline
exit 0
fi
echo "IPAM value: $ipam"

mkdir -p $(dirname "$INTERFACES_FILE")

# Parse the IPAM string
IFS=':' read -r mac vlan_id ip netmask gateway hostname dns search_domains ntp <<EOF
${ipam}
EOF

# Check for required fields
if [ -z "$mac" ] || [ -z "$ip" ] || [ -z "$netmask" ] || [ -z "$dns" ]; then
echo "Error: MAC address, IP address, netmask, and DNS are required."
echo "$ipam"
exit 1
fi

# convert Mac address to colon separated format
mac=$(convert_hyphen_to_colon "$mac")

# convert , (comma) separated values to space separated values
dns=$(echo "$dns" | tr ',' ' ')
search_domains=$(echo "$search_domains" | tr ',' ' ')
ntp=$(echo "$ntp" | tr ',' ' ')

# Get interface name
interface=$(get_interface_name "$mac")
if [ -z "$interface" ]; then
echo "Error: No interface found with MAC address $mac"
exit 1
fi

# Start writing to the interfaces file
{
echo "# Static Network configuration for $interface"
echo ""
echo "auto $interface"

if [ -n "$vlan_id" ]; then
echo "iface $interface inet manual"
echo ""
echo "auto $interface.$vlan_id"
echo "iface $interface.$vlan_id inet static"
else
echo "iface $interface inet static"
fi

echo " address $ip"
echo " netmask $netmask"

[ -n "$gateway" ] && echo " gateway $gateway"
[ -n "$hostname" ] && echo " hostname $hostname"

if [ -n "$dns" ]; then
echo " dns-nameserver $dns"
fi

if [ -n "$search_domains" ]; then
echo " dns-search $search_domains"
fi

if [ -n "$ntp" ]; then
echo " ntp-servers $ntp"
fi

} > "$INTERFACES_FILE"

echo "Network configuration has been written to $INTERFACES_FILE"

# Run ifup on the interface
ifup -v -a -i "$INTERFACES_FILE"

# setup DNS
ROOT=/run/resolvconf/ setup-dns -d "$search_domains" "$dns"
73 changes: 42 additions & 31 deletions files/vlan.sh
Original file line number Diff line number Diff line change
@@ -1,63 +1,74 @@
#!/bin/bash
#!/bin/sh

# This script is intended to be run on the HookOS/Linuxkit host so it must use /bin/sh.
# No other shells are available on the host.

exec 3>&1 4>&2
trap 'exec 2>&4 1>&3' 0 1 2 3
exec 1>/var/log/vlan.log 2>&1

set -e # exit on error

# This script will set up VLAN interfaces if `vlan_id=xxxx` in `/proc/cmdline` has a value.
# It will use the MAC address specified in `hw_addr=` to find the interface to add the VLAN to.

function parse_with_regex_power() {
declare stdin_data cmdline_rest
stdin_data="$(cat)" # read stdin
declare search_argument="${1}"
declare normal_matcher="([a-zA-Z0-9/\\@#\$%^&\!*\(\)'\"=:,._-]+)"
declare quoted_matcher="\"([a-zA-Z0-9/\\@#\$%^&\!*\(\)',=: ._-]+)\""
[ $# -gt 1 ] && normal_matcher="$2" && quoted_matcher="$2"
cmdline_rest="$(printf '%s' "$stdin_data" | sed -rn "s/.* ?${search_argument}=${normal_matcher} ?(.*)+?/\1/p")"
if echo "$cmdline_rest" | grep -Eq '^"'; then
cmdline_rest="$(printf "%s\n" "$stdin_data" | sed -rn "s/.* ?${search_argument}=${quoted_matcher} ?(.*)+?/\1/p")"
fi
printf "%s\n" "$cmdline_rest"
}
parse_from_cmdline() {
local key="${1}"
local cmdline
local ipam_value

function parse_kernel_cmdline_for() {
declare result
# shellcheck disable=SC2002
result=$(cat /proc/cmdline | parse_with_regex_power "$@")
if [ -z "${result}" ]; then
return 1
else
printf "%s" "$result"
fi
# Read the contents of /proc/cmdline
cmdline=$(cat /proc/cmdline)

# Use grep to find the ipam= parameter and awk to extract its value
value=$(echo "$cmdline" | grep -o "${key}=[^ ]*" | awk -F= '{print $2}')

# Check if parameter was found
if [ -n "$value" ]; then
echo "$value"
return 0
else
echo "${key}= parameter not found in /proc/cmdline" >&2
return 1
fi
}

function kernel_cmdline_exists() {
parse_kernel_cmdline_for "$@" > /dev/null
get_interface_name() {
local mac=$1
for interface in /sys/class/net/*; do
if [ -f "$interface/address" ]; then
if [ "$(cat "$interface/address")" == "$mac" ]; then
echo "$(basename "$interface")"
return 0
fi
fi
done
return 1
}

function add_vlan_interface() {
# check if vlan_id are set in the kernel commandline, otherwise return.
if ! kernel_cmdline_exists vlan_id; then
if ! parse_from_cmdline vlan_id; then
echo "No vlan_id=xxxx set in kernel commandline; no VLAN handling." >&2
return
fi

# check if hw_addr are set in the kernel commandline, otherwise return.
if ! kernel_cmdline_exists hw_addr; then
if ! parse_from_cmdline hw_addr; then
echo "No hw_addr=xx:xx:xx:xx:xx:xx set in kernel commandline." >&2
fi

echo "Starting VLAN handling, parsing..." >&2

declare vlan_id hw_addr
vlan_id="$(parse_kernel_cmdline_for vlan_id)"
hw_addr="$(parse_kernel_cmdline_for hw_addr)"
vlan_id="$(parse_from_cmdline vlan_id)"
hw_addr="$(parse_from_cmdline hw_addr)"

echo "VLAN handling - vlan_id: '${vlan_id}', hw_addr: '${hw_addr}'" >&2

if [ -n "$vlan_id" ]; then
if [ -n "$hw_addr" ]; then
echo "VLAN handling - vlan_id: '${vlan_id}', hw_addr: '${hw_addr}', searching for interface..." >&2
ifname="$(ip -br link | awk '$3 ~ /'"${hw_addr}"'/ {print $1}')"
ifname="$(get_interface_name ${hw_addr})"
echo "VLAN handling - vlan_id: '${vlan_id}', hw_addr: '${hw_addr}', found interface: '${ifname}'" >&2
else
echo "VLAN handling - vlan_id: '${vlan_id}', hw_addr: '${hw_addr}', no hw_addr found in kernel commandline; default ifname to eth0." >&2
Expand Down
23 changes: 0 additions & 23 deletions images/hook-ip/Dockerfile

This file was deleted.

Loading
Loading