Skip to content

Commit

Permalink
Add hooks for actions and phases
Browse files Browse the repository at this point in the history
Signed-off-by: Jussi Nummelin <jnummelin@mirantis.com>
  • Loading branch information
jnummelin committed Jun 17, 2021
1 parent cebe904 commit fce5baa
Show file tree
Hide file tree
Showing 7 changed files with 111 additions and 0 deletions.
2 changes: 2 additions & 0 deletions cmd/apply.go
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,7 @@ var applyCommand = &cli.Command{
&phase.ValidateHosts{},
&phase.GatherK0sFacts{},
&phase.ValidateFacts{SkipDowngradeCheck: ctx.Bool("disable-downgrade-check")},
&phase.RunHooks{Stage: "before", Action: "apply"},
&phase.ConfigureK0s{},
&phase.Restore{
RestoreFrom: ctx.String("restore-from"),
Expand All @@ -87,6 +88,7 @@ var applyCommand = &cli.Command{
&phase.UpgradeWorkers{
NoDrain: ctx.Bool("no-drain"),
},
&phase.RunHooks{Stage: "after", Action: "apply"},
&phase.Disconnect{},
)

Expand Down
2 changes: 2 additions & 0 deletions cmd/backup.go
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,9 @@ var backupCommand = &cli.Command{
&phase.DetectOS{},
&phase.GatherFacts{},
&phase.GatherK0sFacts{},
&phase.RunHooks{Stage: "before", Action: "backup"},
&phase.Backup{},
&phase.RunHooks{Stage: "after", Action: "backup"},
&phase.Disconnect{},
)

Expand Down
2 changes: 2 additions & 0 deletions cmd/reset.go
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,9 @@ var resetCommand = &cli.Command{
&phase.DetectOS{},
&phase.PrepareHosts{},
&phase.GatherK0sFacts{},
&phase.RunHooks{Stage: "before", Action: "reset"},
&phase.Reset{},
&phase.RunHooks{Stage: "after", Action: "reset"},
&phase.Disconnect{},
)

Expand Down
12 changes: 12 additions & 0 deletions config/cluster/hook.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package cluster

// Hooks define a list of hooks such as hooks["apply"]["before"] = ["ls -al", "rm foo.txt"]
type Hooks map[string]map[string][]string

// ForActionAndStage return hooks for given action and stage
func (h Hooks) ForActionAndStage(action, stage string) []string {
if len(h[action]) > 0 {
return h[action][stage]
}
return nil
}
1 change: 1 addition & 0 deletions config/cluster/host.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ type Host struct {
InstallFlags Flags `yaml:"installFlags,omitempty"`
Files []UploadFile `yaml:"files,omitempty"`
OSIDOverride string `yaml:"os,omitempty"`
Hooks Hooks `yaml:"hooks,omitempty"`

Metadata HostMetadata `yaml:"-"`
Configurer configurer `yaml:"-"`
Expand Down
86 changes: 86 additions & 0 deletions phase/runhooks.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
package phase

import (
"fmt"
"strings"
"sync"

"github.com/k0sproject/k0sctl/config"
"github.com/k0sproject/k0sctl/config/cluster"
)

var _ phase = &RunHooks{}

// RunHooks phase runs a set of hooks configured for the host
type RunHooks struct {
Action string
Stage string

steps map[*cluster.Host][]string
}

// Title for the phase
func (p *RunHooks) Title() string {
return fmt.Sprintf("Run %s %s Hooks", strings.Title(p.Stage), strings.Title(p.Action))
}

// Prepare digs out the hosts with steps from the config
func (p *RunHooks) Prepare(config *config.Cluster) error {
p.steps = make(map[*cluster.Host][]string)
for _, h := range config.Spec.Hosts {
if len(h.Hooks) > 0 {
p.steps[h] = h.Hooks.ForActionAndStage(p.Action, p.Stage)
}
}

return nil
}

// ShouldRun is true when there are hosts that need to be connected
func (p *RunHooks) ShouldRun() bool {
return len(p.steps) > 0
}

// Run does all the prep work on the hosts in parallel
func (p *RunHooks) Run() error {
var wg sync.WaitGroup
var errors []string
type erritem struct {
host string
err error
}
ec := make(chan erritem, 1)

wg.Add(len(p.steps))

for h, steps := range p.steps {
go func(h *cluster.Host, steps []string) {
for _, s := range steps {
err := h.Exec(s)
if err != nil {
ec <- erritem{h.String(), err}
return // do not exec remaining steps if one fails
}
}

ec <- erritem{h.String(), nil}
}(h, steps)
}

go func() {
for e := range ec {
if e.err != nil {
errors = append(errors, fmt.Sprintf("%s: %s", e.host, e.err.Error()))
}
wg.Done()
}
}()

wg.Wait()

if len(errors) > 0 {
return fmt.Errorf("failed on %d hosts:\n - %s", len(errors), strings.Join(errors, "\n - "))
}

return nil
}
6 changes: 6 additions & 0 deletions smoke-test/k0sctl.yaml.tpl
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,12 @@ spec:
address: "127.0.0.1"
port: 9022
keyPath: ./id_rsa_k0s
hooks:
apply:
before:
- "date > /before-apply.hook"
after:
- "date > /after-apply.hook"
- role: worker
uploadBinary: true
os: "$OS_OVERRIDE"
Expand Down

0 comments on commit fce5baa

Please sign in to comment.