2022-08-10 16:56:07 +00:00
|
|
|
package machine
|
|
|
|
|
|
|
|
import (
|
|
|
|
"fmt"
|
|
|
|
"os"
|
2022-11-16 10:44:18 +00:00
|
|
|
"os/exec"
|
2022-08-10 16:56:07 +00:00
|
|
|
"strings"
|
|
|
|
|
|
|
|
"github.com/denisbrodbeck/machineid"
|
2023-03-17 13:00:02 +00:00
|
|
|
"github.com/kairos-io/kairos-sdk/machine/openrc"
|
|
|
|
"github.com/kairos-io/kairos-sdk/machine/systemd"
|
2022-08-10 16:56:07 +00:00
|
|
|
|
2023-03-17 13:00:02 +00:00
|
|
|
"github.com/kairos-io/kairos-sdk/utils"
|
2022-08-10 16:56:07 +00:00
|
|
|
)
|
|
|
|
|
|
|
|
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 {
|
2022-11-21 17:11:03 +00:00
|
|
|
return os.WriteFile(fmt.Sprintf("/usr/local/.kairos/sentinel_%s", f), []byte{}, os.ModePerm)
|
2022-08-10 16:56:07 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
func SentinelExist(f string) bool {
|
2022-09-17 16:43:51 +00:00
|
|
|
if _, err := os.Stat(fmt.Sprintf("/usr/local/.kairos/sentinel_%s", f)); err == nil {
|
2022-08-10 16:56:07 +00:00
|
|
|
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
|
|
|
|
}
|
2022-11-16 10:44:18 +00:00
|
|
|
|
|
|
|
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
|
|
|
|
}
|