immucore/pkg/op/operation.go
2024-03-20 11:48:51 +01:00

50 lines
1.6 KiB
Go

package op
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"
)
type MountOperation struct {
FstabEntry fstab.Mount
MountOption mount.Mount
Target string
PrepareCallback func() error
}
func (m MountOperation) Run() error {
// Add context to sublogger
l := internalUtils.Log.With().Str("what", m.MountOption.Source).Str("where", m.Target).Str("type", m.MountOption.Type).Strs("options", m.MountOption.Options).Logger()
// Not sure why this defaults to debuglevel when creating a sublogger, so make sure we set it properly
debug := len(internalUtils.ReadCMDLineArg("rd.immucore.debug")) > 0
if debug {
l = l.Level(zerolog.DebugLevel)
}
if m.PrepareCallback != nil {
if err := m.PrepareCallback(); err != nil {
l.Warn().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 {
l.Warn().Err(err).Msg("checking mount status")
return err
}
// In UKI mode we need to remount things from ephemeral to persistent if persistent exists so we need to skip the check for mount
// only in UKI (/home basically)
if mounted && !internalUtils.IsUKI() {
l.Debug().Msg("Already mounted")
return constants.ErrAlreadyMounted
}
l.Debug().Msg("mount ready")
return mount.All([]mount.Mount{m.MountOption}, m.Target)
}