mirror of
https://github.com/kairos-io/kairos-agent.git
synced 2025-09-17 15:27:58 +00:00
Bump to newer sdk (#1166)
This commit is contained in:
@@ -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"
|
||||||
|
@@ -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
|
|
||||||
}
|
|
@@ -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))
|
|
||||||
})
|
|
||||||
})
|
|
||||||
})
|
|
@@ -1,9 +0,0 @@
|
|||||||
package machine
|
|
||||||
|
|
||||||
import "os"
|
|
||||||
|
|
||||||
func Exists(path string) bool {
|
|
||||||
_, err := os.Stat(path)
|
|
||||||
|
|
||||||
return !os.IsNotExist(err)
|
|
||||||
}
|
|
@@ -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
|
|
||||||
}
|
|
@@ -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")
|
|
||||||
}
|
|
@@ -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
|
|
||||||
}
|
|
@@ -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()
|
|
||||||
}
|
|
@@ -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
|
|
||||||
}
|
|
@@ -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
|
|
||||||
}
|
|
@@ -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))
|
|
||||||
}
|
|
@@ -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])
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@@ -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
|
|
||||||
}
|
|
@@ -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()
|
|
||||||
}()
|
|
||||||
}
|
|
@@ -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
|
|
||||||
}
|
|
||||||
}
|
|
@@ -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 ""
|
|
||||||
}
|
|
@@ -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)
|
|
||||||
}
|
|
Reference in New Issue
Block a user