mirror of
https://github.com/kairos-io/immucore.git
synced 2025-09-01 05:08:44 +00:00
4
go.mod
4
go.mod
@@ -9,13 +9,11 @@ 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.3
|
||||
github.com/onsi/gomega v1.27.1
|
||||
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 (
|
||||
@@ -51,7 +49,6 @@ 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
|
||||
@@ -65,6 +62,7 @@ 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
|
||||
|
4
go.sum
4
go.sum
@@ -539,8 +539,6 @@ 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=
|
||||
@@ -600,8 +598,6 @@ 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=
|
||||
|
@@ -14,18 +14,18 @@ const (
|
||||
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"
|
||||
)
|
||||
|
@@ -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), "rd.immucore.uki"):
|
||||
case strings.Contains(string(cmdline), "IMMUCORE_NOPIVOT"):
|
||||
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 label string
|
||||
var img, label string
|
||||
|
||||
label = BootStateToLabelDevice()
|
||||
|
||||
@@ -108,20 +108,16 @@ func GetTarget(dryRun bool) (string, string) {
|
||||
return "fake", label
|
||||
}
|
||||
|
||||
imgs := ReadCMDLineArg("cos-img/filename=")
|
||||
img = ReadCMDLineArg("cos-img/filename=")[0]
|
||||
|
||||
// If no image just panic here, we cannot longer continue
|
||||
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)")
|
||||
}
|
||||
if img == "" {
|
||||
log.Logger.Fatal().Msg("Could not get the image name from cmdline (i.e. cos-img/filename=/cOS/active.img)")
|
||||
}
|
||||
|
||||
Log.Debug().Str("what", imgs[0]).Msg("Target device")
|
||||
Log.Debug().Str("what", label).Msg("Target label")
|
||||
return imgs[0], label
|
||||
log.Debug().Str("what", img).Msg("Target device")
|
||||
log.Debug().Str("what", label).Msg("Target label")
|
||||
return img, label
|
||||
}
|
||||
|
||||
// DisableImmucore identifies if we need to be disabled
|
||||
@@ -136,7 +132,7 @@ func DisableImmucore() bool {
|
||||
// RootRW tells us if the mode to mount root
|
||||
func RootRW() string {
|
||||
if len(ReadCMDLineArg("rd.cos.debugrw")) > 0 {
|
||||
Log.Warn().Msg("Mounting root as RW")
|
||||
log.Logger.Warn().Msg("Mounting root as RW")
|
||||
return "rw"
|
||||
}
|
||||
return "ro"
|
||||
@@ -156,24 +152,6 @@ func GetState() string {
|
||||
case state.Recovery:
|
||||
label = filepath.Join("/dev/disk/by-label/", runtime.Recovery.Label)
|
||||
}
|
||||
Log.Debug().Str("what", label).Msg("Get state label")
|
||||
log.Logger.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
|
||||
}
|
||||
|
@@ -1,47 +0,0 @@
|
||||
package utils
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/rs/zerolog"
|
||||
"golang.org/x/sys/unix"
|
||||
"io"
|
||||
"os"
|
||||
)
|
||||
|
||||
var Log zerolog.Logger
|
||||
|
||||
func SetLogger() {
|
||||
var loggers []io.Writer
|
||||
devKmsg, err := os.OpenFile("/dev/kmsg", unix.O_WRONLY, 0o600)
|
||||
if err == nil {
|
||||
err := os.WriteFile("/proc/sys/kernel/printk_ratelimit", []byte("100"), os.ModeType)
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
}
|
||||
err = os.WriteFile("/proc/sys/kernel/printk_ratelimit_burst", []byte("1000"), os.ModeType)
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
}
|
||||
loggers = append(loggers, zerolog.ConsoleWriter{Out: devKmsg})
|
||||
}
|
||||
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.Stdout})
|
||||
}
|
||||
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)
|
||||
}
|
||||
}
|
@@ -4,9 +4,11 @@ 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
|
||||
@@ -52,7 +54,7 @@ func ReadCMDLineArg(arg string) []string {
|
||||
|
||||
// IsMounted lets us know if the given device is currently mounted
|
||||
func IsMounted(dev string) bool {
|
||||
_, err := CommandWithPath(fmt.Sprintf("findmnt %s", dev))
|
||||
_, err := utils.SH(fmt.Sprintf("findmnt %s", dev))
|
||||
return err == nil
|
||||
}
|
||||
|
||||
@@ -60,19 +62,18 @@ 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 := CommandWithPath(fmt.Sprintf("blkid %s -s TYPE -o value", s))
|
||||
out, e := utils.SH(fmt.Sprintf("blkid %s -s TYPE -o value", s))
|
||||
if e != nil {
|
||||
Log.Err(e).Msg("blkid")
|
||||
log.Logger.Err(e).Msg("blkid")
|
||||
}
|
||||
out = strings.Trim(strings.Trim(out, " "), "\n")
|
||||
Log.Debug().Str("what", s).Str("type", out).Msg("Partition FS type")
|
||||
log.Logger.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 {
|
||||
_, err := CommandWithPath(fmt.Sprintf("rsync -aqAX %s %s", src, dst))
|
||||
return err
|
||||
return exec.Command("rsync", "-aqAX", src, dst).Run()
|
||||
}
|
||||
|
||||
// AppendSlash it's in the name. Appends a slash.
|
||||
@@ -112,9 +113,6 @@ 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 = "/"
|
||||
@@ -163,34 +161,11 @@ func Fsck(device string) error {
|
||||
args = append(args, "-n")
|
||||
}
|
||||
cmd := strings.Join(args, " ")
|
||||
Log.Debug().Str("cmd", cmd).Msg("fsck command")
|
||||
out, e := CommandWithPath(cmd)
|
||||
Log.Debug().Str("output", out).Msg("fsck output")
|
||||
log.Logger.Debug().Str("cmd", cmd).Msg("fsck command")
|
||||
out, e := utils.SH(cmd)
|
||||
log.Logger.Debug().Str("output", out).Msg("fsck output")
|
||||
if e != nil {
|
||||
Log.Warn().Str("error", e.Error()).Str("what", device).Msg("fsck")
|
||||
log.Logger.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
|
||||
}
|
||||
toMount := []m{
|
||||
{"dev", "/dev", "devtmpfs"},
|
||||
{"proc", "/proc", "proc"},
|
||||
{"sys", "/sys", "sysfs"},
|
||||
{"tmp", "/tmp", "tmpfs"},
|
||||
{"run", "/run", "tmpfs"},
|
||||
}
|
||||
for _, mnt := range toMount {
|
||||
_ = os.MkdirAll(mnt.target, 0755)
|
||||
_ = syscall.Mount(mnt.source, mnt.target, mnt.t, 0, "")
|
||||
}
|
||||
}
|
||||
|
@@ -5,7 +5,7 @@ import "runtime"
|
||||
var (
|
||||
version = "v0.0.1"
|
||||
// gitCommit is the git sha1 + dirty if build from a dirty git
|
||||
gitCommit = "none"
|
||||
gitCommit = ""
|
||||
)
|
||||
|
||||
func GetVersion() string {
|
||||
|
44
main.go
44
main.go
@@ -6,6 +6,8 @@ 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"
|
||||
@@ -18,23 +20,27 @@ func main() {
|
||||
app.Authors = []*cli.Author{{Name: "Kairos authors"}}
|
||||
app.Copyright = "kairos authors"
|
||||
app.Action = func(c *cli.Context) (err error) {
|
||||
var targetDevice, targetImage string
|
||||
var state *mount.State
|
||||
|
||||
utils.MinimalMounts()
|
||||
utils.SetLogger()
|
||||
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)
|
||||
}
|
||||
|
||||
v := version.Get()
|
||||
utils.Log.Info().Str("commit", v.GitCommit).Str("compiled with", v.GoVersion).Str("version", v.Version).Msg("Immucore")
|
||||
log.Logger.Info().Str("commit", v.GitCommit).Str("compiled with", v.GoVersion).Str("version", v.Version).Msg("Immucore")
|
||||
|
||||
cmdline, _ := os.ReadFile("/proc/cmdline")
|
||||
utils.Log.Debug().Str("content", string(cmdline)).Msg("cmdline")
|
||||
log.Logger.Debug().Msg(string(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"))
|
||||
|
||||
state = &mount.State{
|
||||
s := &mount.State{
|
||||
Logger: log.Logger,
|
||||
Rootdir: utils.GetRootDir(),
|
||||
TargetDevice: targetDevice,
|
||||
TargetImage: targetImage,
|
||||
@@ -42,21 +48,19 @@ func main() {
|
||||
}
|
||||
|
||||
if utils.DisableImmucore() {
|
||||
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)
|
||||
log.Logger.Info().Msg("Stanza rd.cos.disable on the cmdline or booting from CDROM/Netboot/Squash recovery. Disabling immucore.")
|
||||
err = s.RegisterLiveMedia(g)
|
||||
} else {
|
||||
utils.Log.Info().Msg("Booting on active/passive/recovery.")
|
||||
err = state.RegisterNormalBoot(g)
|
||||
log.Logger.Info().Msg("Booting on active/passive/recovery.")
|
||||
err = s.RegisterNormalBoot(g)
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
s.Logger.Err(err)
|
||||
return err
|
||||
}
|
||||
|
||||
utils.Log.Info().Msg(state.WriteDAG(g))
|
||||
log.Info().Msg(s.WriteDAG(g))
|
||||
|
||||
// Once we print the dag we can exit already
|
||||
if c.Bool("dry-run") {
|
||||
@@ -64,7 +68,7 @@ func main() {
|
||||
}
|
||||
|
||||
err = g.Run(context.Background())
|
||||
utils.Log.Info().Msg(state.WriteDAG(g))
|
||||
log.Info().Msg(s.WriteDAG(g))
|
||||
return err
|
||||
}
|
||||
app.Flags = []cli.Flag{
|
||||
@@ -77,8 +81,10 @@ 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()
|
||||
utils.Log.Info().Str("commit", v.GitCommit).Str("compiled with", v.GoVersion).Str("version", v.Version).Msg("Immucore")
|
||||
log.Logger.Info().Str("commit", v.GitCommit).Str("compiled with", v.GoVersion).Str("version", v.Version).Msg("Immucore")
|
||||
return nil
|
||||
},
|
||||
},
|
||||
|
@@ -31,7 +31,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, cnst.OpRootfsHook), "loading cos-layout.env")
|
||||
s.LogIfError(s.LoadEnvLayoutDagStep(g), "loading cos-layout.env")
|
||||
|
||||
// Mount base overlay under /run/overlay
|
||||
s.LogIfError(s.MountBaseOverlayDagStep(g), "base overlay mount")
|
||||
|
@@ -9,13 +9,12 @@ 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/mudler/go-kdetect"
|
||||
"github.com/rs/zerolog"
|
||||
"github.com/rs/zerolog/log"
|
||||
"github.com/spectrocloud-labs/herd"
|
||||
"golang.org/x/sys/unix"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
"syscall"
|
||||
"time"
|
||||
)
|
||||
|
||||
@@ -44,7 +43,7 @@ func (s *State) MountRootDagStep(g *herd.Graph) error {
|
||||
),
|
||||
)
|
||||
if err != nil {
|
||||
internalUtils.Log.Err(err).Send()
|
||||
s.Logger.Err(err).Send()
|
||||
}
|
||||
|
||||
// 2 - mount the image as a loop device
|
||||
@@ -54,7 +53,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) {
|
||||
internalUtils.Log.Debug().Str("targetImage", s.TargetImage).Str("path", s.Rootdir).Str("TargetDevice", s.TargetDevice).Msg("Not mounting loop, already mounted")
|
||||
log.Logger.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))
|
||||
@@ -66,13 +65,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")
|
||||
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")
|
||||
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")
|
||||
return err
|
||||
},
|
||||
))
|
||||
if err != nil {
|
||||
internalUtils.Log.Err(err).Send()
|
||||
s.Logger.Err(err).Send()
|
||||
}
|
||||
|
||||
// 3 - Mount the labels as Rootdir
|
||||
@@ -95,7 +94,7 @@ func (s *State) MountRootDagStep(g *herd.Graph) error {
|
||||
),
|
||||
)
|
||||
if err != nil {
|
||||
internalUtils.Log.Err(err).Send()
|
||||
s.Logger.Err(err).Send()
|
||||
}
|
||||
return err
|
||||
}
|
||||
@@ -105,23 +104,19 @@ 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, deps ...string) error {
|
||||
func (s *State) LoadEnvLayoutDagStep(g *herd.Graph) error {
|
||||
return g.Add(cnst.OpLoadConfig,
|
||||
herd.WithDeps(deps...),
|
||||
herd.WithDeps(cnst.OpRootfsHook),
|
||||
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 {
|
||||
internalUtils.Log.Err(err).Msg("Reading env")
|
||||
log.Logger.Err(err).Msg("Reading env")
|
||||
return err
|
||||
}
|
||||
// populate from env here
|
||||
@@ -167,7 +162,7 @@ func (s *State) LoadEnvLayoutDagStep(g *herd.Graph, deps ...string) error {
|
||||
func (s *State) MountOemDagStep(g *herd.Graph, deps ...string) error {
|
||||
runtime, err := state.NewRuntime()
|
||||
if err != nil {
|
||||
internalUtils.Log.Debug().Err(err).Msg("runtime")
|
||||
s.Logger.Debug().Err(err).Msg("runtime")
|
||||
}
|
||||
return g.Add(cnst.OpMountOEM,
|
||||
herd.WithDeps(deps...),
|
||||
@@ -225,13 +220,13 @@ func (s *State) MountCustomOverlayDagStep(g *herd.Graph) error {
|
||||
herd.WithCallback(
|
||||
func(ctx context.Context) error {
|
||||
var multierr *multierror.Error
|
||||
internalUtils.Log.Debug().Strs("dirs", s.OverlayDirs).Msg("Mounting overlays")
|
||||
s.Logger.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) {
|
||||
internalUtils.Log.Err(err).Msg("overlay mount")
|
||||
log.Logger.Err(err).Msg("overlay mount")
|
||||
multierr = multierror.Append(multierr, err)
|
||||
continue
|
||||
}
|
||||
@@ -254,25 +249,20 @@ 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"}
|
||||
}
|
||||
err2 := s.MountOP(
|
||||
err = multierror.Append(err, s.MountOP(
|
||||
what,
|
||||
s.path(where),
|
||||
fstype,
|
||||
mountOptions,
|
||||
3*time.Second,
|
||||
)(ctx)
|
||||
10*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)
|
||||
}
|
||||
}
|
||||
internalUtils.Log.Err(err.ErrorOrNil()).Send()
|
||||
s.Logger.Err(err.ErrorOrNil()).Send()
|
||||
|
||||
return err.ErrorOrNil()
|
||||
}),
|
||||
@@ -287,7 +277,7 @@ func (s *State) MountCustomBindsDagStep(g *herd.Graph) error {
|
||||
herd.WithCallback(
|
||||
func(ctx context.Context) error {
|
||||
var err *multierror.Error
|
||||
internalUtils.Log.Debug().Strs("mounts", s.BindMounts).Msg("Mounting binds")
|
||||
s.Logger.Debug().Strs("mounts", s.BindMounts).Msg("Mounting binds")
|
||||
|
||||
for _, p := range s.BindMounts {
|
||||
op := mountBind(p, s.Rootdir, s.StateDir)
|
||||
@@ -298,11 +288,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) {
|
||||
internalUtils.Log.Err(err2).Send()
|
||||
log.Logger.Err(err2).Send()
|
||||
err = multierror.Append(err, err2)
|
||||
}
|
||||
}
|
||||
internalUtils.Log.Err(err.ErrorOrNil()).Send()
|
||||
log.Logger.Err(err.ErrorOrNil()).Send()
|
||||
return err.ErrorOrNil()
|
||||
},
|
||||
),
|
||||
@@ -355,110 +345,11 @@ func (s *State) WriteSentinelDagStep(g *herd.Graph) error {
|
||||
sentinel = "live_mode"
|
||||
}
|
||||
|
||||
internalUtils.Log.Info().Str("to", sentinel).Msg("Setting sentinel file")
|
||||
s.Logger.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!")
|
||||
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
|
||||
}),
|
||||
)
|
||||
}
|
||||
|
@@ -1,52 +0,0 @@
|
||||
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
|
||||
}
|
@@ -62,13 +62,14 @@ 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 = internalUtils.CleanSysrootForFstab(tmpFstab.Spec)
|
||||
tmpFstab.Spec = strings.ReplaceAll(tmpFstab.Spec, root, "")
|
||||
return mountOperation{
|
||||
MountOption: tmpMount,
|
||||
FstabEntry: *tmpFstab,
|
||||
|
@@ -4,8 +4,10 @@ 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 {
|
||||
@@ -16,23 +18,23 @@ type mountOperation struct {
|
||||
}
|
||||
|
||||
func (m mountOperation) run() error {
|
||||
internalUtils.Log.With().Str("what", m.MountOption.Source).Str("where", m.Target).Str("type", m.MountOption.Type).Strs("options", m.MountOption.Options).Logger()
|
||||
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()
|
||||
if m.PrepareCallback != nil {
|
||||
if err := m.PrepareCallback(); err != nil {
|
||||
internalUtils.Log.Err(err).Msg("executing mount callback")
|
||||
log.Logger.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 {
|
||||
internalUtils.Log.Err(err).Msg("checking mount status")
|
||||
log.Logger.Err(err).Msg("checking mount status")
|
||||
return err
|
||||
}
|
||||
if mounted {
|
||||
internalUtils.Log.Debug().Msg("Already mounted")
|
||||
log.Logger.Debug().Msg("Already mounted")
|
||||
return constants.ErrAlreadyMounted
|
||||
}
|
||||
internalUtils.Log.Debug().Msg("mount ready")
|
||||
log.Logger.Debug().Msg("mount ready")
|
||||
return mount.All([]mount.Mount{m.MountOption}, m.Target)
|
||||
}
|
||||
|
@@ -12,11 +12,14 @@ 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
|
||||
@@ -36,6 +39,7 @@ 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 {
|
||||
@@ -58,38 +62,37 @@ 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" && !internalUtils.IsUKI() {
|
||||
if stage == "rootfs" {
|
||||
if _, err := os.Stat("/system"); os.IsNotExist(err) {
|
||||
err = os.Symlink("/sysroot/system", "/system")
|
||||
if err != nil {
|
||||
internalUtils.Log.Err(err).Msg("creating symlink")
|
||||
s.Logger.Err(err).Msg("creating symlink")
|
||||
}
|
||||
}
|
||||
if _, err := os.Stat("/oem"); os.IsNotExist(err) {
|
||||
err = os.Symlink("/sysroot/oem", "/oem")
|
||||
if err != nil {
|
||||
internalUtils.Log.Err(err).Msg("creating symlink")
|
||||
s.Logger.Err(err).Msg("creating symlink")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
cmd := fmt.Sprintf("/usr/bin/elemental run-stage %s", stage)
|
||||
cmd := fmt.Sprintf("elemental run-stage %s", stage)
|
||||
// If we set the level to debug, also call elemental with debug
|
||||
if internalUtils.Log.GetLevel() == zerolog.DebugLevel {
|
||||
if s.Logger.GetLevel() == zerolog.DebugLevel {
|
||||
cmd = fmt.Sprintf("%s --debug", cmd)
|
||||
}
|
||||
output, err := internalUtils.CommandWithPath(cmd)
|
||||
internalUtils.Log.Debug().Msg(output)
|
||||
output, err := utils.SH(cmd)
|
||||
s.Logger.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 {
|
||||
internalUtils.Log.With().Str("what", what).Str("where", where).Str("type", t).Strs("options", options).Logger()
|
||||
log.Logger.With().Str("what", what).Str("where", where).Str("type", t).Strs("options", options).Logger()
|
||||
|
||||
return func(c context.Context) error {
|
||||
cc := time.After(timeout)
|
||||
@@ -98,7 +101,7 @@ func (s *State) MountOP(what, where, t string, options []string, timeout time.Du
|
||||
default:
|
||||
err := internalUtils.CreateIfNotExists(where)
|
||||
if err != nil {
|
||||
internalUtils.Log.Err(err).Msg("Creating dir")
|
||||
log.Logger.Err(err).Msg("Creating dir")
|
||||
continue
|
||||
}
|
||||
time.Sleep(1 * time.Second)
|
||||
@@ -127,18 +130,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) {
|
||||
internalUtils.Log.Err(err).Send()
|
||||
s.Logger.Err(err).Send()
|
||||
continue
|
||||
}
|
||||
internalUtils.Log.Debug().Msg("mount done")
|
||||
log.Logger.Debug().Msg("mount done")
|
||||
return nil
|
||||
case <-c.Done():
|
||||
e := fmt.Errorf("context canceled")
|
||||
internalUtils.Log.Err(e).Msg("mount canceled")
|
||||
log.Logger.Err(e).Msg("mount canceled")
|
||||
return e
|
||||
case <-cc:
|
||||
e := fmt.Errorf("timeout exhausted")
|
||||
internalUtils.Log.Err(e).Msg("Mount timeout")
|
||||
log.Logger.Err(e).Msg("Mount timeout")
|
||||
return e
|
||||
}
|
||||
}
|
||||
@@ -164,7 +167,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 {
|
||||
internalUtils.Log.Err(e).Msg(msgContext)
|
||||
s.Logger.Err(e).Msg(msgContext)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -173,7 +176,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 {
|
||||
internalUtils.Log.Err(e).Msg(msgContext)
|
||||
s.Logger.Err(e).Msg(msgContext)
|
||||
}
|
||||
return e
|
||||
}
|
||||
@@ -183,7 +186,7 @@ func (s *State) LogIfErrorAndReturn(e error, msgContext string) error {
|
||||
// Will also panic
|
||||
func (s *State) LogIfErrorAndPanic(e error, msgContext string) {
|
||||
if e != nil {
|
||||
internalUtils.Log.Err(e).Msg(msgContext)
|
||||
internalUtils.Log.Fatal().Msg(e.Error())
|
||||
s.Logger.Err(e).Msg(msgContext)
|
||||
s.Logger.Fatal().Msg(e.Error())
|
||||
}
|
||||
}
|
||||
|
@@ -2,6 +2,9 @@ package mount_test
|
||||
|
||||
import (
|
||||
"context"
|
||||
"github.com/rs/zerolog"
|
||||
"github.com/rs/zerolog/log"
|
||||
"os"
|
||||
"time"
|
||||
|
||||
"github.com/kairos-io/immucore/pkg/mount"
|
||||
@@ -21,6 +24,7 @@ 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",
|
||||
|
Reference in New Issue
Block a user