Signed-off-by: Alexey Slaykovsky <aslaikov@xxxxxxxxxx> --- storage.go | 114 +++++++++++++++++++++++++++ storage_test.go | 240 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 354 insertions(+) create mode 100644 storage.go create mode 100644 storage_test.go diff --git a/storage.go b/storage.go new file mode 100644 index 0000000..b45f58e --- /dev/null +++ b/storage.go @@ -0,0 +1,114 @@ +/* + * 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 StoragePoolTargetPermissions struct { + Owner string `xml:"owner"` + Group string `xml:"group"` + Mode string `xml:"mode"` + Label string `xml:"label"` +} + +type StoragePoolTarget struct { + Path string `xml:"path"` + Permissions *StoragePoolTargetPermissions `xml:"permissions"` +} + +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 StoragePoolSourceFormat struct { + Type string `xml:"type,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 *StoragePoolSourceFormat `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 uint64 `xml:"allocation,omitempty"` + Capacity uint64 `xml:"capacity,omitempty"` + Available uint64 `xml:"available,omitempty"` + Target *StoragePoolTarget `xml:"target"` + Source *StoragePoolSource `xml:"source"` +} diff --git a/storage_test.go b/storage_test.go new file mode 100644 index 0000000..f08eefe --- /dev/null +++ b/storage_test.go @@ -0,0 +1,240 @@ +/* + * 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 storageTestData = []struct { + Object *StoragePool + Expected []string +}{ + { + Object: &StoragePool{ + Type: "dir", + Name: "pool", + UUID: "3e3fce45-4f53-4fa7-bb32-11f34168b82b", + Allocation: 1000000, + Capacity: 5000000, + Available: 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: &StoragePoolSourceFormat{ + 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: &StoragePoolTarget{ + Path: "/pool", + Permissions: &StoragePoolTargetPermissions{ + 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 TestStorage(t *testing.T) { + for _, test := range storageTestData { + 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 -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list