diff --git a/builder/amazon/chroot/builder.go b/builder/amazon/chroot/builder.go index 1bb00eaa3..0e2b098de 100644 --- a/builder/amazon/chroot/builder.go +++ b/builder/amazon/chroot/builder.go @@ -26,6 +26,7 @@ type Config struct { AttachedDevicePath string `mapstructure:"attached_device_path"` ChrootMounts [][]string `mapstructure:"chroot_mounts"` + CopyFiles []string `mapstructure:"copy_files"` DevicePath string `mapstructure:"device_path"` MountCommand string `mapstructure:"mount_command"` MountPath string `mapstructure:"mount_path"` @@ -49,6 +50,10 @@ func (b *Builder) Prepare(raws ...interface{}) error { b.config.ChrootMounts = make([][]string, 0) } + if b.config.CopyFiles == nil { + b.config.CopyFiles = make([]string, 0) + } + if len(b.config.ChrootMounts) == 0 { b.config.ChrootMounts = [][]string{ []string{"proc", "proc", "/proc"}, @@ -59,6 +64,10 @@ func (b *Builder) Prepare(raws ...interface{}) error { } } + if len(b.config.CopyFiles) == 0 { + b.config.CopyFiles = []string{"/etc/resolv.conf"} + } + if b.config.DevicePath == "" { b.config.DevicePath = "/dev/sdh" } @@ -127,6 +136,7 @@ func (b *Builder) Run(ui packer.Ui, hook packer.Hook, cache packer.Cache) (packe &StepAttachVolume{}, &StepMountDevice{}, &StepMountExtra{}, + &StepCopyFiles{}, &StepChrootProvision{}, } diff --git a/builder/amazon/chroot/step_copy_files.go b/builder/amazon/chroot/step_copy_files.go new file mode 100644 index 000000000..05f523c13 --- /dev/null +++ b/builder/amazon/chroot/step_copy_files.go @@ -0,0 +1,70 @@ +package chroot + +import ( + "fmt" + "github.com/mitchellh/multistep" + "github.com/mitchellh/packer/packer" + "io" + "log" + "os" + "path/filepath" +) + +// StepCopyFiles copies some files from the host into the chroot environment. +type StepCopyFiles struct { + mounts []string +} + +func (s *StepCopyFiles) Run(state map[string]interface{}) multistep.StepAction { + config := state["config"].(*Config) + mountPath := state["mount_path"].(string) + ui := state["ui"].(packer.Ui) + + if len(config.CopyFiles) > 0 { + ui.Say("Copying files from host to chroot...") + for _, path := range config.CopyFiles { + ui.Message(path) + chrootPath := filepath.Join(mountPath, path) + log.Printf("Copying '%s' to '%s'", path, chrootPath) + + if err := s.copySingle(chrootPath, path); err != nil { + err := fmt.Errorf("Error copying file: %s", err) + state["error"] = err + ui.Error(err.Error()) + return multistep.ActionHalt + } + } + } + + return multistep.ActionContinue +} + +func (s *StepCopyFiles) Cleanup(state map[string]interface{}) {} + +func (s *StepCopyFiles) copySingle(dst, src string) error { + srcInfo, err := os.Stat(src) + if err != nil { + return err + } + + srcF, err := os.Open(src) + if err != nil { + return err + } + defer srcF.Close() + + dstF, err := os.Create(dst) + if err != nil { + return err + } + + if _, err := io.Copy(dstF, srcF); err != nil { + return err + } + + if err := os.Chmod(dst, srcInfo.Mode()); err != nil { + return err + } + + return nil +}