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 }