Migrate all libvirt calls to the generated code.
- Update libvirt.go so that all libvirt calls now go through the generated routines. - Remove some libvirt routines that had the same name as generated ones, leave the rest as convenience routines. - Fix the handling of Optional-values (the declarations of which in the .x file look like pointers)
This commit is contained in:
		| @@ -25,6 +25,10 @@ import ( | ||||
| 	"unicode/utf8" | ||||
| ) | ||||
|  | ||||
| // If you're making changes to the generator, or troubleshooting the generated | ||||
| // code, the docs for sunrpc and xdr (the line encoding) are helpful: | ||||
| // https://docs.oracle.com/cd/E26502_01/html/E35597/ | ||||
|  | ||||
| // ConstItem stores an const's symbol and value from the parser. This struct is | ||||
| // also used for enums. | ||||
| type ConstItem struct { | ||||
| @@ -81,7 +85,6 @@ var goEquivTypes = map[string]string{ | ||||
| 	// TODO: Get rid of these. They're only needed because we lose information | ||||
| 	// that the parser has (the parser knows it has emitted a go type), and then | ||||
| 	// we capitalize types to make them public. | ||||
| 	"String":  "string", | ||||
| 	"Int":     "int", | ||||
| 	"Uint":    "uint", | ||||
| 	"Int8":    "int8", | ||||
| @@ -580,7 +583,7 @@ func checkIdentifier(i string) string { | ||||
| } | ||||
|  | ||||
| // GetUnion returns the type information for a union. If the provided type name | ||||
| // isn't a union, the second return value will be false. | ||||
| // isn't a union, this will return a zero-value Union type. | ||||
| func (decl *Decl) GetUnion() Union { | ||||
| 	ix, ok := Gen.UnionMap[decl.Type] | ||||
| 	if ok { | ||||
|   | ||||
| @@ -42,8 +42,10 @@ type {{$casetype}} struct { | ||||
| 	DVal uint32 | ||||
| 	{{.Name}} {{.Type}} | ||||
| } | ||||
| func New{{$casetype}}(v {{.Type}}) *{{$casetype}} { return &{{$casetype}}{DVal: {{.DiscriminantVal}}, {{.Name}}: v} } | ||||
| func Decode{{$casetype}}(dec *xdr.Decoder) (*{{$casetype}}, error) { | ||||
| func New{{$casetype}}(v {{.Type}}) *{{$casetype}} { | ||||
| 	return &{{$casetype}}{DVal: {{.DiscriminantVal}}, {{.Name}}: v} | ||||
| } | ||||
| func decode{{$casetype}}(dec *xdr.Decoder) (*{{$casetype}}, error) { | ||||
| 	var v {{.Type}} | ||||
| 	_, err := dec.Decode(&v) | ||||
| 	if err != nil { | ||||
| @@ -53,49 +55,46 @@ func Decode{{$casetype}}(dec *xdr.Decoder) (*{{$casetype}}, error) { | ||||
| } | ||||
| func (c *{{$casetype}}) Get() interface{} { return c.{{.Name}} } | ||||
| {{end}} | ||||
| {{- end}} | ||||
|  | ||||
| // TODO: Generate this. | ||||
| func decodeTypedParams(dec *xdr.Decoder) ([]TypedParam, error) { | ||||
| 	count, _, err := dec.DecodeInt() | ||||
| 	params := make([]TypedParam, count) | ||||
| func decode{{.Name}}(dec *xdr.Decoder) ({{.Name}}, error) { | ||||
| 	discriminant, _, err := dec.DecodeInt() | ||||
| 	if err != nil { | ||||
| 		return nil, err | ||||
| 	} | ||||
| 	var caseval {{.Name}} | ||||
| 	switch discriminant { | ||||
| {{range .Cases}}{{$casetype := printf "%v%v" $uname .CaseName}}	case {{.DiscriminantVal}}: | ||||
| 		caseval, err = decode{{$casetype}}(dec) | ||||
| {{end}} | ||||
| 	default: | ||||
| 		err = fmt.Errorf("invalid parameter type %v", discriminant) | ||||
| 	} | ||||
|  | ||||
| 	return caseval, err | ||||
| } | ||||
| {{- end}} | ||||
|  | ||||
| // TODO: Generate these. | ||||
| func decodeTypedParam(dec *xdr.Decoder) (*TypedParam, error) { | ||||
| 	name, _, err := dec.DecodeString() | ||||
| 	if err != nil { | ||||
| 		return nil, err | ||||
| 	} | ||||
| 	val, err := decodeTypedParamValue(dec) | ||||
| 	return &TypedParam{name, val}, nil | ||||
| } | ||||
|  | ||||
| func decodeTypedParams(dec *xdr.Decoder) ([]TypedParam, error) { | ||||
| 	count, _, err := dec.DecodeInt() | ||||
| 	if err != nil { | ||||
| 		return nil, err | ||||
| 	} | ||||
| 	params := make([]TypedParam, count) | ||||
| 	for ix := int32(0); ix < count; ix++ { | ||||
| 		name, _, err := dec.DecodeString() | ||||
| 		p, err := decodeTypedParam(dec) | ||||
| 		if err != nil { | ||||
| 			return nil, err | ||||
| 		} | ||||
| 		ptype, _, err := dec.DecodeInt() | ||||
| 		if err != nil { | ||||
| 			return nil, err | ||||
| 		} | ||||
| 		var tpv TypedParamValue | ||||
| 		switch ptype { | ||||
| 		case 1:	// TypedParamValueInt | ||||
| 			tpv, err = DecodeTypedParamValueInt(dec) | ||||
| 		case 2: // TypedParamValueUint | ||||
| 			tpv, err = DecodeTypedParamValueUint(dec) | ||||
| 		case 3: // TypedParamValueLlong | ||||
| 			tpv, err = DecodeTypedParamValueLlong(dec) | ||||
| 		case 4: // TypedParamValueUllong | ||||
| 			tpv, err = DecodeTypedParamValueUllong(dec) | ||||
| 		case 5: // TypedParamValueDouble | ||||
| 			tpv, err = DecodeTypedParamValueDouble(dec) | ||||
| 		case 6: // TypedParamValueBoolean | ||||
| 			tpv, err = DecodeTypedParamValueBoolean(dec) | ||||
| 		case 7: // TypedParamValueString | ||||
| 			tpv, err = DecodeTypedParamValueString(dec) | ||||
| 		default: | ||||
| 			err = fmt.Errorf("invalid parameter type %v", ptype) | ||||
| 		} | ||||
|  | ||||
| 		if err != nil { | ||||
| 			return nil, err | ||||
| 		} | ||||
|  | ||||
| 		params[ix] = TypedParam{name, tpv} | ||||
| 		params[ix] = *p | ||||
| 	} | ||||
|  | ||||
| 	return params, nil | ||||
| @@ -131,17 +130,16 @@ func (l *Libvirt) {{.Name}}({{range $ix, $arg := .Args}}{{if $ix}}, {{end}}{{.Na | ||||
| 	rdr := bytes.NewReader(r.Payload) | ||||
| 	dec := xdr.NewDecoder(rdr) | ||||
| {{range .Ret}}	// {{.Name}}: {{.Type}} | ||||
| {{if eq .Type "[]TypedParam"}}	// {{.Name}} | ||||
| 	r{{.Name}}, err = decodeTypedParams(dec) | ||||
| {{if eq .Type "[]TypedParam"}}	r{{.Name}}, err = decodeTypedParams(dec) | ||||
| 	if err != nil { | ||||
| 		fmt.Println("error decoding typedparams") | ||||
| 		return | ||||
| 	} | ||||
| {{else}}	_, err = dec.Decode(&r{{.Name}}) | ||||
| 	if err != nil { | ||||
| 		return | ||||
| 	} | ||||
| {{end}}{{end}} | ||||
| {{end}} | ||||
| {{end}}{{end}}{{end}} | ||||
| 	return | ||||
| } | ||||
| {{end}} | ||||
|   | ||||
| @@ -146,8 +146,12 @@ variable_array_declaration | ||||
|     | type_specifier variable_ident '<' '>'         { AddVariableArray($2.val, $1.val, "") } | ||||
|     ; | ||||
|  | ||||
| // while pointer_declarations may look like their familiar c-equivalents, in the | ||||
| // XDR language they actually declare "Optional-data". The simplest | ||||
| // representation to use for these is a variable-length array with a size of 1. | ||||
| // See the XDR spec for a more complete explanation of this. | ||||
| pointer_declaration | ||||
|     : type_specifier '*' variable_ident             { AddDeclaration($3.val, "*"+$1.val) } | ||||
|     : type_specifier '*' variable_ident             { AddVariableArray($3.val, $1.val, "1") } | ||||
|     ; | ||||
|  | ||||
| struct_definition | ||||
|   | ||||
							
								
								
									
										586
									
								
								libvirt.gen.go
									
									
									
									
									
								
							
							
						
						
									
										586
									
								
								libvirt.gen.go
									
									
									
									
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										707
									
								
								libvirt.go
									
									
									
									
									
								
							
							
						
						
									
										707
									
								
								libvirt.go
									
									
									
									
									
								
							| @@ -52,17 +52,10 @@ type Libvirt struct { | ||||
| 	s uint32 | ||||
| } | ||||
|  | ||||
| // Domain represents a domain as seen by libvirt. | ||||
| // type Domain struct { | ||||
| // 	Name string | ||||
| // 	UUID [constants.UUIDSize]byte | ||||
| // 	ID   int | ||||
| // } | ||||
|  | ||||
| // DomainEvent represents a libvirt domain event. | ||||
| type DomainEvent struct { | ||||
| 	CallbackID   uint32 | ||||
| 	Domain       Domain | ||||
| 	Domain       NonnullDomain | ||||
| 	Event        string | ||||
| 	Seconds      uint64 | ||||
| 	Microseconds uint32 | ||||
| @@ -70,19 +63,6 @@ type DomainEvent struct { | ||||
| 	Details      []byte | ||||
| } | ||||
|  | ||||
| // Secret represents a secret managed by the libvirt daemon. | ||||
| // type Secret struct { | ||||
| // 	UUID      [constants.UUIDSize]byte | ||||
| // 	UsageType SecretUsageType | ||||
| // 	UsageID   string | ||||
| // } | ||||
|  | ||||
| // StoragePool represents a storage pool as seen by libvirt. | ||||
| // type StoragePool struct { | ||||
| // 	Name string | ||||
| // 	UUID [constants.UUIDSize]byte | ||||
| // } | ||||
|  | ||||
| // qemuError represents a QEMU process error. | ||||
| type qemuError struct { | ||||
| 	Error struct { | ||||
| @@ -137,46 +117,6 @@ const ( | ||||
| 	TypeParamLast | ||||
| ) | ||||
|  | ||||
| // TypedParam represents libvirt's virTypedParameter, which is used to pass | ||||
| // typed parameters to libvirt functions. This is defined as an interface, and | ||||
| // implemented by TypedParam... concrete types. | ||||
| // type TypedParam interface { | ||||
| // 	Field() string | ||||
| // 	Value() interface{} | ||||
| // } | ||||
|  | ||||
| // TypedParamInt contains a 32-bit signed integer. | ||||
| // type TypedParamInt struct { | ||||
| // 	Fld     string | ||||
| // 	PType   int32 | ||||
| // 	Padding [4]byte | ||||
| // 	Val     int32 | ||||
| // } | ||||
|  | ||||
| // Field returns the field name, a string name for the parameter. | ||||
| // func (tp *TypedParamInt) Field() string { | ||||
| // 	return tp.Fld | ||||
| // } | ||||
|  | ||||
| // Value returns the value for the typed parameter, as an empty interface. | ||||
| // func (tp *TypedParamInt) Value() interface{} { | ||||
| // 	return tp.Val | ||||
| // } | ||||
|  | ||||
| // NewTypedParamInt returns a TypedParam encoding for an int. | ||||
| // func NewTypedParamInt(name string, v int32) *TypedParamInt { | ||||
| // 	// Truncate the field name if it's longer than the limit. | ||||
| // 	if len(name) > constants.TypedParamFieldLength { | ||||
| // 		name = name[:constants.TypedParamFieldLength] | ||||
| // 	} | ||||
| // 	tp := TypedParamInt{ | ||||
| // 		Fld:   name, | ||||
| // 		PType: TypeParamInt, | ||||
| // 		Val:   v, | ||||
| // 	} | ||||
| // 	return &tp | ||||
| // } | ||||
|  | ||||
| // TypedParamULongLong contains a 64-bit unsigned integer. | ||||
| type TypedParamULongLong struct { | ||||
| 	Fld   string | ||||
| @@ -506,27 +446,9 @@ const ( | ||||
| 	DomainMemoryStatTagNr | ||||
| ) | ||||
|  | ||||
| // DomainMemoryStat specifies memory stats of the domain | ||||
| // type DomainMemoryStat struct { | ||||
| // 	Tag DomainMemoryStatTag | ||||
| // 	Val uint64 | ||||
| // } | ||||
|  | ||||
| // Capabilities returns an XML document describing the host's capabilties. | ||||
| func (l *Libvirt) Capabilities() ([]byte, error) { | ||||
| 	resp, err := l.request(constants.ProcConnectGetCapabilities, constants.Program, nil) | ||||
| 	if err != nil { | ||||
| 		return nil, err | ||||
| 	} | ||||
|  | ||||
| 	r := <-resp | ||||
| 	if r.Status != StatusOK { | ||||
| 		return nil, decodeError(r.Payload) | ||||
| 	} | ||||
|  | ||||
| 	dec := xdr.NewDecoder(bytes.NewReader(r.Payload)) | ||||
| 	caps, _, err := dec.DecodeString() | ||||
|  | ||||
| 	caps, err := l.ConnectGetCapabilities() | ||||
| 	return []byte(caps), err | ||||
| } | ||||
|  | ||||
| @@ -555,118 +477,13 @@ func (l *Libvirt) Disconnect() error { | ||||
| } | ||||
|  | ||||
| // Domains returns a list of all domains managed by libvirt. | ||||
| func (l *Libvirt) Domains() ([]Domain, error) { | ||||
| func (l *Libvirt) Domains() ([]NonnullDomain, error) { | ||||
| 	// these are the flags as passed by `virsh`, defined in: | ||||
| 	// src/remote/remote_protocol.x # remote_connect_list_all_domains_args | ||||
| 	req := struct { | ||||
| 		NeedResults uint32 | ||||
| 		Flags       uint32 | ||||
| 	}{ | ||||
| 		NeedResults: 1, | ||||
| 		Flags:       3, | ||||
| 	} | ||||
|  | ||||
| 	buf, err := encode(&req) | ||||
| 	if err != nil { | ||||
| 		return nil, err | ||||
| 	} | ||||
|  | ||||
| 	resp, err := l.request(constants.ProcConnectListAllDomains, constants.Program, &buf) | ||||
| 	if err != nil { | ||||
| 		return nil, err | ||||
| 	} | ||||
|  | ||||
| 	r := <-resp | ||||
| 	if r.Status != StatusOK { | ||||
| 		return nil, decodeError(r.Payload) | ||||
| 	} | ||||
|  | ||||
| 	result := struct { | ||||
| 		Domains []Domain | ||||
| 		Count   uint32 | ||||
| 	}{} | ||||
|  | ||||
| 	dec := xdr.NewDecoder(bytes.NewReader(r.Payload)) | ||||
| 	_, err = dec.Decode(&result) | ||||
| 	if err != nil { | ||||
| 		return nil, err | ||||
| 	} | ||||
|  | ||||
| 	return result.Domains, nil | ||||
| 	domains, _, err := l.ConnectListAllDomains(1, 3) | ||||
| 	return domains, err | ||||
| } | ||||
|  | ||||
| // DomainCreateWithFlags starts specified domain with flags | ||||
| // func (l *Libvirt) DomainCreateWithFlags(dom string, flags DomainCreateFlags) error { | ||||
| // 	d, err := l.lookup(dom) | ||||
| // 	if err != nil { | ||||
| // 		return err | ||||
| // 	} | ||||
| // 	req := struct { | ||||
| // 		Domain Domain | ||||
| // 		Flags  DomainCreateFlags | ||||
| // 	}{ | ||||
| // 		Domain: *d, | ||||
| // 		Flags:  flags, | ||||
| // 	} | ||||
| // | ||||
| // 	buf, err := encode(&req) | ||||
| // 	if err != nil { | ||||
| // 		return err | ||||
| // 	} | ||||
| // 	resp, err := l.request(constants.ProcDomainCreateWithFlags, constants.Program, &buf) | ||||
| // 	if err != nil { | ||||
| // 		return err | ||||
| // 	} | ||||
| // 	r := <-resp | ||||
| // 	if r.Status != StatusOK { | ||||
| // 		return decodeError(r.Payload) | ||||
| // 	} | ||||
| // 	return nil | ||||
| // } | ||||
|  | ||||
| // DomainMemoryStats returns memory stats of the domain managed by libvirt. | ||||
| // func (l *Libvirt) DomainMemoryStats(dom string) ([]DomainMemoryStat, error) { | ||||
| // | ||||
| // 	d, err := l.lookup(dom) | ||||
| // 	if err != nil { | ||||
| // 		return nil, err | ||||
| // 	} | ||||
| // | ||||
| // 	req := struct { | ||||
| // 		Domain   Domain | ||||
| // 		MaxStats uint32 | ||||
| // 		Flags    uint32 | ||||
| // 	}{ | ||||
| // 		Domain:   *d, | ||||
| // 		MaxStats: 8, | ||||
| // 		Flags:    0, | ||||
| // 	} | ||||
| // | ||||
| // 	buf, err := encode(&req) | ||||
| // 	if err != nil { | ||||
| // 		return nil, err | ||||
| // 	} | ||||
| // | ||||
| // 	resp, err := l.request(constants.ProcDomainMemoryStats, constants.Program, &buf) | ||||
| // 	if err != nil { | ||||
| // 		return nil, err | ||||
| // 	} | ||||
| // | ||||
| // 	r := <-resp | ||||
| // | ||||
| // 	result := struct { | ||||
| // 		DomainMemoryStats []DomainMemoryStat | ||||
| // 	}{} | ||||
| // | ||||
| // 	dec := xdr.NewDecoder(bytes.NewReader(r.Payload)) | ||||
| // 	_, err = dec.Decode(&result) | ||||
| // 	if err != nil { | ||||
| // 		return nil, err | ||||
| // 	} | ||||
| // | ||||
| // 	return result.DomainMemoryStats, nil | ||||
| // } | ||||
|  | ||||
| // DomainState returns state of the domain managed by libvirt. | ||||
| func (l *Libvirt) DomainState(dom string) (DomainState, error) { | ||||
| 	d, err := l.lookup(dom) | ||||
| @@ -674,41 +491,8 @@ func (l *Libvirt) DomainState(dom string) (DomainState, error) { | ||||
| 		return DomainStateNoState, err | ||||
| 	} | ||||
|  | ||||
| 	req := struct { | ||||
| 		Domain Domain | ||||
| 		Flags  uint32 | ||||
| 	}{ | ||||
| 		Domain: d, | ||||
| 		Flags:  0, | ||||
| 	} | ||||
|  | ||||
| 	buf, err := encode(&req) | ||||
| 	if err != nil { | ||||
| 		return DomainStateNoState, err | ||||
| 	} | ||||
|  | ||||
| 	resp, err := l.request(constants.ProcDomainGetState, constants.Program, &buf) | ||||
| 	if err != nil { | ||||
| 		return DomainStateNoState, err | ||||
| 	} | ||||
|  | ||||
| 	r := <-resp | ||||
| 	if r.Status != StatusOK { | ||||
| 		return DomainStateNoState, decodeError(r.Payload) | ||||
| 	} | ||||
|  | ||||
| 	result := struct { | ||||
| 		State  uint32 | ||||
| 		Reason uint32 | ||||
| 	}{} | ||||
|  | ||||
| 	dec := xdr.NewDecoder(bytes.NewReader(r.Payload)) | ||||
| 	_, err = dec.Decode(&result) | ||||
| 	if err != nil { | ||||
| 		return DomainStateNoState, err | ||||
| 	} | ||||
|  | ||||
| 	return DomainState(result.State), nil | ||||
| 	state, _, err := l.DomainGetState(d, 0) | ||||
| 	return DomainState(state), err | ||||
| } | ||||
|  | ||||
| // Events streams domain events. | ||||
| @@ -723,7 +507,7 @@ func (l *Libvirt) Events(dom string) (<-chan DomainEvent, error) { | ||||
|  | ||||
| 	payload := struct { | ||||
| 		Padding [4]byte | ||||
| 		Domain  Domain | ||||
| 		Domain  NonnullDomain | ||||
| 		Event   [2]byte | ||||
| 		Flags   [2]byte | ||||
| 	}{ | ||||
| @@ -793,39 +577,11 @@ func (l *Libvirt) Migrate(dom string, dest string, flags MigrateFlags) error { | ||||
| 	// and CookieIn. In testing both values are always set to 0 by virsh | ||||
| 	// and the source does not provide clear definitions of their purpose. | ||||
| 	// For now, using the same zero'd values as done by virsh will be Good Enough. | ||||
| 	payload := struct { | ||||
| 		Domain           Domain | ||||
| 		Padding          [4]byte | ||||
| 		DestinationURI   string | ||||
| 		RemoteParameters uint32 | ||||
| 		CookieIn         uint32 | ||||
| 		Flags            MigrateFlags | ||||
| 	}{ | ||||
| 		Domain:           d, | ||||
| 		Padding:          [4]byte{0x0, 0x0, 0x0, 0x1}, | ||||
| 		DestinationURI:   dest, | ||||
| 		RemoteParameters: 0, | ||||
| 		CookieIn:         0, | ||||
| 		Flags:            flags, | ||||
| 	} | ||||
|  | ||||
| 	buf, err := encode(&payload) | ||||
| 	if err != nil { | ||||
| 		return err | ||||
| 	} | ||||
|  | ||||
| 	resp, err := l.request(constants.ProcDomainMigratePerform3Params, | ||||
| 		constants.Program, &buf) | ||||
| 	if err != nil { | ||||
| 		return err | ||||
| 	} | ||||
|  | ||||
| 	r := <-resp | ||||
| 	if r.Status != StatusOK { | ||||
| 		return decodeError(r.Payload) | ||||
| 	} | ||||
|  | ||||
| 	return nil | ||||
| 	destURI := []string{dest} | ||||
| 	remoteParams := []TypedParam{} | ||||
| 	cookieIn := []byte{} | ||||
| 	_, err = l.DomainMigratePerform3Params(d, destURI, remoteParams, cookieIn, uint32(flags)) | ||||
| 	return err | ||||
| } | ||||
|  | ||||
| // MigrateSetMaxSpeed set the maximum migration bandwidth (in MiB/s) for a | ||||
| @@ -837,33 +593,7 @@ func (l *Libvirt) MigrateSetMaxSpeed(dom string, speed int64) error { | ||||
| 		return err | ||||
| 	} | ||||
|  | ||||
| 	payload := struct { | ||||
| 		Padding   [4]byte | ||||
| 		Domain    Domain | ||||
| 		Bandwidth int64 | ||||
| 		Flags     uint32 | ||||
| 	}{ | ||||
| 		Padding:   [4]byte{0x0, 0x0, 0x1, 0x0}, | ||||
| 		Domain:    d, | ||||
| 		Bandwidth: speed, | ||||
| 	} | ||||
|  | ||||
| 	buf, err := encode(&payload) | ||||
| 	if err != nil { | ||||
| 		return err | ||||
| 	} | ||||
|  | ||||
| 	resp, err := l.request(constants.ProcDomainMigrateSetMaxSpeed, constants.Program, &buf) | ||||
| 	if err != nil { | ||||
| 		return err | ||||
| 	} | ||||
|  | ||||
| 	r := <-resp | ||||
| 	if r.Status != StatusOK { | ||||
| 		return decodeError(r.Payload) | ||||
| 	} | ||||
|  | ||||
| 	return nil | ||||
| 	return l.DomainMigrateSetMaxSpeed(d, uint64(speed), 0) | ||||
| } | ||||
|  | ||||
| // Run executes the given QAPI command against a domain's QEMU instance. | ||||
| @@ -876,7 +606,7 @@ func (l *Libvirt) Run(dom string, cmd []byte) ([]byte, error) { | ||||
| 	} | ||||
|  | ||||
| 	payload := struct { | ||||
| 		Domain  Domain | ||||
| 		Domain  NonnullDomain | ||||
| 		Command []byte | ||||
| 		Flags   uint32 | ||||
| 	}{ | ||||
| @@ -919,7 +649,7 @@ func (l *Libvirt) Run(dom string, cmd []byte) ([]byte, error) { | ||||
| } | ||||
|  | ||||
| // Secrets returns all secrets managed by the libvirt daemon. | ||||
| func (l *Libvirt) Secrets() ([]Secret, error) { | ||||
| func (l *Libvirt) Secrets() ([]NonnullSecret, error) { | ||||
| 	req := struct { | ||||
| 		NeedResults uint32 | ||||
| 		Flags       uint32 | ||||
| @@ -944,7 +674,7 @@ func (l *Libvirt) Secrets() ([]Secret, error) { | ||||
| 	} | ||||
|  | ||||
| 	result := struct { | ||||
| 		Secrets []Secret | ||||
| 		Secrets []NonnullSecret | ||||
| 		Count   uint32 | ||||
| 	}{} | ||||
|  | ||||
| @@ -959,112 +689,15 @@ func (l *Libvirt) Secrets() ([]Secret, error) { | ||||
|  | ||||
| // StoragePool returns the storage pool associated with the provided name. | ||||
| // An error is returned if the requested storage pool is not found. | ||||
| func (l *Libvirt) StoragePool(name string) (StoragePool, error) { | ||||
| 	req := struct { | ||||
| 		Name string | ||||
| 	}{ | ||||
| 		Name: name, | ||||
| 	} | ||||
|  | ||||
| 	buf, err := encode(&req) | ||||
| 	if err != nil { | ||||
| 		return nil, err | ||||
| 	} | ||||
|  | ||||
| 	resp, err := l.request(constants.ProcStoragePoolLookupByName, constants.Program, &buf) | ||||
| 	if err != nil { | ||||
| 		return nil, err | ||||
| 	} | ||||
|  | ||||
| 	r := <-resp | ||||
| 	if r.Status != StatusOK { | ||||
| 		return nil, decodeError(r.Payload) | ||||
| 	} | ||||
|  | ||||
| 	result := struct { | ||||
| 		Pool StoragePool | ||||
| 	}{} | ||||
|  | ||||
| 	dec := xdr.NewDecoder(bytes.NewReader(r.Payload)) | ||||
| 	_, err = dec.Decode(&result) | ||||
| 	if err != nil { | ||||
| 		return nil, err | ||||
| 	} | ||||
|  | ||||
| 	return result.Pool, nil | ||||
| func (l *Libvirt) StoragePool(name string) (NonnullStoragePool, error) { | ||||
| 	return l.StoragePoolLookupByName(name) | ||||
| } | ||||
|  | ||||
| // StoragePoolRefresh refreshes the storage pool specified by name. | ||||
| // func (l *Libvirt) StoragePoolRefresh(name string) error { | ||||
| // 	pool, err := l.StoragePool(name) | ||||
| // 	if err != nil { | ||||
| // 		return err | ||||
| // 	} | ||||
| // | ||||
| // 	req := struct { | ||||
| // 		Pool  StoragePool | ||||
| // 		Flags uint32 | ||||
| // 	}{ | ||||
| // 		Pool:  *pool, | ||||
| // 		Flags: 0, // unused per libvirt source, callers should pass 0 | ||||
| // 	} | ||||
| // | ||||
| // 	buf, err := encode(&req) | ||||
| // 	if err != nil { | ||||
| // 		return err | ||||
| // 	} | ||||
| // | ||||
| // 	resp, err := l.request(constants.ProcStoragePoolRefresh, constants.Program, &buf) | ||||
| // 	if err != nil { | ||||
| // 		return err | ||||
| // 	} | ||||
| // | ||||
| // 	r := <-resp | ||||
| // 	if r.Status != StatusOK { | ||||
| // 		return decodeError(r.Payload) | ||||
| // 	} | ||||
| // | ||||
| // 	return nil | ||||
| // } | ||||
|  | ||||
| // StoragePools returns a list of defined storage pools. Pools are filtered by | ||||
| // the provided flags. See StoragePools*. | ||||
| func (l *Libvirt) StoragePools(flags StoragePoolsFlags) ([]StoragePool, error) { | ||||
| 	req := struct { | ||||
| 		NeedResults uint32 | ||||
| 		Flags       StoragePoolsFlags | ||||
| 	}{ | ||||
| 		NeedResults: 1, | ||||
| 		Flags:       flags, | ||||
| 	} | ||||
|  | ||||
| 	buf, err := encode(&req) | ||||
| 	if err != nil { | ||||
| 		return nil, err | ||||
| 	} | ||||
|  | ||||
| 	resp, err := l.request(constants.ProcConnectListAllStoragePools, constants.Program, &buf) | ||||
| 	if err != nil { | ||||
| 		return nil, err | ||||
| 	} | ||||
|  | ||||
| 	r := <-resp | ||||
| 	if r.Status != StatusOK { | ||||
| 		return nil, decodeError(r.Payload) | ||||
| 	} | ||||
|  | ||||
| 	result := struct { | ||||
| 		Pools []StoragePool | ||||
| 		Count uint32 | ||||
| 	}{} | ||||
|  | ||||
| 	dec := xdr.NewDecoder(bytes.NewReader(r.Payload)) | ||||
| 	_, err = dec.Decode(&result) | ||||
| 	if err != nil { | ||||
| 		return nil, err | ||||
| 	} | ||||
|  | ||||
| 	return result.Pools, nil | ||||
| func (l *Libvirt) StoragePools(flags StoragePoolsFlags) ([]NonnullStoragePool, error) { | ||||
| 	pools, _, err := l.ConnectListAllStoragePools(1, uint32(flags)) | ||||
| 	return pools, err | ||||
| } | ||||
|  | ||||
| // Undefine undefines the domain specified by dom, e.g., 'prod-lb-01'. | ||||
| @@ -1077,30 +710,7 @@ func (l *Libvirt) Undefine(dom string, flags UndefineFlags) error { | ||||
| 		return err | ||||
| 	} | ||||
|  | ||||
| 	payload := struct { | ||||
| 		Domain Domain | ||||
| 		Flags  UndefineFlags | ||||
| 	}{ | ||||
| 		Domain: d, | ||||
| 		Flags:  flags, | ||||
| 	} | ||||
|  | ||||
| 	buf, err := encode(&payload) | ||||
| 	if err != nil { | ||||
| 		return err | ||||
| 	} | ||||
|  | ||||
| 	resp, err := l.request(constants.ProcDomainUndefineFlags, constants.Program, &buf) | ||||
| 	if err != nil { | ||||
| 		return err | ||||
| 	} | ||||
|  | ||||
| 	r := <-resp | ||||
| 	if r.Status != StatusOK { | ||||
| 		return decodeError(r.Payload) | ||||
| 	} | ||||
|  | ||||
| 	return nil | ||||
| 	return l.DomainUndefineFlags(d, uint32(flags)) | ||||
| } | ||||
|  | ||||
| // Destroy destroys the domain specified by dom, e.g., 'prod-lb-01'. | ||||
| @@ -1113,30 +723,7 @@ func (l *Libvirt) Destroy(dom string, flags DestroyFlags) error { | ||||
| 		return err | ||||
| 	} | ||||
|  | ||||
| 	payload := struct { | ||||
| 		Domain Domain | ||||
| 		Flags  DestroyFlags | ||||
| 	}{ | ||||
| 		Domain: d, | ||||
| 		Flags:  flags, | ||||
| 	} | ||||
|  | ||||
| 	buf, err := encode(&payload) | ||||
| 	if err != nil { | ||||
| 		return err | ||||
| 	} | ||||
|  | ||||
| 	resp, err := l.request(constants.ProcDomainDestroyFlags, constants.Program, &buf) | ||||
| 	if err != nil { | ||||
| 		return err | ||||
| 	} | ||||
|  | ||||
| 	r := <-resp | ||||
| 	if r.Status != StatusOK { | ||||
| 		return decodeError(r.Payload) | ||||
| 	} | ||||
|  | ||||
| 	return nil | ||||
| 	return l.DomainDestroyFlags(d, uint32(flags)) | ||||
| } | ||||
|  | ||||
| // XML returns a domain's raw XML definition, akin to `virsh dumpxml <domain>`. | ||||
| @@ -1147,85 +734,19 @@ func (l *Libvirt) XML(dom string, flags DomainXMLFlags) ([]byte, error) { | ||||
| 		return nil, err | ||||
| 	} | ||||
|  | ||||
| 	payload := struct { | ||||
| 		Domain Domain | ||||
| 		Flags  DomainXMLFlags | ||||
| 	}{ | ||||
| 		Domain: d, | ||||
| 		Flags:  flags, | ||||
| 	} | ||||
|  | ||||
| 	buf, err := encode(&payload) | ||||
| 	if err != nil { | ||||
| 		return nil, err | ||||
| 	} | ||||
|  | ||||
| 	resp, err := l.request(constants.ProcDomainGetXMLDesc, constants.Program, &buf) | ||||
| 	if err != nil { | ||||
| 		return nil, err | ||||
| 	} | ||||
|  | ||||
| 	r := <-resp | ||||
| 	if r.Status != StatusOK { | ||||
| 		return nil, decodeError(r.Payload) | ||||
| 	} | ||||
|  | ||||
| 	pl := bytes.NewReader(r.Payload) | ||||
| 	dec := xdr.NewDecoder(pl) | ||||
| 	s, _, err := dec.DecodeString() | ||||
| 	if err != nil { | ||||
| 		return nil, err | ||||
| 	} | ||||
|  | ||||
| 	return []byte(s), nil | ||||
| 	xml, err := l.DomainGetXMLDesc(d, uint32(flags)) | ||||
| 	return []byte(xml), err | ||||
| } | ||||
|  | ||||
| // DefineXML defines a domain, but does not start it. | ||||
| func (l *Libvirt) DefineXML(x []byte, flags DomainDefineXMLFlags) error { | ||||
| 	payload := struct { | ||||
| 		Domain []byte | ||||
| 		Flags  DomainDefineXMLFlags | ||||
| 	}{ | ||||
| 		Domain: x, | ||||
| 		Flags:  flags, | ||||
| 	} | ||||
|  | ||||
| 	buf, err := encode(&payload) | ||||
| 	if err != nil { | ||||
| 		return err | ||||
| 	} | ||||
|  | ||||
| 	resp, err := l.request(constants.ProcDomainDefineXMLFlags, constants.Program, &buf) | ||||
| 	if err != nil { | ||||
| 		return err | ||||
| 	} | ||||
|  | ||||
| 	r := <-resp | ||||
| 	if r.Status != StatusOK { | ||||
| 		return decodeError(r.Payload) | ||||
| 	} | ||||
|  | ||||
| 	return nil | ||||
| 	_, err := l.DomainDefineXMLFlags(string(x), uint32(flags)) | ||||
| 	return err | ||||
| } | ||||
|  | ||||
| // Version returns the version of the libvirt daemon. | ||||
| func (l *Libvirt) Version() (string, error) { | ||||
| 	resp, err := l.request(constants.ProcConnectGetLibVersion, constants.Program, nil) | ||||
| 	if err != nil { | ||||
| 		return "", err | ||||
| 	} | ||||
|  | ||||
| 	r := <-resp | ||||
| 	if r.Status != StatusOK { | ||||
| 		return "", decodeError(r.Payload) | ||||
| 	} | ||||
|  | ||||
| 	result := struct { | ||||
| 		Version uint64 | ||||
| 	}{} | ||||
|  | ||||
| 	dec := xdr.NewDecoder(bytes.NewReader(r.Payload)) | ||||
| 	_, err = dec.Decode(&result) | ||||
| 	ver, err := l.ConnectGetLibVersion() | ||||
| 	if err != nil { | ||||
| 		return "", err | ||||
| 	} | ||||
| @@ -1233,11 +754,11 @@ func (l *Libvirt) Version() (string, error) { | ||||
| 	// The version is provided as an int following this formula: | ||||
| 	// version * 1,000,000 + minor * 1000 + micro | ||||
| 	// See src/libvirt-host.c # virConnectGetLibVersion | ||||
| 	major := result.Version / 1000000 | ||||
| 	result.Version %= 1000000 | ||||
| 	minor := result.Version / 1000 | ||||
| 	result.Version %= 1000 | ||||
| 	micro := result.Version | ||||
| 	major := ver / 1000000 | ||||
| 	ver %= 1000000 | ||||
| 	minor := ver / 1000 | ||||
| 	ver %= 1000 | ||||
| 	micro := ver | ||||
|  | ||||
| 	versionString := fmt.Sprintf("%d.%d.%d", major, minor, micro) | ||||
| 	return versionString, nil | ||||
| @@ -1251,30 +772,7 @@ func (l *Libvirt) Shutdown(dom string, flags ShutdownFlags) error { | ||||
| 		return err | ||||
| 	} | ||||
|  | ||||
| 	payload := struct { | ||||
| 		Domain Domain | ||||
| 		Flags  ShutdownFlags | ||||
| 	}{ | ||||
| 		Domain: d, | ||||
| 		Flags:  flags, | ||||
| 	} | ||||
|  | ||||
| 	buf, err := encode(&payload) | ||||
| 	if err != nil { | ||||
| 		return err | ||||
| 	} | ||||
|  | ||||
| 	resp, err := l.request(constants.ProcDomainShutdownFlags, constants.Program, &buf) | ||||
| 	if err != nil { | ||||
| 		return err | ||||
| 	} | ||||
|  | ||||
| 	r := <-resp | ||||
| 	if r.Status != StatusOK { | ||||
| 		return decodeError(r.Payload) | ||||
| 	} | ||||
|  | ||||
| 	return nil | ||||
| 	return l.DomainShutdownFlags(d, uint32(flags)) | ||||
| } | ||||
|  | ||||
| // Reboot reboots the domain. Note that the guest OS may ignore the request. | ||||
| @@ -1285,30 +783,7 @@ func (l *Libvirt) Reboot(dom string, flags RebootFlags) error { | ||||
| 		return err | ||||
| 	} | ||||
|  | ||||
| 	payload := struct { | ||||
| 		Domain Domain | ||||
| 		Flags  RebootFlags | ||||
| 	}{ | ||||
| 		Domain: d, | ||||
| 		Flags:  flags, | ||||
| 	} | ||||
|  | ||||
| 	buf, err := encode(&payload) | ||||
| 	if err != nil { | ||||
| 		return err | ||||
| 	} | ||||
|  | ||||
| 	resp, err := l.request(constants.ProcDomainReboot, constants.Program, &buf) | ||||
| 	if err != nil { | ||||
| 		return err | ||||
| 	} | ||||
|  | ||||
| 	r := <-resp | ||||
| 	if r.Status != StatusOK { | ||||
| 		return decodeError(r.Payload) | ||||
| 	} | ||||
|  | ||||
| 	return nil | ||||
| 	return l.DomainReboot(d, uint32(flags)) | ||||
| } | ||||
|  | ||||
| // Reset resets domain immediately without any guest OS shutdown | ||||
| @@ -1318,30 +793,7 @@ func (l *Libvirt) Reset(dom string) error { | ||||
| 		return err | ||||
| 	} | ||||
|  | ||||
| 	payload := struct { | ||||
| 		Domain Domain | ||||
| 		Flags  uint32 | ||||
| 	}{ | ||||
| 		Domain: d, | ||||
| 		Flags:  0, | ||||
| 	} | ||||
|  | ||||
| 	buf, err := encode(&payload) | ||||
| 	if err != nil { | ||||
| 		return err | ||||
| 	} | ||||
|  | ||||
| 	resp, err := l.request(constants.ProcDomainReset, constants.Program, &buf) | ||||
| 	if err != nil { | ||||
| 		return err | ||||
| 	} | ||||
|  | ||||
| 	r := <-resp | ||||
| 	if r.Status != StatusOK { | ||||
| 		return decodeError(r.Payload) | ||||
| 	} | ||||
|  | ||||
| 	return nil | ||||
| 	return l.DomainReset(d, 0) | ||||
| } | ||||
|  | ||||
| // BlockLimit contains a name and value pair for a Get/SetBlockIOTune limit. The | ||||
| @@ -1404,7 +856,7 @@ func (l *Libvirt) SetBlockIOTune(dom string, disk string, limits ...BlockLimit) | ||||
| 		params[ix] = TypedParam{Field: limit.Name, Value: tpval} | ||||
| 	} | ||||
|  | ||||
| 	return l.DomainSetBlockIOTune(*d, disk, params, FlagDomainAffectLive) | ||||
| 	return l.DomainSetBlockIOTune(d, disk, params, FlagDomainAffectLive) | ||||
| } | ||||
|  | ||||
| // GetBlockIOTune returns a slice containing the current block I/O tunables for | ||||
| @@ -1415,46 +867,12 @@ func (l *Libvirt) GetBlockIOTune(dom string, disk string) ([]BlockLimit, error) | ||||
| 		return nil, err | ||||
| 	} | ||||
|  | ||||
| 	lims, _, err := l.DomainGetBlockIOTune(*d, disk, 32, FlagTypedParamStringOkay) | ||||
| 	lims, _, err := l.DomainGetBlockIOTune(d, []string{disk}, 32, FlagTypedParamStringOkay) | ||||
| 	if err != nil { | ||||
| 		return nil, err | ||||
| 	} | ||||
| 	// payload := struct { | ||||
| 	// 	Domain     Domain | ||||
| 	// 	Disk       []string | ||||
| 	// 	ParamCount uint32 | ||||
| 	// 	Flags      DomainAffectFlags | ||||
| 	// }{ | ||||
| 	// 	Domain:     d, | ||||
| 	// 	Disk:       []string{disk}, | ||||
| 	// 	ParamCount: 32, | ||||
| 	// 	Flags:      FlagTypedParamStringOkay, | ||||
| 	// } | ||||
| 	// | ||||
| 	// buf, err := encode(&payload) | ||||
| 	// if err != nil { | ||||
| 	// 	return nil, err | ||||
| 	// } | ||||
| 	// | ||||
| 	// resp, err := l.request(constants.ProcDomainGetBlockIOTune, constants.Program, &buf) | ||||
| 	// if err != nil { | ||||
| 	// 	return nil, err | ||||
| 	// } | ||||
| 	// | ||||
| 	// r := <-resp | ||||
| 	// if r.Status != StatusOK { | ||||
| 	// 	return nil, decodeError(r.Payload) | ||||
| 	// } | ||||
|  | ||||
| 	var limits []BlockLimit | ||||
| 	// rdr := bytes.NewReader(r.Payload) | ||||
| 	// dec := xdr.NewDecoder(rdr) | ||||
|  | ||||
| 	// find out how many params were returned | ||||
| 	// paramCount, _, err := dec.DecodeInt() | ||||
| 	// if err != nil { | ||||
| 	// 	return nil, err | ||||
| 	// } | ||||
|  | ||||
| 	// now decode each of the returned TypedParams. To do this we read the field | ||||
| 	// name and type, then use the type information to decode the value. | ||||
| @@ -1468,73 +886,40 @@ func (l *Libvirt) GetBlockIOTune(dom string, disk string) ([]BlockLimit, error) | ||||
| 		limits = append(limits, l) | ||||
| 	} | ||||
|  | ||||
| 	// for param := int32(0); param < paramCount; param++ { | ||||
| 	// 	// Get the field name | ||||
| 	// 	name, _, err := dec.DecodeString() | ||||
| 	// 	if err != nil { | ||||
| 	// 		return nil, err | ||||
| 	// 	} | ||||
| 	// 	// ...and the type | ||||
| 	// 	ptype, _, err := dec.DecodeInt() | ||||
| 	// 	if err != nil { | ||||
| 	// 		return nil, err | ||||
| 	// 	} | ||||
| 	// | ||||
| 	// 	// Now we can read the actual value. | ||||
| 	// 	switch ptype { | ||||
| 	// 	case TypeParamULLong: | ||||
| 	// 		var val uint64 | ||||
| 	// 		_, err = dec.Decode(&val) | ||||
| 	// 		if err != nil { | ||||
| 	// 			return nil, err | ||||
| 	// 		} | ||||
| 	// 		lim := BlockLimit{name, val} | ||||
| 	// 		limits = append(limits, lim) | ||||
| 	// 	case TypeParamString: | ||||
| 	// 		var val string | ||||
| 	// 		_, err = dec.Decode(&val) | ||||
| 	// 		if err != nil { | ||||
| 	// 			return nil, err | ||||
| 	// 		} | ||||
| 	// 		// This routine doesn't currently return strings. As of libvirt 3+, | ||||
| 	// 		// there's one string here, `group_name`. | ||||
| 	// 	} | ||||
| 	// } | ||||
|  | ||||
| 	return limits, nil | ||||
| } | ||||
|  | ||||
| // lookup returns a domain as seen by libvirt. | ||||
| func (l *Libvirt) lookup(name string) (Domain, error) { | ||||
| func (l *Libvirt) lookup(name string) (NonnullDomain, error) { | ||||
| 	var d NonnullDomain | ||||
| 	payload := struct { | ||||
| 		Name string | ||||
| 	}{name} | ||||
|  | ||||
| 	buf, err := encode(&payload) | ||||
| 	if err != nil { | ||||
| 		return nil, err | ||||
| 		return d, err | ||||
| 	} | ||||
|  | ||||
| 	resp, err := l.request(constants.ProcDomainLookupByName, constants.Program, &buf) | ||||
| 	if err != nil { | ||||
| 		return nil, err | ||||
| 		return d, err | ||||
| 	} | ||||
|  | ||||
| 	r := <-resp | ||||
| 	if r.Status != StatusOK { | ||||
| 		return nil, decodeError(r.Payload) | ||||
| 		return d, decodeError(r.Payload) | ||||
| 	} | ||||
|  | ||||
| 	dec := xdr.NewDecoder(bytes.NewReader(r.Payload)) | ||||
|  | ||||
| 	// var d Domain | ||||
| 	var d NonnullDomain | ||||
| 	_, err = dec.Decode(&d) | ||||
| 	if err != nil { | ||||
| 		return nil, err | ||||
| 		return d, err | ||||
| 	} | ||||
|  | ||||
| 	return &d, nil | ||||
| 	return d, nil | ||||
| } | ||||
|  | ||||
| // getQEMUError checks the provided response for QEMU process errors. | ||||
|   | ||||
| @@ -153,7 +153,7 @@ func TestDomainMemoryStats(t *testing.T) { | ||||
| 		t.Error(err) | ||||
| 	} | ||||
|  | ||||
| 	gotDomainMemoryStats, err := l.DomainMemoryStats(*d, 8, 0) | ||||
| 	gotDomainMemoryStats, err := l.DomainMemoryStats(d, 8, 0) | ||||
| 	if err != nil { | ||||
| 		t.Error(err) | ||||
| 	} | ||||
| @@ -361,7 +361,7 @@ func TestStoragePoolRefresh(t *testing.T) { | ||||
| 	if err != nil { | ||||
| 		t.Error(err) | ||||
| 	} | ||||
| 	err = l.StoragePoolRefresh(*pool, 0) | ||||
| 	err = l.StoragePoolRefresh(pool, 0) | ||||
| 	if err != nil { | ||||
| 		t.Error(err) | ||||
| 	} | ||||
| @@ -422,7 +422,7 @@ func TestDomainCreateWithFlags(t *testing.T) { | ||||
| 		t.Fatalf("failed to lookup domain: %v", err) | ||||
| 	} | ||||
| 	var flags uint32 | ||||
| 	if _, err := l.DomainCreateWithFlags(*d, flags); err != nil { | ||||
| 	if _, err := l.DomainCreateWithFlags(d, flags); err != nil { | ||||
| 		t.Fatalf("unexpected create error: %v", err) | ||||
| 	} | ||||
| } | ||||
|   | ||||
| @@ -340,10 +340,6 @@ func TestLookup(t *testing.T) { | ||||
| 		t.Error(err) | ||||
| 	} | ||||
|  | ||||
| 	if d == nil { | ||||
| 		t.Error("nil domain returned") | ||||
| 	} | ||||
|  | ||||
| 	if d.Name != name { | ||||
| 		t.Errorf("expected domain %s, got %s", name, d.Name) | ||||
| 	} | ||||
|   | ||||
		Reference in New Issue
	
	Block a user