r8 branch init

This commit is contained in:
Neil Hanlon 2022-10-20 19:51:23 -04:00
commit a7e5a729ce
Signed by: neil
GPG Key ID: 705BC21EC3C70F34
147 changed files with 4696 additions and 0 deletions

4
.gitignore vendored Normal file
View File

@ -0,0 +1,4 @@
build/
.direnv/
.envrc
ass

201
LICENSE Normal file
View File

@ -0,0 +1,201 @@
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "[]"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright [yyyy] [name of copyright owner]
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

33
README.md Normal file
View File

@ -0,0 +1,33 @@
# Rocky Linux Ostree
This repository contains all the bits to get a working Ostree for Rocky Linux (8.6). Although Fedora and Red Hat CoreOS use (rpm)Ostree, this is NOT a CoreOS clone.
If you want to build a Rocky Linux CoreOS, in other words a Red Hat CoreOS clone, then checkout [coreos-assembler](https://coreos.github.io/rpm-ostree/compose-server). Other sites with information about CoreOS and building custom OStree(s):
* https://coreos.github.io/rpm-ostree/compose-server/
* https://www.osbuild.org/
Especially osbuild is a very nice project/tool which is now incorperated in the more recent Red Hat versions.
## Dir: bootserver
Contains an Ansible playbook to configure a PXE bootserver
## Dir: ostree-config
Contains the config files to build a basic Ostree for Rocky Linux
# How to use
From the root directory of this project:
* Create a build directory with the repo and cache directory below it. The repo directory will have the final OStree repository where you could boot from.
* Initialize the ./build/repo directory as a OStree repository
* Build the OStree repo
```
mkdir -p ./build/{repo,cache}
ostree --repo=./build/repo init --mode=archive
sudo rpm-ostree --unified-core compose tree --cachedir=./build/cache --repo=./build/repo config/manifest.yaml
```
When the compose state is finished, rsync the repo to the bootserver and network boot from it.
```
sudo rsync -av --delete ./build/repo root@192.168.122.89:/var/www/html/ostree/
```

12
build.sh Executable file
View File

@ -0,0 +1,12 @@
#!/bin/bash
Error () {
echo "Oops, something did not work"
exit 101
}
sudo rm -rf ./build || Error
mkdir -p ./build/{repo,cache} || Error
ostree --repo=build/repo init --mode=archive || Error
sudo rpm-ostree compoe tree --unified-core --cachedir=./build/cache --repo=./build/repo config/manifest.yaml || Error
sudo rsync -av --delete ./build/repo root@192.168.122.89:/var/www/html/ostree/ || Error

6
commands.txt Normal file
View File

@ -0,0 +1,6 @@
Commands/notes
ostree --repo=./build/repo ls rocky/x86_64/ostree
ostree --repo=./build/repo ls rocky/x86_64/ostree /etc
ostree --repo=./build/repo cat rocky/x86_64/ostree /usr/etc/passwd
ostree --repo=./build/repo ls rocky/x86_64/ostree /usr/lib/systemd/system/*get*

33
image-base.yaml Normal file
View File

@ -0,0 +1,33 @@
# This file is shared by all streams. For a stream-specific change, use
# image.yaml instead.
# Target disk size in GB.
# Make it at least 10G because we want the rootfs to be at least 8G:
# https://github.com/coreos/fedora-coreos-tracker/issues/586
size: 10
extra-kargs:
# Disable SMT on systems vulnerable to MDS or any similar future issue.
- mitigations=auto,nosmt
# Disable networking by default on firstboot. We can drop this once cosa stops
# defaulting to `ip=auto rd.neednet=1` when it doesn't see this key.
ignition-network-kcmdline: []
# Optional remote by which to prefix the deployed OSTree ref
ostree-remote: rocky
# opt in to using the `metadata_csum_seed` feature of the ext4 filesystem
# for the /boot filesystem. Support for this was only recently added to grub
# and isn't available everywhere yet so we'll gate it behind this image.yaml
# knob. It should be easy to know when RHEL/RHCOS supports this by just flipping
# this to `true` and doing a build. It should error when building the disk
# images if grub doesn't support it.
# https://lists.gnu.org/archive/html/grub-devel/2021-06/msg00031.html
bootfs_metadata_csum_seed: true
vmware-os-type: fedora64Guest
# VMware hardware versions: https://kb.vmware.com/s/article/1003746
# We use the newest version allowed by the oldest non-EOL VMware
# Workstation/Player/Fusion/ESXi release: https://lifecycle.vmware.com/
vmware-hw-version: 13

1
image.yaml Normal file
View File

@ -0,0 +1 @@
include: image-base.yaml

36
live/EFI/rocky/grub.cfg Normal file
View File

@ -0,0 +1,36 @@
# Note this file mostly matches the grub.cfg file from within the
# efiboot.img on the Fedora Server DVD iso. Diff this file with that
# file in the future to pick up changes.
#
# One diff to note is we use linux and initrd instead of linuxefi and
# initrdefi. We do this because it works and allows us to use this same
# file on other architectures. https://github.com/coreos/fedora-coreos-config/issues/63
#
# This file is loaded directly when booting via El Torito, and indirectly
# from a stub config in efiboot.img when booting via the hybrid ESP.
set default="1"
function load_video {
insmod efi_gop
insmod efi_uga
insmod video_bochs
insmod video_cirrus
insmod all_video
}
load_video
set gfxpayload=keep
insmod gzio
insmod part_gpt
insmod ext2
set timeout=5
### END /etc/grub.d/00_header ###
### BEGIN /etc/grub.d/10_linux ###
menuentry 'Rocky Linux Core (Live)' --class fedora --class gnu-linux --class gnu --class os {
linux /images/pxeboot/vmlinuz @@KERNEL-ARGS@@ ignition.firstboot ignition.platform.id=metal
################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################ COREOS_KARG_EMBED_AREA
initrd /images/pxeboot/initrd.img /images/ignition.img
}

1
live/README.md Normal file
View File

@ -0,0 +1 @@
Files in this tree are copied into the live ISO and are required for EFI booting (and booting, generally)

5
live/isolinux/boot.msg Normal file
View File

@ -0,0 +1,5 @@
splash.lss
- Press the 01<ENTER>07 key to boot.

View File

@ -0,0 +1,75 @@
# Note this file mostly matches the isolinux.cfg file from the Fedora
# Server DVD iso. Diff this file with that file in the future to pick up
# changes.
serial 0
default vesamenu.c32
# timeout in units of 1/10s. 50 == 5 seconds
timeout 50
display boot.msg
# Clear the screen when exiting the menu, instead of leaving the menu displayed.
# For vesamenu, this means the graphical background is still displayed without
# the menu itself for as long as the screen remains in graphics mode.
menu clear
menu background splash.png
menu title Rocky Linux Core
menu vshift 8
menu rows 18
menu margin 8
#menu hidden
menu helpmsgrow 15
menu tabmsgrow 13
# Border Area
menu color border * #00000000 #00000000 none
# Selected item
menu color sel 0 #ffffffff #00000000 none
# Title bar
menu color title 0 #ff7ba3d0 #00000000 none
# Press [Tab] message
menu color tabmsg 0 #ff3a6496 #00000000 none
# Unselected menu item
menu color unsel 0 #84b8ffff #00000000 none
# Selected hotkey
menu color hotsel 0 #84b8ffff #00000000 none
# Unselected hotkey
menu color hotkey 0 #ffffffff #00000000 none
# Help text
menu color help 0 #ffffffff #00000000 none
# A scrollbar of some type? Not sure.
menu color scrollbar 0 #ffffffff #ff355594 none
# Timeout msg
menu color timeout 0 #ffffffff #00000000 none
menu color timeout_msg 0 #ffffffff #00000000 none
# Command prompt text
menu color cmdmark 0 #84b8ffff #00000000 none
menu color cmdline 0 #ffffffff #00000000 none
# Do not display the actual menu unless the user presses a key. All that is displayed is a timeout message.
menu tabmsg Press Tab for full configuration options on menu items.
menu separator # insert an empty line
menu separator # insert an empty line
label linux
menu label ^Rocky Linux Core (Live)
menu default
kernel /images/pxeboot/vmlinuz
append initrd=/images/pxeboot/initrd.img,/images/ignition.img @@KERNEL-ARGS@@ ignition.firstboot ignition.platform.id=metal
################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################ COREOS_KARG_EMBED_AREA
menu separator # insert an empty line
menu end

12
manifest.yaml Normal file
View File

@ -0,0 +1,12 @@
releasever: 9
variables:
stream: testing
prod: false
repos:
- appstream
- baseos
- extras
include: manifests/rocky-coreos.yaml

View File

@ -0,0 +1,53 @@
# This minimal base starts just from: kernel + systemd + rpm-ostree + bootloader.
# The intent of this is to inherit from this if you are doing something highly
# custom that e.g. might not involve Ignition or podman, but you do want
# rpm-ostree.
# We expect most people though using coreos-assembler to inherit from
# fedora-coreos-base.yaml.
packages:
# Kernel + systemd.
- kernel systemd
# linux-firmware now a recommends so let's explicitly include it
# https://gitlab.com/cki-project/kernel-ark/-/commit/32271d0cd9bd52d386eb35497c4876a8f041f70b
# https://src.fedoraproject.org/rpms/kernel/c/f55c3e9ed8605ff28cb9a922efbab1055947e213?branch=rawhide
- linux-firmware
# rpm-ostree
- rpm-ostree nss-altfiles
# bootloader
packages-aarch64:
- grub2-efi-aa64 efibootmgr shim
# firmware updates
- fwupd
packages-ppc64le:
- grub2 ostree-grub2
# firmware updates
- fwupd
packages-s390x:
# On Fedora, this is provided by s390utils-core. on RHEL, this is for now
# provided by s390utils-base, but soon will be -core too.
- /usr/sbin/zipl
# for Secure Execution
- veritysetup
packages-x86_64:
- grub2 grub2-efi-x64 efibootmgr shim
- microcode_ctl
# firmware updates
- fwupd
postprocess:
# See: https://github.com/coreos/fedora-coreos-tracker/issues/1253
# https://bugzilla.redhat.com/show_bug.cgi?id=2112857
# https://github.com/coreos/rpm-ostree/issues/3918
# Temporary workaround to remove the SetGID binary from liblockfile that is
# pulled by the s390utils but not needed for /usr/sbin/zipl.
- |
#!/usr/bin/env bash
set -xeuo pipefail
rm -f /usr/bin/dotlockfile
exclude-packages:
# Exclude kernel-debug-core to make sure that it doesn't somehow get
# chosen as the package to satisfy the `kernel-core` dependency from
# the kernel package.
- kernel-debug-core

13
manifests/bootupd.yaml Normal file
View File

@ -0,0 +1,13 @@
# Integration with https://github.com/coreos/bootupd
# xref https://github.com/coreos/fedora-coreos-tracker/issues/510
packages:
- bootupd
postprocess:
- |
#!/bin/bash
set -xeuo pipefail
# Until we have https://github.com/coreos/rpm-ostree/pull/2275
mkdir -p /run
# Transforms /usr/lib/ostree-boot into a bootupd-compatible update payload
/usr/bin/bootupctl backend generate-update-metadata /

View File

@ -0,0 +1,11 @@
postprocess:
# Set the fallback hostname to `localhost`. This can be removed
# once we are based on Fedora 37+.
# See https://github.com/coreos/fedora-coreos-tracker/issues/902
- |
#!/usr/bin/env bash
set -euxo pipefail
source /etc/os-release
if [ -z "${DEFAULT_HOSTNAME:-}" ]; then
echo 'DEFAULT_HOSTNAME=localhost' >> /usr/lib/os-release
fi

46
manifests/group Normal file
View File

@ -0,0 +1,46 @@
root:x:0:
bin:x:1:
daemon:x:2:
sys:x:3:
adm:x:4:
tty:x:5:
disk:x:6:
lp:x:7:
mem:x:8:
kmem:x:9:
wheel:x:10:
cdrom:x:11:
mail:x:12:
man:x:15:
sudo:x:16:
dialout:x:18:
floppy:x:19:
games:x:20:
tape:x:33:
video:x:39:
ftp:x:50:
lock:x:54:
audio:x:63:
nobody:x:99:
users:x:100:
ssh_keys:x:999:
systemd-journal:x:190:
polkitd:x:998:
etcd:x:997:
dip:x:40:
cgred:x:996:
avahi-autoipd:x:170:
sssd:x:993:
dockerroot:x:986:
rpcuser:x:29:
nfsnobody:x:65534:
kube:x:994:
chrony:x:992:
tcpdump:x:72:
ceph:x:167:
input:x:104:
systemd-timesync:x:991:
systemd-network:x:990:
systemd-resolve:x:989:
systemd-bus-proxy:x:988:
cockpit-ws:x:987:

View File

@ -0,0 +1,9 @@
remove-from-packages:
# The grub bits are mainly designed for desktops, and IMO haven't seen
# enough testing in concert with ostree. At some point we'll flesh out
# the full plan in https://github.com/coreos/fedora-coreos-tracker/issues/47
- [grub2-tools, /etc/grub.d/08_fallback_counting,
/etc/grub.d/10_reset_boot_success,
/etc/grub.d/12_menu_auto_hide,
/usr/lib/systemd/.*]

View File

@ -0,0 +1,44 @@
# Defines the "core" of a Fedora CoreOS like system; basically (ignition, ostree)
# plus other default tweaks. Things in this file should be something we expect
# basically everyone using both Ignition and (rpm-)ostree to want.
# It may be used as an inheritance base by other projects like Fedora Silverblue or RHCOS.
# One good model is to add fedora-coreos-config as a git submodule. See:
# https://github.com/coreos/coreos-assembler/pull/639
# Include rpm-ostree + kernel + bootloader
include: bootable-rpm-ostree.yaml
# Modern defaults we want
boot-location: modules
tmp-is-dir: true
# Required by Ignition, and makes the system not compatible with Anaconda
machineid-compat: false
packages:
- ignition
- dracut-network
# for encryption
- clevis clevis-luks clevis-dracut clevis-systemd
remove-from-packages:
# We don't want systemd-firstboot.service. It conceptually conflicts with
# Ignition. We also inject runtime bits to disable it in systemd-firstboot.service.d/fcos-disable.conf
# to make it easier to use systemd builds from git.
- [systemd, /usr/bin/systemd-firstboot,
/usr/lib/systemd/system/systemd-firstboot.service,
/usr/lib/systemd/system/sysinit.target.wants/systemd-firstboot.service]
# We don't want auto-generated mount units. See also
# https://github.com/systemd/systemd/issues/13099
- [systemd-udev, /usr/lib/systemd/system-generators/systemd-gpt-auto-generator]
postprocess:
# Undo RPM scripts enabling units; we want the presets to be canonical
# https://github.com/projectatomic/rpm-ostree/issues/1803
- |
#!/usr/bin/env bash
set -xeuo pipefail
rm -rf /etc/systemd/system/*
systemctl preset-all
rm -rf /etc/systemd/user/*
systemctl --user --global preset-all

40
manifests/passwd Normal file
View File

@ -0,0 +1,40 @@
root:x:0:0:root:/root:/bin/bash
bin:x:1:1:bin:/bin:/sbin/nologin
daemon:x:2:2:daemon:/sbin:/sbin/nologin
adm:x:3:4:adm:/var/adm:/sbin/nologin
lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
sync:x:5:0:sync:/sbin:/bin/sync
shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown
halt:x:7:0:halt:/sbin:/sbin/halt
adm:x:3:4:adm:/var/adm:/usr/sbin/nologin
avahi-autoipd:x:170:170:Avahi IPv4LL Stack:/var/lib/avahi-autoipd:/usr/sbin/nologin
bin:x:1:1:bin:/bin:/usr/sbin/nologin
ceph:x:167:167:Ceph daemons:/var/lib/ceph:/usr/sbin/nologin
chrony:x:994:992::/var/lib/chrony:/usr/sbin/nologin
cockpit-ws:x:988:987:User for cockpit-ws:/:/usr/sbin/nologin
daemon:x:2:2:daemon:/sbin:/usr/sbin/nologin
dbus:x:81:81:System Message Bus:/:/usr/sbin/nologin
dockerroot:x:997:986:Docker User:/var/lib/docker:/usr/sbin/nologin
etcd:x:998:997:etcd user:/var/lib/etcd:/usr/sbin/nologin
ftp:x:14:50:FTP User:/var/ftp:/usr/sbin/nologin
games:x:12:100:games:/usr/games:/usr/sbin/nologin
halt:x:7:0:halt:/sbin:/sbin/halt
kube:x:996:994:Kubernetes user:/:/usr/sbin/nologin
lp:x:4:7:lp:/var/spool/lpd:/usr/sbin/nologin
mail:x:8:12:mail:/var/spool/mail:/usr/sbin/nologin
nfsnobody:x:65534:65534:Anonymous NFS User:/var/lib/nfs:/usr/sbin/nologin
nobody:x:99:99:Kernel Overflow User:/:/usr/sbin/nologin
operator:x:11:0:operator:/root:/usr/sbin/nologin
polkitd:x:999:998:User for polkitd:/:/usr/sbin/nologin
root:x:0:0:Super User:/root:/bin/bash
rpc:x:32:32:Rpcbind Daemon:/var/lib/rpcbind:/usr/sbin/nologin
rpcuser:x:29:29:RPC Service User:/var/lib/nfs:/usr/sbin/nologin
shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown
sshd:x:74:74:Privilege-separated SSH:/var/empty/sshd:/usr/sbin/nologin
sssd:x:995:993:User for sssd:/:/usr/sbin/nologin
sync:x:5:0:sync:/sbin:/bin/sync
systemd-bus-proxy:x:989:988:systemd Bus Proxy:/:/usr/sbin/nologin
systemd-network:x:991:990:systemd Network Management:/:/usr/sbin/nologin
systemd-resolve:x:990:989:systemd Resolver:/:/usr/sbin/nologin
systemd-timesync:x:993:991:systemd Time Synchronization:/:/usr/sbin/nologin
tcpdump:x:72:72::/:/usr/sbin/nologin

View File

@ -0,0 +1,60 @@
# Inherits from "Core"
include:
- ignition-and-ostree.yaml
- shared-workarounds.yaml
- system-configuration.yaml
- user-experience.yaml
conditional-include:
- if: releasever <= 8
include: fallback-hostname.yaml
ostree-layers:
- overlay/05core
- overlay/08nouveau
- overlay/09misc
- overlay/20platform-chrony
recommends: false
packages:
- rpm
- policycoreutils
- kernel
- kernel-modules-extra
- rpm-ostree
- ostree-grub2
- selinux-policy-targeted
- biosdevname
- keyutils
- binutils
- nss-altfiles
- polkit
- coreos-installer
ignore-removed-users:
- root
ignore-removed-groups:
- root
etc-group-members:
- wheel
- sudo
- systemd-journal
- adm
- docker
check-passwd:
type: "file"
filename: "passwd"
check-groups:
type: "file"
filename: "group"
# See https://github.com/coreos/bootupd
arch-include:
x86_64: bootupd.yaml
aarch64: bootupd.yaml
default-target: multi-user.target

View File

@ -0,0 +1,60 @@
ref: rocky/${basearch}/ostree/${stream}
rojig:
name: rocky-ostree
summary: "Rocky Linux OSTree ${stream}"
license: MIT
add-commit-metadata:
rocky-core.stream: ${stream}
include:
- rocky-coreos-base.yaml
conditional-include:
- if: basearch != "s390x"
# And remove some cruft from grub2
include: grub2-removals.yaml
ostree-layers:
- overlay/15fcos
automatic-version-prefix: "${releasever}.<date:%Y%m%d>.dev"
mutate-os-release: "${releasever}"
remove-from-packages:
# Drop NetworkManager support for ifcfg files, see also corresponding
# overlay.d/14NetworkManager-plugins
- [NetworkManager, /usr/lib64/NetworkManager/.*/libnm-settings-plugin-ifcfg-rh.so]
# Drop some buggy sysusers fragments which do not match static IDs allocation:
# https://bugzilla.redhat.com/show_bug.cgi?id=2105177
# - [dbus-common, /usr/lib/sysusers.d/dbus.conf]
remove-files:
# We don't ship man(1) or info(1)
- usr/share/info
- usr/share/man
# Drop text docs too
- usr/share/doc
# Things we don't expect to ship on the host. We currently
# have recommends: false so these could only come in via
# hard requirement, in which case the build will fail.
exclude-packages:
- python
- python2
- python2-libs
# - python3
# - python3-libs
- perl
- perl-interpreter
- nodejs
- dnf
- grubby
- cowsay # Just in case
# Let's make sure initscripts doesn't get pulled back in
# https://github.com/coreos/fedora-coreos-tracker/issues/220#issuecomment-611566254
- initscripts
# For (datacenter/cloud oriented) servers, we want to see the details by default.
# https://lists.fedoraproject.org/archives/list/devel@lists.fedoraproject.org/thread/HSMISZ3ETWQ4ETVLWZQJ55ARZT27AAV3/
- plymouth

11
manifests/shared-el9.yaml Normal file
View File

@ -0,0 +1,11 @@
# These are packages that are shared between FCOS and
# RHCOS/SCOS 9+
packages:
# SSH
- ssh-key-dir
- zstd
ostree-layers:
- overlay/06el9

View File

@ -0,0 +1,35 @@
# This manifest is a list of shared workarounds that are needed in both Fedora CoreOS
# and downstreams (i.e. Red Hat CoreOS).
postprocess:
# Put in the fix for multipathd.service in dracut on releases that haven't
# been fixed yet.
# https://github.com/dracutdevs/dracut/pull/1606
# https://github.com/coreos/fedora-coreos-config/pull/1233
- |
#!/usr/bin/env bash
set -xeuo pipefail
source /etc/os-release
# This has landed in Fedora but not in any version of RHEL yet
if [[ ${ID} != "rocky" ]]; then
exit 0
fi
mkdir /usr/lib/dracut/modules.d/36coreos-multipath-fix
cat > /usr/lib/dracut/modules.d/36coreos-multipath-fix/90-multipathd-remove-execstop.conf <<'EOF'
# Temporary workaround for https://github.com/dracutdevs/dracut/pull/1606.
[Service]
ExecStop=
EOF
cat > /usr/lib/dracut/modules.d/36coreos-multipath-fix/module-setup.sh <<'EOF'
#!/bin/bash
# -*- mode: shell-script; indent-tabs-mode: nil; sh-basic-offset: 4; -*-
# ex: ts=8 sw=4 sts=4 et filetype=sh
install() {
# Temporary workaround for https://github.com/dracutdevs/dracut/pull/1606.
mkdir -p "$systemdsystemunitdir/multipathd.service.d"
inst_simple "$moddir/90-multipathd-remove-execstop.conf" \
"$systemdsystemunitdir/multipathd.service.d/90-multipathd-remove-execstop.conf"
}
EOF
chmod +x /usr/lib/dracut/modules.d/36coreos-multipath-fix/module-setup.sh

View File

@ -0,0 +1,50 @@
# These are packages that are related to configuring parts of the system.
# It is intended to be kept generic so that it may be shared downstream with
# RHCOS.
packages:
# Configuring SSH keys, cloud provider check-in, etc
- afterburn afterburn-dracut
# NTP support
- chrony
# Installing CoreOS itself
- coreos-installer coreos-installer-bootinfra
# Storage configuration/management
## cloud-utils-growpart - For growing root partition
- cifs-utils
- cloud-utils-growpart
- cryptsetup
- device-mapper-multipath
- e2fsprogs
- iscsi-initiator-utils
- lvm2
- mdadm
- sg3_utils
- xfsprogs
# User configuration
- passwd
- shadow-utils
- acl
# SELinux policy
- selinux-policy-targeted
# There are things that write outside of the journal still (such as the
# classic wtmp, etc.). auditd also writes outside the journal but it has its
# own log rotation.
# Anything package layered will also tend to expect files dropped in
# /etc/logrotate.d to work. Really, this is a legacy thing, but if we don't
# have it then people's disks will slowly fill up with logs.
- logrotate
# Boost starving threads
# https://github.com/coreos/fedora-coreos-tracker/issues/753
- stalld
postprocess:
# Make kdump work on firstboot
- |
#!/usr/bin/env bash
# Make kdump ignore `ignition.firstboot` when copying kargs from
# the running kernel to the kdump kernel when passing to be kexec.
# This makes it so kdump can be set up on the very first boot.
# Upstream request to have this upstream so we can stop carrying it here:
# https://lists.fedoraproject.org/archives/list/kexec@lists.fedoraproject.org/thread/5P4WIJLW2TSGF4PZGRZGOXYML4RXZU23/
sed -i -e 's/KDUMP_COMMANDLINE_REMOVE="/KDUMP_COMMANDLINE_REMOVE="ignition.firstboot /' /etc/sysconfig/kdump

View File

@ -0,0 +1,47 @@
# This file is included in RHEL CoreOS, see
# https://github.com/openshift/os/blob/71c974b1e456292033e3ef3fe7bcfe17d1855ebc/manifest.yaml#L12
# Only apply changes here that should apply to both FCOS and RHCOS.
# Default to `bash` in our container, the same as other containers we ship.
container-cmd:
- /usr/bin/bash
# These packages are either widely used utilities/services or
# are targeted for improving the general CoreOS user experience.
# It is intended to be kept generic so that it may be shared downstream with
# RHCOS.
packages:
# Basic user tools
## jq - parsing/interacting with JSON data
- bash-completion
- coreutils
- file
- jq
- less
- sudo
- vim-minimal
# File compression/decompression
## bsdtar - dependency of 35coreos-live dracut module
- bsdtar
- bzip2
- gzip
- tar
- xz
- zstd
# Improved MOTD experience
- console-login-helper-messages-issuegen
- console-login-helper-messages-profile
# kdump support
# https://github.com/coreos/fedora-coreos-tracker/issues/622
- kexec-tools
# Remote Access
- openssh-clients openssh-server
# Container tooling
- crun
- podman
- runc
- skopeo
- toolbox
# nvme-cli for managing nvme disks
- nvme-cli
- rpaste

View File

@ -0,0 +1,3 @@
# We don't ship cracklib dicts, so don't try to use them to validate
# password changes.
dictcheck = 0

View File

@ -0,0 +1,2 @@
# https://github.com/openshift/os/issues/96
%sudo ALL=(ALL) NOPASSWD: ALL

View File

@ -0,0 +1,6 @@
# Config file for overriding permission bits on overlay files/dirs
# Format: =<file mode in decimal> <absolute path to a file or directory>
# Some security scanners complain if /etc/sudoers.d files have 0044 mode bits
# https://bugzilla.redhat.com/show_bug.cgi?id=1981979
=384 /etc/sudoers.d/coreos-sudo-group

View File

@ -0,0 +1,2 @@
[connection]
ipv4.dhcp-client-id=mac

View 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}"
}

View File

@ -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
}

View File

@ -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"
}

View File

@ -0,0 +1,18 @@
#!/bin/bash
# -*- mode: shell-script; indent-tabs-mode: nil; sh-basic-offset: 4; -*-
# ex: ts=8 sw=4 sts=4 et filetype=sh
# We want to provide Azure udev rules as part of the initrd, so that Ignition
# is able to detect disks and act on them.
#
# If the WALinuxAgent-udev package is changed to install the udev rules as
# part of the initramfs, we should drop this module.
#
# See https://bugzilla.redhat.com/show_bug.cgi?id=1909287
# See also https://bugzilla.redhat.com/show_bug.cgi?id=1756173
install() {
inst_multiple \
/usr/lib/udev/rules.d/66-azure-storage.rules \
/usr/lib/udev/rules.d/99-azure-product-uuid.rules
}

View File

@ -0,0 +1,26 @@
# 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
[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

View File

@ -0,0 +1,51 @@
#!/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
# And similarly, only inject boot= if it's not already present.
boot=$(karg boot)
if [ -z "${boot}" ]; then
# XXX: `rdcore rootmap --inject-boot-karg` or maybe `rdcore bootmap`
eval $(blkid -o export "${bootdev}")
if [ -z "${UUID}" ]; then
# This should never happen
echo "Boot filesystem ${bootdev} has no UUID" >&2
exit 1
fi
rdcore kargs --boot-mount ${bootmnt} --append boot=UUID=${UUID}
# but also put it in /run for the first boot real root mount
mkdir -p /run/coreos
echo "${UUID}" > /run/coreos/bootfs_uuid
fi

View File

@ -0,0 +1,60 @@
#!/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
fi

View File

@ -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

View File

@ -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 || :

View File

@ -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

View File

@ -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

View File

@ -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

View 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

View File

@ -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

View File

@ -0,0 +1,216 @@
#!/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
}
# 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)
# 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
# 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
if [ -n "$(ls -A /sysroot/etc/NetworkManager/system-connections/)" -o \
-n "$(ls -A /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/
}
main

View File

@ -0,0 +1,59 @@
#!/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 \
sgdisk
inst_simple "$moddir/coreos-diskful-generator" \
"$systemdutildir/system-generators/coreos-diskful-generator"
inst_script "$moddir/coreos-gpt-setup.sh" \
"/usr/sbin/coreos-gpt-setup"
inst_script "$moddir/coreos-ignition-setup-user.sh" \
"/usr/sbin/coreos-ignition-setup-user"
# 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-setup-user.service
}

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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"

View File

@ -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

View File

@ -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:* ]]; 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 and HTTPS 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

View 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

View File

@ -0,0 +1,257 @@
#!/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
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

View File

@ -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"
}

View 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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -0,0 +1,21 @@
[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
# 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

View File

@ -0,0 +1,17 @@
#!/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 final target.
if [ ! -f /sysroot/etc/multipath.conf ] && [ -f /etc/multipath.conf ]; then
echo "info: propagating automatic multipath configuration"
cp -v /etc/multipath.conf /sysroot/etc/
mkdir -p /sysroot/etc/multipath/multipath.conf.d
coreos-relabel /etc/multipath.conf
coreos-relabel /etc/multipath/multipath.conf.d
else
echo "info: no initramfs automatic multipath configuration to propagate"
fi

View 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_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
}
install() {
inst_script "$moddir/coreos-propagate-multipath-conf.sh" \
"/usr/sbin/coreos-propagate-multipath-conf"
install_ignition_unit coreos-propagate-multipath-conf.service subsequent
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"
}

View File

@ -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'

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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"
}

View File

@ -0,0 +1,19 @@
{
"ignition": {
"version": "3.0.0"
},
"passwd": {
"users": [
{
"name": "core",
"gecos": "CoreOS Admin",
"groups": [
"adm",
"sudo",
"systemd-journal",
"wheel"
]
}
]
}
}

View File

@ -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).

View 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"
}

View File

@ -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

View 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[@]}"

View File

@ -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

View File

@ -0,0 +1,13 @@
[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
[Service]
Type=oneshot
ExecStart=/usr/libexec/coreos-check-rootfs-size
RemainAfterExit=yes

View File

@ -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

View File

@ -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

View File

@ -0,0 +1,120 @@
#!/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)
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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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"

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -0,0 +1,244 @@
#!/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
echo "Mounting ${srcdev} ($(realpath "$srcdev")) to $destdir"
mkdir -p "${destdir}"
mount "${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}")
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"
}
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}"
find "${saved_fs}" -mindepth 1 -maxdepth 1 -exec mv -t "${mountpoint}" {} \;
}
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_verbose "${root_part}" /sysroot
cp -aT /sysroot "${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_verbose "${boot_part}" /sysroot/boot
cp -aT /sysroot/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}"
find "${saved_esp}" -mindepth 1 -maxdepth 1 -exec cp -a {} "${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

View File

@ -0,0 +1,22 @@
[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
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

View File

@ -0,0 +1,25 @@
[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
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

View File

@ -0,0 +1,104 @@
#!/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
# 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
}

View File

@ -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

View File

@ -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"
}

View File

@ -0,0 +1,12 @@
# 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
[Service]
Type=oneshot
RemainAfterExit=yes
ExecStart=/usr/bin/touch /run/agetty.reload

View File

@ -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
}

View File

@ -0,0 +1,15 @@
[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
[Service]
Type=oneshot
RemainAfterExit=yes
EnvironmentFile=/run/ignition.env
ExecStart=/usr/bin/ignition-virtio-dump-journal

View File

@ -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

View File

@ -0,0 +1,24 @@
#!/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
inst_hook emergency 99 "${moddir}/timeout.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
}

View File

@ -0,0 +1,99 @@
# Before starting the emergency shell, prompt the user to press Enter.
# If they don't, reboot the system.
#
# Assumes /bin/sh is bash.
# _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
}
_prompt_for_timeout() {
local timeout=300
local interval=15
if [[ -e /.emergency-shell-confirmed ]]; then
return
fi
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
echo "Displaying logs from failed units: ${failed}"
for unit in ${failed}; do
# 10 lines should be enough for everyone
journalctl -b --no-pager --no-hostname -u ${unit} -n 10
done
fi
# Regularly prompt with time remaining. This ensures the prompt doesn't
# get lost among kernel and systemd messages, and makes it clear what's
# going on if the user just connected a serial console.
while [[ $timeout > 0 ]]; do
local m=$(( $timeout / 60 ))
local s=$(( $timeout % 60 ))
local m_label="minutes"
if [[ $m = 1 ]]; then
m_label="minute"
fi
if [[ $s != 0 ]]; then
echo -n -e "Press Enter for emergency shell or wait $m $m_label $s seconds for reboot. \r"
else
echo -n -e "Press Enter for emergency shell or wait $m $m_label for reboot. \r"
fi
local anything
if read -t $interval anything; then
> /.emergency-shell-confirmed
return
fi
timeout=$(( $timeout - $interval ))
done
echo -e "\nRebooting."
# This is not very nice, but since reboot.target likely conflicts with
# the existing goal target wrt the desired state of shutdown.target,
# there doesn't seem to be a better option.
systemctl reboot --force
exit 0
}
# If we're invoked from a dracut breakpoint rather than
# dracut-emergency.service, we won't have a controlling terminal and stdio
# won't be connected to it. Explicitly read/write /dev/console.
_prompt_for_timeout < /dev/console > /dev/console

Some files were not shown because too many files have changed in this diff Show More