github.com/StackPointCloud/packer@v0.10.2-0.20180716202532-b28098e0f79b/builder/lxc/step_lxc_create.go (about) 1 package lxc 2 3 import ( 4 "bytes" 5 "context" 6 "fmt" 7 "log" 8 "os/exec" 9 "path/filepath" 10 "strings" 11 12 "github.com/hashicorp/packer/helper/multistep" 13 "github.com/hashicorp/packer/packer" 14 ) 15 16 type stepLxcCreate struct{} 17 18 func (s *stepLxcCreate) Run(_ context.Context, state multistep.StateBag) multistep.StepAction { 19 config := state.Get("config").(*Config) 20 ui := state.Get("ui").(packer.Ui) 21 22 name := config.ContainerName 23 24 // TODO: read from env 25 lxc_dir := "/var/lib/lxc" 26 rootfs := filepath.Join(lxc_dir, name, "rootfs") 27 28 if config.PackerForce { 29 s.Cleanup(state) 30 } 31 32 commands := make([][]string, 3) 33 commands[0] = append(config.EnvVars, "lxc-create") 34 commands[0] = append(commands[0], config.CreateOptions...) 35 commands[0] = append(commands[0], []string{"-n", name, "-t", config.Name, "--"}...) 36 commands[0] = append(commands[0], config.Parameters...) 37 // prevent tmp from being cleaned on boot, we put provisioning scripts there 38 // todo: wait for init to finish before moving on to provisioning instead of this 39 commands[1] = []string{"touch", filepath.Join(rootfs, "tmp", ".tmpfs")} 40 commands[2] = append([]string{"lxc-start"}, config.StartOptions...) 41 commands[2] = append(commands[2], []string{"-d", "--name", name}...) 42 43 ui.Say("Creating container...") 44 for _, command := range commands { 45 log.Printf("Executing sudo command: %#v", command) 46 err := s.SudoCommand(command...) 47 if err != nil { 48 err := fmt.Errorf("Error creating container: %s", err) 49 state.Put("error", err) 50 ui.Error(err.Error()) 51 return multistep.ActionHalt 52 } 53 } 54 55 state.Put("mount_path", rootfs) 56 57 return multistep.ActionContinue 58 } 59 60 func (s *stepLxcCreate) Cleanup(state multistep.StateBag) { 61 config := state.Get("config").(*Config) 62 ui := state.Get("ui").(packer.Ui) 63 64 command := []string{ 65 "lxc-destroy", "-f", "-n", config.ContainerName, 66 } 67 68 ui.Say("Unregistering and deleting virtual machine...") 69 if err := s.SudoCommand(command...); err != nil { 70 ui.Error(fmt.Sprintf("Error deleting virtual machine: %s", err)) 71 } 72 } 73 74 func (s *stepLxcCreate) SudoCommand(args ...string) error { 75 var stdout, stderr bytes.Buffer 76 77 log.Printf("Executing sudo command: %#v", args) 78 cmd := exec.Command("sudo", args...) 79 cmd.Stdout = &stdout 80 cmd.Stderr = &stderr 81 err := cmd.Run() 82 83 stdoutString := strings.TrimSpace(stdout.String()) 84 stderrString := strings.TrimSpace(stderr.String()) 85 86 if _, ok := err.(*exec.ExitError); ok { 87 err = fmt.Errorf("Sudo command error: %s", stderrString) 88 } 89 90 log.Printf("stdout: %s", stdoutString) 91 log.Printf("stderr: %s", stderrString) 92 93 return err 94 }