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