Browse Source

Make ISO file natively in Go, using go-diskfs

master
Fábio Kaiser Rauber 5 years ago
parent
commit
eff646afb9
  1. 81
      xcp/xcp.go

81
xcp/xcp.go

@ -13,10 +13,9 @@ import (
"io/ioutil" "io/ioutil"
"net/http" "net/http"
"os" "os"
"os/exec"
"path/filepath"
"strings" "strings"
"time" "time"
"path"
"github.com/docker/machine/libmachine/drivers" "github.com/docker/machine/libmachine/drivers"
"github.com/docker/machine/libmachine/log" "github.com/docker/machine/libmachine/log"
@ -27,6 +26,11 @@ import (
"github.com/nilshell/xmlrpc" "github.com/nilshell/xmlrpc"
xsclient "github.com/xenserver/go-xenserver-client" xsclient "github.com/xenserver/go-xenserver-client"
"golang.org/x/net/context" "golang.org/x/net/context"
diskfs "github.com/diskfs/go-diskfs"
"github.com/diskfs/go-diskfs/disk"
"github.com/diskfs/go-diskfs/filesystem"
"github.com/diskfs/go-diskfs/filesystem/iso9660"
) )
const ( const (
@ -972,6 +976,7 @@ func pseudoUuid() (string, error) {
return uuid, nil return uuid, nil
} }
// CoreOS only Config Drive
func (d *Driver) createCoreOSConfigDrive(pubKey []byte, vmuuid string, sruuid string) error { func (d *Driver) createCoreOSConfigDrive(pubKey []byte, vmuuid string, sruuid string) error {
userdatatext := `#cloud-config userdatatext := `#cloud-config
hostname: %XSVMNAMETOHOSTNAME% hostname: %XSVMNAMETOHOSTNAME%
@ -1010,6 +1015,7 @@ ssh_authorized_keys:
return nil return nil
} }
// Generic Config Drive for cloud-init enabled OS templates
func (d *Driver) createGenericConfigDrive(pubKey []byte, vmUuid string, sr *xsclient.SR) (string, error) { func (d *Driver) createGenericConfigDrive(pubKey []byte, vmUuid string, sr *xsclient.SR) (string, error) {
userdatatext := `#cloud-config userdatatext := `#cloud-config
ssh_authorized_keys: ssh_authorized_keys:
@ -1017,41 +1023,68 @@ ssh_authorized_keys:
metadatatext := `{ "uuid": "` + vmUuid + `"}` metadatatext := `{ "uuid": "` + vmUuid + `"}`
tempDir := d.ResolveStorePath("configdrive") //create ISO file
var diskSize int64
diskSize = 10 * 1024 * 1024 // 10 MB
var configIsoFilename = d.ResolveStorePath("configdrive.iso")
cdDisk, err := diskfs.Create(configIsoFilename, diskSize, diskfs.Raw)
if err != nil {
log.Errorf("Unable to create configdrive.iso: %v", err)
}
// the following line is required for an ISO, which may have logical block sizes
// only of 2048, 4096, 8192
cdDisk.LogicalBlocksize = 2048
fspec := disk.FilesystemSpec{Partition: 0, FSType: filesystem.TypeISO9660, VolumeLabel: "config-2"}
cdFS, err := cdDisk.CreateFilesystem(fspec)
if err != nil {
log.Errorf("Unable to create ConfigDrive filesystem: %v", err)
}
cloudInitPrefix := path.Join("/", "openstack", "latest")
// place down cloud-init info
err = cdFS.Mkdir(cloudInitPrefix)
if err != nil {
log.Errorf("Error creating cloud init directory structure: %v", err)
}
//Create the folder structure inside the temp folder metadataPath := path.Join(cloudInitPrefix, "meta_data.json")
path := filepath.Join(tempDir, "openstack", "latest") log.Infof("Opening %s", metadataPath)
os.MkdirAll(path, os.ModePerm) metadataFile, err := cdFS.OpenFile(metadataPath, os.O_CREATE|os.O_RDWR)
f, err := os.OpenFile(filepath.Join(path, "user_data"), os.O_WRONLY|os.O_CREATE, 0666)
if err != nil { if err != nil {
log.Errorf("Unable to open user_data config drive file '%s': %v", path, err) log.Errorf("Error opening meta data: %v", err)
return "", err
} }
io.WriteString(f, userdatatext)
f.Close()
fmetadata, err := os.OpenFile(filepath.Join(path, "meta_data.json"), os.O_WRONLY|os.O_CREATE, 0666) log.Infof("Writing metadata contents")
_, err = metadataFile.Write([]byte(metadatatext))
if err != nil { if err != nil {
log.Errorf("Unable to open meta_data.json config drive file '%s': %v", path, err) log.Errorf("Error writting meta data: %v", err)
return "", err
} }
io.WriteString(fmetadata, metadatatext)
fmetadata.Close()
configIsoFilename := d.ResolveStorePath("configdrive.iso") userdataPath := path.Join(cloudInitPrefix, "user_data")
cmd := exec.Command("mkisofs", "-R", "-V", "config-2", "-o", configIsoFilename, tempDir) log.Infof("Opening %s", userdataPath)
err = cmd.Run() userdataFile, err := cdFS.OpenFile(userdataPath, os.O_CREATE|os.O_RDWR)
if err != nil { if err != nil {
log.Errorf("Unable to create ConfigDrive ISO '%s': %v", configIsoFilename, err) log.Errorf("Error opening user data: %v", err)
return "", err
} }
configIsoFileInfo, err := os.Stat(configIsoFilename) _, err = userdataFile.Write([]byte(userdatatext))
if err != nil { if err != nil {
return "", err log.Errorf("Error writting user data: %v", err)
} }
//finalize ISO
iso, ok := cdFS.(*iso9660.FileSystem)
if !ok {
log.Errorf("not an iso9660 filesystem")
}
err = iso.Finalize(iso9660.FinalizeOptions{})
if err != nil {
log.Errorf("Error finalizing configdrive.iso: %v", err)
}
// Create the VDI // Create the VDI
isoVdi, err := sr.CreateVdi(configIsoFilename, configIsoFileInfo.Size()) isoVdi, err := sr.CreateVdi(configIsoFilename, diskSize)
if err != nil { if err != nil {
log.Errorf("Unable to create ConfigDrive ISO VDI '%s': %v", configIsoFilename, err) log.Errorf("Unable to create ConfigDrive ISO VDI '%s': %v", configIsoFilename, err)
return "", err return "", err

Loading…
Cancel
Save