mirror of
https://hubproxy.babadafafafafa.cn/https://github.com/yunionio/cloudpods.git
synced 2026-09-20 08:03:53 +08:00
guest import from libvirt (#11)
* import servers from libvirt * dep add libvirt-go-xml * fix code * fix code
This commit is contained in:
9
Gopkg.lock
generated
9
Gopkg.lock
generated
@@ -851,6 +851,14 @@
|
||||
revision = "db8e3cd836b82e82e0a9c8edc6896967dd31374f"
|
||||
version = "v1.1.3"
|
||||
|
||||
[[projects]]
|
||||
branch = "master"
|
||||
digest = "1:74e674486930998805335f2b2f0af5fd3b183c755973e53f532363a56831b7a3"
|
||||
name = "github.com/libvirt/libvirt-go-xml"
|
||||
packages = ["."]
|
||||
pruneopts = "UT"
|
||||
revision = "4b6d354bfe8a0c85cebc68f0f7e45f7d5a37de7b"
|
||||
|
||||
[[projects]]
|
||||
digest = "1:4e878df5f4e9fd625bf9c9aac77ef7cbfa4a74c01265505527c23470c0e40300"
|
||||
name = "github.com/marstr/guid"
|
||||
@@ -1827,6 +1835,7 @@
|
||||
"github.com/json-iterator/go",
|
||||
"github.com/koding/websocketproxy",
|
||||
"github.com/kr/pty",
|
||||
"github.com/libvirt/libvirt-go-xml",
|
||||
"github.com/mholt/caddy",
|
||||
"github.com/mholt/caddy/startupshutdown",
|
||||
"github.com/miekg/dns",
|
||||
|
||||
@@ -206,4 +206,7 @@
|
||||
|
||||
[[constraint]]
|
||||
name="github.com/ceph/go-ceph"
|
||||
branch = "master"
|
||||
branch = "master"
|
||||
[[constraint]]
|
||||
branch = "master"
|
||||
name = "github.com/libvirt/libvirt-go-xml"
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
package shell
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
@@ -23,6 +24,7 @@ import (
|
||||
"yunion.io/x/jsonutils"
|
||||
"yunion.io/x/log"
|
||||
|
||||
"yunion.io/x/onecloud/pkg/apis/compute"
|
||||
"yunion.io/x/onecloud/pkg/mcclient"
|
||||
"yunion.io/x/onecloud/pkg/mcclient/modules"
|
||||
"yunion.io/x/onecloud/pkg/mcclient/options"
|
||||
@@ -806,4 +808,33 @@ func init() {
|
||||
}
|
||||
return nil
|
||||
})
|
||||
|
||||
type ServersImportFromLibvirtOptions struct {
|
||||
CONFIG_FILE string `help:"JSON file describing servers from libvirt, e.g. {'hosts': [{'servers': [{'uuid': 'id', 'mac_ip': {'mac1': 'ip1', ...}}]]}}"`
|
||||
}
|
||||
R(&ServersImportFromLibvirtOptions{}, "servers-import-from-libvirt", "Import servers from libvrt", func(s *mcclient.ClientSession, args *ServersImportFromLibvirtOptions) error {
|
||||
rawConfig, err := ioutil.ReadFile(args.CONFIG_FILE)
|
||||
if err != nil {
|
||||
return fmt.Errorf("Read file error: %s", err)
|
||||
}
|
||||
|
||||
config := &compute.SLibvirtImportConfig{}
|
||||
err = json.Unmarshal(rawConfig, config)
|
||||
if err != nil {
|
||||
return fmt.Errorf("Parse config error %s", err)
|
||||
}
|
||||
params, err := jsonutils.Marshal(config.Hosts).GetArray()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
for i := 0; i < len(params); i++ {
|
||||
val := jsonutils.NewDict()
|
||||
val.Set(modules.Servers.KeywordPlural, params[i])
|
||||
params[i] = val
|
||||
}
|
||||
|
||||
results := modules.Servers.BatchPerformClassAction(s, "import-from-libvirt", params)
|
||||
printBatchResults(results, modules.Servers.GetColumns(s))
|
||||
return nil
|
||||
})
|
||||
}
|
||||
|
||||
@@ -104,6 +104,9 @@ const (
|
||||
|
||||
VM_ADMIN = "admin"
|
||||
|
||||
VM_IMPORT = "import"
|
||||
VM_IMPORT_FAILED = "import_fail"
|
||||
|
||||
SHUTDOWN_STOP = "stop"
|
||||
SHUTDOWN_TERMINATE = "terminate"
|
||||
|
||||
|
||||
71
pkg/apis/compute/guest_import_api.go
Normal file
71
pkg/apis/compute/guest_import_api.go
Normal file
@@ -0,0 +1,71 @@
|
||||
package compute
|
||||
|
||||
type SImportNic struct {
|
||||
Index int `json:"index"`
|
||||
Bridge string `json:"bridge"`
|
||||
Domain string `json:"domain"`
|
||||
Ip string `json:"ip"`
|
||||
Vlan int `json:"vlan"`
|
||||
Driver string `json:"driver"`
|
||||
Masklen int `json:"masklen"`
|
||||
Virtual bool `json:"virtual"`
|
||||
Manual bool `json:"manual"`
|
||||
WireId string `json:"wire_id"`
|
||||
NetId string `json:"net_id"`
|
||||
Mac string `json:"mac"`
|
||||
BandWidth int `json:"bw"`
|
||||
Dns string `json:"dns"`
|
||||
Net string `json:"net"`
|
||||
Interface string `json:"interface"`
|
||||
Gateway string `json:"gateway"`
|
||||
Ifname string `json:"ifname"`
|
||||
}
|
||||
|
||||
type SImportDisk struct {
|
||||
Index int `json:"index"`
|
||||
DiskId string `json:"disk_id"`
|
||||
Driver string `json:"driver"`
|
||||
CacheMode string `json:"cache_mode"`
|
||||
AioMode string `json:"aio_mode"`
|
||||
SizeMb int `json:"size"`
|
||||
Format string `json:"format"`
|
||||
Fs string `json:"fs"`
|
||||
Mountpoint string `json:"mountpoint"`
|
||||
Dev string `json:"dev"`
|
||||
TemplateId string `json:"template_id"`
|
||||
AccessPath string `json:"AccessPath"`
|
||||
Backend string `json:"Backend"`
|
||||
}
|
||||
|
||||
type SImportGuestDesc struct {
|
||||
Id string `json:"uuid"`
|
||||
Name string `json:"name"`
|
||||
Nics []SImportNic `json:"nics"`
|
||||
Disks []SImportDisk `json:"disks"`
|
||||
Metadata map[string]string `json:"metadata"`
|
||||
MemSizeMb int `json:"mem"`
|
||||
Cpu int `json:"cpu"`
|
||||
TemplateId string `json:"template_id"`
|
||||
ImagePath string `json:"image_path"`
|
||||
Vdi string `json:"vdi"`
|
||||
Hypervisor string `json:"hypervisor"`
|
||||
HostId string `json:"host"`
|
||||
BootOrder string `json:"boot_order"`
|
||||
IsSystem bool `json:"is_system"`
|
||||
Description string `json:"description"`
|
||||
}
|
||||
|
||||
type SLibvirtServerConfig struct {
|
||||
Uuid string `json:"uuid"`
|
||||
MacIp map[string]string `json:"mac_ip"`
|
||||
}
|
||||
|
||||
type SLibvirtHostConfig struct {
|
||||
Servers []SLibvirtServerConfig `json:"servers"`
|
||||
XmlFilePath string `json:"xml_file_path"`
|
||||
HostIp string `json:"host_ip"`
|
||||
}
|
||||
|
||||
type SLibvirtImportConfig struct {
|
||||
Hosts []SLibvirtHostConfig `json:"hosts"`
|
||||
}
|
||||
@@ -188,6 +188,11 @@ const (
|
||||
|
||||
ACT_RECYCLE_PREPAID = "recycle_prepaid"
|
||||
ACT_UNDO_RECYCLE_PREPAID = "undo_recycle_prepaid"
|
||||
|
||||
ACT_HOST_IMPORT_LIBVIRT_SERVERS = "host_import_libvirt_servers"
|
||||
ACT_HOST_IMPORT_LIBVIRT_SERVERS_FAIL = "host_import_libvirt_servers_fail"
|
||||
ACT_GUEST_CREATE_FROM_IMPORT_SUCC = "guest_create_from_import_succ"
|
||||
ACT_GUEST_CREATE_FROM_IMPORT_FAIL = "guest_create_from_import_fail"
|
||||
)
|
||||
|
||||
type SOpsLogManager struct {
|
||||
|
||||
@@ -2781,91 +2781,9 @@ func (man *SGuestManager) AllowPerformImport(ctx context.Context, userCred mccli
|
||||
return db.IsAdminAllowClassPerform(userCred, man, "import")
|
||||
}
|
||||
|
||||
type SImportNic struct {
|
||||
Index int `json:"index"`
|
||||
Bridge string `json:"bridge"`
|
||||
Domain string `json:"domain"`
|
||||
Ip string `json:"ip"`
|
||||
Vlan int `json:"vlan"`
|
||||
Driver string `json:"driver"`
|
||||
Masklen int `json:"masklen"`
|
||||
Virtual bool `json:"virtual"`
|
||||
Manual bool `json:"manual"`
|
||||
WireId string `json:"wire_id"`
|
||||
NetId string `json:"net_id"`
|
||||
Mac string `json:"mac"`
|
||||
BandWidth int `json:"bw"`
|
||||
Dns string `json:"dns"`
|
||||
Net string `json:"net"`
|
||||
Interface string `json:"interface"`
|
||||
Gateway string `json:"gateway"`
|
||||
Ifname string `json:"ifname"`
|
||||
}
|
||||
|
||||
func (n SImportNic) ToNetConfig(net *SNetwork) *api.NetworkConfig {
|
||||
return &api.NetworkConfig{
|
||||
Network: net.Id,
|
||||
Wire: net.WireId,
|
||||
Address: n.Ip,
|
||||
Mac: n.Mac,
|
||||
Driver: n.Driver,
|
||||
BwLimit: n.BandWidth,
|
||||
}
|
||||
}
|
||||
|
||||
type SImportDisk struct {
|
||||
Index int `json:"index"`
|
||||
DiskId string `json:"disk_id"`
|
||||
Driver string `json:"driver"`
|
||||
CacheMode string `json:"cache_mode"`
|
||||
AioMode string `json:"aio_mode"`
|
||||
SizeMb int `json:"size"`
|
||||
Format string `json:"format"`
|
||||
Fs string `json:"fs"`
|
||||
Mountpoint string `json:"mountpoint"`
|
||||
Dev string `json:"dev"`
|
||||
TemplateId string `json:"template_id"`
|
||||
}
|
||||
|
||||
func (d SImportDisk) ToDiskConfig() *api.DiskConfig {
|
||||
ret := &api.DiskConfig{
|
||||
SizeMb: d.SizeMb,
|
||||
ImageId: d.TemplateId,
|
||||
Format: d.Format,
|
||||
Driver: d.Driver,
|
||||
DiskId: d.DiskId,
|
||||
Cache: d.CacheMode,
|
||||
}
|
||||
if len(d.Mountpoint) > 0 {
|
||||
ret.Mountpoint = d.Mountpoint
|
||||
}
|
||||
if len(d.Fs) > 0 {
|
||||
ret.Fs = d.Fs
|
||||
}
|
||||
return ret
|
||||
}
|
||||
|
||||
type SImportGuestDesc struct {
|
||||
Id string `json:"uuid"`
|
||||
Name string `json:"name"`
|
||||
Nics []SImportNic `json:"nics"`
|
||||
Disks []SImportDisk `json:"disks"`
|
||||
Metadata map[string]string `json:"metadata"`
|
||||
MemSizeMb int `json:"mem"`
|
||||
Cpu int `json:"cpu"`
|
||||
TemplateId string `json:"template_id"`
|
||||
ImagePath string `json:"image_path"`
|
||||
Vdi string `json:"vdi"`
|
||||
Hypervisor string `json:"hypervisor"`
|
||||
HostId string `json:"host"`
|
||||
BootOrder string `json:"boot_order"`
|
||||
IsSystem bool `json:"is_system"`
|
||||
Description string `json:"description"`
|
||||
}
|
||||
|
||||
func (man *SGuestManager) PerformImport(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject, data jsonutils.JSONObject) (jsonutils.JSONObject, error) {
|
||||
desc := SImportGuestDesc{}
|
||||
if err := data.Unmarshal(&desc); err != nil {
|
||||
desc := &api.SImportGuestDesc{}
|
||||
if err := data.Unmarshal(desc); err != nil {
|
||||
return nil, httperrors.NewInputParameterError("Invalid desc: %s", data.String())
|
||||
}
|
||||
if len(desc.Id) == 0 {
|
||||
@@ -2885,6 +2803,16 @@ func (man *SGuestManager) PerformImport(ctx context.Context, userCred mcclient.T
|
||||
} else {
|
||||
desc.HostId = hostObj.GetId()
|
||||
}
|
||||
guset, err := man.DoImport(ctx, userCred, desc)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return jsonutils.Marshal(guset), nil
|
||||
}
|
||||
|
||||
func (man *SGuestManager) DoImport(
|
||||
ctx context.Context, userCred mcclient.TokenCredential, desc *api.SImportGuestDesc,
|
||||
) (*SGuest, error) {
|
||||
// 1. create import guest on host
|
||||
gst, err := man.createImportGuest(ctx, userCred, desc)
|
||||
if err != nil {
|
||||
@@ -2902,10 +2830,10 @@ func (man *SGuestManager) PerformImport(ctx context.Context, userCred mcclient.T
|
||||
for k, v := range desc.Metadata {
|
||||
gst.SetMetadata(ctx, k, v, userCred)
|
||||
}
|
||||
return jsonutils.Marshal(gst), nil
|
||||
return gst, nil
|
||||
}
|
||||
|
||||
func (man *SGuestManager) createImportGuest(ctx context.Context, userCred mcclient.TokenCredential, desc SImportGuestDesc) (*SGuest, error) {
|
||||
func (man *SGuestManager) createImportGuest(ctx context.Context, userCred mcclient.TokenCredential, desc *api.SImportGuestDesc) (*SGuest, error) {
|
||||
model, err := db.NewModelObject(man)
|
||||
if err != nil {
|
||||
return nil, httperrors.NewGeneralError(err)
|
||||
@@ -2919,7 +2847,7 @@ func (man *SGuestManager) createImportGuest(ctx context.Context, userCred mcclie
|
||||
gst.Id = desc.Id
|
||||
gst.Name = desc.Name
|
||||
gst.HostId = desc.HostId
|
||||
gst.Status = "import"
|
||||
gst.Status = api.VM_IMPORT
|
||||
gst.Hypervisor = desc.Hypervisor
|
||||
gst.VmemSize = desc.MemSizeMb
|
||||
gst.VcpuCount = int8(desc.Cpu)
|
||||
@@ -2929,7 +2857,18 @@ func (man *SGuestManager) createImportGuest(ctx context.Context, userCred mcclie
|
||||
return gst, err
|
||||
}
|
||||
|
||||
func (self *SGuest) importNics(ctx context.Context, userCred mcclient.TokenCredential, nics []SImportNic) error {
|
||||
func ToNetConfig(n *api.SImportNic, net *SNetwork) *api.NetworkConfig {
|
||||
return &api.NetworkConfig{
|
||||
Network: net.Id,
|
||||
Wire: net.WireId,
|
||||
Address: n.Ip,
|
||||
Mac: n.Mac,
|
||||
Driver: n.Driver,
|
||||
BwLimit: n.BandWidth,
|
||||
}
|
||||
}
|
||||
|
||||
func (self *SGuest) importNics(ctx context.Context, userCred mcclient.TokenCredential, nics []api.SImportNic) error {
|
||||
if len(nics) == 0 {
|
||||
return httperrors.NewInputParameterError("Empty import nics")
|
||||
}
|
||||
@@ -2938,7 +2877,7 @@ func (self *SGuest) importNics(ctx context.Context, userCred mcclient.TokenCrede
|
||||
if err != nil {
|
||||
return httperrors.NewNotFoundError("Not found network by ip %s", nic.Ip)
|
||||
}
|
||||
_, err = self.attach2NetworkDesc(ctx, userCred, self.GetHost(), nic.ToNetConfig(net), nil)
|
||||
_, err = self.attach2NetworkDesc(ctx, userCred, self.GetHost(), ToNetConfig(&nic, net), nil)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -2946,12 +2885,31 @@ func (self *SGuest) importNics(ctx context.Context, userCred mcclient.TokenCrede
|
||||
return nil
|
||||
}
|
||||
|
||||
func (self *SGuest) importDisks(ctx context.Context, userCred mcclient.TokenCredential, disks []SImportDisk) error {
|
||||
func ToDiskConfig(d *api.SImportDisk) *api.DiskConfig {
|
||||
ret := &api.DiskConfig{
|
||||
SizeMb: d.SizeMb,
|
||||
ImageId: d.TemplateId,
|
||||
Format: d.Format,
|
||||
Driver: d.Driver,
|
||||
DiskId: d.DiskId,
|
||||
Cache: d.CacheMode,
|
||||
Backend: d.Backend,
|
||||
}
|
||||
if len(d.Mountpoint) > 0 {
|
||||
ret.Mountpoint = d.Mountpoint
|
||||
}
|
||||
if len(d.Fs) > 0 {
|
||||
ret.Fs = d.Fs
|
||||
}
|
||||
return ret
|
||||
}
|
||||
|
||||
func (self *SGuest) importDisks(ctx context.Context, userCred mcclient.TokenCredential, disks []api.SImportDisk) error {
|
||||
if len(disks) == 0 {
|
||||
return httperrors.NewInputParameterError("Empty import disks")
|
||||
}
|
||||
for _, disk := range disks {
|
||||
disk, err := self.createDiskOnHost(ctx, userCred, self.GetHost(), disk.ToDiskConfig(), nil, true, true, nil)
|
||||
disk, err := self.createDiskOnHost(ctx, userCred, self.GetHost(), ToDiskConfig(&disk), nil, true, true, nil)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -2959,3 +2917,35 @@ func (self *SGuest) importDisks(ctx context.Context, userCred mcclient.TokenCred
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (manager *SGuestManager) AllowPerformImportFromLibvirt(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject, data jsonutils.JSONObject) bool {
|
||||
return db.IsAdminAllowClassPerform(userCred, manager, "import-from-libvirt")
|
||||
}
|
||||
|
||||
func (manager *SGuestManager) PerformImportFromLibvirt(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject, data jsonutils.JSONObject) (jsonutils.JSONObject, error) {
|
||||
host := &api.SLibvirtHostConfig{}
|
||||
if err := data.Unmarshal(host); err != nil {
|
||||
return nil, httperrors.NewInputParameterError("Unmarshal data error %s", err)
|
||||
}
|
||||
if len(host.XmlFilePath) == 0 {
|
||||
return nil, httperrors.NewInputParameterError("Some host config missing xml_file_path")
|
||||
}
|
||||
if len(host.HostIp) == 0 {
|
||||
return nil, httperrors.NewInputParameterError("Some host config missing host ip")
|
||||
}
|
||||
sHost, err := HostManager.GetHostByIp(host.HostIp)
|
||||
if err != nil {
|
||||
return nil, httperrors.NewInputParameterError("Invalid host ip %s", host.HostIp)
|
||||
}
|
||||
|
||||
taskData := jsonutils.NewDict()
|
||||
taskData.Set("xml_file_path", jsonutils.NewString(host.XmlFilePath))
|
||||
taskData.Set("servers", jsonutils.Marshal(host.Servers))
|
||||
task, err := taskman.TaskManager.NewTask(ctx, "HostImportLibvirtServersTask", sHost, userCred,
|
||||
taskData, "", "", nil)
|
||||
if err != nil {
|
||||
return nil, httperrors.NewInternalServerError("NewTask error: %s", err)
|
||||
}
|
||||
task.ScheduleRun(nil)
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
@@ -2647,7 +2647,7 @@ func (self *SGuest) createDiskOnStorage(ctx context.Context, userCred mcclient.T
|
||||
}
|
||||
|
||||
func (self *SGuest) ChooseHostStorage(host *SHost, backend string, candidate *schedapi.CandidateDisk) *SStorage {
|
||||
log.Errorf("==========candidate %#v", candidate)
|
||||
log.Infof("==========candidate %#v", candidate)
|
||||
if candidate == nil {
|
||||
return self.GetDriver().ChooseHostStorage(host, backend)
|
||||
}
|
||||
|
||||
@@ -223,100 +223,6 @@ func (zone *SZone) getNetworkCount() int {
|
||||
return getNetworkCount(nil, zone)
|
||||
}
|
||||
|
||||
/*def host_count(self, status=None, host_status=None, enabled=None, host_type=None, is_baremetal=None):
|
||||
from hosts import Hosts
|
||||
q = Hosts.query().filter(Hosts.zone_id==self.id)
|
||||
if status is not None:
|
||||
q = q.filter(Hosts.status==status)
|
||||
if host_status is not None:
|
||||
q = q.filter(Hosts.host_status==host_status)
|
||||
if enabled is not None:
|
||||
q = q.filter(Hosts.enabled==enabled)
|
||||
if host_type is not None:
|
||||
q = q.filter(Hosts.host_type==host_type)
|
||||
if is_baremetal is not None:
|
||||
q = q.filter(Hosts.is_baremetal==is_baremetal)
|
||||
return q.count()
|
||||
|
||||
def wire_count(self):
|
||||
from wires import Wires
|
||||
q = Wires.query().filter(Wires.zone_id==self.id)
|
||||
return q.count()
|
||||
*/
|
||||
|
||||
/*
|
||||
|
||||
@classmethod
|
||||
def get_resident_zones_of_tenant(cls, tenant_id):
|
||||
from guests import Guests
|
||||
from hosts import Hosts
|
||||
q = Zones.query(Zones.id, func.count('*')) \
|
||||
.join(Hosts, and_(Hosts.zone_id==Zones.id,
|
||||
Hosts.deleted==False,
|
||||
Hosts.enabled==True,
|
||||
Hosts.host_status==Hosts.HOST_ONLINE)) \
|
||||
.join(Guests, and_(Guests.host_id==Hosts.id,
|
||||
Guests.deleted==False)) \
|
||||
.filter(Guests.tenant_id==tenant_id) \
|
||||
.group_by(Zones.id)
|
||||
ret = []
|
||||
for (zone_id, guest_cnt) in q.all():
|
||||
ret.append((Zones.fetch(zone_id), guest_cnt))
|
||||
return ret
|
||||
|
||||
@classmethod
|
||||
def get_default_schedule_zone_of_tenant(cls, user_cred, tenant_id, params,
|
||||
count=1):
|
||||
from guests import Guests
|
||||
zones = cls.get_resident_zones_of_tenant(tenant_id)
|
||||
if len(zones) == 0:
|
||||
if options.default_zone is not None:
|
||||
zone = Zones.fetch(options.default_zone)
|
||||
ret = Guests.check_resource_limit(user_cred, params, count,
|
||||
range_obj=zone)
|
||||
if len(ret) > 0:
|
||||
logging.error('Default zone out of resources')
|
||||
return None
|
||||
else:
|
||||
return zone
|
||||
else:
|
||||
sel_z = None
|
||||
max_cnt = 0
|
||||
for (z, gcnt) in zones:
|
||||
ret = Guests.check_resource_limit(user_cred, params, count,
|
||||
range_obj=z)
|
||||
if len(ret) == 0:
|
||||
if max_cnt < gcnt:
|
||||
sel_z = z
|
||||
max_cnt = gcnt
|
||||
return sel_z
|
||||
|
||||
def get_wires(self):
|
||||
from wires import Wires
|
||||
q = Wires.query().filter(Wires.zone_id==self.id)
|
||||
return q.all()
|
||||
|
||||
def get_name_cn(self):
|
||||
return self.name_cn or self.name
|
||||
|
||||
|
||||
def get_more_details(self):
|
||||
ret = {}
|
||||
ret.update(self.general_usage(None))
|
||||
return ret
|
||||
|
||||
def get_customize_columns(self, user_cred, kwargs):
|
||||
ret = super(Zones, self).get_customize_columns(user_cred, kwargs)
|
||||
ret.update(self.get_more_details())
|
||||
return ret
|
||||
|
||||
def get_details(self, user_cred, kwargs):
|
||||
ret = super(Zones, self).get_details(user_cred, kwargs)
|
||||
ret.update(self.get_more_details())
|
||||
return ret
|
||||
|
||||
*/
|
||||
|
||||
func zoneExtra(zone *SZone, extra *jsonutils.JSONDict) *jsonutils.JSONDict {
|
||||
usage := zone.GeneralUsage()
|
||||
extra.Update(jsonutils.Marshal(usage))
|
||||
|
||||
222
pkg/compute/tasks/host_import_libvirt_servers_task.go
Normal file
222
pkg/compute/tasks/host_import_libvirt_servers_task.go
Normal file
@@ -0,0 +1,222 @@
|
||||
package tasks
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
|
||||
"yunion.io/x/jsonutils"
|
||||
"yunion.io/x/log"
|
||||
"yunion.io/x/pkg/util/stringutils"
|
||||
|
||||
"yunion.io/x/onecloud/pkg/apis/compute"
|
||||
"yunion.io/x/onecloud/pkg/cloudcommon/db"
|
||||
"yunion.io/x/onecloud/pkg/cloudcommon/db/taskman"
|
||||
"yunion.io/x/onecloud/pkg/compute/models"
|
||||
"yunion.io/x/onecloud/pkg/util/logclient"
|
||||
)
|
||||
|
||||
func init() {
|
||||
taskman.RegisterTask(HostImportLibvirtServersTask{})
|
||||
taskman.RegisterTask(CreateImportedLibvirtGuestTask{})
|
||||
}
|
||||
|
||||
type HostImportLibvirtServersTask struct {
|
||||
taskman.STask
|
||||
}
|
||||
|
||||
func (self *HostImportLibvirtServersTask) OnInit(
|
||||
ctx context.Context, obj db.IStandaloneModel, body jsonutils.JSONObject,
|
||||
) {
|
||||
host := obj.(*models.SHost)
|
||||
self.SetStage("OnRequestHostPrepareImport", nil)
|
||||
self.RequestHostPrepareImport(ctx, host)
|
||||
}
|
||||
|
||||
func (self *HostImportLibvirtServersTask) RequestHostPrepareImport(
|
||||
ctx context.Context, host *models.SHost,
|
||||
) {
|
||||
header := self.GetTaskRequestHeader()
|
||||
if _, err := host.Request(ctx, self.UserCred, "POST",
|
||||
"/servers/prepare-import-from-libvirt", header, self.Params); err != nil {
|
||||
self.TaskFailed(ctx, host, err.Error())
|
||||
}
|
||||
}
|
||||
|
||||
func (self *HostImportLibvirtServersTask) OnRequestHostPrepareImport(
|
||||
ctx context.Context, host *models.SHost, body jsonutils.JSONObject,
|
||||
) {
|
||||
serversNotMatch, _ := body.GetArray("servers_not_match")
|
||||
if len(serversNotMatch) > 0 {
|
||||
db.OpsLog.LogEvent(host, db.ACT_HOST_IMPORT_LIBVIRT_SERVERS,
|
||||
fmt.Sprintf("Servers %s not match host xml description", serversNotMatch), self.UserCred)
|
||||
logclient.AddActionLogWithContext(ctx, host, logclient.ACT_HOST_IMPORT_LIBVIRT_SERVERS,
|
||||
fmt.Sprintf("Servers %s not match host xml description", serversNotMatch), self.UserCred, false)
|
||||
}
|
||||
|
||||
serversMatched, _ := body.Get("servers_matched")
|
||||
if serversMatched == nil {
|
||||
self.TaskFailed(ctx, host, "No matched server found")
|
||||
return
|
||||
}
|
||||
|
||||
guestsDesc := []compute.SImportGuestDesc{}
|
||||
if err := serversMatched.Unmarshal(&guestsDesc); err != nil {
|
||||
self.TaskFailed(ctx, host, fmt.Sprintf("Unmarshal matched servers failed: %s", err))
|
||||
return
|
||||
}
|
||||
self.StartImportServers(ctx, host, guestsDesc)
|
||||
}
|
||||
|
||||
func (self *HostImportLibvirtServersTask) StartImportServers(
|
||||
ctx context.Context, host *models.SHost, guestsDesc []compute.SImportGuestDesc,
|
||||
) {
|
||||
var (
|
||||
note string
|
||||
success bool
|
||||
)
|
||||
for i := 0; i < len(guestsDesc); i++ {
|
||||
self.FillLibvirtGuestDesc(ctx, host, &guestsDesc[i])
|
||||
guest, err := models.GuestManager.DoImport(ctx, self.UserCred, &guestsDesc[i])
|
||||
if err != nil {
|
||||
note = fmt.Sprintf("Guest %s import failed: %s", guestsDesc[i].Id, err)
|
||||
success = false
|
||||
goto end
|
||||
}
|
||||
if err := self.CreateImportedLibvirtGuestOnHost(ctx, host, guest, &guestsDesc[i]); err != nil {
|
||||
note = fmt.Sprintf("Guest %s create on host failed: %s", guestsDesc[i].Id, err)
|
||||
success = false
|
||||
goto end
|
||||
}
|
||||
note = fmt.Sprintf("Guest %s import success, started create on host", guestsDesc[i].Id)
|
||||
success = true
|
||||
|
||||
end:
|
||||
if success {
|
||||
db.OpsLog.LogEvent(host, db.ACT_HOST_IMPORT_LIBVIRT_SERVERS, note, self.UserCred)
|
||||
} else {
|
||||
log.Errorln(note)
|
||||
db.OpsLog.LogEvent(host, db.ACT_HOST_IMPORT_LIBVIRT_SERVERS_FAIL, note, self.UserCred)
|
||||
}
|
||||
logclient.AddActionLogWithContext(ctx, host,
|
||||
logclient.ACT_HOST_IMPORT_LIBVIRT_SERVERS, note, self.UserCred, success)
|
||||
}
|
||||
self.SetStageComplete(ctx, nil)
|
||||
}
|
||||
|
||||
func (self *HostImportLibvirtServersTask) FillLibvirtGuestDesc(
|
||||
ctx context.Context, host *models.SHost, guestDesc *compute.SImportGuestDesc,
|
||||
) {
|
||||
// Generate new uuid for guest to prevent duplicate
|
||||
guestDesc.Id = stringutils.UUID4()
|
||||
guestDesc.HostId = host.Id
|
||||
g, _ := models.GuestManager.FetchByName(self.UserCred, guestDesc.Name)
|
||||
if g != nil {
|
||||
guestDesc.Name = db.GenerateName(models.GuestManager, self.UserCred.GetProjectId(), guestDesc.Name)
|
||||
}
|
||||
for i := 0; i < len(guestDesc.Disks); i++ {
|
||||
guestDesc.Disks[i].DiskId = stringutils.UUID4()
|
||||
if len(guestDesc.Disks[i].Backend) == 0 {
|
||||
guestDesc.Disks[i].Backend = models.STORAGE_LOCAL
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Create sub task to create guest on host, and feedback disk real access path
|
||||
func (self *HostImportLibvirtServersTask) CreateImportedLibvirtGuestOnHost(
|
||||
ctx context.Context, host *models.SHost, guest *models.SGuest, guestDesc *compute.SImportGuestDesc,
|
||||
) error {
|
||||
task, err := taskman.TaskManager.NewTask(
|
||||
ctx, "CreateImportedLibvirtGuestTask", guest, self.UserCred, nil, "", "", nil)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
disksPath := jsonutils.NewDict()
|
||||
for _, disk := range guestDesc.Disks {
|
||||
disksPath.Set(disk.DiskId, jsonutils.NewString(disk.AccessPath))
|
||||
}
|
||||
body := jsonutils.NewDict()
|
||||
body.Set("desc", guest.GetJsonDescAtHypervisor(ctx, host))
|
||||
body.Set("disks_path", disksPath)
|
||||
|
||||
_, err = host.Request(ctx, self.UserCred, "POST",
|
||||
fmt.Sprintf("/servers/%s/create-from-libvirt", guest.Id),
|
||||
task.GetTaskRequestHeader(), body)
|
||||
return err
|
||||
}
|
||||
|
||||
func (self *HostImportLibvirtServersTask) TaskFailed(
|
||||
ctx context.Context, host *models.SHost, reason string,
|
||||
) {
|
||||
self.SetStageFailed(ctx, reason)
|
||||
db.OpsLog.LogEvent(host, db.ACT_HOST_IMPORT_LIBVIRT_SERVERS_FAIL, reason, self.UserCred)
|
||||
logclient.AddActionLogWithContext(ctx, host,
|
||||
logclient.ACT_HOST_IMPORT_LIBVIRT_SERVERS, reason, self.UserCred, false)
|
||||
}
|
||||
|
||||
type CreateImportedLibvirtGuestTask struct {
|
||||
taskman.STask
|
||||
}
|
||||
|
||||
func (self *CreateImportedLibvirtGuestTask) OnInit(
|
||||
ctx context.Context, obj db.IStandaloneModel, body jsonutils.JSONObject,
|
||||
) {
|
||||
guest := obj.(*models.SGuest)
|
||||
disksPath, err := body.GetMap("disks_path")
|
||||
if err != nil {
|
||||
self.TaskFailed(ctx, guest, "guest create on host no disk access path feedback")
|
||||
}
|
||||
guestDisks := guest.GetDisks()
|
||||
for i := 0; i < len(guestDisks); i++ {
|
||||
disk := guestDisks[i].GetDisk()
|
||||
if accessPath, ok := disksPath[disk.Id]; !ok {
|
||||
self.TaskFailed(ctx, guest, fmt.Sprintf("Guest missing disk %s access path", disk.Id))
|
||||
return
|
||||
} else {
|
||||
_, err := db.Update(disk, func() error {
|
||||
disk.AccessPath = accessPath.String()
|
||||
if guestDisks[i].Index == 0 {
|
||||
disk.DiskType = models.DISK_TYPE_SYS
|
||||
}
|
||||
return nil
|
||||
})
|
||||
if err != nil {
|
||||
self.TaskFailed(ctx, guest, fmt.Sprintf("Guest set disk access path error %s", err))
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
self.SetStage("OnGuestSync", nil)
|
||||
guest.StartSyncTask(ctx, self.UserCred, false, self.GetTaskId())
|
||||
}
|
||||
|
||||
func (self *CreateImportedLibvirtGuestTask) OnGuestSync(
|
||||
ctx context.Context, guest *models.SGuest, body jsonutils.JSONObject,
|
||||
) {
|
||||
db.OpsLog.LogEvent(guest, db.ACT_GUEST_CREATE_FROM_IMPORT_SUCC, "", self.UserCred)
|
||||
logclient.AddActionLogWithContext(ctx, guest,
|
||||
logclient.ACT_GUEST_CREATE_FROM_IMPORT, "", self.UserCred, true)
|
||||
self.SetStageComplete(ctx, nil)
|
||||
}
|
||||
|
||||
func (self *CreateImportedLibvirtGuestTask) OnGuestSyncFailed(
|
||||
ctx context.Context, guest *models.SGuest, body jsonutils.JSONObject,
|
||||
) {
|
||||
self.TaskFailed(ctx, guest, body.String())
|
||||
}
|
||||
|
||||
func (self *CreateImportedLibvirtGuestTask) OnInitFailed(
|
||||
ctx context.Context, guest *models.SGuest, body jsonutils.JSONObject,
|
||||
) {
|
||||
self.TaskFailed(ctx, guest, body.String())
|
||||
}
|
||||
|
||||
func (self *CreateImportedLibvirtGuestTask) TaskFailed(
|
||||
ctx context.Context, guest *models.SGuest, reason string,
|
||||
) {
|
||||
guest.SetStatus(self.UserCred, compute.VM_IMPORT_FAILED, reason)
|
||||
db.OpsLog.LogEvent(guest, db.ACT_GUEST_CREATE_FROM_IMPORT_FAIL, reason, self.UserCred)
|
||||
logclient.AddActionLogWithContext(ctx, guest,
|
||||
logclient.ACT_GUEST_CREATE_FROM_IMPORT, reason, self.UserCred, false)
|
||||
self.SetStageFailed(ctx, reason)
|
||||
}
|
||||
@@ -23,12 +23,14 @@ import (
|
||||
"yunion.io/x/jsonutils"
|
||||
"yunion.io/x/log"
|
||||
|
||||
"yunion.io/x/onecloud/pkg/apis/compute"
|
||||
"yunion.io/x/onecloud/pkg/appsrv"
|
||||
"yunion.io/x/onecloud/pkg/hostman/guestman"
|
||||
"yunion.io/x/onecloud/pkg/hostman/hostutils"
|
||||
"yunion.io/x/onecloud/pkg/hostman/storageman"
|
||||
"yunion.io/x/onecloud/pkg/httperrors"
|
||||
"yunion.io/x/onecloud/pkg/mcclient/auth"
|
||||
"yunion.io/x/onecloud/pkg/util/fileutils2"
|
||||
)
|
||||
|
||||
type strDict map[string]string
|
||||
@@ -56,8 +58,9 @@ var (
|
||||
"live-migrate": guestLiveMigrate,
|
||||
"resume": guestResume,
|
||||
// "start-nbd-server": guestStartNbdServer,
|
||||
"drive-mirror": guestDriveMirror,
|
||||
"hotplug-cpu-mem": guestHotplugCpuMem,
|
||||
"drive-mirror": guestDriveMirror,
|
||||
"hotplug-cpu-mem": guestHotplugCpuMem,
|
||||
"create-from-libvirt": guestCreateFromLibvirt,
|
||||
}
|
||||
)
|
||||
|
||||
@@ -71,6 +74,10 @@ func AddGuestTaskHandler(prefix string, app *appsrv.Application) {
|
||||
fmt.Sprintf("%s/%s/cpu-node-balance", prefix, keyWord),
|
||||
auth.Authenticate(cpusetBalance))
|
||||
|
||||
app.AddHandler("POST",
|
||||
fmt.Sprintf("%s/%s/prepare-import-from-libvirt", prefix, keyWord),
|
||||
auth.Authenticate(guestPrepareImportFormLibvirt))
|
||||
|
||||
app.AddHandler("POST",
|
||||
fmt.Sprintf("%s/%s/<sid>/<action>", prefix, keyWord),
|
||||
auth.Authenticate(guestActions))
|
||||
@@ -114,6 +121,33 @@ func cpusetBalance(ctx context.Context, w http.ResponseWriter, r *http.Request)
|
||||
hostutils.ResponseOk(ctx, w)
|
||||
}
|
||||
|
||||
func guestPrepareImportFormLibvirt(ctx context.Context, w http.ResponseWriter, r *http.Request) {
|
||||
_, _, body := appsrv.FetchEnv(ctx, w, r)
|
||||
config := &compute.SLibvirtHostConfig{}
|
||||
err := body.Unmarshal(config)
|
||||
if err != nil {
|
||||
hostutils.Response(ctx, w, httperrors.NewInputParameterError("Parse params to libvirt config error %s", err))
|
||||
return
|
||||
}
|
||||
if len(config.XmlFilePath) == 0 {
|
||||
hostutils.Response(ctx, w, httperrors.NewMissingParameterError("xml_file_path"))
|
||||
return
|
||||
}
|
||||
if !fileutils2.Exists(config.XmlFilePath) {
|
||||
hostutils.Response(ctx, w,
|
||||
httperrors.NewBadRequestError("xml_file_path %s not found", config.XmlFilePath))
|
||||
return
|
||||
}
|
||||
|
||||
if len(config.Servers) == 0 {
|
||||
hostutils.Response(ctx, w, httperrors.NewMissingParameterError("servers"))
|
||||
return
|
||||
}
|
||||
|
||||
hostutils.DelayTask(ctx, guestman.GetGuestManager().PrepareImportFromLibvirt, config)
|
||||
hostutils.ResponseOk(ctx, w)
|
||||
}
|
||||
|
||||
func deleteGuest(ctx context.Context, w http.ResponseWriter, r *http.Request) {
|
||||
params, _, body := appsrv.FetchEnv(ctx, w, r)
|
||||
var sid = params["<sid>"]
|
||||
@@ -351,6 +385,35 @@ func guestHotplugCpuMem(ctx context.Context, sid string, body jsonutils.JSONObje
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
func guestCreateFromLibvirt(ctx context.Context, sid string, body jsonutils.JSONObject) (interface{}, error) {
|
||||
err := guestman.GetGuestManager().PrepareCreate(sid)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
iGuestDesc, err := body.Get("desc")
|
||||
if err != nil {
|
||||
return nil, httperrors.NewMissingParameterError("desc")
|
||||
}
|
||||
guestDesc, ok := iGuestDesc.(*jsonutils.JSONDict)
|
||||
if !ok {
|
||||
return nil, httperrors.NewInputParameterError("desc is not dict")
|
||||
}
|
||||
|
||||
iDisksPath, err := body.Get("disks_path")
|
||||
if err != nil {
|
||||
return nil, httperrors.NewMissingParameterError("disks_path")
|
||||
}
|
||||
disksPath, ok := iDisksPath.(*jsonutils.JSONDict)
|
||||
if !ok {
|
||||
return nil, httperrors.NewInputParameterError("disks_path is not dict")
|
||||
}
|
||||
|
||||
hostutils.DelayTask(ctx, guestman.GetGuestManager().GuestCreateFromLibvirt,
|
||||
&guestman.SGuestCreateFromLibvirt{sid, guestDesc, disksPath})
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
func guestReloadDiskSnapshot(ctx context.Context, sid string, body jsonutils.JSONObject) (interface{}, error) {
|
||||
if !guestman.GetGuestManager().IsGuestExist(sid) {
|
||||
return nil, httperrors.NewNotFoundError("Guest %s not found", sid)
|
||||
|
||||
@@ -87,3 +87,19 @@ type SDeleteDiskSnapshot struct {
|
||||
ConvertSnapshot string
|
||||
PendingDelete bool
|
||||
}
|
||||
|
||||
type SLibvirtServer struct {
|
||||
Uuid string
|
||||
MacIp map[string]string
|
||||
}
|
||||
|
||||
type SLibvirtDomainImportConfig struct {
|
||||
LibvritDomainXmlDir string
|
||||
Servers []SLibvirtServer
|
||||
}
|
||||
|
||||
type SGuestCreateFromLibvirt struct {
|
||||
Sid string
|
||||
GuestDesc *jsonutils.JSONDict
|
||||
DisksPath *jsonutils.JSONDict
|
||||
}
|
||||
|
||||
263
pkg/hostman/guestman/libvirt.go
Normal file
263
pkg/hostman/guestman/libvirt.go
Normal file
@@ -0,0 +1,263 @@
|
||||
package guestman
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"path"
|
||||
"unicode"
|
||||
|
||||
libvirtxml "github.com/libvirt/libvirt-go-xml"
|
||||
|
||||
"yunion.io/x/jsonutils"
|
||||
"yunion.io/x/log"
|
||||
|
||||
"yunion.io/x/onecloud/pkg/apis/compute"
|
||||
"yunion.io/x/onecloud/pkg/hostman/hostutils"
|
||||
"yunion.io/x/onecloud/pkg/hostman/storageman"
|
||||
"yunion.io/x/onecloud/pkg/util/procutils"
|
||||
"yunion.io/x/onecloud/pkg/util/qemuimg"
|
||||
)
|
||||
|
||||
func (m *SGuestManager) GuestCreateFromLibvirt(
|
||||
ctx context.Context, params interface{},
|
||||
) (jsonutils.JSONObject, error) {
|
||||
createConfig, ok := params.(*SGuestCreateFromLibvirt)
|
||||
if !ok {
|
||||
return nil, hostutils.ParamsError
|
||||
}
|
||||
disks, err := createConfig.GuestDesc.GetArray("disks")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
disksPath := jsonutils.NewDict()
|
||||
for _, disk := range disks {
|
||||
diskId, _ := disk.GetString("disk_id")
|
||||
diskPath, err := createConfig.DisksPath.GetString(diskId)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("Disks path missing disk %s", diskId)
|
||||
}
|
||||
storageId, _ := disk.GetString("storage_id")
|
||||
storage := storageman.GetManager().GetStorage(storageId)
|
||||
if storage == nil {
|
||||
return nil, fmt.Errorf("Host has no stroage %s", storageId)
|
||||
}
|
||||
iDisk := storage.CreateDisk(diskId)
|
||||
|
||||
output, err := procutils.NewCommand("mv", diskPath, iDisk.GetPath()).Run()
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("Mv disk from %s to %s error %s", diskPath, iDisk.GetPath(), output)
|
||||
}
|
||||
disksPath.Set(diskId, jsonutils.NewString(iDisk.GetPath()))
|
||||
}
|
||||
guest := m.Servers[createConfig.Sid]
|
||||
if err = guest.SaveDesc(createConfig.GuestDesc); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
ret := jsonutils.NewDict()
|
||||
ret.Set("disks_path", disksPath)
|
||||
return ret, nil
|
||||
}
|
||||
|
||||
func (m *SGuestManager) PrepareImportFromLibvirt(
|
||||
ctx context.Context, params interface{},
|
||||
) (jsonutils.JSONObject, error) {
|
||||
libvirtConfig, ok := params.(*compute.SLibvirtHostConfig)
|
||||
if !ok {
|
||||
return nil, hostutils.ParamsError
|
||||
}
|
||||
guestDescs, err := m.GenerateDescFromXml(libvirtConfig)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return guestDescs, nil
|
||||
}
|
||||
|
||||
func setAttributeFromLibvirtConfig(guestConfig *compute.SImportGuestDesc, libvirtConfig *compute.SLibvirtHostConfig) error {
|
||||
for _, server := range libvirtConfig.Servers {
|
||||
if server.Uuid != guestConfig.Id {
|
||||
continue
|
||||
}
|
||||
for idx, nic := range guestConfig.Nics {
|
||||
if ip, ok := server.MacIp[nic.Mac]; ok {
|
||||
guestConfig.Nics[idx].Ip = ip
|
||||
} else {
|
||||
log.Errorf("Guest %s can't find mac address %s in import config", server.Uuid, nic.Mac)
|
||||
return fmt.Errorf("Guest %s Mac Address %s Not Found", server.Uuid, nic.Mac)
|
||||
}
|
||||
}
|
||||
log.Infof("Import guest %s ", server.Uuid)
|
||||
return nil
|
||||
}
|
||||
return fmt.Errorf("No guest %s found in import config", guestConfig.Id)
|
||||
}
|
||||
|
||||
func (m *SGuestManager) GenerateDescFromXml(libvirtConfig *compute.SLibvirtHostConfig) (jsonutils.JSONObject, error) {
|
||||
xmlFiles, err := ioutil.ReadDir(libvirtConfig.XmlFilePath)
|
||||
if err != nil {
|
||||
log.Errorf("Read dir %s error: %s", libvirtConfig.XmlFilePath, err)
|
||||
return nil, err
|
||||
}
|
||||
|
||||
libvirtServers := []*compute.SImportGuestDesc{}
|
||||
for _, f := range xmlFiles {
|
||||
if !f.Mode().IsRegular() {
|
||||
continue
|
||||
}
|
||||
xmlContent, err := ioutil.ReadFile(path.Join(libvirtConfig.XmlFilePath, f.Name()))
|
||||
if err != nil {
|
||||
log.Errorf("Read file %s error: %s", f.Name(), err)
|
||||
continue
|
||||
}
|
||||
domain := &libvirtxml.Domain{}
|
||||
err = domain.Unmarshal(string(xmlContent))
|
||||
if err != nil {
|
||||
log.Errorf("Unmarshal xml file %s error %s", f.Name(), err)
|
||||
continue
|
||||
}
|
||||
guestConfig, err := m.LibvirtDomainToGuestDesc(domain)
|
||||
if err != nil {
|
||||
log.Errorf("Parse libvirt domain failed %s", err)
|
||||
continue
|
||||
}
|
||||
if err = setAttributeFromLibvirtConfig(guestConfig, libvirtConfig); err != nil {
|
||||
log.Errorf("Import guest %s error %s", guestConfig.Id, err)
|
||||
continue
|
||||
}
|
||||
libvirtServers = append(libvirtServers, guestConfig)
|
||||
}
|
||||
|
||||
var (
|
||||
serverInImports = func(uuid string) bool {
|
||||
for _, s := range libvirtServers {
|
||||
if s.Id == uuid {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
serversNotMatch = []string{}
|
||||
)
|
||||
|
||||
for _, server := range libvirtConfig.Servers {
|
||||
if !serverInImports(server.Uuid) {
|
||||
serversNotMatch = append(serversNotMatch, server.Uuid)
|
||||
}
|
||||
}
|
||||
ret := jsonutils.NewDict()
|
||||
ret.Set("servers_not_match", jsonutils.NewStringArray(serversNotMatch))
|
||||
ret.Set("servers_matched", jsonutils.Marshal(libvirtServers))
|
||||
return ret, nil
|
||||
}
|
||||
|
||||
// Read key infomation from domain xml
|
||||
func (m *SGuestManager) LibvirtDomainToGuestDesc(domain *libvirtxml.Domain) (*compute.SImportGuestDesc, error) {
|
||||
if nil == domain {
|
||||
return nil, fmt.Errorf("Libvirt domain is nil")
|
||||
}
|
||||
if nil == domain.VCPU {
|
||||
return nil, fmt.Errorf("Libvirt domain missing VCPU config")
|
||||
}
|
||||
if nil == domain.CurrentMemory {
|
||||
return nil, fmt.Errorf("Libvirt domain missing CurrentMemory config")
|
||||
}
|
||||
if 0 == len(domain.CurrentMemory.Unit) {
|
||||
return nil, fmt.Errorf("Libvirt Memory config missing unit")
|
||||
}
|
||||
if nil == domain.Devices {
|
||||
return nil, fmt.Errorf("Libvirt domain missing Devices config")
|
||||
}
|
||||
if 0 == len(domain.Devices.Disks) {
|
||||
return nil, fmt.Errorf("Livbirt domain has no Disks")
|
||||
}
|
||||
if 0 == len(domain.Devices.Interfaces) {
|
||||
return nil, fmt.Errorf("Libvirt domain has no network Interfaces")
|
||||
}
|
||||
|
||||
var memSizeMb uint
|
||||
switch unicode.ToLower(rune(domain.CurrentMemory.Unit[0])) {
|
||||
case 'k':
|
||||
memSizeMb = domain.CurrentMemory.Value / 1024
|
||||
if domain.CurrentMemory.Value%1024 > 0 {
|
||||
memSizeMb += 1
|
||||
}
|
||||
case 'm':
|
||||
memSizeMb = domain.CurrentMemory.Value
|
||||
case 'g':
|
||||
memSizeMb = domain.CurrentMemory.Value * 1024
|
||||
case 'b':
|
||||
memSizeMb = domain.CurrentMemory.Value / 1024 / 1024
|
||||
if domain.CurrentMemory.Value%(1024*1024) > 0 {
|
||||
memSizeMb += 1
|
||||
}
|
||||
default:
|
||||
return nil, fmt.Errorf("Unknown memory unit %s", domain.CurrentMemory.Unit)
|
||||
}
|
||||
|
||||
disksConfig, err := m.LibvirtDomainDiskToDiskConfig(domain.Devices.Disks)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
nicsConfig, err := m.LibvirtDomainInterfaceToNicConfig(domain.Devices.Interfaces)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &compute.SImportGuestDesc{
|
||||
Id: domain.UUID,
|
||||
Name: domain.Name,
|
||||
Cpu: domain.VCPU.Value,
|
||||
MemSizeMb: int(memSizeMb),
|
||||
Disks: disksConfig,
|
||||
Nics: nicsConfig,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (m *SGuestManager) LibvirtDomainDiskToDiskConfig(
|
||||
domainDisks []libvirtxml.DomainDisk) ([]compute.SImportDisk, error) {
|
||||
var diskConfigs = []compute.SImportDisk{}
|
||||
for _, disk := range domainDisks {
|
||||
if disk.Source == nil || disk.Source.File == nil {
|
||||
return nil, fmt.Errorf("Domain disk missing source file ?")
|
||||
}
|
||||
if disk.Target == nil {
|
||||
return nil, fmt.Errorf("Domain disk missing target config")
|
||||
}
|
||||
|
||||
// XXX: Ignore backing file
|
||||
var diskConfig = compute.SImportDisk{
|
||||
AccessPath: disk.Source.File.File,
|
||||
Index: int(disk.Source.Index),
|
||||
}
|
||||
if disk.Target.Bus != "virtio" {
|
||||
diskConfig.Driver = "scsi"
|
||||
} else {
|
||||
diskConfig.Driver = disk.Target.Bus
|
||||
}
|
||||
|
||||
if img, err := qemuimg.NewQemuImage(diskConfig.AccessPath); err != nil {
|
||||
return nil, fmt.Errorf("Domain disk %s open failed: %s", diskConfig.AccessPath, err)
|
||||
} else {
|
||||
diskConfig.SizeMb = img.GetSizeMB()
|
||||
diskConfig.Format = img.Format.String()
|
||||
}
|
||||
diskConfigs = append(diskConfigs, diskConfig)
|
||||
}
|
||||
return diskConfigs, nil
|
||||
}
|
||||
|
||||
func (m *SGuestManager) LibvirtDomainInterfaceToNicConfig(
|
||||
domainInterfaces []libvirtxml.DomainInterface) ([]compute.SImportNic, error) {
|
||||
var nicConfigs = []compute.SImportNic{}
|
||||
for idx, nic := range domainInterfaces {
|
||||
if nic.MAC == nil {
|
||||
return nil, fmt.Errorf("Domain interface %#v missing mac address", nic)
|
||||
}
|
||||
nicConfigs = append(nicConfigs, compute.SImportNic{Index: idx, Mac: nic.MAC.Address})
|
||||
}
|
||||
return nicConfigs, nil
|
||||
}
|
||||
@@ -201,9 +201,7 @@ func (d *SKVMGuestDisk) connectionPrecheck() {
|
||||
}
|
||||
|
||||
func (d *SKVMGuestDisk) LvmDisconnectNotify() {
|
||||
if lvmTool.GetPathType(d.rootBackingFilePath()) == LVM_PATH {
|
||||
lvmTool.Signal(d.rootBackingFilePath())
|
||||
}
|
||||
lvmTool.Signal(d.rootBackingFilePath())
|
||||
}
|
||||
|
||||
func (d *SKVMGuestDisk) setupLVMS() (bool, error) {
|
||||
|
||||
@@ -198,7 +198,7 @@ func (this *BaseManager) _submit(session *mcclient.ClientSession, method httputi
|
||||
|
||||
type SubmitResult struct {
|
||||
Status int
|
||||
Id string
|
||||
Id interface{}
|
||||
Data jsonutils.JSONObject
|
||||
}
|
||||
|
||||
@@ -207,7 +207,7 @@ func SubmitResults2JSON(results []SubmitResult) jsonutils.JSONObject {
|
||||
for _, r := range results {
|
||||
obj := jsonutils.NewDict()
|
||||
obj.Add(jsonutils.NewInt(int64(r.Status)), "status")
|
||||
obj.Add(jsonutils.NewString(r.Id), "id")
|
||||
obj.Add(jsonutils.Marshal(r.Id), "id")
|
||||
obj.Add(r.Data, "data")
|
||||
arr.Add(obj)
|
||||
}
|
||||
@@ -233,31 +233,51 @@ func (this *BaseManager) _batch(session *mcclient.ClientSession, method httputil
|
||||
})
|
||||
}
|
||||
|
||||
func BatchDo(ids []string, do func(id string) (jsonutils.JSONObject, error)) []SubmitResult {
|
||||
results := make(chan SubmitResult, len(ids))
|
||||
for _, id := range ids {
|
||||
go func(id string) {
|
||||
r, e := do(id)
|
||||
if e != nil {
|
||||
ecls, ok := e.(*httputils.JSONClientError)
|
||||
if ok {
|
||||
results <- SubmitResult{Status: ecls.Code, Id: id, Data: jsonutils.Marshal(ecls)}
|
||||
} else {
|
||||
results <- SubmitResult{Status: 400, Id: id, Data: jsonutils.NewString(e.Error())}
|
||||
}
|
||||
} else {
|
||||
results <- SubmitResult{Status: 200, Id: id, Data: r}
|
||||
}
|
||||
}(id)
|
||||
func addResult(results chan SubmitResult, id interface{}, r jsonutils.JSONObject, e error) {
|
||||
if e != nil {
|
||||
ecls, ok := e.(*httputils.JSONClientError)
|
||||
if ok {
|
||||
results <- SubmitResult{Status: ecls.Code, Id: id, Data: jsonutils.Marshal(ecls)}
|
||||
} else {
|
||||
results <- SubmitResult{Status: 400, Id: id, Data: jsonutils.NewString(e.Error())}
|
||||
}
|
||||
} else {
|
||||
results <- SubmitResult{Status: 200, Id: id, Data: r}
|
||||
}
|
||||
ret := make([]SubmitResult, len(ids))
|
||||
for i := 0; i < len(ids); i++ {
|
||||
}
|
||||
|
||||
func waitResults(results chan SubmitResult, length int) []SubmitResult {
|
||||
ret := make([]SubmitResult, length)
|
||||
for i := 0; i < length; i++ {
|
||||
ret[i] = <-results
|
||||
}
|
||||
close(results)
|
||||
return ret
|
||||
}
|
||||
|
||||
func BatchDo(ids []string, do func(id string) (jsonutils.JSONObject, error)) []SubmitResult {
|
||||
results := make(chan SubmitResult, len(ids))
|
||||
for i := 0; i < len(ids); i++ {
|
||||
go func(id string) {
|
||||
r, e := do(id)
|
||||
addResult(results, id, r, e)
|
||||
}(ids[i])
|
||||
}
|
||||
return waitResults(results, len(ids))
|
||||
}
|
||||
|
||||
func BatchDoClassAction(
|
||||
batchParams []jsonutils.JSONObject, do func(jsonutils.JSONObject) (jsonutils.JSONObject, error),
|
||||
) []SubmitResult {
|
||||
results := make(chan SubmitResult, len(batchParams))
|
||||
for i := 0; i < len(batchParams); i++ {
|
||||
go func(params jsonutils.JSONObject) {
|
||||
r, e := do(params)
|
||||
addResult(results, params, r, e)
|
||||
}(batchParams[i])
|
||||
}
|
||||
return waitResults(results, len(batchParams))
|
||||
}
|
||||
|
||||
func (this *BaseManager) _get(session *mcclient.ClientSession, path string, respKey string) (jsonutils.JSONObject, error) {
|
||||
/* _, body, err := this.jsonRequest(session, "GET", path, nil, nil)
|
||||
if err != nil {
|
||||
|
||||
@@ -477,6 +477,16 @@ func (this *ResourceManager) PerformClassActionInContexts(session *mcclient.Clie
|
||||
return this._post(session, path, params, this.KeywordPlural)
|
||||
}
|
||||
|
||||
func (this *ResourceManager) BatchPerformClassAction(session *mcclient.ClientSession, action string, batchParams []jsonutils.JSONObject) []SubmitResult {
|
||||
return this.BatchPerformClassActionInContexts(session, action, batchParams, nil)
|
||||
}
|
||||
|
||||
func (this *ResourceManager) BatchPerformClassActionInContexts(session *mcclient.ClientSession, action string, batchParams []jsonutils.JSONObject, ctxs []ManagerContext) []SubmitResult {
|
||||
return BatchDoClassAction(batchParams, func(params jsonutils.JSONObject) (jsonutils.JSONObject, error) {
|
||||
return this.PerformClassActionInContexts(session, action, params, ctxs)
|
||||
})
|
||||
}
|
||||
|
||||
func (this *ResourceManager) BatchPerformAction(session *mcclient.ClientSession, idlist []string, action string, params jsonutils.JSONObject) []SubmitResult {
|
||||
return this.BatchPerformActionInContexts(session, idlist, action, params, nil)
|
||||
}
|
||||
|
||||
@@ -113,6 +113,9 @@ const (
|
||||
ACT_FETCH = "下载密钥"
|
||||
|
||||
ACT_VM_CHANGE_NIC = "更改网卡配置"
|
||||
|
||||
ACT_HOST_IMPORT_LIBVIRT_SERVERS = "libvirt托管虚拟机导入"
|
||||
ACT_GUEST_CREATE_FROM_IMPORT = "导入虚拟机创建"
|
||||
)
|
||||
|
||||
// golang 不支持 const 的string array, http://t.cn/EzAvbw8
|
||||
|
||||
@@ -180,7 +180,7 @@ func PrintJSONBatchResults(results []modules.SubmitResult, columns []string) {
|
||||
} else {
|
||||
err := jsonutils.NewDict()
|
||||
err.Add(jsonutils.NewInt(int64(r.Status)), "status")
|
||||
err.Add(jsonutils.NewString(r.Id), "id")
|
||||
err.Add(jsonutils.Marshal(r.Id), "id")
|
||||
err.Add(r.Data, "error")
|
||||
errs = append(errs, err)
|
||||
}
|
||||
|
||||
4
vendor/github.com/libvirt/libvirt-go-xml/.gitignore
generated
vendored
Normal file
4
vendor/github.com/libvirt/libvirt-go-xml/.gitignore
generated
vendored
Normal file
@@ -0,0 +1,4 @@
|
||||
*~
|
||||
*.bak
|
||||
.\#*
|
||||
testdata/
|
||||
0
vendor/github.com/libvirt/libvirt-go-xml/.gitmodules
generated
vendored
Normal file
0
vendor/github.com/libvirt/libvirt-go-xml/.gitmodules
generated
vendored
Normal file
4
vendor/github.com/libvirt/libvirt-go-xml/.gitpublish
generated
vendored
Normal file
4
vendor/github.com/libvirt/libvirt-go-xml/.gitpublish
generated
vendored
Normal file
@@ -0,0 +1,4 @@
|
||||
[gitpublishprofile "default"]
|
||||
base = master
|
||||
to = libvir-list@redhat.com
|
||||
prefix = go-xml PATCH
|
||||
13
vendor/github.com/libvirt/libvirt-go-xml/.travis.yml
generated
vendored
Normal file
13
vendor/github.com/libvirt/libvirt-go-xml/.travis.yml
generated
vendored
Normal file
@@ -0,0 +1,13 @@
|
||||
language: go
|
||||
os: linux
|
||||
dist: trusty
|
||||
|
||||
go:
|
||||
- 1.5
|
||||
- 1.6
|
||||
- 1.7
|
||||
- 1.8
|
||||
- 1.9
|
||||
|
||||
script:
|
||||
go test -timeout 10m -tags xmlroundtrip -v
|
||||
19
vendor/github.com/libvirt/libvirt-go-xml/LICENSE
generated
vendored
Normal file
19
vendor/github.com/libvirt/libvirt-go-xml/LICENSE
generated
vendored
Normal file
@@ -0,0 +1,19 @@
|
||||
The MIT License
|
||||
|
||||
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.
|
||||
67
vendor/github.com/libvirt/libvirt-go-xml/README.md
generated
vendored
Normal file
67
vendor/github.com/libvirt/libvirt-go-xml/README.md
generated
vendored
Normal file
@@ -0,0 +1,67 @@
|
||||
# libvirt-go-xml [](https://travis-ci.org/libvirt/libvirt-go-xml) [](https://godoc.org/github.com/libvirt/libvirt-go-xml)
|
||||
|
||||
Go API for manipulating libvirt XML documents
|
||||
|
||||
This package provides a Go API that defines a set of structs, annotated for use
|
||||
with "encoding/xml", that can represent libvirt XML documents. There is no
|
||||
dependancy on the libvirt library itself, so this can be used regardless of
|
||||
the way in which the application talks to libvirt.
|
||||
|
||||
## Documentation
|
||||
|
||||
* [API documentation for the bindings](https://godoc.org/github.com/libvirt/libvirt-go-xml)
|
||||
* [Libvirt XML schema documentation](https://libvirt.org/format.html):
|
||||
* [capabilities](https://libvirt.org/formatcaps.html)
|
||||
* [domain](https://libvirt.org/formatdomain.html)
|
||||
* [domain capabilities](https://libvirt.org/formatdomaincaps.html)
|
||||
* [domain snapshot](https://libvirt.org/formatsnapshot.html)
|
||||
* [network](https://libvirt.org/formatnetwork.html)
|
||||
* [node device](https://libvirt.org/formatnode.html)
|
||||
* [nwfilter](https://libvirt.org/formatnwfilter.html)
|
||||
* [secret](https://libvirt.org/formatsecret.html)
|
||||
* [storage](https://libvirt.org/formatstorage.html)
|
||||
* [storage encryption](https://libvirt.org/formatstorageencryption.html)
|
||||
|
||||
## Contributing
|
||||
|
||||
The libvirt project aims to add support for new APIs to libvirt-go
|
||||
as soon as they are added to the main libvirt C library. If you
|
||||
are submitting changes to the libvirt C library API, please submit
|
||||
a libvirt-go change at the same time.
|
||||
|
||||
Bug fixes and other improvements to the libvirt-go library are
|
||||
welcome at any time. The preferred submission method is to use
|
||||
git send-email to submit patches to the libvir-list@redhat.com
|
||||
mailing list. eg. to send a single patch
|
||||
|
||||
```
|
||||
# git send-email --to libvir-list@redhat.com --subject-prefix "PATCH go-xml" \
|
||||
--smtp-server=$HOSTNAME -1
|
||||
```
|
||||
|
||||
Or to send all patches on the current branch, against master
|
||||
|
||||
```
|
||||
$ git send-email --to libvir-list@redhat.com --subject-prefix "PATCH go-xml" \
|
||||
--smtp-server=$HOSTNAME --no-chain-reply-to --cover-letter --annotate \
|
||||
master..
|
||||
```
|
||||
|
||||
Note the master GIT repository is at
|
||||
|
||||
```
|
||||
http://libvirt.org/git/?p=libvirt-go.git;a=summary
|
||||
```
|
||||
|
||||
The following automatic read-only mirrors are available as a
|
||||
convenience to allow contributors to "fork" the repository:
|
||||
|
||||
```
|
||||
https://gitlab.com/libvirt/libvirt-go
|
||||
https://github.com/libvirt/libvirt-go
|
||||
```
|
||||
|
||||
While you can send pull-requests to these mirrors, they will be
|
||||
re-submitted via emai to the mailing list for review before
|
||||
being merged, unless they are trivial/obvious bug fixes.
|
||||
|
||||
326
vendor/github.com/libvirt/libvirt-go-xml/capabilities.go
generated
vendored
Normal file
326
vendor/github.com/libvirt/libvirt-go-xml/capabilities.go
generated
vendored
Normal file
@@ -0,0 +1,326 @@
|
||||
/*
|
||||
* 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) 2016 Red Hat, Inc.
|
||||
*
|
||||
*/
|
||||
|
||||
package libvirtxml
|
||||
|
||||
import (
|
||||
"encoding/xml"
|
||||
)
|
||||
|
||||
type CapsHostCPUTopology struct {
|
||||
Sockets int `xml:"sockets,attr"`
|
||||
Cores int `xml:"cores,attr"`
|
||||
Threads int `xml:"threads,attr"`
|
||||
}
|
||||
|
||||
type CapsHostCPUFeatureFlag struct {
|
||||
Name string `xml:"name,attr"`
|
||||
}
|
||||
|
||||
type CapsHostCPUPageSize struct {
|
||||
Size int `xml:"size,attr"`
|
||||
Unit string `xml:"unit,attr"`
|
||||
}
|
||||
|
||||
type CapsHostCPUMicrocode struct {
|
||||
Version int `xml:"version,attr"`
|
||||
}
|
||||
|
||||
type CapsHostCPU struct {
|
||||
XMLName xml.Name `xml:"cpu"`
|
||||
Arch string `xml:"arch,omitempty"`
|
||||
Model string `xml:"model,omitempty"`
|
||||
Vendor string `xml:"vendor,omitempty"`
|
||||
Topology *CapsHostCPUTopology `xml:"topology"`
|
||||
FeatureFlags []CapsHostCPUFeatureFlag `xml:"feature"`
|
||||
Features *CapsHostCPUFeatures `xml:"features"`
|
||||
PageSizes []CapsHostCPUPageSize `xml:"pages"`
|
||||
Microcode *CapsHostCPUMicrocode `xml:"microcode"`
|
||||
}
|
||||
|
||||
type CapsHostCPUFeature struct {
|
||||
}
|
||||
|
||||
type CapsHostCPUFeatures struct {
|
||||
PAE *CapsHostCPUFeature `xml:"pae"`
|
||||
NonPAE *CapsHostCPUFeature `xml:"nonpae"`
|
||||
SVM *CapsHostCPUFeature `xml:"svm"`
|
||||
VMX *CapsHostCPUFeature `xml:"vmx"`
|
||||
}
|
||||
|
||||
type CapsHostNUMAMemory struct {
|
||||
Size uint64 `xml:",chardata"`
|
||||
Unit string `xml:"unit,attr"`
|
||||
}
|
||||
|
||||
type CapsHostNUMAPageInfo struct {
|
||||
Size int `xml:"size,attr"`
|
||||
Unit string `xml:"unit,attr"`
|
||||
Count uint64 `xml:",chardata"`
|
||||
}
|
||||
|
||||
type CapsHostNUMACPU struct {
|
||||
ID int `xml:"id,attr"`
|
||||
SocketID *int `xml:"socket_id,attr"`
|
||||
CoreID *int `xml:"core_id,attr"`
|
||||
Siblings string `xml:"siblings,attr,omitempty"`
|
||||
}
|
||||
|
||||
type CapsHostNUMASibling struct {
|
||||
ID int `xml:"id,attr"`
|
||||
Value int `xml:"value,attr"`
|
||||
}
|
||||
|
||||
type CapsHostNUMACell struct {
|
||||
ID int `xml:"id,attr"`
|
||||
Memory *CapsHostNUMAMemory `xml:"memory"`
|
||||
PageInfo []CapsHostNUMAPageInfo `xml:"pages"`
|
||||
Distances *CapsHostNUMADistances `xml:"distances"`
|
||||
CPUS *CapsHostNUMACPUs `xml:"cpus"`
|
||||
}
|
||||
|
||||
type CapsHostNUMADistances struct {
|
||||
Siblings []CapsHostNUMASibling `xml:"sibling"`
|
||||
}
|
||||
|
||||
type CapsHostNUMACPUs struct {
|
||||
Num uint `xml:"num,attr,omitempty"`
|
||||
CPUs []CapsHostNUMACPU `xml:"cpu"`
|
||||
}
|
||||
|
||||
type CapsHostNUMATopology struct {
|
||||
Cells *CapsHostNUMACells `xml:"cells"`
|
||||
}
|
||||
|
||||
type CapsHostNUMACells struct {
|
||||
Num uint `xml:"num,attr,omitempty"`
|
||||
Cells []CapsHostNUMACell `xml:"cell"`
|
||||
}
|
||||
|
||||
type CapsHostSecModelLabel struct {
|
||||
Type string `xml:"type,attr"`
|
||||
Value string `xml:",chardata"`
|
||||
}
|
||||
|
||||
type CapsHostSecModel struct {
|
||||
Name string `xml:"model"`
|
||||
DOI string `xml:"doi"`
|
||||
Labels []CapsHostSecModelLabel `xml:"baselabel"`
|
||||
}
|
||||
|
||||
type CapsHostMigrationFeatures struct {
|
||||
Live *CapsHostMigrationLive `xml:"live"`
|
||||
URITransports *CapsHostMigrationURITransports `xml:"uri_transports"`
|
||||
}
|
||||
|
||||
type CapsHostMigrationLive struct {
|
||||
}
|
||||
|
||||
type CapsHostMigrationURITransports struct {
|
||||
URI []string `xml:"uri_transport"`
|
||||
}
|
||||
|
||||
type CapsHost struct {
|
||||
UUID string `xml:"uuid,omitempty"`
|
||||
CPU *CapsHostCPU `xml:"cpu"`
|
||||
PowerManagement *CapsHostPowerManagement `xml:"power_management"`
|
||||
IOMMU *CapsHostIOMMU `xml:"iommu"`
|
||||
MigrationFeatures *CapsHostMigrationFeatures `xml:"migration_features"`
|
||||
NUMA *CapsHostNUMATopology `xml:"topology"`
|
||||
Cache *CapsHostCache `xml:"cache"`
|
||||
MemoryBandwidth *CapsHostMemoryBandwidth `xml:"memory_bandwidth"`
|
||||
SecModel []CapsHostSecModel `xml:"secmodel"`
|
||||
}
|
||||
|
||||
type CapsHostPowerManagement struct {
|
||||
SuspendMem *CapsHostPowerManagementMode `xml:"suspend_mem"`
|
||||
SuspendDisk *CapsHostPowerManagementMode `xml:"suspend_disk"`
|
||||
SuspendHybrid *CapsHostPowerManagementMode `xml:"suspend_hybrid"`
|
||||
}
|
||||
|
||||
type CapsHostPowerManagementMode struct {
|
||||
}
|
||||
|
||||
type CapsHostIOMMU struct {
|
||||
Support string `xml:"support,attr"`
|
||||
}
|
||||
|
||||
type CapsHostCache struct {
|
||||
Banks []CapsHostCacheBank `xml:"bank"`
|
||||
Monitor *CapsHostCacheMonitor `xml:"monitor"`
|
||||
}
|
||||
|
||||
type CapsHostCacheBank struct {
|
||||
ID uint `xml:"id,attr"`
|
||||
Level uint `xml:"level,attr"`
|
||||
Type string `xml:"type,attr"`
|
||||
Size uint `xml:"size,attr"`
|
||||
Unit string `xml:"unit,attr"`
|
||||
CPUs string `xml:"cpus,attr"`
|
||||
Control []CapsHostCacheControl `xml:"control"`
|
||||
}
|
||||
|
||||
type CapsHostCacheMonitor struct {
|
||||
Level uint `xml:"level,attr,omitempty"`
|
||||
ResueThreshold uint `xml:"reuseThreshold,attr,omitempty"`
|
||||
MaxMonitors uint `xml:"maxMonitors,attr"`
|
||||
Features []CapsHostCacheMonitorFeature `xml:"feature"`
|
||||
}
|
||||
|
||||
type CapsHostCacheMonitorFeature struct {
|
||||
Name string `xml:"name,attr"`
|
||||
}
|
||||
|
||||
type CapsHostCacheControl struct {
|
||||
Granularity uint `xml:"granularity,attr"`
|
||||
Min uint `xml:"min,attr,omitempty"`
|
||||
Unit string `xml:"unit,attr"`
|
||||
Type string `xml:"type,attr"`
|
||||
MaxAllows uint `xml:"maxAllocs,attr"`
|
||||
}
|
||||
|
||||
type CapsHostMemoryBandwidth struct {
|
||||
Nodes []CapsHostMemoryBandwidthNode `xml:"node"`
|
||||
Monitor *CapsHostMemoryBandwidthMonitor `xml:"monitor"`
|
||||
}
|
||||
|
||||
type CapsHostMemoryBandwidthNode struct {
|
||||
ID uint `xml:"id,attr"`
|
||||
CPUs string `xml:"cpus,attr"`
|
||||
Control *CapsHostMemoryBandwidthNodeControl `xml:"control"`
|
||||
}
|
||||
|
||||
type CapsHostMemoryBandwidthNodeControl struct {
|
||||
Granularity uint `xml:"granularity,attr"`
|
||||
Min uint `xml:"min,attr"`
|
||||
MaxAllocs uint `xml:"maxAllocs,attr"`
|
||||
}
|
||||
|
||||
type CapsHostMemoryBandwidthMonitor struct {
|
||||
MaxMonitors uint `xml:"maxMonitors,attr"`
|
||||
Features []CapsHostMemoryBandwidthMonitorFeature `xml:"feature"`
|
||||
}
|
||||
|
||||
type CapsHostMemoryBandwidthMonitorFeature struct {
|
||||
Name string `xml:"name,attr"`
|
||||
}
|
||||
|
||||
type CapsGuestMachine struct {
|
||||
Name string `xml:",chardata"`
|
||||
MaxCPUs int `xml:"maxCpus,attr,omitempty"`
|
||||
Canonical string `xml:"canonical,attr,omitempty"`
|
||||
}
|
||||
|
||||
type CapsGuestDomain struct {
|
||||
Type string `xml:"type,attr"`
|
||||
Emulator string `xml:"emulator,omitempty"`
|
||||
Machines []CapsGuestMachine `xml:"machine"`
|
||||
}
|
||||
|
||||
type CapsGuestArch struct {
|
||||
Name string `xml:"name,attr"`
|
||||
WordSize string `xml:"wordsize"`
|
||||
Emulator string `xml:"emulator"`
|
||||
Loader string `xml:"loader,omitempty"`
|
||||
Machines []CapsGuestMachine `xml:"machine"`
|
||||
Domains []CapsGuestDomain `xml:"domain"`
|
||||
}
|
||||
|
||||
type CapsGuestFeatureCPUSelection struct {
|
||||
}
|
||||
|
||||
type CapsGuestFeatureDeviceBoot struct {
|
||||
}
|
||||
|
||||
type CapsGuestFeaturePAE struct {
|
||||
}
|
||||
|
||||
type CapsGuestFeatureNonPAE struct {
|
||||
}
|
||||
|
||||
type CapsGuestFeatureDiskSnapshot struct {
|
||||
Default string `xml:"default,attr,omitempty"`
|
||||
Toggle string `xml:"toggle,attr,omitempty"`
|
||||
}
|
||||
|
||||
type CapsGuestFeatureAPIC struct {
|
||||
Default string `xml:"default,attr,omitempty"`
|
||||
Toggle string `xml:"toggle,attr,omitempty"`
|
||||
}
|
||||
|
||||
type CapsGuestFeatureACPI struct {
|
||||
Default string `xml:"default,attr,omitempty"`
|
||||
Toggle string `xml:"toggle,attr,omitempty"`
|
||||
}
|
||||
|
||||
type CapsGuestFeatureIA64BE struct {
|
||||
}
|
||||
|
||||
type CapsGuestFeatures struct {
|
||||
CPUSelection *CapsGuestFeatureCPUSelection `xml:"cpuselection"`
|
||||
DeviceBoot *CapsGuestFeatureDeviceBoot `xml:"deviceboot"`
|
||||
DiskSnapshot *CapsGuestFeatureDiskSnapshot `xml:"disksnapshot"`
|
||||
PAE *CapsGuestFeaturePAE `xml:"pae"`
|
||||
NonPAE *CapsGuestFeatureNonPAE `xml:"nonpae"`
|
||||
APIC *CapsGuestFeatureAPIC `xml:"apic"`
|
||||
ACPI *CapsGuestFeatureACPI `xml:"acpi"`
|
||||
IA64BE *CapsGuestFeatureIA64BE `xml:"ia64_be"`
|
||||
}
|
||||
|
||||
type CapsGuest struct {
|
||||
OSType string `xml:"os_type"`
|
||||
Arch CapsGuestArch `xml:"arch"`
|
||||
Features *CapsGuestFeatures `xml:"features"`
|
||||
}
|
||||
|
||||
type Caps struct {
|
||||
XMLName xml.Name `xml:"capabilities"`
|
||||
Host CapsHost `xml:"host"`
|
||||
Guests []CapsGuest `xml:"guest"`
|
||||
}
|
||||
|
||||
func (c *CapsHostCPU) Unmarshal(doc string) error {
|
||||
return xml.Unmarshal([]byte(doc), c)
|
||||
}
|
||||
|
||||
func (c *CapsHostCPU) Marshal() (string, error) {
|
||||
doc, err := xml.MarshalIndent(c, "", " ")
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
return string(doc), nil
|
||||
}
|
||||
|
||||
func (c *Caps) Unmarshal(doc string) error {
|
||||
return xml.Unmarshal([]byte(doc), c)
|
||||
}
|
||||
|
||||
func (c *Caps) Marshal() (string, error) {
|
||||
doc, err := xml.MarshalIndent(c, "", " ")
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
return string(doc), nil
|
||||
}
|
||||
62
vendor/github.com/libvirt/libvirt-go-xml/doc.go
generated
vendored
Normal file
62
vendor/github.com/libvirt/libvirt-go-xml/doc.go
generated
vendored
Normal file
@@ -0,0 +1,62 @@
|
||||
/*
|
||||
* 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 libvirt-go-xml defines structs for parsing libvirt XML schemas
|
||||
//
|
||||
// The libvirt API uses XML schemas/documents to describe the configuration
|
||||
// of many of its managed objects. Thus when using the libvirt-go package,
|
||||
// it is often neccessary to either parse or format XML documents. This
|
||||
// package defines a set of Go structs which have been annotated for use
|
||||
// with the encoding/xml API to manage libvirt XML documents.
|
||||
//
|
||||
// Example creating a domain XML document from configuration:
|
||||
//
|
||||
// import (
|
||||
// "github.com/libvirt/libvirt-go-xml"
|
||||
// )
|
||||
//
|
||||
// domcfg := &libvirtxml.Domain{Type: "kvm", Name: "demo",
|
||||
// UUID: "8f99e332-06c4-463a-9099-330fb244e1b3",
|
||||
// ....}
|
||||
// xmldoc, err := domcfg.Marshal()
|
||||
//
|
||||
// Example parsing a domainXML document, in combination with libvirt-go
|
||||
//
|
||||
// import (
|
||||
// "github.com/libvirt/libvirt-go"
|
||||
// "github.com/libvirt/libvirt-go-xml"
|
||||
// "fmt"
|
||||
// )
|
||||
//
|
||||
// conn, err := libvirt.NewConnect("qemu:///system")
|
||||
// dom := conn.LookupDomainByName("demo")
|
||||
// xmldoc, err := dom.GetXMLDesc(0)
|
||||
//
|
||||
// domcfg := &libvirtxml.Domain{}
|
||||
// err := domcfg.Unmarshal(xmldoc)
|
||||
//
|
||||
// fmt.Printf("Virt type %s", domcfg.Type)
|
||||
//
|
||||
package libvirtxml
|
||||
6
vendor/github.com/libvirt/libvirt-go-xml/document.go
generated
vendored
Normal file
6
vendor/github.com/libvirt/libvirt-go-xml/document.go
generated
vendored
Normal file
@@ -0,0 +1,6 @@
|
||||
package libvirtxml
|
||||
|
||||
type Document interface {
|
||||
Unmarshal(doc string) error
|
||||
Marshal() (string, error)
|
||||
}
|
||||
5218
vendor/github.com/libvirt/libvirt-go-xml/domain.go
generated
vendored
Normal file
5218
vendor/github.com/libvirt/libvirt-go-xml/domain.go
generated
vendored
Normal file
File diff suppressed because it is too large
Load Diff
141
vendor/github.com/libvirt/libvirt-go-xml/domain_capabilities.go
generated
vendored
Normal file
141
vendor/github.com/libvirt/libvirt-go-xml/domain_capabilities.go
generated
vendored
Normal file
@@ -0,0 +1,141 @@
|
||||
/*
|
||||
* 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) 2016 Red Hat, Inc.
|
||||
*
|
||||
*/
|
||||
|
||||
package libvirtxml
|
||||
|
||||
import (
|
||||
"encoding/xml"
|
||||
)
|
||||
|
||||
type DomainCaps struct {
|
||||
XMLName xml.Name `xml:"domainCapabilities"`
|
||||
Path string `xml:"path"`
|
||||
Domain string `xml:"domain"`
|
||||
Machine string `xml:"machine,omitempty"`
|
||||
Arch string `xml:"arch"`
|
||||
VCPU *DomainCapsVCPU `xml:"vcpu"`
|
||||
IOThreads *DomainCapsIOThreads `xml:"iothreads"`
|
||||
OS *DomainCapsOS `xml:"os"`
|
||||
CPU *DomainCapsCPU `xml:"cpu"`
|
||||
Devices *DomainCapsDevices `xml:"devices"`
|
||||
Features *DomainCapsFeatures `xml:"features"`
|
||||
}
|
||||
|
||||
type DomainCapsVCPU struct {
|
||||
Max uint `xml:"max,attr"`
|
||||
}
|
||||
|
||||
type DomainCapsOS struct {
|
||||
Supported string `xml:"supported,attr"`
|
||||
Loader *DomainCapsOSLoader `xml:"loader"`
|
||||
}
|
||||
|
||||
type DomainCapsOSLoader struct {
|
||||
Supported string `xml:"supported,attr"`
|
||||
Values []string `xml:"value"`
|
||||
Enums []DomainCapsEnum `xml:"enum"`
|
||||
}
|
||||
|
||||
type DomainCapsIOThreads struct {
|
||||
Supported string `xml:"supported,attr"`
|
||||
}
|
||||
|
||||
type DomainCapsCPU struct {
|
||||
Modes []DomainCapsCPUMode `xml:"mode"`
|
||||
}
|
||||
|
||||
type DomainCapsCPUMode struct {
|
||||
Name string `xml:"name,attr"`
|
||||
Supported string `xml:"supported,attr"`
|
||||
Models []DomainCapsCPUModel `xml:"model"`
|
||||
Vendor string `xml:"vendor,omitempty"`
|
||||
Features []DomainCapsCPUFeature `xml:"feature"`
|
||||
}
|
||||
|
||||
type DomainCapsCPUModel struct {
|
||||
Name string `xml:",chardata"`
|
||||
Usable string `xml:"usable,attr,omitempty"`
|
||||
Fallback string `xml:"fallback,attr,omitempty"`
|
||||
}
|
||||
|
||||
type DomainCapsCPUFeature struct {
|
||||
Policy string `xml:"policy,attr,omitempty"`
|
||||
Name string `xml:"name,attr"`
|
||||
}
|
||||
|
||||
type DomainCapsEnum struct {
|
||||
Name string `xml:"name,attr"`
|
||||
Values []string `xml:"value"`
|
||||
}
|
||||
|
||||
type DomainCapsDevices struct {
|
||||
Disk *DomainCapsDevice `xml:"disk"`
|
||||
Graphics *DomainCapsDevice `xml:"graphics"`
|
||||
Video *DomainCapsDevice `xml:"video"`
|
||||
HostDev *DomainCapsDevice `xml:"hostdev"`
|
||||
}
|
||||
|
||||
type DomainCapsDevice struct {
|
||||
Supported string `xml:"supported,attr"`
|
||||
Enums []DomainCapsEnum `xml:"enum"`
|
||||
}
|
||||
|
||||
type DomainCapsFeatures struct {
|
||||
GIC *DomainCapsFeatureGIC `xml:"gic"`
|
||||
VMCoreInfo *DomainCapsFeatureVMCoreInfo `xml:"vmcoreinfo"`
|
||||
GenID *DomainCapsFeatureGenID `xml:"genid"`
|
||||
SEV *DomainCapsFeatureSEV `xml:"sev"`
|
||||
}
|
||||
|
||||
type DomainCapsFeatureGIC struct {
|
||||
Supported string `xml:"supported,attr"`
|
||||
Enums []DomainCapsEnum `xml:"enum"`
|
||||
}
|
||||
|
||||
type DomainCapsFeatureVMCoreInfo struct {
|
||||
Supported string `xml:"supported,attr"`
|
||||
}
|
||||
|
||||
type DomainCapsFeatureGenID struct {
|
||||
Supported string `xml:"supported,attr"`
|
||||
}
|
||||
|
||||
type DomainCapsFeatureSEV struct {
|
||||
Supported string `xml:"supported,attr"`
|
||||
CBitPos uint `xml:"cbitpos,omitempty"`
|
||||
ReducedPhysBits uint `xml:"reducedPhysBits,omitempty"`
|
||||
}
|
||||
|
||||
func (c *DomainCaps) Unmarshal(doc string) error {
|
||||
return xml.Unmarshal([]byte(doc), c)
|
||||
}
|
||||
|
||||
func (c *DomainCaps) Marshal() (string, error) {
|
||||
doc, err := xml.MarshalIndent(c, "", " ")
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
return string(doc), nil
|
||||
}
|
||||
134
vendor/github.com/libvirt/libvirt-go-xml/domain_snapshot.go
generated
vendored
Normal file
134
vendor/github.com/libvirt/libvirt-go-xml/domain_snapshot.go
generated
vendored
Normal file
@@ -0,0 +1,134 @@
|
||||
/*
|
||||
* 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 DomainSnapshotDiskDriver struct {
|
||||
Type string `xml:"type,attr,omitempty"`
|
||||
}
|
||||
|
||||
type DomainSnapshotDisk struct {
|
||||
Name string `xml:"name,attr"`
|
||||
Snapshot string `xml:"snapshot,attr,omitempty"`
|
||||
Driver *DomainSnapshotDiskDriver `xml:"driver"`
|
||||
Source *DomainDiskSource `xml:"source"`
|
||||
}
|
||||
|
||||
type DomainSnapshotDisks struct {
|
||||
Disks []DomainSnapshotDisk `xml:"disk"`
|
||||
}
|
||||
|
||||
type DomainSnapshotMemory struct {
|
||||
Snapshot string `xml:"snapshot,attr"`
|
||||
File string `xml:"file,attr,omitempty"`
|
||||
}
|
||||
|
||||
type DomainSnapshotParent struct {
|
||||
Name string `xml:"name"`
|
||||
}
|
||||
|
||||
type DomainSnapshot struct {
|
||||
XMLName xml.Name `xml:"domainsnapshot"`
|
||||
Name string `xml:"name,omitempty"`
|
||||
Description string `xml:"description,omitempty"`
|
||||
State string `xml:"state,omitempty"`
|
||||
CreationTime string `xml:"creationTime,omitempty"`
|
||||
Parent *DomainSnapshotParent `xml:"parent"`
|
||||
Memory *DomainSnapshotMemory `xml:"memory"`
|
||||
Disks *DomainSnapshotDisks `xml:"disks"`
|
||||
Domain *Domain `xml:"domain"`
|
||||
Active *uint `xml:"active"`
|
||||
}
|
||||
|
||||
type domainSnapshotDisk DomainSnapshotDisk
|
||||
|
||||
func (a *DomainSnapshotDisk) MarshalXML(e *xml.Encoder, start xml.StartElement) error {
|
||||
start.Name.Local = "disk"
|
||||
if a.Source != nil {
|
||||
if a.Source.File != nil {
|
||||
start.Attr = append(start.Attr, xml.Attr{
|
||||
xml.Name{Local: "type"}, "file",
|
||||
})
|
||||
} else if a.Source.Block != nil {
|
||||
start.Attr = append(start.Attr, xml.Attr{
|
||||
xml.Name{Local: "type"}, "block",
|
||||
})
|
||||
} else if a.Source.Dir != nil {
|
||||
start.Attr = append(start.Attr, xml.Attr{
|
||||
xml.Name{Local: "type"}, "dir",
|
||||
})
|
||||
} else if a.Source.Network != nil {
|
||||
start.Attr = append(start.Attr, xml.Attr{
|
||||
xml.Name{Local: "type"}, "network",
|
||||
})
|
||||
} else if a.Source.Volume != nil {
|
||||
start.Attr = append(start.Attr, xml.Attr{
|
||||
xml.Name{Local: "type"}, "volume",
|
||||
})
|
||||
}
|
||||
}
|
||||
disk := domainSnapshotDisk(*a)
|
||||
return e.EncodeElement(disk, start)
|
||||
}
|
||||
|
||||
func (a *DomainSnapshotDisk) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error {
|
||||
typ, ok := getAttr(start.Attr, "type")
|
||||
if !ok {
|
||||
typ = "file"
|
||||
}
|
||||
a.Source = &DomainDiskSource{}
|
||||
if typ == "file" {
|
||||
a.Source.File = &DomainDiskSourceFile{}
|
||||
} else if typ == "block" {
|
||||
a.Source.Block = &DomainDiskSourceBlock{}
|
||||
} else if typ == "network" {
|
||||
a.Source.Network = &DomainDiskSourceNetwork{}
|
||||
} else if typ == "dir" {
|
||||
a.Source.Dir = &DomainDiskSourceDir{}
|
||||
} else if typ == "volume" {
|
||||
a.Source.Volume = &DomainDiskSourceVolume{}
|
||||
}
|
||||
disk := domainSnapshotDisk(*a)
|
||||
err := d.DecodeElement(&disk, &start)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
*a = DomainSnapshotDisk(disk)
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *DomainSnapshot) Unmarshal(doc string) error {
|
||||
return xml.Unmarshal([]byte(doc), s)
|
||||
}
|
||||
|
||||
func (s *DomainSnapshot) Marshal() (string, error) {
|
||||
doc, err := xml.MarshalIndent(s, "", " ")
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
return string(doc), nil
|
||||
}
|
||||
150
vendor/github.com/libvirt/libvirt-go-xml/interface.go
generated
vendored
Normal file
150
vendor/github.com/libvirt/libvirt-go-xml/interface.go
generated
vendored
Normal file
@@ -0,0 +1,150 @@
|
||||
/*
|
||||
* 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 Lian Duan <blazeblue@gmail.com>
|
||||
*
|
||||
*/
|
||||
|
||||
package libvirtxml
|
||||
|
||||
import (
|
||||
"encoding/xml"
|
||||
)
|
||||
|
||||
type Interface struct {
|
||||
XMLName xml.Name `xml:"interface"`
|
||||
Name string `xml:"name,attr,omitempty"`
|
||||
Start *InterfaceStart `xml:"start"`
|
||||
MTU *InterfaceMTU `xml:"mtu"`
|
||||
Protocol []InterfaceProtocol `xml:"protocol"`
|
||||
Link *InterfaceLink `xml:"link"`
|
||||
MAC *InterfaceMAC `xml:"mac"`
|
||||
Bond *InterfaceBond `xml:"bond"`
|
||||
Bridge *InterfaceBridge `xml:"bridge"`
|
||||
VLAN *InterfaceVLAN `xml:"vlan"`
|
||||
}
|
||||
|
||||
type InterfaceStart struct {
|
||||
Mode string `xml:"mode,attr"`
|
||||
}
|
||||
|
||||
type InterfaceMTU struct {
|
||||
Size uint `xml:"size,attr"`
|
||||
}
|
||||
|
||||
type InterfaceProtocol struct {
|
||||
Family string `xml:"family,attr,omitempty"`
|
||||
AutoConf *InterfaceAutoConf `xml:"autoconf"`
|
||||
DHCP *InterfaceDHCP `xml:"dhcp"`
|
||||
IPs []InterfaceIP `xml:"ip"`
|
||||
Route []InterfaceRoute `xml:"route"`
|
||||
}
|
||||
|
||||
type InterfaceAutoConf struct {
|
||||
}
|
||||
|
||||
type InterfaceDHCP struct {
|
||||
PeerDNS string `xml:"peerdns,attr,omitempty"`
|
||||
}
|
||||
|
||||
type InterfaceIP struct {
|
||||
Address string `xml:"address,attr"`
|
||||
Prefix uint `xml:"prefix,attr,omitempty"`
|
||||
}
|
||||
|
||||
type InterfaceRoute struct {
|
||||
Gateway string `xml:"gateway,attr"`
|
||||
}
|
||||
|
||||
type InterfaceLink struct {
|
||||
Speed uint `xml:"speed,attr,omitempty"`
|
||||
State string `xml:"state,attr,omitempty"`
|
||||
}
|
||||
|
||||
type InterfaceMAC struct {
|
||||
Address string `xml:"address,attr"`
|
||||
}
|
||||
|
||||
type InterfaceBond struct {
|
||||
Mode string `xml:"mode,attr,omitempty"`
|
||||
ARPMon *InterfaceBondARPMon `xml:"arpmon"`
|
||||
MIIMon *InterfaceBondMIIMon `xml:"miimon"`
|
||||
Interfaces []Interface `xml:"interface"`
|
||||
}
|
||||
|
||||
type InterfaceBondARPMon struct {
|
||||
Interval uint `xml:"interval,attr,omitempty"`
|
||||
Target string `xml:"target,attr,omitempty"`
|
||||
Validate string `xml:"validate,attr,omitempty"`
|
||||
}
|
||||
|
||||
type InterfaceBondMIIMon struct {
|
||||
Freq uint `xml:"freq,attr,omitempty"`
|
||||
UpDelay uint `xml:"updelay,attr,omitempty"`
|
||||
Carrier string `xml:"carrier,attr,omitempty"`
|
||||
}
|
||||
|
||||
type InterfaceBridge struct {
|
||||
STP string `xml:"stp,attr,omitempty"`
|
||||
Delay *float64 `xml:"delay,attr"`
|
||||
Interfaces []Interface `xml:"interface"`
|
||||
}
|
||||
|
||||
type InterfaceVLAN struct {
|
||||
Tag *uint `xml:"tag,attr"`
|
||||
Interface *Interface `xml:"interface"`
|
||||
}
|
||||
|
||||
type interfaceDup Interface
|
||||
|
||||
func (s *Interface) MarshalXML(e *xml.Encoder, start xml.StartElement) error {
|
||||
start.Name.Local = "interface"
|
||||
|
||||
typ := "ethernet"
|
||||
if s.Bond != nil {
|
||||
typ = "bond"
|
||||
} else if s.Bridge != nil {
|
||||
typ = "bridge"
|
||||
} else if s.VLAN != nil {
|
||||
typ = "vlan"
|
||||
}
|
||||
|
||||
start.Attr = append(start.Attr, xml.Attr{
|
||||
Name: xml.Name{Local: "type"},
|
||||
Value: typ,
|
||||
})
|
||||
|
||||
i := interfaceDup(*s)
|
||||
|
||||
return e.EncodeElement(i, start)
|
||||
}
|
||||
|
||||
func (s *Interface) Unmarshal(doc string) error {
|
||||
return xml.Unmarshal([]byte(doc), s)
|
||||
}
|
||||
|
||||
func (s *Interface) Marshal() (string, error) {
|
||||
doc, err := xml.MarshalIndent(s, "", " ")
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
return string(doc), nil
|
||||
}
|
||||
538
vendor/github.com/libvirt/libvirt-go-xml/network.go
generated
vendored
Normal file
538
vendor/github.com/libvirt/libvirt-go-xml/network.go
generated
vendored
Normal file
@@ -0,0 +1,538 @@
|
||||
/*
|
||||
* 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 Lian Duan <blazeblue@gmail.com>
|
||||
*
|
||||
*/
|
||||
|
||||
package libvirtxml
|
||||
|
||||
import (
|
||||
"encoding/xml"
|
||||
)
|
||||
|
||||
type NetworkBridge struct {
|
||||
Name string `xml:"name,attr,omitempty"`
|
||||
STP string `xml:"stp,attr,omitempty"`
|
||||
Delay string `xml:"delay,attr,omitempty"`
|
||||
MACTableManager string `xml:"macTableManager,attr,omitempty"`
|
||||
Zone string `xml:"zone,attr,omitempty"`
|
||||
}
|
||||
|
||||
type NetworkVirtualPort struct {
|
||||
Params *NetworkVirtualPortParams `xml:"parameters"`
|
||||
}
|
||||
|
||||
type NetworkVirtualPortParams struct {
|
||||
Any *NetworkVirtualPortParamsAny `xml:"-"`
|
||||
VEPA8021QBG *NetworkVirtualPortParamsVEPA8021QBG `xml:"-"`
|
||||
VNTag8011QBH *NetworkVirtualPortParamsVNTag8021QBH `xml:"-"`
|
||||
OpenVSwitch *NetworkVirtualPortParamsOpenVSwitch `xml:"-"`
|
||||
MidoNet *NetworkVirtualPortParamsMidoNet `xml:"-"`
|
||||
}
|
||||
|
||||
type NetworkVirtualPortParamsAny struct {
|
||||
ManagerID *uint `xml:"managerid,attr"`
|
||||
TypeID *uint `xml:"typeid,attr"`
|
||||
TypeIDVersion *uint `xml:"typeidversion,attr"`
|
||||
InstanceID string `xml:"instanceid,attr,omitempty"`
|
||||
ProfileID string `xml:"profileid,attr,omitempty"`
|
||||
InterfaceID string `xml:"interfaceid,attr,omitempty"`
|
||||
}
|
||||
|
||||
type NetworkVirtualPortParamsVEPA8021QBG struct {
|
||||
ManagerID *uint `xml:"managerid,attr"`
|
||||
TypeID *uint `xml:"typeid,attr"`
|
||||
TypeIDVersion *uint `xml:"typeidversion,attr"`
|
||||
InstanceID string `xml:"instanceid,attr,omitempty"`
|
||||
}
|
||||
|
||||
type NetworkVirtualPortParamsVNTag8021QBH struct {
|
||||
ProfileID string `xml:"profileid,attr,omitempty"`
|
||||
}
|
||||
|
||||
type NetworkVirtualPortParamsOpenVSwitch struct {
|
||||
InterfaceID string `xml:"interfaceid,attr,omitempty"`
|
||||
ProfileID string `xml:"profileid,attr,omitempty"`
|
||||
}
|
||||
|
||||
type NetworkVirtualPortParamsMidoNet struct {
|
||||
InterfaceID string `xml:"interfaceid,attr,omitempty"`
|
||||
}
|
||||
|
||||
type NetworkDomain struct {
|
||||
Name string `xml:"name,attr,omitempty"`
|
||||
LocalOnly string `xml:"localOnly,attr,omitempty"`
|
||||
}
|
||||
|
||||
type NetworkForwardNATAddress struct {
|
||||
Start string `xml:"start,attr"`
|
||||
End string `xml:"end,attr"`
|
||||
}
|
||||
|
||||
type NetworkForwardNATPort struct {
|
||||
Start uint `xml:"start,attr"`
|
||||
End uint `xml:"end,attr"`
|
||||
}
|
||||
|
||||
type NetworkForwardNAT struct {
|
||||
Addresses []NetworkForwardNATAddress `xml:"address"`
|
||||
Ports []NetworkForwardNATPort `xml:"port"`
|
||||
}
|
||||
|
||||
type NetworkForward struct {
|
||||
Mode string `xml:"mode,attr,omitempty"`
|
||||
Dev string `xml:"dev,attr,omitempty"`
|
||||
Managed string `xml:"managed,attr,omitempty"`
|
||||
Driver *NetworkForwardDriver `xml:"driver"`
|
||||
PFs []NetworkForwardPF `xml:"pf"`
|
||||
NAT *NetworkForwardNAT `xml:"nat"`
|
||||
Interfaces []NetworkForwardInterface `xml:"interface"`
|
||||
Addresses []NetworkForwardAddress `xml:"address"`
|
||||
}
|
||||
|
||||
type NetworkForwardDriver struct {
|
||||
Name string `xml:"name,attr"`
|
||||
}
|
||||
|
||||
type NetworkForwardPF struct {
|
||||
Dev string `xml:"dev,attr"`
|
||||
}
|
||||
|
||||
type NetworkForwardAddress struct {
|
||||
PCI *NetworkForwardAddressPCI `xml:"-"`
|
||||
}
|
||||
|
||||
type NetworkForwardAddressPCI struct {
|
||||
Domain *uint `xml:"domain,attr"`
|
||||
Bus *uint `xml:"bus,attr"`
|
||||
Slot *uint `xml:"slot,attr"`
|
||||
Function *uint `xml:"function,attr"`
|
||||
}
|
||||
|
||||
type NetworkForwardInterface struct {
|
||||
XMLName xml.Name `xml:"interface"`
|
||||
Dev string `xml:"dev,attr,omitempty"`
|
||||
}
|
||||
|
||||
type NetworkMAC struct {
|
||||
Address string `xml:"address,attr,omitempty"`
|
||||
}
|
||||
|
||||
type NetworkDHCPRange struct {
|
||||
XMLName xml.Name `xml:"range"`
|
||||
Start string `xml:"start,attr,omitempty"`
|
||||
End string `xml:"end,attr,omitempty"`
|
||||
}
|
||||
|
||||
type NetworkDHCPHost struct {
|
||||
XMLName xml.Name `xml:"host"`
|
||||
ID string `xml:"id,attr,omitempty"`
|
||||
MAC string `xml:"mac,attr,omitempty"`
|
||||
Name string `xml:"name,attr,omitempty"`
|
||||
IP string `xml:"ip,attr,omitempty"`
|
||||
}
|
||||
|
||||
type NetworkBootp struct {
|
||||
File string `xml:"file,attr,omitempty"`
|
||||
Server string `xml:"server,attr,omitempty"`
|
||||
}
|
||||
|
||||
type NetworkDHCP struct {
|
||||
Ranges []NetworkDHCPRange `xml:"range"`
|
||||
Hosts []NetworkDHCPHost `xml:"host"`
|
||||
Bootp []NetworkBootp `xml:"bootp"`
|
||||
}
|
||||
|
||||
type NetworkIP struct {
|
||||
Address string `xml:"address,attr,omitempty"`
|
||||
Family string `xml:"family,attr,omitempty"`
|
||||
Netmask string `xml:"netmask,attr,omitempty"`
|
||||
Prefix uint `xml:"prefix,attr,omitempty"`
|
||||
LocalPtr string `xml:"localPtr,attr,omitempty"`
|
||||
DHCP *NetworkDHCP `xml:"dhcp"`
|
||||
TFTP *NetworkTFTP `xml:"tftp"`
|
||||
}
|
||||
|
||||
type NetworkTFTP struct {
|
||||
Root string `xml:"root,attr,omitempty"`
|
||||
}
|
||||
|
||||
type NetworkRoute struct {
|
||||
Family string `xml:"family,attr,omitempty"`
|
||||
Address string `xml:"address,attr,omitempty"`
|
||||
Netmask string `xml:"netmask,attr,omitempty"`
|
||||
Prefix uint `xml:"prefix,attr,omitempty"`
|
||||
Gateway string `xml:"gateway,attr,omitempty"`
|
||||
Metric string `xml:"metric,attr,omitempty"`
|
||||
}
|
||||
|
||||
type NetworkDNSForwarder struct {
|
||||
Domain string `xml:"domain,attr,omitempty"`
|
||||
Addr string `xml:"addr,attr,omitempty"`
|
||||
}
|
||||
|
||||
type NetworkDNSTXT struct {
|
||||
XMLName xml.Name `xml:"txt"`
|
||||
Name string `xml:"name,attr"`
|
||||
Value string `xml:"value,attr"`
|
||||
}
|
||||
|
||||
type NetworkDNSHostHostname struct {
|
||||
Hostname string `xml:",chardata"`
|
||||
}
|
||||
|
||||
type NetworkDNSHost struct {
|
||||
XMLName xml.Name `xml:"host"`
|
||||
IP string `xml:"ip,attr"`
|
||||
Hostnames []NetworkDNSHostHostname `xml:"hostname"`
|
||||
}
|
||||
|
||||
type NetworkDNSSRV struct {
|
||||
XMLName xml.Name `xml:"srv"`
|
||||
Service string `xml:"service,attr,omitempty"`
|
||||
Protocol string `xml:"protocol,attr,omitempty"`
|
||||
Target string `xml:"target,attr,omitempty"`
|
||||
Port uint `xml:"port,attr,omitempty"`
|
||||
Priority uint `xml:"priority,attr,omitempty"`
|
||||
Weight uint `xml:"weight,attr,omitempty"`
|
||||
Domain string `xml:"domain,attr,omitempty"`
|
||||
}
|
||||
|
||||
type NetworkDNS struct {
|
||||
Enable string `xml:"enable,attr,omitempty"`
|
||||
ForwardPlainNames string `xml:"forwardPlainNames,attr,omitempty"`
|
||||
Forwarders []NetworkDNSForwarder `xml:"forwarder"`
|
||||
TXTs []NetworkDNSTXT `xml:"txt"`
|
||||
Host []NetworkDNSHost `xml:"host"`
|
||||
SRVs []NetworkDNSSRV `xml:"srv"`
|
||||
}
|
||||
|
||||
type NetworkMetadata struct {
|
||||
XML string `xml:",innerxml"`
|
||||
}
|
||||
|
||||
type NetworkMTU struct {
|
||||
Size uint `xml:"size,attr"`
|
||||
}
|
||||
|
||||
type Network struct {
|
||||
XMLName xml.Name `xml:"network"`
|
||||
IPv6 string `xml:"ipv6,attr,omitempty"`
|
||||
TrustGuestRxFilters string `xml:"trustGuestRxFilters,attr,omitempty"`
|
||||
Name string `xml:"name,omitempty"`
|
||||
UUID string `xml:"uuid,omitempty"`
|
||||
Metadata *NetworkMetadata `xml:"metadata"`
|
||||
Forward *NetworkForward `xml:"forward"`
|
||||
Bridge *NetworkBridge `xml:"bridge"`
|
||||
MTU *NetworkMTU `xml:"mtu"`
|
||||
MAC *NetworkMAC `xml:"mac"`
|
||||
Domain *NetworkDomain `xml:"domain"`
|
||||
DNS *NetworkDNS `xml:"dns"`
|
||||
VLAN *NetworkVLAN `xml:"vlan"`
|
||||
Bandwidth *NetworkBandwidth `xml:"bandwidth"`
|
||||
IPs []NetworkIP `xml:"ip"`
|
||||
Routes []NetworkRoute `xml:"route"`
|
||||
VirtualPort *NetworkVirtualPort `xml:"virtualport"`
|
||||
PortGroups []NetworkPortGroup `xml:"portgroup"`
|
||||
}
|
||||
|
||||
type NetworkPortGroup struct {
|
||||
XMLName xml.Name `xml:"portgroup"`
|
||||
Name string `xml:"name,attr,omitempty"`
|
||||
Default string `xml:"default,attr,omitempty"`
|
||||
TrustGuestRxFilters string `xml:"trustGuestRxFilters,attr,omitempty"`
|
||||
VLAN *NetworkVLAN `xml:"vlan"`
|
||||
VirtualPort *NetworkVirtualPort `xml:"virtualport"`
|
||||
}
|
||||
|
||||
type NetworkVLAN struct {
|
||||
Trunk string `xml:"trunk,attr,omitempty"`
|
||||
Tags []NetworkVLANTag `xml:"tag"`
|
||||
}
|
||||
|
||||
type NetworkVLANTag struct {
|
||||
ID uint `xml:"id,attr"`
|
||||
NativeMode string `xml:"nativeMode,attr,omitempty"`
|
||||
}
|
||||
|
||||
type NetworkBandwidthParams struct {
|
||||
Average *uint `xml:"average,attr"`
|
||||
Peak *uint `xml:"peak,attr"`
|
||||
Burst *uint `xml:"burst,attr"`
|
||||
Floor *uint `xml:"floor,attr"`
|
||||
}
|
||||
|
||||
type NetworkBandwidth struct {
|
||||
Inbound *NetworkBandwidthParams `xml:"inbound"`
|
||||
Outbound *NetworkBandwidthParams `xml:"outbound"`
|
||||
}
|
||||
|
||||
func (a *NetworkVirtualPortParams) MarshalXML(e *xml.Encoder, start xml.StartElement) error {
|
||||
start.Name.Local = "parameters"
|
||||
if a.Any != nil {
|
||||
return e.EncodeElement(a.Any, start)
|
||||
} else if a.VEPA8021QBG != nil {
|
||||
return e.EncodeElement(a.VEPA8021QBG, start)
|
||||
} else if a.VNTag8011QBH != nil {
|
||||
return e.EncodeElement(a.VNTag8011QBH, start)
|
||||
} else if a.OpenVSwitch != nil {
|
||||
return e.EncodeElement(a.OpenVSwitch, start)
|
||||
} else if a.MidoNet != nil {
|
||||
return e.EncodeElement(a.MidoNet, start)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (a *NetworkVirtualPortParams) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error {
|
||||
if a.Any != nil {
|
||||
return d.DecodeElement(a.Any, &start)
|
||||
} else if a.VEPA8021QBG != nil {
|
||||
return d.DecodeElement(a.VEPA8021QBG, &start)
|
||||
} else if a.VNTag8011QBH != nil {
|
||||
return d.DecodeElement(a.VNTag8011QBH, &start)
|
||||
} else if a.OpenVSwitch != nil {
|
||||
return d.DecodeElement(a.OpenVSwitch, &start)
|
||||
} else if a.MidoNet != nil {
|
||||
return d.DecodeElement(a.MidoNet, &start)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
type networkVirtualPort NetworkVirtualPort
|
||||
|
||||
func (a *NetworkVirtualPort) MarshalXML(e *xml.Encoder, start xml.StartElement) error {
|
||||
start.Name.Local = "virtualport"
|
||||
if a.Params != nil {
|
||||
if a.Params.Any != nil {
|
||||
/* no type attr wanted */
|
||||
} else if a.Params.VEPA8021QBG != nil {
|
||||
start.Attr = append(start.Attr, xml.Attr{
|
||||
xml.Name{Local: "type"}, "802.1Qbg",
|
||||
})
|
||||
} else if a.Params.VNTag8011QBH != nil {
|
||||
start.Attr = append(start.Attr, xml.Attr{
|
||||
xml.Name{Local: "type"}, "802.1Qbh",
|
||||
})
|
||||
} else if a.Params.OpenVSwitch != nil {
|
||||
start.Attr = append(start.Attr, xml.Attr{
|
||||
xml.Name{Local: "type"}, "openvswitch",
|
||||
})
|
||||
} else if a.Params.MidoNet != nil {
|
||||
start.Attr = append(start.Attr, xml.Attr{
|
||||
xml.Name{Local: "type"}, "midonet",
|
||||
})
|
||||
}
|
||||
}
|
||||
vp := networkVirtualPort(*a)
|
||||
return e.EncodeElement(&vp, start)
|
||||
}
|
||||
|
||||
func (a *NetworkVirtualPort) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error {
|
||||
typ, ok := getAttr(start.Attr, "type")
|
||||
a.Params = &NetworkVirtualPortParams{}
|
||||
if !ok {
|
||||
var any NetworkVirtualPortParamsAny
|
||||
a.Params.Any = &any
|
||||
} else if typ == "802.1Qbg" {
|
||||
var vepa NetworkVirtualPortParamsVEPA8021QBG
|
||||
a.Params.VEPA8021QBG = &vepa
|
||||
} else if typ == "802.1Qbh" {
|
||||
var vntag NetworkVirtualPortParamsVNTag8021QBH
|
||||
a.Params.VNTag8011QBH = &vntag
|
||||
} else if typ == "openvswitch" {
|
||||
var ovs NetworkVirtualPortParamsOpenVSwitch
|
||||
a.Params.OpenVSwitch = &ovs
|
||||
} else if typ == "midonet" {
|
||||
var mido NetworkVirtualPortParamsMidoNet
|
||||
a.Params.MidoNet = &mido
|
||||
}
|
||||
|
||||
vp := networkVirtualPort(*a)
|
||||
err := d.DecodeElement(&vp, &start)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
*a = NetworkVirtualPort(vp)
|
||||
return nil
|
||||
}
|
||||
|
||||
func (a *NetworkForwardAddressPCI) MarshalXML(e *xml.Encoder, start xml.StartElement) error {
|
||||
marshalUintAttr(&start, "domain", a.Domain, "0x%04x")
|
||||
marshalUintAttr(&start, "bus", a.Bus, "0x%02x")
|
||||
marshalUintAttr(&start, "slot", a.Slot, "0x%02x")
|
||||
marshalUintAttr(&start, "function", a.Function, "0x%x")
|
||||
e.EncodeToken(start)
|
||||
e.EncodeToken(start.End())
|
||||
return nil
|
||||
}
|
||||
|
||||
func (a *NetworkForwardAddressPCI) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error {
|
||||
for _, attr := range start.Attr {
|
||||
if attr.Name.Local == "domain" {
|
||||
if err := unmarshalUintAttr(attr.Value, &a.Domain, 0); err != nil {
|
||||
return err
|
||||
}
|
||||
} else if attr.Name.Local == "bus" {
|
||||
if err := unmarshalUintAttr(attr.Value, &a.Bus, 0); err != nil {
|
||||
return err
|
||||
}
|
||||
} else if attr.Name.Local == "slot" {
|
||||
if err := unmarshalUintAttr(attr.Value, &a.Slot, 0); err != nil {
|
||||
return err
|
||||
}
|
||||
} else if attr.Name.Local == "function" {
|
||||
if err := unmarshalUintAttr(attr.Value, &a.Function, 0); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
}
|
||||
d.Skip()
|
||||
return nil
|
||||
}
|
||||
|
||||
func (a *NetworkForwardAddress) MarshalXML(e *xml.Encoder, start xml.StartElement) error {
|
||||
if a.PCI != nil {
|
||||
start.Attr = append(start.Attr, xml.Attr{
|
||||
xml.Name{Local: "type"}, "pci",
|
||||
})
|
||||
return e.EncodeElement(a.PCI, start)
|
||||
} else {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
func (a *NetworkForwardAddress) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error {
|
||||
var typ string
|
||||
for _, attr := range start.Attr {
|
||||
if attr.Name.Local == "type" {
|
||||
typ = attr.Value
|
||||
break
|
||||
}
|
||||
}
|
||||
if typ == "" {
|
||||
d.Skip()
|
||||
return nil
|
||||
}
|
||||
|
||||
if typ == "pci" {
|
||||
a.PCI = &NetworkForwardAddressPCI{}
|
||||
return d.DecodeElement(a.PCI, &start)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *NetworkDHCPHost) Unmarshal(doc string) error {
|
||||
return xml.Unmarshal([]byte(doc), s)
|
||||
}
|
||||
|
||||
func (s *NetworkDHCPHost) Marshal() (string, error) {
|
||||
doc, err := xml.MarshalIndent(s, "", " ")
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
return string(doc), nil
|
||||
}
|
||||
|
||||
func (s *NetworkDNSHost) Unmarshal(doc string) error {
|
||||
return xml.Unmarshal([]byte(doc), s)
|
||||
}
|
||||
|
||||
func (s *NetworkDNSHost) Marshal() (string, error) {
|
||||
doc, err := xml.MarshalIndent(s, "", " ")
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
return string(doc), nil
|
||||
}
|
||||
|
||||
func (s *NetworkPortGroup) Unmarshal(doc string) error {
|
||||
return xml.Unmarshal([]byte(doc), s)
|
||||
}
|
||||
|
||||
func (s *NetworkPortGroup) Marshal() (string, error) {
|
||||
doc, err := xml.MarshalIndent(s, "", " ")
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
return string(doc), nil
|
||||
}
|
||||
|
||||
func (s *NetworkDNSTXT) Unmarshal(doc string) error {
|
||||
return xml.Unmarshal([]byte(doc), s)
|
||||
}
|
||||
|
||||
func (s *NetworkDNSTXT) Marshal() (string, error) {
|
||||
doc, err := xml.MarshalIndent(s, "", " ")
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
return string(doc), nil
|
||||
}
|
||||
|
||||
func (s *NetworkDNSSRV) Unmarshal(doc string) error {
|
||||
return xml.Unmarshal([]byte(doc), s)
|
||||
}
|
||||
|
||||
func (s *NetworkDNSSRV) Marshal() (string, error) {
|
||||
doc, err := xml.MarshalIndent(s, "", " ")
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
return string(doc), nil
|
||||
}
|
||||
|
||||
func (s *NetworkDHCPRange) Unmarshal(doc string) error {
|
||||
return xml.Unmarshal([]byte(doc), s)
|
||||
}
|
||||
|
||||
func (s *NetworkDHCPRange) Marshal() (string, error) {
|
||||
doc, err := xml.MarshalIndent(s, "", " ")
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
return string(doc), nil
|
||||
}
|
||||
|
||||
func (s *NetworkForwardInterface) Unmarshal(doc string) error {
|
||||
return xml.Unmarshal([]byte(doc), s)
|
||||
}
|
||||
|
||||
func (s *NetworkForwardInterface) Marshal() (string, error) {
|
||||
doc, err := xml.MarshalIndent(s, "", " ")
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
return string(doc), nil
|
||||
}
|
||||
|
||||
func (s *Network) Unmarshal(doc string) error {
|
||||
return xml.Unmarshal([]byte(doc), s)
|
||||
}
|
||||
|
||||
func (s *Network) Marshal() (string, error) {
|
||||
doc, err := xml.MarshalIndent(s, "", " ")
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
return string(doc), nil
|
||||
}
|
||||
761
vendor/github.com/libvirt/libvirt-go-xml/node_device.go
generated
vendored
Normal file
761
vendor/github.com/libvirt/libvirt-go-xml/node_device.go
generated
vendored
Normal file
@@ -0,0 +1,761 @@
|
||||
/*
|
||||
* 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"
|
||||
"fmt"
|
||||
"io"
|
||||
"strconv"
|
||||
"strings"
|
||||
)
|
||||
|
||||
type NodeDevice struct {
|
||||
XMLName xml.Name `xml:"device"`
|
||||
Name string `xml:"name"`
|
||||
Path string `xml:"path,omitempty"`
|
||||
DevNodes []NodeDeviceDevNode `xml:"devnode"`
|
||||
Parent string `xml:"parent,omitempty"`
|
||||
Driver *NodeDeviceDriver `xml:"driver"`
|
||||
Capability NodeDeviceCapability `xml:"capability"`
|
||||
}
|
||||
|
||||
type NodeDeviceDevNode struct {
|
||||
Type string `xml:"type,attr,omitempty"`
|
||||
Path string `xml:",chardata"`
|
||||
}
|
||||
|
||||
type NodeDeviceDriver struct {
|
||||
Name string `xml:"name"`
|
||||
}
|
||||
|
||||
type NodeDeviceCapability struct {
|
||||
System *NodeDeviceSystemCapability
|
||||
PCI *NodeDevicePCICapability
|
||||
USB *NodeDeviceUSBCapability
|
||||
USBDevice *NodeDeviceUSBDeviceCapability
|
||||
Net *NodeDeviceNetCapability
|
||||
SCSIHost *NodeDeviceSCSIHostCapability
|
||||
SCSITarget *NodeDeviceSCSITargetCapability
|
||||
SCSI *NodeDeviceSCSICapability
|
||||
Storage *NodeDeviceStorageCapability
|
||||
DRM *NodeDeviceDRMCapability
|
||||
CCW *NodeDeviceCCWCapability
|
||||
MDev *NodeDeviceMDevCapability
|
||||
}
|
||||
|
||||
type NodeDeviceIDName struct {
|
||||
ID string `xml:"id,attr"`
|
||||
Name string `xml:",chardata"`
|
||||
}
|
||||
|
||||
type NodeDevicePCIExpress struct {
|
||||
Links []NodeDevicePCIExpressLink `xml:"link"`
|
||||
}
|
||||
|
||||
type NodeDevicePCIExpressLink struct {
|
||||
Validity string `xml:"validity,attr,omitempty"`
|
||||
Speed float64 `xml:"speed,attr,omitempty"`
|
||||
Port *uint `xml:"port,attr"`
|
||||
Width *uint `xml:"width,attr"`
|
||||
}
|
||||
|
||||
type NodeDeviceIOMMUGroup struct {
|
||||
Number int `xml:"number,attr"`
|
||||
Address []NodeDevicePCIAddress `xml:"address"`
|
||||
}
|
||||
|
||||
type NodeDeviceNUMA struct {
|
||||
Node int `xml:"node,attr"`
|
||||
}
|
||||
|
||||
type NodeDevicePCICapability struct {
|
||||
Class string `xml:"class,omitempty"`
|
||||
Domain *uint `xml:"domain"`
|
||||
Bus *uint `xml:"bus"`
|
||||
Slot *uint `xml:"slot"`
|
||||
Function *uint `xml:"function"`
|
||||
Product NodeDeviceIDName `xml:"product,omitempty"`
|
||||
Vendor NodeDeviceIDName `xml:"vendor,omitempty"`
|
||||
IOMMUGroup *NodeDeviceIOMMUGroup `xml:"iommuGroup"`
|
||||
NUMA *NodeDeviceNUMA `xml:"numa"`
|
||||
PCIExpress *NodeDevicePCIExpress `xml:"pci-express"`
|
||||
Capabilities []NodeDevicePCISubCapability `xml:"capability"`
|
||||
}
|
||||
|
||||
type NodeDevicePCIAddress struct {
|
||||
Domain *uint `xml:"domain,attr"`
|
||||
Bus *uint `xml:"bus,attr"`
|
||||
Slot *uint `xml:"slot,attr"`
|
||||
Function *uint `xml:"function,attr"`
|
||||
}
|
||||
|
||||
type NodeDevicePCISubCapability struct {
|
||||
VirtFunctions *NodeDevicePCIVirtFunctionsCapability
|
||||
PhysFunction *NodeDevicePCIPhysFunctionCapability
|
||||
MDevTypes *NodeDevicePCIMDevTypesCapability
|
||||
Bridge *NodeDevicePCIBridgeCapability
|
||||
}
|
||||
|
||||
type NodeDevicePCIVirtFunctionsCapability struct {
|
||||
Address []NodeDevicePCIAddress `xml:"address,omitempty"`
|
||||
MaxCount int `xml:"maxCount,attr,omitempty"`
|
||||
}
|
||||
|
||||
type NodeDevicePCIPhysFunctionCapability struct {
|
||||
Address NodeDevicePCIAddress `xml:"address,omitempty"`
|
||||
}
|
||||
|
||||
type NodeDevicePCIMDevTypesCapability struct {
|
||||
Types []NodeDevicePCIMDevType `xml:"type"`
|
||||
}
|
||||
|
||||
type NodeDevicePCIMDevType struct {
|
||||
ID string `xml:"id,attr"`
|
||||
Name string `xml:"name"`
|
||||
DeviceAPI string `xml:"deviceAPI"`
|
||||
AvailableInstances uint `xml:"availableInstances"`
|
||||
}
|
||||
|
||||
type NodeDevicePCIBridgeCapability struct {
|
||||
}
|
||||
|
||||
type NodeDeviceSystemHardware struct {
|
||||
Vendor string `xml:"vendor"`
|
||||
Version string `xml:"version"`
|
||||
Serial string `xml:"serial"`
|
||||
UUID string `xml:"uuid"`
|
||||
}
|
||||
|
||||
type NodeDeviceSystemFirmware struct {
|
||||
Vendor string `xml:"vendor"`
|
||||
Version string `xml:"version"`
|
||||
ReleaseData string `xml:"release_date"`
|
||||
}
|
||||
|
||||
type NodeDeviceSystemCapability struct {
|
||||
Product string `xml:"product,omitempty"`
|
||||
Hardware *NodeDeviceSystemHardware `xml:"hardware"`
|
||||
Firmware *NodeDeviceSystemFirmware `xml:"firmware"`
|
||||
}
|
||||
|
||||
type NodeDeviceUSBDeviceCapability struct {
|
||||
Bus int `xml:"bus"`
|
||||
Device int `xml:"device"`
|
||||
Product NodeDeviceIDName `xml:"product,omitempty"`
|
||||
Vendor NodeDeviceIDName `xml:"vendor,omitempty"`
|
||||
}
|
||||
|
||||
type NodeDeviceUSBCapability struct {
|
||||
Number int `xml:"number"`
|
||||
Class int `xml:"class"`
|
||||
Subclass int `xml:"subclass"`
|
||||
Protocol int `xml:"protocol"`
|
||||
Description string `xml:"description,omitempty"`
|
||||
}
|
||||
|
||||
type NodeDeviceNetOffloadFeatures struct {
|
||||
Name string `xml:"name,attr"`
|
||||
}
|
||||
|
||||
type NodeDeviceNetLink struct {
|
||||
State string `xml:"state,attr"`
|
||||
Speed string `xml:"speed,attr,omitempty"`
|
||||
}
|
||||
|
||||
type NodeDeviceNetSubCapability struct {
|
||||
Wireless80211 *NodeDeviceNet80211Capability
|
||||
Ethernet80203 *NodeDeviceNet80203Capability
|
||||
}
|
||||
|
||||
type NodeDeviceNet80211Capability struct {
|
||||
}
|
||||
|
||||
type NodeDeviceNet80203Capability struct {
|
||||
}
|
||||
|
||||
type NodeDeviceNetCapability struct {
|
||||
Interface string `xml:"interface"`
|
||||
Address string `xml:"address"`
|
||||
Link *NodeDeviceNetLink `xml:"link"`
|
||||
Features []NodeDeviceNetOffloadFeatures `xml:"feature,omitempty"`
|
||||
Capability []NodeDeviceNetSubCapability `xml:"capability"`
|
||||
}
|
||||
|
||||
type NodeDeviceSCSIVPortOpsCapability struct {
|
||||
VPorts int `xml:"vports,omitempty"`
|
||||
MaxVPorts int `xml:"maxvports,omitempty"`
|
||||
}
|
||||
|
||||
type NodeDeviceSCSIFCHostCapability struct {
|
||||
WWNN string `xml:"wwnn,omitempty"`
|
||||
WWPN string `xml:"wwpn,omitempty"`
|
||||
FabricWWN string `xml:"fabric_wwn,omitempty"`
|
||||
}
|
||||
|
||||
type NodeDeviceSCSIHostSubCapability struct {
|
||||
VPortOps *NodeDeviceSCSIVPortOpsCapability
|
||||
FCHost *NodeDeviceSCSIFCHostCapability
|
||||
}
|
||||
|
||||
type NodeDeviceSCSIHostCapability struct {
|
||||
Host uint `xml:"host"`
|
||||
UniqueID *uint `xml:"unique_id"`
|
||||
Capability []NodeDeviceSCSIHostSubCapability `xml:"capability"`
|
||||
}
|
||||
|
||||
type NodeDeviceSCSITargetCapability struct {
|
||||
Target string `xml:"target"`
|
||||
Capability []NodeDeviceSCSITargetSubCapability `xml:"capability"`
|
||||
}
|
||||
|
||||
type NodeDeviceSCSITargetSubCapability struct {
|
||||
FCRemotePort *NodeDeviceSCSIFCRemotePortCapability
|
||||
}
|
||||
|
||||
type NodeDeviceSCSIFCRemotePortCapability struct {
|
||||
RPort string `xml:"rport"`
|
||||
WWPN string `xml:"wwpn"`
|
||||
}
|
||||
|
||||
type NodeDeviceSCSICapability struct {
|
||||
Host int `xml:"host"`
|
||||
Bus int `xml:"bus"`
|
||||
Target int `xml:"target"`
|
||||
Lun int `xml:"lun"`
|
||||
Type string `xml:"type"`
|
||||
}
|
||||
|
||||
type NodeDeviceStorageSubCapability struct {
|
||||
Removable *NodeDeviceStorageRemovableCapability
|
||||
}
|
||||
|
||||
type NodeDeviceStorageRemovableCapability struct {
|
||||
MediaAvailable *uint `xml:"media_available"`
|
||||
MediaSize *uint `xml:"media_size"`
|
||||
MediaLabel string `xml:"media_label,omitempty"`
|
||||
LogicalBlockSize *uint `xml:"logical_block_size"`
|
||||
NumBlocks *uint `xml:"num_blocks"`
|
||||
}
|
||||
|
||||
type NodeDeviceStorageCapability struct {
|
||||
Block string `xml:"block,omitempty"`
|
||||
Bus string `xml:"bus,omitempty"`
|
||||
DriverType string `xml:"drive_type,omitempty"`
|
||||
Model string `xml:"model,omitempty"`
|
||||
Vendor string `xml:"vendor,omitempty"`
|
||||
Serial string `xml:"serial,omitempty"`
|
||||
Size *uint `xml:"size"`
|
||||
LogicalBlockSize *uint `xml:"logical_block_size"`
|
||||
NumBlocks *uint `xml:"num_blocks"`
|
||||
Capability []NodeDeviceStorageSubCapability `xml:"capability"`
|
||||
}
|
||||
|
||||
type NodeDeviceDRMCapability struct {
|
||||
Type string `xml:"type"`
|
||||
}
|
||||
|
||||
type NodeDeviceCCWCapability struct {
|
||||
CSSID *uint `xml:"cssid"`
|
||||
SSID *uint `xml:"ssid"`
|
||||
DevNo *uint `xml:"devno"`
|
||||
}
|
||||
|
||||
type NodeDeviceMDevCapability struct {
|
||||
Type *NodeDeviceMDevCapabilityType `xml:"type"`
|
||||
IOMMUGroup *NodeDeviceIOMMUGroup `xml:"iommuGroup"`
|
||||
}
|
||||
|
||||
type NodeDeviceMDevCapabilityType struct {
|
||||
ID string `xml:"id,attr"`
|
||||
}
|
||||
|
||||
func (a *NodeDevicePCIAddress) MarshalXML(e *xml.Encoder, start xml.StartElement) error {
|
||||
marshalUintAttr(&start, "domain", a.Domain, "0x%04x")
|
||||
marshalUintAttr(&start, "bus", a.Bus, "0x%02x")
|
||||
marshalUintAttr(&start, "slot", a.Slot, "0x%02x")
|
||||
marshalUintAttr(&start, "function", a.Function, "0x%x")
|
||||
e.EncodeToken(start)
|
||||
e.EncodeToken(start.End())
|
||||
return nil
|
||||
}
|
||||
|
||||
func (a *NodeDevicePCIAddress) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error {
|
||||
for _, attr := range start.Attr {
|
||||
if attr.Name.Local == "domain" {
|
||||
if err := unmarshalUintAttr(attr.Value, &a.Domain, 0); err != nil {
|
||||
return err
|
||||
}
|
||||
} else if attr.Name.Local == "bus" {
|
||||
if err := unmarshalUintAttr(attr.Value, &a.Bus, 0); err != nil {
|
||||
return err
|
||||
}
|
||||
} else if attr.Name.Local == "slot" {
|
||||
if err := unmarshalUintAttr(attr.Value, &a.Slot, 0); err != nil {
|
||||
return err
|
||||
}
|
||||
} else if attr.Name.Local == "function" {
|
||||
if err := unmarshalUintAttr(attr.Value, &a.Function, 0); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
}
|
||||
d.Skip()
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *NodeDeviceCCWCapability) MarshalXML(e *xml.Encoder, start xml.StartElement) error {
|
||||
e.EncodeToken(start)
|
||||
if c.CSSID != nil {
|
||||
cssid := xml.StartElement{
|
||||
Name: xml.Name{Local: "cssid"},
|
||||
}
|
||||
e.EncodeToken(cssid)
|
||||
e.EncodeToken(xml.CharData(fmt.Sprintf("0x%x", *c.CSSID)))
|
||||
e.EncodeToken(cssid.End())
|
||||
}
|
||||
if c.SSID != nil {
|
||||
ssid := xml.StartElement{
|
||||
Name: xml.Name{Local: "ssid"},
|
||||
}
|
||||
e.EncodeToken(ssid)
|
||||
e.EncodeToken(xml.CharData(fmt.Sprintf("0x%x", *c.SSID)))
|
||||
e.EncodeToken(ssid.End())
|
||||
}
|
||||
if c.DevNo != nil {
|
||||
devno := xml.StartElement{
|
||||
Name: xml.Name{Local: "devno"},
|
||||
}
|
||||
e.EncodeToken(devno)
|
||||
e.EncodeToken(xml.CharData(fmt.Sprintf("0x%04x", *c.DevNo)))
|
||||
e.EncodeToken(devno.End())
|
||||
}
|
||||
e.EncodeToken(start.End())
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *NodeDeviceCCWCapability) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error {
|
||||
for {
|
||||
tok, err := d.Token()
|
||||
if err == io.EOF {
|
||||
break
|
||||
}
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
switch tok := tok.(type) {
|
||||
case xml.StartElement:
|
||||
cdata, err := d.Token()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if tok.Name.Local != "cssid" &&
|
||||
tok.Name.Local != "ssid" &&
|
||||
tok.Name.Local != "devno" {
|
||||
continue
|
||||
}
|
||||
|
||||
chardata, ok := cdata.(xml.CharData)
|
||||
if !ok {
|
||||
return fmt.Errorf("Expected text for CCW '%s'", tok.Name.Local)
|
||||
}
|
||||
|
||||
valstr := strings.TrimPrefix(string(chardata), "0x")
|
||||
val, err := strconv.ParseUint(valstr, 16, 64)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
vali := uint(val)
|
||||
if tok.Name.Local == "cssid" {
|
||||
c.CSSID = &vali
|
||||
} else if tok.Name.Local == "ssid" {
|
||||
c.SSID = &vali
|
||||
} else if tok.Name.Local == "devno" {
|
||||
c.DevNo = &vali
|
||||
}
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *NodeDevicePCISubCapability) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error {
|
||||
typ, ok := getAttr(start.Attr, "type")
|
||||
if !ok {
|
||||
return fmt.Errorf("Missing node device capability type")
|
||||
}
|
||||
|
||||
switch typ {
|
||||
case "virt_functions":
|
||||
var virtFuncCaps NodeDevicePCIVirtFunctionsCapability
|
||||
if err := d.DecodeElement(&virtFuncCaps, &start); err != nil {
|
||||
return err
|
||||
}
|
||||
c.VirtFunctions = &virtFuncCaps
|
||||
case "phys_function":
|
||||
var physFuncCaps NodeDevicePCIPhysFunctionCapability
|
||||
if err := d.DecodeElement(&physFuncCaps, &start); err != nil {
|
||||
return err
|
||||
}
|
||||
c.PhysFunction = &physFuncCaps
|
||||
case "mdev_types":
|
||||
var mdevTypeCaps NodeDevicePCIMDevTypesCapability
|
||||
if err := d.DecodeElement(&mdevTypeCaps, &start); err != nil {
|
||||
return err
|
||||
}
|
||||
c.MDevTypes = &mdevTypeCaps
|
||||
case "pci-bridge":
|
||||
var bridgeCaps NodeDevicePCIBridgeCapability
|
||||
if err := d.DecodeElement(&bridgeCaps, &start); err != nil {
|
||||
return err
|
||||
}
|
||||
c.Bridge = &bridgeCaps
|
||||
}
|
||||
d.Skip()
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *NodeDevicePCISubCapability) MarshalXML(e *xml.Encoder, start xml.StartElement) error {
|
||||
if c.VirtFunctions != nil {
|
||||
start.Attr = append(start.Attr, xml.Attr{
|
||||
xml.Name{Local: "type"}, "virt_functions",
|
||||
})
|
||||
return e.EncodeElement(c.VirtFunctions, start)
|
||||
} else if c.PhysFunction != nil {
|
||||
start.Attr = append(start.Attr, xml.Attr{
|
||||
xml.Name{Local: "type"}, "phys_function",
|
||||
})
|
||||
return e.EncodeElement(c.PhysFunction, start)
|
||||
} else if c.MDevTypes != nil {
|
||||
start.Attr = append(start.Attr, xml.Attr{
|
||||
xml.Name{Local: "type"}, "mdev_types",
|
||||
})
|
||||
return e.EncodeElement(c.MDevTypes, start)
|
||||
} else if c.Bridge != nil {
|
||||
start.Attr = append(start.Attr, xml.Attr{
|
||||
xml.Name{Local: "type"}, "pci-bridge",
|
||||
})
|
||||
return e.EncodeElement(c.Bridge, start)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *NodeDeviceSCSITargetSubCapability) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error {
|
||||
typ, ok := getAttr(start.Attr, "type")
|
||||
if !ok {
|
||||
return fmt.Errorf("Missing node device capability type")
|
||||
}
|
||||
|
||||
switch typ {
|
||||
case "fc_remote_port":
|
||||
var fcCaps NodeDeviceSCSIFCRemotePortCapability
|
||||
if err := d.DecodeElement(&fcCaps, &start); err != nil {
|
||||
return err
|
||||
}
|
||||
c.FCRemotePort = &fcCaps
|
||||
}
|
||||
d.Skip()
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *NodeDeviceSCSITargetSubCapability) MarshalXML(e *xml.Encoder, start xml.StartElement) error {
|
||||
if c.FCRemotePort != nil {
|
||||
start.Attr = append(start.Attr, xml.Attr{
|
||||
xml.Name{Local: "type"}, "fc_remote_port",
|
||||
})
|
||||
return e.EncodeElement(c.FCRemotePort, start)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *NodeDeviceSCSIHostSubCapability) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error {
|
||||
typ, ok := getAttr(start.Attr, "type")
|
||||
if !ok {
|
||||
return fmt.Errorf("Missing node device capability type")
|
||||
}
|
||||
|
||||
switch typ {
|
||||
case "fc_host":
|
||||
var fcCaps NodeDeviceSCSIFCHostCapability
|
||||
if err := d.DecodeElement(&fcCaps, &start); err != nil {
|
||||
return err
|
||||
}
|
||||
c.FCHost = &fcCaps
|
||||
case "vport_ops":
|
||||
var vportCaps NodeDeviceSCSIVPortOpsCapability
|
||||
if err := d.DecodeElement(&vportCaps, &start); err != nil {
|
||||
return err
|
||||
}
|
||||
c.VPortOps = &vportCaps
|
||||
}
|
||||
d.Skip()
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *NodeDeviceSCSIHostSubCapability) MarshalXML(e *xml.Encoder, start xml.StartElement) error {
|
||||
if c.FCHost != nil {
|
||||
start.Attr = append(start.Attr, xml.Attr{
|
||||
xml.Name{Local: "type"}, "fc_host",
|
||||
})
|
||||
return e.EncodeElement(c.FCHost, start)
|
||||
} else if c.VPortOps != nil {
|
||||
start.Attr = append(start.Attr, xml.Attr{
|
||||
xml.Name{Local: "type"}, "vport_ops",
|
||||
})
|
||||
return e.EncodeElement(c.VPortOps, start)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *NodeDeviceStorageSubCapability) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error {
|
||||
typ, ok := getAttr(start.Attr, "type")
|
||||
if !ok {
|
||||
return fmt.Errorf("Missing node device capability type")
|
||||
}
|
||||
|
||||
switch typ {
|
||||
case "removable":
|
||||
var removeCaps NodeDeviceStorageRemovableCapability
|
||||
if err := d.DecodeElement(&removeCaps, &start); err != nil {
|
||||
return err
|
||||
}
|
||||
c.Removable = &removeCaps
|
||||
}
|
||||
d.Skip()
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *NodeDeviceStorageSubCapability) MarshalXML(e *xml.Encoder, start xml.StartElement) error {
|
||||
if c.Removable != nil {
|
||||
start.Attr = append(start.Attr, xml.Attr{
|
||||
xml.Name{Local: "type"}, "removable",
|
||||
})
|
||||
return e.EncodeElement(c.Removable, start)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *NodeDeviceNetSubCapability) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error {
|
||||
typ, ok := getAttr(start.Attr, "type")
|
||||
if !ok {
|
||||
return fmt.Errorf("Missing node device capability type")
|
||||
}
|
||||
|
||||
switch typ {
|
||||
case "80211":
|
||||
var wlanCaps NodeDeviceNet80211Capability
|
||||
if err := d.DecodeElement(&wlanCaps, &start); err != nil {
|
||||
return err
|
||||
}
|
||||
c.Wireless80211 = &wlanCaps
|
||||
case "80203":
|
||||
var ethCaps NodeDeviceNet80203Capability
|
||||
if err := d.DecodeElement(ðCaps, &start); err != nil {
|
||||
return err
|
||||
}
|
||||
c.Ethernet80203 = ðCaps
|
||||
}
|
||||
d.Skip()
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *NodeDeviceNetSubCapability) MarshalXML(e *xml.Encoder, start xml.StartElement) error {
|
||||
if c.Wireless80211 != nil {
|
||||
start.Attr = append(start.Attr, xml.Attr{
|
||||
xml.Name{Local: "type"}, "80211",
|
||||
})
|
||||
return e.EncodeElement(c.Wireless80211, start)
|
||||
} else if c.Ethernet80203 != nil {
|
||||
start.Attr = append(start.Attr, xml.Attr{
|
||||
xml.Name{Local: "type"}, "80203",
|
||||
})
|
||||
return e.EncodeElement(c.Ethernet80203, start)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *NodeDeviceCapability) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error {
|
||||
typ, ok := getAttr(start.Attr, "type")
|
||||
if !ok {
|
||||
return fmt.Errorf("Missing node device capability type")
|
||||
}
|
||||
|
||||
switch typ {
|
||||
case "pci":
|
||||
var pciCaps NodeDevicePCICapability
|
||||
if err := d.DecodeElement(&pciCaps, &start); err != nil {
|
||||
return err
|
||||
}
|
||||
c.PCI = &pciCaps
|
||||
case "system":
|
||||
var systemCaps NodeDeviceSystemCapability
|
||||
if err := d.DecodeElement(&systemCaps, &start); err != nil {
|
||||
return err
|
||||
}
|
||||
c.System = &systemCaps
|
||||
case "usb_device":
|
||||
var usbdevCaps NodeDeviceUSBDeviceCapability
|
||||
if err := d.DecodeElement(&usbdevCaps, &start); err != nil {
|
||||
return err
|
||||
}
|
||||
c.USBDevice = &usbdevCaps
|
||||
case "usb":
|
||||
var usbCaps NodeDeviceUSBCapability
|
||||
if err := d.DecodeElement(&usbCaps, &start); err != nil {
|
||||
return err
|
||||
}
|
||||
c.USB = &usbCaps
|
||||
case "net":
|
||||
var netCaps NodeDeviceNetCapability
|
||||
if err := d.DecodeElement(&netCaps, &start); err != nil {
|
||||
return err
|
||||
}
|
||||
c.Net = &netCaps
|
||||
case "scsi_host":
|
||||
var scsiHostCaps NodeDeviceSCSIHostCapability
|
||||
if err := d.DecodeElement(&scsiHostCaps, &start); err != nil {
|
||||
return err
|
||||
}
|
||||
c.SCSIHost = &scsiHostCaps
|
||||
case "scsi_target":
|
||||
var scsiTargetCaps NodeDeviceSCSITargetCapability
|
||||
if err := d.DecodeElement(&scsiTargetCaps, &start); err != nil {
|
||||
return err
|
||||
}
|
||||
c.SCSITarget = &scsiTargetCaps
|
||||
case "scsi":
|
||||
var scsiCaps NodeDeviceSCSICapability
|
||||
if err := d.DecodeElement(&scsiCaps, &start); err != nil {
|
||||
return err
|
||||
}
|
||||
c.SCSI = &scsiCaps
|
||||
case "storage":
|
||||
var storageCaps NodeDeviceStorageCapability
|
||||
if err := d.DecodeElement(&storageCaps, &start); err != nil {
|
||||
return err
|
||||
}
|
||||
c.Storage = &storageCaps
|
||||
case "drm":
|
||||
var drmCaps NodeDeviceDRMCapability
|
||||
if err := d.DecodeElement(&drmCaps, &start); err != nil {
|
||||
return err
|
||||
}
|
||||
c.DRM = &drmCaps
|
||||
case "ccw":
|
||||
var ccwCaps NodeDeviceCCWCapability
|
||||
if err := d.DecodeElement(&ccwCaps, &start); err != nil {
|
||||
return err
|
||||
}
|
||||
c.CCW = &ccwCaps
|
||||
case "mdev":
|
||||
var mdevCaps NodeDeviceMDevCapability
|
||||
if err := d.DecodeElement(&mdevCaps, &start); err != nil {
|
||||
return err
|
||||
}
|
||||
c.MDev = &mdevCaps
|
||||
}
|
||||
d.Skip()
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *NodeDeviceCapability) MarshalXML(e *xml.Encoder, start xml.StartElement) error {
|
||||
if c.PCI != nil {
|
||||
start.Attr = append(start.Attr, xml.Attr{
|
||||
xml.Name{Local: "type"}, "pci",
|
||||
})
|
||||
return e.EncodeElement(c.PCI, start)
|
||||
} else if c.System != nil {
|
||||
start.Attr = append(start.Attr, xml.Attr{
|
||||
xml.Name{Local: "type"}, "system",
|
||||
})
|
||||
return e.EncodeElement(c.System, start)
|
||||
} else if c.USB != nil {
|
||||
start.Attr = append(start.Attr, xml.Attr{
|
||||
xml.Name{Local: "type"}, "usb",
|
||||
})
|
||||
return e.EncodeElement(c.USB, start)
|
||||
} else if c.USBDevice != nil {
|
||||
start.Attr = append(start.Attr, xml.Attr{
|
||||
xml.Name{Local: "type"}, "usb_device",
|
||||
})
|
||||
return e.EncodeElement(c.USBDevice, start)
|
||||
} else if c.Net != nil {
|
||||
start.Attr = append(start.Attr, xml.Attr{
|
||||
xml.Name{Local: "type"}, "net",
|
||||
})
|
||||
return e.EncodeElement(c.Net, start)
|
||||
} else if c.SCSI != nil {
|
||||
start.Attr = append(start.Attr, xml.Attr{
|
||||
xml.Name{Local: "type"}, "scsi",
|
||||
})
|
||||
return e.EncodeElement(c.SCSI, start)
|
||||
} else if c.SCSIHost != nil {
|
||||
start.Attr = append(start.Attr, xml.Attr{
|
||||
xml.Name{Local: "type"}, "scsi_host",
|
||||
})
|
||||
return e.EncodeElement(c.SCSIHost, start)
|
||||
} else if c.SCSITarget != nil {
|
||||
start.Attr = append(start.Attr, xml.Attr{
|
||||
xml.Name{Local: "type"}, "scsi_target",
|
||||
})
|
||||
return e.EncodeElement(c.SCSITarget, start)
|
||||
} else if c.Storage != nil {
|
||||
start.Attr = append(start.Attr, xml.Attr{
|
||||
xml.Name{Local: "type"}, "storage",
|
||||
})
|
||||
return e.EncodeElement(c.Storage, start)
|
||||
} else if c.DRM != nil {
|
||||
start.Attr = append(start.Attr, xml.Attr{
|
||||
xml.Name{Local: "type"}, "drm",
|
||||
})
|
||||
return e.EncodeElement(c.DRM, start)
|
||||
} else if c.CCW != nil {
|
||||
start.Attr = append(start.Attr, xml.Attr{
|
||||
xml.Name{Local: "type"}, "ccw",
|
||||
})
|
||||
return e.EncodeElement(c.CCW, start)
|
||||
} else if c.MDev != nil {
|
||||
start.Attr = append(start.Attr, xml.Attr{
|
||||
xml.Name{Local: "type"}, "mdev",
|
||||
})
|
||||
return e.EncodeElement(c.MDev, start)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *NodeDevice) Unmarshal(doc string) error {
|
||||
return xml.Unmarshal([]byte(doc), c)
|
||||
}
|
||||
|
||||
func (c *NodeDevice) Marshal() (string, error) {
|
||||
doc, err := xml.MarshalIndent(c, "", " ")
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
return string(doc), nil
|
||||
}
|
||||
514
vendor/github.com/libvirt/libvirt-go-xml/nwfilter.go
generated
vendored
Normal file
514
vendor/github.com/libvirt/libvirt-go-xml/nwfilter.go
generated
vendored
Normal file
@@ -0,0 +1,514 @@
|
||||
/*
|
||||
* 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 Lian Duan <blazeblue@gmail.com>
|
||||
*
|
||||
*/
|
||||
|
||||
package libvirtxml
|
||||
|
||||
import (
|
||||
"encoding/xml"
|
||||
"fmt"
|
||||
"io"
|
||||
"strconv"
|
||||
"strings"
|
||||
)
|
||||
|
||||
type NWFilter struct {
|
||||
XMLName xml.Name `xml:"filter"`
|
||||
Name string `xml:"name,attr"`
|
||||
UUID string `xml:"uuid,omitempty"`
|
||||
Chain string `xml:"chain,attr,omitempty"`
|
||||
Priority int `xml:"priority,attr,omitempty"`
|
||||
Entries []NWFilterEntry
|
||||
}
|
||||
|
||||
type NWFilterEntry struct {
|
||||
Rule *NWFilterRule
|
||||
Ref *NWFilterRef
|
||||
}
|
||||
|
||||
type NWFilterRef struct {
|
||||
Filter string `xml:"filter,attr"`
|
||||
Parameters []NWFilterParameter `xml:"parameter"`
|
||||
}
|
||||
|
||||
type NWFilterParameter struct {
|
||||
Name string `xml:"name,attr"`
|
||||
Value string `xml:"value,attr"`
|
||||
}
|
||||
|
||||
type NWFilterField struct {
|
||||
Var string
|
||||
Str string
|
||||
Uint *uint
|
||||
}
|
||||
|
||||
type NWFilterRule struct {
|
||||
Action string `xml:"action,attr,omitempty"`
|
||||
Direction string `xml:"direction,attr,omitempty"`
|
||||
Priority int `xml:"priority,attr,omitempty"`
|
||||
StateMatch string `xml:"statematch,attr,omitempty"`
|
||||
|
||||
ARP *NWFilterRuleARP `xml:"arp"`
|
||||
RARP *NWFilterRuleRARP `xml:"rarp"`
|
||||
MAC *NWFilterRuleMAC `xml:"mac"`
|
||||
VLAN *NWFilterRuleVLAN `xml:"vlan"`
|
||||
STP *NWFilterRuleSTP `xml:"stp"`
|
||||
IP *NWFilterRuleIP `xml:"ip"`
|
||||
IPv6 *NWFilterRuleIPv6 `xml:"ipv6"`
|
||||
TCP *NWFilterRuleTCP `xml:"tcp"`
|
||||
UDP *NWFilterRuleUDP `xml:"udp"`
|
||||
UDPLite *NWFilterRuleUDPLite `xml:"udplite"`
|
||||
ESP *NWFilterRuleESP `xml:"esp"`
|
||||
AH *NWFilterRuleAH `xml:"ah"`
|
||||
SCTP *NWFilterRuleSCTP `xml:"sctp"`
|
||||
ICMP *NWFilterRuleICMP `xml:"icmp"`
|
||||
All *NWFilterRuleAll `xml:"all"`
|
||||
IGMP *NWFilterRuleIGMP `xml:"igmp"`
|
||||
TCPIPv6 *NWFilterRuleTCPIPv6 `xml:"tcp-ipv6"`
|
||||
UDPIPv6 *NWFilterRuleUDPIPv6 `xml:"udp-ipv6"`
|
||||
UDPLiteIPv6 *NWFilterRuleUDPLiteIPv6 `xml:"udplite-ipv6"`
|
||||
ESPIPv6 *NWFilterRuleESPIPv6 `xml:"esp-ipv6"`
|
||||
AHIPv6 *NWFilterRuleAHIPv6 `xml:"ah-ipv6"`
|
||||
SCTPIPv6 *NWFilterRuleSCTPIPv6 `xml:"sctp-ipv6"`
|
||||
ICMPv6 *NWFilterRuleICMPIPv6 `xml:"icmpv6"`
|
||||
AllIPv6 *NWFilterRuleAllIPv6 `xml:"all-ipv6"`
|
||||
}
|
||||
|
||||
type NWFilterRuleCommonMAC struct {
|
||||
SrcMACAddr NWFilterField `xml:"srcmacaddr,attr,omitempty"`
|
||||
SrcMACMask NWFilterField `xml:"srcmacmask,attr,omitempty"`
|
||||
DstMACAddr NWFilterField `xml:"dstmacaddr,attr,omitempty"`
|
||||
DstMACMask NWFilterField `xml:"dstmacmask,attr,omitempty"`
|
||||
}
|
||||
|
||||
type NWFilterRuleCommonIP struct {
|
||||
SrcMACAddr NWFilterField `xml:"srcmacaddr,attr,omitempty"`
|
||||
SrcIPAddr NWFilterField `xml:"srcipaddr,attr,omitempty"`
|
||||
SrcIPMask NWFilterField `xml:"srcipmask,attr,omitempty"`
|
||||
DstIPAddr NWFilterField `xml:"dstipaddr,attr,omitempty"`
|
||||
DstIPMask NWFilterField `xml:"dstipmask,attr,omitempty"`
|
||||
SrcIPFrom NWFilterField `xml:"srcipfrom,attr,omitempty"`
|
||||
SrcIPTo NWFilterField `xml:"srcipto,attr,omitempty"`
|
||||
DstIPFrom NWFilterField `xml:"dstipfrom,attr,omitempty"`
|
||||
DstIPTo NWFilterField `xml:"dstipto,attr,omitempty"`
|
||||
DSCP NWFilterField `xml:"dscp,attr"`
|
||||
ConnLimitAbove NWFilterField `xml:"connlimit-above,attr"`
|
||||
State NWFilterField `xml:"state,attr,omitempty"`
|
||||
IPSet NWFilterField `xml:"ipset,attr,omitempty"`
|
||||
IPSetFlags NWFilterField `xml:"ipsetflags,attr,omitempty"`
|
||||
}
|
||||
|
||||
type NWFilterRuleCommonPort struct {
|
||||
SrcPortStart NWFilterField `xml:"srcportstart,attr"`
|
||||
SrcPortEnd NWFilterField `xml:"srcportend,attr"`
|
||||
DstPortStart NWFilterField `xml:"dstportstart,attr"`
|
||||
DstPortEnd NWFilterField `xml:"dstportend,attr"`
|
||||
}
|
||||
|
||||
type NWFilterRuleARP struct {
|
||||
Match string `xml:"match,attr,omitempty"`
|
||||
NWFilterRuleCommonMAC
|
||||
HWType NWFilterField `xml:"hwtype,attr"`
|
||||
ProtocolType NWFilterField `xml:"protocoltype,attr"`
|
||||
OpCode NWFilterField `xml:"opcode,attr,omitempty"`
|
||||
ARPSrcMACAddr NWFilterField `xml:"arpsrcmacaddr,attr,omitempty"`
|
||||
ARPDstMACAddr NWFilterField `xml:"arpdstmacaddr,attr,omitempty"`
|
||||
ARPSrcIPAddr NWFilterField `xml:"arpsrcipaddr,attr,omitempty"`
|
||||
ARPSrcIPMask NWFilterField `xml:"arpsrcipmask,attr,omitempty"`
|
||||
ARPDstIPAddr NWFilterField `xml:"arpdstipaddr,attr,omitempty"`
|
||||
ARPDstIPMask NWFilterField `xml:"arpdstipmask,attr,omitempty"`
|
||||
Gratuitous NWFilterField `xml:"gratuitous,attr,omitempty"`
|
||||
Comment string `xml:"comment,attr,omitempty"`
|
||||
}
|
||||
|
||||
type NWFilterRuleRARP struct {
|
||||
Match string `xml:"match,attr,omitempty"`
|
||||
NWFilterRuleCommonMAC
|
||||
HWType NWFilterField `xml:"hwtype,attr"`
|
||||
ProtocolType NWFilterField `xml:"protocoltype,attr"`
|
||||
OpCode NWFilterField `xml:"opcode,attr,omitempty"`
|
||||
ARPSrcMACAddr NWFilterField `xml:"arpsrcmacaddr,attr,omitempty"`
|
||||
ARPDstMACAddr NWFilterField `xml:"arpdstmacaddr,attr,omitempty"`
|
||||
ARPSrcIPAddr NWFilterField `xml:"arpsrcipaddr,attr,omitempty"`
|
||||
ARPSrcIPMask NWFilterField `xml:"arpsrcipmask,attr,omitempty"`
|
||||
ARPDstIPAddr NWFilterField `xml:"arpdstipaddr,attr,omitempty"`
|
||||
ARPDstIPMask NWFilterField `xml:"arpdstipmask,attr,omitempty"`
|
||||
Gratuitous NWFilterField `xml:"gratuitous,attr,omitempty"`
|
||||
Comment string `xml:"comment,attr,omitempty"`
|
||||
}
|
||||
|
||||
type NWFilterRuleMAC struct {
|
||||
Match string `xml:"match,attr,omitempty"`
|
||||
NWFilterRuleCommonMAC
|
||||
ProtocolID NWFilterField `xml:"protocolid,attr,omitempty"`
|
||||
Comment string `xml:"comment,attr,omitempty"`
|
||||
}
|
||||
|
||||
type NWFilterRuleVLAN struct {
|
||||
Match string `xml:"match,attr,omitempty"`
|
||||
NWFilterRuleCommonMAC
|
||||
VLANID NWFilterField `xml:"vlanid,attr,omitempty"`
|
||||
EncapProtocol NWFilterField `xml:"encap-protocol,attr,omitempty"`
|
||||
Comment string `xml:"comment,attr,omitempty"`
|
||||
}
|
||||
|
||||
type NWFilterRuleSTP struct {
|
||||
Match NWFilterField `xml:"match,attr,omitempty"`
|
||||
SrcMACAddr NWFilterField `xml:"srcmacaddr,attr,omitempty"`
|
||||
SrcMACMask NWFilterField `xml:"srcmacmask,attr,omitempty"`
|
||||
Type NWFilterField `xml:"type,attr"`
|
||||
Flags NWFilterField `xml:"flags,attr"`
|
||||
RootPriority NWFilterField `xml:"root-priority,attr"`
|
||||
RootPriorityHi NWFilterField `xml:"root-priority-hi,attr"`
|
||||
RootAddress NWFilterField `xml:"root-address,attr,omitempty"`
|
||||
RootAddressMask NWFilterField `xml:"root-address-mask,attr,omitempty"`
|
||||
RootCost NWFilterField `xml:"root-cost,attr"`
|
||||
RootCostHi NWFilterField `xml:"root-cost-hi,attr"`
|
||||
SenderPriority NWFilterField `xml:"sender-priority,attr"`
|
||||
SenderPriorityHi NWFilterField `xml:"sender-priority-hi,attr"`
|
||||
SenderAddress NWFilterField `xml:"sender-address,attr,omitempty"`
|
||||
SenderAddressMask NWFilterField `xml:"sender-address-mask,attr,omitempty"`
|
||||
Port NWFilterField `xml:"port,attr"`
|
||||
PortHi NWFilterField `xml:"port-hi,attr"`
|
||||
Age NWFilterField `xml:"age,attr"`
|
||||
AgeHi NWFilterField `xml:"age-hi,attr"`
|
||||
MaxAge NWFilterField `xml:"max-age,attr"`
|
||||
MaxAgeHi NWFilterField `xml:"max-age-hi,attr"`
|
||||
HelloTime NWFilterField `xml:"hello-time,attr"`
|
||||
HelloTimeHi NWFilterField `xml:"hello-time-hi,attr"`
|
||||
ForwardDelay NWFilterField `xml:"forward-delay,attr"`
|
||||
ForwardDelayHi NWFilterField `xml:"forward-delay-hi,attr"`
|
||||
Comment string `xml:"comment,attr,omitempty"`
|
||||
}
|
||||
|
||||
type NWFilterRuleIP struct {
|
||||
Match string `xml:"match,attr,omitempty"`
|
||||
NWFilterRuleCommonMAC
|
||||
SrcIPAddr NWFilterField `xml:"srcipaddr,attr,omitempty"`
|
||||
SrcIPMask NWFilterField `xml:"srcipmask,attr,omitempty"`
|
||||
DstIPAddr NWFilterField `xml:"dstipaddr,attr,omitempty"`
|
||||
DstIPMask NWFilterField `xml:"dstipmask,attr,omitempty"`
|
||||
Protocol NWFilterField `xml:"protocol,attr,omitempty"`
|
||||
NWFilterRuleCommonPort
|
||||
DSCP NWFilterField `xml:"dscp,attr"`
|
||||
Comment string `xml:"comment,attr,omitempty"`
|
||||
}
|
||||
|
||||
type NWFilterRuleIPv6 struct {
|
||||
Match string `xml:"match,attr,omitempty"`
|
||||
NWFilterRuleCommonMAC
|
||||
SrcIPAddr NWFilterField `xml:"srcipaddr,attr,omitempty"`
|
||||
SrcIPMask NWFilterField `xml:"srcipmask,attr,omitempty"`
|
||||
DstIPAddr NWFilterField `xml:"dstipaddr,attr,omitempty"`
|
||||
DstIPMask NWFilterField `xml:"dstipmask,attr,omitempty"`
|
||||
Protocol NWFilterField `xml:"protocol,attr,omitempty"`
|
||||
NWFilterRuleCommonPort
|
||||
Type NWFilterField `xml:"type,attr"`
|
||||
TypeEnd NWFilterField `xml:"typeend,attr"`
|
||||
Code NWFilterField `xml:"code,attr"`
|
||||
CodeEnd NWFilterField `xml:"codeend,attr"`
|
||||
Comment string `xml:"comment,attr,omitempty"`
|
||||
}
|
||||
|
||||
type NWFilterRuleTCP struct {
|
||||
Match string `xml:"match,attr,omitempty"`
|
||||
NWFilterRuleCommonIP
|
||||
NWFilterRuleCommonPort
|
||||
Option NWFilterField `xml:"option,attr"`
|
||||
Flags NWFilterField `xml:"flags,attr,omitempty"`
|
||||
Comment string `xml:"comment,attr,omitempty"`
|
||||
}
|
||||
|
||||
type NWFilterRuleUDP struct {
|
||||
Match string `xml:"match,attr,omitempty"`
|
||||
NWFilterRuleCommonIP
|
||||
NWFilterRuleCommonPort
|
||||
Comment string `xml:"comment,attr,omitempty"`
|
||||
}
|
||||
|
||||
type NWFilterRuleUDPLite struct {
|
||||
Match string `xml:"match,attr,omitempty"`
|
||||
NWFilterRuleCommonIP
|
||||
Comment string `xml:"comment,attr,omitempty"`
|
||||
}
|
||||
|
||||
type NWFilterRuleESP struct {
|
||||
Match string `xml:"match,attr,omitempty"`
|
||||
NWFilterRuleCommonIP
|
||||
Comment string `xml:"comment,attr,omitempty"`
|
||||
}
|
||||
|
||||
type NWFilterRuleAH struct {
|
||||
Match string `xml:"match,attr,omitempty"`
|
||||
NWFilterRuleCommonIP
|
||||
Comment string `xml:"comment,attr,omitempty"`
|
||||
}
|
||||
|
||||
type NWFilterRuleSCTP struct {
|
||||
Match string `xml:"match,attr,omitempty"`
|
||||
NWFilterRuleCommonIP
|
||||
NWFilterRuleCommonPort
|
||||
Comment string `xml:"comment,attr,omitempty"`
|
||||
}
|
||||
|
||||
type NWFilterRuleICMP struct {
|
||||
Match string `xml:"match,attr,omitempty"`
|
||||
NWFilterRuleCommonIP
|
||||
Type NWFilterField `xml:"type,attr"`
|
||||
Code NWFilterField `xml:"code,attr"`
|
||||
Comment string `xml:"comment,attr,omitempty"`
|
||||
}
|
||||
|
||||
type NWFilterRuleAll struct {
|
||||
Match string `xml:"match,attr,omitempty"`
|
||||
NWFilterRuleCommonIP
|
||||
Comment string `xml:"comment,attr,omitempty"`
|
||||
}
|
||||
|
||||
type NWFilterRuleIGMP struct {
|
||||
Match string `xml:"match,attr,omitempty"`
|
||||
NWFilterRuleCommonIP
|
||||
Comment string `xml:"comment,attr,omitempty"`
|
||||
}
|
||||
|
||||
type NWFilterRuleTCPIPv6 struct {
|
||||
Match string `xml:"match,attr,omitempty"`
|
||||
NWFilterRuleCommonIP
|
||||
NWFilterRuleCommonPort
|
||||
Option NWFilterField `xml:"option,attr"`
|
||||
Comment string `xml:"comment,attr,omitempty"`
|
||||
}
|
||||
|
||||
type NWFilterRuleUDPIPv6 struct {
|
||||
Match string `xml:"match,attr,omitempty"`
|
||||
NWFilterRuleCommonIP
|
||||
NWFilterRuleCommonPort
|
||||
Comment string `xml:"comment,attr,omitempty"`
|
||||
}
|
||||
|
||||
type NWFilterRuleUDPLiteIPv6 struct {
|
||||
Match string `xml:"match,attr,omitempty"`
|
||||
NWFilterRuleCommonIP
|
||||
Comment string `xml:"comment,attr,omitempty"`
|
||||
}
|
||||
|
||||
type NWFilterRuleESPIPv6 struct {
|
||||
Match string `xml:"match,attr,omitempty"`
|
||||
NWFilterRuleCommonIP
|
||||
Comment string `xml:"comment,attr,omitempty"`
|
||||
}
|
||||
|
||||
type NWFilterRuleAHIPv6 struct {
|
||||
Match string `xml:"match,attr,omitempty"`
|
||||
NWFilterRuleCommonIP
|
||||
Comment string `xml:"comment,attr,omitempty"`
|
||||
}
|
||||
|
||||
type NWFilterRuleSCTPIPv6 struct {
|
||||
Match string `xml:"match,attr,omitempty"`
|
||||
NWFilterRuleCommonIP
|
||||
NWFilterRuleCommonPort
|
||||
Comment string `xml:"comment,attr,omitempty"`
|
||||
}
|
||||
|
||||
type NWFilterRuleICMPIPv6 struct {
|
||||
Match string `xml:"match,attr,omitempty"`
|
||||
NWFilterRuleCommonIP
|
||||
Type NWFilterField `xml:"type,attr"`
|
||||
Code NWFilterField `xml:"code,attr"`
|
||||
Comment string `xml:"comment,attr,omitempty"`
|
||||
}
|
||||
|
||||
type NWFilterRuleAllIPv6 struct {
|
||||
Match string `xml:"match,attr,omitempty"`
|
||||
NWFilterRuleCommonIP
|
||||
Comment string `xml:"comment,attr,omitempty"`
|
||||
}
|
||||
|
||||
func (s *NWFilterField) MarshalXMLAttr(name xml.Name) (xml.Attr, error) {
|
||||
if s == nil {
|
||||
return xml.Attr{}, nil
|
||||
}
|
||||
if s.Str != "" {
|
||||
return xml.Attr{
|
||||
Name: name,
|
||||
Value: s.Str,
|
||||
}, nil
|
||||
} else if s.Var != "" {
|
||||
return xml.Attr{
|
||||
Name: name,
|
||||
Value: "$" + s.Str,
|
||||
}, nil
|
||||
} else if s.Uint != nil {
|
||||
return xml.Attr{
|
||||
Name: name,
|
||||
Value: fmt.Sprintf("0x%x", *s.Uint),
|
||||
}, nil
|
||||
} else {
|
||||
return xml.Attr{}, nil
|
||||
}
|
||||
}
|
||||
|
||||
func (s *NWFilterField) UnmarshalXMLAttr(attr xml.Attr) error {
|
||||
if attr.Value == "" {
|
||||
return nil
|
||||
}
|
||||
if attr.Value[0] == '$' {
|
||||
s.Var = attr.Value[1:]
|
||||
}
|
||||
if strings.HasPrefix(attr.Value, "0x") {
|
||||
val, err := strconv.ParseUint(attr.Value[2:], 16, 64)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
uval := uint(val)
|
||||
s.Uint = &uval
|
||||
}
|
||||
s.Str = attr.Value
|
||||
return nil
|
||||
}
|
||||
|
||||
func (a *NWFilter) MarshalXML(e *xml.Encoder, start xml.StartElement) error {
|
||||
start.Name.Local = "filter"
|
||||
start.Attr = append(start.Attr, xml.Attr{
|
||||
Name: xml.Name{Local: "name"},
|
||||
Value: a.Name,
|
||||
})
|
||||
if a.Chain != "" {
|
||||
start.Attr = append(start.Attr, xml.Attr{
|
||||
Name: xml.Name{Local: "chain"},
|
||||
Value: a.Chain,
|
||||
})
|
||||
}
|
||||
if a.Priority != 0 {
|
||||
start.Attr = append(start.Attr, xml.Attr{
|
||||
Name: xml.Name{Local: "priority"},
|
||||
Value: fmt.Sprintf("%d", a.Priority),
|
||||
})
|
||||
}
|
||||
err := e.EncodeToken(start)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if a.UUID != "" {
|
||||
uuid := xml.StartElement{
|
||||
Name: xml.Name{Local: "uuid"},
|
||||
}
|
||||
e.EncodeToken(uuid)
|
||||
e.EncodeToken(xml.CharData(a.UUID))
|
||||
e.EncodeToken(uuid.End())
|
||||
}
|
||||
|
||||
for _, entry := range a.Entries {
|
||||
if entry.Rule != nil {
|
||||
rule := xml.StartElement{
|
||||
Name: xml.Name{Local: "rule"},
|
||||
}
|
||||
e.EncodeElement(entry.Rule, rule)
|
||||
} else if entry.Ref != nil {
|
||||
ref := xml.StartElement{
|
||||
Name: xml.Name{Local: "filterref"},
|
||||
}
|
||||
e.EncodeElement(entry.Ref, ref)
|
||||
}
|
||||
}
|
||||
|
||||
err = e.EncodeToken(start.End())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (a *NWFilter) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error {
|
||||
name, ok := getAttr(start.Attr, "name")
|
||||
if !ok {
|
||||
return fmt.Errorf("Missing filter name")
|
||||
}
|
||||
a.Name = name
|
||||
a.Chain, _ = getAttr(start.Attr, "chain")
|
||||
prio, ok := getAttr(start.Attr, "priority")
|
||||
if ok {
|
||||
val, err := strconv.ParseInt(prio, 10, 64)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
a.Priority = int(val)
|
||||
}
|
||||
|
||||
for {
|
||||
tok, err := d.Token()
|
||||
if err == io.EOF {
|
||||
break
|
||||
}
|
||||
|
||||
switch tok := tok.(type) {
|
||||
case xml.StartElement:
|
||||
{
|
||||
if tok.Name.Local == "uuid" {
|
||||
txt, err := d.Token()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
txt2, ok := txt.(xml.CharData)
|
||||
if !ok {
|
||||
return fmt.Errorf("Expected UUID string")
|
||||
}
|
||||
a.UUID = string(txt2)
|
||||
} else if tok.Name.Local == "rule" {
|
||||
entry := NWFilterEntry{
|
||||
Rule: &NWFilterRule{},
|
||||
}
|
||||
|
||||
d.DecodeElement(entry.Rule, &tok)
|
||||
|
||||
a.Entries = append(a.Entries, entry)
|
||||
} else if tok.Name.Local == "filterref" {
|
||||
entry := NWFilterEntry{
|
||||
Ref: &NWFilterRef{},
|
||||
}
|
||||
|
||||
d.DecodeElement(entry.Ref, &tok)
|
||||
|
||||
a.Entries = append(a.Entries, entry)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *NWFilter) Unmarshal(doc string) error {
|
||||
return xml.Unmarshal([]byte(doc), s)
|
||||
}
|
||||
|
||||
func (s *NWFilter) Marshal() (string, error) {
|
||||
doc, err := xml.MarshalIndent(s, "", " ")
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
return string(doc), nil
|
||||
}
|
||||
58
vendor/github.com/libvirt/libvirt-go-xml/secret.go
generated
vendored
Normal file
58
vendor/github.com/libvirt/libvirt-go-xml/secret.go
generated
vendored
Normal file
@@ -0,0 +1,58 @@
|
||||
/*
|
||||
* 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) 2016 Red Hat, Inc.
|
||||
*
|
||||
*/
|
||||
|
||||
package libvirtxml
|
||||
|
||||
import (
|
||||
"encoding/xml"
|
||||
)
|
||||
|
||||
type SecretUsage struct {
|
||||
Type string `xml:"type,attr"`
|
||||
Volume string `xml:"volume,omitempty"`
|
||||
Name string `xml:"name,omitempty"`
|
||||
Target string `xml:"target,omitempty"`
|
||||
}
|
||||
|
||||
type Secret struct {
|
||||
XMLName xml.Name `xml:"secret"`
|
||||
Ephemeral string `xml:"ephemeral,attr,omitempty"`
|
||||
Private string `xml:"private,attr,omitempty"`
|
||||
Description string `xml:"description,omitempty"`
|
||||
UUID string `xml:"uuid,omitempty"`
|
||||
Usage *SecretUsage `xml:"usage"`
|
||||
}
|
||||
|
||||
func (s *Secret) Unmarshal(doc string) error {
|
||||
return xml.Unmarshal([]byte(doc), s)
|
||||
}
|
||||
|
||||
func (s *Secret) Marshal() (string, error) {
|
||||
doc, err := xml.MarshalIndent(s, "", " ")
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
return string(doc), nil
|
||||
}
|
||||
50
vendor/github.com/libvirt/libvirt-go-xml/storage_encryption.go
generated
vendored
Normal file
50
vendor/github.com/libvirt/libvirt-go-xml/storage_encryption.go
generated
vendored
Normal file
@@ -0,0 +1,50 @@
|
||||
/*
|
||||
* 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 StorageEncryptionSecret struct {
|
||||
Type string `xml:"type,attr"`
|
||||
UUID string `xml:"uuid,attr"`
|
||||
}
|
||||
|
||||
type StorageEncryptionCipher struct {
|
||||
Name string `xml:"name,attr"`
|
||||
Size uint64 `xml:"size,attr"`
|
||||
Mode string `xml:"mode,attr"`
|
||||
Hash string `xml:"hash,attr"`
|
||||
}
|
||||
|
||||
type StorageEncryptionIvgen struct {
|
||||
Name string `xml:"name,attr"`
|
||||
Hash string `xml:"hash,attr"`
|
||||
}
|
||||
|
||||
type StorageEncryption struct {
|
||||
Format string `xml:"format,attr"`
|
||||
Secret *StorageEncryptionSecret `xml:"secret"`
|
||||
Cipher *StorageEncryptionCipher `xml:"cipher"`
|
||||
Ivgen *StorageEncryptionIvgen `xml:"ivgen"`
|
||||
}
|
||||
234
vendor/github.com/libvirt/libvirt-go-xml/storage_pool.go
generated
vendored
Normal file
234
vendor/github.com/libvirt/libvirt-go-xml/storage_pool.go
generated
vendored
Normal file
@@ -0,0 +1,234 @@
|
||||
/*
|
||||
* 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 StoragePoolSize struct {
|
||||
Unit string `xml:"unit,attr,omitempty"`
|
||||
Value uint64 `xml:",chardata"`
|
||||
}
|
||||
|
||||
type StoragePoolTargetPermissions struct {
|
||||
Owner string `xml:"owner,omitempty"`
|
||||
Group string `xml:"group,omitempty"`
|
||||
Mode string `xml:"mode,omitempty"`
|
||||
Label string `xml:"label,omitempty"`
|
||||
}
|
||||
|
||||
type StoragePoolTargetTimestamps struct {
|
||||
Atime string `xml:"atime"`
|
||||
Mtime string `xml:"mtime"`
|
||||
Ctime string `xml:"ctime"`
|
||||
}
|
||||
|
||||
type StoragePoolTarget struct {
|
||||
Path string `xml:"path,omitempty"`
|
||||
Permissions *StoragePoolTargetPermissions `xml:"permissions"`
|
||||
Timestamps *StoragePoolTargetTimestamps `xml:"timestamps"`
|
||||
Encryption *StorageEncryption `xml:"encryption"`
|
||||
}
|
||||
|
||||
type StoragePoolSourceFormat struct {
|
||||
Type string `xml:"type,attr"`
|
||||
}
|
||||
|
||||
type StoragePoolSourceProtocol struct {
|
||||
Version string `xml:"ver,attr"`
|
||||
}
|
||||
|
||||
type StoragePoolSourceHost struct {
|
||||
Name string `xml:"name,attr"`
|
||||
Port string `xml:"port,attr,omitempty"`
|
||||
}
|
||||
|
||||
type StoragePoolSourceDevice struct {
|
||||
Path string `xml:"path,attr"`
|
||||
PartSeparator string `xml:"part_separator,attr,omitempty"`
|
||||
FreeExtents []StoragePoolSourceDeviceFreeExtent `xml:"freeExtent"`
|
||||
}
|
||||
|
||||
type StoragePoolSourceDeviceFreeExtent struct {
|
||||
Start uint64 `xml:"start,attr"`
|
||||
End uint64 `xml:"end,attr"`
|
||||
}
|
||||
|
||||
type StoragePoolSourceAuthSecret struct {
|
||||
Usage string `xml:"usage,attr,omitempty"`
|
||||
UUID string `xml:"uuid,attr,omitempty"`
|
||||
}
|
||||
|
||||
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 StoragePoolPCIAddress struct {
|
||||
Domain *uint `xml:"domain,attr"`
|
||||
Bus *uint `xml:"bus,attr"`
|
||||
Slot *uint `xml:"slot,attr"`
|
||||
Function *uint `xml:"function,attr"`
|
||||
}
|
||||
|
||||
type StoragePoolSourceAdapterParentAddr struct {
|
||||
UniqueID uint64 `xml:"unique_id,attr"`
|
||||
Address *StoragePoolPCIAddress `xml:"address"`
|
||||
}
|
||||
|
||||
type StoragePoolSourceAdapter struct {
|
||||
Type string `xml:"type,attr,omitempty"`
|
||||
Name string `xml:"name,attr,omitempty"`
|
||||
Parent string `xml:"parent,attr,omitempty"`
|
||||
Managed string `xml:"managed,attr,omitempty"`
|
||||
WWNN string `xml:"wwnn,attr,omitempty"`
|
||||
WWPN string `xml:"wwpn,attr,omitempty"`
|
||||
ParentAddr *StoragePoolSourceAdapterParentAddr `xml:"parentaddr"`
|
||||
}
|
||||
|
||||
type StoragePoolSourceDir struct {
|
||||
Path string `xml:"path,attr"`
|
||||
}
|
||||
|
||||
type StoragePoolSourceInitiator struct {
|
||||
IQN StoragePoolSourceInitiatorIQN `xml:"iqn"`
|
||||
}
|
||||
|
||||
type StoragePoolSourceInitiatorIQN struct {
|
||||
Name string `xml:"name,attr,omitempty"`
|
||||
}
|
||||
|
||||
type StoragePoolSource struct {
|
||||
Name string `xml:"name,omitempty"`
|
||||
Dir *StoragePoolSourceDir `xml:"dir"`
|
||||
Host []StoragePoolSourceHost `xml:"host"`
|
||||
Device []StoragePoolSourceDevice `xml:"device"`
|
||||
Auth *StoragePoolSourceAuth `xml:"auth"`
|
||||
Vendor *StoragePoolSourceVendor `xml:"vendor"`
|
||||
Product *StoragePoolSourceProduct `xml:"product"`
|
||||
Format *StoragePoolSourceFormat `xml:"format"`
|
||||
Protocol *StoragePoolSourceProtocol `xml:"protocol"`
|
||||
Adapter *StoragePoolSourceAdapter `xml:"adapter"`
|
||||
Initiator *StoragePoolSourceInitiator `xml:"initiator"`
|
||||
}
|
||||
|
||||
type StoragePoolRefreshVol struct {
|
||||
Allocation string `xml:"allocation,attr"`
|
||||
}
|
||||
|
||||
type StoragePoolRefresh struct {
|
||||
Volume StoragePoolRefreshVol `xml:"volume"`
|
||||
}
|
||||
|
||||
type StoragePool struct {
|
||||
XMLName xml.Name `xml:"pool"`
|
||||
Type string `xml:"type,attr"`
|
||||
Name string `xml:"name,omitempty"`
|
||||
UUID string `xml:"uuid,omitempty"`
|
||||
Allocation *StoragePoolSize `xml:"allocation"`
|
||||
Capacity *StoragePoolSize `xml:"capacity"`
|
||||
Available *StoragePoolSize `xml:"available"`
|
||||
Target *StoragePoolTarget `xml:"target"`
|
||||
Source *StoragePoolSource `xml:"source"`
|
||||
Refresh *StoragePoolRefresh `xml:"refresh"`
|
||||
|
||||
/* Pool backend namespcaes must be last */
|
||||
FSCommandline *StoragePoolFSCommandline
|
||||
RBDCommandline *StoragePoolRBDCommandline
|
||||
}
|
||||
|
||||
type StoragePoolFSCommandlineOption struct {
|
||||
Name string `xml:"name,attr"`
|
||||
}
|
||||
|
||||
type StoragePoolFSCommandline struct {
|
||||
XMLName xml.Name `xml:"http://libvirt.org/schemas/storagepool/fs/1.0 mount_opts"`
|
||||
Options []StoragePoolFSCommandlineOption `xml:"option"`
|
||||
}
|
||||
|
||||
type StoragePoolRBDCommandlineOption struct {
|
||||
Name string `xml:"name,attr"`
|
||||
Value string `xml:"value,attr"`
|
||||
}
|
||||
|
||||
type StoragePoolRBDCommandline struct {
|
||||
XMLName xml.Name `xml:"http://libvirt.org/schemas/storagepool/rbd/1.0 config_opts"`
|
||||
Options []StoragePoolRBDCommandlineOption `xml:"option"`
|
||||
}
|
||||
|
||||
func (a *StoragePoolPCIAddress) MarshalXML(e *xml.Encoder, start xml.StartElement) error {
|
||||
marshalUintAttr(&start, "domain", a.Domain, "0x%04x")
|
||||
marshalUintAttr(&start, "bus", a.Bus, "0x%02x")
|
||||
marshalUintAttr(&start, "slot", a.Slot, "0x%02x")
|
||||
marshalUintAttr(&start, "function", a.Function, "0x%x")
|
||||
e.EncodeToken(start)
|
||||
e.EncodeToken(start.End())
|
||||
return nil
|
||||
}
|
||||
|
||||
func (a *StoragePoolPCIAddress) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error {
|
||||
for _, attr := range start.Attr {
|
||||
if attr.Name.Local == "domain" {
|
||||
if err := unmarshalUintAttr(attr.Value, &a.Domain, 0); err != nil {
|
||||
return err
|
||||
}
|
||||
} else if attr.Name.Local == "bus" {
|
||||
if err := unmarshalUintAttr(attr.Value, &a.Bus, 0); err != nil {
|
||||
return err
|
||||
}
|
||||
} else if attr.Name.Local == "slot" {
|
||||
if err := unmarshalUintAttr(attr.Value, &a.Slot, 0); err != nil {
|
||||
return err
|
||||
}
|
||||
} else if attr.Name.Local == "function" {
|
||||
if err := unmarshalUintAttr(attr.Value, &a.Function, 0); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
}
|
||||
d.Skip()
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *StoragePool) Unmarshal(doc string) error {
|
||||
return xml.Unmarshal([]byte(doc), s)
|
||||
}
|
||||
|
||||
func (s *StoragePool) Marshal() (string, error) {
|
||||
doc, err := xml.MarshalIndent(s, "", " ")
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
return string(doc), nil
|
||||
}
|
||||
95
vendor/github.com/libvirt/libvirt-go-xml/storage_vol.go
generated
vendored
Normal file
95
vendor/github.com/libvirt/libvirt-go-xml/storage_vol.go
generated
vendored
Normal file
@@ -0,0 +1,95 @@
|
||||
/*
|
||||
* 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 StorageVolumeSize struct {
|
||||
Unit string `xml:"unit,attr,omitempty"`
|
||||
Value uint64 `xml:",chardata"`
|
||||
}
|
||||
|
||||
type StorageVolumeTargetPermissions struct {
|
||||
Owner string `xml:"owner,omitempty"`
|
||||
Group string `xml:"group,omitempty"`
|
||||
Mode string `xml:"mode,omitempty"`
|
||||
Label string `xml:"label,omitempty"`
|
||||
}
|
||||
|
||||
type StorageVolumeTargetFeature struct {
|
||||
LazyRefcounts *struct{} `xml:"lazy_refcounts"`
|
||||
}
|
||||
|
||||
type StorageVolumeTargetFormat struct {
|
||||
Type string `xml:"type,attr"`
|
||||
}
|
||||
|
||||
type StorageVolumeTargetTimestamps struct {
|
||||
Atime string `xml:"atime"`
|
||||
Mtime string `xml:"mtime"`
|
||||
Ctime string `xml:"ctime"`
|
||||
}
|
||||
|
||||
type StorageVolumeTarget struct {
|
||||
Path string `xml:"path,omitempty"`
|
||||
Format *StorageVolumeTargetFormat `xml:"format"`
|
||||
Permissions *StorageVolumeTargetPermissions `xml:"permissions"`
|
||||
Timestamps *StorageVolumeTargetTimestamps `xml:"timestamps"`
|
||||
Compat string `xml:"compat,omitempty"`
|
||||
NoCOW *struct{} `xml:"nocow"`
|
||||
Features []StorageVolumeTargetFeature `xml:"features"`
|
||||
Encryption *StorageEncryption `xml:"encryption"`
|
||||
}
|
||||
|
||||
type StorageVolumeBackingStore struct {
|
||||
Path string `xml:"path"`
|
||||
Format *StorageVolumeTargetFormat `xml:"format"`
|
||||
Permissions *StorageVolumeTargetPermissions `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 *StorageVolumeSize `xml:"allocation"`
|
||||
Capacity *StorageVolumeSize `xml:"capacity"`
|
||||
Physical *StorageVolumeSize `xml:"physical"`
|
||||
Target *StorageVolumeTarget `xml:"target"`
|
||||
BackingStore *StorageVolumeBackingStore `xml:"backingStore"`
|
||||
}
|
||||
|
||||
func (s *StorageVolume) Unmarshal(doc string) error {
|
||||
return xml.Unmarshal([]byte(doc), s)
|
||||
}
|
||||
|
||||
func (s *StorageVolume) Marshal() (string, error) {
|
||||
doc, err := xml.MarshalIndent(s, "", " ")
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
return string(doc), nil
|
||||
}
|
||||
291
vendor/github.com/libvirt/libvirt-go-xml/xmlutil.go
generated
vendored
Normal file
291
vendor/github.com/libvirt/libvirt-go-xml/xmlutil.go
generated
vendored
Normal file
@@ -0,0 +1,291 @@
|
||||
/*
|
||||
* 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"
|
||||
"fmt"
|
||||
"strconv"
|
||||
"strings"
|
||||
)
|
||||
|
||||
type element struct {
|
||||
XMLNS string
|
||||
Name string
|
||||
Attrs map[string]string
|
||||
Content string
|
||||
Children []*element
|
||||
}
|
||||
|
||||
type elementstack []*element
|
||||
|
||||
func (s *elementstack) push(v *element) {
|
||||
*s = append(*s, v)
|
||||
}
|
||||
|
||||
func (s *elementstack) pop() *element {
|
||||
res := (*s)[len(*s)-1]
|
||||
*s = (*s)[:len(*s)-1]
|
||||
return res
|
||||
}
|
||||
|
||||
func getNamespaceURI(xmlnsMap map[string]string, xmlns string, name xml.Name) string {
|
||||
if name.Space != "" {
|
||||
uri, ok := xmlnsMap[name.Space]
|
||||
if !ok {
|
||||
return "undefined://" + name.Space
|
||||
} else {
|
||||
return uri
|
||||
}
|
||||
} else {
|
||||
return xmlns
|
||||
}
|
||||
}
|
||||
|
||||
func xmlName(xmlns string, name xml.Name) string {
|
||||
if xmlns == "" {
|
||||
return name.Local
|
||||
}
|
||||
return name.Local + "(" + xmlns + ")"
|
||||
}
|
||||
|
||||
func loadXML(xmlstr string, ignoreNSDecl bool) (*element, error) {
|
||||
xmlnsMap := make(map[string]string)
|
||||
xmlr := strings.NewReader(xmlstr)
|
||||
|
||||
d := xml.NewDecoder(xmlr)
|
||||
var root *element
|
||||
stack := elementstack{}
|
||||
for {
|
||||
t, err := d.RawToken()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var parent *element
|
||||
if root != nil {
|
||||
if len(stack) == 0 {
|
||||
return nil, fmt.Errorf("Unexpectedly empty stack")
|
||||
}
|
||||
parent = stack[len(stack)-1]
|
||||
}
|
||||
|
||||
switch t := t.(type) {
|
||||
case xml.StartElement:
|
||||
xmlns := ""
|
||||
if parent != nil {
|
||||
xmlns = parent.XMLNS
|
||||
}
|
||||
for _, a := range t.Attr {
|
||||
if a.Name.Space == "xmlns" {
|
||||
xmlnsMap[a.Name.Local] = a.Value
|
||||
} else if a.Name.Space == "" && a.Name.Local == "xmlns" {
|
||||
xmlns = a.Value
|
||||
}
|
||||
}
|
||||
xmlns = getNamespaceURI(xmlnsMap, xmlns, t.Name)
|
||||
child := &element{
|
||||
XMLNS: xmlns,
|
||||
Name: xmlName(xmlns, t.Name),
|
||||
Attrs: make(map[string]string),
|
||||
}
|
||||
|
||||
for _, a := range t.Attr {
|
||||
if a.Name.Space == "xmlns" {
|
||||
continue
|
||||
}
|
||||
if a.Name.Space == "" && a.Name.Local == "xmlns" {
|
||||
continue
|
||||
}
|
||||
attrNS := getNamespaceURI(xmlnsMap, "", a.Name)
|
||||
child.Attrs[xmlName(attrNS, a.Name)] = a.Value
|
||||
}
|
||||
stack.push(child)
|
||||
if root == nil {
|
||||
root = child
|
||||
} else {
|
||||
parent.Children = append(parent.Children, child)
|
||||
parent.Content = ""
|
||||
}
|
||||
case xml.EndElement:
|
||||
stack.pop()
|
||||
case xml.CharData:
|
||||
if parent != nil && len(parent.Children) == 0 {
|
||||
val := string(t)
|
||||
if strings.TrimSpace(val) != "" {
|
||||
parent.Content = val
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if root != nil && len(stack) == 0 {
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
return root, nil
|
||||
}
|
||||
|
||||
func testCompareValue(filename, path, key, expected, actual string) error {
|
||||
if expected == actual {
|
||||
return nil
|
||||
}
|
||||
|
||||
i1, err1 := strconv.ParseInt(expected, 0, 64)
|
||||
i2, err2 := strconv.ParseInt(actual, 0, 64)
|
||||
if err1 == nil && err2 == nil && i1 == i2 {
|
||||
return nil
|
||||
}
|
||||
path = path + "/@" + key
|
||||
return fmt.Errorf("%s: %s: attribute actual value '%s' does not match expected value '%s'",
|
||||
filename, path, actual, expected)
|
||||
}
|
||||
|
||||
func testCompareElement(filename, expectPath, actualPath string, expect, actual *element, extraExpectNodes, extraActualNodes map[string]bool) error {
|
||||
if expect.Name != actual.Name {
|
||||
return fmt.Errorf("%s: name '%s' doesn't match '%s'",
|
||||
expectPath, expect.Name, actual.Name)
|
||||
}
|
||||
|
||||
expectAttr := expect.Attrs
|
||||
for key, val := range actual.Attrs {
|
||||
expectval, ok := expectAttr[key]
|
||||
if !ok {
|
||||
attrPath := actualPath + "/@" + key
|
||||
if _, ok := extraActualNodes[attrPath]; ok {
|
||||
continue
|
||||
}
|
||||
return fmt.Errorf("%s: %s: attribute in actual XML missing in expected XML",
|
||||
filename, attrPath)
|
||||
}
|
||||
err := testCompareValue(filename, actualPath, key, expectval, val)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
delete(expectAttr, key)
|
||||
}
|
||||
for key, _ := range expectAttr {
|
||||
attrPath := expectPath + "/@" + key
|
||||
if _, ok := extraExpectNodes[attrPath]; ok {
|
||||
continue
|
||||
}
|
||||
return fmt.Errorf("%s: %s: attribute '%s' in expected XML missing in actual XML",
|
||||
filename, attrPath, expectAttr[key])
|
||||
}
|
||||
|
||||
if expect.Content != actual.Content {
|
||||
return fmt.Errorf("%s: %s: actual content '%s' does not match expected '%s'",
|
||||
filename, actualPath, actual.Content, expect.Content)
|
||||
}
|
||||
|
||||
used := make([]bool, len(actual.Children))
|
||||
expectChildIndexes := make(map[string]uint)
|
||||
actualChildIndexes := make(map[string]uint)
|
||||
for _, expectChild := range expect.Children {
|
||||
expectIndex, _ := expectChildIndexes[expectChild.Name]
|
||||
expectChildIndexes[expectChild.Name] = expectIndex + 1
|
||||
subExpectPath := fmt.Sprintf("%s/%s[%d]", expectPath, expectChild.Name, expectIndex)
|
||||
|
||||
var actualChild *element = nil
|
||||
for i := 0; i < len(used); i++ {
|
||||
if !used[i] && actual.Children[i].Name == expectChild.Name {
|
||||
actualChild = actual.Children[i]
|
||||
used[i] = true
|
||||
break
|
||||
}
|
||||
}
|
||||
if actualChild == nil {
|
||||
if _, ok := extraExpectNodes[subExpectPath]; ok {
|
||||
continue
|
||||
}
|
||||
return fmt.Errorf("%s: %s: element in expected XML missing in actual XML",
|
||||
filename, subExpectPath)
|
||||
}
|
||||
|
||||
actualIndex, _ := actualChildIndexes[actualChild.Name]
|
||||
actualChildIndexes[actualChild.Name] = actualIndex + 1
|
||||
subActualPath := fmt.Sprintf("%s/%s[%d]", actualPath, actualChild.Name, actualIndex)
|
||||
|
||||
err := testCompareElement(filename, subExpectPath, subActualPath, expectChild, actualChild, extraExpectNodes, extraActualNodes)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
actualChildIndexes = make(map[string]uint)
|
||||
for i, actualChild := range actual.Children {
|
||||
actualIndex, _ := actualChildIndexes[actualChild.Name]
|
||||
actualChildIndexes[actualChild.Name] = actualIndex + 1
|
||||
if used[i] {
|
||||
continue
|
||||
}
|
||||
subActualPath := fmt.Sprintf("%s/%s[%d]", actualPath, actualChild.Name, actualIndex)
|
||||
|
||||
if _, ok := extraActualNodes[subActualPath]; ok {
|
||||
continue
|
||||
}
|
||||
return fmt.Errorf("%s: %s: element in actual XML missing in expected XML",
|
||||
filename, subActualPath)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func makeExtraNodeMap(nodes []string) map[string]bool {
|
||||
ret := make(map[string]bool)
|
||||
for _, node := range nodes {
|
||||
ret[node] = true
|
||||
}
|
||||
return ret
|
||||
}
|
||||
|
||||
func testCompareXML(filename, expectStr, actualStr string, extraExpectNodes, extraActualNodes []string) error {
|
||||
extraExpectNodeMap := makeExtraNodeMap(extraExpectNodes)
|
||||
extraActualNodeMap := makeExtraNodeMap(extraActualNodes)
|
||||
|
||||
//fmt.Printf("%s\n", expectedstr)
|
||||
expectRoot, err := loadXML(expectStr, true)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
//fmt.Printf("%s\n", actualstr)
|
||||
actualRoot, err := loadXML(actualStr, true)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if expectRoot.Name != actualRoot.Name {
|
||||
return fmt.Errorf("%s: /: expected root element '%s' does not match actual '%s'",
|
||||
filename, expectRoot.Name, actualRoot.Name)
|
||||
}
|
||||
|
||||
err = testCompareElement(filename, "/"+expectRoot.Name+"[0]", "/"+actualRoot.Name+"[0]", expectRoot, actualRoot, extraExpectNodeMap, extraActualNodeMap)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
Reference in New Issue
Block a user