Bump to newer sdk (#1166)

This commit is contained in:
Itxaka
2023-03-18 10:27:18 +01:00
parent df8b9824fc
commit b7ea097d35
17 changed files with 1 additions and 809 deletions

View File

@@ -13,9 +13,9 @@ import (
"github.com/imdario/mergo" "github.com/imdario/mergo"
"github.com/itchyny/gojq" "github.com/itchyny/gojq"
"github.com/kairos-io/kairos-sdk/bundles" "github.com/kairos-io/kairos-sdk/bundles"
"github.com/kairos-io/kairos-sdk/machine"
"github.com/kairos-io/kairos-sdk/unstructured" "github.com/kairos-io/kairos-sdk/unstructured"
schema "github.com/kairos-io/kairos/pkg/config/schemas" schema "github.com/kairos-io/kairos/pkg/config/schemas"
"github.com/kairos-io/kairos/pkg/machine"
yip "github.com/mudler/yip/pkg/schema" yip "github.com/mudler/yip/pkg/schema"
"gopkg.in/yaml.v3" "gopkg.in/yaml.v3"

View File

@@ -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
}

View File

@@ -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))
})
})
})

View File

@@ -1,9 +0,0 @@
package machine
import "os"
func Exists(path string) bool {
_, err := os.Stat(path)
return !os.IsNotExist(err)
}

View File

@@ -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
}

View File

@@ -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")
}

View File

@@ -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
}

View File

@@ -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()
}

View File

@@ -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
}

View File

@@ -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
}

View File

@@ -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))
}

View File

@@ -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])
}
}
}

View File

@@ -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
}

View File

@@ -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()
}()
}

View File

@@ -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
}
}

View File

@@ -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 ""
}

View File

@@ -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)
}