Implement generic sysext management

Signed-off-by: Itxaka <itxaka@kairos.io>
This commit is contained in:
Itxaka
2025-04-07 16:36:06 +02:00
parent 6eca30162d
commit 01cdac2c72
5 changed files with 88 additions and 52 deletions

View File

@@ -5,7 +5,6 @@ import (
"encoding/json"
"encoding/pem"
"fmt"
"io/fs"
"os"
"path/filepath"
"strings"
@@ -612,51 +611,3 @@ func (s *State) ExtractCerts(g *herd.Graph, opts ...herd.OpOption) error {
return nil
}))...)
}
// CopySysExtensionsDagStep Copies extensions from the EFI partitions to the persistent one so they can be started.
func (s *State) CopySysExtensionsDagStep(g *herd.Graph, opts ...herd.OpOption) error {
return g.Add(cnst.OpUkiCopySysExtensions, append(opts, herd.WithCallback(func(_ context.Context) error {
if !state.EfiBootFromInstall(internalUtils.Log) {
internalUtils.Log.Debug().Msg("Not copying sysextensions as we think we are booting from removable media")
return nil
}
// Copy the sys extensions to the rootfs
// Remember that we use s.path for the destination as it adds the future /sysroot prefix
// But for source, we are in initramfs so it should be without the prefix
// return if the source or dest dir is not there
if _, err := os.Stat(cnst.SourceSysExtDir); os.IsNotExist(err) {
internalUtils.Log.Debug().Str("dir", cnst.SourceSysExtDir).Msg("No sysextensions found")
return nil
}
if _, err := os.Stat(s.path(cnst.DestSysExtDir)); os.IsNotExist(err) {
_ = os.MkdirAll(s.path(cnst.DestSysExtDir), 0755)
}
err := filepath.WalkDir(s.path(cnst.SourceSysExtDir), func(_ string, d fs.DirEntry, err error) error {
if d.IsDir() {
return nil
}
src := filepath.Join(cnst.SourceSysExtDir, d.Name())
dest := s.path(filepath.Join(cnst.DestSysExtDir, d.Name()))
// TODO: Use the policy from the system config if exists, otherwise drop to default?
// This is to make it work also in non-uki envs where we might have a relaxed policy
output, err2 := internalUtils.CommandWithPath(fmt.Sprintf("systemd-dissect --validate %s %s", cnst.SysextDefaultPolicy, src))
if err2 != nil {
// If the file didn't pass the validation, we don't copy it
internalUtils.Log.Warn().Str("src", src).Msg("Sysextension does not pass validation")
internalUtils.Log.Debug().Err(err2).Str("src", src).Str("output", output).Msg("Validating sysextension")
return nil
}
// Copy the file to the sys-extensions directory
err2 = internalUtils.Copy(src, dest)
if err != nil {
internalUtils.Log.Err(err2).Str("src", src).Str("dest", dest).Msg("Copying sysextension")
}
internalUtils.Log.Debug().Str("src", src).Str("dest", dest).Msg("Copied sysextension")
return err2
})
return err
}))...)
}