Skip to content

Commit

Permalink
Write k3s config to sysconfig
Browse files Browse the repository at this point in the history
This allows to keep them on subsequent boots. Also refactor systemd unit
which was pretty messy
  • Loading branch information
mudler committed Feb 11, 2022
1 parent 234fd96 commit 7d859f3
Show file tree
Hide file tree
Showing 8 changed files with 185 additions and 75 deletions.
13 changes: 10 additions & 3 deletions installer/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,8 @@ func main() {
Name: "get-kubeconfig",
Flags: []cli.Flag{
&cli.StringFlag{
Name: "api",
Name: "api",
Value: "localhost:8080",
},
},
Action: func(c *cli.Context) error {
Expand Down Expand Up @@ -149,7 +150,10 @@ func main() {
if cc.C3OS.Reboot {
Reboot()
} else {
systemd.StartUnit("getty@tty1")
svc, err := systemd.Getty(1)
if err == nil {
svc.Start()
}
}
return nil
}
Expand Down Expand Up @@ -180,7 +184,10 @@ try booting with another vga option from the boot cmdline (e.g. vga=791).`)
go func() {
prompt("Waiting for registration, press any key to abort pairing. To restart run 'c3os install'.")
// give tty1 back
systemd.StartUnit("getty@tty1")
svc, err := systemd.Getty(1)
if err == nil {
svc.Start()
}
cancel()
}()

Expand Down
15 changes: 11 additions & 4 deletions installer/role/master.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ import (
"strings"

"github.com/mudler/c3os/installer/systemd"
"github.com/mudler/c3os/installer/utils"

service "github.com/mudler/edgevpn/api/client/service"
)

Expand All @@ -25,22 +27,27 @@ func Master(c *service.RoleConfig) error {
// Configure k3s service to start on edgevpn0
c.Logger.Info("Configuring k3s")

svc, err := systemd.NewService(systemd.WithName("k3s"))
if err != nil {
return err
}

// Setup systemd unit and starts it
if err := systemd.WriteEnv("/etc/systemd/system/k3s.service.env",
if err := utils.WriteEnv("/etc/sysconfig/k3s",
map[string]string{},
); err != nil {
return err
}

if err := systemd.OverrideServiceCmd("k3s", "/usr/bin/k3s server --flannel-iface=edgevpn0"); err != nil {
if err := svc.OverrideCmd("/usr/bin/k3s server --flannel-iface=edgevpn0"); err != nil {
return err
}

if err := systemd.StartUnitBlocking("k3s"); err != nil {
if err := svc.StartBlocking(); err != nil {
return err
}

if err := systemd.EnableUnit("k3s"); err != nil {
if err := svc.Enable(); err != nil {
return err
}

Expand Down
15 changes: 11 additions & 4 deletions installer/role/worker.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ import (
"strings"

"github.com/mudler/c3os/installer/systemd"
"github.com/mudler/c3os/installer/utils"

service "github.com/mudler/edgevpn/api/client/service"
)

Expand Down Expand Up @@ -37,8 +39,13 @@ func Worker(c *service.RoleConfig) error {

c.Logger.Info("Configuring k3s-agent", ip, masterIP, nodeToken)

svc, err := systemd.NewService(systemd.WithName("k3s-agent"))
if err != nil {
return err
}

// Setup systemd unit and starts it
if err := systemd.WriteEnv("/etc/systemd/system/k3s-agent.service.env",
if err := utils.WriteEnv("/etc/sysconfig/k3s-agent",
map[string]string{
"K3S_URL": fmt.Sprintf("https://%s:6443", masterIP),
"K3S_TOKEN": nodeToken,
Expand All @@ -47,15 +54,15 @@ func Worker(c *service.RoleConfig) error {
return err
}

if err := systemd.OverrideServiceCmd("k3s-agent", fmt.Sprintf("/usr/bin/k3s agent --with-node-id --node-ip %s --flannel-iface=edgevpn0", ip)); err != nil {
if err := svc.OverrideCmd(fmt.Sprintf("/usr/bin/k3s agent --with-node-id --node-ip %s --flannel-iface=edgevpn0", ip)); err != nil {
return err
}

if err := systemd.StartUnitBlocking("k3s-agent"); err != nil {
if err := svc.StartBlocking(); err != nil {
return err
}

if err := systemd.EnableUnit("k3s-agent"); err != nil {
if err := svc.Enable(); err != nil {
return err
}

Expand Down
30 changes: 26 additions & 4 deletions installer/setup.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import (
"os"

role "github.com/mudler/c3os/installer/role"
"github.com/mudler/c3os/installer/utils"
edgeVPNClient "github.com/mudler/edgevpn/api/client"
service "github.com/mudler/edgevpn/api/client/service"

Expand Down Expand Up @@ -48,16 +49,37 @@ func setup(dir string) error {
return err
}

// Setup systemd unit and starts it
if err := systemd.EdgeVPN.Prepare(map[string]string{
svc, err := systemd.EdgeVPN("c3os")
if err != nil {
return err
}

// Setup edgevpn instance
err = utils.WriteEnv("/etc/systemd/system.conf.d/edgevpn-c3os.env", map[string]string{
"EDGEVPNTOKEN": c.C3OS.NetworkToken,
"API": "true",
"APILISTEN": apiAddress,
"EDGEVPNLOWPROFILEVPNN": "true",
"DHCP": "true",
"DHCPLEASEDIR": "/usr/local/.c3os/lease",
}); err != nil {
l.Warnf("failed preparing edgevpn: '%s'", err.Error())
})
if err != nil {
return err
}

err = svc.WriteUnit()
if err != nil {
return err
}

err = svc.Start()
if err != nil {
return err
}

err = svc.Enable()
if err != nil {
return err
}

if role.SentinelExist() {
Expand Down
5 changes: 2 additions & 3 deletions installer/system.go
Original file line number Diff line number Diff line change
@@ -1,12 +1,11 @@
package main

import (
"os/exec"

"github.com/mudler/c3os/installer/utils"
"github.com/pterm/pterm"
)

func Reboot() {
pterm.Info.Println("Rebooting node")
exec.Command("reboot").Start()
utils.SH("reboot")
}
62 changes: 5 additions & 57 deletions installer/systemd/systemd.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,18 +2,9 @@ package systemd

import (
"fmt"
"io/ioutil"
"os"
"os/exec"
"path/filepath"

"github.com/hashicorp/go-multierror"
"github.com/joho/godotenv"
)

type Unit string

const EdgeVPN Unit = `[Unit]
const edgevpnUnit string = `[Unit]
Description=EdgeVPN Daemon
After=network.target
[Service]
Expand All @@ -25,53 +16,10 @@ Restart=always
[Install]
WantedBy=multi-user.target`

const override string = `
[Service]
ExecStart=
ExecStart=%s
`

func systemdWriteUnit(s, content string) error {
return ioutil.WriteFile(fmt.Sprintf("/etc/systemd/system/%s.service", s), []byte(content), 0600)
}

func OverrideServiceCmd(service, cmd string) error {
svcDir := fmt.Sprintf("/etc/systemd/system/%s.service.d/", service)
os.MkdirAll(svcDir, 0600)

return ioutil.WriteFile(filepath.Join(svcDir, "override.conf"), []byte(fmt.Sprintf(override, cmd)), 0600)
}

func WriteEnv(envFile string, config map[string]string) error {
content, _ := ioutil.ReadFile(envFile)
env, _ := godotenv.Unmarshal(string(content))

for key, val := range config {
env[key] = val
}

return godotenv.Write(env, envFile)
}

func (u Unit) Prepare(opts map[string]string) (err error) {

// Setup systemd unit and starts it
err = multierror.Append(WriteEnv("/etc/systemd/system.conf.d/edgevpn-c3os.env", opts))
err = multierror.Append(systemdWriteUnit("edgevpn@", string(u)))
err = multierror.Append(StartUnit("edgevpn@c3os"))
err = multierror.Append(EnableUnit("edgevpn@c3os"))

return
}

func StartUnit(s string) error {
return exec.Command("/bin/sh", "-c", fmt.Sprintf("systemctl start --no-block %s", s)).Run()
}

func EnableUnit(s string) error {
return exec.Command("/bin/sh", "-c", fmt.Sprintf("systemctl enable %s", s)).Run()
func EdgeVPN(instance string) (ServiceUnit, error) {
return NewService(WithName("edgevpn"), WithInstance(instance), WithUnitContent(edgevpnUnit))
}

func StartUnitBlocking(s string) error {
return exec.Command("/bin/sh", "-c", fmt.Sprintf("systemctl start %s", s)).Run()
func Getty(i int) (ServiceUnit, error) {
return NewService(WithName("getty"), WithInstance(fmt.Sprintf("tty%d", i)))
}
96 changes: 96 additions & 0 deletions installer/systemd/unit.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
package systemd

import (
"fmt"
"io/ioutil"
"os"
"path/filepath"

"github.com/mudler/c3os/installer/utils"
)

type ServiceUnit struct {
content string
name, instance string
}

const overrideCmdTemplate string = `
[Service]
ExecStart=
ExecStart=%s
`

type ServiceOpts func(*ServiceUnit) error

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)
}
return ioutil.WriteFile(fmt.Sprintf("/etc/systemd/system/%s.service", uname), []byte(s.content), 0600)
}

func (s ServiceUnit) OverrideCmd(cmd string) error {
svcDir := fmt.Sprintf("/etc/systemd/system/%s.service.d/", s.name)
os.MkdirAll(svcDir, 0600)

return ioutil.WriteFile(filepath.Join(svcDir, "override.conf"), []byte(fmt.Sprintf(overrideCmdTemplate, cmd)), 0600)
}

func (s ServiceUnit) Start() error {
uname := s.name
if s.instance != "" {
uname = fmt.Sprintf("%s@%s", s.name, s.instance)
}
_, err := utils.SH(fmt.Sprintf("systemctl start --no-block %s", uname))
return err
}

func (s ServiceUnit) Enable() error {
uname := s.name
if s.instance != "" {
uname = fmt.Sprintf("%s@%s", s.name, s.instance)
}
_, err := utils.SH(fmt.Sprintf("systemctl enable %s", uname))
return err
}

func (s ServiceUnit) StartBlocking() error {
uname := s.name
if s.instance != "" {
uname = fmt.Sprintf("%s@%s", s.name, s.instance)
}
_, err := utils.SH(fmt.Sprintf("systemctl start %s", uname))
return err
}
24 changes: 24 additions & 0 deletions installer/utils/sh.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
package utils

import (
"io/ioutil"
"os/exec"

"github.com/joho/godotenv"
)

func SH(c string) (string, error) {
o, err := exec.Command("/bin/sh", "-c", c).CombinedOutput()
return string(o), err
}

func WriteEnv(envFile string, config map[string]string) error {
content, _ := ioutil.ReadFile(envFile)
env, _ := godotenv.Unmarshal(string(content))

for key, val := range config {
env[key] = val
}

return godotenv.Write(env, envFile)
}

0 comments on commit 7d859f3

Please sign in to comment.