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  }