[libvirt] [PATCH go-xml] Added Storage Pool and Storage Volume XML schemes.

Signed-off-by: Alexey Slaykovsky <aslaikov@redhat.com> --- domain.go | 9 +- domain_test.go | 8 +- memory.go | 31 +++++ storage.go | 159 ++++++++++++++++++++++ storage_test.go | 413 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 5 files changed, 609 insertions(+), 11 deletions(-) create mode 100644 memory.go create mode 100644 storage.go create mode 100644 storage_test.go diff --git a/domain.go b/domain.go index ec2bd02..f8833a1 100644 --- a/domain.go +++ b/domain.go @@ -121,11 +121,6 @@ type DomainDeviceList struct { Videos []DomainVideo `xml:"video"` } -type DomainMemory struct { - Value string `xml:",chardata"` - Unit string `xml:"unit,attr"` -} - type DomainOSType struct { Arch string `xml:"arch,attr"` Machine string `xml:"machine,attr"` @@ -194,8 +189,8 @@ type Domain struct { Type string `xml:"type,attr"` Name string `xml:"name"` UUID *string `xml:"uuid"` - Memory *DomainMemory `xml:"memory"` - CurrentMemory *DomainMemory `xml:"currentMemory"` + Memory *Memory `xml:"memory"` + CurrentMemory *Memory `xml:"currentMemory"` Devices *DomainDeviceList `xml:"devices"` OS *DomainOS `xml:"os"` SysInfo *DomainSysInfo `xml:"sysinfo"` diff --git a/domain_test.go b/domain_test.go index ae262e5..c22c384 100644 --- a/domain_test.go +++ b/domain_test.go @@ -125,13 +125,13 @@ var domainTestData = []struct { Object: &Domain{ Type: "kvm", Name: "test", - Memory: &DomainMemory{ + Memory: &Memory{ Unit: "KiB", - Value: "8192", + Value: 8192, }, - CurrentMemory: &DomainMemory{ + CurrentMemory: &Memory{ Unit: "KiB", - Value: "4096", + Value: 4096, }, OS: &DomainOS{ Type: &DomainOSType{ diff --git a/memory.go b/memory.go new file mode 100644 index 0000000..78844ac --- /dev/null +++ b/memory.go @@ -0,0 +1,31 @@ +/* + * This file is part of the libvirt-go-xml project + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * Copyright (C) 2017 Red Hat, Inc. + * + */ + +package libvirtxml + +type Memory struct { + Unit string `xml:"unit,attr,omitempty"` + Value uint64 `xml:",chardata"` +} diff --git a/storage.go b/storage.go new file mode 100644 index 0000000..eccbee5 --- /dev/null +++ b/storage.go @@ -0,0 +1,159 @@ +/* + * This file is part of the libvirt-go-xml project + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * Copyright (C) 2017 Red Hat, Inc. + * + */ + +package libvirtxml + +import "encoding/xml" + +type StorageFormat struct { + Type string `xml:"type,attr"` +} + +type StoragePermissions struct { + Owner string `xml:"owner,omitempty"` + Group string `xml:"group,omitempty"` + Mode string `xml:"mode,omitempty"` + Label string `xml:"label,omitempty"` +} + +type StorageTargetEncryptionSecret struct { + Type string `xml:"type,attr,omitempty"` + UUID string `xml:"uuid,attr,omitempty"` +} + +type StorageTargetEncryption struct { + Type string `xml:"type,attr,omitempty"` + Format string `xml:"format,attr,omitempty"` + Secret *StorageTargetEncryptionSecret `xml:"secret"` +} + +type StorageTargetTimestamps struct { + Atime string `xml:"atime"` + Mtime string `xml:"mtime"` + Ctime string `xml:"ctime"` +} + +type StorageTargetFeature struct { + LazyRefcounts *struct{} `xml:"lazy_refcounts"` +} + +type StorageTarget struct { + Path string `xml:"path,omitempty"` + Format *StorageFormat `xml:"format"` + Permissions *StoragePermissions `xml:"permissions"` + Timestamps *StorageTargetTimestamps `xml:"timestamps"` + Compat string `xml:"compat,omitempty"` + NoCOW *struct{} `xml:"nocow"` + Features []StorageTargetFeature `xml:"features"` + Encryption *StorageTargetEncryption `xml:"encryption"` +} + +type StoragePoolSourceHost struct { + Name string `xml:"name,attr"` +} + +type StoragePoolSourceDevice struct { + Path string `xml:"path,attr"` + PartSeparator string `xml:"part_separator,attr,omitempty"` +} + +type StoragePoolSourceAuthSecret struct { + Usage string `xml:"usage,attr"` +} + +type StoragePoolSourceAuth struct { + Type string `xml:"type,attr"` + Username string `xml:"username,attr"` + Secret *StoragePoolSourceAuthSecret `xml:"secret"` +} + +type StoragePoolSourceVendor struct { + Name string `xml:"name,attr"` +} + +type StoragePoolSourceProduct struct { + Name string `xml:"name,attr"` +} + +type StoragePoolSourceAdapterParentAddrAddress struct { + Domain string `xml:"domain,attr"` + Bus string `xml:"bus,attr"` + Slot string `xml:"slot,attr"` + Addr string `xml:"addr,attr"` +} + +type StoragePoolSourceAdapterParentAddr struct { + UniqueID uint64 `xml:"unique_id,attr"` + Address *StoragePoolSourceAdapterParentAddrAddress `xml:"address"` +} + +type StoragePoolSourceAdapter struct { + Type string `xml:"type,attr"` + Name string `xml:"name,attr,omitempty"` + Parent string `xml:"parent,attr,omitempty"` + WWNN string `xml:"wwnn,attr,omitempty"` + WWPN string `xml:"wwpn,attr,omitempty"` + ParentAddr *StoragePoolSourceAdapterParentAddr `xml:"parentaddr"` +} + +type StoragePoolSource struct { + Host *StoragePoolSourceHost `xml:"host"` + Device *StoragePoolSourceDevice `xml:"device"` + Auth *StoragePoolSourceAuth `xml:"auth"` + Vendor *StoragePoolSourceVendor `xml:"vendor"` + Product *StoragePoolSourceProduct `xml:"product"` + Format *StorageFormat `xml:"format"` + Adapter *StoragePoolSourceAdapter `xml:"adapter"` +} + +type StoragePool struct { + XMLName xml.Name `xml:"pool"` + Type string `xml:"type,attr"` + Name string `xml:"name"` + UUID string `xml:"uuid,omitempty"` + Allocation *Memory `xml:"allocation"` + Capacity *Memory `xml:"capacity"` + Available *Memory `xml:"available"` + Target *StorageTarget `xml:"target"` + Source *StoragePoolSource `xml:"source"` +} + +type StorageVolumeBackingStore struct { + Path string `xml:"path"` + Format *StorageFormat `xml:"format"` + Permissions *StoragePermissions `xml:"permissions"` +} + +type StorageVolume struct { + XMLName xml.Name `xml:"volume"` + Type string `xml:"type,attr,omitempty"` + Name string `xml:"name"` + Key string `xml:"key,omitempty"` + Allocation *Memory `xml:"allocation"` + Capacity *Memory `xml:"capacity"` + Physical *Memory `xml:"physical"` + Target *StorageTarget `xml:"target"` + BackingStore *StorageVolumeBackingStore `xml:"backingStore"` +} diff --git a/storage_test.go b/storage_test.go new file mode 100644 index 0000000..f47634a --- /dev/null +++ b/storage_test.go @@ -0,0 +1,413 @@ +/* + * This file is part of the libvirt-go-xml project + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * Copyright (C) 2017 Red Hat, Inc. + * + */ + +package libvirtxml + +import ( + "encoding/xml" + "strings" + "testing" +) + +var storagePoolTestData = []struct { + Object *StoragePool + Expected []string +}{ + { + Object: &StoragePool{ + Type: "dir", + Name: "pool", + UUID: "3e3fce45-4f53-4fa7-bb32-11f34168b82b", + Allocation: &Memory{ + Value: 1000000, + }, + Capacity: &Memory{ + Value: 5000000, + }, + Available: &Memory{ + Value: 3000000, + }, + }, + Expected: []string{ + `<pool type="dir">`, + ` <name>pool</name>`, + ` <uuid>3e3fce45-4f53-4fa7-bb32-11f34168b82b</uuid>`, + ` <allocation>1000000</allocation>`, + ` <capacity>5000000</capacity>`, + ` <available>3000000</available>`, + `</pool>`, + }, + }, + { + Object: &StoragePool{ + Type: "iscsi", + Name: "pool", + Source: &StoragePoolSource{ + Host: &StoragePoolSourceHost{ + Name: "host.example.com", + }, + Device: &StoragePoolSourceDevice{ + Path: "pool.example.com:iscsi-pool", + }, + Auth: &StoragePoolSourceAuth{ + Type: "chap", + Username: "username", + Secret: &StoragePoolSourceAuthSecret{ + Usage: "cluster", + }, + }, + Vendor: &StoragePoolSourceVendor{ + Name: "vendor", + }, + Product: &StoragePoolSourceProduct{ + Name: "product", + }, + }, + }, + Expected: []string{ + `<pool type="iscsi">`, + ` <name>pool</name>`, + ` <source>`, + ` <host name="host.example.com"></host>`, + ` <device path="pool.example.com:iscsi-pool"></device>`, + ` <auth type="chap" username="username">`, + ` <secret usage="cluster"></secret>`, + ` </auth>`, + ` <vendor name="vendor"></vendor>`, + ` <product name="product"></product>`, + ` </source>`, + `</pool>`, + }, + }, + { + Object: &StoragePool{ + Type: "disk", + Name: "pool", + Source: &StoragePoolSource{ + Device: &StoragePoolSourceDevice{ + Path: "/dev/mapper/pool", + PartSeparator: "no", + }, + Format: &StorageFormat{ + Type: "gpt", + }, + }, + }, + Expected: []string{ + `<pool type="disk">`, + ` <name>pool</name>`, + ` <source>`, + ` <device path="/dev/mapper/pool" part_separator="no"></device>`, + ` <format type="gpt"></format>`, + ` </source>`, + `</pool>`, + }, + }, + { + Object: &StoragePool{ + Type: "scsi", + Name: "pool", + Source: &StoragePoolSource{ + Adapter: &StoragePoolSourceAdapter{ + Type: "scsi_host", + Name: "scsi_host", + }, + }, + }, + Expected: []string{ + `<pool type="scsi">`, + ` <name>pool</name>`, + ` <source>`, + ` <adapter type="scsi_host" name="scsi_host"></adapter>`, + ` </source>`, + `</pool>`, + }, + }, + { + Object: &StoragePool{ + Type: "scsi", + Name: "pool", + Source: &StoragePoolSource{ + Adapter: &StoragePoolSourceAdapter{ + Type: "scsi_host", + ParentAddr: &StoragePoolSourceAdapterParentAddr{ + UniqueID: 1, + Address: &StoragePoolSourceAdapterParentAddrAddress{ + Domain: "0x0000", + Bus: "0x00", + Slot: "0x1f", + Addr: "0x2", + }, + }, + }, + }, + }, + Expected: []string{ + `<pool type="scsi">`, + ` <name>pool</name>`, + ` <source>`, + ` <adapter type="scsi_host">`, + ` <parentaddr unique_id="1">`, + ` <address domain="0x0000" bus="0x00" slot="0x1f" addr="0x2"></address>`, + ` </parentaddr>`, + ` </adapter>`, + ` </source>`, + `</pool>`, + }, + }, + { + Object: &StoragePool{ + Type: "fs", + Name: "pool", + Source: &StoragePoolSource{ + Adapter: &StoragePoolSourceAdapter{ + Type: "fc_host", + Parent: "scsi_parent", + WWNN: "20000000c9831b4b", + WWPN: "10000000c9831b4b", + }, + }, + }, + Expected: []string{ + `<pool type="fs">`, + ` <name>pool</name>`, + ` <source>`, + ` <adapter type="fc_host" parent="scsi_parent" wwnn="20000000c9831b4b" wwpn="10000000c9831b4b"></adapter>`, + ` </source>`, + `</pool>`, + }, + }, + { + Object: &StoragePool{ + Type: "dir", + Name: "pool", + Target: &StorageTarget{ + Path: "/pool", + Permissions: &StoragePermissions{ + Owner: "1", + Group: "1", + Mode: "0744", + Label: "pool", + }, + }, + }, + Expected: []string{ + `<pool type="dir">`, + ` <name>pool</name>`, + ` <target>`, + ` <path>/pool</path>`, + ` <permissions>`, + ` <owner>1</owner>`, + ` <group>1</group>`, + ` <mode>0744</mode>`, + ` <label>pool</label>`, + ` </permissions>`, + ` </target>`, + `</pool>`, + }, + }, +} + +func TestStoragePool(t *testing.T) { + for _, test := range storagePoolTestData { + doc, err := xml.MarshalIndent(test.Object, "", " ") + if err != nil { + t.Fatal(err) + } + + expect := strings.Join(test.Expected, "\n") + + if string(doc) != expect { + t.Fatal("Bad xml:\n", string(doc), "\n does not match\n", expect, "\n") + } + } +} + +var storageVolumeTestData = []struct { + Object *StorageVolume + Expected []string +}{ + { + Object: &StorageVolume{ + Type: "file", + Name: "file.img", + Key: "/file.img", + Allocation: &Memory{ + Value: 0, + }, + + Capacity: &Memory{ + Unit: "T", + Value: 1, + }, + }, + Expected: []string{ + `<volume type="file">`, + ` <name>file.img</name>`, + ` <key>/file.img</key>`, + ` <allocation>0</allocation>`, + ` <capacity unit="T">1</capacity>`, + `</volume>`, + }, + }, + { + Object: &StorageVolume{ + Type: "file", + Name: "file.img", + Target: &StorageTarget{ + Path: "/file.img", + Format: &StorageFormat{ + Type: "qcow2", + }, + Permissions: &StoragePermissions{ + Owner: "107", + Group: "107", + Mode: "0744", + Label: "image", + }, + Timestamps: &StorageTargetTimestamps{ + Atime: "1341933637.273190990", + Mtime: "1341930622.047245868", + Ctime: "1341930622.047245868", + }, + Compat: "1.1", + NoCOW: &struct{}{}, + Features: []StorageTargetFeature{ + StorageTargetFeature{ + LazyRefcounts: &struct{}{}, + }, + }, + }, + }, + Expected: []string{ + `<volume type="file">`, + ` <name>file.img</name>`, + ` <target>`, + ` <path>/file.img</path>`, + ` <format type="qcow2"></format>`, + ` <permissions>`, + ` <owner>107</owner>`, + ` <group>107</group>`, + ` <mode>0744</mode>`, + ` <label>image</label>`, + ` </permissions>`, + ` <timestamps>`, + ` <atime>1341933637.273190990</atime>`, + ` <mtime>1341930622.047245868</mtime>`, + ` <ctime>1341930622.047245868</ctime>`, + ` </timestamps>`, + ` <compat>1.1</compat>`, + ` <nocow></nocow>`, + ` <features>`, + ` <lazy_refcounts></lazy_refcounts>`, + ` </features>`, + ` </target>`, + `</volume>`, + }, + }, + { + Object: &StorageVolume{ + Type: "file", + Name: "file.img", + BackingStore: &StorageVolumeBackingStore{ + Path: "/master.img", + Format: &StorageFormat{ + Type: "raw", + }, + Permissions: &StoragePermissions{ + Owner: "107", + Group: "107", + Mode: "0744", + Label: "label", + }, + }, + }, + Expected: []string{ + `<volume type="file">`, + ` <name>file.img</name>`, + ` <backingStore>`, + ` <path>/master.img</path>`, + ` <format type="raw"></format>`, + ` <permissions>`, + ` <owner>107</owner>`, + ` <group>107</group>`, + ` <mode>0744</mode>`, + ` <label>label</label>`, + ` </permissions>`, + ` </backingStore>`, + `</volume>`, + }, + }, + { + Object: &StorageVolume{ + Name: "luks.img", + Capacity: &Memory{ + Unit: "G", + Value: 5, + }, + Target: &StorageTarget{ + Path: "/luks.img", + Format: &StorageFormat{ + Type: "raw", + }, + Encryption: &StorageTargetEncryption{ + Format: "luks", + Secret: &StorageTargetEncryptionSecret{ + Type: "passphrase", + UUID: "f52a81b2-424e-490c-823d-6bd4235bc572", + }, + }, + }, + }, + Expected: []string{ + `<volume>`, + ` <name>luks.img</name>`, + ` <capacity unit="G">5</capacity>`, + ` <target>`, + ` <path>/luks.img</path>`, + ` <format type="raw"></format>`, + ` <encryption format="luks">`, + ` <secret type="passphrase" uuid="f52a81b2-424e-490c-823d-6bd4235bc572"></secret>`, + ` </encryption>`, + ` </target>`, + `</volume>`, + }, + }, +} + +func TestStorageVolume(t *testing.T) { + for _, test := range storageVolumeTestData { + doc, err := xml.MarshalIndent(test.Object, "", " ") + if err != nil { + t.Fatal(err) + } + + expect := strings.Join(test.Expected, "\n") + + if string(doc) != expect { + t.Fatal("Bad xml:\n", string(doc), "\n does not match\n", expect, "\n") + } + } +} -- 2.11.0

On Fri, Jan 06, 2017 at 03:09:59PM +0100, Alexey Slaykovsky wrote:
Signed-off-by: Alexey Slaykovsky <aslaikov@redhat.com> --- domain.go | 9 +- domain_test.go | 8 +- memory.go | 31 +++++ storage.go | 159 ++++++++++++++++++++++ storage_test.go | 413 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 5 files changed, 609 insertions(+), 11 deletions(-) create mode 100644 memory.go create mode 100644 storage.go create mode 100644 storage_test.go
diff --git a/domain.go b/domain.go index ec2bd02..f8833a1 100644 --- a/domain.go +++ b/domain.go @@ -121,11 +121,6 @@ type DomainDeviceList struct { Videos []DomainVideo `xml:"video"` }
-type DomainMemory struct { - Value string `xml:",chardata"` - Unit string `xml:"unit,attr"` -} - type DomainOSType struct { Arch string `xml:"arch,attr"` Machine string `xml:"machine,attr"` @@ -194,8 +189,8 @@ type Domain struct { Type string `xml:"type,attr"` Name string `xml:"name"` UUID *string `xml:"uuid"` - Memory *DomainMemory `xml:"memory"` - CurrentMemory *DomainMemory `xml:"currentMemory"` + Memory *Memory `xml:"memory"` + CurrentMemory *Memory `xml:"currentMemory"` Devices *DomainDeviceList `xml:"devices"` OS *DomainOS `xml:"os"` SysInfo *DomainSysInfo `xml:"sysinfo"` diff --git a/domain_test.go b/domain_test.go index ae262e5..c22c384 100644 --- a/domain_test.go +++ b/domain_test.go @@ -125,13 +125,13 @@ var domainTestData = []struct { Object: &Domain{ Type: "kvm", Name: "test", - Memory: &DomainMemory{ + Memory: &Memory{ Unit: "KiB", - Value: "8192", + Value: 8192, }, - CurrentMemory: &DomainMemory{ + CurrentMemory: &Memory{ Unit: "KiB", - Value: "4096", + Value: 4096, }, OS: &DomainOS{ Type: &DomainOSType{ diff --git a/memory.go b/memory.go new file mode 100644 index 0000000..78844ac --- /dev/null +++ b/memory.go @@ -0,0 +1,31 @@
+package libvirtxml + +type Memory struct { + Unit string `xml:"unit,attr,omitempty"` + Value uint64 `xml:",chardata"` +}
Eww, no, we don't want todo this. Although the two schemas happen to have the same attributes currently, this isn't guaranteed in the future. IF the <memory> element in the domain XML gains extra attributes, we'd need to split out a DomainMemory struct once again, which would be a backwards incompatible change. So just keep the schemas fully separate from each other in this area. Also, the storage pool isn't representing memory, its representing disk usage, so the name is somewhat misleading
diff --git a/storage.go b/storage.go new file mode 100644 index 0000000..eccbee5 --- /dev/null +++ b/storage.go @@ -0,0 +1,159 @@
+ +package libvirtxml + +import "encoding/xml" + +type StorageFormat struct { + Type string `xml:"type,attr"` +} + +type StoragePermissions struct { + Owner string `xml:"owner,omitempty"` + Group string `xml:"group,omitempty"` + Mode string `xml:"mode,omitempty"` + Label string `xml:"label,omitempty"` +} + +type StorageTargetEncryptionSecret struct { + Type string `xml:"type,attr,omitempty"` + UUID string `xml:"uuid,attr,omitempty"` +} + +type StorageTargetEncryption struct { + Type string `xml:"type,attr,omitempty"` + Format string `xml:"format,attr,omitempty"` + Secret *StorageTargetEncryptionSecret `xml:"secret"` +} + +type StorageTargetTimestamps struct { + Atime string `xml:"atime"` + Mtime string `xml:"mtime"` + Ctime string `xml:"ctime"` +} + +type StorageTargetFeature struct { + LazyRefcounts *struct{} `xml:"lazy_refcounts"` +} + +type StorageTarget struct { + Path string `xml:"path,omitempty"` + Format *StorageFormat `xml:"format"` + Permissions *StoragePermissions `xml:"permissions"` + Timestamps *StorageTargetTimestamps `xml:"timestamps"` + Compat string `xml:"compat,omitempty"` + NoCOW *struct{} `xml:"nocow"` + Features []StorageTargetFeature `xml:"features"` + Encryption *StorageTargetEncryption `xml:"encryption"` +} + +type StoragePoolSourceHost struct { + Name string `xml:"name,attr"` +} + +type StoragePoolSourceDevice struct { + Path string `xml:"path,attr"` + PartSeparator string `xml:"part_separator,attr,omitempty"` +} + +type StoragePoolSourceAuthSecret struct { + Usage string `xml:"usage,attr"` +} + +type StoragePoolSourceAuth struct { + Type string `xml:"type,attr"` + Username string `xml:"username,attr"` + Secret *StoragePoolSourceAuthSecret `xml:"secret"` +} + +type StoragePoolSourceVendor struct { + Name string `xml:"name,attr"` +} + +type StoragePoolSourceProduct struct { + Name string `xml:"name,attr"` +} + +type StoragePoolSourceAdapterParentAddrAddress struct { + Domain string `xml:"domain,attr"` + Bus string `xml:"bus,attr"` + Slot string `xml:"slot,attr"` + Addr string `xml:"addr,attr"` +} + +type StoragePoolSourceAdapterParentAddr struct { + UniqueID uint64 `xml:"unique_id,attr"` + Address *StoragePoolSourceAdapterParentAddrAddress `xml:"address"` +} + +type StoragePoolSourceAdapter struct { + Type string `xml:"type,attr"` + Name string `xml:"name,attr,omitempty"` + Parent string `xml:"parent,attr,omitempty"` + WWNN string `xml:"wwnn,attr,omitempty"` + WWPN string `xml:"wwpn,attr,omitempty"` + ParentAddr *StoragePoolSourceAdapterParentAddr `xml:"parentaddr"` +} + +type StoragePoolSource struct { + Host *StoragePoolSourceHost `xml:"host"` + Device *StoragePoolSourceDevice `xml:"device"` + Auth *StoragePoolSourceAuth `xml:"auth"` + Vendor *StoragePoolSourceVendor `xml:"vendor"` + Product *StoragePoolSourceProduct `xml:"product"` + Format *StorageFormat `xml:"format"` + Adapter *StoragePoolSourceAdapter `xml:"adapter"` +} + +type StoragePool struct { + XMLName xml.Name `xml:"pool"` + Type string `xml:"type,attr"` + Name string `xml:"name"` + UUID string `xml:"uuid,omitempty"` + Allocation *Memory `xml:"allocation"` + Capacity *Memory `xml:"capacity"` + Available *Memory `xml:"available"` + Target *StorageTarget `xml:"target"` + Source *StoragePoolSource `xml:"source"` +} + +type StorageVolumeBackingStore struct { + Path string `xml:"path"` + Format *StorageFormat `xml:"format"`
This Format is not the same thing as the pool Format, so we should use separate structs.
+ Permissions *StoragePermissions `xml:"permissions"` +} + +type StorageVolume struct { + XMLName xml.Name `xml:"volume"` + Type string `xml:"type,attr,omitempty"` + Name string `xml:"name"` + Key string `xml:"key,omitempty"` + Allocation *Memory `xml:"allocation"` + Capacity *Memory `xml:"capacity"` + Physical *Memory `xml:"physical"` + Target *StorageTarget `xml:"target"`
Again, can you make sure to use separate StorageVolumeTarget and StoragePoolTarget structs to ensure future extensibility
+ BackingStore *StorageVolumeBackingStore `xml:"backingStore"` +}
Can you use storage_vol.go and storage_pool.go for these, since they are in fact separate XML schemas. Likewise for the test files. Regards, Daniel -- |: http://berrange.com -o- http://www.flickr.com/photos/dberrange/ :| |: http://libvirt.org -o- http://virt-manager.org :| |: http://entangle-photo.org -o- http://search.cpan.org/~danberr/ :|
participants (2)
-
Alexey Slaykovsky
-
Daniel P. Berrange