commit
ff64ccda55
|
@ -105,6 +105,21 @@ func (c *Communicator) uploadReader(dst string, src io.Reader) error {
|
|||
|
||||
// uploadFile uses docker cp to copy the file from the host to the container
|
||||
func (c *Communicator) uploadFile(dst string, src io.Reader, fi *os.FileInfo) error {
|
||||
// find out if it's a directory
|
||||
testDirectoryCommand := fmt.Sprintf(`test -d "%s"`, dst)
|
||||
cmd := &packer.RemoteCmd{Command: testDirectoryCommand}
|
||||
|
||||
err := c.Start(cmd)
|
||||
|
||||
if err != nil {
|
||||
log.Printf("Unable to check whether remote path is a dir: %s", err)
|
||||
return err
|
||||
}
|
||||
cmd.Wait()
|
||||
if cmd.ExitStatus == 0 {
|
||||
log.Printf("path is a directory; copying file into directory.")
|
||||
dst = filepath.Join(dst, filepath.Base((*fi).Name()))
|
||||
}
|
||||
|
||||
// command format: docker cp /path/to/infile containerid:/path/to/outfile
|
||||
log.Printf("Copying to %s on container %s.", dst, c.ContainerID)
|
||||
|
|
|
@ -73,6 +73,24 @@ func (c *LxcAttachCommunicator) Upload(dst string, r io.Reader, fi *os.FileInfo)
|
|||
return err
|
||||
}
|
||||
|
||||
if fi != nil {
|
||||
tfDir := filepath.Dir(tf.Name())
|
||||
// rename tempfile to match original file name. This makes sure that if file is being
|
||||
// moved into a directory, the filename is preserved instead of a temp name.
|
||||
adjustedTempName := filepath.Join(tfDir, (*fi).Name())
|
||||
mvCmd, err := c.CmdWrapper(fmt.Sprintf("sudo mv %s %s", tf.Name(), adjustedTempName))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer os.Remove(adjustedTempName)
|
||||
ShellCommand(mvCmd).Run()
|
||||
// change cpCmd to use new file name as source
|
||||
cpCmd, err = c.CmdWrapper(fmt.Sprintf("sudo cp %s %s", adjustedTempName, dst))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
log.Printf("Running copy command: %s", dst)
|
||||
|
||||
return ShellCommand(cpCmd).Run()
|
||||
|
|
|
@ -55,7 +55,24 @@ func (c *Communicator) Start(cmd *packer.RemoteCmd) error {
|
|||
}
|
||||
|
||||
func (c *Communicator) Upload(dst string, r io.Reader, fi *os.FileInfo) error {
|
||||
cpCmd, err := c.CmdWrapper(fmt.Sprintf("lxc file push - %s", filepath.Join(c.ContainerName, dst)))
|
||||
fileDestination := filepath.Join(c.ContainerName, dst)
|
||||
// find out if the place we are pushing to is a directory
|
||||
testDirectoryCommand := fmt.Sprintf(`test -d "%s"`, dst)
|
||||
cmd := &packer.RemoteCmd{Command: testDirectoryCommand}
|
||||
err := c.Start(cmd)
|
||||
|
||||
if err != nil {
|
||||
log.Printf("Unable to check whether remote path is a dir: %s", err)
|
||||
return err
|
||||
}
|
||||
cmd.Wait()
|
||||
|
||||
if cmd.ExitStatus == 0 {
|
||||
log.Printf("path is a directory; copying file into directory.")
|
||||
fileDestination = filepath.Join(c.ContainerName, dst, (*fi).Name())
|
||||
}
|
||||
|
||||
cpCmd, err := c.CmdWrapper(fmt.Sprintf("lxc file push - %s", fileDestination))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
|
|
@ -402,15 +402,31 @@ func (c *comm) connectToAgent() {
|
|||
|
||||
func (c *comm) sftpUploadSession(path string, input io.Reader, fi *os.FileInfo) error {
|
||||
sftpFunc := func(client *sftp.Client) error {
|
||||
return sftpUploadFile(path, input, client, fi)
|
||||
return c.sftpUploadFile(path, input, client, fi)
|
||||
}
|
||||
|
||||
return c.sftpSession(sftpFunc)
|
||||
}
|
||||
|
||||
func sftpUploadFile(path string, input io.Reader, client *sftp.Client, fi *os.FileInfo) error {
|
||||
func (c *comm) sftpUploadFile(path string, input io.Reader, client *sftp.Client, fi *os.FileInfo) error {
|
||||
log.Printf("[DEBUG] sftp: uploading %s", path)
|
||||
|
||||
// find out if destination is a directory (this is to replicate rsync behavior)
|
||||
testDirectoryCommand := fmt.Sprintf(`test -d "%s"`, path)
|
||||
cmd := &packer.RemoteCmd{Command: testDirectoryCommand}
|
||||
|
||||
err := c.Start(cmd)
|
||||
|
||||
if err != nil {
|
||||
log.Printf("Unable to check whether remote path is a dir: %s", err)
|
||||
return err
|
||||
}
|
||||
cmd.Wait()
|
||||
if cmd.ExitStatus == 0 {
|
||||
log.Printf("path is a directory; copying file into directory.")
|
||||
path = filepath.Join(path, filepath.Base((*fi).Name()))
|
||||
}
|
||||
|
||||
f, err := client.Create(path)
|
||||
if err != nil {
|
||||
return err
|
||||
|
@ -461,7 +477,7 @@ func (c *comm) sftpUploadDirSession(dst string, src string, excl []string) error
|
|||
return nil
|
||||
}
|
||||
|
||||
return sftpVisitFile(finalDst, path, info, client)
|
||||
return c.sftpVisitFile(finalDst, path, info, client)
|
||||
}
|
||||
|
||||
return filepath.Walk(src, walkFunc)
|
||||
|
@ -470,7 +486,7 @@ func (c *comm) sftpUploadDirSession(dst string, src string, excl []string) error
|
|||
return c.sftpSession(sftpFunc)
|
||||
}
|
||||
|
||||
func sftpMkdir(path string, client *sftp.Client, fi os.FileInfo) error {
|
||||
func (c *comm) sftpMkdir(path string, client *sftp.Client, fi os.FileInfo) error {
|
||||
log.Printf("[DEBUG] sftp: creating dir %s", path)
|
||||
|
||||
if err := client.Mkdir(path); err != nil {
|
||||
|
@ -488,16 +504,16 @@ func sftpMkdir(path string, client *sftp.Client, fi os.FileInfo) error {
|
|||
return nil
|
||||
}
|
||||
|
||||
func sftpVisitFile(dst string, src string, fi os.FileInfo, client *sftp.Client) error {
|
||||
func (c *comm) sftpVisitFile(dst string, src string, fi os.FileInfo, client *sftp.Client) error {
|
||||
if !fi.IsDir() {
|
||||
f, err := os.Open(src)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer f.Close()
|
||||
return sftpUploadFile(dst, f, client, &fi)
|
||||
return c.sftpUploadFile(dst, f, client, &fi)
|
||||
} else {
|
||||
err := sftpMkdir(dst, client, fi)
|
||||
err := c.sftpMkdir(dst, client, fi)
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
@ -558,6 +574,23 @@ func (c *comm) scpUploadSession(path string, input io.Reader, fi *os.FileInfo) e
|
|||
target_dir := filepath.Dir(path)
|
||||
target_file := filepath.Base(path)
|
||||
|
||||
// find out if destination is a directory (this is to replicate rsync behavior)
|
||||
testDirectoryCommand := fmt.Sprintf(`test -d "%s"`, path)
|
||||
cmd := &packer.RemoteCmd{Command: testDirectoryCommand}
|
||||
|
||||
err := c.Start(cmd)
|
||||
|
||||
if err != nil {
|
||||
log.Printf("Unable to check whether remote path is a dir: %s", err)
|
||||
return err
|
||||
}
|
||||
cmd.Wait()
|
||||
if cmd.ExitStatus == 0 {
|
||||
log.Printf("path is a directory; copying file into directory.")
|
||||
target_dir = path
|
||||
target_file = filepath.Base((*fi).Name())
|
||||
}
|
||||
|
||||
// On windows, filepath.Dir uses backslash seperators (ie. "\tmp").
|
||||
// This does not work when the target host is unix. Switch to forward slash
|
||||
// which works for unix and windows
|
||||
|
|
|
@ -122,11 +122,28 @@ func runCommand(shell *winrm.Shell, cmd *winrm.Command, rc *packer.RemoteCmd) {
|
|||
}
|
||||
|
||||
// Upload implementation of communicator.Communicator interface
|
||||
func (c *Communicator) Upload(path string, input io.Reader, _ *os.FileInfo) error {
|
||||
func (c *Communicator) Upload(path string, input io.Reader, fi *os.FileInfo) error {
|
||||
wcp, err := c.newCopyClient()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Get information about destination path
|
||||
endpoint := winrm.NewEndpoint(c.endpoint.Host, c.endpoint.Port, c.config.Https, c.config.Insecure, nil, nil, nil, c.config.Timeout)
|
||||
client, err := winrm.NewClient(endpoint, c.config.Username, c.config.Password)
|
||||
if err != nil {
|
||||
return fmt.Errorf("Was unable to create winrm client: %s", err)
|
||||
}
|
||||
stdout, _, _, err := client.RunWithString(fmt.Sprintf("powershell -Command \"(Get-Item %s) -is [System.IO.DirectoryInfo]\"", path), "")
|
||||
if err != nil {
|
||||
return fmt.Errorf("Couldn't determine whether destination was a folder or file: %s", err)
|
||||
}
|
||||
if strings.Contains(stdout, "True") {
|
||||
// The path exists and is a directory.
|
||||
// Upload file into the directory instead of overwriting.
|
||||
path = filepath.Join(path, filepath.Base((*fi).Name()))
|
||||
}
|
||||
|
||||
log.Printf("Uploading file to '%s'", path)
|
||||
return wcp.Write(path, input)
|
||||
}
|
||||
|
|
|
@ -48,6 +48,12 @@ func newMockWinRMServer(t *testing.T) *winrmtest.Remote {
|
|||
func(out, err io.Writer) int {
|
||||
return 0
|
||||
})
|
||||
wrm.CommandFunc(
|
||||
winrmtest.MatchText(`powershell -Command "(Get-Item C:/Temp/packer.cmd) -is [System.IO.DirectoryInfo]"`),
|
||||
func(out, err io.Writer) int {
|
||||
out.Write([]byte("False"))
|
||||
return 0
|
||||
})
|
||||
|
||||
return wrm
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue