mirror of
https://github.com/kairos-io/kairos-sdk.git
synced 2025-09-16 07:09:30 +00:00
Add Sources field to Config (#501)
* Add Sources field to Config and keep track of merged files there. Also print the Sources as a comment in the String() method. Signed-off-by: Dimitris Karakasilis <dimitris@karakasilis.me> * Fix tests Signed-off-by: Dimitris Karakasilis <dimitris@karakasilis.me> * Fix linter Signed-off-by: Dimitris Karakasilis <dimitris@karakasilis.me> * Fix TODO by renaming the toMap function and making it operate on ConfigValues instead of full Config objects (because after all, it wasn't copying the Sources field) Signed-off-by: Dimitris Karakasilis <dimitris@karakasilis.me> * [minor] Return ConfigValues interface when erroring out although nobody should consume it since we errored Signed-off-by: Dimitris Karakasilis <dimitris@karakasilis.me> * Add check for "Sources" comment to check that these all generate a line: - cmdline - remote config (config_url) - local files Signed-off-by: Dimitris Karakasilis <dimitris@karakasilis.me> --------- Signed-off-by: Dimitris Karakasilis <dimitris@karakasilis.me>
This commit is contained in:
committed by
GitHub
parent
5c38240a46
commit
a56cb0bb38
@@ -31,9 +31,14 @@ var ValidFileHeaders = []string{
|
|||||||
|
|
||||||
type Configs []*Config
|
type Configs []*Config
|
||||||
|
|
||||||
|
type ConfigValues map[string]interface{}
|
||||||
|
|
||||||
// We don't allow yamls that are plain arrays because is has no use in Kairos
|
// We don't allow yamls that are plain arrays because is has no use in Kairos
|
||||||
// and there is no way to merge an array yaml with a "map" yaml.
|
// and there is no way to merge an array yaml with a "map" yaml.
|
||||||
type Config map[string]interface{}
|
type Config struct {
|
||||||
|
Sources []string
|
||||||
|
Values ConfigValues
|
||||||
|
}
|
||||||
|
|
||||||
// MergeConfigURL looks for the "config_url" key and if it's found
|
// MergeConfigURL looks for the "config_url" key and if it's found
|
||||||
// it downloads the remote config and merges it with the current one.
|
// it downloads the remote config and merges it with the current one.
|
||||||
@@ -63,49 +68,53 @@ func (c *Config) MergeConfigURL() error {
|
|||||||
return c.MergeConfig(remoteConfig)
|
return c.MergeConfig(remoteConfig)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *Config) toMap() (map[string]interface{}, error) {
|
func (c *Config) valuesCopy() (ConfigValues, error) {
|
||||||
var result map[string]interface{}
|
var result ConfigValues
|
||||||
data, err := yaml.Marshal(c)
|
data, err := yaml.Marshal(c.Values)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return result, err
|
return result, err
|
||||||
}
|
}
|
||||||
|
|
||||||
err = yaml.Unmarshal(data, &result)
|
err = yaml.Unmarshal(data, &result)
|
||||||
|
|
||||||
return result, err
|
return result, err
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *Config) applyMap(i interface{}) error {
|
|
||||||
data, err := yaml.Marshal(i)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
err = yaml.Unmarshal(data, c)
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
// MergeConfig merges the config passed as parameter back to the receiver Config.
|
// MergeConfig merges the config passed as parameter back to the receiver Config.
|
||||||
func (c *Config) MergeConfig(newConfig *Config) error {
|
func (c *Config) MergeConfig(newConfig *Config) error {
|
||||||
var err error
|
var err error
|
||||||
|
|
||||||
// convert the two configs into maps
|
aMap, err := c.valuesCopy()
|
||||||
aMap, err := c.toMap()
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
bMap, err := newConfig.toMap()
|
bMap, err := newConfig.valuesCopy()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO: Consider removing the `name:` key because in the end we end up with the
|
||||||
|
// value from the last config merged. Ideally we should display the name in the "sources"
|
||||||
|
// comment next to the file but doing it here is not possible because the configs
|
||||||
|
// passed, could already be results of various merged thus we don't know which of
|
||||||
|
// the "sources" should take the "name" next to it.
|
||||||
|
//
|
||||||
|
// if _, exists := bMap.Values["name"]; exists {
|
||||||
|
// delete(bMap.Values, "name")
|
||||||
|
// }
|
||||||
|
|
||||||
// deep merge the two maps
|
// deep merge the two maps
|
||||||
cMap, err := DeepMerge(aMap, bMap)
|
mergedValues, err := DeepMerge(aMap, bMap)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
finalConfig := Config{}
|
||||||
|
finalConfig.Sources = append(c.Sources, newConfig.Sources...)
|
||||||
|
finalConfig.Values = mergedValues.(ConfigValues)
|
||||||
|
|
||||||
// apply the result of the deepmerge into the base config
|
*c = finalConfig
|
||||||
return c.applyMap(cMap)
|
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func mergeSlices(sliceA, sliceB []interface{}) ([]interface{}, error) {
|
func mergeSlices(sliceA, sliceB []interface{}) ([]interface{}, error) {
|
||||||
@@ -148,7 +157,7 @@ func mergeSlices(sliceA, sliceB []interface{}) ([]interface{}, error) {
|
|||||||
return sliceA, nil
|
return sliceA, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func deepMergeMaps(a, b map[string]interface{}) (map[string]interface{}, error) {
|
func deepMergeMaps(a, b ConfigValues) (ConfigValues, error) {
|
||||||
// go through all items in b and merge them to a
|
// go through all items in b and merge them to a
|
||||||
for k, v := range b {
|
for k, v := range b {
|
||||||
current, ok := a[k]
|
current, ok := a[k]
|
||||||
@@ -190,7 +199,7 @@ func DeepMerge(a, b interface{}) (interface{}, error) {
|
|||||||
|
|
||||||
// We don't support merging different data structures
|
// We don't support merging different data structures
|
||||||
if typeA.Kind() != typeB.Kind() {
|
if typeA.Kind() != typeB.Kind() {
|
||||||
return map[string]interface{}{}, fmt.Errorf("cannot merge %s with %s", typeA.String(), typeB.String())
|
return ConfigValues{}, fmt.Errorf("cannot merge %s with %s", typeA.String(), typeB.String())
|
||||||
}
|
}
|
||||||
|
|
||||||
if typeA.Kind() == reflect.Slice {
|
if typeA.Kind() == reflect.Slice {
|
||||||
@@ -198,7 +207,7 @@ func DeepMerge(a, b interface{}) (interface{}, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if typeA.Kind() == reflect.Map {
|
if typeA.Kind() == reflect.Map {
|
||||||
return deepMergeMaps(a.(map[string]interface{}), b.(map[string]interface{}))
|
return deepMergeMaps(a.(ConfigValues), b.(ConfigValues))
|
||||||
}
|
}
|
||||||
|
|
||||||
// for any other type, b should take precedence
|
// for any other type, b should take precedence
|
||||||
@@ -207,12 +216,22 @@ func DeepMerge(a, b interface{}) (interface{}, error) {
|
|||||||
|
|
||||||
// String returns a string which is a Yaml representation of the Config.
|
// String returns a string which is a Yaml representation of the Config.
|
||||||
func (c *Config) String() (string, error) {
|
func (c *Config) String() (string, error) {
|
||||||
data, err := yaml.Marshal(c)
|
sourcesComment := ""
|
||||||
if err != nil {
|
config := *c
|
||||||
return "", err
|
if len(config.Sources) > 0 {
|
||||||
|
sourcesComment = "# Sources:\n"
|
||||||
|
for _, s := range config.Sources {
|
||||||
|
sourcesComment += fmt.Sprintf("# - %s\n", s)
|
||||||
|
}
|
||||||
|
sourcesComment += "\n"
|
||||||
}
|
}
|
||||||
|
|
||||||
return fmt.Sprintf("%s\n\n%s", DefaultHeader, string(data)), nil
|
data, err := yaml.Marshal(config.Values)
|
||||||
|
if err != nil {
|
||||||
|
return "", fmt.Errorf("marshalling the config to a string: %s", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return fmt.Sprintf("%s\n\n%s%s", DefaultHeader, sourcesComment, string(data)), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (cs Configs) Merge() (*Config, error) {
|
func (cs Configs) Merge() (*Config, error) {
|
||||||
@@ -251,7 +270,7 @@ func Scan(o *Options, filter func(d []byte) ([]byte, error)) (*Config, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if o.Overwrites != "" {
|
if o.Overwrites != "" {
|
||||||
yaml.Unmarshal([]byte(o.Overwrites), &mergedConfig) //nolint:errcheck
|
yaml.Unmarshal([]byte(o.Overwrites), &mergedConfig.Values) //nolint:errcheck
|
||||||
}
|
}
|
||||||
|
|
||||||
return mergedConfig, nil
|
return mergedConfig, nil
|
||||||
@@ -295,10 +314,12 @@ func parseFiles(dir []string, nologs bool) Configs {
|
|||||||
}
|
}
|
||||||
|
|
||||||
var newConfig Config
|
var newConfig Config
|
||||||
err = yaml.Unmarshal(b, &newConfig)
|
err = yaml.Unmarshal(b, &newConfig.Values)
|
||||||
if err != nil && !nologs {
|
if err != nil && !nologs {
|
||||||
fmt.Printf("warning: failed to parse config:\n%s\n", err.Error())
|
fmt.Printf("warning: failed to parse config:\n%s\n", err.Error())
|
||||||
}
|
}
|
||||||
|
newConfig.Sources = []string{f}
|
||||||
|
|
||||||
result = append(result, &newConfig)
|
result = append(result, &newConfig)
|
||||||
} else {
|
} else {
|
||||||
if !nologs {
|
if !nologs {
|
||||||
@@ -324,9 +345,9 @@ func parseReaders(readers []io.Reader, nologs bool) Configs {
|
|||||||
}
|
}
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
err = yaml.Unmarshal(read, &newConfig)
|
err = yaml.Unmarshal(read, &newConfig.Values)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
err = json.Unmarshal(read, &newConfig)
|
err = json.Unmarshal(read, &newConfig.Values)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if !nologs {
|
if !nologs {
|
||||||
fmt.Printf("Error unmarshalling config(error: %s): %s", err.Error(), string(read))
|
fmt.Printf("Error unmarshalling config(error: %s): %s", err.Error(), string(read))
|
||||||
@@ -334,6 +355,7 @@ func parseReaders(readers []io.Reader, nologs bool) Configs {
|
|||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
newConfig.Sources = []string{"reader"}
|
||||||
result = append(result, &newConfig)
|
result = append(result, &newConfig)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -380,7 +402,7 @@ func listFiles(dir string) ([]string, error) {
|
|||||||
// ParseCmdLine reads options from the kernel cmdline and returns the equivalent
|
// ParseCmdLine reads options from the kernel cmdline and returns the equivalent
|
||||||
// Config.
|
// Config.
|
||||||
func ParseCmdLine(file string, filter func(d []byte) ([]byte, error)) (*Config, error) {
|
func ParseCmdLine(file string, filter func(d []byte) ([]byte, error)) (*Config, error) {
|
||||||
result := Config{}
|
result := Config{Sources: []string{"cmdline"}}
|
||||||
dotToYAML, err := machine.DotToYAML(file)
|
dotToYAML, err := machine.DotToYAML(file)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return &result, err
|
return &result, err
|
||||||
@@ -391,7 +413,7 @@ func ParseCmdLine(file string, filter func(d []byte) ([]byte, error)) (*Config,
|
|||||||
return &result, err
|
return &result, err
|
||||||
}
|
}
|
||||||
|
|
||||||
err = yaml.Unmarshal(filteredYAML, &result)
|
err = yaml.Unmarshal(filteredYAML, &result.Values)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return &result, err
|
return &result, err
|
||||||
}
|
}
|
||||||
@@ -401,7 +423,7 @@ func ParseCmdLine(file string, filter func(d []byte) ([]byte, error)) (*Config,
|
|||||||
|
|
||||||
// ConfigURL returns the value of config_url if set or empty string otherwise.
|
// ConfigURL returns the value of config_url if set or empty string otherwise.
|
||||||
func (c Config) ConfigURL() string {
|
func (c Config) ConfigURL() string {
|
||||||
if val, hasKey := c["config_url"]; hasKey {
|
if val, hasKey := c.Values["config_url"]; hasKey {
|
||||||
if s, isString := val.(string); isString {
|
if s, isString := val.(string); isString {
|
||||||
return s
|
return s
|
||||||
}
|
}
|
||||||
@@ -446,10 +468,12 @@ func fetchRemoteConfig(url string) (*Config, error) {
|
|||||||
return result, nil
|
return result, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := yaml.Unmarshal(body, result); err != nil {
|
if err := yaml.Unmarshal(body, &result.Values); err != nil {
|
||||||
return result, fmt.Errorf("could not unmarshal remote config to an object: %w", err)
|
return result, fmt.Errorf("could not unmarshal remote config to an object: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
result.Sources = []string{url}
|
||||||
|
|
||||||
return result, nil
|
return result, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -46,16 +46,16 @@ var _ = Describe("Config Collector", func() {
|
|||||||
Context("different keys", func() {
|
Context("different keys", func() {
|
||||||
BeforeEach(func() {
|
BeforeEach(func() {
|
||||||
err := yaml.Unmarshal([]byte(`#cloud-config
|
err := yaml.Unmarshal([]byte(`#cloud-config
|
||||||
name: Mario`), originalConfig)
|
name: Mario`), &originalConfig.Values)
|
||||||
Expect(err).ToNot(HaveOccurred())
|
Expect(err).ToNot(HaveOccurred())
|
||||||
err = yaml.Unmarshal([]byte(`#cloud-config
|
err = yaml.Unmarshal([]byte(`#cloud-config
|
||||||
surname: Bros`), newConfig)
|
surname: Bros`), &newConfig.Values)
|
||||||
Expect(err).ToNot(HaveOccurred())
|
Expect(err).ToNot(HaveOccurred())
|
||||||
})
|
})
|
||||||
|
|
||||||
It("gets merged together", func() {
|
It("gets merged together", func() {
|
||||||
Expect(originalConfig.MergeConfig(newConfig)).ToNot(HaveOccurred())
|
Expect(originalConfig.MergeConfig(newConfig)).ToNot(HaveOccurred())
|
||||||
surname, isString := (*originalConfig)["surname"].(string)
|
surname, isString := originalConfig.Values["surname"].(string)
|
||||||
Expect(isString).To(BeTrue())
|
Expect(isString).To(BeTrue())
|
||||||
Expect(surname).To(Equal("Bros"))
|
Expect(surname).To(Equal("Bros"))
|
||||||
})
|
})
|
||||||
@@ -67,58 +67,58 @@ surname: Bros`), newConfig)
|
|||||||
err := yaml.Unmarshal([]byte(`#cloud-config
|
err := yaml.Unmarshal([]byte(`#cloud-config
|
||||||
info:
|
info:
|
||||||
name: Mario
|
name: Mario
|
||||||
`), originalConfig)
|
`), &originalConfig.Values)
|
||||||
Expect(err).ToNot(HaveOccurred())
|
Expect(err).ToNot(HaveOccurred())
|
||||||
err = yaml.Unmarshal([]byte(`#cloud-config
|
err = yaml.Unmarshal([]byte(`#cloud-config
|
||||||
info:
|
info:
|
||||||
surname: Bros
|
surname: Bros
|
||||||
`), newConfig)
|
`), &newConfig.Values)
|
||||||
Expect(err).ToNot(HaveOccurred())
|
Expect(err).ToNot(HaveOccurred())
|
||||||
})
|
})
|
||||||
It("merges the keys", func() {
|
It("merges the keys", func() {
|
||||||
Expect(originalConfig.MergeConfig(newConfig)).ToNot(HaveOccurred())
|
Expect(originalConfig.MergeConfig(newConfig)).ToNot(HaveOccurred())
|
||||||
info, isMap := (*originalConfig)["info"].(Config)
|
info, isMap := originalConfig.Values["info"].(ConfigValues)
|
||||||
Expect(isMap).To(BeTrue())
|
Expect(isMap).To(BeTrue())
|
||||||
Expect(info["name"]).To(Equal("Mario"))
|
Expect(info["name"]).To(Equal("Mario"))
|
||||||
Expect(info["surname"]).To(Equal("Bros"))
|
Expect(info["surname"]).To(Equal("Bros"))
|
||||||
Expect(*originalConfig).To(HaveLen(1))
|
Expect(originalConfig.Values).To(HaveLen(1))
|
||||||
Expect(info).To(HaveLen(2))
|
Expect(info).To(HaveLen(2))
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
Context("when the key is a string", func() {
|
Context("when the key is a string", func() {
|
||||||
BeforeEach(func() {
|
BeforeEach(func() {
|
||||||
err := yaml.Unmarshal([]byte("#cloud-config\nname: Mario"), originalConfig)
|
err := yaml.Unmarshal([]byte("#cloud-config\nname: Mario"), &originalConfig.Values)
|
||||||
Expect(err).ToNot(HaveOccurred())
|
Expect(err).ToNot(HaveOccurred())
|
||||||
err = yaml.Unmarshal([]byte("#cloud-config\nname: Luigi"), newConfig)
|
err = yaml.Unmarshal([]byte("#cloud-config\nname: Luigi"), &newConfig.Values)
|
||||||
Expect(err).ToNot(HaveOccurred())
|
Expect(err).ToNot(HaveOccurred())
|
||||||
})
|
})
|
||||||
|
|
||||||
It("overwrites", func() {
|
It("overwrites", func() {
|
||||||
Expect(originalConfig.MergeConfig(newConfig)).ToNot(HaveOccurred())
|
Expect(originalConfig.MergeConfig(newConfig)).ToNot(HaveOccurred())
|
||||||
name, isString := (*originalConfig)["name"].(string)
|
name, isString := originalConfig.Values["name"].(string)
|
||||||
Expect(isString).To(BeTrue())
|
Expect(isString).To(BeTrue())
|
||||||
Expect(name).To(Equal("Luigi"))
|
Expect(name).To(Equal("Luigi"))
|
||||||
Expect(*originalConfig).To(HaveLen(1))
|
Expect(originalConfig.Values).To(HaveLen(1))
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
Context("reset keys", func() {
|
Context("reset keys", func() {
|
||||||
Context("remove keys", func() {
|
Context("remove keys", func() {
|
||||||
BeforeEach(func() {
|
BeforeEach(func() {
|
||||||
err := yaml.Unmarshal([]byte("#cloud-config\nlist:\n - 1\n - 2\nname: Mario"), originalConfig)
|
err := yaml.Unmarshal([]byte("#cloud-config\nlist:\n - 1\n - 2\nname: Mario"), &originalConfig.Values)
|
||||||
Expect(err).ToNot(HaveOccurred())
|
Expect(err).ToNot(HaveOccurred())
|
||||||
err = yaml.Unmarshal([]byte("#cloud-config\nlist: null\nname: null"), newConfig)
|
err = yaml.Unmarshal([]byte("#cloud-config\nlist: null\nname: null"), &newConfig.Values)
|
||||||
Expect(err).ToNot(HaveOccurred())
|
Expect(err).ToNot(HaveOccurred())
|
||||||
})
|
})
|
||||||
|
|
||||||
It("overwrites", func() {
|
It("overwrites", func() {
|
||||||
Expect(originalConfig.MergeConfig(newConfig)).ToNot(HaveOccurred())
|
Expect(originalConfig.MergeConfig(newConfig)).ToNot(HaveOccurred())
|
||||||
Expect((*originalConfig)["list"]).To(BeEmpty())
|
Expect(originalConfig.Values["list"]).To(BeEmpty())
|
||||||
name, isString := (*originalConfig)["name"].(string)
|
name, isString := originalConfig.Values["name"].(string)
|
||||||
Expect(isString).To(BeTrue())
|
Expect(isString).To(BeTrue())
|
||||||
Expect(name).To(Equal(""))
|
Expect(name).To(Equal(""))
|
||||||
Expect(*originalConfig).To(HaveLen(2))
|
Expect(originalConfig.Values).To(HaveLen(2))
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
@@ -132,13 +132,13 @@ info:
|
|||||||
|
|
||||||
Context("when there is no config_url defined", func() {
|
Context("when there is no config_url defined", func() {
|
||||||
BeforeEach(func() {
|
BeforeEach(func() {
|
||||||
err := yaml.Unmarshal([]byte("#cloud-config\nname: Mario"), originalConfig)
|
err := yaml.Unmarshal([]byte("#cloud-config\nname: Mario"), &originalConfig.Values)
|
||||||
Expect(err).ToNot(HaveOccurred())
|
Expect(err).ToNot(HaveOccurred())
|
||||||
})
|
})
|
||||||
|
|
||||||
It("does nothing", func() {
|
It("does nothing", func() {
|
||||||
Expect(originalConfig.MergeConfigURL()).ToNot(HaveOccurred())
|
Expect(originalConfig.MergeConfigURL()).ToNot(HaveOccurred())
|
||||||
Expect(*originalConfig).To(HaveLen(1))
|
Expect(originalConfig.Values).To(HaveLen(1))
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
@@ -163,7 +163,7 @@ name: Mario
|
|||||||
surname: Bros
|
surname: Bros
|
||||||
info:
|
info:
|
||||||
job: plumber
|
job: plumber
|
||||||
`, port)), originalConfig)
|
`, port)), &originalConfig.Values)
|
||||||
Expect(err).ToNot(HaveOccurred())
|
Expect(err).ToNot(HaveOccurred())
|
||||||
|
|
||||||
err := os.WriteFile(path.Join(tmpDir, "config1.yaml"), []byte(fmt.Sprintf(`#cloud-config
|
err := os.WriteFile(path.Join(tmpDir, "config1.yaml"), []byte(fmt.Sprintf(`#cloud-config
|
||||||
@@ -191,20 +191,20 @@ info:
|
|||||||
err := originalConfig.MergeConfigURL()
|
err := originalConfig.MergeConfigURL()
|
||||||
Expect(err).ToNot(HaveOccurred())
|
Expect(err).ToNot(HaveOccurred())
|
||||||
|
|
||||||
name, ok := (*originalConfig)["name"].(string)
|
name, ok := originalConfig.Values["name"].(string)
|
||||||
Expect(ok).To(BeTrue())
|
Expect(ok).To(BeTrue())
|
||||||
Expect(name).To(Equal("Mario"))
|
Expect(name).To(Equal("Mario"))
|
||||||
|
|
||||||
surname, ok := (*originalConfig)["surname"].(string)
|
surname, ok := originalConfig.Values["surname"].(string)
|
||||||
Expect(ok).To(BeTrue())
|
Expect(ok).To(BeTrue())
|
||||||
Expect(surname).To(Equal("Bras"))
|
Expect(surname).To(Equal("Bras"))
|
||||||
|
|
||||||
info, ok := (*originalConfig)["info"].(Config)
|
info, ok := originalConfig.Values["info"].(ConfigValues)
|
||||||
Expect(ok).To(BeTrue())
|
Expect(ok).To(BeTrue())
|
||||||
Expect(info["job"]).To(Equal("plumber"))
|
Expect(info["job"]).To(Equal("plumber"))
|
||||||
Expect(info["girlfriend"]).To(Equal("princess"))
|
Expect(info["girlfriend"]).To(Equal("princess"))
|
||||||
|
|
||||||
Expect(*originalConfig).To(HaveLen(4))
|
Expect(originalConfig.Values).To(HaveLen(4))
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
@@ -224,12 +224,12 @@ info:
|
|||||||
return d, nil
|
return d, nil
|
||||||
})
|
})
|
||||||
Expect(err).ToNot(HaveOccurred())
|
Expect(err).ToNot(HaveOccurred())
|
||||||
Expect(*c).To(HaveKey("mario"))
|
Expect(c.Values).To(HaveKey("mario"))
|
||||||
Expect(*c).To(HaveKey("luigi"))
|
Expect(c.Values).To(HaveKey("luigi"))
|
||||||
Expect(*c).To(HaveKey("princess"))
|
Expect(c.Values).To(HaveKey("princess"))
|
||||||
Expect((*c)["mario"]).To(Equal("bros"))
|
Expect(c.Values["mario"]).To(Equal("bros"))
|
||||||
Expect((*c)["luigi"]).To(Equal("bros"))
|
Expect(c.Values["luigi"]).To(Equal("bros"))
|
||||||
Expect((*c)["princess"]).To(Equal("peach"))
|
Expect(c.Values["princess"]).To(Equal("peach"))
|
||||||
})
|
})
|
||||||
It("Reads from several reader objects and merges them (json)", func() {
|
It("Reads from several reader objects and merges them (json)", func() {
|
||||||
obj1 := bytes.NewReader([]byte(`{"mario":"bros"}`))
|
obj1 := bytes.NewReader([]byte(`{"mario":"bros"}`))
|
||||||
@@ -245,12 +245,12 @@ info:
|
|||||||
return d, nil
|
return d, nil
|
||||||
})
|
})
|
||||||
Expect(err).ToNot(HaveOccurred())
|
Expect(err).ToNot(HaveOccurred())
|
||||||
Expect(*c).To(HaveKey("mario"))
|
Expect(c.Values).To(HaveKey("mario"))
|
||||||
Expect(*c).To(HaveKey("luigi"))
|
Expect(c.Values).To(HaveKey("luigi"))
|
||||||
Expect(*c).To(HaveKey("princess"))
|
Expect(c.Values).To(HaveKey("princess"))
|
||||||
Expect((*c)["mario"]).To(Equal("bros"))
|
Expect(c.Values["mario"]).To(Equal("bros"))
|
||||||
Expect((*c)["luigi"]).To(Equal("bros"))
|
Expect(c.Values["luigi"]).To(Equal("bros"))
|
||||||
Expect((*c)["princess"]).To(Equal("peach"))
|
Expect(c.Values["princess"]).To(Equal("peach"))
|
||||||
})
|
})
|
||||||
It("Reads from several reader objects and merges them (json+yaml)", func() {
|
It("Reads from several reader objects and merges them (json+yaml)", func() {
|
||||||
obj1 := bytes.NewReader([]byte(`{"mario":"bros"}`))
|
obj1 := bytes.NewReader([]byte(`{"mario":"bros"}`))
|
||||||
@@ -266,12 +266,12 @@ info:
|
|||||||
return d, nil
|
return d, nil
|
||||||
})
|
})
|
||||||
Expect(err).ToNot(HaveOccurred())
|
Expect(err).ToNot(HaveOccurred())
|
||||||
Expect(*c).To(HaveKey("mario"))
|
Expect(c.Values).To(HaveKey("mario"))
|
||||||
Expect(*c).To(HaveKey("luigi"))
|
Expect(c.Values).To(HaveKey("luigi"))
|
||||||
Expect(*c).To(HaveKey("princess"))
|
Expect(c.Values).To(HaveKey("princess"))
|
||||||
Expect((*c)["mario"]).To(Equal("bros"))
|
Expect(c.Values["mario"]).To(Equal("bros"))
|
||||||
Expect((*c)["luigi"]).To(Equal("bros"))
|
Expect(c.Values["luigi"]).To(Equal("bros"))
|
||||||
Expect((*c)["princess"]).To(Equal("peach"))
|
Expect(c.Values["princess"]).To(Equal("peach"))
|
||||||
})
|
})
|
||||||
It("Fails to read from a reader which is neither json or yaml", func() {
|
It("Fails to read from a reader which is neither json or yaml", func() {
|
||||||
obj1 := bytes.NewReader([]byte(`blip`))
|
obj1 := bytes.NewReader([]byte(`blip`))
|
||||||
@@ -288,9 +288,9 @@ info:
|
|||||||
return d, nil
|
return d, nil
|
||||||
})
|
})
|
||||||
Expect(err).ToNot(HaveOccurred())
|
Expect(err).ToNot(HaveOccurred())
|
||||||
Expect(*c).ToNot(HaveKey("mario"))
|
Expect(c.Values).ToNot(HaveKey("mario"))
|
||||||
Expect(*c).ToNot(HaveKey("luigi"))
|
Expect(c.Values).ToNot(HaveKey("luigi"))
|
||||||
Expect(*c).ToNot(HaveKey("princess"))
|
Expect(c.Values).ToNot(HaveKey("princess"))
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
@@ -384,27 +384,27 @@ info:
|
|||||||
})
|
})
|
||||||
|
|
||||||
Context("empty map", func() {
|
Context("empty map", func() {
|
||||||
a := map[string]interface{}{}
|
a := ConfigValues{}
|
||||||
b := map[string]interface{}{
|
b := ConfigValues{
|
||||||
"foo": "bar",
|
"foo": "bar",
|
||||||
}
|
}
|
||||||
|
|
||||||
It("merges", func() {
|
It("merges", func() {
|
||||||
c, err := DeepMerge(a, b)
|
c, err := DeepMerge(a, b)
|
||||||
Expect(err).ToNot(HaveOccurred())
|
Expect(err).ToNot(HaveOccurred())
|
||||||
Expect(c).To(Equal(map[string]interface{}{
|
Expect(c).To(Equal(ConfigValues{
|
||||||
"foo": "bar",
|
"foo": "bar",
|
||||||
}))
|
}))
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
Context("simple map", func() {
|
Context("simple map", func() {
|
||||||
a := map[string]interface{}{
|
a := ConfigValues{
|
||||||
"es": "uno",
|
"es": "uno",
|
||||||
"nl": "een",
|
"nl": "een",
|
||||||
"#": 0,
|
"#": 0,
|
||||||
}
|
}
|
||||||
b := map[string]interface{}{
|
b := ConfigValues{
|
||||||
"en": "one",
|
"en": "one",
|
||||||
"nl": "één",
|
"nl": "één",
|
||||||
"de": "Eins",
|
"de": "Eins",
|
||||||
@@ -414,7 +414,7 @@ info:
|
|||||||
It("merges", func() {
|
It("merges", func() {
|
||||||
c, err := DeepMerge(a, b)
|
c, err := DeepMerge(a, b)
|
||||||
Expect(err).ToNot(HaveOccurred())
|
Expect(err).ToNot(HaveOccurred())
|
||||||
Expect(c).To(Equal(map[string]interface{}{
|
Expect(c).To(Equal(ConfigValues{
|
||||||
"#": 1,
|
"#": 1,
|
||||||
"de": "Eins",
|
"de": "Eins",
|
||||||
"en": "one",
|
"en": "one",
|
||||||
@@ -425,7 +425,7 @@ info:
|
|||||||
})
|
})
|
||||||
|
|
||||||
Context("reset key", func() {
|
Context("reset key", func() {
|
||||||
a := map[string]interface{}{
|
a := ConfigValues{
|
||||||
"string": "val",
|
"string": "val",
|
||||||
"slice": []interface{}{"valA", "valB"},
|
"slice": []interface{}{"valA", "valB"},
|
||||||
"map": map[string]interface{}{
|
"map": map[string]interface{}{
|
||||||
@@ -433,7 +433,7 @@ info:
|
|||||||
"valB": "",
|
"valB": "",
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
b := map[string]interface{}{
|
b := ConfigValues{
|
||||||
"string": nil,
|
"string": nil,
|
||||||
"slice": nil,
|
"slice": nil,
|
||||||
"map": nil,
|
"map": nil,
|
||||||
@@ -442,7 +442,7 @@ info:
|
|||||||
It("merges", func() {
|
It("merges", func() {
|
||||||
c, err := DeepMerge(a, b)
|
c, err := DeepMerge(a, b)
|
||||||
Expect(err).ToNot(HaveOccurred())
|
Expect(err).ToNot(HaveOccurred())
|
||||||
Expect(c).To(Equal(map[string]interface{}{
|
Expect(c).To(Equal(ConfigValues{
|
||||||
"string": "",
|
"string": "",
|
||||||
"slice": []interface{}{},
|
"slice": []interface{}{},
|
||||||
"map": map[string]interface{}{},
|
"map": map[string]interface{}{},
|
||||||
@@ -506,8 +506,12 @@ stages:
|
|||||||
c, err := Scan(o, FilterKeysTestMerge)
|
c, err := Scan(o, FilterKeysTestMerge)
|
||||||
Expect(err).ToNot(HaveOccurred())
|
Expect(err).ToNot(HaveOccurred())
|
||||||
|
|
||||||
fmt.Println(c.String())
|
Expect(c.String()).To(MatchRegexp(`#cloud-config
|
||||||
Expect(c.String()).To(Equal(`#cloud-config
|
|
||||||
|
# Sources:
|
||||||
|
# - .*/local_config_1.yaml
|
||||||
|
# - .*/local_config_2.yaml
|
||||||
|
# - cmdline
|
||||||
|
|
||||||
install:
|
install:
|
||||||
auto: true
|
auto: true
|
||||||
@@ -582,15 +586,19 @@ stages:
|
|||||||
c, err := Scan(o, FilterKeysTestMerge)
|
c, err := Scan(o, FilterKeysTestMerge)
|
||||||
Expect(err).ToNot(HaveOccurred())
|
Expect(err).ToNot(HaveOccurred())
|
||||||
|
|
||||||
fmt.Println(c.String())
|
Expect(c.String()).To(MatchRegexp(`#cloud-config
|
||||||
Expect(c.String()).To(Equal(`#cloud-config
|
|
||||||
|
# Sources:
|
||||||
|
# - .*/local_config_1.yaml
|
||||||
|
# - .*/local_config_2.yaml
|
||||||
|
# - cmdline
|
||||||
|
|
||||||
stages:
|
stages:
|
||||||
initramfs:
|
initramfs:
|
||||||
- users:
|
- users:
|
||||||
kairos:
|
kairos:
|
||||||
passwd: kairos
|
passwd: kairos
|
||||||
- if: '[ ! -f /oem/80_stylus.yaml ]'
|
- if: '\[ ! -f /oem/80_stylus.yaml \]'
|
||||||
name: set_inotify_max_values
|
name: set_inotify_max_values
|
||||||
sysctl:
|
sysctl:
|
||||||
fs.inotify.max_user_instances: "8192"
|
fs.inotify.max_user_instances: "8192"
|
||||||
@@ -674,8 +682,12 @@ install:
|
|||||||
c, err := Scan(o, FilterKeysTestMerge)
|
c, err := Scan(o, FilterKeysTestMerge)
|
||||||
Expect(err).ToNot(HaveOccurred())
|
Expect(err).ToNot(HaveOccurred())
|
||||||
|
|
||||||
fmt.Println(c.String())
|
Expect(c.String()).To(MatchRegexp(`#cloud-config
|
||||||
Expect(c.String()).To(Equal(`#cloud-config
|
|
||||||
|
# Sources:
|
||||||
|
# - .*/local_config_1.yaml
|
||||||
|
# - .*/local_config_2.yaml
|
||||||
|
# - cmdline
|
||||||
|
|
||||||
install:
|
install:
|
||||||
auto: true
|
auto: true
|
||||||
@@ -761,7 +773,10 @@ stages:
|
|||||||
c, err := Scan(o, FilterKeysTestMerge)
|
c, err := Scan(o, FilterKeysTestMerge)
|
||||||
Expect(err).ToNot(HaveOccurred())
|
Expect(err).ToNot(HaveOccurred())
|
||||||
|
|
||||||
Expect(c.String()).To(Equal(`#cloud-config
|
Expect(c.String()).To(MatchRegexp(`#cloud-config
|
||||||
|
|
||||||
|
# Sources:
|
||||||
|
# - .*/local_config_1.yaml
|
||||||
|
|
||||||
foo: bar
|
foo: bar
|
||||||
install:
|
install:
|
||||||
@@ -837,7 +852,12 @@ stages:
|
|||||||
c, err := Scan(o, FilterKeysTestMerge)
|
c, err := Scan(o, FilterKeysTestMerge)
|
||||||
Expect(err).ToNot(HaveOccurred())
|
Expect(err).ToNot(HaveOccurred())
|
||||||
|
|
||||||
Expect(c.String()).To(Equal(`#cloud-config
|
Expect(c.String()).To(MatchRegexp(`#cloud-config
|
||||||
|
|
||||||
|
# Sources:
|
||||||
|
# .*/local_config_1\.yaml
|
||||||
|
# .*/local_config_2\.yaml
|
||||||
|
# - cmdline
|
||||||
|
|
||||||
install:
|
install:
|
||||||
auto: true
|
auto: true
|
||||||
@@ -950,34 +970,51 @@ options:
|
|||||||
c, err := Scan(o, FilterKeysTestMerge)
|
c, err := Scan(o, FilterKeysTestMerge)
|
||||||
Expect(err).ToNot(HaveOccurred())
|
Expect(err).ToNot(HaveOccurred())
|
||||||
|
|
||||||
configURL, ok := (*c)["config_url"].(string)
|
configURL, ok := c.Values["config_url"].(string)
|
||||||
Expect(ok).To(BeTrue())
|
Expect(ok).To(BeTrue())
|
||||||
Expect(configURL).To(MatchRegexp("remote_config_2.yaml"))
|
Expect(configURL).To(MatchRegexp("remote_config_2.yaml"))
|
||||||
|
|
||||||
k := (*c)["local_key_1"].(string)
|
k := c.Values["local_key_1"].(string)
|
||||||
Expect(k).To(Equal("local_value_1"))
|
Expect(k).To(Equal("local_value_1"))
|
||||||
k = (*c)["local_key_2"].(string)
|
k = c.Values["local_key_2"].(string)
|
||||||
Expect(k).To(Equal("local_value_2"))
|
Expect(k).To(Equal("local_value_2"))
|
||||||
k = (*c)["local_key_3"].(string)
|
k = c.Values["local_key_3"].(string)
|
||||||
Expect(k).To(Equal("local_value_3"))
|
Expect(k).To(Equal("local_value_3"))
|
||||||
k = (*c)["remote_key_1"].(string)
|
k = c.Values["remote_key_1"].(string)
|
||||||
Expect(k).To(Equal("remote_value_1"))
|
Expect(k).To(Equal("remote_value_1"))
|
||||||
k = (*c)["remote_key_2"].(string)
|
k = c.Values["remote_key_2"].(string)
|
||||||
Expect(k).To(Equal("remote_value_2"))
|
Expect(k).To(Equal("remote_value_2"))
|
||||||
k = (*c)["remote_key_3"].(string)
|
k = c.Values["remote_key_3"].(string)
|
||||||
Expect(k).To(Equal("remote_value_3"))
|
Expect(k).To(Equal("remote_value_3"))
|
||||||
k = (*c)["remote_key_4"].(string)
|
k = c.Values["remote_key_4"].(string)
|
||||||
Expect(k).To(Equal("remote_value_4"))
|
Expect(k).To(Equal("remote_value_4"))
|
||||||
|
|
||||||
options := (*c)["options"].(Config)
|
options := c.Values["options"].(ConfigValues)
|
||||||
Expect(options["foo"]).To(Equal("bar"))
|
Expect(options["foo"]).To(Equal("bar"))
|
||||||
Expect(options["remote_option_1"]).To(Equal("remote_option_value_1"))
|
Expect(options["remote_option_1"]).To(Equal("remote_option_value_1"))
|
||||||
Expect(options["remote_option_2"]).To(Equal("remote_option_value_2"))
|
Expect(options["remote_option_2"]).To(Equal("remote_option_value_2"))
|
||||||
|
|
||||||
player := (*c)["player"].(Config)
|
player := c.Values["player"].(ConfigValues)
|
||||||
fmt.Print(player)
|
fmt.Print(player)
|
||||||
Expect(player["name"]).NotTo(Equal("Toad"))
|
Expect(player["name"]).NotTo(Equal("Toad"))
|
||||||
Expect(player["surname"]).To(Equal("Bros"))
|
Expect(player["surname"]).To(Equal("Bros"))
|
||||||
|
|
||||||
|
cs, _ := c.String()
|
||||||
|
// Check "Sources" comment
|
||||||
|
Expect(cs).To(MatchRegexp(`.*
|
||||||
|
# Sources:
|
||||||
|
# - /tmp/.*/local_config_1.yaml
|
||||||
|
# - http://127.0.0.1:.*/remote_config_3.yaml
|
||||||
|
# - http://127.0.0.1:.*/remote_config_4.yaml
|
||||||
|
# - /tmp/.*/local_config_2.yaml
|
||||||
|
# - http://127.0.0.1:.*/remote_config_5.yaml
|
||||||
|
# - http://127.0.0.1:.*/remote_config_6.yaml
|
||||||
|
# - /tmp/.*/local_config_3.yaml
|
||||||
|
# - cmdline
|
||||||
|
# - http://127.0.0.1:.*/remote_config_1.yaml
|
||||||
|
# - http://127.0.0.1:.*/remote_config_2.yaml
|
||||||
|
.*
|
||||||
|
`))
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
@@ -1036,19 +1073,19 @@ remote_key_2: remote_value_2`), os.ModePerm)
|
|||||||
c, err := Scan(o, FilterKeysTest)
|
c, err := Scan(o, FilterKeysTest)
|
||||||
Expect(err).ToNot(HaveOccurred())
|
Expect(err).ToNot(HaveOccurred())
|
||||||
|
|
||||||
Expect((*c)["local_key_2"]).To(BeNil())
|
Expect(c.Values["local_key_2"]).To(BeNil())
|
||||||
Expect((*c)["remote_key_2"]).To(BeNil())
|
Expect(c.Values["remote_key_2"]).To(BeNil())
|
||||||
|
|
||||||
// sanity check, the rest should be there
|
// sanity check, the rest should be there
|
||||||
v, ok := (*c)["config_url"].(string)
|
v, ok := c.Values["config_url"].(string)
|
||||||
Expect(ok).To(BeTrue())
|
Expect(ok).To(BeTrue())
|
||||||
Expect(v).To(MatchRegexp("remote_config_2.yaml"))
|
Expect(v).To(MatchRegexp("remote_config_2.yaml"))
|
||||||
|
|
||||||
v, ok = (*c)["local_key_1"].(string)
|
v, ok = c.Values["local_key_1"].(string)
|
||||||
Expect(ok).To(BeTrue())
|
Expect(ok).To(BeTrue())
|
||||||
Expect(v).To(Equal("local_value_1"))
|
Expect(v).To(Equal("local_value_1"))
|
||||||
|
|
||||||
v, ok = (*c)["remote_key_1"].(string)
|
v, ok = c.Values["remote_key_1"].(string)
|
||||||
Expect(ok).To(BeTrue())
|
Expect(ok).To(BeTrue())
|
||||||
Expect(v).To(Equal("remote_value_1"))
|
Expect(v).To(Equal("remote_value_1"))
|
||||||
})
|
})
|
||||||
@@ -1095,14 +1132,14 @@ local_key_2: local_value_2
|
|||||||
c, err := Scan(o, FilterKeysTest)
|
c, err := Scan(o, FilterKeysTest)
|
||||||
Expect(err).ToNot(HaveOccurred())
|
Expect(err).ToNot(HaveOccurred())
|
||||||
|
|
||||||
Expect((*c)["local_key_1"]).ToNot(BeNil())
|
Expect(c.Values["local_key_1"]).ToNot(BeNil())
|
||||||
Expect((*c)["local_key_2"]).ToNot(BeNil())
|
Expect(c.Values["local_key_2"]).ToNot(BeNil())
|
||||||
|
|
||||||
v, ok := (*c)["local_key_1"].(string)
|
v, ok := c.Values["local_key_1"].(string)
|
||||||
Expect(ok).To(BeTrue())
|
Expect(ok).To(BeTrue())
|
||||||
Expect(v).To(Equal("local_value_1"))
|
Expect(v).To(Equal("local_value_1"))
|
||||||
|
|
||||||
v, ok = (*c)["local_key_2"].(string)
|
v, ok = c.Values["local_key_2"].(string)
|
||||||
Expect(ok).To(BeTrue())
|
Expect(ok).To(BeTrue())
|
||||||
Expect(v).To(Equal("local_value_2"))
|
Expect(v).To(Equal("local_value_2"))
|
||||||
})
|
})
|
||||||
@@ -1113,7 +1150,7 @@ local_key_2: local_value_2
|
|||||||
var conf *Config
|
var conf *Config
|
||||||
BeforeEach(func() {
|
BeforeEach(func() {
|
||||||
conf = &Config{}
|
conf = &Config{}
|
||||||
err := yaml.Unmarshal([]byte("name: Mario"), conf)
|
err := yaml.Unmarshal([]byte("name: Mario"), &conf.Values)
|
||||||
Expect(err).ToNot(HaveOccurred())
|
Expect(err).ToNot(HaveOccurred())
|
||||||
})
|
})
|
||||||
|
|
||||||
|
@@ -11,6 +11,7 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
func TestConfig(t *testing.T) {
|
func TestConfig(t *testing.T) {
|
||||||
|
// format.TruncatedDiff = false
|
||||||
RegisterFailHandler(Fail)
|
RegisterFailHandler(Fail)
|
||||||
RunSpecs(t, "Config Collector Suite")
|
RunSpecs(t, "Config Collector Suite")
|
||||||
}
|
}
|
||||||
|
3
go.mod
3
go.mod
@@ -23,7 +23,7 @@ require (
|
|||||||
github.com/qeesung/image2ascii v1.0.1
|
github.com/qeesung/image2ascii v1.0.1
|
||||||
github.com/rs/zerolog v1.33.0
|
github.com/rs/zerolog v1.33.0
|
||||||
github.com/saferwall/pe v1.5.4
|
github.com/saferwall/pe v1.5.4
|
||||||
github.com/santhosh-tekuri/jsonschema/v6 v6.0.1
|
github.com/santhosh-tekuri/jsonschema/v5 v5.3.1
|
||||||
github.com/swaggest/jsonschema-go v0.3.62
|
github.com/swaggest/jsonschema-go v0.3.62
|
||||||
github.com/twpayne/go-vfs/v4 v4.3.0
|
github.com/twpayne/go-vfs/v4 v4.3.0
|
||||||
github.com/urfave/cli/v2 v2.27.4
|
github.com/urfave/cli/v2 v2.27.4
|
||||||
@@ -110,7 +110,6 @@ require (
|
|||||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20231212172506-995d672761c0 // indirect
|
google.golang.org/genproto/googleapis/rpc v0.0.0-20231212172506-995d672761c0 // indirect
|
||||||
google.golang.org/grpc v1.59.0 // indirect
|
google.golang.org/grpc v1.59.0 // indirect
|
||||||
google.golang.org/protobuf v1.34.1 // indirect
|
google.golang.org/protobuf v1.34.1 // indirect
|
||||||
gopkg.in/yaml.v1 v1.0.0-20140924161607-9f9df34309c0 // indirect
|
|
||||||
gopkg.in/yaml.v2 v2.4.0 // indirect
|
gopkg.in/yaml.v2 v2.4.0 // indirect
|
||||||
gotest.tools/v3 v3.4.0 // indirect
|
gotest.tools/v3 v3.4.0 // indirect
|
||||||
howett.net/plist v1.0.0 // indirect
|
howett.net/plist v1.0.0 // indirect
|
||||||
|
14
go.sum
14
go.sum
@@ -119,8 +119,8 @@ github.com/docker/cli v27.1.1+incompatible h1:goaZxOqs4QKxznZjjBWKONQci/MywhtRv2
|
|||||||
github.com/docker/cli v27.1.1+incompatible/go.mod h1:JLrzqnKDaYBop7H2jaqPtU4hHvMKP+vjCwu2uszcLI8=
|
github.com/docker/cli v27.1.1+incompatible/go.mod h1:JLrzqnKDaYBop7H2jaqPtU4hHvMKP+vjCwu2uszcLI8=
|
||||||
github.com/docker/distribution v2.8.2+incompatible h1:T3de5rq0dB1j30rp0sA2rER+m322EBzniBPB6ZIzuh8=
|
github.com/docker/distribution v2.8.2+incompatible h1:T3de5rq0dB1j30rp0sA2rER+m322EBzniBPB6ZIzuh8=
|
||||||
github.com/docker/distribution v2.8.2+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w=
|
github.com/docker/distribution v2.8.2+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w=
|
||||||
github.com/docker/docker v27.2.1+incompatible h1:fQdiLfW7VLscyoeYEBz7/J8soYFDZV1u6VW6gJEjNMI=
|
github.com/docker/docker v27.3.1+incompatible h1:KttF0XoteNTicmUtBO0L2tP+J7FGRFTjaEF4k6WdhfI=
|
||||||
github.com/docker/docker v27.2.1+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk=
|
github.com/docker/docker v27.3.1+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk=
|
||||||
github.com/docker/docker-credential-helpers v0.7.0 h1:xtCHsjxogADNZcdv1pKUHXryefjlVRqWqIhk/uXJp0A=
|
github.com/docker/docker-credential-helpers v0.7.0 h1:xtCHsjxogADNZcdv1pKUHXryefjlVRqWqIhk/uXJp0A=
|
||||||
github.com/docker/docker-credential-helpers v0.7.0/go.mod h1:rETQfLdHNT3foU5kuNkFR1R1V12OJRRO5lzt2D1b5X0=
|
github.com/docker/docker-credential-helpers v0.7.0/go.mod h1:rETQfLdHNT3foU5kuNkFR1R1V12OJRRO5lzt2D1b5X0=
|
||||||
github.com/docker/go-connections v0.4.0 h1:El9xVISelRB7BuFusrZozjnkIM5YnzCViNKohAFqRJQ=
|
github.com/docker/go-connections v0.4.0 h1:El9xVISelRB7BuFusrZozjnkIM5YnzCViNKohAFqRJQ=
|
||||||
@@ -306,8 +306,8 @@ github.com/morikuni/aec v1.0.0 h1:nP9CBfwrvYnBRgY6qfDQkygYDmYwOilePFkwzv4dU8A=
|
|||||||
github.com/morikuni/aec v1.0.0/go.mod h1:BbKIizmSmc5MMPqRYbxO4ZU0S0+P200+tUnFx7PXmsc=
|
github.com/morikuni/aec v1.0.0/go.mod h1:BbKIizmSmc5MMPqRYbxO4ZU0S0+P200+tUnFx7PXmsc=
|
||||||
github.com/mudler/go-pluggable v0.0.0-20230126220627-7710299a0ae5 h1:FaZD86+A9mVt7lh9glAryzQblMsbJYU2VnrdZ8yHlTs=
|
github.com/mudler/go-pluggable v0.0.0-20230126220627-7710299a0ae5 h1:FaZD86+A9mVt7lh9glAryzQblMsbJYU2VnrdZ8yHlTs=
|
||||||
github.com/mudler/go-pluggable v0.0.0-20230126220627-7710299a0ae5/go.mod h1:WmKcT8ONmhDQIqQ+HxU+tkGWjzBEyY/KFO8LTGCu4AI=
|
github.com/mudler/go-pluggable v0.0.0-20230126220627-7710299a0ae5/go.mod h1:WmKcT8ONmhDQIqQ+HxU+tkGWjzBEyY/KFO8LTGCu4AI=
|
||||||
github.com/mudler/yip v1.9.4 h1:yaiPKWG5kt/DTNCf7ZGfyWdb1j5c06zYqWF3F+SVKsE=
|
github.com/mudler/yip v1.10.0 h1:MwEIySEfSRRwTUz2BmQQpRn6+M7jqVGf/OldsepBvz0=
|
||||||
github.com/mudler/yip v1.9.4/go.mod h1:nqf8JFCq7a7rIkm7cSs+SOc8QbiyvVJ/xLbUw4GgzFs=
|
github.com/mudler/yip v1.10.0/go.mod h1:gwH7iGcr1Jimox2xKtN2AprEO00GzY7smvuycqCL7+Y=
|
||||||
github.com/nfnt/resize v0.0.0-20180221191011-83c6a9932646 h1:zYyBkD/k9seD2A7fsi6Oo2LfFZAehjjQMERAvZLEDnQ=
|
github.com/nfnt/resize v0.0.0-20180221191011-83c6a9932646 h1:zYyBkD/k9seD2A7fsi6Oo2LfFZAehjjQMERAvZLEDnQ=
|
||||||
github.com/nfnt/resize v0.0.0-20180221191011-83c6a9932646/go.mod h1:jpp1/29i3P1S/RLdc7JQKbRpFeM1dOBd8T9ki5s+AY8=
|
github.com/nfnt/resize v0.0.0-20180221191011-83c6a9932646/go.mod h1:jpp1/29i3P1S/RLdc7JQKbRpFeM1dOBd8T9ki5s+AY8=
|
||||||
github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A=
|
github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A=
|
||||||
@@ -359,7 +359,6 @@ github.com/saferwall/pe v1.5.4 h1:tLmMggEMUfeqrpJ25zS/okUQmyFdD5xWKL2+z9njCqg=
|
|||||||
github.com/saferwall/pe v1.5.4/go.mod h1:mJx+PuptmNpoPFBNhWs/uDMFL/kTHVZIkg0d4OUJFbQ=
|
github.com/saferwall/pe v1.5.4/go.mod h1:mJx+PuptmNpoPFBNhWs/uDMFL/kTHVZIkg0d4OUJFbQ=
|
||||||
github.com/santhosh-tekuri/jsonschema/v5 v5.3.1 h1:lZUw3E0/J3roVtGQ+SCrUrg3ON6NgVqpn3+iol9aGu4=
|
github.com/santhosh-tekuri/jsonschema/v5 v5.3.1 h1:lZUw3E0/J3roVtGQ+SCrUrg3ON6NgVqpn3+iol9aGu4=
|
||||||
github.com/santhosh-tekuri/jsonschema/v5 v5.3.1/go.mod h1:uToXkOrWAZ6/Oc07xWQrPOhJotwFIyu2bBVN41fcDUY=
|
github.com/santhosh-tekuri/jsonschema/v5 v5.3.1/go.mod h1:uToXkOrWAZ6/Oc07xWQrPOhJotwFIyu2bBVN41fcDUY=
|
||||||
github.com/santhosh-tekuri/jsonschema/v6 v6.0.1/go.mod h1:JXeL+ps8p7/KNMjDQk3TCwPpBy0wYklyWTfbkIzdIFU=
|
|
||||||
github.com/secDre4mer/pkcs7 v0.0.0-20240322103146-665324a4461d h1:RQqyEogx5J6wPdoxqL132b100j8KjcVHO1c0KLRoIhc=
|
github.com/secDre4mer/pkcs7 v0.0.0-20240322103146-665324a4461d h1:RQqyEogx5J6wPdoxqL132b100j8KjcVHO1c0KLRoIhc=
|
||||||
github.com/secDre4mer/pkcs7 v0.0.0-20240322103146-665324a4461d/go.mod h1:PegD7EVqlN88z7TpCqH92hHP+GBpfomGCCnw1PFtNOA=
|
github.com/secDre4mer/pkcs7 v0.0.0-20240322103146-665324a4461d/go.mod h1:PegD7EVqlN88z7TpCqH92hHP+GBpfomGCCnw1PFtNOA=
|
||||||
github.com/sergi/go-diff v1.2.0/go.mod h1:STckp+ISIX8hZLjrqAeVduY0gWCT9IjLuqbuNXdaHfM=
|
github.com/sergi/go-diff v1.2.0/go.mod h1:STckp+ISIX8hZLjrqAeVduY0gWCT9IjLuqbuNXdaHfM=
|
||||||
@@ -412,8 +411,8 @@ github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9de
|
|||||||
github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
||||||
github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
||||||
github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
|
github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
|
||||||
github.com/zcalusic/sysinfo v1.1.0 h1:79Hqn8h4poVz6T57/4ezXbT5ZkZbZm7u1YU1C4paMyk=
|
github.com/zcalusic/sysinfo v1.1.2 h1:38KUgZQmCxlN9vUTt4miis4rU5ISJXGXOJ2rY7bMC8g=
|
||||||
github.com/zcalusic/sysinfo v1.1.0/go.mod h1:NX+qYnWGtJVPV0yWldff9uppNKU4h40hJIRPf/pGLv4=
|
github.com/zcalusic/sysinfo v1.1.2/go.mod h1:NX+qYnWGtJVPV0yWldff9uppNKU4h40hJIRPf/pGLv4=
|
||||||
go.mozilla.org/pkcs7 v0.0.0-20200128120323-432b2356ecb1 h1:A/5uWzF44DlIgdm/PQFwfMkW0JX+cIcQi/SwLAmZP5M=
|
go.mozilla.org/pkcs7 v0.0.0-20200128120323-432b2356ecb1 h1:A/5uWzF44DlIgdm/PQFwfMkW0JX+cIcQi/SwLAmZP5M=
|
||||||
go.mozilla.org/pkcs7 v0.0.0-20200128120323-432b2356ecb1/go.mod h1:SNgMg+EgDFwmvSmLRTNKC5fegJjB7v23qTQ0XLGUNHk=
|
go.mozilla.org/pkcs7 v0.0.0-20200128120323-432b2356ecb1/go.mod h1:SNgMg+EgDFwmvSmLRTNKC5fegJjB7v23qTQ0XLGUNHk=
|
||||||
go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU=
|
go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU=
|
||||||
@@ -793,7 +792,6 @@ gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI=
|
|||||||
gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys=
|
gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys=
|
||||||
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ=
|
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ=
|
||||||
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw=
|
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw=
|
||||||
gopkg.in/yaml.v1 v1.0.0-20140924161607-9f9df34309c0 h1:POO/ycCATvegFmVuPpQzZFJ+pGZeX22Ufu6fibxDVjU=
|
|
||||||
gopkg.in/yaml.v1 v1.0.0-20140924161607-9f9df34309c0/go.mod h1:WDnlLJ4WF5VGsH/HVa3CI79GS0ol3YnhVnKP89i0kNg=
|
gopkg.in/yaml.v1 v1.0.0-20140924161607-9f9df34309c0/go.mod h1:WDnlLJ4WF5VGsH/HVa3CI79GS0ol3YnhVnKP89i0kNg=
|
||||||
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||||
gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||||
|
Reference in New Issue
Block a user