github.com/phobos182/packer@v0.2.3-0.20130819023704-c84d2aeffc68/common/step_create_floppy.go (about) 1 package common 2 3 import ( 4 "fmt" 5 "github.com/mitchellh/go-fs" 6 "github.com/mitchellh/go-fs/fat" 7 "github.com/mitchellh/multistep" 8 "github.com/mitchellh/packer/packer" 9 "io" 10 "io/ioutil" 11 "log" 12 "os" 13 "path/filepath" 14 ) 15 16 // StepCreateFloppy will create a floppy disk with the given files. 17 // The floppy disk doesn't support sub-directories. Only files at the 18 // root level are supported. 19 type StepCreateFloppy struct { 20 Files []string 21 22 floppyPath string 23 } 24 25 func (s *StepCreateFloppy) Run(state map[string]interface{}) multistep.StepAction { 26 if len(s.Files) == 0 { 27 log.Println("No floppy files specified. Floppy disk will not be made.") 28 return multistep.ActionContinue 29 } 30 31 ui := state["ui"].(packer.Ui) 32 ui.Say("Creating floppy disk...") 33 34 // Create a temporary file to be our floppy drive 35 floppyF, err := ioutil.TempFile("", "packer") 36 if err != nil { 37 state["error"] = fmt.Errorf("Error creating temporary file for floppy: %s", err) 38 return multistep.ActionHalt 39 } 40 defer floppyF.Close() 41 42 // Set the path so we can remove it later 43 s.floppyPath = floppyF.Name() 44 45 log.Printf("Floppy path: %s", floppyF.Name()) 46 47 // Set the size of the file to be a floppy sized 48 if err := floppyF.Truncate(1440 * 1024); err != nil { 49 state["error"] = fmt.Errorf("Error creating floppy: %s", err) 50 return multistep.ActionHalt 51 } 52 53 // BlockDevice backed by the file for our filesystem 54 log.Println("Initializing block device backed by temporary file") 55 device, err := fs.NewFileDisk(floppyF) 56 if err != nil { 57 state["error"] = fmt.Errorf("Error creating floppy: %s", err) 58 return multistep.ActionHalt 59 } 60 61 // Format the block device so it contains a valid FAT filesystem 62 log.Println("Formatting the block device with a FAT filesystem...") 63 formatConfig := &fat.SuperFloppyConfig{ 64 FATType: fat.FAT12, 65 Label: "packer", 66 OEMName: "packer", 67 } 68 if fat.FormatSuperFloppy(device, formatConfig); err != nil { 69 state["error"] = fmt.Errorf("Error creating floppy: %s", err) 70 return multistep.ActionHalt 71 } 72 73 // The actual FAT filesystem 74 log.Println("Initializing FAT filesystem on block device") 75 fatFs, err := fat.New(device) 76 if err != nil { 77 state["error"] = fmt.Errorf("Error creating floppy: %s", err) 78 return multistep.ActionHalt 79 } 80 81 // Get the root directory to the filesystem 82 log.Println("Reading the root directory from the filesystem") 83 rootDir, err := fatFs.RootDir() 84 if err != nil { 85 state["error"] = fmt.Errorf("Error creating floppy: %s", err) 86 return multistep.ActionHalt 87 } 88 89 // Go over each file and copy it. 90 for _, filename := range s.Files { 91 ui.Message(fmt.Sprintf("Copying: %s", filepath.Base(filename))) 92 if s.addSingleFile(rootDir, filename); err != nil { 93 state["error"] = fmt.Errorf("Error adding file to floppy: %s", err) 94 return multistep.ActionHalt 95 } 96 } 97 98 // Set the path to the floppy so it can be used later 99 state["floppy_path"] = s.floppyPath 100 101 return multistep.ActionContinue 102 } 103 104 func (s *StepCreateFloppy) Cleanup(map[string]interface{}) { 105 if s.floppyPath != "" { 106 log.Printf("Deleting floppy disk: %s", s.floppyPath) 107 os.Remove(s.floppyPath) 108 } 109 } 110 111 func (s *StepCreateFloppy) addSingleFile(dir fs.Directory, src string) error { 112 log.Printf("Adding file to floppy: %s", src) 113 114 inputF, err := os.Open(src) 115 if err != nil { 116 return err 117 } 118 defer inputF.Close() 119 120 entry, err := dir.AddFile(filepath.Base(src)) 121 if err != nil { 122 return err 123 } 124 125 fatFile, err := entry.File() 126 if err != nil { 127 return err 128 } 129 130 if _, err := io.Copy(fatFile, inputF); err != nil { 131 return err 132 } 133 134 return nil 135 }