Uki Support (#67)

Signed-off-by: Itxaka <itxaka.garcia@spectrocloud.com>
This commit is contained in:
Itxaka 2023-03-01 11:42:46 +01:00 committed by GitHub
parent de9ed759eb
commit 086227d672
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
16 changed files with 384 additions and 145 deletions

4
go.mod
View File

@ -9,11 +9,13 @@ require (
github.com/joho/godotenv v1.5.1
github.com/kairos-io/kairos v1.5.0
github.com/moby/sys/mountinfo v0.6.2
github.com/mudler/go-kdetect v0.0.0-20210802130128-dd92e121bed8
github.com/onsi/ginkgo/v2 v2.8.4
github.com/onsi/gomega v1.27.2
github.com/rs/zerolog v1.29.0
github.com/spectrocloud-labs/herd v0.4.2
github.com/urfave/cli/v2 v2.24.4
golang.org/x/sys v0.5.0
)
require (
@ -49,6 +51,7 @@ require (
github.com/mattn/go-runewidth v0.0.14 // indirect
github.com/mitchellh/go-homedir v1.1.0 // indirect
github.com/nfnt/resize v0.0.0-20180221191011-83c6a9932646 // indirect
github.com/pilebones/go-udev v0.0.0-20210126000448-a3c2a7a4afb7 // indirect
github.com/pkg/errors v0.9.1 // indirect
github.com/pterm/pterm v0.12.54 // indirect
github.com/qeesung/image2ascii v1.0.1 // indirect
@ -62,7 +65,6 @@ require (
go.opencensus.io v0.23.0 // indirect
golang.org/x/exp v0.0.0-20220909182711-5c715a9e8561 // indirect
golang.org/x/net v0.7.0 // indirect
golang.org/x/sys v0.5.0 // indirect
golang.org/x/term v0.5.0 // indirect
golang.org/x/text v0.7.0 // indirect
golang.org/x/tools v0.6.0 // indirect

12
go.sum
View File

@ -68,8 +68,6 @@ github.com/Microsoft/hcsshim v0.8.14/go.mod h1:NtVKoYxQuTLx6gEq0L96c9Ju4JbRJ4nY2
github.com/Microsoft/hcsshim v0.8.15/go.mod h1:x38A4YbHbdxJtc0sF6oIz+RG0npwSCAvn69iY6URG00=
github.com/Microsoft/hcsshim v0.8.16/go.mod h1:o5/SZqmR7x9JNKsW3pu+nqHm0MF8vbA+VxGOoXdC600=
github.com/Microsoft/hcsshim v0.8.21/go.mod h1:+w2gRZ5ReXQhFOrvSQeNfhrYB/dg3oDwTOcER2fw4I4=
github.com/Microsoft/hcsshim v0.9.6 h1:VwnDOgLeoi2du6dAznfmspNqTiwczvjv4K7NxuY9jsY=
github.com/Microsoft/hcsshim v0.9.6/go.mod h1:7pLA8lDk46WKDWlVsENo92gC0XFa8rbKfyFRBqxEbCc=
github.com/Microsoft/hcsshim v0.9.7 h1:mKNHW/Xvv1aFH87Jb6ERDzXTJTLPlmzfZ28VBFD/bfg=
github.com/Microsoft/hcsshim v0.9.7/go.mod h1:7pLA8lDk46WKDWlVsENo92gC0XFa8rbKfyFRBqxEbCc=
github.com/Microsoft/hcsshim/test v0.0.0-20201218223536-d3e5debf77da/go.mod h1:5hlzMzRKMLyo42nCZ9oml8AdTlq/0cvIaBv6tK1RehU=
@ -166,8 +164,6 @@ github.com/containerd/containerd v1.5.0-beta.4/go.mod h1:GmdgZd2zA2GYIBZ0w09Zvgq
github.com/containerd/containerd v1.5.0-rc.0/go.mod h1:V/IXoMqNGgBlabz3tHD2TWDoTJseu1FGOKuoA4nNb2s=
github.com/containerd/containerd v1.5.1/go.mod h1:0DOxVqwDy2iZvrZp2JUx/E+hS0UNTVn7dJnIOwtYR4g=
github.com/containerd/containerd v1.5.7/go.mod h1:gyvv6+ugqY25TiXxcZC3L5yOeYgEw0QMhscqVp1AR9c=
github.com/containerd/containerd v1.6.18 h1:qZbsLvmyu+Vlty0/Ex5xc0z2YtKpIsb5n45mAMI+2Ns=
github.com/containerd/containerd v1.6.18/go.mod h1:1RdCUu95+gc2v9t3IL+zIlpClSmew7/0YS8O5eQZrOw=
github.com/containerd/containerd v1.6.19 h1:F0qgQPrG0P2JPgwpxWxYavrVeXAG0ezUIB9Z/4FTUAU=
github.com/containerd/containerd v1.6.19/go.mod h1:HZCDMn4v/Xl2579/MvtOC2M206i+JJ6VxFWU/NetrGY=
github.com/containerd/continuity v0.0.0-20190426062206-aaeac12a7ffc/go.mod h1:GL3xCUCBDV3CZiTSEKksMWbLE66hEyuu9qyDOOqM47Y=
@ -543,6 +539,8 @@ github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lN
github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
github.com/morikuni/aec v1.0.0/go.mod h1:BbKIizmSmc5MMPqRYbxO4ZU0S0+P200+tUnFx7PXmsc=
github.com/mrunalp/fileutils v0.5.0/go.mod h1:M1WthSahJixYnrXQl/DFQuteStB1weuxD2QJNHXfbSQ=
github.com/mudler/go-kdetect v0.0.0-20210802130128-dd92e121bed8 h1:+g0budy5fEFMX5+ChzEhXbb7YnNWNveQgHF/iQ/UXmE=
github.com/mudler/go-kdetect v0.0.0-20210802130128-dd92e121bed8/go.mod h1:826dAJvIa3X5kfBoxSupdQbIFO4egt+hoUiw4BfPKdI=
github.com/munnerz/goautoneg v0.0.0-20120707110453-a547fc61f48d/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ=
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ=
github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U=
@ -564,8 +562,6 @@ github.com/onsi/ginkgo v1.10.3/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+
github.com/onsi/ginkgo v1.11.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
github.com/onsi/ginkgo v1.12.0/go.mod h1:oUhWkIvk5aDxtKvDDuw8gItl8pKl42LzjC9KZE0HfGg=
github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk=
github.com/onsi/ginkgo/v2 v2.8.3 h1:RpbK1G8nWPNaCVFBWsOGnEQQGgASi6b8fxcWBvDYjxQ=
github.com/onsi/ginkgo/v2 v2.8.3/go.mod h1:6OaUA8BCi0aZfmzYT/q9AacwTzDpNbxILUT+TlBq6MY=
github.com/onsi/ginkgo/v2 v2.8.4 h1:gf5mIQ8cLFieruNLAdgijHF1PYfLphKm2dxxcUtcqK0=
github.com/onsi/ginkgo/v2 v2.8.4/go.mod h1:427dEDQZkDKsBvCjc2A/ZPefhKxsTTrsQegMlayL730=
github.com/onsi/gomega v0.0.0-20151007035656-2152b45fa28a/go.mod h1:C1qb7wdrVGGVU+Z6iS04AVkA3Q65CEZX59MT0QO5uiA=
@ -575,8 +571,6 @@ github.com/onsi/gomega v1.7.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1Cpa
github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY=
github.com/onsi/gomega v1.9.0/go.mod h1:Ho0h+IUsWyvy1OpqCwxlQ/21gkhVunqlU8fDGcoTdcA=
github.com/onsi/gomega v1.10.3/go.mod h1:V9xEwhxec5O8UDM77eCW8vLymOMltsqPVYWrpDsH8xc=
github.com/onsi/gomega v1.27.1 h1:rfztXRbg6nv/5f+Raen9RcGoSecHIFgBBLQK3Wdj754=
github.com/onsi/gomega v1.27.1/go.mod h1:aHX5xOykVYzWOV4WqQy0sy8BQptgukenXpCXfadcIAw=
github.com/onsi/gomega v1.27.2 h1:SKU0CXeKE/WVgIV1T61kSa3+IRE8Ekrv9rdXDwwTqnY=
github.com/onsi/gomega v1.27.2/go.mod h1:5mR3phAHpkAVIDkHEUBY6HGVsU+cpcEscrGPB4oPlZI=
github.com/opencontainers/go-digest v0.0.0-20170106003457-a6d0ee40d420/go.mod h1:cMLVZDEM3+U2I4VmLI6N8jQYUd2OVphdqWwCJHrFt2s=
@ -606,6 +600,8 @@ github.com/opencontainers/selinux v1.8.2/go.mod h1:MUIHuUEvKB1wtJjQdOyYRgOnLD2xA
github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic=
github.com/pelletier/go-toml v1.8.1/go.mod h1:T2/BmBdy8dvIRq1a/8aqjN41wvWlN4lrapLU/GW4pbc=
github.com/peterbourgon/diskv v2.0.1+incompatible/go.mod h1:uqqh8zWWbv1HBMNONnaR/tNboyR3/BZd58JJSHlUSCU=
github.com/pilebones/go-udev v0.0.0-20210126000448-a3c2a7a4afb7 h1:1If5vu3Qy1ZL3NshlsrSQMsdRhujenaVFbHcFM9XQUk=
github.com/pilebones/go-udev v0.0.0-20210126000448-a3c2a7a4afb7/go.mod h1:T2eI2tUSK0hA2WS5QLjXJUfQkluZQu+18Cqvem3CaXI=
github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pkg/errors v0.8.1-0.20171018195549-f15c970de5b7/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=

View File

@ -10,22 +10,22 @@ func DefaultRWPaths() []string {
var ErrAlreadyMounted = errors.New("already mounted")
const (
OpCustomMounts = "custom-mount"
OpDiscoverState = "discover-state"
OpMountState = "mount-state"
OpMountBind = "mount-bind"
OpMountRoot = "mount-root"
OpOverlayMount = "overlay-mount"
OpWriteFstab = "write-fstab"
OpMountBaseOverlay = "mount-base-overlay"
OpMountOEM = "mount-oem"
OpRootfsHook = "rootfs-hook"
OpLoadConfig = "load-config"
OpMountTmpfs = "mount-tmpfs"
OpSentinel = "create-sentinel"
OpCustomMounts = "custom-mount"
OpDiscoverState = "discover-state"
OpMountState = "mount-state"
OpMountBind = "mount-bind"
OpMountRoot = "mount-root"
OpOverlayMount = "overlay-mount"
OpWriteFstab = "write-fstab"
OpMountBaseOverlay = "mount-base-overlay"
OpMountOEM = "mount-oem"
OpRootfsHook = "rootfs-hook"
OpInitramfsHook = "initramfs-hook"
OpLoadConfig = "load-config"
OpMountTmpfs = "mount-tmpfs"
OpRemountRootRO = "remount-ro"
OpUkiInit = "uki-init"
OpSentinel = "create-sentinel"
OpUkiUdev = "uki-udev"
PersistentStateTarget = "/usr/local/.state"
)

View File

@ -3,8 +3,8 @@ package utils
import (
"github.com/joho/godotenv"
"github.com/kairos-io/kairos/sdk/state"
"github.com/rs/zerolog/log"
"os"
"os/exec"
"path/filepath"
"strings"
)
@ -32,7 +32,7 @@ func BootStateToLabelDevice() string {
func GetRootDir() string {
cmdline, _ := os.ReadFile("/proc/cmdline")
switch {
case strings.Contains(string(cmdline), "IMMUCORE_NOPIVOT"):
case strings.Contains(string(cmdline), "rd.immucore.uki"):
return "/"
default:
// Default is sysroot for normal no-pivot boot
@ -99,7 +99,7 @@ func CleanupSlice(slice []string) []string {
// GetTarget gets the target image and device to mount in /sysroot
func GetTarget(dryRun bool) (string, string) {
var img, label string
var label string
label = BootStateToLabelDevice()
@ -108,16 +108,20 @@ func GetTarget(dryRun bool) (string, string) {
return "fake", label
}
img = ReadCMDLineArg("cos-img/filename=")[0]
imgs := ReadCMDLineArg("cos-img/filename=")
// If no image just panic here, we cannot longer continue
if img == "" {
log.Logger.Fatal().Msg("Could not get the image name from cmdline (i.e. cos-img/filename=/cOS/active.img)")
if len(imgs) == 0 {
if IsUKI() {
imgs = []string{""}
} else {
Log.Fatal().Msg("could not get the image name from cmdline (i.e. cos-img/filename=/cOS/active.img)")
}
}
log.Debug().Str("what", img).Msg("Target device")
log.Debug().Str("what", label).Msg("Target label")
return img, label
Log.Debug().Str("what", imgs[0]).Msg("Target device")
Log.Debug().Str("what", label).Msg("Target label")
return imgs[0], label
}
// DisableImmucore identifies if we need to be disabled
@ -132,7 +136,7 @@ func DisableImmucore() bool {
// RootRW tells us if the mode to mount root
func RootRW() string {
if len(ReadCMDLineArg("rd.cos.debugrw")) > 0 {
log.Logger.Warn().Msg("Mounting root as RW")
Log.Warn().Msg("Mounting root as RW")
return "rw"
}
return "ro"
@ -152,6 +156,24 @@ func GetState() string {
case state.Recovery:
label = filepath.Join("/dev/disk/by-label/", runtime.Recovery.Label)
}
log.Logger.Debug().Str("what", label).Msg("Get state label")
Log.Debug().Str("what", label).Msg("Get state label")
return label
}
func IsUKI() bool {
if len(ReadCMDLineArg("rd.immucore.uki")) > 0 {
return true
}
return false
}
// CommandWithPath runs a command adding the usual PATH to environment
// Useful under UKI as there is nothing setting the PATH
func CommandWithPath(c string) (string, error) {
cmd := exec.Command("/bin/sh", "-c", c)
cmd.Env = os.Environ()
// TODO: extract PATH from env and append to existing instead of overwriting
cmd.Env = append(cmd.Env, "PATH=/usr/bin:/usr/sbin")
o, err := cmd.CombinedOutput()
return string(o), err
}

45
internal/utils/log.go Normal file
View File

@ -0,0 +1,45 @@
package utils
import (
"github.com/rs/zerolog"
"golang.org/x/sys/unix"
"io"
"os"
)
var Log zerolog.Logger
var devKmsgFile *os.File
var logFile *os.File
func CloseLogFiles() {
devKmsgFile.Close()
logFile.Close()
}
func SetLogger() {
var loggers []io.Writer
devKmsgFile, err := os.OpenFile("/dev/kmsg", unix.O_WRONLY, 0o600)
if err == nil {
loggers = append(loggers, zerolog.ConsoleWriter{Out: devKmsgFile})
}
logFile, err := os.Create("/run/immucore.log")
if err == nil {
loggers = append(loggers, zerolog.ConsoleWriter{Out: logFile})
}
// No loggers? Then stdout ¯\_(ツ)_/¯
if len(loggers) == 0 {
loggers = append(loggers, zerolog.ConsoleWriter{Out: os.Stderr})
}
multi := zerolog.MultiLevelWriter(loggers...)
Log = zerolog.New(multi).With().Logger()
Log.WithLevel(zerolog.InfoLevel)
// Set debug logger
debug := len(ReadCMDLineArg("rd.immucore.debug")) > 0
debugFromEnv := os.Getenv("IMMUCORE_DEBUG") != ""
if debug || debugFromEnv {
Log = zerolog.New(multi).With().Caller().Logger()
Log.WithLevel(zerolog.DebugLevel)
}
}

View File

@ -4,11 +4,9 @@ import (
"fmt"
"github.com/containerd/containerd/mount"
"github.com/deniswernert/go-fstab"
"github.com/kairos-io/kairos/pkg/utils"
"github.com/rs/zerolog/log"
"os"
"os/exec"
"strings"
"syscall"
)
// https://github.com/kairos-io/packages/blob/7c3581a8ba6371e5ce10c3a98bae54fde6a505af/packages/system/dracut/immutable-rootfs/30cos-immutable-rootfs/cos-mount-layout.sh#L58
@ -54,7 +52,7 @@ func ReadCMDLineArg(arg string) []string {
// IsMounted lets us know if the given device is currently mounted
func IsMounted(dev string) bool {
_, err := utils.SH(fmt.Sprintf("findmnt %s", dev))
_, err := CommandWithPath(fmt.Sprintf("findmnt %s", dev))
return err == nil
}
@ -62,18 +60,19 @@ func IsMounted(dev string) bool {
// Does NOT need to be mounted
// Needs full path so either /dev/sda1 or /dev/disk/by-{label,uuid}/{label,uuid}
func DiskFSType(s string) string {
out, e := utils.SH(fmt.Sprintf("blkid %s -s TYPE -o value", s))
out, e := CommandWithPath(fmt.Sprintf("blkid %s -s TYPE -o value", s))
if e != nil {
log.Logger.Err(e).Msg("blkid")
Log.Err(e).Msg("blkid")
}
out = strings.Trim(strings.Trim(out, " "), "\n")
log.Logger.Debug().Str("what", s).Str("type", out).Msg("Partition FS type")
Log.Debug().Str("what", s).Str("type", out).Msg("Partition FS type")
return out
}
// SyncState will rsync source into destination. Useful for Bind mounts.
func SyncState(src, dst string) error {
return exec.Command("rsync", "-aqAX", src, dst).Run()
_, err := CommandWithPath(fmt.Sprintf("rsync -aqAX %s %s", src, dst))
return err
}
// AppendSlash it's in the name. Appends a slash.
@ -113,6 +112,9 @@ func MountToFstab(m mount.Mount) *fstab.Mount {
// Special care for the root (/sysroot) path as we can't just simple remove that path and call it a day
// as that will return an empty mountpoint which will break fstab mounting
func CleanSysrootForFstab(path string) string {
if IsUKI() {
return path
}
cleaned := strings.ReplaceAll(path, "/sysroot", "")
if cleaned == "" {
cleaned = "/"
@ -161,11 +163,41 @@ func Fsck(device string) error {
args = append(args, "-n")
}
cmd := strings.Join(args, " ")
log.Logger.Debug().Str("cmd", cmd).Msg("fsck command")
out, e := utils.SH(cmd)
log.Logger.Debug().Str("output", out).Msg("fsck output")
Log.Debug().Str("cmd", cmd).Msg("fsck command")
out, e := CommandWithPath(cmd)
Log.Debug().Str("output", out).Msg("fsck output")
if e != nil {
log.Logger.Warn().Str("error", e.Error()).Str("what", device).Msg("fsck")
Log.Warn().Str("error", e.Error()).Str("what", device).Msg("fsck")
}
return e
}
// MinimalMounts will set the minimal mounts needed for immucore
// For now only proc is needed to read the cmdline fully in uki mode
// in normal modes this should already be done by the initramfs process, so we can ignore errors
// Just mount dev, tmp and sys just in case
func MinimalMounts() {
type m struct {
source string
target string
t string
flags int
data string
}
toMount := []m{
{"dev", "/dev", "devtmpfs", syscall.MS_NOSUID, "mode=755"},
{"proc", "/proc", "proc", syscall.MS_NOSUID | syscall.MS_NODEV | syscall.MS_NOEXEC | syscall.MS_RELATIME, ""},
{"sys", "/sys", "sysfs", syscall.MS_NOSUID | syscall.MS_NODEV | syscall.MS_NOEXEC | syscall.MS_RELATIME, ""},
{"tmp", "/tmp", "tmpfs", syscall.MS_NOSUID | syscall.MS_NODEV, ""},
{"run", "/run", "tmpfs", syscall.MS_NOSUID | syscall.MS_NODEV | syscall.MS_NOEXEC | syscall.MS_RELATIME, "mode=755"},
}
for _, mnt := range toMount {
_ = os.MkdirAll(mnt.target, 0755)
if !IsMounted(mnt.target) {
err := syscall.Mount(mnt.source, mnt.target, mnt.t, uintptr(mnt.flags), mnt.data)
if err != nil {
fmt.Println(err.Error())
}
}
}
}

View File

@ -5,7 +5,7 @@ import "runtime"
var (
version = "v0.0.1"
// gitCommit is the git sha1 + dirty if build from a dirty git
gitCommit = ""
gitCommit = "none"
)
func GetVersion() string {

44
main.go
View File

@ -6,8 +6,6 @@ import (
"github.com/kairos-io/immucore/internal/utils"
"github.com/kairos-io/immucore/internal/version"
"github.com/kairos-io/immucore/pkg/mount"
"github.com/rs/zerolog"
"github.com/rs/zerolog/log"
"github.com/spectrocloud-labs/herd"
"github.com/urfave/cli/v2"
"os"
@ -20,27 +18,23 @@ func main() {
app.Authors = []*cli.Author{{Name: "Kairos authors"}}
app.Copyright = "kairos authors"
app.Action = func(c *cli.Context) (err error) {
debug := len(utils.ReadCMDLineArg("rd.immucore.debug")) > 0
log.Logger = log.Output(zerolog.ConsoleWriter{Out: os.Stderr}).With().Logger()
zerolog.SetGlobalLevel(zerolog.InfoLevel)
debugFromEnv := os.Getenv("IMMUCORE_DEBUG") != ""
if debug || debugFromEnv {
log.Logger = log.Output(zerolog.ConsoleWriter{Out: os.Stderr}).With().Caller().Logger()
zerolog.SetGlobalLevel(zerolog.DebugLevel)
}
var targetDevice, targetImage string
var state *mount.State
utils.MinimalMounts()
utils.SetLogger()
v := version.Get()
log.Logger.Info().Str("commit", v.GitCommit).Str("compiled with", v.GoVersion).Str("version", v.Version).Msg("Immucore")
utils.Log.Info().Str("commit", v.GitCommit).Str("compiled with", v.GoVersion).Str("version", v.Version).Msg("Immucore")
cmdline, _ := os.ReadFile("/proc/cmdline")
log.Logger.Debug().Msg(string(cmdline))
utils.Log.Debug().Str("content", string(cmdline)).Msg("cmdline")
g := herd.DAG(herd.EnableInit)
// Get targets and state
targetImage, targetDevice := utils.GetTarget(c.Bool("dry-run"))
targetImage, targetDevice = utils.GetTarget(c.Bool("dry-run"))
s := &mount.State{
Logger: log.Logger,
state = &mount.State{
Rootdir: utils.GetRootDir(),
TargetDevice: targetDevice,
TargetImage: targetImage,
@ -48,19 +42,21 @@ func main() {
}
if utils.DisableImmucore() {
log.Logger.Info().Msg("Stanza rd.cos.disable on the cmdline or booting from CDROM/Netboot/Squash recovery. Disabling immucore.")
err = s.RegisterLiveMedia(g)
utils.Log.Info().Msg("Stanza rd.cos.disable on the cmdline or booting from CDROM/Netboot/Squash recovery. Disabling immucore.")
err = state.RegisterLiveMedia(g)
} else if utils.IsUKI() {
utils.Log.Info().Msg("UKI booting!")
err = state.RegisterUKI(g)
} else {
log.Logger.Info().Msg("Booting on active/passive/recovery.")
err = s.RegisterNormalBoot(g)
utils.Log.Info().Msg("Booting on active/passive/recovery.")
err = state.RegisterNormalBoot(g)
}
if err != nil {
s.Logger.Err(err)
return err
}
log.Info().Msg(s.WriteDAG(g))
utils.Log.Info().Msg(state.WriteDAG(g))
// Once we print the dag we can exit already
if c.Bool("dry-run") {
@ -68,7 +64,7 @@ func main() {
}
err = g.Run(context.Background())
log.Info().Msg(s.WriteDAG(g))
utils.Log.Info().Msg(state.WriteDAG(g))
return err
}
app.Flags = []cli.Flag{
@ -81,10 +77,8 @@ func main() {
Name: "version",
Usage: "version",
Action: func(c *cli.Context) error {
log.Logger = log.Output(zerolog.ConsoleWriter{Out: os.Stderr}).With().Logger()
zerolog.SetGlobalLevel(zerolog.InfoLevel)
v := version.Get()
log.Logger.Info().Str("commit", v.GitCommit).Str("compiled with", v.GoVersion).Str("version", v.Version).Msg("Immucore")
utils.Log.Info().Str("commit", v.GitCommit).Str("compiled with", v.GoVersion).Str("version", v.Version).Msg("Immucore")
return nil
},
},

View File

@ -1,6 +1,7 @@
package mount
import (
internalUtils "github.com/kairos-io/immucore/internal/utils"
"github.com/spectrocloud-labs/herd"
)
@ -10,5 +11,6 @@ func (s *State) RegisterLiveMedia(g *herd.Graph) error {
var err error
// Maybe LogIfErrorAndPanic ? If no sentinel, a lot of config files are not going to run
err = s.LogIfErrorAndReturn(s.WriteSentinelDagStep(g), "write sentinel")
internalUtils.CloseLogFiles()
return err
}

View File

@ -2,6 +2,7 @@ package mount
import (
cnst "github.com/kairos-io/immucore/internal/constants"
internalUtils "github.com/kairos-io/immucore/internal/utils"
"github.com/spectrocloud-labs/herd"
)
@ -31,7 +32,7 @@ func (s *State) RegisterNormalBoot(g *herd.Graph) error {
// Populate state bind mounts, overlay mounts, custom-mounts from /run/cos/cos-layout.env
// Requires stage rootfs to have run, which usually creates the cos-layout.env file
s.LogIfError(s.LoadEnvLayoutDagStep(g), "loading cos-layout.env")
s.LogIfError(s.LoadEnvLayoutDagStep(g, cnst.OpRootfsHook), "loading cos-layout.env")
// Mount base overlay under /run/overlay
s.LogIfError(s.MountBaseOverlayDagStep(g), "base overlay mount")
@ -51,6 +52,6 @@ func (s *State) RegisterNormalBoot(g *herd.Graph) error {
// Write fstab file
s.LogIfError(s.WriteFstabDagStep(g), "write fstab")
internalUtils.CloseLogFiles()
return err
}

View File

@ -9,12 +9,13 @@ import (
internalUtils "github.com/kairos-io/immucore/internal/utils"
"github.com/kairos-io/kairos/pkg/utils"
"github.com/kairos-io/kairos/sdk/state"
"github.com/rs/zerolog"
"github.com/rs/zerolog/log"
"github.com/mudler/go-kdetect"
"github.com/spectrocloud-labs/herd"
"golang.org/x/sys/unix"
"os"
"path/filepath"
"strings"
"syscall"
"time"
)
@ -43,7 +44,7 @@ func (s *State) MountRootDagStep(g *herd.Graph) error {
),
)
if err != nil {
s.Logger.Err(err).Send()
internalUtils.Log.Err(err).Send()
}
// 2 - mount the image as a loop device
@ -53,7 +54,7 @@ func (s *State) MountRootDagStep(g *herd.Graph) error {
func(ctx context.Context) error {
// Check if loop device is mounted already
if internalUtils.IsMounted(s.TargetDevice) {
log.Logger.Debug().Str("targetImage", s.TargetImage).Str("path", s.Rootdir).Str("TargetDevice", s.TargetDevice).Msg("Not mounting loop, already mounted")
internalUtils.Log.Debug().Str("targetImage", s.TargetImage).Str("path", s.Rootdir).Str("TargetDevice", s.TargetDevice).Msg("Not mounting loop, already mounted")
return nil
}
_ = internalUtils.Fsck(s.path("/run/initramfs/cos-state", s.TargetImage))
@ -65,13 +66,13 @@ func (s *State) MountRootDagStep(g *herd.Graph) error {
// But on other it seems like it won't trigger which causes the sysroot to not be mounted as we cant find
// the block device by the target label. Make sure we run this after mounting so we refresh the devices.
sh, _ := utils.SH("udevadm trigger")
s.Logger.Debug().Str("output", sh).Msg("udevadm trigger")
log.Logger.Debug().Str("targetImage", s.TargetImage).Str("path", s.Rootdir).Str("TargetDevice", s.TargetDevice).Msg("mount done")
internalUtils.Log.Debug().Str("output", sh).Msg("udevadm trigger")
internalUtils.Log.Debug().Str("targetImage", s.TargetImage).Str("path", s.Rootdir).Str("TargetDevice", s.TargetDevice).Msg("mount done")
return err
},
))
if err != nil {
s.Logger.Err(err).Send()
internalUtils.Log.Err(err).Send()
}
// 3 - Mount the labels as Rootdir
@ -94,7 +95,7 @@ func (s *State) MountRootDagStep(g *herd.Graph) error {
),
)
if err != nil {
s.Logger.Err(err).Send()
internalUtils.Log.Err(err).Send()
}
return err
}
@ -104,19 +105,23 @@ func (s *State) RootfsStageDagStep(g *herd.Graph, deps ...string) error {
return g.Add(cnst.OpRootfsHook, herd.WithDeps(deps...), herd.WithCallback(s.RunStageOp("rootfs")))
}
// InitramfsStageDagStep will add the rootfs stage.
func (s *State) InitramfsStageDagStep(g *herd.Graph, deps ...string) error {
return g.Add(cnst.OpInitramfsHook, herd.WithDeps(deps...), herd.WeakDeps, herd.WithCallback(s.RunStageOp("initramfs")))
}
// LoadEnvLayoutDagStep will add the stage to load from cos-layout.env and fill the proper CustomMounts, OverlayDirs and BindMounts
func (s *State) LoadEnvLayoutDagStep(g *herd.Graph) error {
func (s *State) LoadEnvLayoutDagStep(g *herd.Graph, deps ...string) error {
return g.Add(cnst.OpLoadConfig,
herd.WithDeps(cnst.OpRootfsHook),
herd.WithDeps(deps...),
herd.WithCallback(func(ctx context.Context) error {
log.Logger = log.Output(zerolog.ConsoleWriter{Out: os.Stderr}).With().Logger()
if s.CustomMounts == nil {
s.CustomMounts = map[string]string{}
}
env, err := internalUtils.ReadEnv("/run/cos/cos-layout.env")
if err != nil {
log.Logger.Err(err).Msg("Reading env")
internalUtils.Log.Err(err).Msg("Reading env")
return err
}
// populate from env here
@ -162,7 +167,7 @@ func (s *State) LoadEnvLayoutDagStep(g *herd.Graph) error {
func (s *State) MountOemDagStep(g *herd.Graph, deps ...string) error {
runtime, err := state.NewRuntime()
if err != nil {
s.Logger.Debug().Err(err).Msg("runtime")
internalUtils.Log.Debug().Err(err).Msg("runtime")
}
return g.Add(cnst.OpMountOEM,
herd.WithDeps(deps...),
@ -220,13 +225,13 @@ func (s *State) MountCustomOverlayDagStep(g *herd.Graph) error {
herd.WithCallback(
func(ctx context.Context) error {
var multierr *multierror.Error
s.Logger.Debug().Strs("dirs", s.OverlayDirs).Msg("Mounting overlays")
internalUtils.Log.Debug().Strs("dirs", s.OverlayDirs).Msg("Mounting overlays")
for _, p := range s.OverlayDirs {
op := mountWithBaseOverlay(p, s.Rootdir, "/run/overlay")
err := op.run()
// Append to errors only if it's not an already mounted error
if err != nil && !errors.Is(err, cnst.ErrAlreadyMounted) {
log.Logger.Err(err).Msg("overlay mount")
internalUtils.Log.Err(err).Msg("overlay mount")
multierr = multierror.Append(multierr, err)
continue
}
@ -249,20 +254,25 @@ func (s *State) MountCustomMountsDagStep(g *herd.Graph) error {
// TODO: scan for the custom mount disk to know the underlying fs and set it proper
fstype := "ext4"
mountOptions := []string{"ro"}
// TODO: Are custom mounts always rw?ro?depends? Clarify.
// Persistent needs to be RW
if strings.Contains(what, "COS_PERSISTENT") {
mountOptions = []string{"rw"}
}
err = multierror.Append(err, s.MountOP(
err2 := s.MountOP(
what,
s.path(where),
fstype,
mountOptions,
10*time.Second,
)(ctx))
3*time.Second,
)(ctx)
// If its COS_OEM and it fails then we can safely ignore, as it's not mandatory to have COS_OEM
if err2 != nil && !strings.Contains(what, "COS_OEM") {
err = multierror.Append(err, err2)
}
}
s.Logger.Err(err.ErrorOrNil()).Send()
internalUtils.Log.Err(err.ErrorOrNil()).Send()
return err.ErrorOrNil()
}),
@ -277,7 +287,7 @@ func (s *State) MountCustomBindsDagStep(g *herd.Graph) error {
herd.WithCallback(
func(ctx context.Context) error {
var err *multierror.Error
s.Logger.Debug().Strs("mounts", s.BindMounts).Msg("Mounting binds")
internalUtils.Log.Debug().Strs("mounts", s.BindMounts).Msg("Mounting binds")
for _, p := range s.BindMounts {
op := mountBind(p, s.Rootdir, s.StateDir)
@ -288,11 +298,11 @@ func (s *State) MountCustomBindsDagStep(g *herd.Graph) error {
}
// Append to errors only if it's not an already mounted error
if err2 != nil && !errors.Is(err2, cnst.ErrAlreadyMounted) {
log.Logger.Err(err2).Send()
internalUtils.Log.Err(err2).Send()
err = multierror.Append(err, err2)
}
}
log.Logger.Err(err.ErrorOrNil()).Send()
internalUtils.Log.Err(err.ErrorOrNil()).Send()
return err.ErrorOrNil()
},
),
@ -345,11 +355,111 @@ func (s *State) WriteSentinelDagStep(g *herd.Graph) error {
sentinel = "live_mode"
}
s.Logger.Info().Str("to", sentinel).Msg("Setting sentinel file")
internalUtils.Log.Info().Str("to", sentinel).Msg("Setting sentinel file")
err = os.WriteFile(filepath.Join("/run/cos/", sentinel), []byte("1"), os.ModePerm)
if err != nil {
return err
}
// Lets add a uki sentinel as well!
if strings.Contains(cmdlineS, "rd.immucore.uki") {
err = os.WriteFile("/run/cos/uki_mode", []byte("1"), os.ModePerm)
if err != nil {
return err
}
}
return nil
}))
}
// UKIBootInitDagStep tries to launch /sbin/init in root and pass over the system
// booting to the real init process
// Drops to emergency if not able to. Panic if it cant even launch emergency
func (s *State) UKIBootInitDagStep(g *herd.Graph, deps ...string) error {
return g.Add(cnst.OpUkiInit,
herd.WithDeps(deps...),
herd.WeakDeps,
herd.WithCallback(func(ctx context.Context) error {
// Print dag before exit, otherwise its never printed as we never exit the program
internalUtils.Log.Info().Msg(s.WriteDAG(g))
internalUtils.Log.Debug().Msg("Executing init callback!")
internalUtils.CloseLogFiles()
if err := unix.Exec("/sbin/init", []string{"/sbin/init", "--system"}, os.Environ()); err != nil {
internalUtils.Log.Err(err).Msg("running init")
// drop to emergency shell
if err := unix.Exec("/bin/bash", []string{"/bin/bash"}, os.Environ()); err != nil {
internalUtils.Log.Fatal().Msg("Could not drop to emergency shell")
}
}
return nil
}))
}
// UKIRemountRootRODagStep remount root read only
func (s *State) UKIRemountRootRODagStep(g *herd.Graph, deps ...string) error {
return g.Add(cnst.OpRemountRootRO,
herd.WithDeps(deps...),
herd.WithCallback(func(ctx context.Context) error {
return syscall.Mount("/", "/", "rootfs", syscall.MS_REMOUNT|syscall.MS_RDONLY, "")
}),
)
}
// UKIUdevDaemon launches the udevd daemon and triggers+settles in order to discover devices
// Needed if we expect to find devices by label...
func (s *State) UKIUdevDaemon(g *herd.Graph) error {
return g.Add(cnst.OpUkiUdev,
herd.WithCallback(func(ctx context.Context) error {
// Should probably figure out other udevd binaries....
var udevBin string
if _, err := os.Stat("/usr/lib/systemd/systemd-udevd"); !os.IsNotExist(err) {
udevBin = "/usr/lib/systemd/systemd-udevd"
}
cmd := fmt.Sprintf("%s --daemon", udevBin)
out, err := internalUtils.CommandWithPath(cmd)
internalUtils.Log.Debug().Str("out", out).Str("cmd", cmd).Msg("Udev daemon")
if err != nil {
internalUtils.Log.Err(err).Msg("Udev daemon")
return err
}
out, err = internalUtils.CommandWithPath("udevadm trigger")
internalUtils.Log.Debug().Str("out", out).Msg("Udev trigger")
if err != nil {
internalUtils.Log.Err(err).Msg("Udev trigger")
return err
}
out, err = internalUtils.CommandWithPath("udevadm settle")
internalUtils.Log.Debug().Str("out", out).Msg("Udev settle")
if err != nil {
internalUtils.Log.Err(err).Msg("Udev settle")
return err
}
return nil
}),
)
}
// LoadKernelModules loads kernel modules needed during uki boot to load the disks for.
// Mainly block devices and net devices
// probably others down the line
func (s *State) LoadKernelModules(g *herd.Graph) error {
return g.Add("kernel-modules",
herd.WithCallback(func(ctx context.Context) error {
drivers, err := kdetect.ProbeKernelModules("")
if err != nil {
internalUtils.Log.Err(err).Msg("Detecting needed modules")
}
internalUtils.Log.Debug().Strs("drivers", drivers).Msg("Detecting needed modules")
for _, driver := range drivers {
cmd := fmt.Sprintf("modprobe %s", driver)
out, err := internalUtils.CommandWithPath(cmd)
if err != nil {
internalUtils.Log.Err(err).Str("out", out).Msg("modprobe")
}
}
return nil
}),
)
}

52
pkg/mount/dag_uki_boot.go Normal file
View File

@ -0,0 +1,52 @@
package mount
import (
cnst "github.com/kairos-io/immucore/internal/constants"
"github.com/spectrocloud-labs/herd"
)
// RegisterUKI registers the dag for booting from UKI
func (s *State) RegisterUKI(g *herd.Graph) error {
// Write sentinel
s.LogIfError(s.WriteSentinelDagStep(g), "sentinel")
s.LogIfError(s.LoadKernelModules(g), "kernel modules")
// Udev for devices discovery
s.LogIfError(s.UKIUdevDaemon(g), "udev")
// Run rootfs stage
s.LogIfError(s.RootfsStageDagStep(g, cnst.OpSentinel), "uki rootfs")
// Remount root RO
s.LogIfError(s.UKIRemountRootRODagStep(g, cnst.OpRootfsHook), "remount root")
// Mount base overlay under /run/overlay
s.LogIfError(s.MountBaseOverlayDagStep(g), "base overlay")
// Populate state bind mounts, overlay mounts, custom-mounts from /run/cos/cos-layout.env
// Requires stage rootfs to have run, which usually creates the cos-layout.env file
s.LogIfError(s.LoadEnvLayoutDagStep(g, cnst.OpRootfsHook), "loading cos-layout.env")
// Mount custom overlays loaded from the /run/cos/cos-layout.env file
s.LogIfError(s.MountCustomOverlayDagStep(g), "custom overlays mount")
// Mount custom mounts loaded from the /run/cos/cos-layout.env file
s.LogIfError(s.MountCustomMountsDagStep(g), "custom mounts mount")
// Mount custom binds loaded from the /run/cos/cos-layout.env file
// Depends on mount binds as that usually mounts COS_PERSISTENT
s.LogIfError(s.MountCustomBindsDagStep(g), "custom binds mount")
// run initramfs stage
s.LogIfError(s.InitramfsStageDagStep(g, cnst.OpMountBind), "uki initramfs")
s.LogIfError(g.Add(cnst.OpWriteFstab,
herd.WithDeps(cnst.OpLoadConfig, cnst.OpCustomMounts, cnst.OpMountBind, cnst.OpOverlayMount),
herd.WeakDeps,
herd.WithCallback(s.WriteFstab(s.path("/etc/fstab")))), "fstab")
// Handover to /sbin/init
_ = s.UKIBootInitDagStep(g, cnst.OpRemountRootRO, cnst.OpRootfsHook, cnst.OpInitramfsHook)
return nil
}

View File

@ -62,14 +62,13 @@ func mountBind(mountpoint, root, stateTarget string) mountOperation {
Type: "overlay",
Source: stateDir,
Options: []string{
//"defaults",
"bind",
},
}
internalUtils.Log.Debug().Str("mountpoint", mountpoint).Str("root", root).Str("bindMountPath", bindMountPath).Msg("BIND")
tmpFstab := internalUtils.MountToFstab(tmpMount)
tmpFstab.File = internalUtils.CleanSysrootForFstab(fmt.Sprintf("/%s", mountpoint))
tmpFstab.Spec = strings.ReplaceAll(tmpFstab.Spec, root, "")
tmpFstab.Spec = internalUtils.CleanSysrootForFstab(tmpFstab.Spec)
return mountOperation{
MountOption: tmpMount,
FstabEntry: *tmpFstab,

View File

@ -4,10 +4,8 @@ import (
"github.com/containerd/containerd/mount"
"github.com/deniswernert/go-fstab"
"github.com/kairos-io/immucore/internal/constants"
internalUtils "github.com/kairos-io/immucore/internal/utils"
"github.com/moby/sys/mountinfo"
"github.com/rs/zerolog"
"github.com/rs/zerolog/log"
"os"
)
type mountOperation struct {
@ -18,23 +16,23 @@ type mountOperation struct {
}
func (m mountOperation) run() error {
log.Logger = log.Output(zerolog.ConsoleWriter{Out: os.Stderr}).With().Str("what", m.MountOption.Source).Str("where", m.Target).Str("type", m.MountOption.Type).Strs("options", m.MountOption.Options).Logger()
internalUtils.Log.With().Str("what", m.MountOption.Source).Str("where", m.Target).Str("type", m.MountOption.Type).Strs("options", m.MountOption.Options).Logger()
if m.PrepareCallback != nil {
if err := m.PrepareCallback(); err != nil {
log.Logger.Err(err).Msg("executing mount callback")
internalUtils.Log.Err(err).Msg("executing mount callback")
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).Msg("checking mount status")
internalUtils.Log.Err(err).Msg("checking mount status")
return err
}
if mounted {
log.Logger.Debug().Msg("Already mounted")
internalUtils.Log.Debug().Msg("Already mounted")
return constants.ErrAlreadyMounted
}
log.Logger.Debug().Msg("mount ready")
internalUtils.Log.Debug().Msg("mount ready")
return mount.All([]mount.Mount{m.MountOption}, m.Target)
}

View File

@ -12,14 +12,11 @@ import (
"github.com/deniswernert/go-fstab"
"github.com/kairos-io/immucore/internal/constants"
internalUtils "github.com/kairos-io/immucore/internal/utils"
"github.com/kairos-io/kairos/pkg/utils"
"github.com/rs/zerolog"
"github.com/rs/zerolog/log"
"github.com/spectrocloud-labs/herd"
)
type State struct {
Logger zerolog.Logger
Rootdir string // where to mount the root partition e.g. /sysroot inside initrd with pivot, / with nopivot
TargetImage string // image from the state partition to mount as loop device e.g. /cOS/active.img
TargetDevice string // e.g. /dev/disk/by-label/COS_ACTIVE
@ -39,7 +36,6 @@ func (s *State) path(p ...string) string {
}
func (s *State) WriteFstab(fstabFile string) func(context.Context) error {
log.Logger = log.Output(zerolog.ConsoleWriter{Out: os.Stderr}).With().Logger()
return func(ctx context.Context) error {
for _, fst := range s.fstabs {
select {
@ -62,37 +58,38 @@ func (s *State) WriteFstab(fstabFile string) func(context.Context) error {
}
// RunStageOp runs elemental run-stage stage. If its rootfs its special as it needs som symlinks
// If its uki we don't symlink as we already have everything in the sysroot
func (s *State) RunStageOp(stage string) func(context.Context) error {
return func(ctx context.Context) error {
if stage == "rootfs" {
if stage == "rootfs" && !internalUtils.IsUKI() {
if _, err := os.Stat("/system"); os.IsNotExist(err) {
err = os.Symlink("/sysroot/system", "/system")
if err != nil {
s.Logger.Err(err).Msg("creating symlink")
internalUtils.Log.Err(err).Msg("creating symlink")
}
}
if _, err := os.Stat("/oem"); os.IsNotExist(err) {
err = os.Symlink("/sysroot/oem", "/oem")
if err != nil {
s.Logger.Err(err).Msg("creating symlink")
internalUtils.Log.Err(err).Msg("creating symlink")
}
}
}
cmd := fmt.Sprintf("elemental run-stage %s", stage)
cmd := fmt.Sprintf("/usr/bin/elemental run-stage %s", stage)
// If we set the level to debug, also call elemental with debug
if s.Logger.GetLevel() == zerolog.DebugLevel {
if internalUtils.Log.GetLevel() == zerolog.DebugLevel {
cmd = fmt.Sprintf("%s --debug", cmd)
}
output, err := utils.SH(cmd)
s.Logger.Debug().Msg(output)
output, err := internalUtils.CommandWithPath(cmd)
internalUtils.Log.Debug().Msg(output)
return err
}
}
// MountOP creates and executes a mount operation
func (s *State) MountOP(what, where, t string, options []string, timeout time.Duration) func(context.Context) error {
log.Logger.With().Str("what", what).Str("where", where).Str("type", t).Strs("options", options).Logger()
internalUtils.Log.With().Str("what", what).Str("where", where).Str("type", t).Strs("options", options).Logger()
return func(c context.Context) error {
cc := time.After(timeout)
@ -101,7 +98,7 @@ func (s *State) MountOP(what, where, t string, options []string, timeout time.Du
default:
err := internalUtils.CreateIfNotExists(where)
if err != nil {
log.Logger.Err(err).Msg("Creating dir")
internalUtils.Log.Err(err).Msg("Creating dir")
continue
}
time.Sleep(1 * time.Second)
@ -130,18 +127,18 @@ func (s *State) MountOP(what, where, t string, options []string, timeout time.Du
// only continue the loop if it's an error and not an already mounted error
if err != nil && !errors.Is(err, constants.ErrAlreadyMounted) {
s.Logger.Err(err).Send()
internalUtils.Log.Err(err).Send()
continue
}
log.Logger.Debug().Msg("mount done")
internalUtils.Log.Debug().Msg("mount done")
return nil
case <-c.Done():
e := fmt.Errorf("context canceled")
log.Logger.Err(e).Msg("mount canceled")
internalUtils.Log.Err(e).Msg("mount canceled")
return e
case <-cc:
e := fmt.Errorf("timeout exhausted")
log.Logger.Err(e).Msg("Mount timeout")
internalUtils.Log.Err(e).Msg("Mount timeout")
return e
}
}
@ -167,7 +164,7 @@ func (s *State) WriteDAG(g *herd.Graph) (out string) {
// Context can be empty
func (s *State) LogIfError(e error, msgContext string) {
if e != nil {
s.Logger.Err(e).Msg(msgContext)
internalUtils.Log.Err(e).Msg(msgContext)
}
}
@ -176,7 +173,7 @@ func (s *State) LogIfError(e error, msgContext string) {
// Will also return the error
func (s *State) LogIfErrorAndReturn(e error, msgContext string) error {
if e != nil {
s.Logger.Err(e).Msg(msgContext)
internalUtils.Log.Err(e).Msg(msgContext)
}
return e
}
@ -186,7 +183,7 @@ func (s *State) LogIfErrorAndReturn(e error, msgContext string) error {
// Will also panic
func (s *State) LogIfErrorAndPanic(e error, msgContext string) {
if e != nil {
s.Logger.Err(e).Msg(msgContext)
s.Logger.Fatal().Msg(e.Error())
internalUtils.Log.Err(e).Msg(msgContext)
internalUtils.Log.Fatal().Msg(e.Error())
}
}

View File

@ -2,9 +2,6 @@ package mount_test
import (
"context"
"github.com/rs/zerolog"
"github.com/rs/zerolog/log"
"os"
"time"
"github.com/kairos-io/immucore/pkg/mount"
@ -24,7 +21,6 @@ var _ = Describe("mounting immutable setup", func() {
Context("simple invocation", func() {
It("generates normal dag", func() {
s := &mount.State{
Logger: log.Output(zerolog.ConsoleWriter{Out: os.Stderr}).With().Logger(),
Rootdir: "/",
TargetImage: "/cOS/myimage.img",
TargetDevice: "/dev/disk/by-label/COS_LABEL",
@ -73,17 +69,10 @@ var _ = Describe("mounting immutable setup", func() {
func checkLiveCDDag(dag [][]herd.GraphEntry, actualDag string) {
Expect(len(dag)).To(Equal(2), actualDag)
Expect(len(dag[0])).To(Equal(1), actualDag)
Expect(len(dag[1])).To(Equal(2), actualDag)
Expect(len(dag[1])).To(Equal(1), actualDag)
Expect(dag[0][0].Name).To(Equal("init"))
Expect(dag[1][0].Name).To(Or(
Equal("mount-tmpfs"),
Equal("create-sentinel"),
), actualDag)
Expect(dag[1][1].Name).To(Or(
Equal("mount-tmpfs"),
Equal("create-sentinel"),
), actualDag)
Expect(dag[1][0].Name).To(Equal("create-sentinel"))
}
func checkDag(dag [][]herd.GraphEntry, actualDag string) {