github.com/phobos182/packer@v0.2.3-0.20130819023704-c84d2aeffc68/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  	"os/exec"
    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 map[string]interface{}) multistep.StepAction {
    28  	config := state["config"].(*Config)
    29  	ui := state["ui"].(packer.Ui)
    30  	device := state["device"].(string)
    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["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["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["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 := fmt.Sprintf("%s %s %s", config.MountCommand, device, mountPath)
    63  	cmd := exec.Command("/bin/sh", "-c", mountCommand)
    64  	cmd.Stderr = stderr
    65  	if err := cmd.Run(); err != nil {
    66  		err := fmt.Errorf(
    67  			"Error mounting root volume: %s\nStderr: %s", err, stderr.String())
    68  		state["error"] = err
    69  		ui.Error(err.Error())
    70  		return multistep.ActionHalt
    71  	}
    72  
    73  	// Set the mount path so we remember to unmount it later
    74  	s.mountPath = mountPath
    75  	state["mount_path"] = s.mountPath
    76  	state["mount_device_cleanup"] = s
    77  
    78  	return multistep.ActionContinue
    79  }
    80  
    81  func (s *StepMountDevice) Cleanup(state map[string]interface{}) {
    82  	ui := state["ui"].(packer.Ui)
    83  	if err := s.CleanupFunc(state); err != nil {
    84  		ui.Error(err.Error())
    85  	}
    86  }
    87  
    88  func (s *StepMountDevice) CleanupFunc(state map[string]interface{}) error {
    89  	if s.mountPath == "" {
    90  		return nil
    91  	}
    92  
    93  	config := state["config"].(*Config)
    94  	ui := state["ui"].(packer.Ui)
    95  	ui.Say("Unmounting the root device...")
    96  
    97  	unmountCommand := fmt.Sprintf("%s %s", config.UnmountCommand, s.mountPath)
    98  	cmd := exec.Command("/bin/sh", "-c", unmountCommand)
    99  	if err := cmd.Run(); err != nil {
   100  		return fmt.Errorf("Error unmounting root device: %s", err)
   101  	}
   102  
   103  	s.mountPath = ""
   104  	return nil
   105  }