github.com/rahart/packer@v0.12.2-0.20161229105310-282bb6ad370f/builder/amazon/chroot/step_mount_device.go (about) 1 package chroot 2 3 import ( 4 "bytes" 5 "fmt" 6 "log" 7 "os" 8 "path/filepath" 9 "strings" 10 11 "github.com/aws/aws-sdk-go/service/ec2" 12 "github.com/mitchellh/multistep" 13 "github.com/mitchellh/packer/packer" 14 "github.com/mitchellh/packer/template/interpolate" 15 ) 16 17 type mountPathData struct { 18 Device string 19 } 20 21 // StepMountDevice mounts the attached device. 22 // 23 // Produces: 24 // mount_path string - The location where the volume was mounted. 25 // mount_device_cleanup CleanupFunc - To perform early cleanup 26 type StepMountDevice struct { 27 MountOptions []string 28 MountPartition int 29 30 mountPath string 31 } 32 33 func (s *StepMountDevice) Run(state multistep.StateBag) multistep.StepAction { 34 config := state.Get("config").(*Config) 35 ui := state.Get("ui").(packer.Ui) 36 device := state.Get("device").(string) 37 wrappedCommand := state.Get("wrappedCommand").(CommandWrapper) 38 39 var virtualizationType string 40 if config.FromScratch { 41 virtualizationType = config.AMIVirtType 42 } else { 43 image := state.Get("source_image").(*ec2.Image) 44 virtualizationType = *image.VirtualizationType 45 log.Printf("Source image virtualization type is: %s", virtualizationType) 46 } 47 48 ctx := config.ctx 49 ctx.Data = &mountPathData{Device: filepath.Base(device)} 50 mountPath, err := interpolate.Render(config.MountPath, &ctx) 51 52 if err != nil { 53 err := fmt.Errorf("Error preparing mount directory: %s", err) 54 state.Put("error", err) 55 ui.Error(err.Error()) 56 return multistep.ActionHalt 57 } 58 59 mountPath, err = filepath.Abs(mountPath) 60 if err != nil { 61 err := fmt.Errorf("Error preparing mount directory: %s", err) 62 state.Put("error", err) 63 ui.Error(err.Error()) 64 return multistep.ActionHalt 65 } 66 67 log.Printf("Mount path: %s", mountPath) 68 69 if err := os.MkdirAll(mountPath, 0755); err != nil { 70 err := fmt.Errorf("Error creating mount directory: %s", err) 71 state.Put("error", err) 72 ui.Error(err.Error()) 73 return multistep.ActionHalt 74 } 75 76 deviceMount := device 77 if virtualizationType == "hvm" { 78 deviceMount = fmt.Sprintf("%s%d", device, s.MountPartition) 79 } 80 state.Put("deviceMount", deviceMount) 81 82 ui.Say("Mounting the root device...") 83 stderr := new(bytes.Buffer) 84 85 // build mount options from mount_options config, usefull for nouuid options 86 // or other specific device type settings for mount 87 opts := "" 88 if len(s.MountOptions) > 0 { 89 opts = "-o " + strings.Join(s.MountOptions, " -o ") 90 } 91 mountCommand, err := wrappedCommand( 92 fmt.Sprintf("mount %s %s %s", opts, deviceMount, mountPath)) 93 if err != nil { 94 err := fmt.Errorf("Error creating mount command: %s", err) 95 state.Put("error", err) 96 ui.Error(err.Error()) 97 return multistep.ActionHalt 98 } 99 100 cmd := ShellCommand(mountCommand) 101 cmd.Stderr = stderr 102 if err := cmd.Run(); err != nil { 103 err := fmt.Errorf( 104 "Error mounting root volume: %s\nStderr: %s", err, stderr.String()) 105 state.Put("error", err) 106 ui.Error(err.Error()) 107 return multistep.ActionHalt 108 } 109 110 // Set the mount path so we remember to unmount it later 111 s.mountPath = mountPath 112 state.Put("mount_path", s.mountPath) 113 state.Put("mount_device_cleanup", s) 114 115 return multistep.ActionContinue 116 } 117 118 func (s *StepMountDevice) Cleanup(state multistep.StateBag) { 119 ui := state.Get("ui").(packer.Ui) 120 if err := s.CleanupFunc(state); err != nil { 121 ui.Error(err.Error()) 122 } 123 } 124 125 func (s *StepMountDevice) CleanupFunc(state multistep.StateBag) error { 126 if s.mountPath == "" { 127 return nil 128 } 129 130 ui := state.Get("ui").(packer.Ui) 131 wrappedCommand := state.Get("wrappedCommand").(CommandWrapper) 132 133 ui.Say("Unmounting the root device...") 134 unmountCommand, err := wrappedCommand(fmt.Sprintf("umount %s", s.mountPath)) 135 if err != nil { 136 return fmt.Errorf("Error creating unmount command: %s", err) 137 } 138 139 cmd := ShellCommand(unmountCommand) 140 if err := cmd.Run(); err != nil { 141 return fmt.Errorf("Error unmounting root device: %s", err) 142 } 143 144 s.mountPath = "" 145 return nil 146 }