github.com/mmcquillan/packer@v1.1.1-0.20171009221028-c85cf0483a5d/builder/lxc/step_export.go (about) 1 package lxc 2 3 import ( 4 "bytes" 5 "fmt" 6 "github.com/hashicorp/packer/packer" 7 "github.com/mitchellh/multistep" 8 "io" 9 "log" 10 "os" 11 "os/exec" 12 "path/filepath" 13 "strings" 14 ) 15 16 type stepExport struct{} 17 18 func (s *stepExport) Run(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 containerDir := fmt.Sprintf("/var/lib/lxc/%s", name) 25 outputPath := filepath.Join(config.OutputDir, "rootfs.tar.gz") 26 configFilePath := filepath.Join(config.OutputDir, "lxc-config") 27 28 configFile, err := os.Create(configFilePath) 29 30 if err != nil { 31 err := fmt.Errorf("Error creating config file: %s", err) 32 state.Put("error", err) 33 ui.Error(err.Error()) 34 return multistep.ActionHalt 35 } 36 37 originalConfigFile, err := os.Open(config.ConfigFile) 38 39 if err != nil { 40 err := fmt.Errorf("Error opening config file: %s", err) 41 state.Put("error", err) 42 ui.Error(err.Error()) 43 return multistep.ActionHalt 44 } 45 46 _, err = io.Copy(configFile, originalConfigFile) 47 48 commands := make([][]string, 4) 49 commands[0] = []string{ 50 "lxc-stop", "--name", name, 51 } 52 commands[1] = []string{ 53 "tar", "-C", containerDir, "--numeric-owner", "--anchored", "--exclude=./rootfs/dev/log", "-czf", outputPath, "./rootfs", 54 } 55 commands[2] = []string{ 56 "chmod", "+x", configFilePath, 57 } 58 commands[3] = []string{ 59 "sh", "-c", "chown $USER:`id -gn` " + filepath.Join(config.OutputDir, "*"), 60 } 61 62 ui.Say("Exporting container...") 63 for _, command := range commands { 64 err := s.SudoCommand(command...) 65 if err != nil { 66 err := fmt.Errorf("Error exporting container: %s", err) 67 state.Put("error", err) 68 ui.Error(err.Error()) 69 return multistep.ActionHalt 70 } 71 } 72 73 return multistep.ActionContinue 74 } 75 76 func (s *stepExport) Cleanup(state multistep.StateBag) {} 77 78 func (s *stepExport) SudoCommand(args ...string) error { 79 var stdout, stderr bytes.Buffer 80 81 log.Printf("Executing sudo command: %#v", args) 82 cmd := exec.Command("sudo", args...) 83 cmd.Stdout = &stdout 84 cmd.Stderr = &stderr 85 err := cmd.Run() 86 87 stdoutString := strings.TrimSpace(stdout.String()) 88 stderrString := strings.TrimSpace(stderr.String()) 89 90 if _, ok := err.(*exec.ExitError); ok { 91 err = fmt.Errorf("Sudo command error: %s", stderrString) 92 } 93 94 log.Printf("stdout: %s", stdoutString) 95 log.Printf("stderr: %s", stderrString) 96 97 return err 98 }