github.com/mitchellh/packer@v1.3.2/builder/virtualbox/common/step_attach_floppy.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  // This step attaches the ISO to the virtual machine.
    17  //
    18  // Uses:
    19  //   driver Driver
    20  //   ui packer.Ui
    21  //   vmName string
    22  //
    23  // Produces:
    24  type StepAttachFloppy struct {
    25  	floppyPath string
    26  }
    27  
    28  func (s *StepAttachFloppy) Run(_ context.Context, state multistep.StateBag) multistep.StepAction {
    29  	// Determine if we even have a floppy disk to attach
    30  	var floppyPath string
    31  	if floppyPathRaw, ok := state.GetOk("floppy_path"); ok {
    32  		floppyPath = floppyPathRaw.(string)
    33  	} else {
    34  		log.Println("No floppy disk, not attaching.")
    35  		return multistep.ActionContinue
    36  	}
    37  
    38  	// VirtualBox is really dumb and can't figure out the format of the file
    39  	// without an extension, so we need to add the "vfd" extension to the
    40  	// floppy.
    41  	floppyPath, err := s.copyFloppy(floppyPath)
    42  	if err != nil {
    43  		state.Put("error", fmt.Errorf("Error preparing floppy: %s", err))
    44  		return multistep.ActionHalt
    45  	}
    46  
    47  	driver := state.Get("driver").(Driver)
    48  	ui := state.Get("ui").(packer.Ui)
    49  	vmName := state.Get("vmName").(string)
    50  
    51  	ui.Say("Attaching floppy disk...")
    52  
    53  	// Create the floppy disk controller
    54  	command := []string{
    55  		"storagectl", vmName,
    56  		"--name", "Floppy Controller",
    57  		"--add", "floppy",
    58  	}
    59  	if err := driver.VBoxManage(command...); err != nil {
    60  		state.Put("error", fmt.Errorf("Error creating floppy controller: %s", err))
    61  		return multistep.ActionHalt
    62  	}
    63  
    64  	// Attach the floppy to the controller
    65  	command = []string{
    66  		"storageattach", vmName,
    67  		"--storagectl", "Floppy Controller",
    68  		"--port", "0",
    69  		"--device", "0",
    70  		"--type", "fdd",
    71  		"--medium", floppyPath,
    72  	}
    73  	if err := driver.VBoxManage(command...); err != nil {
    74  		state.Put("error", fmt.Errorf("Error attaching floppy: %s", err))
    75  		return multistep.ActionHalt
    76  	}
    77  
    78  	// Track the path so that we can unregister it from VirtualBox later
    79  	s.floppyPath = floppyPath
    80  
    81  	return multistep.ActionContinue
    82  }
    83  
    84  func (s *StepAttachFloppy) Cleanup(state multistep.StateBag) {
    85  	if s.floppyPath == "" {
    86  		return
    87  	}
    88  
    89  	// Delete the floppy disk
    90  	defer os.Remove(s.floppyPath)
    91  
    92  	driver := state.Get("driver").(Driver)
    93  	vmName := state.Get("vmName").(string)
    94  
    95  	command := []string{
    96  		"storageattach", vmName,
    97  		"--storagectl", "Floppy Controller",
    98  		"--port", "0",
    99  		"--device", "0",
   100  		"--medium", "none",
   101  	}
   102  
   103  	if err := driver.VBoxManage(command...); err != nil {
   104  		log.Printf("Error unregistering floppy: %s", err)
   105  	}
   106  }
   107  
   108  func (s *StepAttachFloppy) copyFloppy(path string) (string, error) {
   109  	tempdir, err := ioutil.TempDir("", "packer")
   110  	if err != nil {
   111  		return "", err
   112  	}
   113  
   114  	floppyPath := filepath.Join(tempdir, "floppy.vfd")
   115  	f, err := os.Create(floppyPath)
   116  	if err != nil {
   117  		return "", err
   118  	}
   119  	defer f.Close()
   120  
   121  	sourceF, err := os.Open(path)
   122  	if err != nil {
   123  		return "", err
   124  	}
   125  	defer sourceF.Close()
   126  
   127  	log.Printf("Copying floppy to temp location: %s", floppyPath)
   128  	if _, err := io.Copy(f, sourceF); err != nil {
   129  		return "", err
   130  	}
   131  
   132  	return floppyPath, nil
   133  }