github.com/sneal/packer@v0.5.2/builder/amazon/chroot/step_mount_device.go (about) 1 package chroot 2 3 import ( 4 "bytes" 5 "fmt" 6 "github.com/mitchellh/multistep" 7 "github.com/mitchellh/packer/packer" 8 "log" 9 "os" 10 "path/filepath" 11 ) 12 13 type mountPathData struct { 14 Device string 15 } 16 17 // StepMountDevice mounts the attached device. 18 // 19 // Produces: 20 // mount_path string - The location where the volume was mounted. 21 // mount_device_cleanup CleanupFunc - To perform early cleanup 22 type StepMountDevice struct { 23 mountPath string 24 } 25 26 func (s *StepMountDevice) Run(state multistep.StateBag) multistep.StepAction { 27 config := state.Get("config").(*Config) 28 ui := state.Get("ui").(packer.Ui) 29 device := state.Get("device").(string) 30 wrappedCommand := state.Get("wrappedCommand").(CommandWrapper) 31 32 mountPath, err := config.tpl.Process(config.MountPath, &mountPathData{ 33 Device: filepath.Base(device), 34 }) 35 36 if err != nil { 37 err := fmt.Errorf("Error preparing mount directory: %s", err) 38 state.Put("error", err) 39 ui.Error(err.Error()) 40 return multistep.ActionHalt 41 } 42 43 mountPath, err = filepath.Abs(mountPath) 44 if err != nil { 45 err := fmt.Errorf("Error preparing mount directory: %s", err) 46 state.Put("error", err) 47 ui.Error(err.Error()) 48 return multistep.ActionHalt 49 } 50 51 log.Printf("Mount path: %s", mountPath) 52 53 if err := os.MkdirAll(mountPath, 0755); err != nil { 54 err := fmt.Errorf("Error creating mount directory: %s", err) 55 state.Put("error", err) 56 ui.Error(err.Error()) 57 return multistep.ActionHalt 58 } 59 60 ui.Say("Mounting the root device...") 61 stderr := new(bytes.Buffer) 62 mountCommand, err := wrappedCommand( 63 fmt.Sprintf("mount %s %s", device, mountPath)) 64 if err != nil { 65 err := fmt.Errorf("Error creating mount command: %s", err) 66 state.Put("error", err) 67 ui.Error(err.Error()) 68 return multistep.ActionHalt 69 } 70 71 cmd := ShellCommand(mountCommand) 72 cmd.Stderr = stderr 73 if err := cmd.Run(); err != nil { 74 err := fmt.Errorf( 75 "Error mounting root volume: %s\nStderr: %s", err, stderr.String()) 76 state.Put("error", err) 77 ui.Error(err.Error()) 78 return multistep.ActionHalt 79 } 80 81 // Set the mount path so we remember to unmount it later 82 s.mountPath = mountPath 83 state.Put("mount_path", s.mountPath) 84 state.Put("mount_device_cleanup", s) 85 86 return multistep.ActionContinue 87 } 88 89 func (s *StepMountDevice) Cleanup(state multistep.StateBag) { 90 ui := state.Get("ui").(packer.Ui) 91 if err := s.CleanupFunc(state); err != nil { 92 ui.Error(err.Error()) 93 } 94 } 95 96 func (s *StepMountDevice) CleanupFunc(state multistep.StateBag) error { 97 if s.mountPath == "" { 98 return nil 99 } 100 101 ui := state.Get("ui").(packer.Ui) 102 wrappedCommand := state.Get("wrappedCommand").(CommandWrapper) 103 104 ui.Say("Unmounting the root device...") 105 unmountCommand, err := wrappedCommand(fmt.Sprintf("umount %s", s.mountPath)) 106 if err != nil { 107 return fmt.Errorf("Error creating unmount command: %s", err) 108 } 109 110 cmd := ShellCommand(unmountCommand) 111 if err := cmd.Run(); err != nil { 112 return fmt.Errorf("Error unmounting root device: %s", err) 113 } 114 115 s.mountPath = "" 116 return nil 117 }