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