Skip to content

Commit

Permalink
systemd: add scripts and systemd units for running at boot
Browse files Browse the repository at this point in the history
Should be compatible with the legacy kargs syntax, with the following
adjustments:

- Drop coreos.inst=yes, since it's redundant.  coreos.inst.install_dev is
  mandatory, so run only if that karg is specified.
- Expect full device paths in coreos.inst.install_dev.  For compatibility,
  prepend "/dev/" if a bare device name is specified.
- Make coreos.inst.ignition_url optional.  For compatibility, ignore the karg
  if "skip" is specified as the value.
- Add kargs for Fedora CoreOS stream, stream base URL, and to enable insecure
  mode.
  • Loading branch information
bgilbert authored and dustymabe committed Jan 6, 2020
1 parent da95cd2 commit 6dd597a
Show file tree
Hide file tree
Showing 5 changed files with 172 additions and 0 deletions.
23 changes: 23 additions & 0 deletions systemd/coreos-installer-generator
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
#!/bin/bash
# -*- mode: shell-script; indent-tabs-mode: nil; sh-basic-offset: 4; -*-
# ex: ts=8 sw=4 sts=4 et filetype=sh

set -e

UNIT_DIR="${1:-/tmp}"

cmdline=( $(</proc/cmdline) )
cmdline_arg() {
local name="$1" value="$2"
for arg in "${cmdline[@]}"; do
if [[ "${arg%%=*}" == "${name}" ]]; then
value="${arg#*=}"
fi
done
echo "${value}"
}

if [ -n "$(cmdline_arg coreos.inst.install_dev)" ]; then
ln -sf "/usr/lib/systemd/system/coreos-installer.target" \
"${UNIT_DIR}/default.target"
fi
10 changes: 10 additions & 0 deletions systemd/coreos-installer-reboot.service
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
[Unit]
Description=Reboot after CoreOS Installer
After=coreos-installer.target
OnFailure=emergency.target
OnFailureJobMode=isolate
ConditionPathExists=/run/coreos-installer-reboot

[Service]
Type=simple
ExecStart=/sbin/systemctl --no-block reboot
118 changes: 118 additions & 0 deletions systemd/coreos-installer-service
Original file line number Diff line number Diff line change
@@ -0,0 +1,118 @@
#!/bin/bash

set -e

# Kernel networking params to persist
PERSIST_KERNEL_NET_PARAMS=("ipv6.disable")

# Dracut networking params to persist
# Everything other than rd.neednet.
# List from https://www.mankier.com/7/dracut.cmdline#Description-Network
PERSIST_DRACUT_NET_PARAMS=("ip" "ifname" "rd.route" "bootdev" "BOOTIF" "rd.bootif" "nameserver" "rd.peerdns" "biosdevname" "vlan" "bond" "team" "bridge" "rd.net.timeout.carrier" "coreos.no_persist_ip")

args=("install")

cmdline=( $(</proc/cmdline) )
karg() {
local name="$1" value="$2"
for arg in "${cmdline[@]}"; do
if [[ "${arg%%=*}" == "${name}" ]]; then
value="${arg#*=}"
fi
done
echo "${value}"
}

karg_bool() {
local value=$(cmdline_arg "$@")
case "$value" in
""|0|no|off) return 1;;
*) return 0;;
esac
}

copy_arg() {
local arg="$1"; shift
local opt="$1"; shift

local value="$(karg "${arg}")"
if [ ! -z "${value}" ]; then
args+=("${opt}" "${value}")
fi
}

# Wait for the network to be up by trying to HEAD a URL.
# If an image URL was specified, use that.
check_url="$(karg coreos.inst.image_url)"
# Otherwise, an Ignition config URL.
check_url="${check_url:-$(karg coreos.inst.ignition_url)}"
# Otherwise, fall back to a globally accessible URL. Try this last because
# we might not have access to the Internet.
check_url="${check_url:-http://fedoraproject.org/static/hotspot.txt}"
# We'd like to disable the progress meter but we can only do that completely
# with --silent, which also disables status updates. Use the compact
# progress bar instead, since at least it's smaller.
curl --head --progress-bar --fail \
--retry 60 --retry-delay 1 --retry-connrefused \
-o /dev/null "${check_url}"

# Get install device
device="$(karg coreos.inst.install_dev)"
if [ -z "${device}" ]; then
echo "No install device specified."
exit 1
fi
if [ "${device##*/}" = "${device}" ]; then
# karg contains no slashes. Prepend "/dev/" for compatibility.
device="/dev/${device}"
fi
args+=("${device}")

# Fetch the Ignition URL, if any, and cache it locally.
ignition_url="$(karg coreos.inst.ignition_url)"
# Ignore "skip" for compatibility
if [ -n "${ignition_url}" -a "${ignition_url}" != "skip" ]; then
ignition_file="$(mktemp -t coreos-installer-XXXXXX)"
trap "rm -f \"${ignition_file}\"" EXIT
curl --progress-bar --fail -o "${ignition_file}" "${ignition_url}"
args+=("--ignition" "${ignition_file}")
fi

# First-boot kernel arguments
firstboot_args=""
for param in "${PERSIST_KERNEL_NET_PARAMS[@]}" "${PERSIST_DRACUT_NET_PARAMS[@]}"
do
value=$(getarg "${param}")
if [ -n "${value}" ]; then
firstboot_args+="${param}=${value} "
fi
done
# Only pass firstboot-kargs if additional networking options have been
# specified, since the default in ignition-dracut specifies
# `rd.neednet=1 ip=dhcp` when no options are persisted
if [ -n "${firstboot_args}" ]; then
args+=("--firstboot-args" "rd.neednet=1 ${firstboot_args}")
fi

# Other args that should just be copied over
copy_arg coreos.inst.image_url --image-url
copy_arg coreos.inst.platform_id --platform
copy_arg coreos.inst.stream --stream
copy_arg coreos.inst.stream_base_url --stream-base-url

# Insecure boolean
if karg_bool coreos.inst.insecure; then
args+=("--insecure")
fi

# Ensure device nodes have been created
udevadm settle

# Install
echo "coreos-installer ${args[@]}"
coreos-installer "${args[@]}"

# Create precondition for coreos-installer-reboot.service if requested
if ! karg_bool coreos.inst.skip_reboot; then
touch /run/coreos-installer-reboot
fi
9 changes: 9 additions & 0 deletions systemd/coreos-installer.service
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
[Unit]
Description=CoreOS Installer
Before=coreos-installer.target
ConditionKernelCommandLine=coreos.inst.install_dev

[Service]
Type=simple
ExecStart=/usr/libexec/coreos-installer-service
StandardOutput=kmsg+console
12 changes: 12 additions & 0 deletions systemd/coreos-installer.target
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
[Unit]
Description=CoreOS Installer Target
OnFailure=emergency.target
OnFailureJobMode=isolate
AllowIsolate=yes

Requires=coreos-installer.service
Requires=coreos-installer-reboot.service

# Run after most things are up
Requires=basic.target
After=basic.target

0 comments on commit 6dd597a

Please sign in to comment.