github.com/sneal/packer@v0.5.2/builder/amazon/chroot/step_mount_extra.go (about) 1 package chroot 2 3 import ( 4 "bytes" 5 "fmt" 6 "github.com/mitchellh/multistep" 7 "github.com/mitchellh/packer/packer" 8 "os" 9 ) 10 11 // StepMountExtra mounts the attached device. 12 // 13 // Produces: 14 // mount_extra_cleanup CleanupFunc - To perform early cleanup 15 type StepMountExtra struct { 16 mounts []string 17 } 18 19 func (s *StepMountExtra) Run(state multistep.StateBag) multistep.StepAction { 20 config := state.Get("config").(*Config) 21 mountPath := state.Get("mount_path").(string) 22 ui := state.Get("ui").(packer.Ui) 23 wrappedCommand := state.Get("wrappedCommand").(CommandWrapper) 24 25 s.mounts = make([]string, 0, len(config.ChrootMounts)) 26 27 ui.Say("Mounting additional paths within the chroot...") 28 for _, mountInfo := range config.ChrootMounts { 29 innerPath := mountPath + mountInfo[2] 30 31 if err := os.MkdirAll(innerPath, 0755); err != nil { 32 err := fmt.Errorf("Error creating mount directory: %s", err) 33 state.Put("error", err) 34 ui.Error(err.Error()) 35 return multistep.ActionHalt 36 } 37 38 flags := "-t " + mountInfo[0] 39 if mountInfo[0] == "bind" { 40 flags = "--bind" 41 } 42 43 ui.Message(fmt.Sprintf("Mounting: %s", mountInfo[2])) 44 stderr := new(bytes.Buffer) 45 mountCommand, err := wrappedCommand(fmt.Sprintf( 46 "mount %s %s %s", 47 flags, 48 mountInfo[1], 49 innerPath)) 50 if err != nil { 51 err := fmt.Errorf("Error creating mount command: %s", err) 52 state.Put("error", err) 53 ui.Error(err.Error()) 54 return multistep.ActionHalt 55 } 56 57 cmd := ShellCommand(mountCommand) 58 cmd.Stderr = stderr 59 if err := cmd.Run(); err != nil { 60 err := fmt.Errorf( 61 "Error mounting: %s\nStderr: %s", err, stderr.String()) 62 state.Put("error", err) 63 ui.Error(err.Error()) 64 return multistep.ActionHalt 65 } 66 67 s.mounts = append(s.mounts, innerPath) 68 } 69 70 state.Put("mount_extra_cleanup", s) 71 return multistep.ActionContinue 72 } 73 74 func (s *StepMountExtra) Cleanup(state multistep.StateBag) { 75 ui := state.Get("ui").(packer.Ui) 76 77 if err := s.CleanupFunc(state); err != nil { 78 ui.Error(err.Error()) 79 return 80 } 81 } 82 83 func (s *StepMountExtra) CleanupFunc(state multistep.StateBag) error { 84 if s.mounts == nil { 85 return nil 86 } 87 88 wrappedCommand := state.Get("wrappedCommand").(CommandWrapper) 89 for len(s.mounts) > 0 { 90 var path string 91 lastIndex := len(s.mounts) - 1 92 path, s.mounts = s.mounts[lastIndex], s.mounts[:lastIndex] 93 unmountCommand, err := wrappedCommand(fmt.Sprintf("umount %s", path)) 94 if err != nil { 95 return fmt.Errorf("Error creating unmount command: %s", err) 96 } 97 98 stderr := new(bytes.Buffer) 99 cmd := ShellCommand(unmountCommand) 100 cmd.Stderr = stderr 101 if err := cmd.Run(); err != nil { 102 return fmt.Errorf( 103 "Error unmounting device: %s\nStderr: %s", err, stderr.String()) 104 } 105 } 106 107 s.mounts = nil 108 return nil 109 }