kairos-agent/pkg/config/config.go

192 lines
5.0 KiB
Go
Raw Normal View History

package config
import (
"fmt"
"os"
"path/filepath"
2022-07-13 22:23:47 +00:00
"strings"
"unicode"
"github.com/kairos-io/kairos-sdk/bundles"
"github.com/kairos-io/kairos/v2/pkg/config/collector"
schema "github.com/kairos-io/kairos/v2/pkg/config/schemas"
yip "github.com/mudler/yip/pkg/schema"
"gopkg.in/yaml.v3"
)
const (
DefaultWebUIListenAddress = ":8080"
FilePrefix = "file://"
)
type Install struct {
sparkles: custom user bind and ephemeral mounts (#692) * :sparkles: custom user bind and ephemeral mounts Users can now specify custom and ephemeral mounts in cloud-init under the `install` section, e.g.: ``` users: - name: kairos ... install: auto: true device: "auto" bind_mounts: - /mnt/bind1 - /mnt/bind2 ephemeral_mounts: - /mnt/ephemeral - /mnt/ephemeral2 ... ``` Ephemeral mounts are mounted as RW - but changes are discarded when the machine is restart. Bind mounts will persist changes after restarted. This is a fix for #210 Signed-off-by: Oz Tiram <oz@spectrocloud.com> * Add the custom user mount to /cos/run/cos-layout.env Signed-off-by: Oz Tiram <oz@spectrocloud.com> * Add docs for custom user mounts in configuration example Signed-off-by: Oz Tiram <oz@spectrocloud.com> * Reuse test_install function DRY the code, change how we call the function install_test Signed-off-by: Oz Tiram <oz@spectrocloud.com> * Enable custom mount tests and install tests Signed-off-by: Oz Tiram <oz@spectrocloud.com> * Enable tests in CI Signed-off-by: Oz Tiram <oz@spectrocloud.com> * Remove duplicate if check Signed-off-by: Oz Tiram <oz@spectrocloud.com> * Remove uneeded fmt.Println ... Signed-off-by: Oz Tiram <oz@spectrocloud.com> * Use separate label for custom mounts Signed-off-by: Oz Tiram <oz@spectrocloud.com> * 🔧 Earthfile - DRY ginkgo We repeat this a more than twice so just extract to own target... Signed-off-by: Oz Tiram <oz@spectrocloud.com> * Correct return type for ContainElements Signed-off-by: Oz Tiram <oz@spectrocloud.com> * Remove CLOUD_INIT from custom mounts test This is not needed here. Signed-off-by: Oz Tiram <oz@spectrocloud.com> * Fix qemu-test-* earthly targets Signed-off-by: Oz Tiram <oz@spectrocloud.com> * 🔧 Fix CPU passing to VM Signed-off-by: Oz Tiram <oz@spectrocloud.com> * 🔧 remove apt cache after install qemu Helps deal with space running out in the CI. Signed-off-by: Oz Tiram <oz@spectrocloud.com> * :book: Document custom mounts Signed-off-by: Oz Tiram <oz@spectrocloud.com> --------- Signed-off-by: Oz Tiram <oz@spectrocloud.com> Co-authored-by: Ettore Di Giacinto <mudler@users.noreply.github.com>
2023-02-03 10:04:02 +00:00
Auto bool `yaml:"auto,omitempty"`
Reboot bool `yaml:"reboot,omitempty"`
Device string `yaml:"device,omitempty"`
Poweroff bool `yaml:"poweroff,omitempty"`
GrubOptions map[string]string `yaml:"grub_options,omitempty"`
Bundles Bundles `yaml:"bundles,omitempty"`
Encrypt []string `yaml:"encrypted_partitions,omitempty"`
SkipEncryptCopyPlugins bool `yaml:"skip_copy_kcrypt_plugin,omitempty"`
Env []string `yaml:"env,omitempty"`
Image string `yaml:"image,omitempty"`
EphemeralMounts []string `yaml:"ephemeral_mounts,omitempty"`
BindMounts []string `yaml:"bind_mounts,omitempty"`
}
type Config struct {
Install *Install `yaml:"install,omitempty"`
collector.Config
// TODO: Remove this too?
2022-07-13 22:23:47 +00:00
ConfigURL string `yaml:"config_url,omitempty"`
Options map[string]string `yaml:"options,omitempty"`
FailOnBundleErrors bool `yaml:"fail_on_bundles_errors,omitempty"`
2022-07-13 22:23:47 +00:00
Bundles Bundles `yaml:"bundles,omitempty"`
GrubOptions map[string]string `yaml:"grub_options,omitempty"`
Env []string `yaml:"env,omitempty"`
2022-07-13 22:23:47 +00:00
}
type Bundles []Bundle
type Bundle struct {
Repository string `yaml:"repository,omitempty"`
Rootfs string `yaml:"rootfs_path,omitempty"`
DB string `yaml:"db_path,omitempty"`
LocalFile bool `yaml:"local_file,omitempty"`
Targets []string `yaml:"targets,omitempty"`
2022-07-13 22:23:47 +00:00
}
const DefaultHeader = "#cloud-config"
func HasHeader(userdata, head string) (bool, string) {
header := strings.SplitN(userdata, "\n", 2)[0]
// Trim trailing whitespaces
header = strings.TrimRightFunc(header, unicode.IsSpace)
if head != "" {
return head == header, header
}
return (header == DefaultHeader) || (header == "#kairos-config") || (header == "#node-config"), header
}
func (b Bundles) Options() (res [][]bundles.BundleOption) {
2022-07-13 22:23:47 +00:00
for _, bundle := range b {
for _, t := range bundle.Targets {
opts := []bundles.BundleOption{bundles.WithRepository(bundle.Repository), bundles.WithTarget(t)}
2022-07-13 22:23:47 +00:00
if bundle.Rootfs != "" {
opts = append(opts, bundles.WithRootFS(bundle.Rootfs))
2022-07-13 22:23:47 +00:00
}
if bundle.DB != "" {
opts = append(opts, bundles.WithDBPath(bundle.DB))
2022-07-13 22:23:47 +00:00
}
if bundle.LocalFile {
opts = append(opts, bundles.WithLocalFile(true))
}
2022-07-13 22:23:47 +00:00
res = append(res, opts)
}
}
return
}
sparkles: Integrate schema validation (#853) * Change ValidationError to return the actual error Signed-off-by: Mauro Morales <mauro.morales@spectrocloud.com> * Add validate command Signed-off-by: Mauro Morales <mauro.morales@spectrocloud.com> * Warn validation errors when scanning configs Signed-off-by: Mauro Morales <mauro.morales@spectrocloud.com> * Lint Signed-off-by: Mauro Morales <mauro.morales@spectrocloud.com> * Add schema command to print config json schema Signed-off-by: Mauro Morales <mauro.morales@spectrocloud.com> * Add strict-validations flag Signed-off-by: Mauro Morales <mauro.morales@spectrocloud.com> * Lint and remove focus Signed-off-by: Mauro Morales <mauro.morales@spectrocloud.com> * Rename command schema to print-schema Signed-off-by: Mauro Morales <mauro.morales@spectrocloud.com> * Fix issue by reading originalData Signed-off-by: Mauro Morales <mauro.morales@spectrocloud.com> * Lint Signed-off-by: Mauro Morales <mauro.morales@spectrocloud.com> * Remove test from removed feature Signed-off-by: Mauro Morales <mauro.morales@spectrocloud.com> * Add comments to exported functions Signed-off-by: Mauro Morales <mauro.morales@spectrocloud.com> * Lint Signed-off-by: Mauro Morales <mauro.morales@spectrocloud.com> * Add test for validate.go Signed-off-by: Mauro Morales <mauro.morales@spectrocloud.com> * Remove focus Signed-off-by: Mauro Morales <mauro.morales@spectrocloud.com> * Add more tests for root schema Signed-off-by: Mauro Morales <mauro.morales@spectrocloud.com> * Add more tests Signed-off-by: Mauro Morales <mauro.morales@spectrocloud.com> --------- Signed-off-by: Mauro Morales <mauro.morales@spectrocloud.com> Co-authored-by: Itxaka <itxaka.garcia@spectrocloud.com>
2023-02-14 15:15:13 +00:00
// HasConfigURL returns true if ConfigURL has been set and false if it's empty.
func (c Config) HasConfigURL() bool {
return c.ConfigURL != ""
}
func Scan(opts ...collector.Option) (c *Config, err error) {
result := &Config{}
o := &collector.Options{}
if err := o.Apply(opts...); err != nil {
return result, err
2022-07-13 22:23:47 +00:00
}
genericConfig, err := collector.Scan(o)
if err != nil {
return result, err
sparkles: Integrate schema validation (#853) * Change ValidationError to return the actual error Signed-off-by: Mauro Morales <mauro.morales@spectrocloud.com> * Add validate command Signed-off-by: Mauro Morales <mauro.morales@spectrocloud.com> * Warn validation errors when scanning configs Signed-off-by: Mauro Morales <mauro.morales@spectrocloud.com> * Lint Signed-off-by: Mauro Morales <mauro.morales@spectrocloud.com> * Add schema command to print config json schema Signed-off-by: Mauro Morales <mauro.morales@spectrocloud.com> * Add strict-validations flag Signed-off-by: Mauro Morales <mauro.morales@spectrocloud.com> * Lint and remove focus Signed-off-by: Mauro Morales <mauro.morales@spectrocloud.com> * Rename command schema to print-schema Signed-off-by: Mauro Morales <mauro.morales@spectrocloud.com> * Fix issue by reading originalData Signed-off-by: Mauro Morales <mauro.morales@spectrocloud.com> * Lint Signed-off-by: Mauro Morales <mauro.morales@spectrocloud.com> * Remove test from removed feature Signed-off-by: Mauro Morales <mauro.morales@spectrocloud.com> * Add comments to exported functions Signed-off-by: Mauro Morales <mauro.morales@spectrocloud.com> * Lint Signed-off-by: Mauro Morales <mauro.morales@spectrocloud.com> * Add test for validate.go Signed-off-by: Mauro Morales <mauro.morales@spectrocloud.com> * Remove focus Signed-off-by: Mauro Morales <mauro.morales@spectrocloud.com> * Add more tests for root schema Signed-off-by: Mauro Morales <mauro.morales@spectrocloud.com> * Add more tests Signed-off-by: Mauro Morales <mauro.morales@spectrocloud.com> --------- Signed-off-by: Mauro Morales <mauro.morales@spectrocloud.com> Co-authored-by: Itxaka <itxaka.garcia@spectrocloud.com>
2023-02-14 15:15:13 +00:00
}
result.Config = *genericConfig
configStr, err := genericConfig.String()
if err != nil {
return result, err
sparkles: Integrate schema validation (#853) * Change ValidationError to return the actual error Signed-off-by: Mauro Morales <mauro.morales@spectrocloud.com> * Add validate command Signed-off-by: Mauro Morales <mauro.morales@spectrocloud.com> * Warn validation errors when scanning configs Signed-off-by: Mauro Morales <mauro.morales@spectrocloud.com> * Lint Signed-off-by: Mauro Morales <mauro.morales@spectrocloud.com> * Add schema command to print config json schema Signed-off-by: Mauro Morales <mauro.morales@spectrocloud.com> * Add strict-validations flag Signed-off-by: Mauro Morales <mauro.morales@spectrocloud.com> * Lint and remove focus Signed-off-by: Mauro Morales <mauro.morales@spectrocloud.com> * Rename command schema to print-schema Signed-off-by: Mauro Morales <mauro.morales@spectrocloud.com> * Fix issue by reading originalData Signed-off-by: Mauro Morales <mauro.morales@spectrocloud.com> * Lint Signed-off-by: Mauro Morales <mauro.morales@spectrocloud.com> * Remove test from removed feature Signed-off-by: Mauro Morales <mauro.morales@spectrocloud.com> * Add comments to exported functions Signed-off-by: Mauro Morales <mauro.morales@spectrocloud.com> * Lint Signed-off-by: Mauro Morales <mauro.morales@spectrocloud.com> * Add test for validate.go Signed-off-by: Mauro Morales <mauro.morales@spectrocloud.com> * Remove focus Signed-off-by: Mauro Morales <mauro.morales@spectrocloud.com> * Add more tests for root schema Signed-off-by: Mauro Morales <mauro.morales@spectrocloud.com> * Add more tests Signed-off-by: Mauro Morales <mauro.morales@spectrocloud.com> --------- Signed-off-by: Mauro Morales <mauro.morales@spectrocloud.com> Co-authored-by: Itxaka <itxaka.garcia@spectrocloud.com>
2023-02-14 15:15:13 +00:00
}
err = yaml.Unmarshal([]byte(configStr), result)
if err != nil {
return result, err
sparkles: Integrate schema validation (#853) * Change ValidationError to return the actual error Signed-off-by: Mauro Morales <mauro.morales@spectrocloud.com> * Add validate command Signed-off-by: Mauro Morales <mauro.morales@spectrocloud.com> * Warn validation errors when scanning configs Signed-off-by: Mauro Morales <mauro.morales@spectrocloud.com> * Lint Signed-off-by: Mauro Morales <mauro.morales@spectrocloud.com> * Add schema command to print config json schema Signed-off-by: Mauro Morales <mauro.morales@spectrocloud.com> * Add strict-validations flag Signed-off-by: Mauro Morales <mauro.morales@spectrocloud.com> * Lint and remove focus Signed-off-by: Mauro Morales <mauro.morales@spectrocloud.com> * Rename command schema to print-schema Signed-off-by: Mauro Morales <mauro.morales@spectrocloud.com> * Fix issue by reading originalData Signed-off-by: Mauro Morales <mauro.morales@spectrocloud.com> * Lint Signed-off-by: Mauro Morales <mauro.morales@spectrocloud.com> * Remove test from removed feature Signed-off-by: Mauro Morales <mauro.morales@spectrocloud.com> * Add comments to exported functions Signed-off-by: Mauro Morales <mauro.morales@spectrocloud.com> * Lint Signed-off-by: Mauro Morales <mauro.morales@spectrocloud.com> * Add test for validate.go Signed-off-by: Mauro Morales <mauro.morales@spectrocloud.com> * Remove focus Signed-off-by: Mauro Morales <mauro.morales@spectrocloud.com> * Add more tests for root schema Signed-off-by: Mauro Morales <mauro.morales@spectrocloud.com> * Add more tests Signed-off-by: Mauro Morales <mauro.morales@spectrocloud.com> --------- Signed-off-by: Mauro Morales <mauro.morales@spectrocloud.com> Co-authored-by: Itxaka <itxaka.garcia@spectrocloud.com>
2023-02-14 15:15:13 +00:00
}
kc, err := schema.NewConfigFromYAML(configStr, schema.RootSchema{})
sparkles: Integrate schema validation (#853) * Change ValidationError to return the actual error Signed-off-by: Mauro Morales <mauro.morales@spectrocloud.com> * Add validate command Signed-off-by: Mauro Morales <mauro.morales@spectrocloud.com> * Warn validation errors when scanning configs Signed-off-by: Mauro Morales <mauro.morales@spectrocloud.com> * Lint Signed-off-by: Mauro Morales <mauro.morales@spectrocloud.com> * Add schema command to print config json schema Signed-off-by: Mauro Morales <mauro.morales@spectrocloud.com> * Add strict-validations flag Signed-off-by: Mauro Morales <mauro.morales@spectrocloud.com> * Lint and remove focus Signed-off-by: Mauro Morales <mauro.morales@spectrocloud.com> * Rename command schema to print-schema Signed-off-by: Mauro Morales <mauro.morales@spectrocloud.com> * Fix issue by reading originalData Signed-off-by: Mauro Morales <mauro.morales@spectrocloud.com> * Lint Signed-off-by: Mauro Morales <mauro.morales@spectrocloud.com> * Remove test from removed feature Signed-off-by: Mauro Morales <mauro.morales@spectrocloud.com> * Add comments to exported functions Signed-off-by: Mauro Morales <mauro.morales@spectrocloud.com> * Lint Signed-off-by: Mauro Morales <mauro.morales@spectrocloud.com> * Add test for validate.go Signed-off-by: Mauro Morales <mauro.morales@spectrocloud.com> * Remove focus Signed-off-by: Mauro Morales <mauro.morales@spectrocloud.com> * Add more tests for root schema Signed-off-by: Mauro Morales <mauro.morales@spectrocloud.com> * Add more tests Signed-off-by: Mauro Morales <mauro.morales@spectrocloud.com> --------- Signed-off-by: Mauro Morales <mauro.morales@spectrocloud.com> Co-authored-by: Itxaka <itxaka.garcia@spectrocloud.com>
2023-02-14 15:15:13 +00:00
if err != nil {
if !o.NoLogs && !o.StrictValidation {
fmt.Printf("WARNING: %s\n", err.Error())
}
sparkles: Integrate schema validation (#853) * Change ValidationError to return the actual error Signed-off-by: Mauro Morales <mauro.morales@spectrocloud.com> * Add validate command Signed-off-by: Mauro Morales <mauro.morales@spectrocloud.com> * Warn validation errors when scanning configs Signed-off-by: Mauro Morales <mauro.morales@spectrocloud.com> * Lint Signed-off-by: Mauro Morales <mauro.morales@spectrocloud.com> * Add schema command to print config json schema Signed-off-by: Mauro Morales <mauro.morales@spectrocloud.com> * Add strict-validations flag Signed-off-by: Mauro Morales <mauro.morales@spectrocloud.com> * Lint and remove focus Signed-off-by: Mauro Morales <mauro.morales@spectrocloud.com> * Rename command schema to print-schema Signed-off-by: Mauro Morales <mauro.morales@spectrocloud.com> * Fix issue by reading originalData Signed-off-by: Mauro Morales <mauro.morales@spectrocloud.com> * Lint Signed-off-by: Mauro Morales <mauro.morales@spectrocloud.com> * Remove test from removed feature Signed-off-by: Mauro Morales <mauro.morales@spectrocloud.com> * Add comments to exported functions Signed-off-by: Mauro Morales <mauro.morales@spectrocloud.com> * Lint Signed-off-by: Mauro Morales <mauro.morales@spectrocloud.com> * Add test for validate.go Signed-off-by: Mauro Morales <mauro.morales@spectrocloud.com> * Remove focus Signed-off-by: Mauro Morales <mauro.morales@spectrocloud.com> * Add more tests for root schema Signed-off-by: Mauro Morales <mauro.morales@spectrocloud.com> * Add more tests Signed-off-by: Mauro Morales <mauro.morales@spectrocloud.com> --------- Signed-off-by: Mauro Morales <mauro.morales@spectrocloud.com> Co-authored-by: Itxaka <itxaka.garcia@spectrocloud.com>
2023-02-14 15:15:13 +00:00
if o.StrictValidation {
return result, fmt.Errorf("ERROR: %s", err.Error())
}
}
sparkles: Integrate schema validation (#853) * Change ValidationError to return the actual error Signed-off-by: Mauro Morales <mauro.morales@spectrocloud.com> * Add validate command Signed-off-by: Mauro Morales <mauro.morales@spectrocloud.com> * Warn validation errors when scanning configs Signed-off-by: Mauro Morales <mauro.morales@spectrocloud.com> * Lint Signed-off-by: Mauro Morales <mauro.morales@spectrocloud.com> * Add schema command to print config json schema Signed-off-by: Mauro Morales <mauro.morales@spectrocloud.com> * Add strict-validations flag Signed-off-by: Mauro Morales <mauro.morales@spectrocloud.com> * Lint and remove focus Signed-off-by: Mauro Morales <mauro.morales@spectrocloud.com> * Rename command schema to print-schema Signed-off-by: Mauro Morales <mauro.morales@spectrocloud.com> * Fix issue by reading originalData Signed-off-by: Mauro Morales <mauro.morales@spectrocloud.com> * Lint Signed-off-by: Mauro Morales <mauro.morales@spectrocloud.com> * Remove test from removed feature Signed-off-by: Mauro Morales <mauro.morales@spectrocloud.com> * Add comments to exported functions Signed-off-by: Mauro Morales <mauro.morales@spectrocloud.com> * Lint Signed-off-by: Mauro Morales <mauro.morales@spectrocloud.com> * Add test for validate.go Signed-off-by: Mauro Morales <mauro.morales@spectrocloud.com> * Remove focus Signed-off-by: Mauro Morales <mauro.morales@spectrocloud.com> * Add more tests for root schema Signed-off-by: Mauro Morales <mauro.morales@spectrocloud.com> * Add more tests Signed-off-by: Mauro Morales <mauro.morales@spectrocloud.com> --------- Signed-off-by: Mauro Morales <mauro.morales@spectrocloud.com> Co-authored-by: Itxaka <itxaka.garcia@spectrocloud.com>
2023-02-14 15:15:13 +00:00
if !kc.IsValid() {
if !o.NoLogs && !o.StrictValidation {
fmt.Printf("WARNING: %s\n", kc.ValidationError.Error())
}
if o.StrictValidation {
return result, fmt.Errorf("ERROR: %s", kc.ValidationError.Error())
sparkles: Integrate schema validation (#853) * Change ValidationError to return the actual error Signed-off-by: Mauro Morales <mauro.morales@spectrocloud.com> * Add validate command Signed-off-by: Mauro Morales <mauro.morales@spectrocloud.com> * Warn validation errors when scanning configs Signed-off-by: Mauro Morales <mauro.morales@spectrocloud.com> * Lint Signed-off-by: Mauro Morales <mauro.morales@spectrocloud.com> * Add schema command to print config json schema Signed-off-by: Mauro Morales <mauro.morales@spectrocloud.com> * Add strict-validations flag Signed-off-by: Mauro Morales <mauro.morales@spectrocloud.com> * Lint and remove focus Signed-off-by: Mauro Morales <mauro.morales@spectrocloud.com> * Rename command schema to print-schema Signed-off-by: Mauro Morales <mauro.morales@spectrocloud.com> * Fix issue by reading originalData Signed-off-by: Mauro Morales <mauro.morales@spectrocloud.com> * Lint Signed-off-by: Mauro Morales <mauro.morales@spectrocloud.com> * Remove test from removed feature Signed-off-by: Mauro Morales <mauro.morales@spectrocloud.com> * Add comments to exported functions Signed-off-by: Mauro Morales <mauro.morales@spectrocloud.com> * Lint Signed-off-by: Mauro Morales <mauro.morales@spectrocloud.com> * Add test for validate.go Signed-off-by: Mauro Morales <mauro.morales@spectrocloud.com> * Remove focus Signed-off-by: Mauro Morales <mauro.morales@spectrocloud.com> * Add more tests for root schema Signed-off-by: Mauro Morales <mauro.morales@spectrocloud.com> * Add more tests Signed-off-by: Mauro Morales <mauro.morales@spectrocloud.com> --------- Signed-off-by: Mauro Morales <mauro.morales@spectrocloud.com> Co-authored-by: Itxaka <itxaka.garcia@spectrocloud.com>
2023-02-14 15:15:13 +00:00
}
}
return result, nil
}
type Stage string
const (
NetworkStage Stage = "network"
)
func (n Stage) String() string {
return string(n)
}
func SaveCloudConfig(name Stage, yc yip.YipConfig) error {
dnsYAML, err := yaml.Marshal(yc)
if err != nil {
return err
}
return os.WriteFile(filepath.Join("usr", "local", "cloud-config", fmt.Sprintf("100_%s.yaml", name)), dnsYAML, 0700)
}
func FromString(s string, o interface{}) error {
return yaml.Unmarshal([]byte(s), o)
}
func MergeYAML(objs ...interface{}) ([]byte, error) {
content := [][]byte{}
for _, o := range objs {
dat, err := yaml.Marshal(o)
if err != nil {
return []byte{}, err
}
content = append(content, dat)
}
finalData := make(map[string]interface{})
for _, c := range content {
if err := yaml.Unmarshal(c, &finalData); err != nil {
return []byte{}, err
}
}
return yaml.Marshal(finalData)
}
func AddHeader(header, data string) string {
return fmt.Sprintf("%s\n%s", header, data)
}