diff --git a/lxc/snapshot.go b/lxc/snapshot.go index 2b3ccfff92a5..af8687ce3cd6 100644 --- a/lxc/snapshot.go +++ b/lxc/snapshot.go @@ -2,15 +2,19 @@ package main import ( "fmt" + "io" + "os" "strings" "time" "github.com/spf13/cobra" + "gopkg.in/yaml.v2" "github.com/canonical/lxd/shared" "github.com/canonical/lxd/shared/api" cli "github.com/canonical/lxd/shared/cmd" "github.com/canonical/lxd/shared/i18n" + "github.com/canonical/lxd/shared/termios" ) type cmdSnapshot struct { @@ -30,9 +34,11 @@ func (c *cmdSnapshot) command() *cobra.Command { When --stateful is used, LXD attempts to checkpoint the instance's running state, including process memory state, TCP connections, ...`)) - cmd.Example = cli.FormatSection("", i18n.G( - `lxc snapshot u1 snap0 - Create a snapshot of "u1" called "snap0".`)) + cmd.Example = cli.FormatSection("", i18n.G(`lxc snapshot create u1 snap0 + Create a snapshot of "u1" called "snap0". + + lxc snapshot create u1 snap0 < config.yaml + Create a snapshot of "u1" called "snap0" with the configuration from "config.yaml".`)) cmd.RunE = c.run cmd.Flags().BoolVar(&c.flagStateful, "stateful", false, i18n.G("Whether or not to snapshot the instance's running state")) @@ -43,6 +49,7 @@ running state, including process memory state, TCP connections, ...`)) } func (c *cmdSnapshot) run(cmd *cobra.Command, args []string) error { + var stdinData api.InstanceSnapshotPut conf := c.global.conf // Quick checks. @@ -51,6 +58,19 @@ func (c *cmdSnapshot) run(cmd *cobra.Command, args []string) error { return err } + // If stdin isn't a terminal, read text from it + if !termios.IsTerminal(getStdinFd()) { + contents, err := io.ReadAll(os.Stdin) + if err != nil { + return err + } + + err = yaml.Unmarshal(contents, &stdinData) + if err != nil { + return err + } + } + var snapname string if len(args) < 2 { snapname = "" @@ -98,6 +118,10 @@ func (c *cmdSnapshot) run(cmd *cobra.Command, args []string) error { Stateful: c.flagStateful, } + if !stdinData.ExpiresAt.IsZero() { + req.ExpiresAt = &stdinData.ExpiresAt + } + if c.flagNoExpiry { req.ExpiresAt = &time.Time{} }