|
| 1 | +#!/bin/sh |
| 2 | + |
| 3 | +# This script is intended to be run on the HookOS/Linuxkit host so it must use /bin/sh. |
| 4 | +# No other shells are available on the host. |
| 5 | + |
| 6 | +# this script will statically configure a single network interface based on the ipam= parameter |
| 7 | +# passed in the kernel command line. The ipam parameter is a colon separated string with the following fields: |
| 8 | +# ipam=<mac-address>:<vlan-id>:<ip-address>:<netmask>:<gateway>:<hostname>:<dns>:<search-domains>:<ntp> |
| 9 | +# 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 |
| 10 | +# the mac address format requires it to be hyphen separated. |
| 11 | + |
| 12 | +exec 3>&1 4>&2 |
| 13 | +trap 'exec 2>&4 1>&3' 0 1 2 3 |
| 14 | +exec 1>/var/log/network_config.log 2>&1 |
| 15 | + |
| 16 | +set -xeuo pipefail |
| 17 | + |
| 18 | +# Define the location of the interfaces file |
| 19 | +INTERFACES_FILE="/var/run/network/interfaces" |
| 20 | + |
| 21 | +parse_ipam_from_cmdline() { |
| 22 | + local cmdline |
| 23 | + local ipam_value |
| 24 | + |
| 25 | + # Read the contents of /proc/cmdline |
| 26 | + cmdline=$(cat /proc/cmdline) |
| 27 | + |
| 28 | + # Use grep to find the ipam= parameter and awk to extract its value |
| 29 | + ipam_value=$(echo "$cmdline" | grep -o 'ipam=[^ ]*' | awk -F= '{print $2}') |
| 30 | + |
| 31 | + # Check if ipam= parameter was found |
| 32 | + if [ -n "$ipam_value" ]; then |
| 33 | + echo "$ipam_value" |
| 34 | + return 0 |
| 35 | + else |
| 36 | + echo "ipam= parameter not found in /proc/cmdline" >&2 |
| 37 | + return 1 |
| 38 | + fi |
| 39 | +} |
| 40 | + |
| 41 | +# Function to get interface name from MAC address |
| 42 | +# TODO(jacobweinstock): if a vlan id is provided we should match for the vlan interface |
| 43 | +get_interface_name() { |
| 44 | + local mac=$1 |
| 45 | + for interface in /sys/class/net/*; do |
| 46 | + if [ -f "$interface/address" ]; then |
| 47 | + if [ "$(cat "$interface/address")" == "$mac" ]; then |
| 48 | + echo "$(basename "$interface")" |
| 49 | + return 0 |
| 50 | + fi |
| 51 | + fi |
| 52 | + done |
| 53 | + return 1 |
| 54 | +} |
| 55 | + |
| 56 | +convert_hyphen_to_colon() { |
| 57 | + echo "$1" | tr '-' ':' |
| 58 | +} |
| 59 | + |
| 60 | +ipam=$(parse_ipam_from_cmdline) |
| 61 | +if [ $? -ne 0 ]; then |
| 62 | + echo "Failed to get IPAM value, not statically configuring network" |
| 63 | + cat /proc/cmdline |
| 64 | + exit 0 |
| 65 | +fi |
| 66 | +echo "IPAM value: $ipam" |
| 67 | + |
| 68 | +mkdir -p $(dirname "$INTERFACES_FILE") |
| 69 | + |
| 70 | +# Parse the IPAM string |
| 71 | +IFS=':' read -r mac vlan_id ip netmask gateway hostname dns search_domains ntp <<EOF |
| 72 | +${ipam} |
| 73 | +EOF |
| 74 | + |
| 75 | +# Check for required fields |
| 76 | +if [ -z "$mac" ] || [ -z "$ip" ] || [ -z "$netmask" ] || [ -z "$dns" ]; then |
| 77 | + echo "Error: MAC address, IP address, netmask, and DNS are required." |
| 78 | + echo "$ipam" |
| 79 | + exit 1 |
| 80 | +fi |
| 81 | + |
| 82 | +# convert Mac address to colon separated format |
| 83 | +mac=$(convert_hyphen_to_colon "$mac") |
| 84 | + |
| 85 | +# convert , (comma) separated values to space separated values |
| 86 | +dns=$(echo "$dns" | tr ',' ' ') |
| 87 | +search_domains=$(echo "$search_domains" | tr ',' ' ') |
| 88 | +ntp=$(echo "$ntp" | tr ',' ' ') |
| 89 | + |
| 90 | +# Get interface name |
| 91 | +interface=$(get_interface_name "$mac") |
| 92 | +if [ -z "$interface" ]; then |
| 93 | + echo "Error: No interface found with MAC address $mac" |
| 94 | + exit 1 |
| 95 | +fi |
| 96 | + |
| 97 | +# Start writing to the interfaces file |
| 98 | +{ |
| 99 | + echo "# Static Network configuration for $interface" |
| 100 | + echo "" |
| 101 | + echo "auto $interface" |
| 102 | + |
| 103 | + if [ -n "$vlan_id" ]; then |
| 104 | + echo "iface $interface inet manual" |
| 105 | + echo "" |
| 106 | + echo "auto $interface.$vlan_id" |
| 107 | + echo "iface $interface.$vlan_id inet static" |
| 108 | + else |
| 109 | + echo "iface $interface inet static" |
| 110 | + fi |
| 111 | + |
| 112 | + echo " address $ip" |
| 113 | + echo " netmask $netmask" |
| 114 | + |
| 115 | + [ -n "$gateway" ] && echo " gateway $gateway" |
| 116 | + [ -n "$hostname" ] && echo " hostname $hostname" |
| 117 | + |
| 118 | + if [ -n "$dns" ]; then |
| 119 | + echo " dns-nameserver $dns" |
| 120 | + fi |
| 121 | + |
| 122 | + if [ -n "$search_domains" ]; then |
| 123 | + echo " dns-search $search_domains" |
| 124 | + fi |
| 125 | + |
| 126 | + if [ -n "$ntp" ]; then |
| 127 | + echo " ntp-servers $ntp" |
| 128 | + fi |
| 129 | + |
| 130 | +} > "$INTERFACES_FILE" |
| 131 | + |
| 132 | +echo "Network configuration has been written to $INTERFACES_FILE" |
| 133 | + |
| 134 | +# Run ifup on the interface |
| 135 | +ifup -v -a -i "$INTERFACES_FILE" |
| 136 | + |
| 137 | +# setup DNS |
| 138 | +ROOT=/run/resolvconf/ setup-dns -d "$search_domains" "$dns" |
0 commit comments