art: Expose interactive install to providers

In this way install can be driven from providers too

Part of: https://github.com/c3os-io/c3os/issues/68
This commit is contained in:
mudler
2022-08-12 12:21:12 +02:00
committed by Itxaka
parent b17ccae684
commit 122d29cbac
4 changed files with 84 additions and 33 deletions

View File

@@ -8,9 +8,10 @@ import (
)
type BrandingText struct {
Install string `yaml:"install"`
Reset string `yaml:"reset"`
Recovery string `yaml:"recovery"`
InteractiveInstall string `yaml:"install"`
Install string `yaml:"install"`
Reset string `yaml:"reset"`
Recovery string `yaml:"recovery"`
}
type Config struct {
@@ -31,6 +32,13 @@ func LoadConfig(path ...string) (*Config, error) {
}
}
if cfg.Branding.InteractiveInstall == "" {
f, err := ioutil.ReadFile(c3os.BrandingFile("interactive_install_text"))
if err == nil {
cfg.Branding.InteractiveInstall = string(f)
}
}
if cfg.Branding.Install == "" {
f, err := ioutil.ReadFile(c3os.BrandingFile("install_text"))
if err == nil {

View File

@@ -15,7 +15,6 @@ import (
config "github.com/c3os-io/c3os/pkg/config"
"github.com/c3os-io/c3os/internal/bus"
sdkBus "github.com/c3os-io/c3os/sdk/bus"
"github.com/c3os-io/c3os/internal/cmd"
"github.com/c3os-io/c3os/pkg/utils"
@@ -157,7 +156,7 @@ func Install(dir ...string) error {
pterm.Info.Println("Starting installation")
utils.SH("elemental run-stage c3os-install.pre") //nolint:errcheck
sdkBus.RunHookScript("/usr/bin/c3os-agent.install.pre.hook") //nolint:errcheck
events.RunHookScript("/usr/bin/c3os-agent.install.pre.hook") //nolint:errcheck
if err := RunInstall(r); err != nil {
return err
@@ -217,7 +216,7 @@ func RunInstall(options map[string]string) error {
os.Exit(1)
}
utils.SH("elemental run-stage c3os-install.after") //nolint:errcheck
sdkBus.RunHookScript("/usr/bin/c3os-agent.install.after.hook") //nolint:errcheck
events.RunHookScript("/usr/bin/c3os-agent.install.after.hook") //nolint:errcheck
if reboot || c.Install != nil && c.Install.Reboot {
utils.Reboot()

View File

@@ -1,16 +1,21 @@
package agent
import (
"encoding/json"
"fmt"
"strings"
"github.com/c3os-io/c3os/internal/bus"
"github.com/c3os-io/c3os/internal/cmd"
providerConfig "github.com/c3os-io/c3os/internal/provider/config"
config "github.com/c3os-io/c3os/pkg/config"
events "github.com/c3os-io/c3os/sdk/bus"
"github.com/c3os-io/c3os/sdk/unstructured"
"github.com/c3os-io/c3os/pkg/utils"
"github.com/erikgeiser/promptkit/textinput"
"github.com/jaypipes/ghw"
"github.com/mudler/edgevpn/pkg/node"
"github.com/mudler/go-pluggable"
"github.com/mudler/yip/pkg/schema"
"github.com/pterm/pterm"
)
@@ -49,9 +54,16 @@ const (
)
func InteractiveInstall(spawnShell bool) error {
bus.Manager.Initialize()
cmd.PrintBranding(DefaultBanner)
pterm.DefaultBox.WithTitle("Installation").WithTitleBottomRight().WithRightPadding(0).WithBottomPadding(0).Println(
`Interactive installation. Documentation is available at https://docs.c3os.io.`)
agentConfig, err := LoadConfig()
if err != nil {
return err
}
cmd.PrintText(agentConfig.Branding.InteractiveInstall, "Installation")
disks := []string{}
maxSize := float64(0)
@@ -73,7 +85,6 @@ func InteractiveInstall(spawnShell bool) error {
for _, d := range disks {
pterm.Info.Println(" " + d)
}
var networkToken string
device, err := prompt("What's the target install device?", preferedDevice, "Cannot be empty", false, false)
if err != nil {
@@ -101,28 +112,66 @@ func InteractiveInstall(spawnShell bool) error {
sshUsers := strings.Split(users, ",")
k3sAuto, err := prompt("Do you want to enable k3s automated setup? (requires multiple nodes)", "n", yesNo, true, false)
// Prompt the user by prompts defined by the provider
r := []events.YAMLPrompt{}
bus.Manager.Response(events.EventInteractiveInstall, func(p *pluggable.Plugin, resp *pluggable.EventResponse) {
err := json.Unmarshal([]byte(resp.Data), &r)
if err != nil {
fmt.Println(err)
}
})
_, err = bus.Manager.Publish(events.EventInteractiveInstall, events.EventPayload{})
if err != nil {
return err
}
if isYes(k3sAuto) {
hasNetworkToken, err := prompt("Do you have a network token already?", "n", yesNo, true, false)
if err != nil {
return err
unstructuredYAML := map[string]interface{}{}
for _, p := range r {
var res string
if p.AskFirst {
ask, err := prompt(p.AskPrompt, "n", yesNo, true, false)
if err == nil && !isYes(ask) {
continue
}
}
if isYes(hasNetworkToken) {
networkToken, err = prompt("Input network token", "", "", false, true)
if p.Bool {
def := "n"
if p.Default != "" {
def = p.Default
}
val, err := prompt(p.Prompt, def, yesNo, true, false)
if err != nil {
return err
}
if isYes(val) {
val = "true"
} else {
val = "false"
}
unstructuredYAML[p.YAMLSection] = val
res = val
} else {
networkToken = node.GenerateNewConnectionData().Base64()
def := ""
if p.Default != "" {
def = p.Default
}
val, err := prompt(p.Prompt, def, p.PlaceHolder, true, false)
if err != nil {
return err
}
unstructuredYAML[p.YAMLSection] = val
res = val
}
if res == "" && p.IfEmpty != "" {
res = p.IfEmpty
unstructuredYAML[p.YAMLSection] = res
}
}
k3sStandalone, err := prompt("Do you want to enable k3s standalone?", "n", yesNo, true, false)
result, err := unstructured.ToYAMLMap(unstructuredYAML)
if err != nil {
return err
}
@@ -142,15 +191,6 @@ func InteractiveInstall(spawnShell bool) error {
},
}
providerCfg := providerConfig.Config{
C3OS: &providerConfig.C3OS{
NetworkToken: networkToken,
},
K3s: providerConfig.K3s{
Enabled: isYes(k3sStandalone),
},
}
usersToSet := map[string]schema.User{}
if userName != "" {
@@ -173,16 +213,19 @@ func InteractiveInstall(spawnShell bool) error {
},
}}}
dat, err := config.MergeYAML(cloudConfig, c, providerCfg)
dat, err := config.MergeYAML(cloudConfig, c, result)
if err != nil {
return err
}
finalCloudConfig:=config.AddHeader("#node-config", string(dat))
pterm.Info.Println("Starting installation")
pterm.Info.Println(finalCloudConfig)
err = RunInstall(map[string]string{
"device": device,
"cc": config.AddHeader("#node-config", string(dat)),
"cc": finalCloudConfig,
})
if err != nil {
pterm.Error.Println(err.Error())

View File

@@ -21,7 +21,8 @@ type Bus struct {
}
func (b *Bus) LoadProviders() {
b.Manager.Autoload("agent-provider", "/system/providers").Register()
wd, _ := os.Getwd()
b.Manager.Autoload("agent-provider", "/system/providers", wd).Register()
}
func (b *Bus) Initialize() {