github.com/phobos182/packer@v0.2.3-0.20130819023704-c84d2aeffc68/builder/amazon/chroot/step_mount_extra.go (about)

     1  package chroot
     2  
     3  import (
     4  	"bytes"
     5  	"fmt"
     6  	"github.com/mitchellh/multistep"
     7  	"github.com/mitchellh/packer/packer"
     8  	"os"
     9  	"os/exec"
    10  )
    11  
    12  // StepMountExtra mounts the attached device.
    13  //
    14  // Produces:
    15  //   mount_extra_cleanup CleanupFunc - To perform early cleanup
    16  type StepMountExtra struct {
    17  	mounts []string
    18  }
    19  
    20  func (s *StepMountExtra) Run(state map[string]interface{}) multistep.StepAction {
    21  	config := state["config"].(*Config)
    22  	mountPath := state["mount_path"].(string)
    23  	ui := state["ui"].(packer.Ui)
    24  
    25  	s.mounts = make([]string, 0, len(config.ChrootMounts))
    26  
    27  	ui.Say("Mounting additional paths within the chroot...")
    28  	for _, mountInfo := range config.ChrootMounts {
    29  		innerPath := mountPath + mountInfo[2]
    30  
    31  		if err := os.MkdirAll(innerPath, 0755); err != nil {
    32  			err := fmt.Errorf("Error creating mount directory: %s", err)
    33  			state["error"] = err
    34  			ui.Error(err.Error())
    35  			return multistep.ActionHalt
    36  		}
    37  
    38  		flags := "-t " + mountInfo[0]
    39  		if mountInfo[0] == "bind" {
    40  			flags = "--bind"
    41  		}
    42  
    43  		ui.Message(fmt.Sprintf("Mounting: %s", mountInfo[2]))
    44  		stderr := new(bytes.Buffer)
    45  		mountCommand := fmt.Sprintf(
    46  			"%s %s %s %s",
    47  			config.MountCommand,
    48  			flags,
    49  			mountInfo[1],
    50  			innerPath)
    51  		cmd := exec.Command("/bin/sh", "-c", mountCommand)
    52  		cmd.Stderr = stderr
    53  		if err := cmd.Run(); err != nil {
    54  			err := fmt.Errorf(
    55  				"Error mounting: %s\nStderr: %s", err, stderr.String())
    56  			state["error"] = err
    57  			ui.Error(err.Error())
    58  			return multistep.ActionHalt
    59  		}
    60  
    61  		s.mounts = append(s.mounts, innerPath)
    62  	}
    63  
    64  	state["mount_extra_cleanup"] = s
    65  	return multistep.ActionContinue
    66  }
    67  
    68  func (s *StepMountExtra) Cleanup(state map[string]interface{}) {
    69  	ui := state["ui"].(packer.Ui)
    70  
    71  	if err := s.CleanupFunc(state); err != nil {
    72  		ui.Error(err.Error())
    73  		return
    74  	}
    75  }
    76  
    77  func (s *StepMountExtra) CleanupFunc(state map[string]interface{}) error {
    78  	if s.mounts == nil {
    79  		return nil
    80  	}
    81  
    82  	config := state["config"].(*Config)
    83  	for len(s.mounts) > 0 {
    84  		var path string
    85  		lastIndex := len(s.mounts) - 1
    86  		path, s.mounts = s.mounts[lastIndex], s.mounts[:lastIndex]
    87  		unmountCommand := fmt.Sprintf("%s %s", config.UnmountCommand, path)
    88  
    89  		stderr := new(bytes.Buffer)
    90  		cmd := exec.Command("/bin/sh", "-c", unmountCommand)
    91  		cmd.Stderr = stderr
    92  		if err := cmd.Run(); err != nil {
    93  			return fmt.Errorf(
    94  				"Error unmounting device: %s\nStderr: %s", err, stderr.String())
    95  		}
    96  	}
    97  
    98  	s.mounts = nil
    99  	return nil
   100  }