2023-01-13 15:41:39 +00:00
|
|
|
// package config contains all the logic around kcrypt config
|
|
|
|
// This config includes everything below `kcrypt:` in the kairos config yaml
|
|
|
|
package config
|
|
|
|
|
|
|
|
import (
|
|
|
|
"fmt"
|
2023-03-29 12:14:50 +00:00
|
|
|
"os"
|
2023-01-13 15:41:39 +00:00
|
|
|
"strings"
|
|
|
|
|
|
|
|
"github.com/jaypipes/ghw/pkg/block"
|
2023-06-14 12:26:42 +00:00
|
|
|
"github.com/kairos-io/kairos-sdk/collector"
|
2023-01-13 15:41:39 +00:00
|
|
|
"github.com/pkg/errors"
|
2024-07-15 17:53:00 +00:00
|
|
|
"gopkg.in/yaml.v3"
|
2023-01-13 15:41:39 +00:00
|
|
|
)
|
|
|
|
|
|
|
|
// There are the directories under which we expect to find kairos configuration.
|
|
|
|
// When we are booted from an iso (during installation), configuration is expected
|
|
|
|
// under `/oem`. When we are booting an installed system (in initramfs phase),
|
|
|
|
// the path is `/sysroot/oem`.
|
|
|
|
var ConfigScanDirs = []string{"/oem", "/sysroot/oem"}
|
|
|
|
|
|
|
|
// This file is "hardcoded" to `/oem` because we only use this at install time
|
|
|
|
// in which case the config is in `/oem`.
|
|
|
|
var MappingsFile = "/oem/91-kcrypt-mappings.yaml"
|
|
|
|
|
|
|
|
type Config struct {
|
|
|
|
Kcrypt struct {
|
|
|
|
UUIDLabelMappings map[string]string `yaml:"uuid_label_mappings,omitempty"`
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func PartitionToString(p *block.Partition) string {
|
2023-05-03 13:18:56 +00:00
|
|
|
return fmt.Sprintf("%s:%s:%s", p.FilesystemLabel, p.Name, p.UUID)
|
2023-01-13 15:41:39 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// Takes a partition info string (as returned by PartitionToString) and return
|
|
|
|
// the partition label and the UUID
|
|
|
|
func partitionDataFromString(partitionStr string) (string, string, error) {
|
|
|
|
parts := strings.Split(partitionStr, ":")
|
|
|
|
if len(parts) != 3 {
|
|
|
|
return "", "", errors.New("partition string not valid")
|
|
|
|
}
|
|
|
|
|
|
|
|
return strings.TrimSpace(parts[0]), strings.TrimSpace(parts[2]), nil
|
|
|
|
}
|
|
|
|
|
|
|
|
func GetConfiguration(configDirs []string) (Config, error) {
|
|
|
|
var result Config
|
|
|
|
|
2023-06-14 12:26:42 +00:00
|
|
|
o := &collector.Options{MergeBootCMDLine: false}
|
2023-03-23 16:10:39 +00:00
|
|
|
|
|
|
|
if err := o.Apply(collector.Directories(configDirs...), collector.NoLogs); err != nil {
|
2023-01-13 15:41:39 +00:00
|
|
|
return result, err
|
|
|
|
}
|
|
|
|
|
2023-06-14 12:26:42 +00:00
|
|
|
c, err := collector.Scan(o, func(d []byte) ([]byte, error) {
|
|
|
|
return d, nil
|
|
|
|
})
|
2023-03-23 16:10:39 +00:00
|
|
|
if err != nil {
|
|
|
|
return result, err
|
|
|
|
}
|
|
|
|
configStr, err := c.String()
|
|
|
|
if err != nil {
|
|
|
|
return result, err
|
|
|
|
}
|
|
|
|
if err = yaml.Unmarshal([]byte(configStr), &result); err != nil {
|
2023-01-13 15:41:39 +00:00
|
|
|
return result, err
|
|
|
|
}
|
|
|
|
|
|
|
|
return result, nil
|
|
|
|
}
|
|
|
|
|
|
|
|
// SetMapping updates the Config with partition information for
|
|
|
|
// one partition. This doesn't persist on the file. WriteMappings needs to
|
|
|
|
// be called after all mapping are in the Config (possibly with multiple calls
|
|
|
|
// to this function).
|
|
|
|
func (c *Config) SetMapping(partitionInfo string) error {
|
|
|
|
label, uuid, err := partitionDataFromString(partitionInfo)
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
// Initialize map
|
|
|
|
if c.Kcrypt.UUIDLabelMappings == nil {
|
|
|
|
c.Kcrypt.UUIDLabelMappings = map[string]string{}
|
|
|
|
}
|
|
|
|
c.Kcrypt.UUIDLabelMappings[label] = uuid
|
|
|
|
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
|
|
|
// WriteMappings will create or replace the MappingsFile
|
|
|
|
// It's called by kairos agent, at installation time, after the partitions
|
|
|
|
// have been created (and we have the UUIDs available).
|
|
|
|
func (c *Config) WriteMappings(fileName string) error {
|
|
|
|
data, err := yaml.Marshal(&c)
|
|
|
|
if err != nil {
|
|
|
|
return errors.Wrap(err, "marshalling the kcrypt configuration to yaml")
|
|
|
|
}
|
|
|
|
|
2023-03-23 16:10:39 +00:00
|
|
|
data = append([]byte(collector.DefaultHeader+"\n"), data...)
|
|
|
|
|
2023-03-29 12:14:50 +00:00
|
|
|
err = os.WriteFile(fileName, data, 0744)
|
2023-01-13 15:41:39 +00:00
|
|
|
if err != nil {
|
|
|
|
return errors.Wrap(err, "writing the kcrypt configuration file")
|
|
|
|
}
|
|
|
|
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
|
|
|
func (c Config) LookupUUIDForLabel(l string) string {
|
|
|
|
return c.Kcrypt.UUIDLabelMappings[l]
|
|
|
|
}
|
|
|
|
|
|
|
|
func (c Config) LookupLabelForUUID(uuid string) string {
|
|
|
|
for k, v := range c.Kcrypt.UUIDLabelMappings {
|
|
|
|
if v == uuid {
|
|
|
|
return k
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return ""
|
|
|
|
}
|