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  }