github.com/phobos182/packer@v0.2.3-0.20130819023704-c84d2aeffc68/builder/amazon/chroot/communicator.go (about) 1 package chroot 2 3 import ( 4 "github.com/mitchellh/packer/packer" 5 "io" 6 "log" 7 "os" 8 "os/exec" 9 "path/filepath" 10 "syscall" 11 ) 12 13 // Communicator is a special communicator that works by executing 14 // commands locally but within a chroot. 15 type Communicator struct { 16 Chroot string 17 } 18 19 func (c *Communicator) Start(cmd *packer.RemoteCmd) error { 20 chrootCmdPath, err := exec.LookPath("chroot") 21 if err != nil { 22 return err 23 } 24 25 localCmd := exec.Command(chrootCmdPath, c.Chroot, "/bin/sh", "-c", cmd.Command) 26 localCmd.Stdin = cmd.Stdin 27 localCmd.Stdout = cmd.Stdout 28 localCmd.Stderr = cmd.Stderr 29 log.Printf("Executing: %s %#v", localCmd.Path, localCmd.Args) 30 if err := localCmd.Start(); err != nil { 31 return err 32 } 33 34 go func() { 35 exitStatus := 0 36 if err := localCmd.Wait(); err != nil { 37 if exitErr, ok := err.(*exec.ExitError); ok { 38 exitStatus = 1 39 40 // There is no process-independent way to get the REAL 41 // exit status so we just try to go deeper. 42 if status, ok := exitErr.Sys().(syscall.WaitStatus); ok { 43 exitStatus = status.ExitStatus() 44 } 45 } 46 } 47 48 log.Printf( 49 "Chroot executation ended with '%d': '%s'", 50 exitStatus, cmd.Command) 51 cmd.SetExited(exitStatus) 52 }() 53 54 return nil 55 } 56 57 func (c *Communicator) Upload(dst string, r io.Reader) error { 58 dst = filepath.Join(c.Chroot, dst) 59 log.Printf("Uploading to chroot dir: %s", dst) 60 f, err := os.Create(dst) 61 if err != nil { 62 return err 63 } 64 defer f.Close() 65 66 if _, err := io.Copy(f, r); err != nil { 67 return err 68 } 69 70 return nil 71 } 72 73 func (c *Communicator) Download(src string, w io.Writer) error { 74 src = filepath.Join(c.Chroot, src) 75 log.Printf("Downloading from chroot dir: %s", src) 76 f, err := os.Open(src) 77 if err != nil { 78 return err 79 } 80 defer f.Close() 81 82 if _, err := io.Copy(w, f); err != nil { 83 return err 84 } 85 86 return nil 87 }