* Add Virtual Kubelet provider for VIC Initial virtual kubelet provider for VMware VIC. This provider currently handles creating and starting of a pod VM via the VIC portlayer and persona server. Image store handling via the VIC persona server. This provider currently requires the feature/wolfpack branch of VIC. * Added pod stop and delete. Also added node capacity. Added the ability to stop and delete pod VMs via VIC. Also retrieve node capacity information from the VCH. * Cleanup and readme file Some file clean up and added a Readme.md markdown file for the VIC provider. * Cleaned up errors, added function comments, moved operation code 1. Cleaned up error handling. Set standard for creating errors. 2. Added method prototype comments for all interface functions. 3. Moved PodCreator, PodStarter, PodStopper, and PodDeleter to a new folder. * Add mocking code and unit tests for podcache, podcreator, and podstarter Used the unit test framework used in VIC to handle assertions in the provider's unit test. Mocking code generated using OSS project mockery, which is compatible with the testify assertion framework. * Vendored packages for the VIC provider Requires feature/wolfpack branch of VIC and a few specific commit sha of projects used within VIC. * Implementation of POD Stopper and Deleter unit tests (#4) * Updated files for initial PR
260 lines
5.8 KiB
Go
260 lines
5.8 KiB
Go
package dbus
|
|
|
|
import (
|
|
"fmt"
|
|
"reflect"
|
|
"strings"
|
|
)
|
|
|
|
var sigToType = map[byte]reflect.Type{
|
|
'y': byteType,
|
|
'b': boolType,
|
|
'n': int16Type,
|
|
'q': uint16Type,
|
|
'i': int32Type,
|
|
'u': uint32Type,
|
|
'x': int64Type,
|
|
't': uint64Type,
|
|
'd': float64Type,
|
|
's': stringType,
|
|
'g': signatureType,
|
|
'o': objectPathType,
|
|
'v': variantType,
|
|
'h': unixFDIndexType,
|
|
}
|
|
|
|
// Signature represents a correct type signature as specified by the D-Bus
|
|
// specification. The zero value represents the empty signature, "".
|
|
type Signature struct {
|
|
str string
|
|
}
|
|
|
|
// SignatureOf returns the concatenation of all the signatures of the given
|
|
// values. It panics if one of them is not representable in D-Bus.
|
|
func SignatureOf(vs ...interface{}) Signature {
|
|
var s string
|
|
for _, v := range vs {
|
|
s += getSignature(reflect.TypeOf(v))
|
|
}
|
|
return Signature{s}
|
|
}
|
|
|
|
// SignatureOfType returns the signature of the given type. It panics if the
|
|
// type is not representable in D-Bus.
|
|
func SignatureOfType(t reflect.Type) Signature {
|
|
return Signature{getSignature(t)}
|
|
}
|
|
|
|
// getSignature returns the signature of the given type and panics on unknown types.
|
|
func getSignature(t reflect.Type) string {
|
|
// handle simple types first
|
|
switch t.Kind() {
|
|
case reflect.Uint8:
|
|
return "y"
|
|
case reflect.Bool:
|
|
return "b"
|
|
case reflect.Int16:
|
|
return "n"
|
|
case reflect.Uint16:
|
|
return "q"
|
|
case reflect.Int, reflect.Int32:
|
|
if t == unixFDType {
|
|
return "h"
|
|
}
|
|
return "i"
|
|
case reflect.Uint, reflect.Uint32:
|
|
if t == unixFDIndexType {
|
|
return "h"
|
|
}
|
|
return "u"
|
|
case reflect.Int64:
|
|
return "x"
|
|
case reflect.Uint64:
|
|
return "t"
|
|
case reflect.Float64:
|
|
return "d"
|
|
case reflect.Ptr:
|
|
return getSignature(t.Elem())
|
|
case reflect.String:
|
|
if t == objectPathType {
|
|
return "o"
|
|
}
|
|
return "s"
|
|
case reflect.Struct:
|
|
if t == variantType {
|
|
return "v"
|
|
} else if t == signatureType {
|
|
return "g"
|
|
}
|
|
var s string
|
|
for i := 0; i < t.NumField(); i++ {
|
|
field := t.Field(i)
|
|
if field.PkgPath == "" && field.Tag.Get("dbus") != "-" {
|
|
s += getSignature(t.Field(i).Type)
|
|
}
|
|
}
|
|
return "(" + s + ")"
|
|
case reflect.Array, reflect.Slice:
|
|
return "a" + getSignature(t.Elem())
|
|
case reflect.Map:
|
|
if !isKeyType(t.Key()) {
|
|
panic(InvalidTypeError{t})
|
|
}
|
|
return "a{" + getSignature(t.Key()) + getSignature(t.Elem()) + "}"
|
|
case reflect.Interface:
|
|
return "v"
|
|
}
|
|
panic(InvalidTypeError{t})
|
|
}
|
|
|
|
// ParseSignature returns the signature represented by this string, or a
|
|
// SignatureError if the string is not a valid signature.
|
|
func ParseSignature(s string) (sig Signature, err error) {
|
|
if len(s) == 0 {
|
|
return
|
|
}
|
|
if len(s) > 255 {
|
|
return Signature{""}, SignatureError{s, "too long"}
|
|
}
|
|
sig.str = s
|
|
for err == nil && len(s) != 0 {
|
|
err, s = validSingle(s, 0)
|
|
}
|
|
if err != nil {
|
|
sig = Signature{""}
|
|
}
|
|
|
|
return
|
|
}
|
|
|
|
// ParseSignatureMust behaves like ParseSignature, except that it panics if s
|
|
// is not valid.
|
|
func ParseSignatureMust(s string) Signature {
|
|
sig, err := ParseSignature(s)
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
return sig
|
|
}
|
|
|
|
// Empty retruns whether the signature is the empty signature.
|
|
func (s Signature) Empty() bool {
|
|
return s.str == ""
|
|
}
|
|
|
|
// Single returns whether the signature represents a single, complete type.
|
|
func (s Signature) Single() bool {
|
|
err, r := validSingle(s.str, 0)
|
|
return err != nil && r == ""
|
|
}
|
|
|
|
// String returns the signature's string representation.
|
|
func (s Signature) String() string {
|
|
return s.str
|
|
}
|
|
|
|
// A SignatureError indicates that a signature passed to a function or received
|
|
// on a connection is not a valid signature.
|
|
type SignatureError struct {
|
|
Sig string
|
|
Reason string
|
|
}
|
|
|
|
func (e SignatureError) Error() string {
|
|
return fmt.Sprintf("dbus: invalid signature: %q (%s)", e.Sig, e.Reason)
|
|
}
|
|
|
|
// Try to read a single type from this string. If it was successful, err is nil
|
|
// and rem is the remaining unparsed part. Otherwise, err is a non-nil
|
|
// SignatureError and rem is "". depth is the current recursion depth which may
|
|
// not be greater than 64 and should be given as 0 on the first call.
|
|
func validSingle(s string, depth int) (err error, rem string) {
|
|
if s == "" {
|
|
return SignatureError{Sig: s, Reason: "empty signature"}, ""
|
|
}
|
|
if depth > 64 {
|
|
return SignatureError{Sig: s, Reason: "container nesting too deep"}, ""
|
|
}
|
|
switch s[0] {
|
|
case 'y', 'b', 'n', 'q', 'i', 'u', 'x', 't', 'd', 's', 'g', 'o', 'v', 'h':
|
|
return nil, s[1:]
|
|
case 'a':
|
|
if len(s) > 1 && s[1] == '{' {
|
|
i := findMatching(s[1:], '{', '}')
|
|
if i == -1 {
|
|
return SignatureError{Sig: s, Reason: "unmatched '{'"}, ""
|
|
}
|
|
i++
|
|
rem = s[i+1:]
|
|
s = s[2:i]
|
|
if err, _ = validSingle(s[:1], depth+1); err != nil {
|
|
return err, ""
|
|
}
|
|
err, nr := validSingle(s[1:], depth+1)
|
|
if err != nil {
|
|
return err, ""
|
|
}
|
|
if nr != "" {
|
|
return SignatureError{Sig: s, Reason: "too many types in dict"}, ""
|
|
}
|
|
return nil, rem
|
|
}
|
|
return validSingle(s[1:], depth+1)
|
|
case '(':
|
|
i := findMatching(s, '(', ')')
|
|
if i == -1 {
|
|
return SignatureError{Sig: s, Reason: "unmatched ')'"}, ""
|
|
}
|
|
rem = s[i+1:]
|
|
s = s[1:i]
|
|
for err == nil && s != "" {
|
|
err, s = validSingle(s, depth+1)
|
|
}
|
|
if err != nil {
|
|
rem = ""
|
|
}
|
|
return
|
|
}
|
|
return SignatureError{Sig: s, Reason: "invalid type character"}, ""
|
|
}
|
|
|
|
func findMatching(s string, left, right rune) int {
|
|
n := 0
|
|
for i, v := range s {
|
|
if v == left {
|
|
n++
|
|
} else if v == right {
|
|
n--
|
|
}
|
|
if n == 0 {
|
|
return i
|
|
}
|
|
}
|
|
return -1
|
|
}
|
|
|
|
// typeFor returns the type of the given signature. It ignores any left over
|
|
// characters and panics if s doesn't start with a valid type signature.
|
|
func typeFor(s string) (t reflect.Type) {
|
|
err, _ := validSingle(s, 0)
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
|
|
if t, ok := sigToType[s[0]]; ok {
|
|
return t
|
|
}
|
|
switch s[0] {
|
|
case 'a':
|
|
if s[1] == '{' {
|
|
i := strings.LastIndex(s, "}")
|
|
t = reflect.MapOf(sigToType[s[2]], typeFor(s[3:i]))
|
|
} else {
|
|
t = reflect.SliceOf(typeFor(s[1:]))
|
|
}
|
|
case '(':
|
|
t = interfacesType
|
|
}
|
|
return
|
|
}
|