mirror of
https://github.com/kairos-io/kairos-agent.git
synced 2025-08-26 03:48:55 +00:00
[WIP] Add --source
to various commands
Signed-off-by: Dimitris Karakasilis <dimitris@karakasilis.me>
This commit is contained in:
parent
1170576dcc
commit
7d18e6504a
@ -53,16 +53,16 @@ func displayInfo(agentConfig *Config) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func ManualInstall(c, device string, reboot, poweroff, strictValidations bool) error {
|
func ManualInstall(c, sourceImg, device string, reboot, poweroff, strictValidations bool) error {
|
||||||
ctx, cancel := context.WithCancel(context.Background())
|
ctx, cancel := context.WithCancel(context.Background())
|
||||||
defer cancel()
|
defer cancel()
|
||||||
|
|
||||||
source, err := prepareConfiguration(ctx, c)
|
ConfigSource, err := prepareConfiguration(ctx, c)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
cc, err := config.Scan(collector.Directories(source), collector.MergeBootLine, collector.StrictValidation(strictValidations), collector.NoLogs)
|
cc, err := config.Scan(collector.Directories(ConfigSource), collector.MergeBootLine, collector.StrictValidation(strictValidations), collector.NoLogs)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@ -80,10 +80,10 @@ func ManualInstall(c, device string, reboot, poweroff, strictValidations bool) e
|
|||||||
// Override from flags!
|
// Override from flags!
|
||||||
cc.Install.Device = device
|
cc.Install.Device = device
|
||||||
}
|
}
|
||||||
return RunInstall(cc)
|
return RunInstall(cc, sourceImg)
|
||||||
}
|
}
|
||||||
|
|
||||||
func Install(dir ...string) error {
|
func Install(sourceImg string, dir ...string) error {
|
||||||
var cc *config.Config
|
var cc *config.Config
|
||||||
var err error
|
var err error
|
||||||
|
|
||||||
@ -120,7 +120,7 @@ func Install(dir ...string) error {
|
|||||||
// runs the installation
|
// runs the installation
|
||||||
cc, err = config.Scan(collector.Directories(dir...), collector.MergeBootLine)
|
cc, err = config.Scan(collector.Directories(dir...), collector.MergeBootLine)
|
||||||
if err == nil && cc.Install != nil && cc.Install.Auto {
|
if err == nil && cc.Install != nil && cc.Install.Auto {
|
||||||
err = RunInstall(cc)
|
err = RunInstall(cc, sourceImg)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@ -184,7 +184,7 @@ func Install(dir ...string) error {
|
|||||||
pterm.Info.Println("Starting installation")
|
pterm.Info.Println("Starting installation")
|
||||||
|
|
||||||
cc.Logger.Debugf("Runinstall with cc: %s\n", litter.Sdump(cc))
|
cc.Logger.Debugf("Runinstall with cc: %s\n", litter.Sdump(cc))
|
||||||
if err := RunInstall(cc); err != nil {
|
if err := RunInstall(cc, sourceImg); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -213,7 +213,7 @@ func Install(dir ...string) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func RunInstall(c *config.Config) error {
|
func RunInstall(c *config.Config, sourceImg string) error {
|
||||||
utils.SetEnv(c.Env)
|
utils.SetEnv(c.Env)
|
||||||
utils.SetEnv(c.Install.Env)
|
utils.SetEnv(c.Install.Env)
|
||||||
|
|
||||||
@ -250,7 +250,28 @@ func RunInstall(c *config.Config) error {
|
|||||||
// Set our cloud-init to the file we just created
|
// Set our cloud-init to the file we just created
|
||||||
installSpec.CloudInit = append(installSpec.CloudInit, f.Name())
|
installSpec.CloudInit = append(installSpec.CloudInit, f.Name())
|
||||||
// Get the source of the installation if we are overriding it
|
// Get the source of the installation if we are overriding it
|
||||||
if c.Install.Image != "" {
|
if sourceImg != "" {
|
||||||
|
imgSource, err := v1.NewSrcFromURI(sourceImg)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
installSpec.Active.Source = imgSource
|
||||||
|
|
||||||
|
// TODO: Why only setting active source above? What about size?
|
||||||
|
// TODO: These 2 blocks are identical, DRY them.
|
||||||
|
|
||||||
|
// size, err := GetSourceSize(cfg, imgSource)
|
||||||
|
// if err != nil {
|
||||||
|
// c.Logger.Warnf("Failed to infer size for images: %s", err.Error())
|
||||||
|
// }
|
||||||
|
|
||||||
|
// installSpec.Active.Source = imgSource
|
||||||
|
// installSpec.Passive.Source = imgSource
|
||||||
|
// installSpec.Recovery.Source = imgSource
|
||||||
|
// installSpec.Active.Size = uint(size)
|
||||||
|
// installSpec.Passive.Size = uint(size)
|
||||||
|
// installSpec.Recovery.Size = uint(size)
|
||||||
|
} else if c.Install.Image != "" {
|
||||||
imgSource, err := v1.NewSrcFromURI(c.Install.Image)
|
imgSource, err := v1.NewSrcFromURI(c.Install.Image)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
@ -129,7 +129,7 @@ func detectDevice() string {
|
|||||||
return preferedDevice
|
return preferedDevice
|
||||||
}
|
}
|
||||||
|
|
||||||
func InteractiveInstall(debug, spawnShell bool) error {
|
func InteractiveInstall(debug, spawnShell bool, sourceImg string) error {
|
||||||
var sshUsers []string
|
var sshUsers []string
|
||||||
bus.Manager.Initialize()
|
bus.Manager.Initialize()
|
||||||
|
|
||||||
@ -229,7 +229,7 @@ func InteractiveInstall(debug, spawnShell bool) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if !isYes(allGood) {
|
if !isYes(allGood) {
|
||||||
return InteractiveInstall(debug, spawnShell)
|
return InteractiveInstall(debug, spawnShell, sourceImg)
|
||||||
}
|
}
|
||||||
|
|
||||||
usersToSet := map[string]schema.User{}
|
usersToSet := map[string]schema.User{}
|
||||||
@ -283,6 +283,7 @@ func InteractiveInstall(debug, spawnShell bool) error {
|
|||||||
fmt.Printf("could not write event cloud init: %s\n", err.Error())
|
fmt.Printf("could not write event cloud init: %s\n", err.Error())
|
||||||
}
|
}
|
||||||
// override cc with our new config object from the scan, so it's updated for the RunInstall function
|
// override cc with our new config object from the scan, so it's updated for the RunInstall function
|
||||||
|
// TODO: Alternative solution: pass a reader here (the new feature) and add the image source
|
||||||
cc, _ = config.Scan(collector.Directories(tmpdir), collector.MergeBootLine, collector.NoLogs)
|
cc, _ = config.Scan(collector.Directories(tmpdir), collector.MergeBootLine, collector.NoLogs)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -291,7 +292,7 @@ func InteractiveInstall(debug, spawnShell bool) error {
|
|||||||
ccString, _ := cc.String()
|
ccString, _ := cc.String()
|
||||||
pterm.Info.Println(ccString)
|
pterm.Info.Println(ccString)
|
||||||
|
|
||||||
err = RunInstall(cc)
|
err = RunInstall(cc, sourceImg)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
pterm.Error.Println(err.Error())
|
pterm.Error.Println(err.Error())
|
||||||
}
|
}
|
||||||
|
65
main.go
65
main.go
@ -110,15 +110,8 @@ See https://kairos.io/docs/upgrade/manual/ for documentation.
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
Before: func(c *cli.Context) error {
|
Before: func(c *cli.Context) error {
|
||||||
source := c.String("source")
|
if err := validateSource(c.String("source")); err != nil {
|
||||||
if source != "" {
|
return err
|
||||||
r, err := regexp.Compile(`^oci:|dir:|file:`)
|
|
||||||
if err != nil {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
if !r.MatchString(source) {
|
|
||||||
return fmt.Errorf("source %s does not match any of oci:, dir: or file: ", source)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return checkRoot()
|
return checkRoot()
|
||||||
@ -385,13 +378,23 @@ This command is meant to be used from the boot GRUB menu, but can be also starte
|
|||||||
&cli.BoolFlag{
|
&cli.BoolFlag{
|
||||||
Name: "shell",
|
Name: "shell",
|
||||||
},
|
},
|
||||||
|
&cli.StringFlag{
|
||||||
|
Name: "source",
|
||||||
|
Usage: "Source for upgrade. Composed of `type:address`. Accepts `file:`,`dir:` or `oci:` for the type of source.\nFor example `file:/var/share/myimage.tar`, `dir:/tmp/extracted` or `oci:repo/image:tag`",
|
||||||
|
},
|
||||||
},
|
},
|
||||||
Usage: "Starts interactive installation",
|
Usage: "Starts interactive installation",
|
||||||
Before: func(c *cli.Context) error {
|
Before: func(c *cli.Context) error {
|
||||||
|
if err := validateSource(c.String("source")); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
return checkRoot()
|
return checkRoot()
|
||||||
},
|
},
|
||||||
Action: func(c *cli.Context) error {
|
Action: func(c *cli.Context) error {
|
||||||
return agent.InteractiveInstall(c.Bool("debug"), c.Bool("shell"))
|
source := c.String("source")
|
||||||
|
|
||||||
|
return agent.InteractiveInstall(c.Bool("debug"), c.Bool("shell"), source)
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -410,8 +413,16 @@ This command is meant to be used from the boot GRUB menu, but can be also starte
|
|||||||
&cli.BoolFlag{
|
&cli.BoolFlag{
|
||||||
Name: "reboot",
|
Name: "reboot",
|
||||||
},
|
},
|
||||||
|
&cli.StringFlag{
|
||||||
|
Name: "source",
|
||||||
|
Usage: "Source for upgrade. Composed of `type:address`. Accepts `file:`,`dir:` or `oci:` for the type of source.\nFor example `file:/var/share/myimage.tar`, `dir:/tmp/extracted` or `oci:repo/image:tag`",
|
||||||
|
},
|
||||||
},
|
},
|
||||||
Before: func(c *cli.Context) error {
|
Before: func(c *cli.Context) error {
|
||||||
|
if err := validateSource(c.String("source")); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
return checkRoot()
|
return checkRoot()
|
||||||
},
|
},
|
||||||
Action: func(c *cli.Context) error {
|
Action: func(c *cli.Context) error {
|
||||||
@ -420,7 +431,9 @@ This command is meant to be used from the boot GRUB menu, but can be also starte
|
|||||||
}
|
}
|
||||||
config := c.Args().First()
|
config := c.Args().First()
|
||||||
|
|
||||||
return agent.ManualInstall(config, c.String("device"), c.Bool("reboot"), c.Bool("poweroff"), c.Bool("strict-validation"))
|
source := c.String("source")
|
||||||
|
|
||||||
|
return agent.ManualInstall(config, source, c.String("device"), c.Bool("reboot"), c.Bool("poweroff"), c.Bool("strict-validation"))
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -436,10 +449,22 @@ See also https://kairos.io/docs/installation/qrcode/ for documentation.
|
|||||||
This command is meant to be used from the boot GRUB menu, but can be started manually`,
|
This command is meant to be used from the boot GRUB menu, but can be started manually`,
|
||||||
Aliases: []string{"i"},
|
Aliases: []string{"i"},
|
||||||
Before: func(c *cli.Context) error {
|
Before: func(c *cli.Context) error {
|
||||||
|
if err := validateSource(c.String("source")); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
return checkRoot()
|
return checkRoot()
|
||||||
},
|
},
|
||||||
|
Flags: []cli.Flag{
|
||||||
|
&cli.StringFlag{
|
||||||
|
Name: "source",
|
||||||
|
Usage: "Source for upgrade. Composed of `type:address`. Accepts `file:`,`dir:` or `oci:` for the type of source.\nFor example `file:/var/share/myimage.tar`, `dir:/tmp/extracted` or `oci:repo/image:tag`",
|
||||||
|
},
|
||||||
|
},
|
||||||
Action: func(c *cli.Context) error {
|
Action: func(c *cli.Context) error {
|
||||||
return agent.Install(configScanDir...)
|
source := c.String("source")
|
||||||
|
|
||||||
|
return agent.Install(source, configScanDir...)
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -686,3 +711,19 @@ func checkRoot() error {
|
|||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func validateSource(source string) error {
|
||||||
|
if source == "" {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
r, err := regexp.Compile(`^oci:|dir:|file:`)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if !r.MatchString(source) {
|
||||||
|
return fmt.Errorf("source %s does not match any of oci:, dir: or file: ", source)
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user