mirror of
https://github.com/kairos-io/immucore.git
synced 2025-09-19 09:43:14 +00:00
Merge pull request #26 from kairos-io/changes_v4
This commit is contained in:
10
Earthfile
10
Earthfile
@@ -55,14 +55,16 @@ lint:
|
|||||||
|
|
||||||
build-immucore:
|
build-immucore:
|
||||||
FROM +golang-image
|
FROM +golang-image
|
||||||
COPY +version/VERSION ./
|
|
||||||
ARG VERSION=$(cat VERSION)
|
|
||||||
WORKDIR /work
|
WORKDIR /work
|
||||||
COPY go.mod go.sum /work
|
COPY go.mod go.sum /work
|
||||||
COPY main.go /work
|
COPY main.go /work
|
||||||
COPY --dir internal /work
|
COPY --dir internal /work
|
||||||
COPY --dir pkg /work
|
COPY --dir pkg /work
|
||||||
RUN CGO_ENABLED=0 go build -o immucore -ldflags "-X internal/version.Version=$VERSION"
|
COPY +version/VERSION ./
|
||||||
|
ARG VERSION=$(cat VERSION)
|
||||||
|
ARG LDFLAGS="-s -w -X github.com/kairos-io/immucore/internal/version.Version=$VERSION"
|
||||||
|
RUN echo ${LDFLAGS}
|
||||||
|
RUN CGO_ENABLED=0 go build -o immucore -ldflags "${LDFLAGS}"
|
||||||
SAVE ARTIFACT /work/immucore AS LOCAL build/immucore-$VERSION
|
SAVE ARTIFACT /work/immucore AS LOCAL build/immucore-$VERSION
|
||||||
|
|
||||||
build-dracut:
|
build-dracut:
|
||||||
@@ -78,7 +80,7 @@ build-dracut:
|
|||||||
RUN rm /etc/dracut.conf.d/02-cos-immutable-rootfs.conf
|
RUN rm /etc/dracut.conf.d/02-cos-immutable-rootfs.conf
|
||||||
END
|
END
|
||||||
RUN kernel=$(ls /lib/modules | head -n1) && \
|
RUN kernel=$(ls /lib/modules | head -n1) && \
|
||||||
dracut -f "/boot/initrd-${kernel}" "${kernel}" && \
|
dracut -v -f "/boot/initrd-${kernel}" "${kernel}" && \
|
||||||
ln -sf "initrd-${kernel}" /boot/initrd
|
ln -sf "initrd-${kernel}" /boot/initrd
|
||||||
ARG INITRD=$(readlink -f /boot/initrd)
|
ARG INITRD=$(readlink -f /boot/initrd)
|
||||||
SAVE ARTIFACT $INITRD Initrd AS LOCAL build/initrd-$VERSION
|
SAVE ARTIFACT $INITRD Initrd AS LOCAL build/initrd-$VERSION
|
||||||
|
52
dracut/28immucore/generator.sh
Normal file → Executable file
52
dracut/28immucore/generator.sh
Normal file → Executable file
@@ -1,46 +1,32 @@
|
|||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
|
|
||||||
|
set +x
|
||||||
|
|
||||||
type getarg >/dev/null 2>&1 || . /lib/dracut-lib.sh
|
type getarg >/dev/null 2>&1 || . /lib/dracut-lib.sh
|
||||||
|
|
||||||
GENERATOR_DIR="$2"
|
GENERATOR_DIR="$2"
|
||||||
|
|
||||||
[ -z "$GENERATOR_DIR" ] && exit 1
|
[ -z "$GENERATOR_DIR" ] && exit 1
|
||||||
[ -d "$GENERATOR_DIR" ] || mkdir "$GENERATOR_DIR"
|
[ -d "$GENERATOR_DIR" ] || mkdir "$GENERATOR_DIR"
|
||||||
|
|
||||||
oem_label=$(getarg rd.cos.oemlabel=)
|
|
||||||
|
|
||||||
# See https://github.com/kairos-io/packages/blob/d12b12b043a71d8471454f7b4fc84c3181d2bf60/packages/system/dracut/immutable-rootfs/30cos-immutable-rootfs/cos-generator.sh#L29
|
## GENERATE SYSROOT
|
||||||
|
cos_img=$(getarg cos-img/filename=)
|
||||||
|
[ -z "${cos_img}" ] && exit 0
|
||||||
|
|
||||||
|
# This is necessary because otherwise systemd-fstab-generator will se the cmdline with the root=LABEL=X stanza and
|
||||||
|
# say, hey this is the ROOT where we need to boot! so it auto creates a sysroot.mount with the content of the value
|
||||||
|
# passed in the cmdline. But because we usually pass the label of the img (COS_ACTIVE) it will create the wrong mount
|
||||||
|
# service and be stuck in there forever.
|
||||||
|
# by generating it ourselves we get the sysroot.mount intot he generators.early dir, which tells systemd to not generate it
|
||||||
|
# as it already exists and the rest is history
|
||||||
{
|
{
|
||||||
echo "[Unit]"
|
echo "[Unit]"
|
||||||
|
echo "Before=initrd-root-fs.target"
|
||||||
echo "DefaultDependencies=no"
|
echo "DefaultDependencies=no"
|
||||||
echo "Before=initrd-fs.target"
|
echo "[Mount]"
|
||||||
echo "Conflicts=initrd-switch-root.target"
|
echo "Where=/sysroot"
|
||||||
echo "Requires=initrd-root-fs.target"
|
echo "What=/run/initramfs/cos-state/${cos_img#/}"
|
||||||
if getargbool 0 rd.neednet; then
|
echo "Options=ro,suid,dev,exec,auto,nouser,async"
|
||||||
echo "Wants=network-online.target"
|
} > "$GENERATOR_DIR"/sysroot.mount
|
||||||
echo "After=network-online.target"
|
|
||||||
echo "Description=immucore online mount"
|
|
||||||
else
|
|
||||||
echo "Description=immucore mount"
|
|
||||||
fi
|
|
||||||
# Itxaka: oem is mounted by immucore?
|
|
||||||
# OEM is special as immucore plugins might need that in order to unlock other partitions and plugins can reside in /oem as well and immucore needs to find them
|
|
||||||
#if [ -n "${oem_label}" ]; then
|
|
||||||
# echo "After=oem.mount"
|
|
||||||
#fi
|
|
||||||
echo "After=initrd-root-fs.target cos-setup-rootfs.service"
|
|
||||||
echo "[Service]"
|
|
||||||
echo "Type=oneshot"
|
|
||||||
echo "RemainAfterExit=yes"
|
|
||||||
echo "ExecStart=/usr/bin/immucore start"
|
|
||||||
|
|
||||||
echo "[Install]"
|
## END GENERATE SYSROOT
|
||||||
echo "RequiredBy=initrd-fs.target"
|
|
||||||
} > "$GENERATOR_DIR"/immucore.service
|
|
||||||
|
|
||||||
|
|
||||||
if [ ! -e "$GENERATOR_DIR/initrd-fs.target.requires/immucore.service" ]; then
|
|
||||||
mkdir -p "$GENERATOR_DIR"/initrd-fs.target.requires
|
|
||||||
ln -s "$GENERATOR_DIR"/immucore.service \
|
|
||||||
"$GENERATOR_DIR"/initrd-fs.target.requires/immucore.service
|
|
||||||
fi
|
|
14
dracut/28immucore/immucore.service
Normal file
14
dracut/28immucore/immucore.service
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
[Unit]
|
||||||
|
Description=immucore
|
||||||
|
DefaultDependencies=no
|
||||||
|
After=systemd-udev-settle.service
|
||||||
|
Requires=systemd-udev-settle.service
|
||||||
|
Before=dracut-initqueue.service
|
||||||
|
Conflicts=initrd-switch-root.target
|
||||||
|
|
||||||
|
[Service]
|
||||||
|
Type=oneshot
|
||||||
|
RemainAfterExit=yes
|
||||||
|
StandardOutput=journal+console
|
||||||
|
ExecStartPre=-/usr/bin/systemctl stop oem.mount
|
||||||
|
ExecStart=/usr/bin/immucore start
|
@@ -23,18 +23,16 @@ install() {
|
|||||||
declare moddir=${moddir}
|
declare moddir=${moddir}
|
||||||
declare systemdutildir=${systemdutildir}
|
declare systemdutildir=${systemdutildir}
|
||||||
declare systemdsystemunitdir=${systemdsystemunitdir}
|
declare systemdsystemunitdir=${systemdsystemunitdir}
|
||||||
declare initdir="${initdir}"
|
declare initdir=${initdir}
|
||||||
|
|
||||||
# Add missing elemental binary, drop once we get yip lib inside immucore as its only needed to run the stages
|
# Add missing elemental binary, drop once we get yip lib inside immucore as its only needed to run the stages
|
||||||
inst_multiple \
|
inst_multiple immucore elemental
|
||||||
immucore elemental
|
# add utils used by elemental or stages
|
||||||
|
inst_multiple partprobe sync udevadm parted mkfs.ext2 mkfs.ext3 mkfs.ext4 mkfs.vfat mkfs.fat blkid e2fsck resize2fs mount umount sgdisk
|
||||||
inst_script "${moddir}/generator.sh" \
|
# missing mkfs.xfs xfs_growfs in image?
|
||||||
"${systemdutildir}/system-generators/immucore-generator"
|
inst_script "${moddir}/generator.sh" "${systemdutildir}/system-generators/immucore-generator"
|
||||||
|
inst_simple "${moddir}/immucore.service" "${systemdsystemunitdir}/immucore.service"
|
||||||
mkdir -p "${initdir}/${systemdsystemunitdir}/initrd-fs.target.requires"
|
mkdir -p "${initdir}/${systemdsystemunitdir}/initrd-fs.target.requires"
|
||||||
ln_r "../immucore.service" \
|
ln_r "../immucore.service" "${systemdsystemunitdir}/initrd-fs.target.requires/immucore.service"
|
||||||
"${systemdsystemunitdir}/initrd-fs.target.requires/immucore.service"
|
|
||||||
|
|
||||||
dracut_need_initqueue
|
dracut_need_initqueue
|
||||||
}
|
}
|
@@ -1,6 +1,8 @@
|
|||||||
# This services should be run from immucore directly, rootfs at start of immucore and initramfs once we mount everything,
|
# This services should be run from immucore directly, rootfs once we mount /sysroot and initramfs once we mount everything,
|
||||||
# so at the end, just before we let init do the switch_root
|
# so at the end, just before we let init do the switch_root. Notice that we run really early in the boot with immucore so
|
||||||
|
# maybe by this time some things are not ready...
|
||||||
# Note that initramfs run with RootDirectory=/sysroot
|
# Note that initramfs run with RootDirectory=/sysroot
|
||||||
install_items+=" /etc/systemd/system/cos-setup-initramfs.service /etc/systemd/system/initrd.target.requires/cos-setup-initramfs.service "
|
install_items+=" /etc/systemd/system/cos-setup-initramfs.service /etc/systemd/system/initrd.target.requires/cos-setup-initramfs.service "
|
||||||
install_items+=" /etc/systemd/system/cos-setup-rootfs.service /etc/systemd/system/initrd-fs.target.requires/cos-setup-rootfs.service "
|
# RUN BY IMMUCORE BUT FAILING
|
||||||
|
#install_items+=" /etc/systemd/system/cos-setup-rootfs.service /etc/systemd/system/initrd-fs.target.requires/cos-setup-rootfs.service "
|
||||||
add_dracutmodules+=" immucore "
|
add_dracutmodules+=" immucore "
|
@@ -84,12 +84,21 @@ func (s *State) WriteFstab(fstabFile string) func(context.Context) error {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// ln -sf -t / /sysroot/system
|
|
||||||
func (s *State) RunStageOp(stage string) func(context.Context) error {
|
func (s *State) RunStageOp(stage string) func(context.Context) error {
|
||||||
return func(ctx context.Context) error {
|
return func(ctx context.Context) error {
|
||||||
|
log.Logger = log.Output(zerolog.ConsoleWriter{Out: os.Stderr}).With().Caller().Logger()
|
||||||
|
if stage == "rootfs" {
|
||||||
|
err := os.Symlink("/sysroot/system", "/system")
|
||||||
|
if err != nil {
|
||||||
|
s.Logger.Err(err).Msg("creating symlink")
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
cmd := fmt.Sprintf("elemental run-stage %s", stage)
|
cmd := fmt.Sprintf("elemental run-stage %s", stage)
|
||||||
s.Logger.Debug().Str("cmd", cmd)
|
log.Logger.Debug().Str("cmd", cmd).Msg("")
|
||||||
_, err := utils.SH(cmd)
|
output, err := utils.SH(cmd)
|
||||||
|
log.Logger.Debug().Str("output", output).Msg("")
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -183,8 +192,10 @@ func (s *State) Register(g *herd.Graph) error {
|
|||||||
|
|
||||||
runtime, err := state.NewRuntime()
|
runtime, err := state.NewRuntime()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
s.Logger.Debug().Err(err).Msg("")
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
s.Logger.Debug().Str("state", litter.Sdump(runtime)).Msg("Register")
|
||||||
|
|
||||||
// TODO: add hooks, fstab (might have missed some), systemd compat
|
// TODO: add hooks, fstab (might have missed some), systemd compat
|
||||||
// TODO: We should also set tmpfs here (not -related)
|
// TODO: We should also set tmpfs here (not -related)
|
||||||
@@ -250,7 +261,7 @@ func (s *State) Register(g *herd.Graph) error {
|
|||||||
// "auto",
|
// "auto",
|
||||||
//"nouser",
|
//"nouser",
|
||||||
"async",
|
"async",
|
||||||
}, 60*time.Second),
|
}, 10*time.Second),
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -263,24 +274,26 @@ func (s *State) Register(g *herd.Graph) error {
|
|||||||
// This is building the mountRoot dependendency if it was enabled
|
// This is building the mountRoot dependendency if it was enabled
|
||||||
mountRootCondition := herd.ConditionalOption(func() bool { return s.MountRoot }, herd.WithDeps(opMountRoot))
|
mountRootCondition := herd.ConditionalOption(func() bool { return s.MountRoot }, herd.WithDeps(opMountRoot))
|
||||||
|
|
||||||
// TODO: this needs to be run after state is discovered
|
// TODO: this needs to be run after sysroot so we can link to /sysroot/system/oem and after /oem mounted
|
||||||
// TODO: add symlink if Rootdir != ""
|
|
||||||
// TODO: chroot?
|
|
||||||
s.Logger.Debug().Str("what", opRootfsHook).Msg("Add operation")
|
s.Logger.Debug().Str("what", opRootfsHook).Msg("Add operation")
|
||||||
err = g.Add(opRootfsHook, mountRootCondition, herd.WithDeps(opMountOEM), herd.WithCallback(s.RunStageOp("rootfs")))
|
err = g.Add(opRootfsHook, mountRootCondition, herd.WithDeps(opMountRoot, opMountOEM), herd.WithCallback(s.RunStageOp("rootfs")))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
s.Logger.Err(err)
|
s.Logger.Err(err).Msg("running rootfs stage")
|
||||||
}
|
}
|
||||||
|
|
||||||
// /run/cos-layout.env
|
// /run/cos/cos-layout.env
|
||||||
// populate state bindmounts, overlaymounts, custommounts
|
// populate state bindmounts, overlaymounts, custommounts
|
||||||
s.Logger.Debug().Str("what", opLoadConfig).Msg("Add operation")
|
s.Logger.Debug().Str("what", opLoadConfig).Msg("Add operation")
|
||||||
err = g.Add(opLoadConfig,
|
err = g.Add(opLoadConfig,
|
||||||
herd.WithDeps(opRootfsHook),
|
herd.WithDeps(opRootfsHook),
|
||||||
herd.WithCallback(func(ctx context.Context) error {
|
herd.WithCallback(func(ctx context.Context) error {
|
||||||
log.Logger = log.Output(zerolog.ConsoleWriter{Out: os.Stderr}).With().Caller().Logger()
|
log.Logger = log.Output(zerolog.ConsoleWriter{Out: os.Stderr}).With().Caller().Logger()
|
||||||
env, err := readEnv("/run/cos-layout.env")
|
if s.CustomMounts == nil {
|
||||||
|
s.CustomMounts = map[string]string{}
|
||||||
|
}
|
||||||
|
env, err := readEnv("/run/cos/cos-layout.env")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
log.Logger.Err(err).Msg("Reading env")
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
log.Logger.Debug().Str("envfile", litter.Sdump(env)).Msg("loading cos layout")
|
log.Logger.Debug().Str("envfile", litter.Sdump(env)).Msg("loading cos layout")
|
||||||
@@ -389,7 +402,7 @@ func (s *State) Register(g *herd.Graph) error {
|
|||||||
[]string{
|
[]string{
|
||||||
"ro", // or rw
|
"ro", // or rw
|
||||||
},
|
},
|
||||||
60*time.Second,
|
10*time.Second,
|
||||||
)(ctx))
|
)(ctx))
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -435,7 +448,7 @@ func (s *State) Register(g *herd.Graph) error {
|
|||||||
mountRootCondition,
|
mountRootCondition,
|
||||||
herd.WithCallback(
|
herd.WithCallback(
|
||||||
s.MountOP(
|
s.MountOP(
|
||||||
runtime.OEM.Label,
|
runtime.OEM.Name,
|
||||||
s.path("/oem"),
|
s.path("/oem"),
|
||||||
runtime.OEM.Type,
|
runtime.OEM.Type,
|
||||||
[]string{
|
[]string{
|
||||||
@@ -443,8 +456,8 @@ func (s *State) Register(g *herd.Graph) error {
|
|||||||
"suid",
|
"suid",
|
||||||
"dev",
|
"dev",
|
||||||
"exec",
|
"exec",
|
||||||
"noauto",
|
//"noauto",
|
||||||
"nouser",
|
//"nouser",
|
||||||
"async",
|
"async",
|
||||||
}, 10*time.Second),
|
}, 10*time.Second),
|
||||||
),
|
),
|
||||||
|
@@ -3,6 +3,10 @@ package mount
|
|||||||
import (
|
import (
|
||||||
"github.com/containerd/containerd/mount"
|
"github.com/containerd/containerd/mount"
|
||||||
"github.com/deniswernert/go-fstab"
|
"github.com/deniswernert/go-fstab"
|
||||||
|
"github.com/moby/sys/mountinfo"
|
||||||
|
"github.com/rs/zerolog"
|
||||||
|
"github.com/rs/zerolog/log"
|
||||||
|
"os"
|
||||||
)
|
)
|
||||||
|
|
||||||
type mountOperation struct {
|
type mountOperation struct {
|
||||||
@@ -13,11 +17,22 @@ type mountOperation struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (m mountOperation) run() error {
|
func (m mountOperation) run() error {
|
||||||
|
log.Logger = log.Output(zerolog.ConsoleWriter{Out: os.Stderr}).With().Caller().Logger()
|
||||||
if m.PrepareCallback != nil {
|
if m.PrepareCallback != nil {
|
||||||
if err := m.PrepareCallback(); err != nil {
|
if err := m.PrepareCallback(); err != nil {
|
||||||
|
log.Logger.Err(err).Str("what", m.MountOption.Source).Str("where", m.Target).Str("type", m.MountOption.Type).Msg("executing mount callback")
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
//TODO: not only check if mounted but also if the type,options and source are the same?
|
||||||
|
mounted, err := mountinfo.Mounted(m.Target)
|
||||||
|
if err != nil {
|
||||||
|
log.Logger.Err(err).Str("what", m.MountOption.Source).Str("where", m.Target).Str("type", m.MountOption.Type).Msg("checking mount status")
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if mounted {
|
||||||
|
log.Logger.Debug().Str("what", m.MountOption.Source).Str("where", m.Target).Str("type", m.MountOption.Type).Msg("Already mounted")
|
||||||
|
return nil
|
||||||
|
}
|
||||||
return mount.All([]mount.Mount{m.MountOption}, m.Target)
|
return mount.All([]mount.Mount{m.MountOption}, m.Target)
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user