gear: Extract netboot artifacts

This changeset also adds a `config_url` and `options` keyword in the c3os config.
Along with that the config logic is changed so the configuration is taken also from boot commands and merged in the final installed config file.
This commit is contained in:
Ettore Di Giacinto 2022-07-07 16:57:38 +00:00 committed by Itxaka
parent 63cd28d1cb
commit 49e4bd9503
3 changed files with 130 additions and 0 deletions

View File

@ -0,0 +1,88 @@
package machine
import (
"errors"
"fmt"
"io/ioutil"
"strings"
"github.com/google/shlex"
"github.com/hashicorp/go-multierror"
"github.com/itchyny/gojq"
"gopkg.in/yaml.v2"
)
func DotToYAML(file string) ([]byte, error) {
if file == "" {
file = "/proc/cmdline"
}
dat, err := ioutil.ReadFile(file)
if err != nil {
return []byte{}, err
}
v := stringToMap(string(dat))
return dotToYAML(v)
}
func stringToMap(s string) map[string]interface{} {
v := map[string]interface{}{}
splitted, _ := shlex.Split(s)
for _, item := range splitted {
parts := strings.SplitN(item, "=", 2)
value := "true"
if len(parts) > 1 {
value = strings.Trim(parts[1], `"`)
}
key := strings.Trim(parts[0], `"`)
v[key] = value
}
return v
}
func jq(command string, data map[string]interface{}) (map[string]interface{}, error) {
query, err := gojq.Parse(command)
if err != nil {
return nil, err
}
code, err := gojq.Compile(query)
if err != nil {
return nil, err
}
iter := code.Run(data)
v, ok := iter.Next()
if !ok {
return nil, errors.New("failed getting rsult from gojq")
}
if err, ok := v.(error); ok {
return nil, err
}
if t, ok := v.(map[string]interface{}); ok {
return t, nil
}
return make(map[string]interface{}), nil
}
func dotToYAML(v map[string]interface{}) ([]byte, error) {
data := map[string]interface{}{}
var errs error
for k, value := range v {
newData, err := jq(fmt.Sprintf(".%s=\"%s\"", k, value), data)
if err != nil {
errs = multierror.Append(errs, err)
continue
}
data = newData
}
out, err := yaml.Marshal(&data)
if err != nil {
errs = multierror.Append(errs, err)
}
return out, err
}

View File

@ -0,0 +1,29 @@
package machine_test
import (
"io/ioutil"
"os"
. "github.com/c3os-io/c3os/internal/machine"
. "github.com/onsi/ginkgo/v2"
. "github.com/onsi/gomega"
)
var _ = Describe("BootCMDLine", func() {
Context("parses data", func() {
It("returns cmdline if provided", func() {
f, err := ioutil.TempFile("", "test")
Expect(err).ToNot(HaveOccurred())
defer os.RemoveAll(f.Name())
err = ioutil.WriteFile(f.Name(), []byte(`config_url="foo bar" baz.bar=""`), os.ModePerm)
Expect(err).ToNot(HaveOccurred())
b, err := DotToYAML(f.Name())
Expect(err).ToNot(HaveOccurred())
Expect(string(b)).To(Equal("baz:\n bar: \"\"\nconfig_url: foo bar\n"))
})
})
})

View File

@ -0,0 +1,13 @@
package machine_test
import (
"testing"
. "github.com/onsi/ginkgo/v2"
. "github.com/onsi/gomega"
)
func TestInstaller(t *testing.T) {
RegisterFailHandler(Fail)
RunSpecs(t, "Machine Suite")
}