|
@ -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 |
|
|