builder/common: step to create floppy disks
This commit is contained in:
parent
6e1aff9ad5
commit
c8019f10e6
|
@ -0,0 +1,126 @@
|
|||
package common
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/mitchellh/go-fs"
|
||||
"github.com/mitchellh/go-fs/fat"
|
||||
"github.com/mitchellh/multistep"
|
||||
"github.com/mitchellh/packer/packer"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"log"
|
||||
"os"
|
||||
"path/filepath"
|
||||
)
|
||||
|
||||
// StepCreateFloppy will create a floppy disk with the given files.
|
||||
// The floppy disk doesn't support sub-directories. Only files at the
|
||||
// root level are supported.
|
||||
type StepCreateFloppy struct {
|
||||
Files []string
|
||||
}
|
||||
|
||||
func (s *StepCreateFloppy) Run(state map[string]interface{}) multistep.StepAction {
|
||||
if len(s.Files) == 0 {
|
||||
log.Println("No floppy files specified. Floppy disk will not be made.")
|
||||
return multistep.ActionContinue
|
||||
}
|
||||
|
||||
ui := state["ui"].(packer.Ui)
|
||||
ui.Say("Creating floppy disk...")
|
||||
|
||||
// Create a temporary file to be our floppy drive
|
||||
floppyF, err := ioutil.TempFile("", "packer")
|
||||
if err != nil {
|
||||
state["error"] = fmt.Errorf("Error creating temporary file for floppy: %s", err)
|
||||
return multistep.ActionHalt
|
||||
}
|
||||
defer floppyF.Close()
|
||||
|
||||
log.Printf("Floppy path: %s", floppyF.Name())
|
||||
|
||||
// Set the size of the file to be a floppy sized
|
||||
if err := floppyF.Truncate(1440 * 1024); err != nil {
|
||||
state["error"] = fmt.Errorf("Error creating floppy: %s", err)
|
||||
return multistep.ActionHalt
|
||||
}
|
||||
|
||||
// BlockDevice backed by the file for our filesystem
|
||||
log.Println("Initializing block device backed by temporary file")
|
||||
device, err := fs.NewFileDisk(floppyF)
|
||||
if err != nil {
|
||||
state["error"] = fmt.Errorf("Error creating floppy: %s", err)
|
||||
return multistep.ActionHalt
|
||||
}
|
||||
|
||||
// Format the block device so it contains a valid FAT filesystem
|
||||
log.Println("Formatting the block device with a FAT filesystem...")
|
||||
formatConfig := &fat.SuperFloppyConfig{
|
||||
FATType: fat.FAT12,
|
||||
Label: "packer",
|
||||
OEMName: "packer",
|
||||
}
|
||||
if fat.FormatSuperFloppy(device, formatConfig); err != nil {
|
||||
state["error"] = fmt.Errorf("Error creating floppy: %s", err)
|
||||
return multistep.ActionHalt
|
||||
}
|
||||
|
||||
// The actual FAT filesystem
|
||||
log.Println("Initializing FAT filesystem on block device")
|
||||
fatFs, err := fat.New(device)
|
||||
if err != nil {
|
||||
state["error"] = fmt.Errorf("Error creating floppy: %s", err)
|
||||
return multistep.ActionHalt
|
||||
}
|
||||
|
||||
// Get the root directory to the filesystem
|
||||
log.Println("Reading the root directory from the filesystem")
|
||||
rootDir, err := fatFs.RootDir()
|
||||
if err != nil {
|
||||
state["error"] = fmt.Errorf("Error creating floppy: %s", err)
|
||||
return multistep.ActionHalt
|
||||
}
|
||||
|
||||
// Go over each file and copy it.
|
||||
for _, filename := range s.Files {
|
||||
ui.Message(fmt.Sprintf("Copying: %s", filepath.Base(filename)))
|
||||
if s.addSingleFile(rootDir, filename); err != nil {
|
||||
state["error"] = fmt.Errorf("Error adding file to floppy: %s", err)
|
||||
return multistep.ActionHalt
|
||||
}
|
||||
}
|
||||
|
||||
// Set the path to the floppy so it can be used later
|
||||
state["floppy_path"] = floppyF.Name()
|
||||
|
||||
return multistep.ActionHalt
|
||||
}
|
||||
|
||||
func (s *StepCreateFloppy) Cleanup(map[string]interface{}) {
|
||||
}
|
||||
|
||||
func (s *StepCreateFloppy) addSingleFile(dir fs.Directory, src string) error {
|
||||
log.Printf("Adding file to floppy: %s", src)
|
||||
|
||||
inputF, err := os.Open(src)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer inputF.Close()
|
||||
|
||||
entry, err := dir.AddFile(filepath.Base(src))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
fatFile, err := entry.File()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if _, err := io.Copy(fatFile, inputF); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
Loading…
Reference in New Issue