github.phpd.cn/hashicorp/packer@v1.3.2/builder/hyperv/common/step_mount_floppydrive.go (about)

     1  package common
     2  
     3  import (
     4  	"context"
     5  	"fmt"
     6  	"io"
     7  	"io/ioutil"
     8  	"log"
     9  	"os"
    10  	"path/filepath"
    11  
    12  	"github.com/hashicorp/packer/helper/multistep"
    13  	"github.com/hashicorp/packer/packer"
    14  )
    15  
    16  const (
    17  	FloppyFileName = "assets.vfd"
    18  )
    19  
    20  type StepMountFloppydrive struct {
    21  	Generation uint
    22  	floppyPath string
    23  }
    24  
    25  func (s *StepMountFloppydrive) Run(_ context.Context, state multistep.StateBag) multistep.StepAction {
    26  	if s.Generation > 1 {
    27  		return multistep.ActionContinue
    28  	}
    29  
    30  	driver := state.Get("driver").(Driver)
    31  
    32  	// Determine if we even have a floppy disk to attach
    33  	var floppyPath string
    34  	if floppyPathRaw, ok := state.GetOk("floppy_path"); ok {
    35  		floppyPath = floppyPathRaw.(string)
    36  	} else {
    37  		log.Println("No floppy disk, not attaching.")
    38  		return multistep.ActionContinue
    39  	}
    40  
    41  	// Hyper-V is really dumb and can't figure out the format of the file
    42  	// without an extension, so we need to add the "vfd" extension to the
    43  	// floppy.
    44  	floppyPath, err := s.copyFloppy(floppyPath)
    45  	if err != nil {
    46  		state.Put("error", fmt.Errorf("Error preparing floppy: %s", err))
    47  		return multistep.ActionHalt
    48  	}
    49  
    50  	ui := state.Get("ui").(packer.Ui)
    51  	vmName := state.Get("vmName").(string)
    52  
    53  	ui.Say("Mounting floppy drive...")
    54  
    55  	err = driver.MountFloppyDrive(vmName, floppyPath)
    56  	if err != nil {
    57  		state.Put("error", fmt.Errorf("Error mounting floppy drive: %s", err))
    58  		return multistep.ActionHalt
    59  	}
    60  
    61  	// Track the path so that we can unregister it from Hyper-V later
    62  	s.floppyPath = floppyPath
    63  
    64  	return multistep.ActionContinue
    65  }
    66  
    67  func (s *StepMountFloppydrive) Cleanup(state multistep.StateBag) {
    68  	if s.Generation > 1 {
    69  		return
    70  	}
    71  	driver := state.Get("driver").(Driver)
    72  	if s.floppyPath == "" {
    73  		return
    74  	}
    75  
    76  	errorMsg := "Error unmounting floppy drive: %s"
    77  
    78  	vmName := state.Get("vmName").(string)
    79  	ui := state.Get("ui").(packer.Ui)
    80  
    81  	ui.Say("Cleanup floppy drive...")
    82  
    83  	err := driver.UnmountFloppyDrive(vmName)
    84  	if err != nil {
    85  		log.Print(fmt.Sprintf(errorMsg, err))
    86  	}
    87  
    88  	err = os.Remove(s.floppyPath)
    89  
    90  	if err != nil {
    91  		log.Print(fmt.Sprintf(errorMsg, err))
    92  	}
    93  }
    94  
    95  func (s *StepMountFloppydrive) copyFloppy(path string) (string, error) {
    96  	tempdir, err := ioutil.TempDir("", "packer")
    97  	if err != nil {
    98  		return "", err
    99  	}
   100  
   101  	floppyPath := filepath.Join(tempdir, "floppy.vfd")
   102  	f, err := os.Create(floppyPath)
   103  	if err != nil {
   104  		return "", err
   105  	}
   106  	defer f.Close()
   107  
   108  	sourceF, err := os.Open(path)
   109  	if err != nil {
   110  		return "", err
   111  	}
   112  	defer sourceF.Close()
   113  
   114  	log.Printf("Copying floppy to temp location: %s", floppyPath)
   115  	if _, err := io.Copy(f, sourceF); err != nil {
   116  		return "", err
   117  	}
   118  
   119  	return floppyPath, nil
   120  }