stop container before committing if windows
This commit is contained in:
parent
8f3313d81e
commit
3b87f2a519
|
@ -38,7 +38,7 @@ type Config struct {
|
|||
RunCommand []string `mapstructure:"run_command"`
|
||||
Volumes map[string]string
|
||||
FixUploadOwner bool `mapstructure:"fix_upload_owner"`
|
||||
WindowsContainer bool `windows_container`
|
||||
WindowsContainer bool `mapstructure:"windows_container"`
|
||||
|
||||
// This is used to login to dockerhub to pull a private base container. For
|
||||
// pushing to dockerhub, see the docker post-processors
|
||||
|
|
|
@ -46,7 +46,10 @@ type Driver interface {
|
|||
// along with a potential error.
|
||||
StartContainer(*ContainerConfig) (string, error)
|
||||
|
||||
// StopContainer forcibly stops a container.
|
||||
// KillContainer forcibly stops a container.
|
||||
KillContainer(id string) error
|
||||
|
||||
// StopContainer gently stops a container.
|
||||
StopContainer(id string) error
|
||||
|
||||
// TagImage tags the image with the given ID
|
||||
|
|
|
@ -314,6 +314,13 @@ func (d *DockerDriver) StartContainer(config *ContainerConfig) (string, error) {
|
|||
}
|
||||
|
||||
func (d *DockerDriver) StopContainer(id string) error {
|
||||
if err := exec.Command("docker", "stop", id).Run(); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (d *DockerDriver) KillContainer(id string) error {
|
||||
if err := exec.Command("docker", "kill", id).Run(); err != nil {
|
||||
return err
|
||||
}
|
||||
|
|
|
@ -19,6 +19,16 @@ func (s *StepCommit) Run(_ context.Context, state multistep.StateBag) multistep.
|
|||
config := state.Get("config").(*Config)
|
||||
ui := state.Get("ui").(packer.Ui)
|
||||
|
||||
if config.WindowsContainer {
|
||||
// docker can't commit a running Windows container
|
||||
err := driver.StopContainer(containerId)
|
||||
if err != nil {
|
||||
state.Put("error", err)
|
||||
ui.Error(fmt.Sprintf("Error halting windows container for commit: %s",
|
||||
err.Error()))
|
||||
return multistep.ActionHalt
|
||||
}
|
||||
}
|
||||
ui.Say("Committing the container")
|
||||
imageId, err := driver.Commit(containerId, config.Author, config.Changes, config.Message)
|
||||
if err != nil {
|
||||
|
|
|
@ -32,16 +32,28 @@ func (s *StepConnectDocker) Run(_ context.Context, state multistep.StateBag) mul
|
|||
|
||||
// Create the communicator that talks to Docker via various
|
||||
// os/exec tricks.
|
||||
comm := &Communicator{
|
||||
ContainerID: containerId,
|
||||
HostDir: tempDir,
|
||||
ContainerDir: config.ContainerDir,
|
||||
Version: version,
|
||||
Config: config,
|
||||
ContainerUser: containerUser,
|
||||
}
|
||||
if config.WindowsContainer {
|
||||
comm := &WindowsContainerCommunicator{
|
||||
ContainerID: containerId,
|
||||
HostDir: tempDir,
|
||||
ContainerDir: config.ContainerDir,
|
||||
Version: version,
|
||||
Config: config,
|
||||
ContainerUser: containerUser,
|
||||
}
|
||||
state.Put("communicator", comm)
|
||||
|
||||
state.Put("communicator", comm)
|
||||
} else {
|
||||
comm := &Communicator{
|
||||
ContainerID: containerId,
|
||||
HostDir: tempDir,
|
||||
ContainerDir: config.ContainerDir,
|
||||
Version: version,
|
||||
Config: config,
|
||||
ContainerUser: containerUser,
|
||||
}
|
||||
state.Put("communicator", comm)
|
||||
}
|
||||
return multistep.ActionContinue
|
||||
}
|
||||
|
||||
|
|
|
@ -58,7 +58,7 @@ func (s *StepRun) Cleanup(state multistep.StateBag) {
|
|||
// just mean that the container doesn't exist anymore, which isn't a
|
||||
// big deal.
|
||||
ui.Say(fmt.Sprintf("Killing the container: %s", s.containerId))
|
||||
driver.StopContainer(s.containerId)
|
||||
driver.KillContainer(s.containerId)
|
||||
|
||||
// Reset the container ID so that we're idempotent
|
||||
s.containerId = ""
|
||||
|
|
|
@ -260,63 +260,6 @@ func (c *WindowsContainerCommunicator) uploadFileOld(dst string, src io.Reader,
|
|||
return nil
|
||||
}
|
||||
|
||||
func (c *WindowsContainerCommunicator) UploadDir(dst string, src string, exclude []string) error {
|
||||
/*
|
||||
from https://docs.docker.com/engine/reference/commandline/cp/#extended-description
|
||||
SRC_PATH specifies a directory
|
||||
DEST_PATH does not exist
|
||||
DEST_PATH is created as a directory and the contents of the source directory are copied into this directory
|
||||
DEST_PATH exists and is a file
|
||||
Error condition: cannot copy a directory to a file
|
||||
DEST_PATH exists and is a directory
|
||||
SRC_PATH does not end with /. (that is: slash followed by dot)
|
||||
the source directory is copied into this directory
|
||||
SRC_PATH does end with /. (that is: slash followed by dot)
|
||||
the content of the source directory is copied into this directory
|
||||
|
||||
translating that in to our semantics:
|
||||
|
||||
if source ends in /
|
||||
docker cp src. dest
|
||||
otherwise, cp source dest
|
||||
|
||||
*/
|
||||
|
||||
var dockerSource string
|
||||
|
||||
if src[len(src)-1] == '/' {
|
||||
dockerSource = fmt.Sprintf("%s.", src)
|
||||
} else {
|
||||
dockerSource = fmt.Sprintf("%s", src)
|
||||
}
|
||||
|
||||
// Make the directory, then copy into it
|
||||
localCmd := exec.Command("docker", "cp", dockerSource, fmt.Sprintf("%s:%s", c.ContainerID, dst))
|
||||
|
||||
stderrP, err := localCmd.StderrPipe()
|
||||
if err != nil {
|
||||
return fmt.Errorf("Failed to open pipe: %s", err)
|
||||
}
|
||||
if err := localCmd.Start(); err != nil {
|
||||
return fmt.Errorf("Failed to copy: %s", err)
|
||||
}
|
||||
stderrOut, err := ioutil.ReadAll(stderrP)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Wait for the copy to complete
|
||||
if err := localCmd.Wait(); err != nil {
|
||||
return fmt.Errorf("Failed to upload to '%s' in container: %s. %s.", dst, stderrOut, err)
|
||||
}
|
||||
|
||||
if err := c.fixDestinationOwner(dst); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// Download pulls a file out of a container using `docker cp`. We have a source
|
||||
// path and want to write to an io.Writer, not a file. We use - to make docker
|
||||
// cp to write to stdout, and then copy the stream to our destination io.Writer.
|
||||
|
|
Loading…
Reference in New Issue