add in overlays
This commit is contained in:
parent
a1422529c0
commit
e95986917e
1
.gitignore
vendored
1
.gitignore
vendored
@ -1,3 +1,4 @@
|
||||
build/
|
||||
.direnv/
|
||||
.envrc
|
||||
ass
|
||||
|
@ -0,0 +1,3 @@
|
||||
# We don't ship cracklib dicts, so don't try to use them to validate
|
||||
# password changes.
|
||||
dictcheck = 0
|
2
overlay.d/05core/etc/sudoers.d/coreos-sudo-group
Normal file
2
overlay.d/05core/etc/sudoers.d/coreos-sudo-group
Normal file
@ -0,0 +1,2 @@
|
||||
# https://github.com/openshift/os/issues/96
|
||||
%sudo ALL=(ALL) NOPASSWD: ALL
|
7
overlay.d/05core/statoverride
Normal file
7
overlay.d/05core/statoverride
Normal file
@ -0,0 +1,7 @@
|
||||
# Config file for overriding permission bits on overlay files/dirs
|
||||
# Format: =<file mode in decimal> <absolute path to a file or directory>
|
||||
|
||||
# sudo prefers its config files to be mode 440, and some security scanners
|
||||
# complain if /etc/sudoers.d files are world-readable.
|
||||
# https://bugzilla.redhat.com/show_bug.cgi?id=1981979
|
||||
=288 /etc/sudoers.d/coreos-sudo-group
|
@ -0,0 +1,2 @@
|
||||
[connection]
|
||||
ipv4.dhcp-client-id=mac
|
30
overlay.d/05core/usr/lib/coreos/generator-lib.sh
Normal file
30
overlay.d/05core/usr/lib/coreos/generator-lib.sh
Normal file
@ -0,0 +1,30 @@
|
||||
# File intended to be sourced by shell script generators shipped with CoreOS systems
|
||||
|
||||
# Generators don't have logging right now
|
||||
# https://github.com/systemd/systemd/issues/15638
|
||||
exec 1>/dev/kmsg; exec 2>&1
|
||||
|
||||
UNIT_DIR="${1:-/tmp}"
|
||||
|
||||
have_karg() {
|
||||
local arg="$1"
|
||||
local cmdline=( $(</proc/cmdline) )
|
||||
local i
|
||||
for i in "${cmdline[@]}"; do
|
||||
if [[ "$i" =~ "$arg=" ]]; then
|
||||
return 0
|
||||
fi
|
||||
done
|
||||
return 1
|
||||
}
|
||||
|
||||
karg() {
|
||||
local name="$1" value="${2:-}"
|
||||
local cmdline=( $(</proc/cmdline) )
|
||||
for arg in "${cmdline[@]}"; do
|
||||
if [[ "${arg%%=*}" == "${name}" ]]; then
|
||||
value="${arg#*=}"
|
||||
fi
|
||||
done
|
||||
echo "${value}"
|
||||
}
|
@ -0,0 +1,2 @@
|
||||
# Default rpm-ostree model is server-side generated initramfs
|
||||
hostonly=no
|
@ -0,0 +1,3 @@
|
||||
# We don't ship `strip` or `eu-strip` today, and even if we did, it doesn't
|
||||
# save much space. So let's disable it to avoid the error-looking message.
|
||||
do_strip=no
|
@ -0,0 +1,15 @@
|
||||
# We don't support root on NFS, so we don't need it in the initramfs. It also
|
||||
# conflicts with /var mount support in ignition because NFS tries to mount stuff
|
||||
# in /var/ and then ignition can't cleanly unmount it. For example:
|
||||
# https://github.com/dracutdevs/dracut/blob/1856ae95c873a6fe855b3dccd0144f1a96b9e71c/modules.d/95nfs/nfs-start-rpc.sh#L7
|
||||
# See also discussion in https://github.com/coreos/fedora-coreos-config/pull/60
|
||||
# Further, we currently do not use LVM, iSCSI or dmraid
|
||||
omit_dracutmodules+=" nfs lvm iscsi dmraid "
|
||||
# More storage modules we don't use
|
||||
omit_dracutmodules+=" fcoe fcoe-uefi nbd "
|
||||
# We use NetworkManager
|
||||
omit_dracutmodules+=" systemd-networkd network-legacy network-wicked "
|
||||
# We use systemd network naming
|
||||
omit_dracutmodules+=" biosdevname "
|
||||
# Random stuff we don't want
|
||||
omit_dracutmodules+=" rngd busybox dbus-daemon memstrack pcsc bluetooth "
|
@ -0,0 +1,13 @@
|
||||
# -*- mode: shell-script; indent-tabs-mode: nil; sh-basic-offset: 4; -*-
|
||||
# ex: ts=8 sw=4 sts=4 et filetype=sh
|
||||
|
||||
# 1) Fix for https://bugzilla.redhat.com/show_bug.cgi?id=1918244
|
||||
# On s390x systems with IBM 2810XIV discs multipath couldn't be configured
|
||||
# because SCSI_IDENT_* udev properties are not set at boot time
|
||||
# 2-) Fix for https://bugzilla.redhat.com/show_bug.cgi?id=1990506
|
||||
# Missing symlinks to disk install
|
||||
install() {
|
||||
inst_simple sg_inq
|
||||
inst_rules 61-scsi-sg3_id.rules
|
||||
inst_rules 63-scsi-sg3_symlink.rules
|
||||
}
|
@ -0,0 +1,23 @@
|
||||
# For now we are using kmsg [1] for multiplexing output to
|
||||
# multiple console devices during early boot. We need to also tell
|
||||
# the kernel not to ratelimit kmsg during the initramfs.
|
||||
#
|
||||
# We do not want to use kmsg in the future as there may be sensitive
|
||||
# ignition data that leaks to non-root users (by reading the kernel
|
||||
# ring buffer using `dmesg`). In the future we will rely on kernel
|
||||
# console multiplexing [2] for this and will not use kmsg.
|
||||
#
|
||||
# [1] https://github.com/coreos/ignition-dracut/blob/26f2396b116286dcb46644dc157e4211aea3aba5/dracut/99journald-conf/00-journal-log-forwarding.conf#L2
|
||||
# [2] https://github.com/coreos/fedora-coreos-tracker/issues/136
|
||||
|
||||
# See also 10-coreos-ratelimit-kmsg.conf, which turns ratelimiting back *on*
|
||||
# in the real root.
|
||||
|
||||
check() {
|
||||
return 0
|
||||
}
|
||||
|
||||
install() {
|
||||
mkdir -p "$initdir/etc/sysctl.d"
|
||||
echo "kernel.printk_devkmsg = on" > "$initdir/etc/sysctl.d/10-dont-ratelimit-kmsg.conf"
|
||||
}
|
@ -0,0 +1,70 @@
|
||||
{
|
||||
"ignition": {
|
||||
"version": "3.2.0"
|
||||
},
|
||||
"storage": {
|
||||
"disks": [
|
||||
{
|
||||
"device": "${BOOTDEV}",
|
||||
"partitions": [
|
||||
{
|
||||
"label": "boot",
|
||||
"number": 3
|
||||
},
|
||||
{
|
||||
"label": "root",
|
||||
"number": 4,
|
||||
"resize": true,
|
||||
"sizeMiB": 0
|
||||
},
|
||||
{
|
||||
"number": 5,
|
||||
"shouldExist": false,
|
||||
"wipePartitionEntry": true
|
||||
},
|
||||
{
|
||||
"number": 6,
|
||||
"shouldExist": false,
|
||||
"wipePartitionEntry": true
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"luks": [
|
||||
{
|
||||
"device": "/dev/disk/by-partlabel/boot",
|
||||
"label": "crypt_bootfs",
|
||||
"name": "boot",
|
||||
"options": [
|
||||
"--integrity",
|
||||
"hmac-sha256"
|
||||
],
|
||||
"wipeVolume": true
|
||||
},
|
||||
{
|
||||
"device": "/dev/disk/by-partlabel/root",
|
||||
"label": "crypt_rootfs",
|
||||
"name": "root",
|
||||
"options": [
|
||||
"--integrity",
|
||||
"hmac-sha256"
|
||||
],
|
||||
"wipeVolume": true
|
||||
}
|
||||
],
|
||||
"filesystems": [
|
||||
{
|
||||
"device": "/dev/mapper/boot",
|
||||
"format": "ext4",
|
||||
"label": "boot",
|
||||
"wipeFilesystem": true
|
||||
},
|
||||
{
|
||||
"device": "/dev/mapper/root",
|
||||
"format": "xfs",
|
||||
"label": "root",
|
||||
"wipeFilesystem": true
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
@ -0,0 +1,10 @@
|
||||
# CoreOS-specific symlink for boot disk
|
||||
|
||||
ACTION!="add|change", GOTO="stable_boot_end"
|
||||
SUBSYSTEM!="block", GOTO="stable_boot_end"
|
||||
|
||||
ENV{DEVTYPE}=="disk" \
|
||||
, PROGRAM=="coreos-disk-contains-fs $name boot" \
|
||||
, SYMLINK+="disk/by-id/coreos-boot-disk"
|
||||
|
||||
LABEL="stable_boot_end"
|
@ -0,0 +1,32 @@
|
||||
# This unit will run late in the initrd process after Ignition is completed
|
||||
# successfully and temporarily mount /boot read-write to make edits
|
||||
# (e.g. removing firstboot networking configuration files if necessary).
|
||||
|
||||
[Unit]
|
||||
Description=CoreOS Boot Edit
|
||||
ConditionPathExists=/usr/lib/initrd-release
|
||||
OnFailure=emergency.target
|
||||
OnFailureJobMode=isolate
|
||||
|
||||
# Since we are mounting /boot, require the device first. This isn't strictly
|
||||
# necessary since we run late, but on principle let's make clear the dependency.
|
||||
Requires=dev-disk-by\x2dlabel-boot.device
|
||||
After=dev-disk-by\x2dlabel-boot.device
|
||||
# Start after Ignition has finished
|
||||
After=ignition-files.service
|
||||
# As above, this isn't strictly necessary, but on principle.
|
||||
After=coreos-multipath-wait.target
|
||||
# Finish before systemd starts tearing down services
|
||||
Before=initrd.target
|
||||
# initrd-parse-etc.service starts initrd-cleanup.service which will race
|
||||
# with us completing before we get nuked. Need to get to the bottom of it,
|
||||
# but for now we need this.
|
||||
Before=initrd-parse-etc.service
|
||||
|
||||
[Service]
|
||||
Type=oneshot
|
||||
ExecStart=/usr/sbin/coreos-boot-edit
|
||||
RemainAfterExit=yes
|
||||
# MountFlags=slave is so the umount of /boot is guaranteed to happen.
|
||||
# /boot will only be mounted for the lifetime of the unit.
|
||||
MountFlags=slave
|
@ -0,0 +1,45 @@
|
||||
#!/bin/bash
|
||||
set -euo pipefail
|
||||
|
||||
# For a description of how this is used, see `coreos-boot-edit.service`.
|
||||
|
||||
cmdline=( $(</proc/cmdline) )
|
||||
karg() {
|
||||
local name="$1" value="${2:-}"
|
||||
for arg in "${cmdline[@]}"; do
|
||||
if [[ "${arg%%=*}" == "${name}" ]]; then
|
||||
value="${arg#*=}"
|
||||
fi
|
||||
done
|
||||
echo "${value}"
|
||||
}
|
||||
|
||||
# Mount /boot. Note that we mount /boot but we don't unmount it because we
|
||||
# are run in a systemd unit with MountFlags=slave so it is unmounted for us.
|
||||
bootmnt=/mnt/boot_partition
|
||||
mkdir -p ${bootmnt}
|
||||
bootdev=/dev/disk/by-label/boot
|
||||
mount -o rw ${bootdev} ${bootmnt}
|
||||
|
||||
# Clean up firstboot networking config files if the user copied them into the
|
||||
# installed system (most likely by using `coreos-installer install --copy-network`).
|
||||
firstboot_network_dir_basename="coreos-firstboot-network"
|
||||
initramfs_firstboot_network_dir="${bootmnt}/${firstboot_network_dir_basename}"
|
||||
rm -vrf ${initramfs_firstboot_network_dir}
|
||||
|
||||
# If root is specified, assume rootmap is already configured. Otherwise,
|
||||
# append rootmap kargs to the BLS configs.
|
||||
root=$(karg root)
|
||||
if [ -z "${root}" ]; then
|
||||
rdcore rootmap /sysroot --boot-mount ${bootmnt}
|
||||
fi
|
||||
|
||||
# This does a few things:
|
||||
# 1. it puts the boot UUID in /run/coreos/bootfs_uuid which is used by the real
|
||||
# root for mounting the bootfs in this boot
|
||||
# 2. it adds a boot=UUID= karg which is used by the real root for mounting the
|
||||
# bootfs in subsequent boots
|
||||
# 3. it create a .root_uuid stamp file on the bootfs or fails if one exists
|
||||
# 4. it adds GRUB bootuuid.cfg dropins so that GRUB selects the boot filesystem
|
||||
# by UUID
|
||||
rdcore bind-boot /sysroot ${bootmnt}
|
@ -0,0 +1,20 @@
|
||||
#!/bin/bash
|
||||
# checks whether `disk` contains filesystem labeled `label`
|
||||
set -euo pipefail
|
||||
|
||||
disk=$1
|
||||
label=$2
|
||||
|
||||
# during execution of udev rules on disks 'lsblk' returns empty fields
|
||||
for pt in /sys/block/$disk/*; do
|
||||
name=$(basename $pt)
|
||||
if [[ "$name" =~ ${disk}p?[[:digit:]] ]] && [[ -e "/sys/block/$disk/$name/start" ]];
|
||||
then
|
||||
eval $(udevadm info --query=property -n /dev/$name | grep -e ID_FS_LABEL -e PARTNAME)
|
||||
if [[ "${ID_FS_LABEL:-}" == "$label" ]] || [[ "${PARTNAME:-}" == "$label" ]]; then
|
||||
exit 0
|
||||
fi
|
||||
fi
|
||||
done
|
||||
|
||||
exit 1
|
@ -0,0 +1,77 @@
|
||||
#!/bin/bash
|
||||
# -*- mode: shell-script; indent-tabs-mode: nil; sh-basic-offset: 4; -*-
|
||||
# ex: ts=8 sw=4 sts=4 et filetype=sh
|
||||
|
||||
# Originally this was known as 'ignition-generator' found in ignition-dracut.
|
||||
# With Ignition v 2.5.0, ignition-dracut was merged into Ignition and the CoreOS
|
||||
# specific bits were deposited here.
|
||||
|
||||
set -e
|
||||
|
||||
# Generators don't have logging right now
|
||||
# https://github.com/systemd/systemd/issues/15638
|
||||
exec 1>/dev/kmsg; exec 2>&1
|
||||
|
||||
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}"
|
||||
}
|
||||
|
||||
cmdline_bool() {
|
||||
local value=$(cmdline_arg "$@")
|
||||
case "$value" in
|
||||
""|0|no|off) return 1;;
|
||||
*) return 0;;
|
||||
esac
|
||||
}
|
||||
|
||||
add_requires() {
|
||||
local name="$1"; shift
|
||||
local target="$1"; shift
|
||||
local requires_dir="${UNIT_DIR}/${target}.requires"
|
||||
mkdir -p "${requires_dir}"
|
||||
ln -sf "../${name}" "${requires_dir}/${name}"
|
||||
}
|
||||
|
||||
if ! $(cmdline_bool 'ignition.firstboot' 0); then
|
||||
exit 0
|
||||
fi
|
||||
|
||||
if ! is-live-image; then
|
||||
# coreos-ignition-setup-user.service should depend on the boot device node
|
||||
# only on diskful boots
|
||||
mkdir -p "${UNIT_DIR}/coreos-ignition-setup-user.service.d"
|
||||
cat > "${UNIT_DIR}/coreos-ignition-setup-user.service.d/diskful.conf" <<EOF
|
||||
[Unit]
|
||||
Requires=dev-disk-by\x2dlabel-boot.device
|
||||
After=dev-disk-by\x2dlabel-boot.device
|
||||
|
||||
Requires=coreos-gpt-setup.service
|
||||
After=coreos-gpt-setup.service
|
||||
EOF
|
||||
|
||||
# create symlink for udev rule
|
||||
mkdir -p /run/udev/rules.d/
|
||||
ln -sf /usr/lib/coreos/80-coreos-boot-disk.rules \
|
||||
/run/udev/rules.d/80-coreos-boot-disk.rules
|
||||
|
||||
# IBM Secure Execution case
|
||||
# During firstboot we have to reencrypt '/boot' and '/', to do that an Ignition config
|
||||
# is injected. 'coreos-boot-disk' is required for this
|
||||
secure_execution=0
|
||||
if [[ $(uname -m) == s390x ]] && [[ -e /sys/firmware/uv/prot_virt_guest ]]; then
|
||||
secure_execution=$(cat /sys/firmware/uv/prot_virt_guest)
|
||||
fi
|
||||
if [[ "${secure_execution}" = "1" ]]; then
|
||||
mkdir -p /run/coreos/
|
||||
touch /run/coreos/secure-execution
|
||||
fi
|
||||
fi
|
@ -0,0 +1,36 @@
|
||||
[Unit]
|
||||
Description=Generate New UUID For Boot Disk GPT
|
||||
ConditionPathExists=/etc/initrd-release
|
||||
DefaultDependencies=no
|
||||
Before=local-fs-pre.target systemd-fsck-root.service
|
||||
Before=ignition-diskful.target
|
||||
Wants=systemd-udevd.service
|
||||
After=systemd-udevd.service
|
||||
|
||||
# This unit must be the first to run when the disk holding the root partition
|
||||
# becomes available. To avoid relying on the name of the root partition which
|
||||
# is different between RHCOS LUKS setup and current FCOS setup, we wait for the
|
||||
# partition labeled 'boot' to become available. This is reliable as we don't
|
||||
# have any plan to support re-provisioning/re-writing the /boot partition,
|
||||
#
|
||||
# This is the only unit where it is safe to wait only on a specific disk label
|
||||
# as this will call udevadm settle after the GPT setup. Units that requires the
|
||||
# boot and root partitions to be available should order themselves after this
|
||||
# unit.
|
||||
Requires=dev-disk-by\x2dlabel-boot.device
|
||||
After=dev-disk-by\x2dlabel-boot.device
|
||||
# And since the boot device may be on multipath; optionally wait for it to
|
||||
# appear via the dynamic target.
|
||||
After=coreos-multipath-wait.target
|
||||
|
||||
# Run before services that use device nodes, preventing them from racing
|
||||
# with udev activity generated by sgdisk
|
||||
Before=coreos-ignition-setup-user.service ignition-disks.service
|
||||
|
||||
OnFailure=emergency.target
|
||||
OnFailureJobMode=isolate
|
||||
|
||||
[Service]
|
||||
Type=oneshot
|
||||
RemainAfterExit=yes
|
||||
ExecStart=/usr/sbin/coreos-gpt-setup /dev/disk/by-label/boot
|
@ -0,0 +1,42 @@
|
||||
#!/bin/bash
|
||||
# randomizes the disk guid on the disk containing the partition specified by $1
|
||||
# and moves the secondary gpt header/partition table to the end of the disk where it
|
||||
# should be. If the disk guid is already randomized, it does nothing.
|
||||
set -euo pipefail
|
||||
|
||||
UNINITIALIZED_GUID='00000000-0000-4000-a000-000000000001'
|
||||
|
||||
# If it's on multipath, get the parent device from udev properties.
|
||||
DM_MPATH=$(eval $(udevadm info --query property --export "$1") && echo "${DM_MPATH:-}")
|
||||
|
||||
if [ -n "${DM_MPATH:-}" ]; then
|
||||
PKNAME=/dev/mapper/$DM_MPATH
|
||||
PTUUID=$(eval $(udevadm info --query property --export "$PKNAME") && echo "${ID_PART_TABLE_UUID:-}")
|
||||
else
|
||||
# On RHEL 8 the version of lsblk doesn't have PTUUID. Let's detect
|
||||
# if lsblk supports it. In the future we can remove the 'if' and
|
||||
# just use the 'else'.
|
||||
if ! lsblk --help | grep -q PTUUID; then
|
||||
# Get the PKNAME
|
||||
eval $(lsblk --output PKNAME --pairs --paths --nodeps "$1")
|
||||
# Get the PTUUID
|
||||
eval $(blkid -o export $PKNAME)
|
||||
else
|
||||
# PTUUID is the disk guid, PKNAME is the parent kernel name
|
||||
eval $(lsblk --output PTUUID,PKNAME --pairs --paths --nodeps "$1")
|
||||
fi
|
||||
fi
|
||||
|
||||
# Skip in the following two cases:
|
||||
# - The PTUUID is != $UNINITIALIZED_GUID
|
||||
# - The PTUUID is empty. This happens on s390x where DASD disks don't
|
||||
# have PTUUID or any of the other traditional partition table
|
||||
# attributes of GPT disks.
|
||||
if [ "${PTUUID:-}" != "$UNINITIALIZED_GUID" ]; then
|
||||
echo "Not randomizing disk GUID; found ${PTUUID:-none}"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
echo "Randomizing disk GUID"
|
||||
sgdisk --disk-guid=R --move-second-header "$PKNAME"
|
||||
udevadm settle || :
|
@ -0,0 +1,23 @@
|
||||
[Unit]
|
||||
Description=CoreOS Ignition User Config Setup
|
||||
Documentation=https://github.com/coreos/ignition
|
||||
ConditionPathExists=/etc/initrd-release
|
||||
DefaultDependencies=false
|
||||
|
||||
# We run before config fetch because we may copy in new/different configs
|
||||
# for Ignition to consume.
|
||||
Before=ignition-fetch-offline.service
|
||||
|
||||
OnFailure=emergency.target
|
||||
OnFailureJobMode=isolate
|
||||
|
||||
# On diskful boots, coreos-diskful-generator adds Requires/After on
|
||||
# dev-disk-by\x2dlabel-boot.device and coreos-gpt-setup.service
|
||||
|
||||
[Service]
|
||||
Type=oneshot
|
||||
RemainAfterExit=yes
|
||||
# The MountFlags=slave is so the umount of /boot is guaranteed to happen
|
||||
# /boot will only be mounted for the lifetime of the unit.
|
||||
MountFlags=slave
|
||||
ExecStart=/usr/sbin/coreos-ignition-setup-user
|
@ -0,0 +1,32 @@
|
||||
#!/bin/bash
|
||||
set -euo pipefail
|
||||
|
||||
copy_file_if_exists() {
|
||||
src="${1}"; dst="${2}"
|
||||
if [ -f "${src}" ]; then
|
||||
echo "Copying ${src} to ${dst}"
|
||||
cp "${src}" "${dst}"
|
||||
else
|
||||
echo "File ${src} does not exist.. Skipping copy"
|
||||
fi
|
||||
}
|
||||
|
||||
destination=/usr/lib/ignition
|
||||
mkdir -p $destination
|
||||
|
||||
if is-live-image; then
|
||||
# Live image. If the user has supplied a config.ign via an appended
|
||||
# initrd, put it in the right place.
|
||||
copy_file_if_exists "/config.ign" "${destination}/user.ign"
|
||||
else
|
||||
# We will support a user embedded config in the boot partition
|
||||
# under $bootmnt/ignition/config.ign. Note that we mount /boot
|
||||
# but we don't unmount boot because we are run in a systemd unit
|
||||
# with MountFlags=slave so it is unmounted for us.
|
||||
bootmnt=/mnt/boot_partition
|
||||
mkdir -p $bootmnt
|
||||
# mount as read-only since we don't strictly need write access and we may be
|
||||
# running alongside other code that also has it mounted ro
|
||||
mount -o ro /dev/disk/by-label/boot $bootmnt
|
||||
copy_file_if_exists "${bootmnt}/ignition/config.ign" "${destination}/user.ign"
|
||||
fi
|
@ -0,0 +1,19 @@
|
||||
[Unit]
|
||||
Description=CoreOS Ensure Unique Boot Filesystem
|
||||
ConditionPathExists=/etc/initrd-release
|
||||
OnFailure=emergency.target
|
||||
OnFailureJobMode=isolate
|
||||
|
||||
# That's a weak dependency, so service won't fail if boot dissaperears
|
||||
Wants=dev-disk-by\x2dlabel-boot.device
|
||||
After=dev-disk-by\x2dlabel-boot.device
|
||||
|
||||
# Start after ignition has finished with disks but before mounting them
|
||||
After=ignition-disks.service
|
||||
Before=ignition-mount.service
|
||||
Before=ignition-ostree-uuid-root.service
|
||||
|
||||
[Service]
|
||||
Type=oneshot
|
||||
RemainAfterExit=yes
|
||||
ExecStart=/usr/bin/rdcore verify-unique-fs-label --rereadpt boot
|
@ -0,0 +1,23 @@
|
||||
[Unit]
|
||||
Description=CoreOS Kernel Arguments Reboot
|
||||
ConditionPathExists=/etc/initrd-release
|
||||
ConditionPathExists=/run/coreos-kargs-reboot
|
||||
DefaultDependencies=false
|
||||
Before=ignition-complete.target
|
||||
|
||||
# This runs after ignition-kargs & before ignition-disks so that it can optionally reboot
|
||||
# if kargs were modified via Ignition. This is done in a two-stage fashion so that other
|
||||
# mechanisms which may want to reboot (e.x. FIPS) can also hook in here and only reboot
|
||||
# once from the initrd.
|
||||
After=ignition-kargs.service
|
||||
Before=ignition-disks.service
|
||||
|
||||
OnFailure=emergency.target
|
||||
OnFailureJobMode=isolate
|
||||
|
||||
[Service]
|
||||
Type=oneshot
|
||||
RemainAfterExit=yes
|
||||
# --force causes a rapid reboot. Without it, systemd continues running
|
||||
# Ignition stages in parallel with shutting down.
|
||||
ExecStart=/usr/bin/systemctl reboot --force
|
12
overlay.d/05core/usr/lib/dracut/modules.d/35coreos-ignition/coreos-kargs.sh
Executable file
12
overlay.d/05core/usr/lib/dracut/modules.d/35coreos-ignition/coreos-kargs.sh
Executable file
@ -0,0 +1,12 @@
|
||||
#!/bin/bash
|
||||
set -euo pipefail
|
||||
|
||||
if is-live-image; then
|
||||
/usr/bin/rdcore kargs --current --create-if-changed /run/coreos-kargs-changed "$@"
|
||||
if [ -e /run/coreos-kargs-changed ]; then
|
||||
echo "Need to modify kernel arguments, but cannot affect live system." >&2
|
||||
exit 1
|
||||
fi
|
||||
else
|
||||
/usr/bin/rdcore kargs --boot-device /dev/disk/by-label/boot --create-if-changed /run/coreos-kargs-reboot "$@"
|
||||
fi
|
@ -0,0 +1,17 @@
|
||||
# This unit will run late in the initrd process after the Ignition files
|
||||
# stage has completed successfully so that we may validate ignition changes
|
||||
|
||||
[Unit]
|
||||
Description=CoreOS Post Ignition Checks
|
||||
ConditionPathExists=/usr/lib/initrd-release
|
||||
OnFailure=emergency.target
|
||||
OnFailureJobMode=isolate
|
||||
|
||||
# Start after Ignition has finished creating files and before ignition umount
|
||||
After=ignition-files.service
|
||||
Before=ignition-complete.target
|
||||
|
||||
[Service]
|
||||
Type=oneshot
|
||||
ExecStart=/usr/sbin/coreos-post-ignition-checks
|
||||
RemainAfterExit=yes
|
@ -0,0 +1,18 @@
|
||||
#!/bin/bash
|
||||
# See coreos-post-ignition-checks.service for more information about this script
|
||||
set -euo pipefail
|
||||
|
||||
# Verify that GRUB password directives are only used when GRUB is being used
|
||||
arch=$(uname -p)
|
||||
# Butane sugar will tell ignition to mount /boot to /sysroot/boot. We can simply check if
|
||||
# the file exists to see whether the check needs to be performed.
|
||||
# It is possible that the user creates a config, which will mount /boot at a different path
|
||||
# but that case is not officially supported.
|
||||
if [ -f /sysroot/boot/grub2/user.cfg ]; then
|
||||
# s390x does not use GRUB, ppcle64 uses petitboot with a GRUB config parser which does not support passwords
|
||||
# So in both these cases, GRUB password is not supported
|
||||
if grep -q password_pbkdf2 /sysroot/boot/grub2/user.cfg && [[ "$arch" =~ ^(s390x|ppc64le)$ ]]; then
|
||||
echo "Ignition config provisioned a GRUB password, which is not supported on $arch"
|
||||
exit 1
|
||||
fi
|
||||
fi
|
@ -0,0 +1,38 @@
|
||||
# Clean up the initramfs networking on first boot
|
||||
# so the real network is being brought up
|
||||
# https://github.com/coreos/fedora-coreos-tracker/issues/394#issuecomment-599721763
|
||||
|
||||
[Unit]
|
||||
Description=CoreOS Tear Down Initramfs
|
||||
DefaultDependencies=false
|
||||
|
||||
# We want to run the teardown after all other Ignition stages
|
||||
# have run because some platforms (like Packet) do remote status
|
||||
# reporting for each Ignition stage. Since we are tearing down
|
||||
# the networking using an ExecStop we need to make sure we run
|
||||
# the ExecStop *after* any other ignition*.service unit's ExecStop.
|
||||
# The only other one right now is ignition-mount that has an ExecStop
|
||||
# for doing an unmount. Since the ordering for ExecStop is the
|
||||
# opposite of ExecStart we need to use `Before=ignition-mount.service`.
|
||||
# https://github.com/coreos/fedora-coreos-tracker/issues/440
|
||||
Before=ignition-mount.service
|
||||
Before=ignition-complete.target
|
||||
|
||||
# Make sure ExecStop= runs before we switch root
|
||||
Conflicts=initrd-switch-root.target umount.target
|
||||
Before=initrd-switch-root.target
|
||||
|
||||
OnFailure=emergency.target
|
||||
OnFailureJobMode=isolate
|
||||
|
||||
# If we are already heading towards emergency.target
|
||||
# then don't try to stop this unit because it will fail
|
||||
# when trying to access files in /sysroot/etc/. The failure
|
||||
# is mostly harmless but having the extra error messages
|
||||
# leads us away from the original problem.
|
||||
IgnoreOnIsolate=true
|
||||
|
||||
[Service]
|
||||
Type=oneshot
|
||||
RemainAfterExit=yes
|
||||
ExecStop=/usr/sbin/coreos-teardown-initramfs
|
@ -0,0 +1,240 @@
|
||||
#!/bin/bash
|
||||
# -*- mode: shell-script; indent-tabs-mode: nil; sh-basic-offset: 4; -*-
|
||||
# ex: ts=8 sw=4 sts=4 et filetype=sh
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
# Load dracut libraries. Using getargbool() and getargs() from
|
||||
# dracut-lib and ip_to_var() from net-lib
|
||||
load_dracut_libs() {
|
||||
# dracut is not friendly to set -eu
|
||||
set +euo pipefail
|
||||
type getargbool &>/dev/null || . /lib/dracut-lib.sh
|
||||
type ip_to_var &>/dev/null || . /lib/net-lib.sh
|
||||
set -euo pipefail
|
||||
}
|
||||
|
||||
dracut_func() {
|
||||
# dracut is not friendly to set -eu
|
||||
set +euo pipefail
|
||||
"$@"; local rc=$?
|
||||
set -euo pipefail
|
||||
return $rc
|
||||
}
|
||||
|
||||
# Get the BOOTIF and rd.bootif kernel arguments from
|
||||
# the kernel command line.
|
||||
get_bootif_kargs() {
|
||||
bootif_kargs=""
|
||||
bootif_karg=$(dracut_func getarg BOOTIF)
|
||||
if [ ! -z "$bootif_karg" ]; then
|
||||
bootif_kargs+="BOOTIF=${bootif_karg}"
|
||||
fi
|
||||
rdbootif_karg=$(dracut_func getarg rd.bootif)
|
||||
if [ ! -z "$rdbootif_karg" ]; then
|
||||
bootif_kargs+=" rd.bootif=${rdbootif_karg}"
|
||||
fi
|
||||
echo $bootif_kargs
|
||||
}
|
||||
|
||||
# Determine if the generated NM connection profiles match the default
|
||||
# that would be given to us if the user had provided no additional
|
||||
# configuration. i.e. did the user give us any network configuration
|
||||
# other than the default? We determine this by comparing the generated
|
||||
# output of nm-initrd-generator with a new run of nm-initrd-generator.
|
||||
# If it matches then it was the default, if not then the user provided
|
||||
# something extra.
|
||||
are_default_NM_configs() {
|
||||
# pick up our CoreOS default networking kargs from the afterburn dropin
|
||||
DEFAULT_KARGS_FILE=/usr/lib/systemd/system/afterburn-network-kargs.service.d/50-afterburn-network-kargs-default.conf
|
||||
source <(grep -o 'AFTERBURN_NETWORK_KARGS_DEFAULT=.*' $DEFAULT_KARGS_FILE)
|
||||
# Also pick up BOOTIF/rd.bootif kargs and apply them here.
|
||||
# See https://github.com/coreos/fedora-coreos-tracker/issues/1048
|
||||
BOOTIF_KARGS=$(get_bootif_kargs)
|
||||
# Make two dirs for storing files to use in the comparison
|
||||
mkdir -p /run/coreos-teardown-initramfs/connections-compare-{1,2}
|
||||
# Make another that's just a throwaway for the initrd-data-dir
|
||||
mkdir -p /run/coreos-teardown-initramfs/initrd-data-dir
|
||||
# Copy over the previously generated connection(s) profiles
|
||||
cp /run/NetworkManager/system-connections/* \
|
||||
/run/coreos-teardown-initramfs/connections-compare-1/
|
||||
# Do a new run with the default input
|
||||
/usr/libexec/nm-initrd-generator \
|
||||
-c /run/coreos-teardown-initramfs/connections-compare-2 \
|
||||
-i /run/coreos-teardown-initramfs/initrd-data-dir \
|
||||
-- $AFTERBURN_NETWORK_KARGS_DEFAULT $BOOTIF_KARGS
|
||||
# remove unique identifiers from the files (so our diff can work)
|
||||
sed -i '/^uuid=/d' /run/coreos-teardown-initramfs/connections-compare-{1,2}/*
|
||||
# currently the output will differ based on whether rd.neednet=1
|
||||
# was part of the kargs. Let's ignore the single difference (wait-device-timeout)
|
||||
sed -i '/^wait-device-timeout=/d' /run/coreos-teardown-initramfs/connections-compare-{1,2}/*
|
||||
if diff -r -q /run/coreos-teardown-initramfs/connections-compare-{1,2}/; then
|
||||
rc=0 # They are the default configs
|
||||
else
|
||||
rc=1 # They are not the defaults, user must have added configuration
|
||||
fi
|
||||
rm -rf /run/coreos-teardown-initramfs
|
||||
return $rc
|
||||
}
|
||||
|
||||
# Propagate initramfs networking if desired. The policy here is:
|
||||
#
|
||||
# - If a networking configuration was provided before this point
|
||||
# (most likely via Ignition) and exists in the real root then
|
||||
# we do nothing and don't propagate any initramfs networking.
|
||||
# - If a user did not provide any networking configuration
|
||||
# then we'll propagate the initramfs networking configuration
|
||||
# into the real root, but only if it's different than the NM
|
||||
# defaults (trying dhcp/dhcp6 on everything). If it's just the
|
||||
# defaults then we want to avoid a slight behavior diff between
|
||||
# propagating configs and just booting with no configuration. See
|
||||
# https://github.com/coreos/fedora-coreos-tracker/issues/696
|
||||
#
|
||||
# See https://github.com/coreos/fedora-coreos-tracker/issues/394#issuecomment-599721173
|
||||
propagate_initramfs_networking() {
|
||||
# Check for any real root config in the two locations where a user could have
|
||||
# provided network configuration. On FCOS we only support keyfiles, but on RHCOS
|
||||
# we support keyfiles and ifcfg. We also need to ignore readme-ifcfg-rh.txt
|
||||
# which is a cosmetic file added in
|
||||
# https://gitlab.freedesktop.org/NetworkManager/NetworkManager/-/commit/96d7362
|
||||
if [ -n "$(ls -A /sysroot/etc/NetworkManager/system-connections/)" -o \
|
||||
-n "$(ls -A -I readme-ifcfg-rh.txt /sysroot/etc/sysconfig/network-scripts/)" ]; then
|
||||
echo "info: networking config is defined in the real root"
|
||||
realrootconfig=1
|
||||
else
|
||||
echo "info: no networking config is defined in the real root"
|
||||
realrootconfig=0
|
||||
fi
|
||||
|
||||
# Did the user tell us to force initramfs networking config
|
||||
# propagation even if real root networking config exists?
|
||||
# Hopefully we only need this in rare circumstances.
|
||||
# https://github.com/coreos/fedora-coreos-tracker/issues/853
|
||||
forcepropagate=0
|
||||
if dracut_func getargbool 0 'coreos.force_persist_ip'; then
|
||||
forcepropagate=1
|
||||
echo "info: coreos.force_persist_ip detected: will force network config propagation"
|
||||
fi
|
||||
|
||||
if [ $realrootconfig == 1 -a $forcepropagate == 0 ]; then
|
||||
echo "info: will not attempt to propagate initramfs networking"
|
||||
fi
|
||||
|
||||
if [ $realrootconfig == 0 -o $forcepropagate == 1 ]; then
|
||||
if [ -n "$(ls -A /run/NetworkManager/system-connections/)" ]; then
|
||||
if are_default_NM_configs; then
|
||||
echo "info: skipping propagation of default networking configs"
|
||||
else
|
||||
echo "info: propagating initramfs networking config to the real root"
|
||||
cp -v /run/NetworkManager/system-connections/* /sysroot/etc/NetworkManager/system-connections/
|
||||
coreos-relabel /etc/NetworkManager/system-connections/
|
||||
fi
|
||||
else
|
||||
echo "info: no initramfs networking information to propagate"
|
||||
fi
|
||||
fi
|
||||
}
|
||||
|
||||
# Propagate the ip= karg hostname if desired. The policy here is:
|
||||
#
|
||||
# - IF a hostname was detected in ip= kargs by NetworkManager
|
||||
# - AND no hostname was set via Ignition (realroot `/etc/hostname`)
|
||||
# - THEN we make the hostname detected by NM apply permanently
|
||||
# by writing it into `/etc/hostname`
|
||||
#
|
||||
propagate_initramfs_hostname() {
|
||||
if [ -e '/sysroot/etc/hostname' ]; then
|
||||
echo "info: hostname is defined in the real root"
|
||||
echo "info: will not attempt to propagate initramfs hostname"
|
||||
return 0
|
||||
fi
|
||||
|
||||
# If any hostname was provided NetworkManager will write it out to
|
||||
# /run/NetworkManager/initrd/hostname. See
|
||||
# https://gitlab.freedesktop.org/NetworkManager/NetworkManager/-/merge_requests/481
|
||||
if [ -s /run/NetworkManager/initrd/hostname ]; then
|
||||
hostname=$(</run/NetworkManager/initrd/hostname)
|
||||
echo "info: propagating initramfs hostname (${hostname}) to the real root"
|
||||
echo $hostname > /sysroot/etc/hostname
|
||||
coreos-relabel /etc/hostname
|
||||
else
|
||||
echo "info: no initramfs hostname information to propagate"
|
||||
fi
|
||||
}
|
||||
|
||||
down_interface() {
|
||||
echo "info: taking down network device: $1"
|
||||
# On recommendation from the NM team let's try to delete the device
|
||||
# first and if that doesn't work then set it to down and flush any
|
||||
# associated addresses. Deleting virtual devices (bonds, teams, bridges,
|
||||
# ip-tunnels, etc) will clean up any associated kernel resources. A real
|
||||
# device can't be deleted so that will fail and we'll fallback to setting
|
||||
# it down and flushing addresses.
|
||||
if ! ip link delete $1; then
|
||||
ip link set $1 down
|
||||
ip addr flush dev $1
|
||||
fi
|
||||
}
|
||||
|
||||
# Iterate through the interfaces in the machine and take them down.
|
||||
# Note that in the futre we would like to possibly use `nmcli` networking off`
|
||||
# for this. See the following two comments for details:
|
||||
# https://github.com/coreos/fedora-coreos-tracker/issues/394#issuecomment-599721763
|
||||
# https://github.com/coreos/fedora-coreos-tracker/issues/394#issuecomment-599746049
|
||||
down_interfaces() {
|
||||
if ! [ -z "$(ls /sys/class/net)" ]; then
|
||||
for f in /sys/class/net/*; do
|
||||
interface=$(basename "$f")
|
||||
# The `bonding_masters` entry is not a true interface and thus
|
||||
# cannot be taken down. Also skip local loopback
|
||||
case "$interface" in
|
||||
"lo" | "bonding_masters")
|
||||
continue
|
||||
;;
|
||||
esac
|
||||
# When we start taking down devices some other devices can
|
||||
# start to disappear (for example vlan on top of interface).
|
||||
# If the device we're about to take down has disappeared
|
||||
# since the start of this loop then skip taking it down.
|
||||
if [ ! -e "$f" ]; then
|
||||
echo "info: skipping teardown of ${interface}; no longer exists."
|
||||
continue
|
||||
fi
|
||||
down_interface $interface
|
||||
done
|
||||
fi
|
||||
}
|
||||
|
||||
main() {
|
||||
# Load libraries from dracut
|
||||
load_dracut_libs
|
||||
|
||||
# Take down all interfaces set up in the initramfs
|
||||
down_interfaces
|
||||
|
||||
# Clean up all routing
|
||||
echo "info: flushing all routing"
|
||||
ip route flush table main
|
||||
ip route flush cache
|
||||
|
||||
# Hopefully our logic is sound enough that this is never needed, but
|
||||
# user's can explicitly disable initramfs network/hostname propagation
|
||||
# with the coreos.no_persist_ip karg.
|
||||
if dracut_func getargbool 0 'coreos.no_persist_ip'; then
|
||||
echo "info: coreos.no_persist_ip karg detected"
|
||||
echo "info: skipping propagating initramfs settings"
|
||||
else
|
||||
propagate_initramfs_hostname
|
||||
propagate_initramfs_networking
|
||||
fi
|
||||
|
||||
# Now that the configuration has been propagated (or not)
|
||||
# clean it up so that no information from outside of the
|
||||
# real root is passed on to NetworkManager in the real root
|
||||
rm -rf /run/NetworkManager/
|
||||
|
||||
rm -f /run/udev/rules.d/80-coreos-boot-disk.rules
|
||||
rm -f /dev/disk/by-id/coreos-boot-disk
|
||||
}
|
||||
|
||||
main
|
@ -0,0 +1,22 @@
|
||||
[Unit]
|
||||
Description=Ensure filesystem labeled `boot` is unique
|
||||
ConditionPathExists=/etc/initrd-release
|
||||
DefaultDependencies=no
|
||||
Before=ignition-diskful.target
|
||||
Wants=systemd-udevd.service
|
||||
After=systemd-udevd.service
|
||||
# And since the boot device may be on multipath; optionally wait for it to
|
||||
# appear via the dynamic target.
|
||||
After=coreos-multipath-wait.target
|
||||
Requires=dev-disk-by\x2dlabel-boot.device
|
||||
After=dev-disk-by\x2dlabel-boot.device
|
||||
# Run before services that modify/use `boot` partition
|
||||
Before=coreos-gpt-setup.service coreos-boot-edit.service
|
||||
|
||||
OnFailure=emergency.target
|
||||
OnFailureJobMode=isolate
|
||||
|
||||
[Service]
|
||||
Type=oneshot
|
||||
RemainAfterExit=yes
|
||||
ExecStart=/usr/bin/rdcore verify-unique-fs-label boot
|
79
overlay.d/05core/usr/lib/dracut/modules.d/35coreos-ignition/module-setup.sh
Executable file
79
overlay.d/05core/usr/lib/dracut/modules.d/35coreos-ignition/module-setup.sh
Executable file
@ -0,0 +1,79 @@
|
||||
#!/bin/bash
|
||||
# -*- mode: shell-script; indent-tabs-mode: nil; sh-basic-offset: 4; -*-
|
||||
# ex: ts=8 sw=4 sts=4 et filetype=sh
|
||||
|
||||
depends() {
|
||||
echo systemd network ignition coreos-live
|
||||
}
|
||||
|
||||
install_ignition_unit() {
|
||||
local unit="$1"; shift
|
||||
local target="${1:-ignition-complete.target}"; shift
|
||||
local instantiated="${1:-$unit}"; shift
|
||||
inst_simple "$moddir/$unit" "$systemdsystemunitdir/$unit"
|
||||
# note we `|| exit 1` here so we error out if e.g. the units are missing
|
||||
# see https://github.com/coreos/fedora-coreos-config/issues/799
|
||||
systemctl -q --root="$initdir" add-requires "$target" "$instantiated" || exit 1
|
||||
}
|
||||
|
||||
install() {
|
||||
inst_multiple \
|
||||
basename \
|
||||
diff \
|
||||
lsblk \
|
||||
sed \
|
||||
grep \
|
||||
sgdisk \
|
||||
uname
|
||||
|
||||
inst_simple "$moddir/coreos-diskful-generator" \
|
||||
"$systemdutildir/system-generators/coreos-diskful-generator"
|
||||
|
||||
inst_script "$moddir/coreos-gpt-setup.sh" \
|
||||
"/usr/sbin/coreos-gpt-setup"
|
||||
|
||||
# This has to work only on diskful systems during firstboot.
|
||||
# coreos-diskful-generator will create a symlink
|
||||
inst_simple "$moddir/80-coreos-boot-disk.rules" \
|
||||
"/usr/lib/coreos/80-coreos-boot-disk.rules"
|
||||
|
||||
inst_script "$moddir/coreos-disk-contains-fs.sh" \
|
||||
"/usr/lib/udev/coreos-disk-contains-fs"
|
||||
|
||||
inst_script "$moddir/coreos-ignition-setup-user.sh" \
|
||||
"/usr/sbin/coreos-ignition-setup-user"
|
||||
|
||||
inst_script "$moddir/coreos-post-ignition-checks.sh" \
|
||||
"/usr/sbin/coreos-post-ignition-checks"
|
||||
|
||||
install_ignition_unit coreos-post-ignition-checks.service
|
||||
|
||||
# For consistency tear down the network and persist multipath between the initramfs and
|
||||
# real root. See https://github.com/coreos/fedora-coreos-tracker/issues/394#issuecomment-599721763
|
||||
inst_script "$moddir/coreos-teardown-initramfs.sh" \
|
||||
"/usr/sbin/coreos-teardown-initramfs"
|
||||
install_ignition_unit coreos-teardown-initramfs.service
|
||||
|
||||
# units only started when we have a boot disk
|
||||
# path generated by systemd-escape --path /dev/disk/by-label/root
|
||||
install_ignition_unit coreos-gpt-setup.service ignition-diskful.target
|
||||
|
||||
# dracut inst_script doesn't allow overwrites and we are replacing
|
||||
# the default script placed by Ignition
|
||||
binpath="/usr/sbin/ignition-kargs-helper"
|
||||
cp "$moddir/coreos-kargs.sh" "$initdir$binpath"
|
||||
install_ignition_unit coreos-kargs-reboot.service
|
||||
|
||||
inst_script "$moddir/coreos-boot-edit.sh" \
|
||||
"/usr/sbin/coreos-boot-edit"
|
||||
# Only start when the system has disks since we are editing /boot.
|
||||
install_ignition_unit "coreos-boot-edit.service" \
|
||||
"ignition-diskful.target"
|
||||
|
||||
install_ignition_unit coreos-ignition-unique-boot.service ignition-diskful.target
|
||||
install_ignition_unit coreos-unique-boot.service ignition-diskful.target
|
||||
install_ignition_unit coreos-ignition-setup-user.service
|
||||
|
||||
# IBM Secure Execution. Ignition config for reencryption of / and /boot
|
||||
inst_simple "$moddir/01-secex.ign" /usr/lib/coreos/01-secex.ign
|
||||
}
|
@ -0,0 +1,18 @@
|
||||
# SSSD caches passwd data from /etc in /var. If we have a persistent /var
|
||||
# but not a persistent /etc, ignition-files.service can think a user
|
||||
# already exists when in fact it needs to be (re-)created. Clear the
|
||||
# cache to avoid this.
|
||||
|
||||
[Unit]
|
||||
Description=Clear SSSD NSS cache in persistent /var
|
||||
DefaultDependencies=false
|
||||
ConditionPathExists=/run/ostree-live
|
||||
ConditionPathExists=/sysroot/var/lib/sss/mc
|
||||
|
||||
After=ignition-mount.service
|
||||
Before=ignition-files.service
|
||||
|
||||
[Service]
|
||||
Type=oneshot
|
||||
RemainAfterExit=yes
|
||||
ExecStart=/usr/bin/rm -r /sysroot/var/lib/sss/mc
|
@ -0,0 +1,24 @@
|
||||
# If the user specified a persistent /var, ideally it'd just be mounted
|
||||
# overtop of our tmpfs /var and everything would be fine. That works
|
||||
# fine in the initramfs, where ignition-mount handles the mounting.
|
||||
# But in the real root, the user's mount unit is ignored by systemd,
|
||||
# since there's already a filesystem mounted on /var. To fix this, we
|
||||
# notice that the user wants to mount /var, and unmount our tmpfs /var
|
||||
# before switching roots.
|
||||
|
||||
[Unit]
|
||||
Description=Unmount live /var if persistent /var is configured
|
||||
DefaultDependencies=false
|
||||
ConditionPathExists=/run/ostree-live
|
||||
ConditionPathExists=|/sysroot/etc/systemd/system/var.mount
|
||||
ConditionPathExists=|/sysroot/etc/fstab
|
||||
Before=initrd-switch-root.target
|
||||
|
||||
# Run after Ignition mounts are unmounted, since the Ignition config
|
||||
# presumably mounted overtop /sysroot/var
|
||||
After=ignition-mount.service
|
||||
|
||||
[Service]
|
||||
Type=oneshot
|
||||
RemainAfterExit=yes
|
||||
ExecStart=/usr/sbin/coreos-live-unmount-tmpfs-var
|
@ -0,0 +1,33 @@
|
||||
#!/bin/bash
|
||||
# If the user specified a persistent /var, ideally it'd just be mounted
|
||||
# overtop of our tmpfs /var and everything would be fine. That works
|
||||
# fine in the initramfs, where ignition-mount handles the mounting.
|
||||
# But in the real root, the user's mount unit is ignored by systemd,
|
||||
# since there's already a filesystem mounted on /var. To fix this, we
|
||||
# notice that the user wants to mount /var, and unmount our tmpfs /var
|
||||
# before switching roots.
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
should_unmount() {
|
||||
# Did the user specify a mount unit for /var?
|
||||
if [ -e /sysroot/etc/systemd/system/var.mount ]; then
|
||||
return 0
|
||||
fi
|
||||
|
||||
# Is there an fstab entry for /var?
|
||||
if [ -e /sysroot/etc/fstab ]; then
|
||||
# Uncommented entry with mountpoint on /var, without noauto in options
|
||||
result=$(awk '(! /^\s*#/) && ($2 == "/var") && ($4 !~ /noauto/) {print "found"}' /sysroot/etc/fstab)
|
||||
if [ -n "$result" ]; then
|
||||
return 0
|
||||
fi
|
||||
fi
|
||||
|
||||
return 1
|
||||
}
|
||||
|
||||
if should_unmount; then
|
||||
echo "Unmounting /sysroot/var"
|
||||
umount /sysroot/var
|
||||
fi
|
@ -0,0 +1,17 @@
|
||||
[Unit]
|
||||
Description=Persist osmet files (ISO)
|
||||
DefaultDependencies=false
|
||||
ConditionPathExists=/run/ostree-live
|
||||
ConditionKernelCommandLine=coreos.liveiso
|
||||
RequiresMountsFor=/run/media/iso
|
||||
# on el8, the ISO is mounted by our own systemd unit
|
||||
After=run-media-iso-mount.service
|
||||
Before=initrd-switch-root.target
|
||||
|
||||
[Service]
|
||||
Type=oneshot
|
||||
RemainAfterExit=yes
|
||||
ExecStart=/usr/bin/mkdir -p /run/coreos-installer/osmet
|
||||
# bsdtar reads cpio archives, and unlike cpio(1L), knows how to seek over
|
||||
# members it isn't reading
|
||||
ExecStart=/usr/bin/bsdtar -x -C /run/coreos-installer/osmet -f /run/media/iso/images/pxeboot/rootfs.img *.osmet
|
@ -0,0 +1,14 @@
|
||||
[Unit]
|
||||
Description=Persist osmet files (PXE)
|
||||
DefaultDependencies=false
|
||||
ConditionPathExists=/run/ostree-live
|
||||
ConditionKernelCommandLine=!coreos.liveiso
|
||||
# Downloads and unpacks the osmet files if not already appended
|
||||
After=coreos-livepxe-rootfs.service
|
||||
Before=initrd-switch-root.target
|
||||
|
||||
[Service]
|
||||
Type=oneshot
|
||||
RemainAfterExit=yes
|
||||
ExecStart=/usr/bin/mkdir -p /run/coreos-installer/osmet
|
||||
ExecStart=/usr/bin/sh -c "if ls /*.osmet &>/dev/null; then cp /*.osmet /run/coreos-installer/osmet; fi"
|
@ -0,0 +1,21 @@
|
||||
[Unit]
|
||||
Description=Acquire live PXE rootfs image
|
||||
DefaultDependencies=false
|
||||
ConditionPathExists=/usr/lib/initrd-release
|
||||
ConditionPathExists=/run/ostree-live
|
||||
ConditionKernelCommandLine=!coreos.liveiso
|
||||
|
||||
After=basic.target
|
||||
# Network is enabled here
|
||||
After=nm-run.service
|
||||
# compat: remove when everyone is on dracut 053+
|
||||
After=dracut-initqueue.service
|
||||
|
||||
# If we fail, the boot will fail. Be explicit about it.
|
||||
OnFailure=emergency.target
|
||||
OnFailureJobMode=isolate
|
||||
|
||||
[Service]
|
||||
Type=oneshot
|
||||
RemainAfterExit=yes
|
||||
ExecStart=/usr/sbin/coreos-livepxe-rootfs
|
@ -0,0 +1,70 @@
|
||||
#!/bin/bash
|
||||
# Ensure that a PXE-booted system has a valid rootfs.
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
# Get rootfs_url karg
|
||||
set +euo pipefail
|
||||
. /usr/lib/dracut-lib.sh
|
||||
rootfs_url=$(getarg coreos.live.rootfs_url=)
|
||||
set -euo pipefail
|
||||
|
||||
if [[ -f /etc/coreos-live-rootfs ]]; then
|
||||
# rootfs image was injected via PXE. Verify that the initramfs and
|
||||
# rootfs versions match.
|
||||
initramfs_ver=$(cat /etc/coreos-live-initramfs)
|
||||
rootfs_ver=$(cat /etc/coreos-live-rootfs)
|
||||
if [[ $initramfs_ver != $rootfs_ver ]]; then
|
||||
echo "Found initramfs version $initramfs_ver but rootfs version $rootfs_ver." >&2
|
||||
echo "Please fix your PXE configuration." >&2
|
||||
exit 1
|
||||
fi
|
||||
elif [[ -n "${rootfs_url}" ]]; then
|
||||
# rootfs URL was provided as karg. Fetch image, check its hash, and
|
||||
# unpack it.
|
||||
echo "Fetching rootfs image from ${rootfs_url}..."
|
||||
if [[ ${rootfs_url} != http:* && ${rootfs_url} != https:* && ${rootfs_url} != tftp:* ]]; then
|
||||
# Don't commit to supporting protocols we might not want to expose in
|
||||
# the long term.
|
||||
echo "Unsupported scheme for image specified by:" >&2
|
||||
echo "coreos.live.rootfs_url=${rootfs_url}" >&2
|
||||
echo "Only HTTP, HTTPS, and TFTP are supported. Please fix your PXE configuration." >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# First, reach out to the server to verify connectivity before
|
||||
# trying to download and pipe content through other programs.
|
||||
# Doing this allows us to retry all errors (including transient
|
||||
# "no route to host" errors during startup). Note we can't use
|
||||
# curl's --retry-all-errors here because it's not in el8's curl yet.
|
||||
# We retry forever, matching Ignition's semantics.
|
||||
curl_common_args="--silent --show-error --insecure --location"
|
||||
while ! curl --head $curl_common_args "${rootfs_url}" >/dev/null; do
|
||||
echo "Couldn't establish connectivity with the server specified by:" >&2
|
||||
echo "coreos.live.rootfs_url=${rootfs_url}" >&2
|
||||
echo "Retrying in 5s..." >&2
|
||||
sleep 5
|
||||
done
|
||||
|
||||
# We don't need to verify TLS certificates because we're checking the
|
||||
# image hash.
|
||||
# bsdtar can read cpio archives and we already depend on it for
|
||||
# coreos-liveiso-persist-osmet.service, so use it instead of cpio.
|
||||
# We shouldn't need a --retry here since we've just successfully HEADed the
|
||||
# file, but let's add one just to be safe (e.g. if the connection just went
|
||||
# online and flickers or something).
|
||||
if ! curl $curl_common_args --retry 5 "${rootfs_url}" | \
|
||||
rdcore stream-hash /etc/coreos-live-want-rootfs | \
|
||||
bsdtar -xf - -C / ; then
|
||||
echo "Couldn't fetch, verify, and unpack image specified by:" >&2
|
||||
echo "coreos.live.rootfs_url=${rootfs_url}" >&2
|
||||
echo "Check that the URL is correct and that the rootfs version matches the initramfs." >&2
|
||||
exit 1
|
||||
fi
|
||||
else
|
||||
# Nothing. Fail.
|
||||
echo "No rootfs image found. Modify your PXE configuration to add the rootfs" >&2
|
||||
echo "image as a second initrd, or use the coreos.live.rootfs_url kernel parameter" >&2
|
||||
echo "to specify an HTTP or HTTPS URL to the rootfs." >&2
|
||||
exit 1
|
||||
fi
|
6
overlay.d/05core/usr/lib/dracut/modules.d/35coreos-live/is-live-image.sh
Executable file
6
overlay.d/05core/usr/lib/dracut/modules.d/35coreos-live/is-live-image.sh
Executable file
@ -0,0 +1,6 @@
|
||||
#!/bin/sh
|
||||
# Script invoked by ignition-dracut generator to detect whether this is a
|
||||
# live system without a root device. We can't test for /run/ostree-live
|
||||
# because it's created by a generator.
|
||||
# This file is created by coreos-assembler buildextend-live.
|
||||
test -f /etc/coreos-live-initramfs
|
271
overlay.d/05core/usr/lib/dracut/modules.d/35coreos-live/live-generator
Executable file
271
overlay.d/05core/usr/lib/dracut/modules.d/35coreos-live/live-generator
Executable file
@ -0,0 +1,271 @@
|
||||
#!/bin/bash
|
||||
# -*- mode: shell-script; indent-tabs-mode: nil; sh-basic-offset: 4; -*-
|
||||
# ex: ts=8 sw=4 sts=4 et filetype=sh
|
||||
|
||||
# Generators don't have logging right now
|
||||
# https://github.com/systemd/systemd/issues/15638
|
||||
exec 1>/dev/kmsg; exec 2>&1
|
||||
|
||||
command -v getarg >/dev/null || . /usr/lib/dracut-lib.sh
|
||||
|
||||
set -e
|
||||
|
||||
UNIT_DIR="${1:-/tmp}"
|
||||
|
||||
add_requires() {
|
||||
local name="$1"; shift
|
||||
local target="$1"; shift
|
||||
local requires_dir="${UNIT_DIR}/${target}.requires"
|
||||
mkdir -p "${requires_dir}"
|
||||
ln -sf "../${name}" "${requires_dir}/${name}"
|
||||
}
|
||||
|
||||
if ! is-live-image; then
|
||||
exit 0
|
||||
fi
|
||||
|
||||
# Create stamp file that everything else should use to detect a live boot
|
||||
> /run/ostree-live
|
||||
|
||||
add_requires sysroot.mount initrd-root-fs.target
|
||||
add_requires sysroot-etc.mount initrd-root-fs.target
|
||||
add_requires sysroot-var.mount initrd-root-fs.target
|
||||
|
||||
mkdir -p "${UNIT_DIR}/ostree-prepare-root.service.d"
|
||||
cat > "${UNIT_DIR}/ostree-prepare-root.service.d/10-live.conf" <<EOF
|
||||
# With live PXE there's no ostree= argument on the kernel command line, so
|
||||
# we need to find the tree path and pass it to ostree-prepare-root. But
|
||||
# ostree-prepare-root only knows how to read the path from
|
||||
# /proc/cmdline, so we need to synthesize the proper karg and bind-mount
|
||||
# it over /proc/cmdline.
|
||||
# https://github.com/ostreedev/ostree/issues/1920
|
||||
|
||||
[Unit]
|
||||
# The base unit conditions on the ostree karg, which won't exist until
|
||||
# ExecStartPre runs
|
||||
ConditionKernelCommandLine=
|
||||
|
||||
[Service]
|
||||
ExecStartPre=/usr/sbin/ostree-cmdline start
|
||||
ExecStartPost=/usr/sbin/ostree-cmdline stop
|
||||
EOF
|
||||
|
||||
isoroot=$(getarg coreos.liveiso= ||:)
|
||||
is_rhcos8() {
|
||||
# Unfortunately we can't rely on /etc/os-release since el8 doesn't seem to
|
||||
# have https://github.com/dracutdevs/dracut/pull/655.
|
||||
[[ "${isoroot}" == rhcos-* ]] && [[ $(uname -r) == *.el8* ]]
|
||||
}
|
||||
|
||||
if [ -z "${isoroot}" ]; then
|
||||
# In this case, the rootfs is already unpacked into the initrd, or we need
|
||||
# to retrieve it
|
||||
cat >"${UNIT_DIR}/sysroot.mount" <<EOF
|
||||
# Automatically generated by live-generator
|
||||
|
||||
[Unit]
|
||||
DefaultDependencies=false
|
||||
# Verifies that we have the right root.squashfs, or downloads it if needed
|
||||
After=coreos-livepxe-rootfs.service
|
||||
Before=initrd-root-fs.target
|
||||
|
||||
[Mount]
|
||||
What=/root.squashfs
|
||||
Where=/sysroot
|
||||
Type=squashfs
|
||||
Options=loop
|
||||
EOF
|
||||
else
|
||||
# And in this case, it's on the ISO
|
||||
mkdir -p /run/media/iso
|
||||
isosrc=dev/disk/by-label/${isoroot}
|
||||
isosrc_escaped=$(systemd-escape -p --suffix=device "${isosrc}")
|
||||
initrd_rootdev_target_d="${UNIT_DIR}"/initrd-root-device.target.d
|
||||
mkdir -p "${initrd_rootdev_target_d}"
|
||||
cat > "${initrd_rootdev_target_d}/50-root-device.conf" <<EOF
|
||||
[Unit]
|
||||
After=${isosrc_escaped}
|
||||
Requires=${isosrc_escaped}
|
||||
EOF
|
||||
# Temporary hack for rhel8, where our mount unit can race with udev's
|
||||
# cdrom_id using open(O_EXCL). See:
|
||||
# https://github.com/coreos/fedora-coreos-config/pull/1986#pullrequestreview-1120840529
|
||||
# https://issues.redhat.com/browse/OCPBUGS-1505
|
||||
if is_rhcos8; then
|
||||
cat >"${UNIT_DIR}/run-media-iso-mount.service" <<EOF
|
||||
# Automatically generated by live-generator
|
||||
|
||||
[Unit]
|
||||
DefaultDependencies=false
|
||||
# Note that bootup(7) implies that initrd-root-device is After=basic.target
|
||||
# but that appears to not be the case. We explicitly order after sysinit.target
|
||||
After=sysinit.target
|
||||
After=initrd-root-device.target
|
||||
Before=initrd-root-fs.target
|
||||
|
||||
[Service]
|
||||
Type=oneshot
|
||||
RemainAfterExit=yes
|
||||
# See https://issues.redhat.com/browse/OCPBUGS-1505
|
||||
# and https://github.com/coreos/fedora-coreos-config/pull/411
|
||||
ExecStart=/bin/sh -c 'for x in {0..60}; do if mount -o ro -t iso9660 /${isosrc} /run/media/iso; then break; fi; sleep 1; done'
|
||||
EOF
|
||||
add_requires run-media-iso-mount.service initrd-root-fs.target
|
||||
else
|
||||
cat >"${UNIT_DIR}/run-media-iso.mount" <<EOF
|
||||
# Automatically generated by live-generator
|
||||
|
||||
[Unit]
|
||||
DefaultDependencies=false
|
||||
# HACK for https://github.com/coreos/fedora-coreos-config/issues/437
|
||||
Wants=systemd-udev-settle.service
|
||||
# Note that bootup(7) implies that initrd-root-device is After=basic.target
|
||||
# but that appears to not be the case. We explicitly order after sysinit.target
|
||||
After=sysinit.target
|
||||
After=initrd-root-device.target
|
||||
Before=initrd-root-fs.target
|
||||
|
||||
[Mount]
|
||||
What=/${isosrc}
|
||||
Where=/run/media/iso
|
||||
Options=ro
|
||||
Type=iso9660
|
||||
EOF
|
||||
fi
|
||||
|
||||
cat >"${UNIT_DIR}/sysroot.mount" <<EOF
|
||||
# Automatically generated by live-generator
|
||||
|
||||
[Unit]
|
||||
DefaultDependencies=false
|
||||
Before=initrd-root-fs.target
|
||||
RequiresMountsFor=/run/media/iso
|
||||
# on el8, the ISO is mounted by our own systemd unit
|
||||
After=run-media-iso-mount.service
|
||||
|
||||
[Mount]
|
||||
What=/run/media/iso/images/pxeboot/rootfs.img
|
||||
Where=/sysroot
|
||||
Type=squashfs
|
||||
# Offset of the squashfs within the rootfs cpio. Assumes newc format
|
||||
# and that a file named "root.squashfs" is the first member. This offset
|
||||
# is checked by coreos-assembler cmd-buildextend-live at build time.
|
||||
Options=loop,offset=124
|
||||
EOF
|
||||
|
||||
# And one more unit to workaround what we think is a systemd bug.
|
||||
# We've found the system can stall waiting for run-media-iso.mount
|
||||
# and apparently any operation seems to be effective at reviving
|
||||
# the system.
|
||||
# https://github.com/coreos/fedora-coreos-tracker/issues/1233#issuecomment-1238814171
|
||||
cat >"${UNIT_DIR}/workaround-stalled-media-iso-mount.service" <<EOF
|
||||
[Service]
|
||||
Type=simple
|
||||
StandardOutput=journal
|
||||
StandardError=journal
|
||||
ExecStart=bash -c "sleep 10; echo 'warn: tracker issue workaround engaged for https://github.com/coreos/fedora-coreos-tracker/issues/1233'"
|
||||
EOF
|
||||
add_requires workaround-stalled-media-iso-mount.service basic.target
|
||||
fi
|
||||
|
||||
# It turns out that `tmpfs` currently munches all SELinux labels
|
||||
# we set before policy is loaded, so we make an XFS filesystem
|
||||
# loopback mounted that's sized the same as /run.
|
||||
# https://github.com/coreos/fedora-coreos-config/pull/499
|
||||
cat >"${UNIT_DIR}/sysroot-xfs-ephemeral-mkfs.service" <<'EOF'
|
||||
[Unit]
|
||||
DefaultDependencies=false
|
||||
# Let's be sure we have basic devices, but other than that we
|
||||
# can run really early.
|
||||
After=systemd-tmpfiles-setup-dev.service
|
||||
ConditionPathExists=/usr/lib/initrd-release
|
||||
# Something seems to be causing us to rerun?
|
||||
ConditionPathExists=!/run/ephemeral
|
||||
|
||||
[Service]
|
||||
Type=oneshot
|
||||
RemainAfterExit=yes
|
||||
ExecStart=/bin/sh -c 'set -euo pipefail; mem=$$(($$(stat -f -c "%%b * %%s / 1024" /run))) && /bin/truncate -s $${mem}k /run/ephemeral.xfsloop'
|
||||
ExecStart=/sbin/mkfs.xfs /run/ephemeral.xfsloop
|
||||
ExecStart=/bin/mkdir /run/ephemeral
|
||||
EOF
|
||||
add_requires sysroot-xfs-ephemeral-mkfs.service initrd-root-fs.target
|
||||
|
||||
cat >>"${UNIT_DIR}/run-ephemeral.mount" <<EOF
|
||||
[Unit]
|
||||
DefaultDependencies=false
|
||||
Requires=sysroot-xfs-ephemeral-mkfs.service
|
||||
After=sysroot-xfs-ephemeral-mkfs.service
|
||||
[Mount]
|
||||
What=/run/ephemeral.xfsloop
|
||||
Where=/run/ephemeral
|
||||
Type=xfs
|
||||
Options=loop,discard
|
||||
EOF
|
||||
|
||||
cat >"${UNIT_DIR}/sysroot-xfs-ephemeral-setup.service" <<EOF
|
||||
[Unit]
|
||||
DefaultDependencies=false
|
||||
RequiresMountsFor=/run/ephemeral
|
||||
ConditionPathExists=/usr/lib/initrd-release
|
||||
ConditionPathExists=!/run/ephemeral/var
|
||||
# Make sure /sysroot is mounted first, since we're mounting under there
|
||||
Requires=sysroot.mount
|
||||
After=sysroot.mount
|
||||
# And after OSTree has set up the chroot() equivalent
|
||||
After=ostree-prepare-root.service
|
||||
|
||||
[Service]
|
||||
Type=oneshot
|
||||
RemainAfterExit=yes
|
||||
ExecStart=/bin/cp -a /sysroot/etc /run/ephemeral/etc
|
||||
ExecStart=/bin/mkdir /run/ephemeral/var
|
||||
EOF
|
||||
|
||||
common_etcvar_unit() {
|
||||
cat << EOF
|
||||
# Automatically generated by live-generator
|
||||
[Unit]
|
||||
DefaultDependencies=false
|
||||
# Make sure our tmpfs is available
|
||||
Requires=sysroot-xfs-ephemeral-setup.service
|
||||
After=sysroot-xfs-ephemeral-setup.service
|
||||
# We're part of assembling the root fs
|
||||
Before=initrd-root-fs.target
|
||||
EOF
|
||||
}
|
||||
|
||||
common_etcvar_unit > "${UNIT_DIR}/sysroot-etc.mount"
|
||||
cat >>"${UNIT_DIR}/sysroot-etc.mount" <<EOF
|
||||
[Mount]
|
||||
What=/run/ephemeral/etc
|
||||
Where=/sysroot/etc
|
||||
Type=none
|
||||
Options=bind
|
||||
EOF
|
||||
add_requires sysroot-etc.mount initrd-root-fs.target
|
||||
|
||||
common_etcvar_unit >"${UNIT_DIR}/sysroot-var.mount"
|
||||
cat >>"${UNIT_DIR}/sysroot-var.mount" <<EOF
|
||||
[Mount]
|
||||
What=/run/ephemeral/var
|
||||
Where=/sysroot/var
|
||||
Type=none
|
||||
Options=bind
|
||||
EOF
|
||||
add_requires sysroot-var.mount initrd-root-fs.target
|
||||
|
||||
cat >>"${UNIT_DIR}/sysroot-relabel.service" <<EOF
|
||||
[Unit]
|
||||
DefaultDependencies=false
|
||||
RequiresMountsFor=/sysroot/etc /sysroot/var
|
||||
Before=initrd-root-fs.target
|
||||
[Service]
|
||||
Type=oneshot
|
||||
RemainAfterExit=yes
|
||||
# We don't need the full relabeling spam by default for these
|
||||
StandardOutput=null
|
||||
ExecStart=/bin/coreos-relabel /etc
|
||||
ExecStart=/bin/coreos-relabel /var
|
||||
EOF
|
||||
add_requires sysroot-relabel.service initrd-root-fs.target
|
@ -0,0 +1,55 @@
|
||||
depends() {
|
||||
# We need the rdcore binary
|
||||
echo rdcore
|
||||
}
|
||||
|
||||
install_and_enable_unit() {
|
||||
unit="$1"; shift
|
||||
target="$1"; shift
|
||||
inst_simple "$moddir/$unit" "$systemdsystemunitdir/$unit"
|
||||
# note we `|| exit 1` here so we error out if e.g. the units are missing
|
||||
# see https://github.com/coreos/fedora-coreos-config/issues/799
|
||||
systemctl -q --root="$initdir" add-requires "$target" "$unit" || exit 1
|
||||
}
|
||||
|
||||
installkernel() {
|
||||
# we do loopmounts
|
||||
instmods -c loop
|
||||
}
|
||||
|
||||
install() {
|
||||
inst_multiple \
|
||||
bsdtar \
|
||||
curl \
|
||||
truncate
|
||||
|
||||
inst_script "$moddir/is-live-image.sh" \
|
||||
"/usr/bin/is-live-image"
|
||||
|
||||
inst_script "$moddir/ostree-cmdline.sh" \
|
||||
"/usr/sbin/ostree-cmdline"
|
||||
|
||||
inst_simple "$moddir/live-generator" \
|
||||
"$systemdutildir/system-generators/live-generator"
|
||||
|
||||
inst_simple "$moddir/coreos-live-unmount-tmpfs-var.sh" \
|
||||
"/usr/sbin/coreos-live-unmount-tmpfs-var"
|
||||
|
||||
inst_simple "$moddir/coreos-livepxe-rootfs.sh" \
|
||||
"/usr/sbin/coreos-livepxe-rootfs"
|
||||
|
||||
install_and_enable_unit "coreos-live-unmount-tmpfs-var.service" \
|
||||
"initrd-switch-root.target"
|
||||
|
||||
install_and_enable_unit "coreos-livepxe-rootfs.service" \
|
||||
"initrd-root-fs.target"
|
||||
|
||||
install_and_enable_unit "coreos-live-clear-sssd-cache.service" \
|
||||
"ignition-complete.target"
|
||||
|
||||
install_and_enable_unit "coreos-liveiso-persist-osmet.service" \
|
||||
"default.target"
|
||||
|
||||
install_and_enable_unit "coreos-livepxe-persist-osmet.service" \
|
||||
"default.target"
|
||||
}
|
25
overlay.d/05core/usr/lib/dracut/modules.d/35coreos-live/ostree-cmdline.sh
Executable file
25
overlay.d/05core/usr/lib/dracut/modules.d/35coreos-live/ostree-cmdline.sh
Executable file
@ -0,0 +1,25 @@
|
||||
#!/bin/bash
|
||||
# With live PXE there's no ostree= argument on the kernel command line, so
|
||||
# we need to find the tree path and pass it to ostree-prepare-root. But
|
||||
# ostree-prepare-root only knows how to read the path from
|
||||
# /proc/cmdline, so we need to synthesize the proper karg and bind-mount
|
||||
# it over /proc/cmdline.
|
||||
# https://github.com/ostreedev/ostree/issues/1920
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
case "${1:-unset}" in
|
||||
start)
|
||||
treepath="$(echo /sysroot/ostree/boot.1/*/*/0)"
|
||||
echo "$(cat /proc/cmdline) ostree=${treepath#/sysroot}" > /tmp/cmdline
|
||||
mount --bind /tmp/cmdline /proc/cmdline
|
||||
;;
|
||||
stop)
|
||||
umount /proc/cmdline
|
||||
rm /tmp/cmdline
|
||||
;;
|
||||
*)
|
||||
echo "Usage: $0 {start|stop}" >&2
|
||||
exit 1
|
||||
;;
|
||||
esac
|
@ -0,0 +1,30 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Generators don't have logging right now
|
||||
# https://github.com/systemd/systemd/issues/15638
|
||||
exec 1>/dev/kmsg; exec 2>&1
|
||||
|
||||
command -v getargbool >/dev/null || . /usr/lib/dracut-lib.sh
|
||||
|
||||
set -e
|
||||
|
||||
if is-live-image; then
|
||||
exit 0
|
||||
fi
|
||||
|
||||
UNIT_DIR="${1:-/tmp}"
|
||||
|
||||
add_requires() {
|
||||
local name="$1"; shift
|
||||
local target="$1"; shift
|
||||
local requires_dir="${UNIT_DIR}/${target}.requires"
|
||||
mkdir -p "${requires_dir}"
|
||||
ln -sf "../${name}" "${requires_dir}/${name}"
|
||||
}
|
||||
|
||||
if getargbool 0 rd.multipath; then
|
||||
add_requires coreos-multipath-wait.target initrd.target
|
||||
if ! getargbool 0 ignition.firstboot; then
|
||||
add_requires coreos-multipath-trigger.service initrd.target
|
||||
fi
|
||||
fi
|
@ -0,0 +1,19 @@
|
||||
# This unit is needed in the LUKS-on-multipath case on subsequent boots. When
|
||||
# multipathd takes ownership of the individual paths, the by-uuid/ symlink
|
||||
# which systemd-cryptsetup@.service binds to gets lost. So we retrigger udev
|
||||
# here to make sure it's re-added.
|
||||
#
|
||||
# This is tracked at:
|
||||
# https://bugzilla.redhat.com/show_bug.cgi?id=1963242
|
||||
|
||||
[Unit]
|
||||
Description=CoreOS Trigger Multipath
|
||||
DefaultDependencies=false
|
||||
Requires=coreos-multipath-wait.target
|
||||
After=coreos-multipath-wait.target
|
||||
Before=cryptsetup-pre.target
|
||||
|
||||
[Service]
|
||||
Type=oneshot
|
||||
ExecStart=/usr/sbin/udevadm trigger --settle --subsystem-match block
|
||||
RemainAfterExit=yes
|
@ -0,0 +1,17 @@
|
||||
[Unit]
|
||||
Description=CoreOS Wait For Multipathed Boot
|
||||
DefaultDependencies=false
|
||||
Before=dracut-initqueue.service
|
||||
After=dracut-cmdline.service
|
||||
Requires=dev-disk-by\x2dlabel-dm\x2dmpath\x2dboot.device
|
||||
After=dev-disk-by\x2dlabel-dm\x2dmpath\x2dboot.device
|
||||
Requires=multipathd.service
|
||||
After=multipathd.service
|
||||
|
||||
# This is already enforced transitively by coreos-gpt-setup.service, but
|
||||
# let's be more explicit and list it directly here too.
|
||||
Before=coreos-ignition-setup-user.service
|
||||
|
||||
# This is already enforced by coreos-multipath-trigger.service, though ideally
|
||||
# eventually we can get rid of that one and then we *would* need this.
|
||||
Before=cryptsetup-pre.target
|
@ -0,0 +1,24 @@
|
||||
[Unit]
|
||||
Description=CoreOS Propagate Multipath Configuration
|
||||
Before=initrd.target
|
||||
|
||||
# we write to the rootfs, so run after it's ready
|
||||
After=initrd-root-fs.target
|
||||
|
||||
# we only propagate if multipath wasn't configured via Ignition
|
||||
After=ignition-files.service
|
||||
|
||||
# That service starts initrd-cleanup.service which will race with us completing
|
||||
# before we get nuked. Need to get to the bottom of it, but for now we need
|
||||
# this (XXX: add link to systemd issue here).
|
||||
Before=initrd-parse-etc.service
|
||||
|
||||
ConditionKernelCommandLine=rd.multipath=default
|
||||
|
||||
OnFailure=emergency.target
|
||||
OnFailureJobMode=isolate
|
||||
|
||||
[Service]
|
||||
Type=oneshot
|
||||
ExecStart=/usr/sbin/coreos-propagate-multipath-conf
|
||||
RemainAfterExit=yes
|
@ -0,0 +1,23 @@
|
||||
#!/bin/bash
|
||||
set -euo pipefail
|
||||
|
||||
# Persist automatic multipath configuration, if any.
|
||||
# When booting with `rd.multipath=default`, the default multipath
|
||||
# configuration is written. We need to ensure that the multipath configuration
|
||||
# is persisted to the rootfs.
|
||||
|
||||
if [ ! -f /etc/multipath.conf ]; then
|
||||
echo "info: initrd file /etc/multipath.conf does not exist"
|
||||
echo "info: no initrd multipath configuration to propagate"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
if [ -f /sysroot/etc/multipath.conf ]; then
|
||||
echo "info: real root file /etc/multipath.conf exists"
|
||||
echo "info: not propagating initrd multipath configuration"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
echo "info: propagating initrd multipath configuration"
|
||||
cp -v /etc/multipath.conf /sysroot/etc/
|
||||
coreos-relabel /etc/multipath.conf
|
28
overlay.d/05core/usr/lib/dracut/modules.d/35coreos-multipath/module-setup.sh
Executable file
28
overlay.d/05core/usr/lib/dracut/modules.d/35coreos-multipath/module-setup.sh
Executable file
@ -0,0 +1,28 @@
|
||||
#!/bin/bash
|
||||
# -*- mode: shell-script; indent-tabs-mode: nil; sh-basic-offset: 4; -*-
|
||||
# ex: ts=8 sw=4 sts=4 et filetype=sh
|
||||
|
||||
install_unit() {
|
||||
local unit=$1; shift
|
||||
local target=${1:-initrd}
|
||||
inst_simple "$moddir/$unit" "$systemdsystemunitdir/$unit"
|
||||
# note we `|| exit 1` here so we error out if e.g. the units are missing
|
||||
# see https://github.com/coreos/fedora-coreos-config/issues/799
|
||||
systemctl -q --root="$initdir" add-requires "${target}.target" "$unit" || exit 1
|
||||
}
|
||||
|
||||
install() {
|
||||
inst_script "$moddir/coreos-propagate-multipath-conf.sh" \
|
||||
"/usr/sbin/coreos-propagate-multipath-conf"
|
||||
|
||||
install_unit coreos-propagate-multipath-conf.service
|
||||
|
||||
inst_simple "$moddir/coreos-multipath-generator" \
|
||||
"$systemdutildir/system-generators/coreos-multipath-generator"
|
||||
|
||||
# we don't enable these; they're enabled dynamically via the generator
|
||||
inst_simple "$moddir/coreos-multipath-wait.target" \
|
||||
"$systemdsystemunitdir/coreos-multipath-wait.target"
|
||||
inst_simple "$moddir/coreos-multipath-trigger.service" \
|
||||
"$systemdsystemunitdir/coreos-multipath-trigger.service"
|
||||
}
|
@ -0,0 +1,7 @@
|
||||
# This contains the default kargs for firstboot network configuration.
|
||||
# Default values can be dynamically overridden by platform-specific
|
||||
# logic (e.g. injected via a back-channel).
|
||||
# https://github.com/coreos/fedora-coreos-tracker/issues/460
|
||||
|
||||
[Service]
|
||||
Environment=AFTERBURN_NETWORK_KARGS_DEFAULT='ip=auto'
|
@ -0,0 +1,65 @@
|
||||
# This unit will run early in boot and detect if:
|
||||
# - In the diskful case, the user copied in firstboot networking config files
|
||||
# into `/boot` (most likely by using `coreos-installer install
|
||||
# --copy-network`).
|
||||
# - In the live case, the user provided firstboot networking config files in
|
||||
# `/etc` (most likely by using `coreos-installer iso network embed`).
|
||||
#
|
||||
# Since this unit is modifying network configuration there are some
|
||||
# dependencies that we have:
|
||||
#
|
||||
# - In the diskful case, we need to look for networking configuration on the
|
||||
# /boot partition
|
||||
# - i.e. after /dev/disk/by-label/boot is available
|
||||
# - which is implied by running after coreos-gpt-setup (see below)
|
||||
# - Need to run before networking is brought up.
|
||||
# - This is done in nm-initrd.service [1]
|
||||
# - i.e. Before=nm-initrd.service
|
||||
# - Need to make sure karg networking configuration isn't applied
|
||||
# - There are two ways to do this.
|
||||
# - One is to run *before* the nm-config.sh [2] that runs as part of
|
||||
# dracut-cmdline [3] and `ln -sf /bin/true /usr/libexec/nm-initrd-generator`.
|
||||
# - i.e. Before=dracut-cmdline.service
|
||||
# - Another is to run *after* nm-config.sh [2] in dracut-cmdline [3]
|
||||
# and just delete all the files created by nm-initrd-generator.
|
||||
# - i.e. After=dracut-cmdline.service, but Before=nm-initrd.service
|
||||
# - We'll go with the second option here because the need for the /boot
|
||||
# device (mentioned above) means we can't start before dracut-cmdline.service
|
||||
#
|
||||
# [1] https://github.com/dracutdevs/dracut/blob/master/modules.d/35network-manager/nm-initrd.service
|
||||
# [2] https://github.com/dracutdevs/dracut/blob/master/modules.d/35network-manager/nm-config.sh
|
||||
# [3] https://github.com/dracutdevs/dracut/blob/master/modules.d/35network-manager/module-setup.sh#L34
|
||||
#
|
||||
[Unit]
|
||||
Description=Copy CoreOS Firstboot Networking Config
|
||||
ConditionPathExists=/usr/lib/initrd-release
|
||||
DefaultDependencies=false
|
||||
# We're pulled in by ignition-complete.target; as good practice, add a matching
|
||||
# Before to be explicit about it gating on this unit passing.
|
||||
Before=ignition-complete.target
|
||||
Before=nm-initrd.service
|
||||
# compat: remove when everyone is on dracut 054+
|
||||
Before=dracut-initqueue.service
|
||||
After=dracut-cmdline.service
|
||||
# Any services looking at mounts need to order after this
|
||||
# because it causes device re-probing.
|
||||
After=coreos-gpt-setup.service
|
||||
# And since the boot device may be on multipath; optionally wait for it to
|
||||
# appear via the dynamic target.
|
||||
After=coreos-multipath-wait.target
|
||||
# Need to run after coreos-enable-network since it may re-run the NM cmdline
|
||||
# hook which will generate NM configs from the network kargs, but we want to
|
||||
# have precedence.
|
||||
After=coreos-enable-network.service
|
||||
# We've seen races with ignition-kargs.service, which accesses /boot rw.
|
||||
# Let's introduce some ordering here. Need to use `Before` because otherwise
|
||||
# we get a systemd ordering cycle. https://github.com/coreos/fedora-coreos-tracker/issues/883
|
||||
Before=ignition-kargs.service
|
||||
|
||||
[Service]
|
||||
Type=oneshot
|
||||
RemainAfterExit=yes
|
||||
# The MountFlags=slave is so the umount of /boot is guaranteed to happen
|
||||
# /boot will only be mounted for the lifetime of the unit.
|
||||
MountFlags=slave
|
||||
ExecStart=/usr/sbin/coreos-copy-firstboot-network
|
@ -0,0 +1,49 @@
|
||||
#!/bin/bash
|
||||
set -euo pipefail
|
||||
|
||||
# For a description of how this is used see coreos-copy-firstboot-network.service
|
||||
|
||||
bootmnt=/mnt/boot_partition
|
||||
bootdev=/dev/disk/by-label/boot
|
||||
firstboot_network_dir_basename="coreos-firstboot-network"
|
||||
boot_firstboot_network_dir="${bootmnt}/${firstboot_network_dir_basename}"
|
||||
etc_firstboot_network_dir="/etc/${firstboot_network_dir_basename}"
|
||||
initramfs_network_dir="/run/NetworkManager/system-connections/"
|
||||
|
||||
copy_firstboot_network() {
|
||||
local src=$1; shift
|
||||
|
||||
# Clear out any files that may have already been generated from
|
||||
# kargs by nm-initrd-generator
|
||||
rm -f ${initramfs_network_dir}/*
|
||||
# Copy files that were placed into the source
|
||||
# to the appropriate location for NetworkManager to use the configuration.
|
||||
echo "info: copying files from ${src} to ${initramfs_network_dir}"
|
||||
mkdir -p ${initramfs_network_dir}
|
||||
cp -v ${src}/* ${initramfs_network_dir}/
|
||||
}
|
||||
|
||||
if ! is-live-image; then
|
||||
# Mount /boot. Note that we mount /boot but we don't unmount boot because we
|
||||
# are run in a systemd unit with MountFlags=slave so it is unmounted for us.
|
||||
# Mount as read-only since we don't strictly need write access and we may be
|
||||
# running alongside other code that also has it mounted ro
|
||||
mkdir -p ${bootmnt}
|
||||
mount -o ro ${bootdev} ${bootmnt}
|
||||
|
||||
if [ -n "$(ls -A ${boot_firstboot_network_dir} 2>/dev/null)" ]; then
|
||||
# Likely placed there by coreos-installer, see:
|
||||
# https://github.com/coreos/coreos-installer/pull/212
|
||||
copy_firstboot_network "${boot_firstboot_network_dir}"
|
||||
else
|
||||
echo "info: no files to copy from ${boot_firstboot_network_dir}; skipping"
|
||||
fi
|
||||
else
|
||||
if [ -n "$(ls -A ${etc_firstboot_network_dir} 2>/dev/null)" ]; then
|
||||
# Also placed there by coreos-installer but in a different flow, see:
|
||||
# https://github.com/coreos/coreos-installer/pull/713
|
||||
copy_firstboot_network "${etc_firstboot_network_dir}"
|
||||
else
|
||||
echo "info: no files to copy from ${etc_firstboot_network_dir}; skipping"
|
||||
fi
|
||||
fi
|
@ -0,0 +1,30 @@
|
||||
[Unit]
|
||||
Description=CoreOS Enable Network
|
||||
ConditionPathExists=/etc/initrd-release
|
||||
DefaultDependencies=false
|
||||
After=basic.target
|
||||
|
||||
# Triggering conditions for cases where we need network:
|
||||
# * when Ignition signals that it is required for provisioning.
|
||||
# * on live systems fetching the remote rootfs in initramfs.
|
||||
# * on Azure and Azure Stack Hub, for hostname fetching (metadata endpoint) and boot check-in (wireserver).
|
||||
ConditionPathExists=|/run/ignition/neednet
|
||||
ConditionKernelCommandLine=|coreos.live.rootfs_url
|
||||
ConditionKernelCommandLine=|ignition.platform.id=azure
|
||||
ConditionKernelCommandLine=|ignition.platform.id=azurestack
|
||||
|
||||
# Creates /run/ignition/neednet
|
||||
After=ignition-fetch-offline.service
|
||||
# Needs networking
|
||||
Before=ignition-fetch.service
|
||||
|
||||
# See hack in coreos-enable-network, as well as coreos-copy-firstboot-network.service.
|
||||
After=dracut-cmdline.service
|
||||
Before=nm-initrd.service
|
||||
# compat: remove when everyone is on dracut 054+
|
||||
Before=dracut-initqueue.service
|
||||
|
||||
[Service]
|
||||
Type=oneshot
|
||||
RemainAfterExit=yes
|
||||
ExecStart=/usr/sbin/coreos-enable-network
|
@ -0,0 +1,27 @@
|
||||
#!/bin/bash
|
||||
set -euo pipefail
|
||||
|
||||
set +euo pipefail
|
||||
. /usr/lib/dracut-lib.sh
|
||||
set -euo pipefail
|
||||
|
||||
dracut_func() {
|
||||
# dracut is not friendly to set -eu
|
||||
set +euo pipefail
|
||||
"$@"; local rc=$?
|
||||
set -euo pipefail
|
||||
return $rc
|
||||
}
|
||||
|
||||
# If networking hasn't been requested yet, request it.
|
||||
if ! dracut_func getargbool 0 'rd.neednet'; then
|
||||
echo "rd.neednet=1" > /etc/cmdline.d/40-coreos-neednet.conf
|
||||
|
||||
# Hack: we need to rerun the NM cmdline hook because we run after
|
||||
# dracut-cmdline.service because we need udev. We should be able to move
|
||||
# away from this once we run NM as a systemd unit. See also:
|
||||
# https://github.com/coreos/fedora-coreos-config/pull/346#discussion_r409843428
|
||||
set +euo pipefail
|
||||
. /usr/lib/dracut/hooks/cmdline/99-nm-config.sh
|
||||
set -euo pipefail
|
||||
fi
|
@ -0,0 +1,26 @@
|
||||
install_and_enable_unit() {
|
||||
unit="$1"; shift
|
||||
target="$1"; shift
|
||||
inst_simple "$moddir/$unit" "$systemdsystemunitdir/$unit"
|
||||
# note we `|| exit 1` here so we error out if e.g. the units are missing
|
||||
# see https://github.com/coreos/fedora-coreos-config/issues/799
|
||||
systemctl -q --root="$initdir" add-requires "$target" "$unit" || exit 1
|
||||
}
|
||||
|
||||
install() {
|
||||
inst_simple "$moddir/coreos-enable-network.sh" \
|
||||
"/usr/sbin/coreos-enable-network"
|
||||
install_and_enable_unit "coreos-enable-network.service" \
|
||||
"initrd.target"
|
||||
|
||||
inst_simple "$moddir/coreos-copy-firstboot-network.sh" \
|
||||
"/usr/sbin/coreos-copy-firstboot-network"
|
||||
install_and_enable_unit "coreos-copy-firstboot-network.service" \
|
||||
"ignition-complete.target"
|
||||
|
||||
# Dropin with firstboot network configuration kargs, applied via
|
||||
# Afterburn.
|
||||
inst_simple "$moddir/50-afterburn-network-kargs-default.conf" \
|
||||
"/usr/lib/systemd/system/afterburn-network-kargs.service.d/50-afterburn-network-kargs-default.conf"
|
||||
|
||||
}
|
@ -0,0 +1,19 @@
|
||||
{
|
||||
"ignition": {
|
||||
"version": "3.0.0"
|
||||
},
|
||||
"passwd": {
|
||||
"users": [
|
||||
{
|
||||
"name": "core",
|
||||
"gecos": "CoreOS Admin",
|
||||
"groups": [
|
||||
"adm",
|
||||
"sudo",
|
||||
"systemd-journal",
|
||||
"wheel"
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
@ -0,0 +1 @@
|
||||
`00-core.ign` is the base config shared between FCOS and RHCOS. The configs specific to FCOS are in [50ignition-conf-fcos](../../../../../../15fcos/usr/lib/dracut/modules.d/50ignition-conf-fcos).
|
13
overlay.d/05core/usr/lib/dracut/modules.d/40ignition-conf/module-setup.sh
Executable file
13
overlay.d/05core/usr/lib/dracut/modules.d/40ignition-conf/module-setup.sh
Executable file
@ -0,0 +1,13 @@
|
||||
#!/bin/bash
|
||||
# -*- mode: shell-script; indent-tabs-mode: nil; sh-basic-offset: 4; -*-
|
||||
# ex: ts=8 sw=4 sts=4 et filetype=sh
|
||||
|
||||
depends() {
|
||||
echo ignition
|
||||
}
|
||||
|
||||
install() {
|
||||
mkdir -p "$initdir/usr/lib/ignition/base.d"
|
||||
inst "$moddir/00-core.ign" \
|
||||
"/usr/lib/ignition/base.d/00-core.ign"
|
||||
}
|
@ -0,0 +1,37 @@
|
||||
#!/bin/bash
|
||||
set -euo pipefail
|
||||
|
||||
# See also ignition-ostree-check-rootfs-size.service
|
||||
# https://github.com/coreos/fedora-coreos-tracker/issues/586#issuecomment-777220000
|
||||
|
||||
srcdev=$(findmnt -nvr -o SOURCE /sysroot | tail -n1)
|
||||
size=$(lsblk --nodeps --noheadings --bytes -o SIZE "${srcdev}")
|
||||
|
||||
MINIMUM_GB=8
|
||||
MINIMUM_BYTES=$((1024 * 1024 * 1024 * MINIMUM_GB))
|
||||
|
||||
MOTD_DROPIN=/etc/motd.d/60-coreos-rootfs-size.motd
|
||||
|
||||
YELLOW=$(echo -e '\033[0;33m')
|
||||
RESET=$(echo -e '\033[0m')
|
||||
|
||||
if [ "${size}" -lt "${MINIMUM_BYTES}" ]; then
|
||||
mkdir -p "/sysroot/$(dirname "${MOTD_DROPIN}")"
|
||||
cat > "/sysroot/${MOTD_DROPIN}" <<EOF
|
||||
${YELLOW}
|
||||
############################################################################
|
||||
WARNING: The root filesystem is too small. It is strongly recommended to
|
||||
allocate at least ${MINIMUM_GB} GiB of space to allow for upgrades. From June 2021, this
|
||||
condition will trigger a failure in some cases. For more information, see:
|
||||
https://docs.fedoraproject.org/en-US/fedora-coreos/storage/
|
||||
|
||||
You may delete this warning using:
|
||||
sudo rm ${MOTD_DROPIN}
|
||||
############################################################################
|
||||
${RESET}
|
||||
EOF
|
||||
|
||||
# And also write it on stdout for the journal and console
|
||||
cat "/sysroot/${MOTD_DROPIN}"
|
||||
coreos-relabel "${MOTD_DROPIN}"
|
||||
fi
|
35
overlay.d/05core/usr/lib/dracut/modules.d/40ignition-ostree/coreos-relabel
Executable file
35
overlay.d/05core/usr/lib/dracut/modules.d/40ignition-ostree/coreos-relabel
Executable file
@ -0,0 +1,35 @@
|
||||
#!/bin/bash
|
||||
set -euo pipefail
|
||||
|
||||
err() {
|
||||
echo "$@" >&2
|
||||
}
|
||||
|
||||
fatal() {
|
||||
err "$@"
|
||||
exit 1
|
||||
}
|
||||
|
||||
if [ $# -eq 0 ]; then
|
||||
err "Usage: $0 [PATTERN...]"
|
||||
err " e.g.: $0 /etc/passwd '/etc/group*'"
|
||||
fi
|
||||
|
||||
if [ ! -f /sysroot/etc/selinux/config ]; then
|
||||
exit 0
|
||||
fi
|
||||
|
||||
source /sysroot/etc/selinux/config
|
||||
|
||||
if [ -z "${SELINUXTYPE:-}" ]; then
|
||||
fatal "Couldn't find SELINUXTYPE in /sysroot/etc/selinux/config"
|
||||
fi
|
||||
|
||||
file_contexts="/sysroot/etc/selinux/${SELINUXTYPE}/contexts/files/file_contexts"
|
||||
|
||||
prefixed_patterns=()
|
||||
while [ $# -ne 0 ]; do
|
||||
pattern=$1; shift
|
||||
prefixed_patterns+=("/sysroot/$pattern")
|
||||
done
|
||||
setfiles -vFi0 -r /sysroot "$file_contexts" "${prefixed_patterns[@]}"
|
@ -0,0 +1,30 @@
|
||||
#!/bin/bash
|
||||
set -euo pipefail
|
||||
|
||||
# see related comment block in transposefs.sh re. inspecting the config directly
|
||||
ignition_cfg=/run/ignition.json
|
||||
rootpath=/dev/disk/by-label/root
|
||||
|
||||
query_rootfs() {
|
||||
local filter=$1
|
||||
jq -re ".storage?.filesystems? // [] |
|
||||
map(select(.label == \"root\" and .wipeFilesystem == true)) |
|
||||
.[0] | $filter" "${ignition_cfg}"
|
||||
}
|
||||
|
||||
# If the rootfs was reprovisioned, then the mountOptions from the Ignition
|
||||
# config has priority.
|
||||
if [ -d /run/ignition-ostree-transposefs/root ]; then
|
||||
if query_rootfs 'has("mountOptions")' >/dev/null; then
|
||||
query_rootfs '.mountOptions | join(",")'
|
||||
exit 0
|
||||
fi
|
||||
fi
|
||||
|
||||
eval $(blkid -o export ${rootpath})
|
||||
if [ "${TYPE}" == "xfs" ]; then
|
||||
# We use prjquota on XFS by default to aid multi-tenant Kubernetes (and
|
||||
# other container) clusters. See
|
||||
# https://github.com/coreos/coreos-assembler/pull/303/commits/6103effbd006bb6109467830d6a3e42dd847668d
|
||||
echo "prjquota"
|
||||
fi
|
@ -0,0 +1,15 @@
|
||||
[Unit]
|
||||
Description=Ignition OSTree: Check Root Filesystem Size
|
||||
Documentation=https://docs.fedoraproject.org/en-US/fedora-coreos/storage/
|
||||
DefaultDependencies=false
|
||||
ConditionKernelCommandLine=ostree
|
||||
ConditionPathExists=!/run/ostree-live
|
||||
After=ignition-ostree-growfs.service
|
||||
After=ostree-prepare-root.service
|
||||
# Allow Ignition config to blank out the warning
|
||||
Before=ignition-files.service
|
||||
|
||||
[Service]
|
||||
Type=oneshot
|
||||
ExecStart=/usr/libexec/coreos-check-rootfs-size
|
||||
RemainAfterExit=yes
|
@ -0,0 +1,68 @@
|
||||
#!/bin/bash
|
||||
set -euo pipefail
|
||||
# https://github.com/coreos/fedora-coreos-tracker/issues/465
|
||||
# coreos-assembler generates disk images which are installed bit-for-bit
|
||||
# or booted directly in the cloud.
|
||||
# Generate new UUID on firstboot; this is general best practice, but in the future
|
||||
# we may use this for mounting by e.g. adding a boot=<uuid> and root=<uuid> kernel args.
|
||||
|
||||
label=$1
|
||||
|
||||
# Keep this in sync with https://github.com/coreos/coreos-assembler/blob/e3905fd2e138de04184c1cd86b99b0fd83cbe5cf/src/create_disk.sh#L17
|
||||
bootfs_uuid="96d15588-3596-4b3c-adca-a2ff7279ea63"
|
||||
rootfs_uuid="910678ff-f77e-4a7d-8d53-86f2ac47a823"
|
||||
|
||||
target=/dev/disk/by-label/${label}
|
||||
if ! [ -b "${target}" ]; then
|
||||
echo "$0: Failed to find block device ${target}" 1>&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
eval $(blkid -o export ${target})
|
||||
case "${label}" in
|
||||
root) orig_uuid="${rootfs_uuid}"; orig_type=xfs ;;
|
||||
boot) orig_uuid="${bootfs_uuid}"; orig_type=ext4 ;;
|
||||
*) echo "unexpected ${label}"; exit 1 ;;
|
||||
esac
|
||||
|
||||
if [ "${TYPE}" == "${orig_type}" ] && [ "${UUID}" == "${orig_uuid}" ]; then
|
||||
case "${TYPE}" in
|
||||
ext4)
|
||||
# If the filesystem supports metadata_csum_seed then the UUID is stored
|
||||
# in the superblock and there is no need to worry with an fsck. For the
|
||||
# boot filesystem this FS feature wasn't supported by GRUB until recently.
|
||||
# https://lists.gnu.org/archive/html/grub-devel/2021-06/msg00031.html
|
||||
# Once grub is updated in all systems we care about we can standardize
|
||||
# on the metadata_csum_seed and delete the `else` code block.
|
||||
if tune2fs -l ${target} | grep 'metadata_csum_seed'; then
|
||||
tune2fs -U random "${target}"
|
||||
else
|
||||
# Run an fsck since tune2fs -U requires the FS to be clean
|
||||
e2fsck -fy "${target}"
|
||||
# We just ran an fsck, but there is a bug where tune2fs -U will still
|
||||
# complain. It will still error if the last checked timestamp (just
|
||||
# set by the e2fsck above) is older than the last mount timestamp (happens
|
||||
# on systems with out of date or non-functioning hardware clocks).
|
||||
# See https://github.com/coreos/fedora-coreos-tracker/issues/735#issuecomment-859605953
|
||||
# Potentially fixed in future by: https://www.spinics.net/lists/linux-ext4/msg78012.html
|
||||
tune2fsinfo="$(tune2fs -l ${target})"
|
||||
lastmount=$(echo "$tune2fsinfo" | grep '^Last mount time:' | cut -d ':' -f 2,3,4)
|
||||
lastfsck=$(echo "$tune2fsinfo" | grep '^Last checked:' | cut -d ':' -f 2,3,4)
|
||||
lastmountsse=$(date --date="$lastmount" +%s)
|
||||
lastfscksse=$(date --date="$lastfsck" +%s)
|
||||
if (( lastfscksse < lastmountsse )); then
|
||||
echo "Detected timestamp of last fsck is older than timestamp of last mount."
|
||||
echo "Setting "${target}" timestamp of last fsck to same time as last mount."
|
||||
tune2fs -T $(date --date="$lastmount" +%Y%m%d%H%M%S) "${target}"
|
||||
fi
|
||||
# Finally, we can randomize the UUID
|
||||
tune2fs -U random "${target}"
|
||||
fi ;;
|
||||
xfs) xfs_admin -U generate "${target}" ;;
|
||||
*) echo "unexpected filesystem type ${TYPE}" 1>&2; exit 1 ;;
|
||||
esac
|
||||
udevadm settle || :
|
||||
echo "Regenerated UUID for ${target}"
|
||||
else
|
||||
echo "No changes required for ${target} TYPE=${TYPE} UUID=${UUID}"
|
||||
fi
|
@ -0,0 +1,15 @@
|
||||
[Unit]
|
||||
Description=Ignition OSTree: Grow root filesystem
|
||||
DefaultDependencies=false
|
||||
ConditionKernelCommandLine=ostree
|
||||
ConditionPathExists=!/run/ostree-live
|
||||
Before=initrd-root-fs.target
|
||||
After=sysroot.mount ignition-ostree-mount-firstboot-sysroot.service
|
||||
# This shouldn't be strictly necessary, but it's cleaner to not have OSTree muck
|
||||
# around with moving mounts while we're still resizing the filesystem.
|
||||
Before=ostree-prepare-root.service
|
||||
|
||||
[Service]
|
||||
Type=oneshot
|
||||
ExecStart=/usr/sbin/ignition-ostree-growfs
|
||||
RemainAfterExit=yes
|
@ -0,0 +1,126 @@
|
||||
#!/bin/bash
|
||||
set -euo pipefail
|
||||
|
||||
# This script is run by ignition-ostree-growfs.service. It grows the root
|
||||
# partition, unless it determines that either the rootfs was moved or the
|
||||
# partition was already resized (e.g. via Ignition).
|
||||
|
||||
# If root reprovisioning was triggered, this file contains state of the root
|
||||
# partition *before* ignition-disks.
|
||||
saved_partstate=/run/ignition-ostree-rootfs-partstate.sh
|
||||
|
||||
# We run after the rootfs is mounted at /sysroot, but before ostree-prepare-root
|
||||
# moves it to /sysroot/sysroot.
|
||||
path=/sysroot
|
||||
|
||||
# The use of tail is to avoid errors from duplicate mounts;
|
||||
# this shouldn't happen for us but we're being conservative.
|
||||
src=$(findmnt -nvr -o SOURCE "$path" | tail -n1)
|
||||
|
||||
# In the IBM Secure Execution case we use Ignition to grow and reencrypt rootfs
|
||||
# see overlay.d/05core/usr/lib/dracut/modules.d/35coreos-ignition/coreos-diskful-generator
|
||||
if [[ -f /run/coreos/secure-execution ]]; then
|
||||
exit 0
|
||||
fi
|
||||
|
||||
if [ ! -f "${saved_partstate}" ]; then
|
||||
partition=$(realpath /dev/disk/by-label/root)
|
||||
else
|
||||
# The rootfs was reprovisioned. Our rule in this case is: we only grow if
|
||||
# the partition backing the rootfs is the same and its size didn't change
|
||||
# (IOW, it was an in-place reprovisioning; e.g. LUKS or xfs -> btrfs).
|
||||
source "${saved_partstate}"
|
||||
if [ "${TYPE}" != "part" ]; then
|
||||
# this really should never happen; but play nice
|
||||
echo "$0: original rootfs blockdev not of type 'part'; not auto-growing"
|
||||
exit 0
|
||||
fi
|
||||
partition=$(realpath "${NAME}")
|
||||
if [ "${SIZE}" != "$(lsblk --nodeps -bno SIZE "${partition}")" ]; then
|
||||
echo "$0: original root partition changed size; not auto-growing"
|
||||
exit 0
|
||||
fi
|
||||
if ! lsblk -no MOUNTPOINT "${partition}" | grep -q '^/sysroot$'; then
|
||||
echo "$0: original root partition no longer backing rootfs; not auto-growing"
|
||||
exit 0
|
||||
fi
|
||||
fi
|
||||
|
||||
# Go through each blockdev in the hierarchy and verify we know how to grow them
|
||||
lsblk -no TYPE "${partition}" | while read dev; do
|
||||
case "${dev}" in
|
||||
part|crypt) ;;
|
||||
*) echo "error: Unsupported blockdev type ${dev}" 1>&2; exit 1 ;;
|
||||
esac
|
||||
done
|
||||
|
||||
# Get the filesystem type before extending the partition. This matters
|
||||
# because the partition, once extended, might include leftover superblocks
|
||||
# from the previous contents of the disk (notably ZFS), causing blkid to
|
||||
# refuse to return any filesystem type at all.
|
||||
eval $(blkid -o export "${src}")
|
||||
ROOTFS_TYPE=${TYPE:-}
|
||||
case "${ROOTFS_TYPE}" in
|
||||
xfs|ext4|btrfs) ;;
|
||||
*) echo "error: Unsupported filesystem for ${path}: '${ROOTFS_TYPE}'" 1>&2; exit 1 ;;
|
||||
esac
|
||||
|
||||
# Now, go through the hierarchy, growing everything. Note we go one device at a
|
||||
# time using --nodeps, because ordering is buggy in el8:
|
||||
# https://bugzilla.redhat.com/show_bug.cgi?id=1940607
|
||||
current_blkdev=${partition}
|
||||
while true; do
|
||||
eval "$(lsblk --paths --nodeps --pairs -o NAME,TYPE,PKNAME "${current_blkdev}")"
|
||||
MAJMIN=$(echo $(lsblk -dno MAJ:MIN "${NAME}"))
|
||||
case "${TYPE}" in
|
||||
part)
|
||||
eval $(udevadm info --query property --export "${current_blkdev}" | grep ^DM_ || :)
|
||||
if [ -n "${DM_MPATH:-}" ]; then
|
||||
# Since growpart does not understand device mapper, we have to use sfdisk.
|
||||
echo ", +" | sfdisk --no-reread --no-tell-kernel --force -N "${DM_PART}" "/dev/mapper/${DM_MPATH}"
|
||||
udevadm settle || : # Wait for udev-triggered kpartx to update mappings
|
||||
else
|
||||
partnum=$(cat "/sys/dev/block/${MAJMIN}/partition")
|
||||
# XXX: ideally this'd be idempotent and we wouldn't `|| :`
|
||||
growpart "${PKNAME}" "${partnum}" || :
|
||||
fi
|
||||
;;
|
||||
crypt)
|
||||
# XXX: yuck... we need to expose this sanely in clevis
|
||||
(. /usr/bin/clevis-luks-common-functions
|
||||
eval $(udevadm info --query=property --export "${NAME}")
|
||||
# lsblk doesn't print PKNAME of crypt devices with --nodeps
|
||||
PKNAME=/dev/$(ls "/sys/dev/block/${MAJMIN}/slaves")
|
||||
clevis_luks_unlock_device "${PKNAME}" | cryptsetup resize -d- "${DM_NAME}"
|
||||
)
|
||||
;;
|
||||
# already checked
|
||||
*) echo "unreachable" 1>&2; exit 1 ;;
|
||||
esac
|
||||
holders="/sys/dev/block/${MAJMIN}/holders"
|
||||
[ -d "${holders}" ] || break
|
||||
nholders="$(ls "${holders}" | wc -l)"
|
||||
if [ "${nholders}" -eq 0 ]; then
|
||||
break
|
||||
elif [ "${nholders}" -gt 1 ]; then
|
||||
# this shouldn't happen since we've checked the partition types already
|
||||
echo "error: Unsupported block device with multiple children: ${NAME}" 1>&2
|
||||
exit 1
|
||||
fi
|
||||
current_blkdev=/dev/$(ls "${holders}")
|
||||
done
|
||||
|
||||
# Wipe any filesystem signatures from the extended partition that don't
|
||||
# correspond to the FS type we detected earlier.
|
||||
wipefs -af -t "no${ROOTFS_TYPE}" "${src}"
|
||||
|
||||
# TODO: Add XFS to https://github.com/systemd/systemd/blob/master/src/partition/growfs.c
|
||||
# and use it instead.
|
||||
case "${ROOTFS_TYPE}" in
|
||||
xfs) xfs_growfs "${path}" ;;
|
||||
ext4) resize2fs "${src}" ;;
|
||||
btrfs) btrfs filesystem resize max ${path} ;;
|
||||
esac
|
||||
|
||||
# this is useful for tests
|
||||
touch /run/ignition-ostree-growfs.stamp
|
@ -0,0 +1,25 @@
|
||||
[Unit]
|
||||
Description=Ignition OSTree: Mount (firstboot) /sysroot
|
||||
# These dependencies should match the "other" in
|
||||
# ignition-ostree-mount-subsequent-sysroot.service
|
||||
DefaultDependencies=false
|
||||
# If root is specified, then systemd's generator will win
|
||||
ConditionKernelCommandLine=!root
|
||||
ConditionKernelCommandLine=ostree
|
||||
# This is redundant since we're queued on -diskful.target, but eh.
|
||||
ConditionPathExists=!/run/ostree-live
|
||||
# There can be only one, Highlander style
|
||||
Conflicts=ignition-ostree-mount-subsequent-sysroot.service
|
||||
Before=initrd-root-fs.target
|
||||
After=ignition-disks.service
|
||||
# Note we don't have a Requires: /dev/disk/by-label/root here like
|
||||
# the -subsequent service does because ignition-disks may have
|
||||
# regenerated it.
|
||||
Requires=ignition-disks.service
|
||||
# These have an explicit dependency on After=sysroot.mount today
|
||||
Before=ostree-prepare-root.service ignition-remount-sysroot.service
|
||||
|
||||
[Service]
|
||||
Type=oneshot
|
||||
RemainAfterExit=yes
|
||||
ExecStart=/usr/sbin/ignition-ostree-mount-sysroot
|
@ -0,0 +1,24 @@
|
||||
# Note this unit is conditionally enabled by ignition-ostree-generator
|
||||
[Unit]
|
||||
Description=CoreOS: Mount (subsequent) /sysroot
|
||||
# These dependencies should match the "other" in
|
||||
# ignition-ostree-mount-firsboot-sysroot.service
|
||||
DefaultDependencies=false
|
||||
# If root is specified, then systemd's generator will win
|
||||
ConditionKernelCommandLine=!root
|
||||
ConditionKernelCommandLine=ostree
|
||||
ConditionPathExists=!/run/ostree-live
|
||||
# There can be only one, Highlander style
|
||||
Conflicts=ignition-ostree-mount-firstboot-sysroot.service
|
||||
# And in contrast to the firstboot, we expect
|
||||
# the root device to be ready.
|
||||
Requires=dev-disk-by\x2dlabel-root.device
|
||||
After=dev-disk-by\x2dlabel-root.device
|
||||
Before=initrd-root-fs.target
|
||||
# This has an explicit dependency on After=sysroot.mount today
|
||||
Before=ostree-prepare-root.service
|
||||
|
||||
[Service]
|
||||
Type=oneshot
|
||||
RemainAfterExit=yes
|
||||
ExecStart=/usr/sbin/ignition-ostree-mount-sysroot
|
@ -0,0 +1,18 @@
|
||||
#!/bin/bash
|
||||
set -euo pipefail
|
||||
|
||||
# Note that on *new machines* this script is now only ever used on firstboot. On
|
||||
# subsequent boots, systemd-fstab-generator mounts /sysroot from the
|
||||
# root=UUID=... and rootflags=... kargs.
|
||||
|
||||
# We may do a migration window at some point where older machines have these
|
||||
# kargs injected so that we can simplify the model further.
|
||||
|
||||
rootpath=/dev/disk/by-label/root
|
||||
if ! [ -b "${rootpath}" ]; then
|
||||
echo "ignition-ostree-mount-sysroot: Failed to find ${rootpath}" 1>&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "Mounting ${rootpath} ($(realpath "${rootpath}")) to /sysroot"
|
||||
mount -o "$(coreos-rootflags)" "${rootpath}" /sysroot
|
@ -0,0 +1,26 @@
|
||||
[Unit]
|
||||
Description=Mount OSTree /var
|
||||
DefaultDependencies=false
|
||||
ConditionKernelCommandLine=ostree
|
||||
ConditionPathExists=!/run/ostree-live
|
||||
|
||||
# Make sure ExecStop= runs before we switch root
|
||||
Before=initrd-switch-root.target
|
||||
|
||||
# Make sure if ExecStop= fails, the boot fails
|
||||
OnFailure=emergency.target
|
||||
OnFailureJobMode=isolate
|
||||
|
||||
# Make sure /sysroot is mounted first, since we're mounting under there
|
||||
Requires=initrd-root-fs.target
|
||||
After=initrd-root-fs.target
|
||||
|
||||
# Need to do this before Ignition mounts any other filesystems (potentially
|
||||
# shadowing our own bind mount).
|
||||
Before=ignition-mount.service
|
||||
|
||||
[Service]
|
||||
Type=oneshot
|
||||
RemainAfterExit=yes
|
||||
ExecStart=/usr/sbin/ignition-ostree-mount-var mount
|
||||
ExecStop=/usr/sbin/ignition-ostree-mount-var umount
|
@ -0,0 +1,52 @@
|
||||
#!/bin/bash
|
||||
set -euo pipefail
|
||||
|
||||
fatal() {
|
||||
echo "$@" >&2
|
||||
exit 1
|
||||
}
|
||||
|
||||
if [ $# -ne 1 ] || { [[ $1 != mount ]] && [[ $1 != umount ]]; }; then
|
||||
fatal "Usage: $0 <mount|umount>"
|
||||
fi
|
||||
|
||||
get_ostree_arg() {
|
||||
# yes, this doesn't account for spaces within args, e.g. myarg="my val", but
|
||||
# it still works for our purposes
|
||||
(
|
||||
IFS=$' '
|
||||
# shellcheck disable=SC2013
|
||||
for arg in $(cat /proc/cmdline); do
|
||||
if [[ $arg == ostree=* ]]; then
|
||||
echo "${arg#ostree=}"
|
||||
fi
|
||||
done
|
||||
)
|
||||
}
|
||||
|
||||
do_mount() {
|
||||
ostree=$(get_ostree_arg)
|
||||
if [ -z "${ostree}" ]; then
|
||||
fatal "No ostree= kernel argument in /proc/cmdline"
|
||||
fi
|
||||
|
||||
deployment_path=/sysroot/${ostree}
|
||||
if [ ! -L "${deployment_path}" ]; then
|
||||
fatal "${deployment_path} is not a symlink"
|
||||
fi
|
||||
|
||||
stateroot_var_path=$(realpath "${deployment_path}/../../var")
|
||||
if [ ! -d "${stateroot_var_path}" ]; then
|
||||
fatal "${stateroot_var_path} is not a directory"
|
||||
fi
|
||||
|
||||
echo "Mounting $stateroot_var_path"
|
||||
mount --bind "$stateroot_var_path" /sysroot/var
|
||||
}
|
||||
|
||||
do_umount() {
|
||||
echo "Unmounting /sysroot/var"
|
||||
umount /sysroot/var
|
||||
}
|
||||
|
||||
"do_$1"
|
@ -0,0 +1,16 @@
|
||||
[Unit]
|
||||
Description=Populate OSTree /var
|
||||
DefaultDependencies=false
|
||||
ConditionKernelCommandLine=|ostree
|
||||
ConditionPathExists=|/run/ostree-live
|
||||
|
||||
# Need to do this with all mount points active
|
||||
After=ignition-mount.service
|
||||
|
||||
# But *before* we start dumping files in there
|
||||
Before=ignition-files.service
|
||||
|
||||
[Service]
|
||||
Type=oneshot
|
||||
RemainAfterExit=yes
|
||||
ExecStart=/usr/sbin/ignition-ostree-populate-var
|
@ -0,0 +1,45 @@
|
||||
#!/bin/bash
|
||||
set -euo pipefail
|
||||
|
||||
fatal() {
|
||||
echo "$@" >&2
|
||||
exit 1
|
||||
}
|
||||
|
||||
if [ $# -ne 0 ]; then
|
||||
fatal "Usage: $0"
|
||||
fi
|
||||
|
||||
# See the similar code block in Anaconda, which handles this today for Atomic
|
||||
# Host and Silverblue:
|
||||
# https://github.com/rhinstaller/anaconda/blob/b9ea8ce4e68196b30a524c1cc5680dcdc4b89371/pyanaconda/payload/rpmostreepayload.py#L332
|
||||
|
||||
for varsubdir in lib log home roothome opt srv usrlocal mnt media; do
|
||||
|
||||
# If the directory already existed, just ignore. This addresses the live
|
||||
# image case with persistent `/var`; we don't want to relabel all the files
|
||||
# there on each boot.
|
||||
if [ -d "/sysroot/var/${varsubdir}" ]; then
|
||||
continue
|
||||
fi
|
||||
|
||||
if [[ $varsubdir == lib ]] || [[ $varsubdir == log ]]; then
|
||||
# Simply manually mkdir /var/{lib,log}; the tmpfiles.d entries otherwise
|
||||
# reference users/groups which we don't have access to from here
|
||||
# (though... we *could* import them from the sysroot, and have
|
||||
# nss-altfiles in the initrd, but meh... let's just wait for
|
||||
# systemd-sysusers which will make this way easier:
|
||||
# https://github.com/coreos/fedora-coreos-config/pull/56/files#r262592361).
|
||||
mkdir -p /sysroot/var/${varsubdir}
|
||||
else
|
||||
systemd-tmpfiles --create --boot --root=/sysroot --prefix="/var/${varsubdir}"
|
||||
fi
|
||||
|
||||
if [[ $varsubdir == roothome ]]; then
|
||||
# TODO move this to tmpfiles.d once systemd-tmpfiles handles C! with --root correctly.
|
||||
# See https://github.com/coreos/fedora-coreos-config/pull/137
|
||||
cp /sysroot/etc/skel/.bash* /sysroot/var/${varsubdir}
|
||||
fi
|
||||
|
||||
coreos-relabel "/var/${varsubdir}"
|
||||
done
|
@ -0,0 +1,18 @@
|
||||
# RHOCS 4.12.s390x has an old kernel with a known issue: https://bugzilla.redhat.com/show_bug.cgi?id=2075085
|
||||
# Once we have kernel >= 4.18.0-387.el8.s390x we should drop this unit and copy config in coreos-diskful-generator
|
||||
[Unit]
|
||||
Description=Ignition OSTree: Inject Secure Execution Config
|
||||
DefaultDependencies=false
|
||||
ConditionArchitecture=s390x
|
||||
ConditionKernelCommandLine=ostree
|
||||
ConditionPathExists=/run/coreos/secure-execution
|
||||
OnFailure=emergency.target
|
||||
OnFailureJobMode=isolate
|
||||
|
||||
After=coreos-gpt-setup.service
|
||||
Before=ignition-fetch-offline.service
|
||||
|
||||
[Service]
|
||||
Type=oneshot
|
||||
RemainAfterExit=yes
|
||||
ExecStart=/usr/libexec/ignition-ostree-secex-config
|
@ -0,0 +1,5 @@
|
||||
#!/bin/bash
|
||||
set -euo pipefail
|
||||
|
||||
bootdev=$(blkid --list-one --output device --match-token PARTLABEL=boot | sed 's,[0-9]\+$,,')
|
||||
sed "s,\${BOOTDEV},$bootdev," < /usr/lib/coreos/01-secex.ign > /usr/lib/ignition/base.d/01-secex.ign
|
@ -0,0 +1,20 @@
|
||||
[Unit]
|
||||
Description=Ignition OSTree: Detect Partition Transposition
|
||||
DefaultDependencies=false
|
||||
After=ignition-fetch.service
|
||||
Before=ignition-disks.service
|
||||
Before=initrd-root-fs.target
|
||||
Before=sysroot.mount
|
||||
ConditionKernelCommandLine=ostree
|
||||
OnFailure=emergency.target
|
||||
OnFailureJobMode=isolate
|
||||
|
||||
# This stage requires udevd to detect disks
|
||||
Requires=systemd-udevd.service
|
||||
After=systemd-udevd.service
|
||||
|
||||
[Service]
|
||||
Type=oneshot
|
||||
RemainAfterExit=yes
|
||||
ExecStart=/usr/libexec/ignition-ostree-transposefs detect
|
||||
ExecStop=/usr/libexec/ignition-ostree-transposefs cleanup
|
@ -0,0 +1,20 @@
|
||||
[Unit]
|
||||
Description=Ignition OSTree: Restore Partitions
|
||||
DefaultDependencies=false
|
||||
After=ignition-disks.service
|
||||
# Avoid racing with UUID regeneration
|
||||
After=ignition-ostree-uuid-root.service
|
||||
Before=ignition-ostree-growfs.service
|
||||
Before=ignition-ostree-mount-firstboot-sysroot.service
|
||||
OnFailure=emergency.target
|
||||
OnFailureJobMode=isolate
|
||||
|
||||
ConditionKernelCommandLine=ostree
|
||||
ConditionPathIsDirectory=/run/ignition-ostree-transposefs
|
||||
|
||||
[Service]
|
||||
Type=oneshot
|
||||
RemainAfterExit=yes
|
||||
# So we can transiently mount sysroot
|
||||
MountFlags=slave
|
||||
ExecStart=/usr/libexec/ignition-ostree-transposefs restore
|
@ -0,0 +1,19 @@
|
||||
[Unit]
|
||||
Description=Ignition OSTree: Save Partitions
|
||||
DefaultDependencies=false
|
||||
After=ignition-ostree-transposefs-detect.service
|
||||
Before=ignition-disks.service
|
||||
ConditionKernelCommandLine=ostree
|
||||
ConditionPathIsDirectory=/run/ignition-ostree-transposefs
|
||||
# Any services looking at mounts need to order after this
|
||||
# because it causes device re-probing.
|
||||
After=coreos-gpt-setup.service
|
||||
OnFailure=emergency.target
|
||||
OnFailureJobMode=isolate
|
||||
|
||||
[Service]
|
||||
Type=oneshot
|
||||
RemainAfterExit=yes
|
||||
# So we can transiently mount sysroot
|
||||
MountFlags=slave
|
||||
ExecStart=/usr/libexec/ignition-ostree-transposefs save
|
@ -0,0 +1,299 @@
|
||||
#!/bin/bash
|
||||
set -euo pipefail
|
||||
|
||||
boot_sector_size=440
|
||||
esp_typeguid=c12a7328-f81f-11d2-ba4b-00a0c93ec93b
|
||||
bios_typeguid=21686148-6449-6e6f-744e-656564454649
|
||||
prep_typeguid=9e1a2d38-c612-4316-aa26-8b49521e5a8b
|
||||
|
||||
# This is implementation details of Ignition; in the future, we should figure
|
||||
# out a way to ask Ignition directly whether there's a filesystem with label
|
||||
# "root" being set up.
|
||||
ignition_cfg=/run/ignition.json
|
||||
root_part=/dev/disk/by-label/root
|
||||
boot_part=/dev/disk/by-label/boot
|
||||
esp_part=/dev/disk/by-label/EFI-SYSTEM
|
||||
bios_part=/dev/disk/by-partlabel/BIOS-BOOT
|
||||
prep_part=/dev/disk/by-partlabel/PowerPC-PReP-boot
|
||||
saved_data=/run/ignition-ostree-transposefs
|
||||
saved_root=${saved_data}/root
|
||||
saved_boot=${saved_data}/boot
|
||||
saved_esp=${saved_data}/esp
|
||||
saved_bios=${saved_data}/bios
|
||||
saved_prep=${saved_data}/prep
|
||||
zram_dev=${saved_data}/zram_dev
|
||||
partstate_root=/run/ignition-ostree-rootfs-partstate.sh
|
||||
|
||||
# Print jq query string for wiped filesystems with label $1
|
||||
query_fslabel() {
|
||||
echo ".storage?.filesystems? // [] | map(select(.label == \"$1\" and .wipeFilesystem == true))"
|
||||
}
|
||||
|
||||
# Print jq query string for partitions with type GUID $1
|
||||
query_parttype() {
|
||||
echo ".storage?.disks? // [] | map(.partitions?) | flatten | map(select(try .typeGuid catch \"\" | ascii_downcase == \"$1\"))"
|
||||
}
|
||||
|
||||
# Print partition labels for partitions with type GUID $1
|
||||
get_partlabels_for_parttype() {
|
||||
jq -r "$(query_parttype $1) | .[].label" "${ignition_cfg}"
|
||||
}
|
||||
|
||||
# Mounts device to directory, with extra logging of the src device
|
||||
mount_verbose() {
|
||||
local srcdev=$1; shift
|
||||
local destdir=$1; shift
|
||||
local mode=${1:-ro}
|
||||
echo "Mounting ${srcdev} ${mode} ($(realpath "$srcdev")) to $destdir"
|
||||
mkdir -p "${destdir}"
|
||||
mount -o "${mode}" "${srcdev}" "${destdir}"
|
||||
}
|
||||
|
||||
# Sometimes, for some reason the by-label symlinks aren't updated. Detect these
|
||||
# cases, and explicitly `udevadm trigger`.
|
||||
# See: https://bugzilla.redhat.com/show_bug.cgi?id=1908780
|
||||
udev_trigger_on_label_mismatch() {
|
||||
local label=$1; shift
|
||||
local expected_dev=$1; shift
|
||||
local actual_dev
|
||||
expected_dev=$(realpath "${expected_dev}")
|
||||
# We `|| :` here because sometimes /dev/disk/by-label/$label is missing.
|
||||
# We've seen this on Fedora kernels with debug enabled (common in `rawhide`).
|
||||
# See https://github.com/coreos/fedora-coreos-tracker/issues/1092
|
||||
actual_dev=$(realpath "/dev/disk/by-label/$label" || :)
|
||||
if [ "$actual_dev" != "$expected_dev" ]; then
|
||||
echo "Expected /dev/disk/by-label/$label to point to $expected_dev, but points to $actual_dev; triggering udev"
|
||||
udevadm trigger --settle "$expected_dev"
|
||||
fi
|
||||
}
|
||||
|
||||
# Print partition offset for device node $1
|
||||
get_partition_offset() {
|
||||
local devpath=$(udevadm info --query=path "$1")
|
||||
cat "/sys${devpath}/start"
|
||||
}
|
||||
|
||||
# copied from generator-lib.sh
|
||||
karg() {
|
||||
local name="$1" value="${2:-}"
|
||||
local cmdline=( $(</proc/cmdline) )
|
||||
for arg in "${cmdline[@]}"; do
|
||||
if [[ "${arg%%=*}" == "${name}" ]]; then
|
||||
value="${arg#*=}"
|
||||
fi
|
||||
done
|
||||
echo "${value}"
|
||||
}
|
||||
|
||||
mount_and_restore_filesystem_by_label() {
|
||||
local label=$1; shift
|
||||
local mountpoint=$1; shift
|
||||
local saved_fs=$1; shift
|
||||
local new_dev
|
||||
new_dev=$(jq -r "$(query_fslabel "${label}") | .[0].device" "${ignition_cfg}")
|
||||
udev_trigger_on_label_mismatch "${label}" "${new_dev}"
|
||||
mount_verbose "/dev/disk/by-label/${label}" "${mountpoint}" rw
|
||||
find "${saved_fs}" -mindepth 1 -maxdepth 1 -exec mv -t "${mountpoint}" {} +
|
||||
}
|
||||
|
||||
mount_and_save_filesystem_by_label() {
|
||||
local label=$1; shift
|
||||
local saved_fs=$1; shift
|
||||
local fs=/dev/disk/by-label/${label}
|
||||
if [[ -f /run/coreos/secure-execution ]]; then
|
||||
local roothash_karg=${label}fs.roothash
|
||||
local roothash=$(karg "${roothash_karg}")
|
||||
if [ -z "${roothash}" ]; then
|
||||
echo "Missing kernel argument ${roothash_karg}; aborting"
|
||||
exit 1
|
||||
fi
|
||||
local roothash_part=/dev/disk/by-partlabel/${label}hash
|
||||
veritysetup open "${fs}" "${label}" "${roothash_part}" "${roothash}"
|
||||
fs=/dev/mapper/${label}
|
||||
fi
|
||||
mount_verbose "${fs}" /var/tmp/mnt
|
||||
cp -aT /var/tmp/mnt "${saved_fs}"
|
||||
umount /var/tmp/mnt
|
||||
if [[ -f /run/coreos/secure-execution ]]; then
|
||||
veritysetup close "${label}"
|
||||
fi
|
||||
}
|
||||
|
||||
# In Secure Execution case user is not allowed to modify partition table
|
||||
check_and_set_secex_config() {
|
||||
if [[ -f /run/coreos/secure-execution ]]; then
|
||||
local wr=$(jq "$(query_fslabel root) | length" "${ignition_cfg}")
|
||||
local wb=$(jq "$(query_fslabel boot) | length" "${ignition_cfg}")
|
||||
if [ "${wr}${wb}" != "00" ]; then
|
||||
echo "Modifying bootfs and rootfs is not supported in Secure Execution mode"
|
||||
exit 1
|
||||
fi
|
||||
# Cached config isn't merged, so reset it and recheck again, just to make sure
|
||||
ignition_cfg=/usr/lib/ignition/base.d/01-secex.ign
|
||||
fi
|
||||
}
|
||||
|
||||
# We could have done this during 'detect' below, but other cases also request
|
||||
# info from config, so just check cached one and reset to secex.ign now
|
||||
check_and_set_secex_config
|
||||
|
||||
case "${1:-}" in
|
||||
detect)
|
||||
# Mounts are not in a private namespace so we can mount ${saved_data}
|
||||
wipes_root=$(jq "$(query_fslabel root) | length" "${ignition_cfg}")
|
||||
wipes_boot=$(jq "$(query_fslabel boot) | length" "${ignition_cfg}")
|
||||
creates_esp=$(jq "$(query_parttype ${esp_typeguid}) | length" "${ignition_cfg}")
|
||||
creates_bios=$(jq "$(query_parttype ${bios_typeguid}) | length" "${ignition_cfg}")
|
||||
creates_prep=$(jq "$(query_parttype ${prep_typeguid}) | length" "${ignition_cfg}")
|
||||
if [ "${wipes_root}${wipes_boot}${creates_esp}${creates_bios}${creates_prep}" = "00000" ]; then
|
||||
exit 0
|
||||
fi
|
||||
echo "Detected partition replacement in fetched Ignition config: /run/ignition.json"
|
||||
# verify all ESP, BIOS, and PReP partitions have non-null unique labels
|
||||
unique_esp=$(jq -r "$(query_parttype ${esp_typeguid}) | [.[].label | values] | unique | length" "${ignition_cfg}")
|
||||
unique_bios=$(jq -r "$(query_parttype ${bios_typeguid}) | [.[].label | values] | unique | length" "${ignition_cfg}")
|
||||
unique_prep=$(jq -r "$(query_parttype ${prep_typeguid}) | [.[].label | values] | unique | length" "${ignition_cfg}")
|
||||
if [ "${creates_esp}" != "${unique_esp}" -o "${creates_bios}" != "${unique_bios}" -o "${creates_prep}" != "${unique_prep}" ]; then
|
||||
echo "Found duplicate or missing ESP, BIOS-BOOT, or PReP labels in config" >&2
|
||||
exit 1
|
||||
fi
|
||||
mem_available=$(grep MemAvailable /proc/meminfo | awk '{print $2}')
|
||||
# Just error out early if we don't even have 1G to work with. This
|
||||
# commonly happens if you `cosa run` but forget to add `--memory`. That
|
||||
# way you get a nicer error instead of the spew of EIO errors from `cp`.
|
||||
# The amount we need is really dependent on a bunch of factors, but just
|
||||
# ballpark it at 3G.
|
||||
if [ "${mem_available}" -lt $((1*1024*1024)) ] && [ "${wipes_root}" != 0 ]; then
|
||||
echo "Root reprovisioning requires at least 3G of RAM" >&2
|
||||
exit 1
|
||||
fi
|
||||
modprobe zram num_devices=0
|
||||
read dev < /sys/class/zram-control/hot_add
|
||||
# disksize is set arbitrarily large, as zram is capped by mem_limit
|
||||
echo 10G > /sys/block/zram"${dev}"/disksize
|
||||
# Limit zram to 90% of available RAM: we want to be greedy since the
|
||||
# boot breaks anyway, but we still want to leave room for everything
|
||||
# else so it hits ENOSPC and doesn't invoke the OOM killer
|
||||
echo $(( mem_available * 90 / 100 ))K > /sys/block/zram"${dev}"/mem_limit
|
||||
mkfs.xfs -q /dev/zram"${dev}"
|
||||
mkdir "${saved_data}"
|
||||
mount /dev/zram"${dev}" "${saved_data}"
|
||||
# save the zram device number created for when called to cleanup
|
||||
echo "${dev}" > "${zram_dev}"
|
||||
|
||||
if [ "${wipes_root}" != "0" ]; then
|
||||
mkdir "${saved_root}"
|
||||
fi
|
||||
if [ "${wipes_boot}" != "0" ]; then
|
||||
mkdir "${saved_boot}"
|
||||
fi
|
||||
if [ "${creates_esp}" != "0" ]; then
|
||||
mkdir "${saved_esp}"
|
||||
fi
|
||||
if [ "${creates_bios}" != "0" ]; then
|
||||
mkdir "${saved_bios}"
|
||||
fi
|
||||
if [ "${creates_prep}" != "0" ]; then
|
||||
mkdir "${saved_prep}"
|
||||
fi
|
||||
;;
|
||||
save)
|
||||
# Mounts happen in a private mount namespace since we're not "offically" mounting
|
||||
if [ -d "${saved_root}" ]; then
|
||||
echo "Moving rootfs to RAM..."
|
||||
mount_and_save_filesystem_by_label root "${saved_root}"
|
||||
# also store the state of the partition
|
||||
lsblk "${root_part}" --nodeps --pairs -b --paths -o NAME,TYPE,SIZE > "${partstate_root}"
|
||||
fi
|
||||
if [ -d "${saved_boot}" ]; then
|
||||
echo "Moving bootfs to RAM..."
|
||||
mount_and_save_filesystem_by_label boot "${saved_boot}"
|
||||
fi
|
||||
if [ -d "${saved_esp}" ]; then
|
||||
echo "Moving EFI System Partition to RAM..."
|
||||
mount_verbose "${esp_part}" /sysroot/boot/efi
|
||||
cp -aT /sysroot/boot/efi "${saved_esp}"
|
||||
fi
|
||||
if [ -d "${saved_bios}" ]; then
|
||||
echo "Moving BIOS Boot partition and boot sector to RAM..."
|
||||
# save partition
|
||||
cat "${bios_part}" > "${saved_bios}/partition"
|
||||
# save boot sector
|
||||
bios_disk=$(lsblk --noheadings --output PKNAME --paths "${bios_part}")
|
||||
dd if="${bios_disk}" of="${saved_bios}/boot-sector" bs="${boot_sector_size}" count=1 status=none
|
||||
# store partition start offset so we can check it later
|
||||
get_partition_offset "${bios_part}" > "${saved_bios}/start"
|
||||
fi
|
||||
if [ -d "${saved_prep}" ]; then
|
||||
echo "Moving PReP partition to RAM..."
|
||||
cat "${prep_part}" > "${saved_prep}/partition"
|
||||
fi
|
||||
echo "zram usage:"
|
||||
read dev < "${zram_dev}"
|
||||
cat /sys/block/zram"${dev}"/mm_stat
|
||||
;;
|
||||
restore)
|
||||
# Mounts happen in a private mount namespace since we're not "offically" mounting
|
||||
if [ -d "${saved_root}" ]; then
|
||||
echo "Restoring rootfs from RAM..."
|
||||
mount_and_restore_filesystem_by_label root /sysroot "${saved_root}"
|
||||
chcon -v --reference "${saved_root}" /sysroot # the root of the fs itself
|
||||
chattr +i $(ls -d /sysroot/ostree/deploy/*/deploy/*/)
|
||||
fi
|
||||
if [ -d "${saved_boot}" ]; then
|
||||
echo "Restoring bootfs from RAM..."
|
||||
mount_and_restore_filesystem_by_label boot /sysroot/boot "${saved_boot}"
|
||||
chcon -v --reference "${saved_boot}" /sysroot/boot # the root of the fs itself
|
||||
fi
|
||||
if [ -d "${saved_esp}" ]; then
|
||||
echo "Restoring EFI System Partition from RAM..."
|
||||
get_partlabels_for_parttype "${esp_typeguid}" | while read label; do
|
||||
# Don't use mount_and_restore_filesystem_by_label because:
|
||||
# 1. We're mounting by partlabel, not FS label
|
||||
# 2. We need to copy the contents to each partition, not move
|
||||
# them once
|
||||
# 3. We don't need the by-label symlink to be correct and
|
||||
# nothing later in boot will be mounting the filesystem
|
||||
mountpoint="/mnt/esp-${label}"
|
||||
mount_verbose "/dev/disk/by-partlabel/${label}" "${mountpoint}" rw
|
||||
find "${saved_esp}" -mindepth 1 -maxdepth 1 -exec cp -at "${mountpoint}" {} +
|
||||
done
|
||||
fi
|
||||
if [ -d "${saved_bios}" ]; then
|
||||
echo "Restoring BIOS Boot partition and boot sector from RAM..."
|
||||
expected_start=$(cat "${saved_bios}/start")
|
||||
get_partlabels_for_parttype "${bios_typeguid}" | while read label; do
|
||||
cur_part="/dev/disk/by-partlabel/${label}"
|
||||
# boot sector hardcodes the partition start; ensure it matches
|
||||
cur_start=$(get_partition_offset "${cur_part}")
|
||||
if [ "${cur_start}" != "${expected_start}" ]; then
|
||||
echo "Partition ${cur_part} starts at ${cur_start}; expected ${expected_start}" >&2
|
||||
exit 1
|
||||
fi
|
||||
# copy partition contents
|
||||
cat "${saved_bios}/partition" > "${cur_part}"
|
||||
# copy boot sector
|
||||
cur_disk=$(lsblk --noheadings --output PKNAME --paths "${cur_part}")
|
||||
cat "${saved_bios}/boot-sector" > "${cur_disk}"
|
||||
done
|
||||
fi
|
||||
if [ -d "${saved_prep}" ]; then
|
||||
echo "Restoring PReP partition from RAM..."
|
||||
get_partlabels_for_parttype "${prep_typeguid}" | while read label; do
|
||||
cat "${saved_prep}/partition" > "/dev/disk/by-partlabel/${label}"
|
||||
done
|
||||
fi
|
||||
;;
|
||||
cleanup)
|
||||
# Mounts are not in a private namespace so we can unmount ${saved_data}
|
||||
if [ -d "${saved_data}" ]; then
|
||||
read dev < "${zram_dev}"
|
||||
umount "${saved_data}"
|
||||
rm -rf "${saved_data}" "${partstate_root}"
|
||||
echo "${dev}" > /sys/class/zram-control/hot_remove
|
||||
fi
|
||||
;;
|
||||
*)
|
||||
echo "Unsupported operation: ${1:-}" 1>&2; exit 1
|
||||
;;
|
||||
esac
|
@ -0,0 +1,24 @@
|
||||
[Unit]
|
||||
Description=Ignition OSTree: Regenerate Filesystem UUID (boot)
|
||||
DefaultDependencies=false
|
||||
ConditionPathExists=/usr/lib/initrd-release
|
||||
ConditionKernelCommandLine=ostree
|
||||
ConditionPathExists=!/run/ostree-live
|
||||
# We run pretty early
|
||||
Before=coreos-copy-firstboot-network.service
|
||||
Before=coreos-ignition-setup-user.service
|
||||
Before=ignition-fetch-offline.service
|
||||
# Any services looking at mounts need to order after this
|
||||
# because it causes device re-probing.
|
||||
After=coreos-gpt-setup.service
|
||||
# If we're going to reprovision the bootfs, then there's no need to restamp
|
||||
ConditionKernelCommandLine=!bootfs.roothash
|
||||
|
||||
Before=systemd-fsck@dev-disk-by\x2dlabel-boot.service
|
||||
Requires=dev-disk-by\x2dlabel-boot.device
|
||||
After=dev-disk-by\x2dlabel-boot.device
|
||||
|
||||
[Service]
|
||||
Type=oneshot
|
||||
RemainAfterExit=yes
|
||||
ExecStart=/usr/sbin/ignition-ostree-firstboot-uuid boot
|
@ -0,0 +1,26 @@
|
||||
[Unit]
|
||||
Description=Ignition OSTree: Regenerate Filesystem UUID (root)
|
||||
# These conditions match ignition-ostree-mount-firstboot-sysroot.service
|
||||
DefaultDependencies=false
|
||||
ConditionKernelCommandLine=ostree
|
||||
ConditionPathExists=!/run/ostree-live
|
||||
Before=sysroot.mount initrd-root-fs.target
|
||||
After=ignition-disks.service
|
||||
# If we've reprovisioned the rootfs, then there's no need to restamp
|
||||
ConditionPathExists=!/run/ignition-ostree-transposefs
|
||||
ConditionKernelCommandLine=!rootfs.roothash
|
||||
|
||||
After=dev-disk-by\x2dlabel-root.device
|
||||
# Avoid racing with fsck
|
||||
Before=systemd-fsck@dev-disk-by\x2dlabel-root.service
|
||||
Before=systemd-fsck@dev-disk-by\x2dlabel-dm-mpath-root.service
|
||||
|
||||
# Note we don't have a Requires: /dev/disk/by-label/root here like
|
||||
# the -subsequent service does because ignition-disks may have
|
||||
# regenerated it.
|
||||
Before=ignition-ostree-mount-firstboot-sysroot.service
|
||||
|
||||
[Service]
|
||||
Type=oneshot
|
||||
RemainAfterExit=yes
|
||||
ExecStart=/usr/sbin/ignition-ostree-firstboot-uuid root
|
115
overlay.d/05core/usr/lib/dracut/modules.d/40ignition-ostree/module-setup.sh
Executable file
115
overlay.d/05core/usr/lib/dracut/modules.d/40ignition-ostree/module-setup.sh
Executable file
@ -0,0 +1,115 @@
|
||||
#!/bin/bash
|
||||
# -*- mode: shell-script; indent-tabs-mode: nil; sh-basic-offset: 4; -*-
|
||||
# ex: ts=8 sw=4 sts=4 et filetype=sh
|
||||
|
||||
depends() {
|
||||
echo ignition rdcore
|
||||
}
|
||||
|
||||
install_ignition_unit() {
|
||||
local unit=$1; shift
|
||||
local target=${1:-complete}
|
||||
inst_simple "$moddir/$unit" "$systemdsystemunitdir/$unit"
|
||||
# note we `|| exit 1` here so we error out if e.g. the units are missing
|
||||
# see https://github.com/coreos/fedora-coreos-config/issues/799
|
||||
systemctl -q --root="$initdir" add-requires "ignition-${target}.target" "$unit" || exit 1
|
||||
}
|
||||
|
||||
installkernel() {
|
||||
# Used by ignition-ostree-transposefs
|
||||
instmods -c zram
|
||||
}
|
||||
|
||||
install() {
|
||||
inst_multiple \
|
||||
realpath \
|
||||
setfiles \
|
||||
chcon \
|
||||
systemd-sysusers \
|
||||
systemd-tmpfiles \
|
||||
sort \
|
||||
uniq
|
||||
|
||||
if [[ $(uname -m) = s390x ]]; then
|
||||
# for Secure Execution
|
||||
inst_multiple \
|
||||
veritysetup
|
||||
fi
|
||||
|
||||
# ignition-ostree-growfs deps
|
||||
inst_multiple \
|
||||
basename \
|
||||
blkid \
|
||||
cat \
|
||||
dirname \
|
||||
findmnt \
|
||||
growpart \
|
||||
realpath \
|
||||
resize2fs \
|
||||
tail \
|
||||
tune2fs \
|
||||
touch \
|
||||
xfs_admin \
|
||||
xfs_growfs \
|
||||
wc \
|
||||
wipefs
|
||||
|
||||
# growpart deps
|
||||
# Mostly generated from the following command:
|
||||
# $ bash --rpm-requires /usr/bin/growpart | sort | uniq | grep executable
|
||||
# with a few false positives (rq, rqe, -v) and one missed (mktemp)
|
||||
inst_multiple \
|
||||
awk \
|
||||
cat \
|
||||
dd \
|
||||
grep \
|
||||
mktemp \
|
||||
partx \
|
||||
rm \
|
||||
sed \
|
||||
sfdisk \
|
||||
sgdisk \
|
||||
find
|
||||
|
||||
for x in mount populate; do
|
||||
install_ignition_unit ignition-ostree-${x}-var.service
|
||||
inst_script "$moddir/ignition-ostree-${x}-var.sh" "/usr/sbin/ignition-ostree-${x}-var"
|
||||
done
|
||||
|
||||
inst_simple \
|
||||
/usr/lib/udev/rules.d/90-coreos-device-mapper.rules
|
||||
|
||||
inst_multiple jq chattr
|
||||
inst_script "$moddir/ignition-ostree-transposefs.sh" "/usr/libexec/ignition-ostree-transposefs"
|
||||
for x in detect save restore; do
|
||||
install_ignition_unit ignition-ostree-transposefs-${x}.service
|
||||
done
|
||||
|
||||
# Disk support
|
||||
install_ignition_unit ignition-ostree-mount-firstboot-sysroot.service diskful
|
||||
for p in boot root; do
|
||||
install_ignition_unit ignition-ostree-uuid-${p}.service diskful
|
||||
done
|
||||
inst_script "$moddir/ignition-ostree-firstboot-uuid" \
|
||||
"/usr/sbin/ignition-ostree-firstboot-uuid"
|
||||
install_ignition_unit ignition-ostree-mount-subsequent-sysroot.service diskful-subsequent
|
||||
inst_script "$moddir/ignition-ostree-mount-sysroot.sh" \
|
||||
"/usr/sbin/ignition-ostree-mount-sysroot"
|
||||
inst_script "$moddir/coreos-rootflags.sh" \
|
||||
"/usr/sbin/coreos-rootflags"
|
||||
|
||||
install_ignition_unit ignition-ostree-growfs.service
|
||||
inst_script "$moddir/ignition-ostree-growfs.sh" \
|
||||
/usr/sbin/ignition-ostree-growfs
|
||||
|
||||
install_ignition_unit ignition-ostree-check-rootfs-size.service
|
||||
inst_script "$moddir/coreos-check-rootfs-size" \
|
||||
/usr/libexec/coreos-check-rootfs-size
|
||||
|
||||
inst_script "$moddir/coreos-relabel" /usr/bin/coreos-relabel
|
||||
|
||||
# Workaround for https://bugzilla.redhat.com/show_bug.cgi?id=2075085
|
||||
install_ignition_unit ignition-ostree-secex-config.service
|
||||
inst_script "$moddir/ignition-ostree-secex-config.sh" \
|
||||
/usr/libexec/ignition-ostree-secex-config
|
||||
}
|
@ -0,0 +1,10 @@
|
||||
[Unit]
|
||||
Description=Check that initrd matches kernel
|
||||
DefaultDependencies=false
|
||||
Before=sysinit.target systemd-modules-load.service
|
||||
ConditionPathIsDirectory=!/usr/lib/modules/%v
|
||||
|
||||
[Service]
|
||||
Type=oneshot
|
||||
RemainAfterExit=yes
|
||||
ExecStart=/bin/false
|
@ -0,0 +1,15 @@
|
||||
install_unit() {
|
||||
unit="$1"; shift
|
||||
target="$1"; shift
|
||||
inst_simple "$moddir/$unit" "$systemdsystemunitdir/$unit"
|
||||
# note we `|| exit 1` here so we error out if e.g. the units are missing
|
||||
# see https://github.com/coreos/fedora-coreos-config/issues/799
|
||||
systemctl -q --root="$initdir" add-requires "$target" "$unit" || exit 1
|
||||
}
|
||||
|
||||
install() {
|
||||
inst_multiple \
|
||||
false
|
||||
|
||||
install_unit "coreos-check-kernel.service" "sysinit.target"
|
||||
}
|
@ -0,0 +1,13 @@
|
||||
# Temporary hack to work around agetty SELinux denials.
|
||||
# https://github.com/coreos/fedora-coreos-config/pull/859#issuecomment-783713383
|
||||
# https://bugzilla.redhat.com/show_bug.cgi?id=1932053
|
||||
[Unit]
|
||||
Description=CoreOS: Touch /run/agetty.reload
|
||||
Documentation=https://bugzilla.redhat.com/show_bug.cgi?id=1932053
|
||||
DefaultDependencies=false
|
||||
Before=initrd.target
|
||||
|
||||
[Service]
|
||||
Type=oneshot
|
||||
RemainAfterExit=yes
|
||||
ExecStart=/usr/bin/touch /run/agetty.reload
|
@ -0,0 +1,21 @@
|
||||
#!/bin/bash
|
||||
# -*- mode: shell-script; indent-tabs-mode: nil; sh-basic-offset: 4; -*-
|
||||
# ex: ts=8 sw=4 sts=4 et filetype=sh
|
||||
|
||||
# Temporary workaround for https://bugzilla.redhat.com/show_bug.cgi?id=1932053.
|
||||
|
||||
install_unit() {
|
||||
local unit=$1; shift
|
||||
inst_simple "$moddir/$unit" "$systemdsystemunitdir/$unit"
|
||||
# note we `|| exit 1` here so we error out if e.g. the units are missing
|
||||
# see https://github.com/coreos/fedora-coreos-config/issues/799
|
||||
systemctl -q --root="$initdir" add-requires initrd.target "$unit" || exit 1
|
||||
}
|
||||
|
||||
install() {
|
||||
inst_multiple \
|
||||
touch
|
||||
|
||||
# TODO f35: check if we can drop this whole module
|
||||
install_unit coreos-touch-run-agetty.service
|
||||
}
|
@ -0,0 +1,78 @@
|
||||
# Display relevant errors then enter emergency shell
|
||||
|
||||
# _wait_for_journalctl_to_stop will block until either:
|
||||
# - no messages have appeared in journalctl for the past 5 seconds
|
||||
# - 15 seconds have elapsed
|
||||
_wait_for_journalctl_to_stop() {
|
||||
local time_since_last_log=0
|
||||
|
||||
local time_started="$(date '+%s')"
|
||||
local now="$(date '+%s')"
|
||||
|
||||
while [ ${time_since_last_log} -lt 5 -a $((now-time_started)) -lt 15 ]; do
|
||||
sleep 1
|
||||
|
||||
local last_log_timestamp="$(journalctl -e -n 1 -q -o short-unix | cut -d '.' -f 1)"
|
||||
local now="$(date '+%s')"
|
||||
|
||||
local time_since_last_log=$((now-last_log_timestamp))
|
||||
done
|
||||
}
|
||||
|
||||
_display_relevant_errors() {
|
||||
failed=$(systemctl --failed --no-legend --plain | cut -f 1 -d ' ')
|
||||
if [ -n "${failed}" ]; then
|
||||
# Something failed, suppress kernel logs so that it's more likely
|
||||
# the useful bits from the journal are available.
|
||||
dmesg --console-off
|
||||
|
||||
# There's a couple straggler systemd messages. Wait until it's been 5
|
||||
# seconds since something was written to the journal.
|
||||
_wait_for_journalctl_to_stop
|
||||
|
||||
# Print Ignition logs
|
||||
if echo ${failed} | grep -qFe 'ignition-'; then
|
||||
cat <<EOF
|
||||
------
|
||||
Ignition has failed. Please ensure your config is valid. Note that only
|
||||
Ignition spec v3.0.0+ configs are accepted.
|
||||
|
||||
A CLI validation tool to check this called ignition-validate can be
|
||||
downloaded from GitHub:
|
||||
https://github.com/coreos/ignition/releases
|
||||
------
|
||||
|
||||
EOF
|
||||
fi
|
||||
|
||||
# If this is a live boot, check for ENOSPC in initramfs filesystem
|
||||
# Try creating a 64 KiB file, in case a small file was deleted on
|
||||
# service failure
|
||||
# https://github.com/coreos/fedora-coreos-tracker/issues/1055
|
||||
if [ -f /etc/coreos-live-initramfs ] && \
|
||||
! dd if=/dev/zero of=/tmp/check-space bs=4K count=16 2>/dev/null; then
|
||||
cat <<EOF
|
||||
------
|
||||
Ran out of memory when unpacking initrd filesystem. Ensure your system has
|
||||
at least 2 GiB RAM if booting with coreos.live.rootfs_url, or 4 GiB otherwise.
|
||||
------
|
||||
|
||||
EOF
|
||||
# Don't show logs from failed units, since they'll just be
|
||||
# random misleading errors.
|
||||
else
|
||||
echo "Displaying logs from failed units: ${failed}"
|
||||
for unit in ${failed}; do
|
||||
# 10 lines should be enough for everyone
|
||||
SYSTEMD_COLORS=true journalctl -b --no-pager --no-hostname -u ${unit} -n 10
|
||||
done
|
||||
fi
|
||||
fi
|
||||
}
|
||||
|
||||
# Print warnings/informational messages to all configured consoles on the
|
||||
# machine. Code inspired by https://github.com/dracutdevs/dracut/commit/32f68c1
|
||||
MESSAGE="$(_display_relevant_errors)"
|
||||
while read -r _tty rest; do
|
||||
echo -e "$MESSAGE" > /dev/"$_tty"
|
||||
done < /proc/consoles
|
@ -0,0 +1,16 @@
|
||||
[Unit]
|
||||
Description=Dump journal to virtio port
|
||||
ConditionPathExists=/etc/initrd-release
|
||||
DefaultDependencies=false
|
||||
ConditionVirtualization=|kvm
|
||||
ConditionVirtualization=|qemu
|
||||
Requires=systemd-journald.service
|
||||
After=systemd-journald.service
|
||||
After=basic.target
|
||||
Before=initrd.target
|
||||
|
||||
[Service]
|
||||
Type=oneshot
|
||||
RemainAfterExit=yes
|
||||
EnvironmentFile=/run/ignition.env
|
||||
ExecStart=/usr/bin/ignition-virtio-dump-journal
|
@ -0,0 +1,13 @@
|
||||
#!/bin/bash
|
||||
set -euo pipefail
|
||||
|
||||
port=/dev/virtio-ports/com.coreos.ignition.journal
|
||||
if [ -e "${port}" ]; then
|
||||
# Sync to backing filesystem before dumping what's there
|
||||
journalctl --sync
|
||||
journalctl -o json > "${port}"
|
||||
# And this signals end of stream
|
||||
echo '{}' > "${port}"
|
||||
else
|
||||
echo "Didn't find virtio port ${port}"
|
||||
fi
|
@ -0,0 +1,25 @@
|
||||
#!/bin/bash
|
||||
# -*- mode: shell-script; indent-tabs-mode: nil; sh-basic-offset: 4; -*-
|
||||
# ex: ts=8 sw=4 sts=4 et filetype=sh
|
||||
|
||||
install_unit_wants() {
|
||||
local unit="$1"; shift
|
||||
local target="$1"; shift
|
||||
local instantiated="${1:-$unit}"; shift
|
||||
inst_simple "$moddir/$unit" "$systemdsystemunitdir/$unit"
|
||||
# note we `|| exit 1` here so we error out if e.g. the units are missing
|
||||
# see https://github.com/coreos/fedora-coreos-config/issues/799
|
||||
systemctl -q --root="$initdir" add-wants "$target" "$instantiated" || exit 1
|
||||
}
|
||||
|
||||
install() {
|
||||
inst_multiple \
|
||||
cut \
|
||||
date \
|
||||
dd
|
||||
|
||||
inst_hook emergency 99 "${moddir}/emergency-shell.sh"
|
||||
|
||||
inst_script "$moddir/ignition-virtio-dump-journal.sh" "/usr/bin/ignition-virtio-dump-journal"
|
||||
install_unit_wants ignition-virtio-dump-journal.service emergency.target
|
||||
}
|
@ -0,0 +1,12 @@
|
||||
[Journal]
|
||||
# For now we are using kmsg for multiplexing output to
|
||||
# multiple console devices during early boot.
|
||||
#
|
||||
# We do not want to use kmsg in the future as there may be sensitive
|
||||
# ignition data that leaks to non-root users (by reading the kernel
|
||||
# ring buffer using `dmesg`). In the future we will rely on kernel
|
||||
# console multiplexing (link below) for this and will not use kmsg.
|
||||
#
|
||||
# https://github.com/coreos/fedora-coreos-tracker/issues/136
|
||||
ForwardToKMsg=yes
|
||||
MaxLevelKMsg=info
|
12
overlay.d/05core/usr/lib/dracut/modules.d/99journal-conf/module-setup.sh
Executable file
12
overlay.d/05core/usr/lib/dracut/modules.d/99journal-conf/module-setup.sh
Executable file
@ -0,0 +1,12 @@
|
||||
#!/bin/bash
|
||||
# -*- mode: shell-script; indent-tabs-mode: nil; sh-basic-offset: 4; -*-
|
||||
# ex: ts=8 sw=4 sts=4 et filetype=sh
|
||||
|
||||
depends() {
|
||||
echo systemd
|
||||
}
|
||||
|
||||
install() {
|
||||
inst_simple "$moddir/00-journal-log-forwarding.conf" \
|
||||
"/etc/systemd/journald.conf.d/00-journal-log-forwarding.conf"
|
||||
}
|
@ -0,0 +1,3 @@
|
||||
# See also 10coreos-sysctl dracut module, which turns off ratelimiting in the
|
||||
# initrd.
|
||||
kernel.printk_devkmsg = ratelimit
|
@ -0,0 +1,6 @@
|
||||
# Hardcode persistent journal by default. journald has this "auto" behaviour
|
||||
# that only makes logs persistent if `/var/log/journal` exists, which it won't
|
||||
# on first boot because `/var` isn't fully populated. We should be able to get
|
||||
# rid of this once we move to sysusers and create the dir in the initrd.
|
||||
[Journal]
|
||||
Storage=persistent
|
115
overlay.d/05core/usr/lib/systemd/system-generators/coreos-boot-mount-generator
Executable file
115
overlay.d/05core/usr/lib/systemd/system-generators/coreos-boot-mount-generator
Executable file
@ -0,0 +1,115 @@
|
||||
#!/bin/bash
|
||||
export PATH="/usr/bin:/usr/sbin:${PATH}"
|
||||
set -euo pipefail
|
||||
|
||||
. /usr/lib/coreos/generator-lib.sh
|
||||
|
||||
# Turn out if you boot with "root=..." $UNIT_DIR is not writable.
|
||||
[ -w "${UNIT_DIR}" ] || {
|
||||
echo "skipping coreos-boot-mount-generator: ${UNIT_DIR} is not writable"
|
||||
exit 0
|
||||
}
|
||||
|
||||
# If there's already an /etc/fstab entries for /boot, then this is is a non-FCOS
|
||||
# system, likely RHCOS pre-4.3 (which still used Anaconda). In that case, we
|
||||
# don't want to overwrite what the systemd-fstab-generator will do.
|
||||
if findmnt --fstab /boot &>/dev/null; then
|
||||
exit 0
|
||||
fi
|
||||
|
||||
# Don't create mount units for /boot on live systems.
|
||||
# ConditionPathExists won't work here because conditions don't affect
|
||||
# the dependency on the underlying device unit.
|
||||
if [ -f /run/ostree-live ]; then
|
||||
exit 0
|
||||
fi
|
||||
|
||||
add_wants() {
|
||||
local name="$1"; shift
|
||||
local wants_dir="${UNIT_DIR}/local-fs.target.wants"
|
||||
mkdir -p "${wants_dir}"
|
||||
ln -sf "../${name}" "${wants_dir}/${name}"
|
||||
}
|
||||
|
||||
# Generate mount units that work with device mapper. The traditional
|
||||
# device unit (dev-disk-by\x2dlabel...) does not work since it is not the
|
||||
# device that systemd will fsck. This code ensures that if the label
|
||||
# is backed by a device-mapper target the dev-mapper.*.device is used.
|
||||
mk_mount() {
|
||||
local mount_pt="${1}"; shift
|
||||
local path="${1}"; shift
|
||||
local options="${1}"; shift
|
||||
|
||||
local devservice=$(systemd-escape -p ${path} --suffix=service)
|
||||
local unit_name=$(systemd-escape -p ${mount_pt} --suffix=mount)
|
||||
|
||||
cat > "${UNIT_DIR}/${unit_name}" <<EOF
|
||||
# Automatically created by coreos-boot-mount-generator
|
||||
[Unit]
|
||||
Description=CoreOS Dynamic Mount for ${mount_pt}
|
||||
Documentation=https://github.com/coreos/fedora-coreos-config
|
||||
|
||||
Before=local-fs.target
|
||||
Requires=systemd-fsck@${devservice}
|
||||
After=systemd-fsck@${devservice}
|
||||
|
||||
[Mount]
|
||||
What=${path}
|
||||
Where=${mount_pt}
|
||||
Options=${options}
|
||||
EOF
|
||||
add_wants "${unit_name}"
|
||||
}
|
||||
|
||||
# Copied from
|
||||
# https://github.com/dracutdevs/dracut/blob/9491e599282d0d6bb12063eddbd192c0d2ce8acf/modules.d/99base/dracut-lib.sh#L586
|
||||
# rather than sourcing it.
|
||||
label_uuid_to_dev() {
|
||||
local _dev
|
||||
_dev="${1#block:}"
|
||||
case "$_dev" in
|
||||
LABEL=*)
|
||||
echo "/dev/disk/by-label/$(echo "${_dev#LABEL=}" | sed 's,/,\\x2f,g;s, ,\\x20,g')"
|
||||
;;
|
||||
PARTLABEL=*)
|
||||
echo "/dev/disk/by-partlabel/$(echo "${_dev#PARTLABEL=}" | sed 's,/,\\x2f,g;s, ,\\x20,g')"
|
||||
;;
|
||||
UUID=*)
|
||||
echo "/dev/disk/by-uuid/$(echo "${_dev#UUID=}" | tr "[:upper:]" "[:lower:]")"
|
||||
;;
|
||||
PARTUUID=*)
|
||||
echo "/dev/disk/by-partuuid/$(echo "${_dev#PARTUUID=}" | tr "[:upper:]" "[:lower:]")"
|
||||
;;
|
||||
esac
|
||||
}
|
||||
|
||||
# If the root device is multipath, hook up /boot to use that too,
|
||||
# based on our custom udev rules in 90-coreos-device-mapper.rules
|
||||
# that creates "label found on mpath" links.
|
||||
# Otherwise, use the usual by-label symlink.
|
||||
# See discussion in https://github.com/coreos/fedora-coreos-config/pull/1022
|
||||
bootdev=/dev/disk/by-label/boot
|
||||
bootkarg=$(karg boot)
|
||||
mpath=$(karg rd.multipath)
|
||||
if [ -n "${mpath}" ] && [ "${mpath}" != 0 ]; then
|
||||
bootdev=/dev/disk/by-label/dm-mpath-boot
|
||||
# Newer nodes inject boot=UUID=..., but we support a larger subset of the dracut/fips API
|
||||
elif [ -n "${bootkarg}" ]; then
|
||||
# Adapted from https://github.com/dracutdevs/dracut/blob/9491e599282d0d6bb12063eddbd192c0d2ce8acf/modules.d/01fips/fips.sh#L17
|
||||
case "$bootkarg" in
|
||||
LABEL=* | UUID=* | PARTUUID=* | PARTLABEL=*)
|
||||
bootdev="$(label_uuid_to_dev "$bootkarg")";;
|
||||
/dev/*) bootdev=$bootkarg;;
|
||||
*) echo "Unknown boot karg '${bootkarg}'; falling back to ${bootdev}";;
|
||||
esac
|
||||
# This is used for the first boot only
|
||||
elif [ -f /run/coreos/bootfs_uuid ]; then
|
||||
bootdev=/dev/disk/by-uuid/$(cat /run/coreos/bootfs_uuid)
|
||||
fi
|
||||
|
||||
# We mount read-only by default mostly to protect
|
||||
# against accidental damage. Only a few things
|
||||
# owned by CoreOS should be touching /boot or the ESP.
|
||||
# Use nodev,nosuid because some hardening guides want
|
||||
# that even though it's of minimal value.
|
||||
mk_mount /boot "${bootdev}" ro,nodev,nosuid
|
@ -0,0 +1,105 @@
|
||||
#!/bin/bash
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
. /usr/lib/coreos/generator-lib.sh
|
||||
|
||||
write_dropin() {
|
||||
local service="$1"; shift
|
||||
local args="$1"; shift
|
||||
|
||||
local out_dir="${UNIT_DIR}/${service}.d"
|
||||
mkdir -p "${out_dir}"
|
||||
|
||||
# /tmp isn't r/w yet, and the shell needs to cache the here-document
|
||||
TMPDIR=/run
|
||||
cat > "${out_dir}/10-autologin.conf" <<EOF
|
||||
[Service]
|
||||
ExecStart=
|
||||
ExecStart=-/sbin/agetty --autologin core -o '-p -f core' ${args} %I \$TERM
|
||||
EOF
|
||||
}
|
||||
|
||||
quiet_kernel_console_messages() {
|
||||
cat <<'EOF' > /etc/sysctl.d/20-coreos-autologin-kernel-printk.conf
|
||||
# Raise console message logging level from DEBUG (7) to WARNING (4)
|
||||
# so that kernel debug message don't get interspersed on the console
|
||||
# that
|
||||
# may frustrate a user trying to interactively do an install with
|
||||
# nmtui and coreos-installer.
|
||||
kernel.printk=4
|
||||
EOF
|
||||
}
|
||||
|
||||
write_interactive_live_motd() {
|
||||
# Write motd to a tmp file and not directly to /etc/motd because
|
||||
# SELinux denies write from init_t to etc_t
|
||||
cat <<EOF > /run/interactive-live-motd
|
||||
|
||||
###########################################################################
|
||||
Welcome to the CoreOS live environment. This system is running completely
|
||||
from memory, making it a good candidate for hardware discovery and
|
||||
installing persistently to disk. Here is an example of running an install
|
||||
to disk via coreos-installer:
|
||||
|
||||
sudo coreos-installer install /dev/sda \\
|
||||
--ignition-url https://example.com/example.ign
|
||||
|
||||
You may configure networking via 'sudo nmcli' or 'sudo nmtui' and have
|
||||
that configuration persist into the installed system by passing the
|
||||
'--copy-network' argument to 'coreos-installer install'. Please run
|
||||
'coreos-installer install --help' for more information on the possible
|
||||
install options.
|
||||
###########################################################################
|
||||
|
||||
EOF
|
||||
# Create coreos-cp-interactive-live-motd.service to copy over the motd in
|
||||
# place. Note this intentionally overwrites the existing motd, which is
|
||||
# blank on FCOS and populated on RHCOS.
|
||||
service="coreos-cp-interactive-live-motd.service"
|
||||
cat <<EOF > "${UNIT_DIR}/${service}"
|
||||
# generated by coreos-liveiso-autologin-generator
|
||||
[Unit]
|
||||
Description=Copy CoreOS Interactive Live MOTD
|
||||
Before=systemd-user-sessions.service
|
||||
[Service]
|
||||
Type=oneshot
|
||||
RemainAfterExit=yes
|
||||
ExecStart=/bin/cp -v /run/interactive-live-motd /etc/motd
|
||||
EOF
|
||||
mkdir -p "${UNIT_DIR}/multi-user.target.wants"
|
||||
ln -sf "../${service}" "${UNIT_DIR}/multi-user.target.wants/"
|
||||
}
|
||||
|
||||
# Only allow automatic autologin on live systems
|
||||
if [ ! -e /run/ostree-live ]; then
|
||||
exit 0
|
||||
fi
|
||||
|
||||
# Autologin on ISO boots but not PXE boots. The only way to tell the
|
||||
# difference is a kernel argument.
|
||||
if ! have_karg coreos.liveiso; then
|
||||
exit 0
|
||||
fi
|
||||
|
||||
# If the user supplied an Ignition config, they have the ability to enable
|
||||
# autologin themselves. Don't automatically render them insecure, since
|
||||
# they might be running in production and booting via e.g. IPMI.
|
||||
if jq -e .userConfigProvided /etc/.ignition-result.json &>/dev/null; then
|
||||
exit 0
|
||||
fi
|
||||
|
||||
write_dropin "getty@.service" "--noclear"
|
||||
# Also autologin on serial console if someone enables that
|
||||
write_dropin "serial-getty@.service" "--keep-baud 115200,38400,9600"
|
||||
|
||||
# When the installer runs a lot of things happen on the system (audit
|
||||
# messages from running via sudo, re-reading partition table messages,
|
||||
# mounting filesystem messages, etc.). Quieting the verbosity of the
|
||||
# kernel console will help us keep our sanity.
|
||||
quiet_kernel_console_messages
|
||||
|
||||
|
||||
# Write an motd that will let the user know about the live environment
|
||||
# and what is possible.
|
||||
write_interactive_live_motd
|
@ -0,0 +1,16 @@
|
||||
# This file contains overrides for systemd services that are
|
||||
# enabled by default, but conflict with things we ship.
|
||||
|
||||
# We don't have swap by default, and systemd-oomd hard requires it.
|
||||
disable systemd-oomd.service
|
||||
|
||||
# Disable systemd-firstboot because it conflicts with Ignition.
|
||||
# In most cases this is handled via the remove-from-packages
|
||||
# bits in the manifest (ignition-and-ostree.yaml), but
|
||||
# we want to support overlaying builds of systemd from git.
|
||||
disable systemd-firstboot.service
|
||||
|
||||
# This hasn't been tested with ostree/rpm-ostree and heavily overlaps
|
||||
# with the latter. Preemptively disable the service; it will hopefully
|
||||
# be subpackaged though for Fedora.
|
||||
disable systemd-sysext.service
|
@ -0,0 +1,34 @@
|
||||
# Presets here that eventually should live in the generic fedora presets
|
||||
|
||||
# console-login-helper-messages - https://github.com/coreos/console-login-helper-messages
|
||||
enable console-login-helper-messages-gensnippet-os-release.service
|
||||
enable console-login-helper-messages-gensnippet-ssh-keys.service
|
||||
# CA certs (probably to add to base fedora eventually)
|
||||
enable coreos-update-ca-trust.service
|
||||
# Set kernel console log level
|
||||
enable coreos-printk-quiet.service
|
||||
# https://github.com/coreos/ignition/issues/1125
|
||||
enable coreos-ignition-firstboot-complete.service
|
||||
# Delete Ignition config from provider on platforms where it's possible
|
||||
# https://github.com/coreos/ignition/pull/1350
|
||||
enable ignition-delete-config.service
|
||||
# Delete Ignition config from provider when upgrading existing nodes
|
||||
enable coreos-ignition-delete-config.service
|
||||
# Boot checkin services for cloud providers.
|
||||
enable afterburn-checkin.service
|
||||
enable afterburn-firstboot-checkin.service
|
||||
# Target to write SSH key snippets from cloud providers.
|
||||
enable afterburn-sshkeys.target
|
||||
# Update agent
|
||||
enable zincati.service
|
||||
# Testing aid
|
||||
enable coreos-liveiso-success.service
|
||||
# See bootupd.yaml
|
||||
enable bootupd.socket
|
||||
# Enable rtas_errd for ppc64le to discover dynamically attached pci devices - https://bugzilla.redhat.com/show_bug.cgi?id=1811537
|
||||
# The event for the attached device comes as a diag event.
|
||||
# Ideally it should have been added as part of base Fedora - but since it was arch specific, it was not added: https://bugzilla.redhat.com/show_bug.cgi?id=1433859
|
||||
enable rtas_errd.service
|
||||
enable clevis-luks-askpass.path
|
||||
# Provide status information about the Ignition run
|
||||
enable coreos-ignition-write-issues.service
|
@ -0,0 +1,28 @@
|
||||
# Can be removed from FCOS in Fedora 37 or after the next barrier release,
|
||||
# whichever comes first. Can be removed from RHCOS in the first release
|
||||
# after every node is guaranteed to have booted at least once with 4.11 or
|
||||
# higher.
|
||||
|
||||
[Unit]
|
||||
Description=CoreOS Delete Ignition Config From Hypervisor
|
||||
Documentation=https://coreos.github.io/ignition/
|
||||
|
||||
ConditionKernelCommandLine=|ignition.platform.id=virtualbox
|
||||
ConditionKernelCommandLine=|ignition.platform.id=vmware
|
||||
ConditionPathExists=!/var/lib/coreos-ignition-delete-config.stamp
|
||||
# Hack: if the user masked ignition-delete-config.service, we shouldn't run
|
||||
# either.
|
||||
ConditionPathIsSymbolicLink=!/etc/systemd/system/ignition-delete-config.service
|
||||
|
||||
# We check a stamp file written by ignition-delete-config.service. That
|
||||
# service runs Before=sysinit.target, on which we have a default dependency,
|
||||
# so this is really just documentation.
|
||||
After=ignition-delete-config.service
|
||||
|
||||
[Service]
|
||||
Type=oneshot
|
||||
ExecStart=/usr/libexec/coreos-ignition-delete-config
|
||||
RemainAfterExit=yes
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
@ -0,0 +1,21 @@
|
||||
[Unit]
|
||||
Description=CoreOS Mark Ignition Boot Complete
|
||||
Documentation=https://docs.fedoraproject.org/en-US/fedora-coreos/
|
||||
ConditionKernelCommandLine=ignition.firstboot
|
||||
ConditionPathExists=!/run/ostree-live
|
||||
RequiresMountsFor=/boot
|
||||
|
||||
[Service]
|
||||
Type=oneshot
|
||||
RemainAfterExit=yes
|
||||
# The MountFlags=slave is so we remount /boot temporarily writable;
|
||||
# see https://github.com/ostreedev/ostree/issues/1265 for the bigger picture.
|
||||
# This option creates a new mount namespace; from the point of view of
|
||||
# everything else, /boot stays readonly. We only have a transient writable mount
|
||||
# for the lifetime of the unit.
|
||||
MountFlags=slave
|
||||
ExecStart=/usr/libexec/coreos-ignition-firstboot-complete
|
||||
|
||||
[Install]
|
||||
# Part of basic.target so this happens early on in firstboot
|
||||
WantedBy=basic.target
|
@ -0,0 +1,16 @@
|
||||
# This service writes issue files describing status
|
||||
# information about the Ignition run, which includes
|
||||
# Ignition warnings and information if no Ignition
|
||||
# config is provided.
|
||||
[Unit]
|
||||
Description=Create Ignition Status Issue Files
|
||||
Before=systemd-user-sessions.service
|
||||
ConditionPathExists=/etc/.ignition-result.json
|
||||
|
||||
[Service]
|
||||
Type=oneshot
|
||||
ExecStart=/usr/libexec/coreos-ignition-write-issues
|
||||
RemainAfterExit=yes
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
@ -0,0 +1,26 @@
|
||||
# This is used by our test framework in coreos-assembler
|
||||
# since for the "live ISO without Ignition" case we
|
||||
# don't have an easy way to test it.
|
||||
[Unit]
|
||||
Description=CoreOS Live ISO virtio success
|
||||
Documentation=https://github.com/coreos/fedora-coreos-config
|
||||
# Only run on the Live ISO, and only if there's no Ignition config
|
||||
ConditionKernelCommandLine=coreos.liveiso
|
||||
ConditionPathExists=!/config.ign
|
||||
ConditionVirtualization=|kvm
|
||||
ConditionVirtualization=|qemu
|
||||
# Start running late to help ensure that the below conditional works
|
||||
After=systemd-user-sessions.service
|
||||
ConditionPathExists=/dev/virtio-ports/coreos.liveiso-success
|
||||
|
||||
[Service]
|
||||
Type=simple
|
||||
# Wait for a user session to start, then write a static message to the
|
||||
# virtio channel, which https://github.com/coreos/coreos-assembler/pull/1330
|
||||
# knows how to read. We previously did "journalctl -f ... | head -1" here,
|
||||
# but RHEL 8 has systemd 239, which has
|
||||
# https://github.com/systemd/systemd/issues/9374.
|
||||
ExecStart=/bin/sh -c 'while [ -z "$(loginctl list-sessions --no-legend)" ]; do sleep 1; done; echo coreos-liveiso-success > /dev/virtio-ports/coreos.liveiso-success'
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
@ -0,0 +1,27 @@
|
||||
[Unit]
|
||||
Description=CoreOS: Set printk To Level 4 (warn)
|
||||
Documentation=https://github.com/coreos/fedora-coreos-tracker/issues/1244
|
||||
# We can run right after `/proc` being mounted at least
|
||||
DefaultDependencies=no
|
||||
# We run as early as possible; the only dependency we have really
|
||||
# is the implicit After=systemd-journald.socket injected by the
|
||||
# default of our stdout writing to the journal.
|
||||
Conflicts=shutdown.target
|
||||
Before=sysinit.target shutdown.target
|
||||
# We want this service to read what we wrote
|
||||
Before=systemd-sysctl.service
|
||||
# Relatedly, we don't want to override an explicitly specified kernel argument
|
||||
ConditionKernelCommandLine=!debug
|
||||
ConditionKernelCommandLine=!quiet
|
||||
ConditionKernelCommandLine=!loglevel
|
||||
|
||||
[Service]
|
||||
Type=oneshot
|
||||
RemainAfterExit=yes
|
||||
# We need to make /run/sysctl.d if it doesn't exist and also
|
||||
# ensure it has a SELinux label that works for systemd-sysctl.service.
|
||||
# Then we just generate a sysctl file which is read by systemd-sysctl.service.
|
||||
ExecStart=/bin/bash -euo pipefail -c 'mkdir -p /run/sysctl.d && chcon --reference=/etc/sysctl.d /run/sysctl.d && echo "kernel.printk = 4" > /run/sysctl.d/01-coreos-printk.conf'
|
||||
|
||||
[Install]
|
||||
WantedBy=sysinit.target
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user