From e29f06fe1c3639254cd55f49c072fe8d8cb3d372 Mon Sep 17 00:00:00 2001 From: Chris Lundquist Date: Sun, 7 Aug 2016 03:25:57 +0000 Subject: [PATCH] [lxd] refactor commands to dry things up --- builder/lxd/command.go | 28 +++++++++++++++++++ builder/lxd/communicator.go | 2 +- builder/lxd/step_lxd_launch.go | 51 ++++++++-------------------------- builder/lxd/step_provision.go | 2 +- builder/lxd/step_publish.go | 23 ++------------- 5 files changed, 44 insertions(+), 62 deletions(-) diff --git a/builder/lxd/command.go b/builder/lxd/command.go index a432e0bba..c9a39279d 100644 --- a/builder/lxd/command.go +++ b/builder/lxd/command.go @@ -1,7 +1,11 @@ package lxd import ( + "bytes" + "fmt" + "log" "os/exec" + "strings" ) // CommandWrapper is a type that given a command, will possibly modify that @@ -13,3 +17,27 @@ type CommandWrapper func(string) (string, error) func ShellCommand(command string) *exec.Cmd { return exec.Command("/bin/sh", "-c", command) } + +// Yeah...LXD calls `lxc` because the command line is different between the +// packages. This should also avoid a naming collision between the LXC builder. +func LXDCommand(args ...string) (string, error) { + var stdout, stderr bytes.Buffer + + log.Printf("Executing lxc command: %#v", args) + cmd := exec.Command("lxc", args...) + cmd.Stdout = &stdout + cmd.Stderr = &stderr + err := cmd.Run() + + stdoutString := strings.TrimSpace(stdout.String()) + stderrString := strings.TrimSpace(stderr.String()) + + if _, ok := err.(*exec.ExitError); ok { + err = fmt.Errorf("LXD command error: %s", stderrString) + } + + log.Printf("stdout: %s", stdoutString) + log.Printf("stderr: %s", stderrString) + + return stdoutString, err +} diff --git a/builder/lxd/communicator.go b/builder/lxd/communicator.go index 16f4d35eb..3df1cf8bc 100644 --- a/builder/lxd/communicator.go +++ b/builder/lxd/communicator.go @@ -128,7 +128,7 @@ func (c *Communicator) DownloadDir(src string, dst string, exclude []string) err func (c *Communicator) Execute(commandString string) (*exec.Cmd, error) { log.Printf("Executing with lxc exec in container: %s %s", c.ContainerName, commandString) command, err := c.CmdWrapper( - fmt.Sprintf("sudo lxc exec %s -- /bin/sh -c \"%s\"", c.ContainerName, commandString)) + fmt.Sprintf("lxc exec %s -- /bin/sh -c \"%s\"", c.ContainerName, commandString)) if err != nil { return nil, err } diff --git a/builder/lxd/step_lxd_launch.go b/builder/lxd/step_lxd_launch.go index 44a52b0b9..0cc0b80ac 100644 --- a/builder/lxd/step_lxd_launch.go +++ b/builder/lxd/step_lxd_launch.go @@ -1,13 +1,9 @@ package lxd import ( - "bytes" "fmt" "github.com/mitchellh/multistep" "github.com/mitchellh/packer/packer" - "log" - "os/exec" - "strings" "time" ) @@ -20,20 +16,17 @@ func (s *stepLxdLaunch) Run(state multistep.StateBag) multistep.StepAction { name := config.ContainerName image := config.Image - commands := [][]string{ - {"lxc", "launch", image, name}, + args := []string{ + "launch", image, name, } ui.Say("Creating container...") - for _, command := range commands { - log.Printf("Executing sudo command: %#v", command) - err := s.SudoCommand(command...) - if err != nil { - err := fmt.Errorf("Error creating container: %s", err) - state.Put("error", err) - ui.Error(err.Error()) - return multistep.ActionHalt - } + _, err := LXDCommand(args...) + if err != nil { + err := fmt.Errorf("Error creating container: %s", err) + state.Put("error", err) + ui.Error(err.Error()) + return multistep.ActionHalt } // TODO: Should we check `lxc info ` for "Running"? // We have to do this so /tmp doens't get cleared and lose our provisioner scripts. @@ -46,34 +39,12 @@ func (s *stepLxdLaunch) Cleanup(state multistep.StateBag) { config := state.Get("config").(*Config) ui := state.Get("ui").(packer.Ui) - command := []string{ - "lxc", "delete", "--force", config.ContainerName, + args := []string{ + "delete", "--force", config.ContainerName, } ui.Say("Unregistering and deleting deleting container...") - if err := s.SudoCommand(command...); err != nil { + if _, err := LXDCommand(args...); err != nil { ui.Error(fmt.Sprintf("Error deleting container: %s", err)) } } - -func (s *stepLxdLaunch) SudoCommand(args ...string) error { - var stdout, stderr bytes.Buffer - - log.Printf("Executing sudo command: %#v", args) - cmd := exec.Command("sudo", args...) - cmd.Stdout = &stdout - cmd.Stderr = &stderr - err := cmd.Run() - - stdoutString := strings.TrimSpace(stdout.String()) - stderrString := strings.TrimSpace(stderr.String()) - - if _, ok := err.(*exec.ExitError); ok { - err = fmt.Errorf("Sudo command error: %s", stderrString) - } - - log.Printf("stdout: %s", stdoutString) - log.Printf("stderr: %s", stderrString) - - return err -} diff --git a/builder/lxd/step_provision.go b/builder/lxd/step_provision.go index 21356fb59..584d61659 100644 --- a/builder/lxd/step_provision.go +++ b/builder/lxd/step_provision.go @@ -6,7 +6,7 @@ import ( "log" ) -// StepProvision provisions the instance within a chroot. +// StepProvision provisions the container type StepProvision struct{} func (s *StepProvision) Run(state multistep.StateBag) multistep.StepAction { diff --git a/builder/lxd/step_publish.go b/builder/lxd/step_publish.go index e519a7252..cf3c98bb3 100644 --- a/builder/lxd/step_publish.go +++ b/builder/lxd/step_publish.go @@ -1,20 +1,15 @@ package lxd import ( - "bytes" "fmt" "github.com/mitchellh/multistep" "github.com/mitchellh/packer/packer" - "log" - "os/exec" "regexp" - "strings" ) type stepPublish struct{} func (s *stepPublish) Run(state multistep.StateBag) multistep.StepAction { - var stdout, stderr bytes.Buffer config := state.Get("config").(*Config) ui := state.Get("ui").(packer.Ui) @@ -23,25 +18,13 @@ func (s *stepPublish) Run(state multistep.StateBag) multistep.StepAction { args := []string{ // If we use `lxc stop `, an ephemeral container would die forever. // `lxc publish` has special logic to handle this case. - "lxc", "publish", "--force", name, "--alias", config.OutputImage, + "publish", "--force", name, "--alias", config.OutputImage, } ui.Say("Publishing container...") - cmd := exec.Command("sudo", args...) - cmd.Stdout = &stdout - cmd.Stderr = &stderr - err := cmd.Run() - stdoutString := strings.TrimSpace(stdout.String()) - stderrString := strings.TrimSpace(stderr.String()) - - if _, ok := err.(*exec.ExitError); ok { - err = fmt.Errorf("Sudo command error: %s", stderrString) - } - - log.Printf("stdout: %s", stdoutString) - log.Printf("stderr: %s", stderrString) - + stdoutString, err := LXDCommand(args...) if err != nil { + err := fmt.Errorf("Error publishing container: %s", err) state.Put("error", err) ui.Error(err.Error()) return multistep.ActionHalt