diff --git a/pkg/config/config.go b/pkg/config/config.go index 56db327..00007b3 100644 --- a/pkg/config/config.go +++ b/pkg/config/config.go @@ -13,9 +13,9 @@ import ( "github.com/imdario/mergo" "github.com/itchyny/gojq" "github.com/kairos-io/kairos-sdk/bundles" + "github.com/kairos-io/kairos-sdk/machine" "github.com/kairos-io/kairos-sdk/unstructured" schema "github.com/kairos-io/kairos/pkg/config/schemas" - "github.com/kairos-io/kairos/pkg/machine" yip "github.com/mudler/yip/pkg/schema" "gopkg.in/yaml.v3" diff --git a/pkg/machine/bootcmdline.go b/pkg/machine/bootcmdline.go deleted file mode 100644 index c2e0c90..0000000 --- a/pkg/machine/bootcmdline.go +++ /dev/null @@ -1,40 +0,0 @@ -package machine - -import ( - "os" - "strings" - - "github.com/google/shlex" - "github.com/kairos-io/kairos-sdk/unstructured" -) - -func DotToYAML(file string) ([]byte, error) { - if file == "" { - file = "/proc/cmdline" - } - dat, err := os.ReadFile(file) - if err != nil { - return []byte{}, err - } - - v := stringToMap(string(dat)) - - return unstructured.ToYAML(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 -} diff --git a/pkg/machine/bootcmdline_test.go b/pkg/machine/bootcmdline_test.go deleted file mode 100644 index 028eb60..0000000 --- a/pkg/machine/bootcmdline_test.go +++ /dev/null @@ -1,28 +0,0 @@ -package machine_test - -import ( - "os" - - . "github.com/kairos-io/kairos/pkg/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 := os.CreateTemp("", "test") - Expect(err).ToNot(HaveOccurred()) - defer os.RemoveAll(f.Name()) - - err = os.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"), string(b)) - }) - }) -}) diff --git a/pkg/machine/file.go b/pkg/machine/file.go deleted file mode 100644 index b966e26..0000000 --- a/pkg/machine/file.go +++ /dev/null @@ -1,9 +0,0 @@ -package machine - -import "os" - -func Exists(path string) bool { - _, err := os.Stat(path) - - return !os.IsNotExist(err) -} diff --git a/pkg/machine/machine.go b/pkg/machine/machine.go deleted file mode 100644 index 1fd581a..0000000 --- a/pkg/machine/machine.go +++ /dev/null @@ -1,150 +0,0 @@ -package machine - -import ( - "fmt" - "os" - "os/exec" - "strings" - - "github.com/denisbrodbeck/machineid" - "github.com/kairos-io/kairos/pkg/machine/openrc" - "github.com/kairos-io/kairos/pkg/machine/systemd" - - "github.com/kairos-io/kairos/pkg/utils" -) - -type Service interface { - WriteUnit() error - Start() error - OverrideCmd(string) error - Enable() error - Restart() error -} - -const ( - PassiveBoot = "passive" - ActiveBoot = "active" - RecoveryBoot = "recovery" - LiveCDBoot = "liveCD" - NetBoot = "netboot" - UnknownBoot = "unknown" -) - -// BootFrom returns the booting partition of the SUT. -func BootFrom() string { - out, err := utils.SH("cat /proc/cmdline") - if err != nil { - return UnknownBoot - } - switch { - case strings.Contains(out, "COS_ACTIVE"): - return ActiveBoot - case strings.Contains(out, "COS_PASSIVE"): - return PassiveBoot - case strings.Contains(out, "COS_RECOVERY"), strings.Contains(out, "COS_SYSTEM"): - return RecoveryBoot - case strings.Contains(out, "live:CDLABEL"): - return LiveCDBoot - case strings.Contains(out, "netboot"): - return NetBoot - default: - return UnknownBoot - } -} - -type fakegetty struct{} - -func (fakegetty) Restart() error { return nil } -func (fakegetty) Enable() error { return nil } -func (fakegetty) OverrideCmd(string) error { return nil } -func (fakegetty) SetEnvFile(string) error { return nil } -func (fakegetty) WriteUnit() error { return nil } -func (fakegetty) Start() error { - utils.SH("chvt 2") //nolint:errcheck - return nil -} - -func Getty(i int) (Service, error) { - if utils.IsOpenRCBased() { - return &fakegetty{}, nil - } - - return systemd.NewService( - systemd.WithName("getty"), - systemd.WithInstance(fmt.Sprintf("tty%d", i)), - ) -} - -func K3s() (Service, error) { - if utils.IsOpenRCBased() { - return openrc.NewService( - openrc.WithName("k3s"), - ) - } - - return systemd.NewService( - systemd.WithName("k3s"), - ) -} - -func K3sAgent() (Service, error) { - if utils.IsOpenRCBased() { - return openrc.NewService( - openrc.WithName("k3s-agent"), - ) - } - - return systemd.NewService( - systemd.WithName("k3s-agent"), - ) -} - -func K3sEnvUnit(unit string) string { - if utils.IsOpenRCBased() { - return fmt.Sprintf("/etc/rancher/k3s/%s.env", unit) - } - - return fmt.Sprintf("/etc/sysconfig/%s", unit) -} - -func UUID() string { - if os.Getenv("UUID") != "" { - return os.Getenv("UUID") - } - id, _ := machineid.ID() - hostname, _ := os.Hostname() - return fmt.Sprintf("%s-%s", id, hostname) -} - -func CreateSentinel(f string) error { - return os.WriteFile(fmt.Sprintf("/usr/local/.kairos/sentinel_%s", f), []byte{}, os.ModePerm) -} - -func SentinelExist(f string) bool { - if _, err := os.Stat(fmt.Sprintf("/usr/local/.kairos/sentinel_%s", f)); err == nil { - return true - } - return false -} - -func ExecuteInlineCloudConfig(cloudConfig, stage string) error { - _, err := utils.ShellSTDIN(cloudConfig, fmt.Sprintf("elemental run-stage -s %s -", stage)) - return err -} - -func ExecuteCloudConfig(file, stage string) error { - _, err := utils.SH(fmt.Sprintf("elemental run-stage -s %s %s", stage, file)) - return err -} - -func FindCommand(def string, options []string) string { - for _, p := range options { - path, err := exec.LookPath(p) - if err == nil { - return path - } - } - - // Otherwise return default - return def -} diff --git a/pkg/machine/machine_suite_test.go b/pkg/machine/machine_suite_test.go deleted file mode 100644 index 51bc130..0000000 --- a/pkg/machine/machine_suite_test.go +++ /dev/null @@ -1,13 +0,0 @@ -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") -} diff --git a/pkg/machine/network.go b/pkg/machine/network.go deleted file mode 100644 index 377a674..0000000 --- a/pkg/machine/network.go +++ /dev/null @@ -1,44 +0,0 @@ -package machine - -import ( - "net" -) - -func Interfaces() (in []string) { - ifaces, err := net.Interfaces() - if err != nil { - return - } - for _, i := range ifaces { - if i.Flags == net.FlagLoopback { - continue - } - in = append(in, i.Name) - } - return -} - -func LocalIPs() (ips []string) { - ifaces, err := net.Interfaces() - if err != nil { - return - } - for _, i := range ifaces { - if i.Flags == net.FlagLoopback { - continue - } - addrs, err := i.Addrs() - if err != nil { - continue - } - for _, a := range addrs { - ip, _, err := net.ParseCIDR(a.String()) - if err != nil { - continue - } - - ips = append(ips, ip.String()) - } - } - return -} diff --git a/pkg/machine/openrc/unit.go b/pkg/machine/openrc/unit.go deleted file mode 100644 index 1eeee84..0000000 --- a/pkg/machine/openrc/unit.go +++ /dev/null @@ -1,98 +0,0 @@ -package openrc - -import ( - "fmt" - "os" - "path/filepath" - "strings" - - "github.com/kairos-io/kairos/pkg/utils" -) - -type ServiceUnit struct { - content string - name string - rootdir string -} - -type ServiceOpts func(*ServiceUnit) error - -func WithRoot(n string) ServiceOpts { - return func(su *ServiceUnit) error { - su.rootdir = n - return nil - } -} - -func WithName(n string) ServiceOpts { - return func(su *ServiceUnit) error { - su.name = n - return nil - } -} - -func WithUnitContent(n string) ServiceOpts { - return func(su *ServiceUnit) error { - su.content = n - return nil - } -} - -func NewService(opts ...ServiceOpts) (ServiceUnit, error) { - s := &ServiceUnit{} - for _, o := range opts { - if err := o(s); err != nil { - return *s, err - } - } - return *s, nil -} - -func (s ServiceUnit) WriteUnit() error { - uname := s.name - - if err := os.WriteFile(filepath.Join(s.rootdir, fmt.Sprintf("/etc/init.d/%s", uname)), []byte(s.content), 0755); err != nil { - return err - } - - return nil -} - -// TODO: This is too much k3s specific. -func (s ServiceUnit) OverrideCmd(cmd string) error { - k3sbin := utils.K3sBin() - if k3sbin == "" { - return fmt.Errorf("no k3s binary found (?)") - } - cmd = strings.ReplaceAll(cmd, k3sbin+" ", "") - envFile := filepath.Join(s.rootdir, fmt.Sprintf("/etc/rancher/k3s/%s.env", s.name)) - env := make(map[string]string) - env["command_args"] = fmt.Sprintf("%s >>/var/log/%s.log 2>&1", cmd, s.name) - - return utils.WriteEnv(envFile, env) -} - -func (s ServiceUnit) Start() error { - out, err := utils.SH(fmt.Sprintf("/etc/init.d/%s start", s.name)) - if err != nil { - return fmt.Errorf("failed starting service: %s. %s (%w)", s.name, out, err) - } - return nil -} - -func (s ServiceUnit) Restart() error { - out, err := utils.SH(fmt.Sprintf("/etc/init.d/%s restart", s.name)) - if err != nil { - return fmt.Errorf("failed restarting service: %s. %s (%w)", s.name, out, err) - } - return nil -} - -func (s ServiceUnit) Enable() error { - _, err := utils.SH(fmt.Sprintf("ln -sf /etc/init.d/%s /etc/runlevels/default/%s", s.name, s.name)) - return err -} - -func (s ServiceUnit) StartBlocking() error { - return s.Start() -} diff --git a/pkg/machine/partitions.go b/pkg/machine/partitions.go deleted file mode 100644 index 558cd6a..0000000 --- a/pkg/machine/partitions.go +++ /dev/null @@ -1,48 +0,0 @@ -package machine - -import ( - "fmt" - "os" - "strings" - - "github.com/kairos-io/kairos/pkg/utils" -) - -func Umount(path string) error { - out, err := utils.SH(fmt.Sprintf("umount %s", path)) - if err != nil { - return fmt.Errorf("failed umounting: %s: %w", out, err) - } - return nil -} - -func Remount(opt, path string) error { - out, err := utils.SH(fmt.Sprintf("mount -o %s,remount %s", opt, path)) - if err != nil { - return fmt.Errorf("failed umounting: %s: %w", out, err) - } - return nil -} - -func Mount(label, mountpoint string) error { - part, _ := utils.SH(fmt.Sprintf("blkid -L %s", label)) - if part == "" { - fmt.Printf("%s partition not found\n", label) - return fmt.Errorf("partition not found") - } - - part = strings.TrimSuffix(part, "\n") - - if !Exists(mountpoint) { - err := os.MkdirAll(mountpoint, 0755) - if err != nil { - return err - } - } - mount, err := utils.SH(fmt.Sprintf("mount %s %s", part, mountpoint)) - if err != nil { - fmt.Printf("could not mount: %s\n", mount+err.Error()) - return err - } - return nil -} diff --git a/pkg/machine/systemd/unit.go b/pkg/machine/systemd/unit.go deleted file mode 100644 index bc152ad..0000000 --- a/pkg/machine/systemd/unit.go +++ /dev/null @@ -1,114 +0,0 @@ -package systemd - -import ( - "fmt" - "os" - "path/filepath" - "strings" - - "github.com/kairos-io/kairos/pkg/utils" -) - -type ServiceUnit struct { - content string - name, instance string - rootdir string -} - -const overrideCmdTemplate string = ` -[Service] -ExecStart= -ExecStart=%s -` - -type ServiceOpts func(*ServiceUnit) error - -func WithRoot(n string) ServiceOpts { - return func(su *ServiceUnit) error { - su.rootdir = n - return nil - } -} - -func WithName(n string) ServiceOpts { - return func(su *ServiceUnit) error { - su.name = n - return nil - } -} - -func WithInstance(n string) ServiceOpts { - return func(su *ServiceUnit) error { - su.instance = n - return nil - } -} - -func WithUnitContent(n string) ServiceOpts { - return func(su *ServiceUnit) error { - su.content = n - return nil - } -} - -func NewService(opts ...ServiceOpts) (ServiceUnit, error) { - s := &ServiceUnit{} - for _, o := range opts { - if err := o(s); err != nil { - return *s, err - } - } - return *s, nil -} - -func (s ServiceUnit) WriteUnit() error { - uname := s.name - if s.instance != "" { - uname = fmt.Sprintf("%s@", s.name) - } - - if err := os.WriteFile(filepath.Join(s.rootdir, fmt.Sprintf("/etc/systemd/system/%s.service", uname)), []byte(s.content), 0600); err != nil { - return err - } - - _, err := utils.SH("systemctl daemon-reload") - return err -} - -func (s ServiceUnit) OverrideCmd(cmd string) error { - svcDir := filepath.Join(s.rootdir, fmt.Sprintf("/etc/systemd/system/%s.service.d/", s.name)) - os.MkdirAll(svcDir, 0600) //nolint:errcheck - - return os.WriteFile(filepath.Join(svcDir, "override.conf"), []byte(fmt.Sprintf(overrideCmdTemplate, cmd)), 0600) -} - -func (s ServiceUnit) Start() error { - return s.systemctl("start", false) -} - -func (s ServiceUnit) Restart() error { - return s.systemctl("restart", false) -} - -func (s ServiceUnit) Enable() error { - return s.systemctl("enable", false) -} - -func (s ServiceUnit) StartBlocking() error { - return s.systemctl("start", true) -} - -func (s ServiceUnit) systemctl(action string, blocking bool) error { - uname := s.name - if s.instance != "" { - uname = fmt.Sprintf("%s@%s", s.name, s.instance) - } - args := []string{action} - if !blocking { - args = append(args, "--no-block") - } - args = append(args, uname) - - _, err := utils.SH(fmt.Sprintf("systemctl %s", strings.Join(args, " "))) - return err -} diff --git a/pkg/utils/console.go b/pkg/utils/console.go deleted file mode 100644 index 4b9c12d..0000000 --- a/pkg/utils/console.go +++ /dev/null @@ -1,37 +0,0 @@ -package utils - -import ( - "bufio" - "bytes" - "fmt" - "image" - "os" - "strings" - - "github.com/pterm/pterm" - "github.com/qeesung/image2ascii/convert" -) - -func Prompt(t string) (string, error) { - if t != "" { - pterm.Info.Println(t) - } - answer, err := bufio.NewReader(os.Stdin).ReadString('\n') - if err != nil { - return "", err - } - - return strings.TrimSpace(answer), nil -} - -func PrintBanner(d []byte) { - img, _, _ := image.Decode(bytes.NewReader(d)) - - convertOptions := convert.DefaultOptions - convertOptions.FixedWidth = 100 - convertOptions.FixedHeight = 40 - - // Create the image converter - converter := convert.NewImageConverter() - fmt.Print(converter.Image2ASCIIString(img, &convertOptions)) -} diff --git a/pkg/utils/env.go b/pkg/utils/env.go deleted file mode 100644 index 514ab66..0000000 --- a/pkg/utils/env.go +++ /dev/null @@ -1,16 +0,0 @@ -package utils - -import ( - "os" - "strings" -) - -func SetEnv(env []string) { - - for _, e := range env { - pair := strings.SplitN(e, "=", 2) - if len(pair) >= 2 { - os.Setenv(pair[0], pair[1]) - } - } -} diff --git a/pkg/utils/sh.go b/pkg/utils/sh.go deleted file mode 100644 index dbe6670..0000000 --- a/pkg/utils/sh.go +++ /dev/null @@ -1,52 +0,0 @@ -package utils - -import ( - "bytes" - "os" - "os/exec" - - "github.com/joho/godotenv" -) - -func SHInDir(c, dir string) (string, error) { - cmd := exec.Command("/bin/sh", "-c", c) - cmd.Env = os.Environ() - cmd.Dir = dir - o, err := cmd.CombinedOutput() - return string(o), err -} - -func SH(c string) (string, error) { - cmd := exec.Command("/bin/sh", "-c", c) - cmd.Env = os.Environ() - o, err := cmd.CombinedOutput() - return string(o), err -} - -func WriteEnv(envFile string, config map[string]string) error { - content, _ := os.ReadFile(envFile) - env, _ := godotenv.Unmarshal(string(content)) - - for key, val := range config { - env[key] = val - } - - return godotenv.Write(env, envFile) -} - -func Shell() *exec.Cmd { - cmd := exec.Command("/bin/sh") - cmd.Stdout = os.Stdout - cmd.Stderr = os.Stderr - cmd.Stdin = os.Stdin - return cmd -} - -func ShellSTDIN(s, c string) (string, error) { - cmd := exec.Command("/bin/sh", "-c", c) - cmd.Stdout = os.Stdout - cmd.Stderr = os.Stderr - cmd.Stdin = bytes.NewBuffer([]byte(s)) - o, err := cmd.CombinedOutput() - return string(o), err -} diff --git a/pkg/utils/signal.go b/pkg/utils/signal.go deleted file mode 100644 index 62af370..0000000 --- a/pkg/utils/signal.go +++ /dev/null @@ -1,15 +0,0 @@ -package utils - -import ( - "os" - "os/signal" -) - -func OnSignal(fn func(), sig ...os.Signal) { - sigs := make(chan os.Signal, 1) - signal.Notify(sigs, sig...) - go func() { - <-sigs - fn() - }() -} diff --git a/pkg/utils/strings.go b/pkg/utils/strings.go deleted file mode 100644 index 33897ce..0000000 --- a/pkg/utils/strings.go +++ /dev/null @@ -1,37 +0,0 @@ -package utils - -import ( - "encoding/json" - "math/rand" - "strings" - "time" - - "gopkg.in/yaml.v1" -) - -func init() { - rand.Seed(time.Now().UnixNano()) -} - -var letterRunes = []rune("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ") - -func RandStringRunes(n int) string { - b := make([]rune, n) - for i := range b { - b[i] = letterRunes[rand.Intn(len(letterRunes))] - } - return string(b) -} - -func ListOutput(rels []string, output string) []string { - switch strings.ToLower(output) { - case "yaml": - d, _ := yaml.Marshal(rels) - return []string{string(d)} - case "json": - d, _ := json.Marshal(rels) - return []string{string(d)} - default: - return rels - } -} diff --git a/pkg/utils/system.go b/pkg/utils/system.go deleted file mode 100644 index e6477e3..0000000 --- a/pkg/utils/system.go +++ /dev/null @@ -1,94 +0,0 @@ -package utils - -import ( - "fmt" - "net" - "os" - "strings" - - "github.com/joho/godotenv" - "github.com/pterm/pterm" -) - -func Reboot() { - pterm.Info.Println("Rebooting node") - SH("reboot") //nolint:errcheck -} - -func PowerOFF() { - pterm.Info.Println("Shutdown node") - if IsOpenRCBased() { - SH("poweroff") //nolint:errcheck - } else { - SH("shutdown") //nolint:errcheck - } -} - -func Version() string { - release, _ := godotenv.Read("/etc/os-release") - v := release["VERSION"] - v = strings.ReplaceAll(v, "+k3s1-Kairos", "-") - v = strings.ReplaceAll(v, "+k3s-Kairos", "-") - return strings.ReplaceAll(v, "Kairos", "") -} - -func OSRelease(key string) (string, error) { - release, err := godotenv.Read("/etc/os-release") - if err != nil { - return "", err - } - v, exists := release[key] - if !exists { - return "", fmt.Errorf("key not found") - } - return v, nil -} - -func Flavor() string { - release, _ := godotenv.Read("/etc/os-release") - v := release["NAME"] - return strings.ReplaceAll(v, "kairos-", "") -} - -func IsOpenRCBased() bool { - f := Flavor() - return strings.Contains(f, "alpine") -} - -func GetInterfaceIP(in string) string { - ifaces, err := net.Interfaces() - if err != nil { - fmt.Println("failed getting system interfaces") - return "" - } - for _, i := range ifaces { - if i.Name == in { - addrs, _ := i.Addrs() - // handle err - for _, addr := range addrs { - var ip net.IP - switch v := addr.(type) { - case *net.IPNet: - ip = v.IP - case *net.IPAddr: - ip = v.IP - } - if ip != nil { - return ip.String() - - } - } - } - } - return "" -} - -func K3sBin() string { - for _, p := range []string{"/usr/bin/k3s", "/usr/local/bin/k3s"} { - if _, err := os.Stat(p); err == nil { - return p - } - } - - return "" -} diff --git a/pkg/utils/token.go b/pkg/utils/token.go deleted file mode 100644 index 884ed53..0000000 --- a/pkg/utils/token.go +++ /dev/null @@ -1,13 +0,0 @@ -package utils - -import "strings" - -const sep = "_CREDENTIALS_" - -func EncodeRecoveryToken(data ...string) string { - return strings.Join(data, sep) -} - -func DecodeRecoveryToken(recoverytoken string) []string { - return strings.Split(recoverytoken, sep) -}