| # Copyright 2025 The Chromium OS Authors. All rights reserved. | |
| # Use of this source code is governed by a BSD-style license that can be | |
| # found in the LICENSE file. | |
| description "Start the DHCP service for satlab." | |
| author "chromium-os-dev@chromium.org" | |
| # Disable OOM killer, critical for Satlab operation. | |
| oom score never | |
| start on (stopped satlab-network-init RESULT=ok and started satlab-dockerd) | |
| respawn | |
| normal exit 0 | |
| script | |
| mkdir -p /var/log/bootup/ # croslint: disable: ensure that the logging directory exists | |
| exec >>/var/log/bootup/${UPSTART_JOB}.log 2>&1 | |
| set -x | |
| set +e | |
| APP_KEY="$(vpd -i RW_VPD -g application)" | |
| if [ "$?" != "0" ] || [ "${APP_KEY}" != "satlab" ]; then | |
| echo "Cannot start ${UPSTART_JOB} for APP_KEY = ${APP_KEY}." | |
| exit 1 | |
| fi | |
| set -e | |
| logger -t "$UPSTART_JOB" "Starting." | |
| SERVER_ADDRESS=192.168.231.1 | |
| SERVER_NETMASK=255.255.255.0 | |
| INTERFACE_LAN='LAN' | |
| # Normal case, one interface connected to a network that should have | |
| # access to google, that interface should have an IP address. | |
| # The other interface has the DUT's connected, no DHCP server has been | |
| # started yet so no IP address on that interface. | |
| find_network_interfaces_by_ip_addr() { | |
| INT_IFACE="" | |
| logger -t "${UPSTART_JOB}" "Finding interfaces by ip address" | |
| local node | |
| local server_net_prefix=$( echo "${SERVER_ADDRESS}" | | |
| awk -F '.' '{print $1 $2 $3}' ) | |
| for node in "$@"; do | |
| local inet_addr=$( ip addr show $node | | |
| grep "inet\b" | | |
| awk '{print $2}' | | |
| cut -d/ -f1 ) | |
| # Exclude the dhcp server subnet from being the external interface | |
| local net_prefix=$( echo "${inet_addr}" | | |
| awk -F '.' '{print $1 $2 $3}' ) | |
| if [ "${net_prefix}" = "${server_net_prefix}" ]; then | |
| if [ -z ${INT_IFACE} ]; then | |
| INT_IFACE=$node | |
| else | |
| logger -t "${UPSTART_JOB}" "Multiple interfaces meet the criteria \ | |
| for External interface, please check wiring connections, only one\ | |
| network cable to internet required." | |
| fi | |
| fi | |
| done | |
| } | |
| find_network_interfaces() { | |
| INT_IFACE="" | |
| local count=0 | |
| find_network_interfaces_by_ip_addr $@ | |
| logger -t "${UPSTART_JOB}" "Internal ${INT_IFACE}" | |
| } | |
| wait_for_interface() { | |
| # Check the interface existence for 5 mins after boot. | |
| # Taking one parameter as the interface name - either 'built-in' or 'USB' | |
| local reps=0 | |
| while [ ${reps} -lt 300 ]; do | |
| find_network_interfaces eth0 eth1 | |
| local intf | |
| case "$1" in | |
| ${INTERFACE_WAN}) intf=${EXT_IFACE} | |
| ;; | |
| ${INTERFACE_LAN}) intf=${INT_IFACE} | |
| ;; | |
| *) logger -t "${UPSTART_JOB}" "Illegal network interface $1" | |
| break | |
| ;; | |
| esac | |
| if [ -n "${intf}" ]; then | |
| logger -t "${UPSTART_JOB}" "Found $1 Ethernet interface ${intf}." | |
| break | |
| fi | |
| if [ $((reps % 30)) -eq 0 ]; then | |
| logger -t "${UPSTART_JOB}" \ | |
| "Waiting for $1 Ethernet connection(${reps} secs)" | |
| fi | |
| : $((reps += 1)) | |
| sleep 1 | |
| done | |
| } | |
| wait_for_interface ${INTERFACE_LAN} | |
| if [ -z "${INT_IFACE}" ]; then | |
| logger -t "${UPSTART_JOB}" "No internal connection on eth0 or eth1." | |
| exit 0 | |
| fi | |
| reps=0 | |
| while [ ${reps} -lt 100 ] && ! docker info ; do | |
| : $((reps += 1)) | |
| sleep 1 | |
| done | |
| # Override dhcp lease time when in dev environment. | |
| DNSMASQ_DEV_CONF_PATH="/etc/dnsmasq-dev.conf" | |
| DEV_ARGS="" | |
| if [ -e /etc/lsb-release ]; then | |
| track=$(cat /etc/lsb-release | \ | |
| grep "CHROMEOS_RELEASE_TRACK" | \ | |
| awk -F = '{ print $2 }') | |
| case $track in | |
| testimage-channel | dev-channel | developer-build ) | |
| DEV_ARGS="--conf-file=${DNSMASQ_DEV_CONF_PATH}" | |
| esac | |
| fi | |
| # You can't have --rm and --restart on a docker run command. | |
| # However this means that on a non clean shutdown the dhcp container is | |
| # restarted, this causes internal/external network detection issues and | |
| # put the moblab in a bad state. | |
| # On boot get rid of any prior containers and make sure we have the latest | |
| # dhcp container. | |
| docker stop dhcp || true | |
| docker rm dhcp || true | |
| docker pull us-docker.pkg.dev/chromeos-partner-moblab/satlab/satlab-dhcp:release | |
| docker run --name dhcp -v leases:/var/lib/misc -d \ | |
| --cap-add=NET_ADMIN --network host \ | |
| --restart always \ | |
| us-docker.pkg.dev/chromeos-partner-moblab/satlab/satlab-dhcp:release \ | |
| ${DEV_ARGS} --interface "${INT_IFACE}" --bind-interfaces | |
| logger -t "$UPSTART_JOB" "Ending." | |
| end script |