Adding test coverage
This commit is contained in:
parent
8aa0fd9445
commit
9499553706
|
@ -11,168 +11,148 @@ import (
|
|||
|
||||
//export GuestCapabilities
|
||||
func GuestCapabilities(pluginName, pluginType *C.char) *C.char {
|
||||
r := vagrant.Response{}
|
||||
p, err := getGuestCapsPlugin(pluginName, pluginType)
|
||||
r := &Response{}
|
||||
i, err := Plugins.PluginLookup(to_gs(pluginName), to_gs(pluginType))
|
||||
if err != nil {
|
||||
r.Error = err
|
||||
return C.CString(r.Dump())
|
||||
return r.Dump()
|
||||
}
|
||||
p, ok := i.(*plugin.RemoteGuestCapabilities)
|
||||
if !ok {
|
||||
r.Error = errors.New("failed to load requested plugin")
|
||||
return r.Dump()
|
||||
}
|
||||
r.Result, r.Error = p.GuestCapabilities.GuestCapabilities()
|
||||
return C.CString(r.Dump())
|
||||
return r.Dump()
|
||||
}
|
||||
|
||||
//export GuestCapability
|
||||
func GuestCapability(pluginName, pluginType, cname, cplatform, cargs, cmachine *C.char) *C.char {
|
||||
r := vagrant.Response{}
|
||||
p, err := getGuestCapsPlugin(pluginName, pluginType)
|
||||
r := &Response{}
|
||||
i, err := Plugins.PluginLookup(to_gs(pluginName), to_gs(pluginType))
|
||||
if err != nil {
|
||||
r.Error = err
|
||||
return C.CString(r.Dump())
|
||||
return r.Dump()
|
||||
}
|
||||
machine, err := vagrant.LoadMachine(C.GoString(cmachine), nil)
|
||||
p, ok := i.(*plugin.RemoteGuestCapabilities)
|
||||
if !ok {
|
||||
r.Error = errors.New("Failed to load requested plugin")
|
||||
return r.Dump()
|
||||
}
|
||||
machine, err := vagrant.LoadMachine(to_gs(cmachine), nil)
|
||||
if err != nil {
|
||||
r.Error = err
|
||||
return C.CString(r.Dump())
|
||||
return r.Dump()
|
||||
}
|
||||
var args interface{}
|
||||
err = json.Unmarshal([]byte(C.GoString(cargs)), &args)
|
||||
err = json.Unmarshal([]byte(to_gs(cargs)), &args)
|
||||
if err != nil {
|
||||
r.Error = err
|
||||
return C.CString(r.Dump())
|
||||
return r.Dump()
|
||||
}
|
||||
cap := &vagrant.SystemCapability{
|
||||
Name: C.GoString(cname),
|
||||
Platform: C.GoString(cplatform)}
|
||||
Name: to_gs(cname),
|
||||
Platform: to_gs(cplatform)}
|
||||
r.Result, r.Error = p.GuestCapabilities.GuestCapability(cap, args, machine)
|
||||
return C.CString(r.Dump())
|
||||
return r.Dump()
|
||||
}
|
||||
|
||||
//export HostCapabilities
|
||||
func HostCapabilities(pluginName, pluginType *C.char) *C.char {
|
||||
r := vagrant.Response{}
|
||||
p, err := getHostCapsPlugin(pluginName, pluginType)
|
||||
r := &Response{}
|
||||
i, err := Plugins.PluginLookup(to_gs(pluginName), to_gs(pluginType))
|
||||
if err != nil {
|
||||
r.Error = err
|
||||
return C.CString(r.Dump())
|
||||
return r.Dump()
|
||||
}
|
||||
p, ok := i.(*plugin.RemoteHostCapabilities)
|
||||
if !ok {
|
||||
r.Error = errors.New("Failed to load requested plugin")
|
||||
return r.Dump()
|
||||
}
|
||||
|
||||
r.Result, r.Error = p.HostCapabilities.HostCapabilities()
|
||||
return C.CString(r.Dump())
|
||||
return r.Dump()
|
||||
}
|
||||
|
||||
//export HostCapability
|
||||
func HostCapability(pluginName, pluginType, cname, cplatform, cargs, cenv *C.char) *C.char {
|
||||
r := vagrant.Response{}
|
||||
p, err := getHostCapsPlugin(pluginName, pluginType)
|
||||
r := &Response{}
|
||||
i, err := Plugins.PluginLookup(to_gs(pluginName), to_gs(pluginType))
|
||||
if err != nil {
|
||||
r.Error = err
|
||||
return C.CString(r.Dump())
|
||||
return r.Dump()
|
||||
}
|
||||
env, err := vagrant.LoadEnvironment(C.GoString(cenv), nil)
|
||||
p, ok := i.(*plugin.RemoteHostCapabilities)
|
||||
if !ok {
|
||||
r.Error = errors.New("Failed to load requested plugin")
|
||||
return r.Dump()
|
||||
}
|
||||
|
||||
env, err := vagrant.LoadEnvironment(to_gs(cenv), nil)
|
||||
if err != nil {
|
||||
r.Error = err
|
||||
return C.CString(r.Dump())
|
||||
return r.Dump()
|
||||
}
|
||||
var args interface{}
|
||||
err = json.Unmarshal([]byte(C.GoString(cargs)), &args)
|
||||
err = json.Unmarshal([]byte(to_gs(cargs)), &args)
|
||||
if err != nil {
|
||||
r.Error = err
|
||||
return C.CString(r.Dump())
|
||||
return r.Dump()
|
||||
}
|
||||
cap := &vagrant.SystemCapability{
|
||||
Name: C.GoString(cname),
|
||||
Platform: C.GoString(cplatform)}
|
||||
Name: to_gs(cname),
|
||||
Platform: to_gs(cplatform)}
|
||||
r.Result, r.Error = p.HostCapabilities.HostCapability(cap, args, env)
|
||||
return C.CString(r.Dump())
|
||||
return r.Dump()
|
||||
}
|
||||
|
||||
//export ProviderCapabilities
|
||||
func ProviderCapabilities(pluginName, pluginType *C.char) *C.char {
|
||||
r := vagrant.Response{}
|
||||
p, err := getProviderCapsPlugin(pluginName, pluginType)
|
||||
r := &Response{}
|
||||
i, err := Plugins.PluginLookup(to_gs(pluginName), to_gs(pluginType))
|
||||
if err != nil {
|
||||
r.Error = err
|
||||
return C.CString(r.Dump())
|
||||
return r.Dump()
|
||||
}
|
||||
p, ok := i.(*plugin.RemoteProviderCapabilities)
|
||||
if !ok {
|
||||
r.Error = errors.New("Failed to load requested plugin")
|
||||
return r.Dump()
|
||||
}
|
||||
|
||||
r.Result, r.Error = p.ProviderCapabilities.ProviderCapabilities()
|
||||
return C.CString(r.Dump())
|
||||
return r.Dump()
|
||||
}
|
||||
|
||||
//export ProviderCapability
|
||||
func ProviderCapability(pluginName, pluginType, cname, cprovider, cargs, cmach *C.char) *C.char {
|
||||
r := vagrant.Response{}
|
||||
p, err := getProviderCapsPlugin(pluginName, pluginType)
|
||||
r := &Response{}
|
||||
i, err := Plugins.PluginLookup(to_gs(pluginName), to_gs(pluginType))
|
||||
if err != nil {
|
||||
r.Error = err
|
||||
return C.CString(r.Dump())
|
||||
return r.Dump()
|
||||
}
|
||||
m, err := vagrant.LoadMachine(C.GoString(cmach), nil)
|
||||
p, ok := i.(*plugin.RemoteProviderCapabilities)
|
||||
if !ok {
|
||||
r.Error = errors.New("Failed to load requested plugin")
|
||||
return r.Dump()
|
||||
}
|
||||
|
||||
m, err := vagrant.LoadMachine(to_gs(cmach), nil)
|
||||
if err != nil {
|
||||
r.Error = err
|
||||
return C.CString(r.Dump())
|
||||
return r.Dump()
|
||||
}
|
||||
var args interface{}
|
||||
err = json.Unmarshal([]byte(C.GoString(cargs)), &args)
|
||||
err = json.Unmarshal([]byte(to_gs(cargs)), &args)
|
||||
if err != nil {
|
||||
r.Error = err
|
||||
return C.CString(r.Dump())
|
||||
return r.Dump()
|
||||
}
|
||||
cap := &vagrant.ProviderCapability{
|
||||
Name: C.GoString(cname),
|
||||
Provider: C.GoString(cprovider)}
|
||||
Name: to_gs(cname),
|
||||
Provider: to_gs(cprovider)}
|
||||
r.Result, r.Error = p.ProviderCapabilities.ProviderCapability(cap, args, m)
|
||||
return C.CString(r.Dump())
|
||||
}
|
||||
|
||||
func getProviderCapsPlugin(pluginName, pluginType *C.char) (c *plugin.RemoteProviderCapabilities, err error) {
|
||||
pname := C.GoString(pluginName)
|
||||
ptype := C.GoString(pluginType)
|
||||
|
||||
if ptype == "provider" {
|
||||
p, ok := Plugins.Providers[pname]
|
||||
if ok {
|
||||
c = &plugin.RemoteProviderCapabilities{
|
||||
Client: p.Client,
|
||||
ProviderCapabilities: p.Provider}
|
||||
}
|
||||
}
|
||||
if c == nil {
|
||||
err = errors.New("Failed to locate requested plugin")
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func getGuestCapsPlugin(pluginName, pluginType *C.char) (c *plugin.RemoteGuestCapabilities, err error) {
|
||||
pname := C.GoString(pluginName)
|
||||
ptype := C.GoString(pluginType)
|
||||
|
||||
if ptype == "provider" {
|
||||
p, ok := Plugins.Providers[pname]
|
||||
if ok {
|
||||
c = &plugin.RemoteGuestCapabilities{
|
||||
Client: p.Client,
|
||||
GuestCapabilities: p.Provider}
|
||||
}
|
||||
}
|
||||
if c == nil {
|
||||
err = errors.New("Failed to locate requested plugin")
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func getHostCapsPlugin(pluginName, pluginType *C.char) (c *plugin.RemoteHostCapabilities, err error) {
|
||||
pname := C.GoString(pluginName)
|
||||
ptype := C.GoString(pluginType)
|
||||
|
||||
if ptype == "provider" {
|
||||
p, ok := Plugins.Providers[pname]
|
||||
if ok {
|
||||
c = &plugin.RemoteHostCapabilities{
|
||||
Client: p.Client,
|
||||
HostCapabilities: p.Provider}
|
||||
}
|
||||
}
|
||||
if c == nil {
|
||||
err = errors.New("Failed to locate requested plugin")
|
||||
}
|
||||
return
|
||||
return r.Dump()
|
||||
}
|
||||
|
|
|
@ -0,0 +1,414 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"testing"
|
||||
|
||||
"github.com/hashicorp/go-plugin"
|
||||
vplugin "github.com/hashicorp/vagrant/ext/go-plugin/vagrant/plugin"
|
||||
)
|
||||
|
||||
func TestCapabilities_GuestCapabilities(t *testing.T) {
|
||||
client, server := plugin.TestPluginGRPCConn(t, map[string]plugin.Plugin{
|
||||
"caps": &vplugin.GuestCapabilitiesPlugin{Impl: &vplugin.MockGuestCapabilities{}}})
|
||||
defer server.Stop()
|
||||
defer client.Close()
|
||||
|
||||
raw, err := client.Dispense("caps")
|
||||
if err != nil {
|
||||
t.Fatalf("err: %s", err)
|
||||
}
|
||||
impl, ok := raw.(vplugin.GuestCapabilities)
|
||||
if !ok {
|
||||
t.Fatalf("bad %#v", raw)
|
||||
}
|
||||
|
||||
p := &vplugin.RemoteGuestCapabilities{
|
||||
GuestCapabilities: impl}
|
||||
Plugins = vplugin.VagrantPluginInit()
|
||||
Plugins.PluginLookup = func(_, _ string) (r interface{}, err error) {
|
||||
r = p
|
||||
return
|
||||
}
|
||||
|
||||
result := GuestCapabilities(nil, nil)
|
||||
resp, err := LoadResponse(result)
|
||||
if err != nil {
|
||||
t.Fatalf("err: %s", err)
|
||||
}
|
||||
caps, ok := resp.Result.([]interface{})
|
||||
if !ok {
|
||||
t.Fatalf("bad %#v", resp.Result)
|
||||
}
|
||||
|
||||
cap, ok := caps[0].(map[string]interface{})
|
||||
if !ok {
|
||||
t.Fatalf("bad %#v", caps[0])
|
||||
}
|
||||
|
||||
if cap["name"] != "test_cap" {
|
||||
t.Errorf("%s != test_cap", cap["name"])
|
||||
}
|
||||
if cap["platform"] != "testOS" {
|
||||
t.Errorf("%s != testOS", cap["platform"])
|
||||
}
|
||||
}
|
||||
|
||||
func TestCapabilities_GuestCapability(t *testing.T) {
|
||||
client, server := plugin.TestPluginGRPCConn(t, map[string]plugin.Plugin{
|
||||
"caps": &vplugin.GuestCapabilitiesPlugin{Impl: &vplugin.MockGuestCapabilities{}}})
|
||||
defer server.Stop()
|
||||
defer client.Close()
|
||||
|
||||
raw, err := client.Dispense("caps")
|
||||
if err != nil {
|
||||
t.Fatalf("err: %s", err)
|
||||
}
|
||||
impl, ok := raw.(vplugin.GuestCapabilities)
|
||||
if !ok {
|
||||
t.Fatalf("bad %#v", raw)
|
||||
}
|
||||
|
||||
p := &vplugin.RemoteGuestCapabilities{
|
||||
GuestCapabilities: impl}
|
||||
Plugins = vplugin.VagrantPluginInit()
|
||||
Plugins.PluginLookup = func(_, _ string) (r interface{}, err error) {
|
||||
r = p
|
||||
return
|
||||
}
|
||||
|
||||
a, err := json.Marshal([]string{"test_arg", "other_arg"})
|
||||
if err != nil {
|
||||
t.Fatalf("err: %s", err)
|
||||
}
|
||||
args := string(a)
|
||||
result := GuestCapability(nil, nil, to_cs("test_cap"), to_cs("test_platform"), to_cs(args), to_cs("{}"))
|
||||
resp, err := LoadResponse(result)
|
||||
if err != nil {
|
||||
t.Fatalf("err: %s", err)
|
||||
}
|
||||
|
||||
r, ok := resp.Result.([]interface{})
|
||||
if !ok {
|
||||
t.Fatalf("bad %#v", resp.Result)
|
||||
}
|
||||
|
||||
if r[0] != "test_cap" {
|
||||
t.Errorf("%s != test_cap", r[0])
|
||||
}
|
||||
if r[1] != "test_arg" {
|
||||
t.Errorf("%s != test_arg", r[1])
|
||||
}
|
||||
}
|
||||
|
||||
func TestCapabilities_GuestCapability_noargs(t *testing.T) {
|
||||
client, server := plugin.TestPluginGRPCConn(t, map[string]plugin.Plugin{
|
||||
"caps": &vplugin.GuestCapabilitiesPlugin{Impl: &vplugin.MockGuestCapabilities{}}})
|
||||
defer server.Stop()
|
||||
defer client.Close()
|
||||
|
||||
raw, err := client.Dispense("caps")
|
||||
if err != nil {
|
||||
t.Fatalf("err: %s", err)
|
||||
}
|
||||
impl, ok := raw.(vplugin.GuestCapabilities)
|
||||
if !ok {
|
||||
t.Fatalf("bad %#v", raw)
|
||||
}
|
||||
|
||||
p := &vplugin.RemoteGuestCapabilities{
|
||||
GuestCapabilities: impl}
|
||||
Plugins = vplugin.VagrantPluginInit()
|
||||
Plugins.PluginLookup = func(_, _ string) (r interface{}, err error) {
|
||||
r = p
|
||||
return
|
||||
}
|
||||
|
||||
result := GuestCapability(nil, nil, to_cs("test_cap"), to_cs("test_platform"), to_cs("null"), to_cs("{}"))
|
||||
resp, err := LoadResponse(result)
|
||||
if err != nil {
|
||||
t.Fatalf("err: %s - %s", err, to_gs(result))
|
||||
}
|
||||
|
||||
r, ok := resp.Result.([]interface{})
|
||||
if !ok {
|
||||
t.Fatalf("bad %#v", resp.Result)
|
||||
}
|
||||
|
||||
if len(r) != 1 {
|
||||
t.Errorf("%d != 1", len(r))
|
||||
}
|
||||
if r[0] != "test_cap" {
|
||||
t.Errorf("%s != test_cap", r[0])
|
||||
}
|
||||
}
|
||||
|
||||
func TestCapabilities_HostCapabilities(t *testing.T) {
|
||||
client, server := plugin.TestPluginGRPCConn(t, map[string]plugin.Plugin{
|
||||
"caps": &vplugin.HostCapabilitiesPlugin{Impl: &vplugin.MockHostCapabilities{}}})
|
||||
defer server.Stop()
|
||||
defer client.Close()
|
||||
|
||||
raw, err := client.Dispense("caps")
|
||||
if err != nil {
|
||||
t.Fatalf("err: %s", err)
|
||||
}
|
||||
impl, ok := raw.(vplugin.HostCapabilities)
|
||||
if !ok {
|
||||
t.Fatalf("bad %#v", raw)
|
||||
}
|
||||
|
||||
p := &vplugin.RemoteHostCapabilities{
|
||||
HostCapabilities: impl}
|
||||
Plugins = vplugin.VagrantPluginInit()
|
||||
Plugins.PluginLookup = func(_, _ string) (r interface{}, err error) {
|
||||
r = p
|
||||
return
|
||||
}
|
||||
|
||||
result := HostCapabilities(nil, nil)
|
||||
resp, err := LoadResponse(result)
|
||||
if err != nil {
|
||||
t.Fatalf("err: %s", err)
|
||||
}
|
||||
caps, ok := resp.Result.([]interface{})
|
||||
if !ok {
|
||||
t.Fatalf("bad %#v", resp.Result)
|
||||
}
|
||||
|
||||
cap, ok := caps[0].(map[string]interface{})
|
||||
if !ok {
|
||||
t.Fatalf("bad %#v", caps[0])
|
||||
}
|
||||
|
||||
if cap["name"] != "test_cap" {
|
||||
t.Errorf("%s != test_cap", cap["name"])
|
||||
}
|
||||
if cap["platform"] != "testOS" {
|
||||
t.Errorf("%s != testOS", cap["platform"])
|
||||
}
|
||||
}
|
||||
|
||||
func TestCapabilities_HostCapability(t *testing.T) {
|
||||
client, server := plugin.TestPluginGRPCConn(t, map[string]plugin.Plugin{
|
||||
"caps": &vplugin.HostCapabilitiesPlugin{Impl: &vplugin.MockHostCapabilities{}}})
|
||||
defer server.Stop()
|
||||
defer client.Close()
|
||||
|
||||
raw, err := client.Dispense("caps")
|
||||
if err != nil {
|
||||
t.Fatalf("err: %s", err)
|
||||
}
|
||||
impl, ok := raw.(vplugin.HostCapabilities)
|
||||
if !ok {
|
||||
t.Fatalf("bad %#v", raw)
|
||||
}
|
||||
|
||||
p := &vplugin.RemoteHostCapabilities{
|
||||
HostCapabilities: impl}
|
||||
Plugins = vplugin.VagrantPluginInit()
|
||||
Plugins.PluginLookup = func(_, _ string) (r interface{}, err error) {
|
||||
r = p
|
||||
return
|
||||
}
|
||||
|
||||
a, err := json.Marshal([]string{"test_arg", "other_arg"})
|
||||
if err != nil {
|
||||
t.Fatalf("err: %s", err)
|
||||
}
|
||||
args := string(a)
|
||||
result := HostCapability(nil, nil, to_cs("test_cap"), to_cs("test_platform"), to_cs(args), to_cs("{}"))
|
||||
resp, err := LoadResponse(result)
|
||||
if err != nil {
|
||||
t.Fatalf("err: %s", err)
|
||||
}
|
||||
|
||||
r, ok := resp.Result.([]interface{})
|
||||
if !ok {
|
||||
t.Fatalf("bad %#v", resp.Result)
|
||||
}
|
||||
|
||||
if r[0] != "test_cap" {
|
||||
t.Errorf("%s != test_cap", r[0])
|
||||
}
|
||||
if r[1] != "test_arg" {
|
||||
t.Errorf("%s != test_arg", r[1])
|
||||
}
|
||||
}
|
||||
|
||||
func TestCapabilities_HostCapability_noargs(t *testing.T) {
|
||||
client, server := plugin.TestPluginGRPCConn(t, map[string]plugin.Plugin{
|
||||
"caps": &vplugin.HostCapabilitiesPlugin{Impl: &vplugin.MockHostCapabilities{}}})
|
||||
defer server.Stop()
|
||||
defer client.Close()
|
||||
|
||||
raw, err := client.Dispense("caps")
|
||||
if err != nil {
|
||||
t.Fatalf("err: %s", err)
|
||||
}
|
||||
impl, ok := raw.(vplugin.HostCapabilities)
|
||||
if !ok {
|
||||
t.Fatalf("bad %#v", raw)
|
||||
}
|
||||
|
||||
p := &vplugin.RemoteHostCapabilities{
|
||||
HostCapabilities: impl}
|
||||
Plugins = vplugin.VagrantPluginInit()
|
||||
Plugins.PluginLookup = func(_, _ string) (r interface{}, err error) {
|
||||
r = p
|
||||
return
|
||||
}
|
||||
|
||||
result := HostCapability(nil, nil, to_cs("test_cap"), to_cs("test_platform"), to_cs("null"), to_cs("{}"))
|
||||
resp, err := LoadResponse(result)
|
||||
if err != nil {
|
||||
t.Fatalf("err: %s - %s", err, to_gs(result))
|
||||
}
|
||||
|
||||
r, ok := resp.Result.([]interface{})
|
||||
if !ok {
|
||||
t.Fatalf("bad %#v", resp.Result)
|
||||
}
|
||||
|
||||
if len(r) != 1 {
|
||||
t.Errorf("%d != 1", len(r))
|
||||
}
|
||||
if r[0] != "test_cap" {
|
||||
t.Errorf("%s != test_cap", r[0])
|
||||
}
|
||||
}
|
||||
|
||||
func TestCapabilities_ProviderCapabilities(t *testing.T) {
|
||||
client, server := plugin.TestPluginGRPCConn(t, map[string]plugin.Plugin{
|
||||
"caps": &vplugin.ProviderCapabilitiesPlugin{Impl: &vplugin.MockProviderCapabilities{}}})
|
||||
defer server.Stop()
|
||||
defer client.Close()
|
||||
|
||||
raw, err := client.Dispense("caps")
|
||||
if err != nil {
|
||||
t.Fatalf("err: %s", err)
|
||||
}
|
||||
impl, ok := raw.(vplugin.ProviderCapabilities)
|
||||
if !ok {
|
||||
t.Fatalf("bad %#v", raw)
|
||||
}
|
||||
|
||||
p := &vplugin.RemoteProviderCapabilities{
|
||||
ProviderCapabilities: impl}
|
||||
Plugins = vplugin.VagrantPluginInit()
|
||||
Plugins.PluginLookup = func(_, _ string) (r interface{}, err error) {
|
||||
r = p
|
||||
return
|
||||
}
|
||||
|
||||
result := ProviderCapabilities(nil, nil)
|
||||
resp, err := LoadResponse(result)
|
||||
if err != nil {
|
||||
t.Fatalf("err: %s", err)
|
||||
}
|
||||
caps, ok := resp.Result.([]interface{})
|
||||
if !ok {
|
||||
t.Fatalf("bad %#v", resp.Result)
|
||||
}
|
||||
|
||||
cap, ok := caps[0].(map[string]interface{})
|
||||
if !ok {
|
||||
t.Fatalf("bad %#v", caps[0])
|
||||
}
|
||||
|
||||
if cap["name"] != "test_cap" {
|
||||
t.Errorf("%s != test_cap", cap["name"])
|
||||
}
|
||||
if cap["provider"] != "testProvider" {
|
||||
t.Errorf("%s != testProvider", cap["provider"])
|
||||
}
|
||||
}
|
||||
|
||||
func TestCapabilities_ProviderCapability(t *testing.T) {
|
||||
client, server := plugin.TestPluginGRPCConn(t, map[string]plugin.Plugin{
|
||||
"caps": &vplugin.ProviderCapabilitiesPlugin{Impl: &vplugin.MockProviderCapabilities{}}})
|
||||
defer server.Stop()
|
||||
defer client.Close()
|
||||
|
||||
raw, err := client.Dispense("caps")
|
||||
if err != nil {
|
||||
t.Fatalf("err: %s", err)
|
||||
}
|
||||
impl, ok := raw.(vplugin.ProviderCapabilities)
|
||||
if !ok {
|
||||
t.Fatalf("bad %#v", raw)
|
||||
}
|
||||
|
||||
p := &vplugin.RemoteProviderCapabilities{
|
||||
ProviderCapabilities: impl}
|
||||
Plugins = vplugin.VagrantPluginInit()
|
||||
Plugins.PluginLookup = func(_, _ string) (r interface{}, err error) {
|
||||
r = p
|
||||
return
|
||||
}
|
||||
|
||||
a, err := json.Marshal([]string{"test_arg", "other_arg"})
|
||||
if err != nil {
|
||||
t.Fatalf("err: %s", err)
|
||||
}
|
||||
args := string(a)
|
||||
result := ProviderCapability(nil, nil, to_cs("test_cap"), to_cs("test_provider"), to_cs(args), to_cs("{}"))
|
||||
resp, err := LoadResponse(result)
|
||||
if err != nil {
|
||||
t.Fatalf("err: %s", err)
|
||||
}
|
||||
|
||||
r, ok := resp.Result.([]interface{})
|
||||
if !ok {
|
||||
t.Fatalf("bad %#v", resp.Result)
|
||||
}
|
||||
|
||||
if r[0] != "test_cap" {
|
||||
t.Errorf("%s != test_cap", r[0])
|
||||
}
|
||||
if r[1] != "test_arg" {
|
||||
t.Errorf("%s != test_arg", r[1])
|
||||
}
|
||||
}
|
||||
|
||||
func TestCapabilities_ProviderCapability_noargs(t *testing.T) {
|
||||
client, server := plugin.TestPluginGRPCConn(t, map[string]plugin.Plugin{
|
||||
"caps": &vplugin.ProviderCapabilitiesPlugin{Impl: &vplugin.MockProviderCapabilities{}}})
|
||||
defer server.Stop()
|
||||
defer client.Close()
|
||||
|
||||
raw, err := client.Dispense("caps")
|
||||
if err != nil {
|
||||
t.Fatalf("err: %s", err)
|
||||
}
|
||||
impl, ok := raw.(vplugin.ProviderCapabilities)
|
||||
if !ok {
|
||||
t.Fatalf("bad %#v", raw)
|
||||
}
|
||||
|
||||
p := &vplugin.RemoteProviderCapabilities{
|
||||
ProviderCapabilities: impl}
|
||||
Plugins = vplugin.VagrantPluginInit()
|
||||
Plugins.PluginLookup = func(_, _ string) (r interface{}, err error) {
|
||||
r = p
|
||||
return
|
||||
}
|
||||
|
||||
result := ProviderCapability(nil, nil, to_cs("test_cap"), to_cs("test_provider"), to_cs("null"), to_cs("{}"))
|
||||
resp, err := LoadResponse(result)
|
||||
if err != nil {
|
||||
t.Fatalf("err: %s - %s", err, to_gs(result))
|
||||
}
|
||||
|
||||
r, ok := resp.Result.([]interface{})
|
||||
if !ok {
|
||||
t.Fatalf("bad %#v", resp.Result)
|
||||
}
|
||||
|
||||
if len(r) != 1 {
|
||||
t.Errorf("%d != 1", len(r))
|
||||
}
|
||||
if r[0] != "test_cap" {
|
||||
t.Errorf("%s != test_cap", r[0])
|
||||
}
|
||||
}
|
|
@ -4,7 +4,6 @@ import (
|
|||
"C"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
|
||||
"github.com/hashicorp/vagrant/ext/go-plugin/vagrant"
|
||||
"github.com/hashicorp/vagrant/ext/go-plugin/vagrant/plugin"
|
||||
|
@ -12,87 +11,87 @@ import (
|
|||
|
||||
//export ConfigLoad
|
||||
func ConfigLoad(pluginName, pluginType, data *C.char) *C.char {
|
||||
r := vagrant.Response{}
|
||||
p, err := getConfigPlugin(pluginName, pluginType)
|
||||
r := &Response{}
|
||||
i, err := Plugins.PluginLookup(to_gs(pluginName), to_gs(pluginType))
|
||||
if err != nil {
|
||||
r.Error = err
|
||||
return C.CString(r.Dump())
|
||||
return r.Dump()
|
||||
}
|
||||
p, ok := i.(*plugin.RemoteConfig)
|
||||
if !ok {
|
||||
r.Error = errors.New("failed to load requested plugin")
|
||||
return r.Dump()
|
||||
}
|
||||
var cdata map[string]interface{}
|
||||
r.Error = json.Unmarshal([]byte(C.GoString(data)), &cdata)
|
||||
r.Error = json.Unmarshal([]byte(to_gs(data)), &cdata)
|
||||
if r.Error != nil {
|
||||
return C.CString(r.Dump())
|
||||
return r.Dump()
|
||||
}
|
||||
r.Result, r.Error = p.Config.ConfigLoad(cdata)
|
||||
return C.CString(r.Dump())
|
||||
return r.Dump()
|
||||
}
|
||||
|
||||
//export ConfigAttributes
|
||||
func ConfigAttributes(pluginName, pluginType *C.char) *C.char {
|
||||
r := vagrant.Response{}
|
||||
p, err := getConfigPlugin(pluginName, pluginType)
|
||||
r := &Response{}
|
||||
i, err := Plugins.PluginLookup(to_gs(pluginName), to_gs(pluginType))
|
||||
if err != nil {
|
||||
r.Error = err
|
||||
return C.CString(r.Dump())
|
||||
return r.Dump()
|
||||
}
|
||||
p, ok := i.(*plugin.RemoteConfig)
|
||||
if !ok {
|
||||
r.Error = errors.New("failed to load requested plugin")
|
||||
return r.Dump()
|
||||
}
|
||||
r.Result, r.Error = p.Config.ConfigAttributes()
|
||||
return C.CString(r.Dump())
|
||||
return r.Dump()
|
||||
}
|
||||
|
||||
//export ConfigValidate
|
||||
func ConfigValidate(pluginName, pluginType, data, machData *C.char) *C.char {
|
||||
var m *vagrant.Machine
|
||||
r := vagrant.Response{}
|
||||
p, err := getConfigPlugin(pluginName, pluginType)
|
||||
r := &Response{}
|
||||
i, err := Plugins.PluginLookup(to_gs(pluginName), to_gs(pluginType))
|
||||
if err != nil {
|
||||
r.Error = err
|
||||
return C.CString(r.Dump())
|
||||
return r.Dump()
|
||||
}
|
||||
p, ok := i.(*plugin.RemoteConfig)
|
||||
if !ok {
|
||||
r.Error = errors.New("failed to load requested plugin")
|
||||
return r.Dump()
|
||||
}
|
||||
var cdata map[string]interface{}
|
||||
r.Error = json.Unmarshal([]byte(C.GoString(data)), &cdata)
|
||||
r.Error = json.Unmarshal([]byte(to_gs(data)), &cdata)
|
||||
if r.Error != nil {
|
||||
return C.CString(r.Dump())
|
||||
return r.Dump()
|
||||
}
|
||||
m, r.Error = vagrant.LoadMachine(C.GoString(machData), nil)
|
||||
m, r.Error = vagrant.LoadMachine(to_gs(machData), nil)
|
||||
if r.Error != nil {
|
||||
return C.CString(r.Dump())
|
||||
return r.Dump()
|
||||
}
|
||||
r.Result, r.Error = p.Config.ConfigValidate(cdata, m)
|
||||
return C.CString(r.Dump())
|
||||
return r.Dump()
|
||||
}
|
||||
|
||||
//export ConfigFinalize
|
||||
func ConfigFinalize(pluginName, pluginType, data *C.char) *C.char {
|
||||
r := vagrant.Response{}
|
||||
p, err := getConfigPlugin(pluginName, pluginType)
|
||||
r := &Response{}
|
||||
i, err := Plugins.PluginLookup(to_gs(pluginName), to_gs(pluginType))
|
||||
if err != nil {
|
||||
r.Error = err
|
||||
return C.CString(r.Dump())
|
||||
return r.Dump()
|
||||
}
|
||||
p, ok := i.(*plugin.RemoteConfig)
|
||||
if !ok {
|
||||
r.Error = errors.New("failed to load requested plugin")
|
||||
return r.Dump()
|
||||
}
|
||||
var cdata map[string]interface{}
|
||||
r.Error = json.Unmarshal([]byte(C.GoString(data)), &cdata)
|
||||
r.Error = json.Unmarshal([]byte(to_gs(data)), &cdata)
|
||||
if r.Error == nil {
|
||||
println("FINALIZE HAS VALID CONFIG")
|
||||
r.Result, r.Error = p.Config.ConfigFinalize(cdata)
|
||||
}
|
||||
fmt.Printf("Full result: %s\n", r.Dump())
|
||||
return C.CString(r.Dump())
|
||||
}
|
||||
|
||||
func getConfigPlugin(pluginName, pluginType *C.char) (c *plugin.RemoteConfig, err error) {
|
||||
pname := C.GoString(pluginName)
|
||||
ptype := C.GoString(pluginType)
|
||||
|
||||
if ptype == "provider" {
|
||||
p, ok := Plugins.Providers[pname]
|
||||
if ok {
|
||||
c = &plugin.RemoteConfig{
|
||||
Client: p.Client,
|
||||
Config: p.Provider}
|
||||
}
|
||||
}
|
||||
if c == nil {
|
||||
err = errors.New("Failed to locate requested plugin")
|
||||
}
|
||||
return
|
||||
return r.Dump()
|
||||
}
|
||||
|
|
|
@ -0,0 +1,203 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"testing"
|
||||
|
||||
"github.com/hashicorp/go-plugin"
|
||||
vplugin "github.com/hashicorp/vagrant/ext/go-plugin/vagrant/plugin"
|
||||
)
|
||||
|
||||
func TestConfig_Load(t *testing.T) {
|
||||
client, server := plugin.TestPluginGRPCConn(t, map[string]plugin.Plugin{
|
||||
"config": &vplugin.ConfigPlugin{Impl: &vplugin.MockConfig{}}})
|
||||
defer server.Stop()
|
||||
defer client.Close()
|
||||
|
||||
raw, err := client.Dispense("config")
|
||||
if err != nil {
|
||||
t.Fatalf("err: %s", err)
|
||||
}
|
||||
impl, ok := raw.(vplugin.Config)
|
||||
if !ok {
|
||||
t.Fatalf("bad %#v", raw)
|
||||
}
|
||||
|
||||
p := &vplugin.RemoteConfig{
|
||||
Config: impl}
|
||||
Plugins = vplugin.VagrantPluginInit()
|
||||
Plugins.PluginLookup = func(_, _ string) (r interface{}, err error) {
|
||||
r = p
|
||||
return
|
||||
}
|
||||
|
||||
data := map[string]string{"test_key": "custom_val"}
|
||||
s, err := json.Marshal(data)
|
||||
if err != nil {
|
||||
t.Fatalf("err: %s", err)
|
||||
}
|
||||
|
||||
result := ConfigLoad(nil, nil, to_cs(string(s)))
|
||||
resp, err := LoadResponse(result)
|
||||
if err != nil {
|
||||
t.Fatalf("err: %s", err)
|
||||
}
|
||||
if resp.Error != nil {
|
||||
t.Fatalf("err: %s", resp.Error)
|
||||
}
|
||||
config, ok := resp.Result.(map[string]interface{})
|
||||
if !ok {
|
||||
t.Fatalf("bad %#v", resp.Result)
|
||||
}
|
||||
|
||||
if config["test_key"] != "test_val" {
|
||||
t.Errorf("%s != test_val", config["test_key"])
|
||||
}
|
||||
if config["sent_key"] != "custom_val" {
|
||||
t.Errorf("%s != custom_val", config["sent_key"])
|
||||
}
|
||||
}
|
||||
|
||||
func TestConfig_Attributes(t *testing.T) {
|
||||
client, server := plugin.TestPluginGRPCConn(t, map[string]plugin.Plugin{
|
||||
"config": &vplugin.ConfigPlugin{Impl: &vplugin.MockConfig{}}})
|
||||
defer server.Stop()
|
||||
defer client.Close()
|
||||
|
||||
raw, err := client.Dispense("config")
|
||||
if err != nil {
|
||||
t.Fatalf("err: %s", err)
|
||||
}
|
||||
impl, ok := raw.(vplugin.Config)
|
||||
if !ok {
|
||||
t.Fatalf("bad %#v", raw)
|
||||
}
|
||||
|
||||
p := &vplugin.RemoteConfig{
|
||||
Config: impl}
|
||||
Plugins = vplugin.VagrantPluginInit()
|
||||
Plugins.PluginLookup = func(_, _ string) (r interface{}, err error) {
|
||||
r = p
|
||||
return
|
||||
}
|
||||
|
||||
result := ConfigAttributes(nil, nil)
|
||||
resp, err := LoadResponse(result)
|
||||
if err != nil {
|
||||
t.Fatalf("err: %s", err)
|
||||
}
|
||||
if resp.Error != nil {
|
||||
t.Fatalf("err: %s", resp.Error)
|
||||
}
|
||||
attrs, ok := resp.Result.([]interface{})
|
||||
if !ok {
|
||||
t.Fatalf("bad %#v", resp.Result)
|
||||
}
|
||||
|
||||
if len(attrs) != 2 {
|
||||
t.Fatalf("%d != 2", len(attrs))
|
||||
}
|
||||
if attrs[0] != "fubar" {
|
||||
t.Errorf("%s != fubar", attrs[0])
|
||||
}
|
||||
if attrs[1] != "foobar" {
|
||||
t.Errorf("%s != foobar", attrs[1])
|
||||
}
|
||||
}
|
||||
|
||||
func TestConfig_Validate(t *testing.T) {
|
||||
client, server := plugin.TestPluginGRPCConn(t, map[string]plugin.Plugin{
|
||||
"config": &vplugin.ConfigPlugin{Impl: &vplugin.MockConfig{}}})
|
||||
defer server.Stop()
|
||||
defer client.Close()
|
||||
|
||||
raw, err := client.Dispense("config")
|
||||
if err != nil {
|
||||
t.Fatalf("err: %s", err)
|
||||
}
|
||||
impl, ok := raw.(vplugin.Config)
|
||||
if !ok {
|
||||
t.Fatalf("bad %#v", raw)
|
||||
}
|
||||
|
||||
p := &vplugin.RemoteConfig{
|
||||
Config: impl}
|
||||
Plugins = vplugin.VagrantPluginInit()
|
||||
Plugins.PluginLookup = func(_, _ string) (r interface{}, err error) {
|
||||
r = p
|
||||
return
|
||||
}
|
||||
|
||||
data := map[string]string{"test_key": "custom_val"}
|
||||
s, err := json.Marshal(data)
|
||||
if err != nil {
|
||||
t.Fatalf("err: %s", err)
|
||||
}
|
||||
|
||||
result := ConfigValidate(nil, nil, to_cs(string(s)), to_cs("{}"))
|
||||
resp, err := LoadResponse(result)
|
||||
if err != nil {
|
||||
t.Fatalf("err: %s", err)
|
||||
}
|
||||
if resp.Error != nil {
|
||||
t.Fatalf("err: %s", resp.Error)
|
||||
}
|
||||
errs, ok := resp.Result.([]interface{})
|
||||
if !ok {
|
||||
t.Fatalf("bad %#v", resp.Result)
|
||||
}
|
||||
|
||||
if len(errs) != 1 {
|
||||
t.Fatalf("%d != 1", len(errs))
|
||||
}
|
||||
if errs[0] != "test error" {
|
||||
t.Errorf("%s != test error", errs[0])
|
||||
}
|
||||
}
|
||||
|
||||
func TestConfig_Finalize(t *testing.T) {
|
||||
client, server := plugin.TestPluginGRPCConn(t, map[string]plugin.Plugin{
|
||||
"config": &vplugin.ConfigPlugin{Impl: &vplugin.MockConfig{}}})
|
||||
defer server.Stop()
|
||||
defer client.Close()
|
||||
|
||||
raw, err := client.Dispense("config")
|
||||
if err != nil {
|
||||
t.Fatalf("err: %s", err)
|
||||
}
|
||||
impl, ok := raw.(vplugin.Config)
|
||||
if !ok {
|
||||
t.Fatalf("bad %#v", raw)
|
||||
}
|
||||
|
||||
p := &vplugin.RemoteConfig{
|
||||
Config: impl}
|
||||
Plugins = vplugin.VagrantPluginInit()
|
||||
Plugins.PluginLookup = func(_, _ string) (r interface{}, err error) {
|
||||
r = p
|
||||
return
|
||||
}
|
||||
|
||||
data := map[string]string{"test_key": "custom_val"}
|
||||
s, err := json.Marshal(data)
|
||||
if err != nil {
|
||||
t.Fatalf("err: %s", err)
|
||||
}
|
||||
|
||||
result := ConfigFinalize(nil, nil, to_cs(string(s)))
|
||||
resp, err := LoadResponse(result)
|
||||
if err != nil {
|
||||
t.Fatalf("err: %s", err)
|
||||
}
|
||||
if resp.Error != nil {
|
||||
t.Fatalf("err: %s", resp.Error)
|
||||
}
|
||||
config, ok := resp.Result.(map[string]interface{})
|
||||
if !ok {
|
||||
t.Fatalf("bad %#v", resp.Result)
|
||||
}
|
||||
|
||||
if config["test_key"] != "custom_val-updated" {
|
||||
t.Errorf("%s != custom_val-updated", config["test_key"])
|
||||
}
|
||||
}
|
|
@ -14,7 +14,7 @@ var Plugins *plugin.VagrantPlugin
|
|||
|
||||
//export Setup
|
||||
func Setup(enableLogger, timestamps bool, logLevel *C.char) bool {
|
||||
lvl := C.GoString(logLevel)
|
||||
lvl := to_gs(logLevel)
|
||||
lopts := &hclog.LoggerOptions{Name: "vagrant"}
|
||||
if enableLogger {
|
||||
lopts.Output = os.Stderr
|
||||
|
@ -32,10 +32,7 @@ func Setup(enableLogger, timestamps bool, logLevel *C.char) bool {
|
|||
return false
|
||||
}
|
||||
|
||||
Plugins = &plugin.VagrantPlugin{
|
||||
PluginDirectories: []string{},
|
||||
Providers: map[string]*plugin.RemoteProvider{},
|
||||
Logger: vagrant.DefaultLogger().Named("go-plugin")}
|
||||
Plugins = plugin.VagrantPluginInit()
|
||||
return true
|
||||
}
|
||||
|
||||
|
@ -46,7 +43,7 @@ func LoadPlugins(plgpath *C.char) bool {
|
|||
return false
|
||||
}
|
||||
|
||||
p := C.GoString(plgpath)
|
||||
p := to_gs(plgpath)
|
||||
err := Plugins.LoadPlugins(p)
|
||||
if err != nil {
|
||||
Plugins.Logger.Error("failed loading plugins",
|
||||
|
@ -86,3 +83,13 @@ func Teardown() {
|
|||
|
||||
// stub required for build
|
||||
func main() {}
|
||||
|
||||
// helper to convert c string to go string
|
||||
func to_gs(s *C.char) string {
|
||||
return C.GoString(s)
|
||||
}
|
||||
|
||||
// helper to convert go string to c string
|
||||
func to_cs(s string) *C.char {
|
||||
return C.CString(s)
|
||||
}
|
||||
|
|
|
@ -4,7 +4,6 @@ import (
|
|||
"C"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
|
||||
"github.com/hashicorp/vagrant/ext/go-plugin/vagrant"
|
||||
"github.com/hashicorp/vagrant/ext/go-plugin/vagrant/plugin"
|
||||
|
@ -13,169 +12,176 @@ import (
|
|||
//export ListProviders
|
||||
func ListProviders() *C.char {
|
||||
list := map[string]interface{}{}
|
||||
r := vagrant.Response{Result: list}
|
||||
r := &Response{Result: list}
|
||||
if Plugins == nil {
|
||||
return C.CString(r.Dump())
|
||||
return r.Dump()
|
||||
}
|
||||
for n, p := range Plugins.Providers {
|
||||
list[n] = p.Provider.Info()
|
||||
}
|
||||
r.Result = list
|
||||
return C.CString(r.Dump())
|
||||
return r.Dump()
|
||||
}
|
||||
|
||||
//export ProviderAction
|
||||
func ProviderAction(providerName *C.char, actionName *C.char, machData *C.char) *C.char {
|
||||
var p *plugin.RemoteProvider
|
||||
var m *vagrant.Machine
|
||||
|
||||
r := vagrant.Response{}
|
||||
p, r.Error = getProvider(providerName)
|
||||
if r.Error != nil {
|
||||
return C.CString(r.Dump())
|
||||
r := &Response{}
|
||||
i, err := Plugins.PluginLookup(to_gs(providerName), "provider")
|
||||
if err != nil {
|
||||
r.Error = err
|
||||
return r.Dump()
|
||||
}
|
||||
m, r.Error = vagrant.LoadMachine(C.GoString(machData), nil)
|
||||
if r.Error != nil {
|
||||
return C.CString(r.Dump())
|
||||
p, ok := i.(*plugin.RemoteProvider)
|
||||
if !ok {
|
||||
r.Error = errors.New("failed to load requested plugin")
|
||||
return r.Dump()
|
||||
}
|
||||
aName := C.GoString(actionName)
|
||||
m, err := vagrant.LoadMachine(to_gs(machData), nil)
|
||||
if err != nil {
|
||||
r.Error = err
|
||||
return r.Dump()
|
||||
}
|
||||
aName := to_gs(actionName)
|
||||
r.Result, r.Error = p.Provider.Action(aName, m)
|
||||
return C.CString(r.Dump())
|
||||
return r.Dump()
|
||||
}
|
||||
|
||||
//export ProviderIsInstalled
|
||||
func ProviderIsInstalled(providerName *C.char, machData *C.char) *C.char {
|
||||
var p *plugin.RemoteProvider
|
||||
var m *vagrant.Machine
|
||||
|
||||
r := vagrant.Response{}
|
||||
p, r.Error = getProvider(providerName)
|
||||
if r.Error != nil {
|
||||
return C.CString(r.Dump())
|
||||
r := &Response{}
|
||||
i, err := Plugins.PluginLookup(to_gs(providerName), "provider")
|
||||
if err != nil {
|
||||
r.Error = err
|
||||
return r.Dump()
|
||||
}
|
||||
m, r.Error = vagrant.LoadMachine(C.GoString(machData), nil)
|
||||
if r.Error != nil {
|
||||
return C.CString(r.Dump())
|
||||
p, ok := i.(*plugin.RemoteProvider)
|
||||
if !ok {
|
||||
r.Error = errors.New("failed to load requested plugin")
|
||||
return r.Dump()
|
||||
}
|
||||
m, err := vagrant.LoadMachine(to_gs(machData), nil)
|
||||
if err != nil {
|
||||
r.Error = err
|
||||
return r.Dump()
|
||||
}
|
||||
r.Result, r.Error = p.Provider.IsInstalled(m)
|
||||
return C.CString(r.Dump())
|
||||
return r.Dump()
|
||||
}
|
||||
|
||||
//export ProviderIsUsable
|
||||
func ProviderIsUsable(providerName *C.char, machData *C.char) *C.char {
|
||||
var p *plugin.RemoteProvider
|
||||
var m *vagrant.Machine
|
||||
|
||||
r := vagrant.Response{}
|
||||
p, r.Error = getProvider(providerName)
|
||||
if r.Error != nil {
|
||||
return C.CString(r.Dump())
|
||||
r := &Response{}
|
||||
i, err := Plugins.PluginLookup(to_gs(providerName), "provider")
|
||||
if err != nil {
|
||||
r.Error = err
|
||||
return r.Dump()
|
||||
}
|
||||
m, r.Error = vagrant.LoadMachine(C.GoString(machData), nil)
|
||||
if r.Error != nil {
|
||||
return C.CString(r.Dump())
|
||||
p, ok := i.(*plugin.RemoteProvider)
|
||||
if !ok {
|
||||
r.Error = errors.New("failed to load requested plugin")
|
||||
return r.Dump()
|
||||
}
|
||||
|
||||
m, err := vagrant.LoadMachine(to_gs(machData), nil)
|
||||
if err != nil {
|
||||
r.Error = err
|
||||
return r.Dump()
|
||||
}
|
||||
r.Result, r.Error = p.Provider.IsUsable(m)
|
||||
return C.CString(r.Dump())
|
||||
return r.Dump()
|
||||
}
|
||||
|
||||
//export ProviderMachineIdChanged
|
||||
func ProviderMachineIdChanged(providerName *C.char, machData *C.char) *C.char {
|
||||
var p *plugin.RemoteProvider
|
||||
var m *vagrant.Machine
|
||||
|
||||
r := vagrant.Response{}
|
||||
p, r.Error = getProvider(providerName)
|
||||
if r.Error != nil {
|
||||
return C.CString(r.Dump())
|
||||
r := &Response{}
|
||||
i, err := Plugins.PluginLookup(to_gs(providerName), "provider")
|
||||
if err != nil {
|
||||
r.Error = err
|
||||
return r.Dump()
|
||||
}
|
||||
m, r.Error = vagrant.LoadMachine(C.GoString(machData), nil)
|
||||
if r.Error != nil {
|
||||
return C.CString(r.Dump())
|
||||
p, ok := i.(*plugin.RemoteProvider)
|
||||
if !ok {
|
||||
r.Error = errors.New("failed to load requested plugin")
|
||||
return r.Dump()
|
||||
}
|
||||
m, err := vagrant.LoadMachine(to_gs(machData), nil)
|
||||
if err != nil {
|
||||
r.Error = err
|
||||
return r.Dump()
|
||||
}
|
||||
r.Error = p.Provider.MachineIdChanged(m)
|
||||
return C.CString(r.Dump())
|
||||
return r.Dump()
|
||||
}
|
||||
|
||||
//export ProviderRunAction
|
||||
func ProviderRunAction(providerName *C.char, actName *C.char, runData *C.char, machData *C.char) *C.char {
|
||||
var p *plugin.RemoteProvider
|
||||
var m *vagrant.Machine
|
||||
|
||||
r := vagrant.Response{}
|
||||
p, r.Error = getProvider(providerName)
|
||||
if r.Error != nil {
|
||||
return C.CString(r.Dump())
|
||||
r := &Response{}
|
||||
i, err := Plugins.PluginLookup(to_gs(providerName), "provider")
|
||||
if err != nil {
|
||||
r.Error = err
|
||||
return r.Dump()
|
||||
}
|
||||
m, r.Error = vagrant.LoadMachine(C.GoString(machData), nil)
|
||||
if r.Error != nil {
|
||||
return C.CString(r.Dump())
|
||||
p, ok := i.(*plugin.RemoteProvider)
|
||||
if !ok {
|
||||
r.Error = errors.New("failed to load requested plugin")
|
||||
return r.Dump()
|
||||
}
|
||||
m, err := vagrant.LoadMachine(to_gs(machData), nil)
|
||||
if err != nil {
|
||||
r.Error = err
|
||||
return r.Dump()
|
||||
}
|
||||
aName := to_gs(actName)
|
||||
var rData interface{}
|
||||
err = json.Unmarshal([]byte(to_gs(runData)), &rData)
|
||||
if err != nil {
|
||||
r.Error = err
|
||||
return r.Dump()
|
||||
}
|
||||
aName := C.GoString(actName)
|
||||
rData := C.GoString(runData)
|
||||
r.Result, r.Error = p.Provider.RunAction(aName, rData, m)
|
||||
return C.CString(r.Dump())
|
||||
return r.Dump()
|
||||
}
|
||||
|
||||
//export ProviderSshInfo
|
||||
func ProviderSshInfo(providerName *C.char, machData *C.char) *C.char {
|
||||
var p *plugin.RemoteProvider
|
||||
var m *vagrant.Machine
|
||||
|
||||
r := vagrant.Response{}
|
||||
p, r.Error = getProvider(providerName)
|
||||
if r.Error != nil {
|
||||
return C.CString(r.Dump())
|
||||
r := &Response{}
|
||||
i, err := Plugins.PluginLookup(to_gs(providerName), "provider")
|
||||
if err != nil {
|
||||
r.Error = err
|
||||
return r.Dump()
|
||||
}
|
||||
m, r.Error = vagrant.LoadMachine(C.GoString(machData), nil)
|
||||
if r.Error != nil {
|
||||
return C.CString(r.Dump())
|
||||
p, ok := i.(*plugin.RemoteProvider)
|
||||
if !ok {
|
||||
r.Error = errors.New("failed to load requested plugin")
|
||||
return r.Dump()
|
||||
}
|
||||
m, err := vagrant.LoadMachine(to_gs(machData), nil)
|
||||
if err != nil {
|
||||
r.Error = err
|
||||
return r.Dump()
|
||||
}
|
||||
r.Result, r.Error = p.Provider.SshInfo(m)
|
||||
return C.CString(r.Dump())
|
||||
return r.Dump()
|
||||
}
|
||||
|
||||
//export ProviderState
|
||||
func ProviderState(providerName *C.char, machData *C.char) *C.char {
|
||||
var p *plugin.RemoteProvider
|
||||
var m *vagrant.Machine
|
||||
|
||||
r := vagrant.Response{}
|
||||
p, r.Error = getProvider(providerName)
|
||||
if r.Error != nil {
|
||||
return C.CString(r.Dump())
|
||||
r := &Response{}
|
||||
i, err := Plugins.PluginLookup(to_gs(providerName), "provider")
|
||||
if err != nil {
|
||||
r.Error = err
|
||||
return r.Dump()
|
||||
}
|
||||
m, r.Error = vagrant.LoadMachine(C.GoString(machData), nil)
|
||||
if r.Error != nil {
|
||||
return C.CString(r.Dump())
|
||||
p, ok := i.(*plugin.RemoteProvider)
|
||||
if !ok {
|
||||
r.Error = errors.New("failed to load requested plugin")
|
||||
return r.Dump()
|
||||
}
|
||||
m, err := vagrant.LoadMachine(to_gs(machData), nil)
|
||||
if err != nil {
|
||||
r.Error = err
|
||||
return r.Dump()
|
||||
}
|
||||
r.Result, r.Error = p.Provider.State(m)
|
||||
return C.CString(r.Dump())
|
||||
}
|
||||
|
||||
func getProvider(pName *C.char) (*plugin.RemoteProvider, error) {
|
||||
providerName := C.GoString(pName)
|
||||
p, ok := Plugins.Providers[providerName]
|
||||
if !ok {
|
||||
Plugins.Logger.Error("error fetching plugin", "type", "provider",
|
||||
"name", providerName, "reason", "not found")
|
||||
return nil, errors.New(fmt.Sprintf(
|
||||
"failed to locate provider plugin `%s`", providerName))
|
||||
}
|
||||
return p, nil
|
||||
}
|
||||
|
||||
// Loads the machine data JSON string to ensure that it is
|
||||
// valid JSON. Returns the converted GoString to be used
|
||||
// internally
|
||||
func validateMachine(machineData *C.char) (string, error) {
|
||||
mData := C.GoString(machineData)
|
||||
Plugins.Logger.Debug("received machine info", "data", mData)
|
||||
err := json.Unmarshal([]byte(mData), &vagrant.Machine{})
|
||||
if err != nil {
|
||||
fmt.Printf("Error: %s\n", err)
|
||||
err = errors.New(fmt.Sprintf(
|
||||
"failed to load vagrant environment information - %s", err))
|
||||
}
|
||||
return mData, err
|
||||
return r.Dump()
|
||||
}
|
||||
|
|
|
@ -0,0 +1,320 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"testing"
|
||||
|
||||
"github.com/hashicorp/go-plugin"
|
||||
vplugin "github.com/hashicorp/vagrant/ext/go-plugin/vagrant/plugin"
|
||||
)
|
||||
|
||||
func TestProvider_ListProviders(t *testing.T) {
|
||||
client, server := plugin.TestPluginGRPCConn(t, map[string]plugin.Plugin{
|
||||
"provider": &vplugin.ProviderPlugin{Impl: &vplugin.MockProvider{}}})
|
||||
defer server.Stop()
|
||||
defer client.Close()
|
||||
|
||||
raw, err := client.Dispense("provider")
|
||||
if err != nil {
|
||||
t.Fatalf("err: %s", err)
|
||||
}
|
||||
impl, ok := raw.(vplugin.Provider)
|
||||
if !ok {
|
||||
t.Fatalf("bad %#v", raw)
|
||||
}
|
||||
|
||||
p := &vplugin.RemoteProvider{
|
||||
Provider: impl}
|
||||
Plugins = vplugin.VagrantPluginInit()
|
||||
Plugins.Providers[impl.Name()] = p
|
||||
|
||||
result := ListProviders()
|
||||
resp, err := LoadResponse(result)
|
||||
if err != nil {
|
||||
t.Fatalf("err: %s", err)
|
||||
}
|
||||
if resp.Error != nil {
|
||||
t.Fatalf("err: %s", err)
|
||||
}
|
||||
|
||||
r, ok := resp.Result.(map[string]interface{})
|
||||
if !ok {
|
||||
t.Fatalf("bad %#v", resp.Result)
|
||||
}
|
||||
|
||||
if r["mock_provider"] == nil {
|
||||
t.Fatalf("bad result")
|
||||
}
|
||||
|
||||
i, ok := r["mock_provider"].(map[string]interface{})
|
||||
if !ok {
|
||||
t.Fatalf("bad %#v", r["mock_provider"])
|
||||
}
|
||||
|
||||
if i["description"] != "Custom" {
|
||||
t.Errorf("%s != Custom", i["description"])
|
||||
}
|
||||
if i["priority"] != 10.0 {
|
||||
t.Errorf("%d != 10", i["priority"])
|
||||
}
|
||||
}
|
||||
|
||||
func TestProvider_ProviderAction(t *testing.T) {
|
||||
client, server := plugin.TestPluginGRPCConn(t, map[string]plugin.Plugin{
|
||||
"provider": &vplugin.ProviderPlugin{Impl: &vplugin.MockProvider{}}})
|
||||
defer server.Stop()
|
||||
defer client.Close()
|
||||
|
||||
raw, err := client.Dispense("provider")
|
||||
if err != nil {
|
||||
t.Fatalf("err: %s", err)
|
||||
}
|
||||
impl, ok := raw.(vplugin.Provider)
|
||||
if !ok {
|
||||
t.Fatalf("bad %#v", raw)
|
||||
}
|
||||
|
||||
p := &vplugin.RemoteProvider{
|
||||
Provider: impl}
|
||||
Plugins = vplugin.VagrantPluginInit()
|
||||
Plugins.PluginLookup = func(_, _ string) (r interface{}, err error) {
|
||||
r = p
|
||||
return
|
||||
}
|
||||
|
||||
result := ProviderAction(nil, to_cs("valid"), to_cs("{}"))
|
||||
resp, err := LoadResponse(result)
|
||||
if resp.Error != nil {
|
||||
t.Fatalf("err: %s", resp.Error)
|
||||
}
|
||||
r := resp.Result.([]interface{})
|
||||
if r[0] != "self::DoTask" {
|
||||
t.Errorf("%s != self::DoTask", r[0])
|
||||
}
|
||||
}
|
||||
|
||||
func TestProvider_ProviderIsInstalled(t *testing.T) {
|
||||
client, server := plugin.TestPluginGRPCConn(t, map[string]plugin.Plugin{
|
||||
"provider": &vplugin.ProviderPlugin{Impl: &vplugin.MockProvider{}}})
|
||||
defer server.Stop()
|
||||
defer client.Close()
|
||||
|
||||
raw, err := client.Dispense("provider")
|
||||
if err != nil {
|
||||
t.Fatalf("err: %s", err)
|
||||
}
|
||||
impl, ok := raw.(vplugin.Provider)
|
||||
if !ok {
|
||||
t.Fatalf("bad %#v", raw)
|
||||
}
|
||||
|
||||
p := &vplugin.RemoteProvider{
|
||||
Provider: impl}
|
||||
Plugins = vplugin.VagrantPluginInit()
|
||||
Plugins.PluginLookup = func(_, _ string) (r interface{}, err error) {
|
||||
r = p
|
||||
return
|
||||
}
|
||||
|
||||
result := ProviderIsInstalled(nil, to_cs("{}"))
|
||||
resp, err := LoadResponse(result)
|
||||
if resp.Error != nil {
|
||||
t.Fatalf("err: %s", resp.Error)
|
||||
}
|
||||
|
||||
if !resp.Result.(bool) {
|
||||
t.Errorf("bad result")
|
||||
}
|
||||
}
|
||||
|
||||
func TestProvider_ProviderIsUsable(t *testing.T) {
|
||||
client, server := plugin.TestPluginGRPCConn(t, map[string]plugin.Plugin{
|
||||
"provider": &vplugin.ProviderPlugin{Impl: &vplugin.MockProvider{}}})
|
||||
defer server.Stop()
|
||||
defer client.Close()
|
||||
|
||||
raw, err := client.Dispense("provider")
|
||||
if err != nil {
|
||||
t.Fatalf("err: %s", err)
|
||||
}
|
||||
impl, ok := raw.(vplugin.Provider)
|
||||
if !ok {
|
||||
t.Fatalf("bad %#v", raw)
|
||||
}
|
||||
|
||||
p := &vplugin.RemoteProvider{
|
||||
Provider: impl}
|
||||
Plugins = vplugin.VagrantPluginInit()
|
||||
Plugins.PluginLookup = func(_, _ string) (r interface{}, err error) {
|
||||
r = p
|
||||
return
|
||||
}
|
||||
|
||||
result := ProviderIsUsable(nil, to_cs("{}"))
|
||||
resp, err := LoadResponse(result)
|
||||
if resp.Error != nil {
|
||||
t.Fatalf("err: %s", resp.Error)
|
||||
}
|
||||
|
||||
if !resp.Result.(bool) {
|
||||
t.Errorf("bad result")
|
||||
}
|
||||
}
|
||||
|
||||
func TestProvider_ProviderMachineIdChanged(t *testing.T) {
|
||||
client, server := plugin.TestPluginGRPCConn(t, map[string]plugin.Plugin{
|
||||
"provider": &vplugin.ProviderPlugin{Impl: &vplugin.MockProvider{}}})
|
||||
defer server.Stop()
|
||||
defer client.Close()
|
||||
|
||||
raw, err := client.Dispense("provider")
|
||||
if err != nil {
|
||||
t.Fatalf("err: %s", err)
|
||||
}
|
||||
impl, ok := raw.(vplugin.Provider)
|
||||
if !ok {
|
||||
t.Fatalf("bad %#v", raw)
|
||||
}
|
||||
|
||||
p := &vplugin.RemoteProvider{
|
||||
Provider: impl}
|
||||
Plugins = vplugin.VagrantPluginInit()
|
||||
Plugins.PluginLookup = func(_, _ string) (r interface{}, err error) {
|
||||
r = p
|
||||
return
|
||||
}
|
||||
|
||||
result := ProviderMachineIdChanged(nil, to_cs("{}"))
|
||||
resp, err := LoadResponse(result)
|
||||
if resp.Error != nil {
|
||||
t.Fatalf("err: %s", resp.Error)
|
||||
}
|
||||
}
|
||||
|
||||
func TestProvider_ProviderRunAction(t *testing.T) {
|
||||
client, server := plugin.TestPluginGRPCConn(t, map[string]plugin.Plugin{
|
||||
"provider": &vplugin.ProviderPlugin{Impl: &vplugin.MockProvider{}}})
|
||||
defer server.Stop()
|
||||
defer client.Close()
|
||||
|
||||
raw, err := client.Dispense("provider")
|
||||
if err != nil {
|
||||
t.Fatalf("err: %s", err)
|
||||
}
|
||||
impl, ok := raw.(vplugin.Provider)
|
||||
if !ok {
|
||||
t.Fatalf("bad %#v", raw)
|
||||
}
|
||||
|
||||
p := &vplugin.RemoteProvider{
|
||||
Provider: impl}
|
||||
Plugins = vplugin.VagrantPluginInit()
|
||||
Plugins.PluginLookup = func(_, _ string) (r interface{}, err error) {
|
||||
r = p
|
||||
return
|
||||
}
|
||||
|
||||
a, err := json.Marshal([]string{"test_arg"})
|
||||
args := string(a)
|
||||
|
||||
result := ProviderRunAction(nil, to_cs("valid"), to_cs(args), to_cs("{}"))
|
||||
resp, err := LoadResponse(result)
|
||||
if resp.Error != nil {
|
||||
t.Fatalf("err: %s", err)
|
||||
}
|
||||
|
||||
r, ok := resp.Result.([]interface{})
|
||||
if !ok {
|
||||
t.Fatalf("bad %#v", resp.Result)
|
||||
}
|
||||
if r[0] != "valid" {
|
||||
t.Errorf("%s != valid", r[0])
|
||||
}
|
||||
if r[1] != "test_arg" {
|
||||
t.Errorf("%s != test_arg", r[1])
|
||||
}
|
||||
}
|
||||
|
||||
func TestProvider_ProviderSshInfo(t *testing.T) {
|
||||
client, server := plugin.TestPluginGRPCConn(t, map[string]plugin.Plugin{
|
||||
"provider": &vplugin.ProviderPlugin{Impl: &vplugin.MockProvider{}}})
|
||||
defer server.Stop()
|
||||
defer client.Close()
|
||||
|
||||
raw, err := client.Dispense("provider")
|
||||
if err != nil {
|
||||
t.Fatalf("err: %s", err)
|
||||
}
|
||||
impl, ok := raw.(vplugin.Provider)
|
||||
if !ok {
|
||||
t.Fatalf("bad %#v", raw)
|
||||
}
|
||||
|
||||
p := &vplugin.RemoteProvider{
|
||||
Provider: impl}
|
||||
Plugins = vplugin.VagrantPluginInit()
|
||||
Plugins.PluginLookup = func(_, _ string) (r interface{}, err error) {
|
||||
r = p
|
||||
return
|
||||
}
|
||||
|
||||
result := ProviderSshInfo(nil, to_cs("{}"))
|
||||
resp, err := LoadResponse(result)
|
||||
if resp.Error != nil {
|
||||
t.Fatalf("err: %s", err)
|
||||
}
|
||||
|
||||
r, ok := resp.Result.(map[string]interface{})
|
||||
if !ok {
|
||||
t.Fatalf("bad %#v", resp.Result)
|
||||
}
|
||||
|
||||
if r["host"] != "localhost" {
|
||||
t.Errorf("%s != localhost", r["host"])
|
||||
}
|
||||
if r["port"] != 2222.0 {
|
||||
t.Errorf("%d != 2222", r["port"])
|
||||
}
|
||||
}
|
||||
|
||||
func TestProvider_ProviderState(t *testing.T) {
|
||||
client, server := plugin.TestPluginGRPCConn(t, map[string]plugin.Plugin{
|
||||
"provider": &vplugin.ProviderPlugin{Impl: &vplugin.MockProvider{}}})
|
||||
defer server.Stop()
|
||||
defer client.Close()
|
||||
|
||||
raw, err := client.Dispense("provider")
|
||||
if err != nil {
|
||||
t.Fatalf("err: %s", err)
|
||||
}
|
||||
impl, ok := raw.(vplugin.Provider)
|
||||
if !ok {
|
||||
t.Fatalf("bad %#v", raw)
|
||||
}
|
||||
|
||||
p := &vplugin.RemoteProvider{
|
||||
Provider: impl}
|
||||
Plugins = vplugin.VagrantPluginInit()
|
||||
Plugins.PluginLookup = func(_, _ string) (r interface{}, err error) {
|
||||
r = p
|
||||
return
|
||||
}
|
||||
|
||||
result := ProviderState(nil, to_cs("{}"))
|
||||
resp, err := LoadResponse(result)
|
||||
if resp.Error != nil {
|
||||
t.Fatalf("err: %s", err)
|
||||
}
|
||||
|
||||
r, ok := resp.Result.(map[string]interface{})
|
||||
if !ok {
|
||||
t.Fatalf("bad %#v", resp.Result)
|
||||
}
|
||||
|
||||
if r["id"] != "default" {
|
||||
t.Errorf("%s != default", r["id"])
|
||||
}
|
||||
if r["short_description"] != "running" {
|
||||
t.Errorf("%s != running", r["short_description"])
|
||||
}
|
||||
}
|
|
@ -0,0 +1,48 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"C"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
)
|
||||
|
||||
type Response struct {
|
||||
Error error `json:"error"`
|
||||
Result interface{} `json:"result"`
|
||||
}
|
||||
|
||||
// Serialize the response into a JSON C string
|
||||
func (r *Response) Dump() *C.char {
|
||||
tmp := map[string]interface{}{}
|
||||
if r.Error != nil {
|
||||
tmp["error"] = r.Error.Error()
|
||||
} else {
|
||||
tmp["error"] = nil
|
||||
}
|
||||
tmp["result"] = r.Result
|
||||
result, err := json.Marshal(tmp)
|
||||
if err != nil {
|
||||
return to_cs(fmt.Sprintf(`{"error": "failed to encode response - %s"}`, err))
|
||||
}
|
||||
return to_cs(string(result[:]))
|
||||
}
|
||||
|
||||
// Load a new response from a JSON C string
|
||||
func LoadResponse(s *C.char) (r *Response, err error) {
|
||||
tmp := map[string]interface{}{}
|
||||
st := []byte(to_gs(s))
|
||||
r = &Response{}
|
||||
err = json.Unmarshal(st, &tmp)
|
||||
if tmp["error"] != nil {
|
||||
e, ok := tmp["error"].(string)
|
||||
if !ok {
|
||||
err = errors.New(
|
||||
fmt.Sprintf("cannot load error content - %s", tmp["error"]))
|
||||
return
|
||||
}
|
||||
r.Error = errors.New(e)
|
||||
}
|
||||
r.Result = tmp["result"]
|
||||
return
|
||||
}
|
|
@ -12,135 +12,135 @@ import (
|
|||
//export ListSyncedFolders
|
||||
func ListSyncedFolders() *C.char {
|
||||
list := map[string]interface{}{}
|
||||
r := vagrant.Response{Result: list}
|
||||
r := &Response{Result: list}
|
||||
if Plugins == nil {
|
||||
return C.CString(r.Dump())
|
||||
return r.Dump()
|
||||
}
|
||||
for n, p := range Plugins.SyncedFolders {
|
||||
list[n] = p.SyncedFolder.Info()
|
||||
}
|
||||
r.Result = list
|
||||
return C.CString(r.Dump())
|
||||
return r.Dump()
|
||||
}
|
||||
|
||||
//export SyncedFolderCleanup
|
||||
func SyncedFolderCleanup(pluginName, machine, opts *C.char) *C.char {
|
||||
r := vagrant.Response{}
|
||||
r := &Response{}
|
||||
p, err := getSyncedFolderPlugin(pluginName)
|
||||
if err != nil {
|
||||
r.Error = err
|
||||
return C.CString(r.Dump())
|
||||
return r.Dump()
|
||||
}
|
||||
m, err := vagrant.LoadMachine(C.GoString(machine), nil)
|
||||
if err != nil {
|
||||
r.Error = err
|
||||
return C.CString(r.Dump())
|
||||
return r.Dump()
|
||||
}
|
||||
var o vagrant.FolderOptions
|
||||
r.Error = json.Unmarshal([]byte(C.GoString(opts)), &o)
|
||||
if r.Error != nil {
|
||||
return C.CString(r.Dump())
|
||||
return r.Dump()
|
||||
}
|
||||
r.Error = p.SyncedFolder.Cleanup(m, &o)
|
||||
return C.CString(r.Dump())
|
||||
r.Error = p.SyncedFolder.Cleanup(m, o)
|
||||
return r.Dump()
|
||||
}
|
||||
|
||||
//export SyncedFolderDisable
|
||||
func SyncedFolderDisable(pluginName, machine, folders, opts *C.char) *C.char {
|
||||
r := vagrant.Response{}
|
||||
r := &Response{}
|
||||
p, err := getSyncedFolderPlugin(pluginName)
|
||||
if err != nil {
|
||||
r.Error = err
|
||||
return C.CString(r.Dump())
|
||||
return r.Dump()
|
||||
}
|
||||
m, err := vagrant.LoadMachine(C.GoString(machine), nil)
|
||||
if err != nil {
|
||||
r.Error = err
|
||||
return C.CString(r.Dump())
|
||||
return r.Dump()
|
||||
}
|
||||
var f vagrant.FolderList
|
||||
r.Error = json.Unmarshal([]byte(C.GoString(folders)), &f)
|
||||
if r.Error != nil {
|
||||
return C.CString(r.Dump())
|
||||
return r.Dump()
|
||||
}
|
||||
var o vagrant.FolderOptions
|
||||
r.Error = json.Unmarshal([]byte(C.GoString(opts)), &o)
|
||||
if r.Error != nil {
|
||||
return C.CString(r.Dump())
|
||||
return r.Dump()
|
||||
}
|
||||
r.Error = p.SyncedFolder.Disable(m, &f, &o)
|
||||
return C.CString(r.Dump())
|
||||
r.Error = p.SyncedFolder.Disable(m, f, o)
|
||||
return r.Dump()
|
||||
}
|
||||
|
||||
//export SyncedFolderEnable
|
||||
func SyncedFolderEnable(pluginName, machine, folders, opts *C.char) *C.char {
|
||||
r := vagrant.Response{}
|
||||
r := &Response{}
|
||||
p, err := getSyncedFolderPlugin(pluginName)
|
||||
if err != nil {
|
||||
r.Error = err
|
||||
return C.CString(r.Dump())
|
||||
return r.Dump()
|
||||
}
|
||||
m, err := vagrant.LoadMachine(C.GoString(machine), nil)
|
||||
if err != nil {
|
||||
r.Error = err
|
||||
return C.CString(r.Dump())
|
||||
return r.Dump()
|
||||
}
|
||||
var f vagrant.FolderList
|
||||
r.Error = json.Unmarshal([]byte(C.GoString(folders)), &f)
|
||||
if r.Error != nil {
|
||||
return C.CString(r.Dump())
|
||||
return r.Dump()
|
||||
}
|
||||
var o vagrant.FolderOptions
|
||||
r.Error = json.Unmarshal([]byte(C.GoString(opts)), &o)
|
||||
if r.Error != nil {
|
||||
return C.CString(r.Dump())
|
||||
return r.Dump()
|
||||
}
|
||||
r.Error = p.SyncedFolder.Enable(m, &f, &o)
|
||||
return C.CString(r.Dump())
|
||||
r.Error = p.SyncedFolder.Enable(m, f, o)
|
||||
return r.Dump()
|
||||
}
|
||||
|
||||
//export SyncedFolderIsUsable
|
||||
func SyncedFolderIsUsable(pluginName, machine *C.char) *C.char {
|
||||
r := vagrant.Response{}
|
||||
r := &Response{}
|
||||
p, err := getSyncedFolderPlugin(pluginName)
|
||||
if err != nil {
|
||||
r.Error = err
|
||||
return C.CString(r.Dump())
|
||||
return r.Dump()
|
||||
}
|
||||
m, err := vagrant.LoadMachine(C.GoString(machine), nil)
|
||||
if err != nil {
|
||||
r.Error = err
|
||||
return C.CString(r.Dump())
|
||||
return r.Dump()
|
||||
}
|
||||
r.Result, r.Error = p.SyncedFolder.IsUsable(m)
|
||||
return C.CString(r.Dump())
|
||||
return r.Dump()
|
||||
}
|
||||
|
||||
//export SyncedFolderPrepare
|
||||
func SyncedFolderPrepare(pluginName, machine, folders, opts *C.char) *C.char {
|
||||
r := vagrant.Response{}
|
||||
r := &Response{}
|
||||
p, err := getSyncedFolderPlugin(pluginName)
|
||||
if err != nil {
|
||||
r.Error = err
|
||||
return C.CString(r.Dump())
|
||||
return r.Dump()
|
||||
}
|
||||
m, err := vagrant.LoadMachine(C.GoString(machine), nil)
|
||||
if err != nil {
|
||||
r.Error = err
|
||||
return C.CString(r.Dump())
|
||||
return r.Dump()
|
||||
}
|
||||
var f vagrant.FolderList
|
||||
r.Error = json.Unmarshal([]byte(C.GoString(folders)), &f)
|
||||
if r.Error != nil {
|
||||
return C.CString(r.Dump())
|
||||
return r.Dump()
|
||||
}
|
||||
var o vagrant.FolderOptions
|
||||
r.Error = json.Unmarshal([]byte(C.GoString(opts)), &o)
|
||||
if r.Error != nil {
|
||||
return C.CString(r.Dump())
|
||||
return r.Dump()
|
||||
}
|
||||
r.Error = p.SyncedFolder.Prepare(m, &f, &o)
|
||||
return C.CString(r.Dump())
|
||||
r.Error = p.SyncedFolder.Prepare(m, f, o)
|
||||
return r.Dump()
|
||||
}
|
||||
|
||||
func getSyncedFolderPlugin(pluginName *C.char) (c *plugin.RemoteSyncedFolder, err error) {
|
||||
|
|
|
@ -7,7 +7,7 @@ type SystemCapability struct {
|
|||
|
||||
type ProviderCapability struct {
|
||||
Name string `json:"name"`
|
||||
Provider string `json:"name"`
|
||||
Provider string `json:"provider"`
|
||||
}
|
||||
|
||||
type GuestCapabilities interface {
|
||||
|
|
|
@ -6,3 +6,10 @@ type Config interface {
|
|||
ConfigValidate(data map[string]interface{}, m *Machine) (errors []string, err error)
|
||||
ConfigFinalize(data map[string]interface{}) (finaldata map[string]interface{}, err error)
|
||||
}
|
||||
|
||||
type NoConfig struct{}
|
||||
|
||||
func (c *NoConfig) ConfigAttributes() (a []string, e error) { return }
|
||||
func (c *NoConfig) ConfigLoad(map[string]interface{}) (d map[string]interface{}, e error) { return }
|
||||
func (c *NoConfig) ConfigValidate(map[string]interface{}, *Machine) (es []string, e error) { return }
|
||||
func (c *NoConfig) ConfigFinalize(map[string]interface{}) (f map[string]interface{}, e error) { return }
|
||||
|
|
|
@ -2,6 +2,7 @@ package plugin
|
|||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"os"
|
||||
"os/exec"
|
||||
|
||||
|
@ -11,6 +12,13 @@ import (
|
|||
"github.com/hashicorp/vagrant/ext/go-plugin/vagrant"
|
||||
)
|
||||
|
||||
var (
|
||||
Handshake = go_plugin.HandshakeConfig{
|
||||
MagicCookieKey: "VAGRANT_PLUGIN_MAGIC_COOKIE",
|
||||
MagicCookieValue: "1561a662a76642f98df77ad025aa13a9b16225d93f90475e91090fbe577317ed",
|
||||
ProtocolVersion: 1}
|
||||
)
|
||||
|
||||
type RemoteConfig struct {
|
||||
Client *go_plugin.Client
|
||||
Config vagrant.Config
|
||||
|
@ -45,9 +53,36 @@ type VagrantPlugin struct {
|
|||
Providers map[string]*RemoteProvider
|
||||
SyncedFolders map[string]*RemoteSyncedFolder
|
||||
PluginDirectories []string
|
||||
PluginLookup func(name, kind string) (p interface{}, err error)
|
||||
Logger hclog.Logger
|
||||
}
|
||||
|
||||
func VagrantPluginInit() *VagrantPlugin {
|
||||
v := &VagrantPlugin{
|
||||
PluginDirectories: []string{},
|
||||
Providers: map[string]*RemoteProvider{},
|
||||
SyncedFolders: map[string]*RemoteSyncedFolder{},
|
||||
Logger: vagrant.DefaultLogger().Named("go-plugin")}
|
||||
v.PluginLookup = v.DefaultPluginLookup
|
||||
return v
|
||||
}
|
||||
|
||||
func (v *VagrantPlugin) DefaultPluginLookup(name, kind string) (p interface{}, err error) {
|
||||
switch kind {
|
||||
case "provider":
|
||||
p = v.Providers[name]
|
||||
case "synced_folder":
|
||||
p = v.SyncedFolders[name]
|
||||
default:
|
||||
err = errors.New("invalid plugin type")
|
||||
return
|
||||
}
|
||||
if p == nil {
|
||||
err = errors.New(fmt.Sprintf("Failed to locate %s plugin of type %s", name, kind))
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func (v *VagrantPlugin) LoadPlugins(pluginPath string) error {
|
||||
for _, p := range v.PluginDirectories {
|
||||
if p == pluginPath {
|
||||
|
@ -78,12 +113,8 @@ func (v *VagrantPlugin) LoadProviders(pluginPath string) error {
|
|||
client := go_plugin.NewClient(&go_plugin.ClientConfig{
|
||||
AllowedProtocols: []go_plugin.Protocol{go_plugin.ProtocolGRPC},
|
||||
Logger: v.Logger,
|
||||
HandshakeConfig: go_plugin.HandshakeConfig{
|
||||
MagicCookieKey: "BASIC_PLUGIN",
|
||||
MagicCookieValue: "hello",
|
||||
ProtocolVersion: 1,
|
||||
},
|
||||
Cmd: exec.Command(providerPath),
|
||||
HandshakeConfig: Handshake,
|
||||
Cmd: exec.Command(providerPath),
|
||||
VersionedPlugins: map[int]go_plugin.PluginSet{
|
||||
2: {"provider": &ProviderPlugin{}}}})
|
||||
gclient, err := client.Client()
|
||||
|
@ -121,12 +152,8 @@ func (v *VagrantPlugin) LoadSyncedFolders(pluginPath string) error {
|
|||
client := go_plugin.NewClient(&go_plugin.ClientConfig{
|
||||
AllowedProtocols: []go_plugin.Protocol{go_plugin.ProtocolGRPC},
|
||||
Logger: v.Logger,
|
||||
HandshakeConfig: go_plugin.HandshakeConfig{
|
||||
MagicCookieKey: "BASIC_PLUGIN",
|
||||
MagicCookieValue: "hello",
|
||||
ProtocolVersion: 1,
|
||||
},
|
||||
Cmd: exec.Command(folderPath),
|
||||
HandshakeConfig: Handshake,
|
||||
Cmd: exec.Command(folderPath),
|
||||
VersionedPlugins: map[int]go_plugin.PluginSet{
|
||||
2: {"synced_folders": &SyncedFolderPlugin{}}}})
|
||||
gclient, err := client.Client()
|
||||
|
|
|
@ -5,6 +5,8 @@ import (
|
|||
"encoding/json"
|
||||
"errors"
|
||||
|
||||
"google.golang.org/grpc"
|
||||
|
||||
go_plugin "github.com/hashicorp/go-plugin"
|
||||
"github.com/hashicorp/vagrant/ext/go-plugin/vagrant"
|
||||
"github.com/hashicorp/vagrant/ext/go-plugin/vagrant/plugin/proto/vagrant_caps"
|
||||
|
@ -21,6 +23,23 @@ type GuestCapabilitiesPlugin struct {
|
|||
Impl GuestCapabilities
|
||||
}
|
||||
|
||||
func (g *GuestCapabilitiesPlugin) GRPCServer(broker *go_plugin.GRPCBroker, s *grpc.Server) error {
|
||||
g.Impl.Init()
|
||||
vagrant_caps.RegisterGuestCapabilitiesServer(s, &GRPCGuestCapabilitiesServer{
|
||||
Impl: g.Impl,
|
||||
GRPCIOServer: GRPCIOServer{
|
||||
Impl: g.Impl}})
|
||||
return nil
|
||||
}
|
||||
|
||||
func (g *GuestCapabilitiesPlugin) GRPCClient(ctx context.Context, broker *go_plugin.GRPCBroker, c *grpc.ClientConn) (interface{}, error) {
|
||||
client := vagrant_caps.NewGuestCapabilitiesClient(c)
|
||||
return &GRPCGuestCapabilitiesClient{
|
||||
client: client,
|
||||
GRPCIOClient: GRPCIOClient{
|
||||
client: client}}, nil
|
||||
}
|
||||
|
||||
type GRPCGuestCapabilitiesServer struct {
|
||||
GRPCIOServer
|
||||
Impl GuestCapabilities
|
||||
|
@ -43,8 +62,7 @@ func (s *GRPCGuestCapabilitiesServer) GuestCapabilities(ctx context.Context, req
|
|||
func (s *GRPCGuestCapabilitiesServer) GuestCapability(ctx context.Context, req *vagrant_caps.GuestCapabilityRequest) (resp *vagrant_caps.GuestCapabilityResponse, err error) {
|
||||
resp = &vagrant_caps.GuestCapabilityResponse{}
|
||||
var args interface{}
|
||||
err = json.Unmarshal([]byte(req.Arguments), args)
|
||||
if err != nil {
|
||||
if err = json.Unmarshal([]byte(req.Arguments), &args); err != nil {
|
||||
return
|
||||
}
|
||||
machine, err := vagrant.LoadMachine(req.Machine, s.Impl)
|
||||
|
@ -67,6 +85,8 @@ func (s *GRPCGuestCapabilitiesServer) GuestCapability(ctx context.Context, req *
|
|||
}
|
||||
|
||||
type GRPCGuestCapabilitiesClient struct {
|
||||
GRPCCoreClient
|
||||
GRPCIOClient
|
||||
client vagrant_caps.GuestCapabilitiesClient
|
||||
}
|
||||
|
||||
|
@ -102,6 +122,13 @@ func (c *GRPCGuestCapabilitiesClient) GuestCapability(cap *vagrant.SystemCapabil
|
|||
Capability: &vagrant_caps.Capability{Name: cap.Name, Platform: cap.Platform},
|
||||
Machine: m,
|
||||
Arguments: string(a)})
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
if resp.Error != "" {
|
||||
err = errors.New(resp.Error)
|
||||
return
|
||||
}
|
||||
err = json.Unmarshal([]byte(resp.Result), &result)
|
||||
return
|
||||
}
|
||||
|
@ -111,6 +138,28 @@ type HostCapabilities interface {
|
|||
Meta
|
||||
}
|
||||
|
||||
type HostCapabilitiesPlugin struct {
|
||||
go_plugin.NetRPCUnsupportedPlugin
|
||||
Impl HostCapabilities
|
||||
}
|
||||
|
||||
func (h *HostCapabilitiesPlugin) GRPCServer(broker *go_plugin.GRPCBroker, s *grpc.Server) error {
|
||||
h.Impl.Init()
|
||||
vagrant_caps.RegisterHostCapabilitiesServer(s, &GRPCHostCapabilitiesServer{
|
||||
Impl: h.Impl,
|
||||
GRPCIOServer: GRPCIOServer{
|
||||
Impl: h.Impl}})
|
||||
return nil
|
||||
}
|
||||
|
||||
func (h *HostCapabilitiesPlugin) GRPCClient(ctx context.Context, broker *go_plugin.GRPCBroker, c *grpc.ClientConn) (interface{}, error) {
|
||||
client := vagrant_caps.NewHostCapabilitiesClient(c)
|
||||
return &GRPCHostCapabilitiesClient{
|
||||
client: client,
|
||||
GRPCIOClient: GRPCIOClient{
|
||||
client: client}}, nil
|
||||
}
|
||||
|
||||
type GRPCHostCapabilitiesServer struct {
|
||||
GRPCIOServer
|
||||
Impl HostCapabilities
|
||||
|
@ -133,8 +182,7 @@ func (s *GRPCHostCapabilitiesServer) HostCapabilities(ctx context.Context, req *
|
|||
func (s *GRPCHostCapabilitiesServer) HostCapability(ctx context.Context, req *vagrant_caps.HostCapabilityRequest) (resp *vagrant_caps.HostCapabilityResponse, err error) {
|
||||
resp = &vagrant_caps.HostCapabilityResponse{}
|
||||
var args interface{}
|
||||
err = json.Unmarshal([]byte(req.Arguments), args)
|
||||
if err != nil {
|
||||
if err = json.Unmarshal([]byte(req.Arguments), &args); err != nil {
|
||||
return
|
||||
}
|
||||
env, err := vagrant.LoadEnvironment(req.Environment, s.Impl)
|
||||
|
@ -157,6 +205,8 @@ func (s *GRPCHostCapabilitiesServer) HostCapability(ctx context.Context, req *va
|
|||
}
|
||||
|
||||
type GRPCHostCapabilitiesClient struct {
|
||||
GRPCCoreClient
|
||||
GRPCIOClient
|
||||
client vagrant_caps.HostCapabilitiesClient
|
||||
}
|
||||
|
||||
|
@ -194,6 +244,9 @@ func (c *GRPCHostCapabilitiesClient) HostCapability(cap *vagrant.SystemCapabilit
|
|||
Platform: cap.Platform},
|
||||
Environment: e,
|
||||
Arguments: string(a)})
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
err = json.Unmarshal([]byte(resp.Result), &result)
|
||||
return
|
||||
}
|
||||
|
@ -203,6 +256,28 @@ type ProviderCapabilities interface {
|
|||
Meta
|
||||
}
|
||||
|
||||
type ProviderCapabilitiesPlugin struct {
|
||||
go_plugin.NetRPCUnsupportedPlugin
|
||||
Impl ProviderCapabilities
|
||||
}
|
||||
|
||||
func (p *ProviderCapabilitiesPlugin) GRPCServer(broker *go_plugin.GRPCBroker, s *grpc.Server) error {
|
||||
p.Impl.Init()
|
||||
vagrant_caps.RegisterProviderCapabilitiesServer(s, &GRPCProviderCapabilitiesServer{
|
||||
Impl: p.Impl,
|
||||
GRPCIOServer: GRPCIOServer{
|
||||
Impl: p.Impl}})
|
||||
return nil
|
||||
}
|
||||
|
||||
func (p *ProviderCapabilitiesPlugin) GRPCClient(ctx context.Context, broker *go_plugin.GRPCBroker, c *grpc.ClientConn) (interface{}, error) {
|
||||
client := vagrant_caps.NewProviderCapabilitiesClient(c)
|
||||
return &GRPCProviderCapabilitiesClient{
|
||||
client: client,
|
||||
GRPCIOClient: GRPCIOClient{
|
||||
client: client}}, nil
|
||||
}
|
||||
|
||||
type GRPCProviderCapabilitiesServer struct {
|
||||
GRPCIOServer
|
||||
Impl ProviderCapabilities
|
||||
|
@ -225,7 +300,7 @@ func (s *GRPCProviderCapabilitiesServer) ProviderCapabilities(ctx context.Contex
|
|||
func (s *GRPCProviderCapabilitiesServer) ProviderCapability(ctx context.Context, req *vagrant_caps.ProviderCapabilityRequest) (resp *vagrant_caps.ProviderCapabilityResponse, err error) {
|
||||
resp = &vagrant_caps.ProviderCapabilityResponse{}
|
||||
var args interface{}
|
||||
err = json.Unmarshal([]byte(req.Arguments), args)
|
||||
err = json.Unmarshal([]byte(req.Arguments), &args)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
@ -249,6 +324,8 @@ func (s *GRPCProviderCapabilitiesServer) ProviderCapability(ctx context.Context,
|
|||
}
|
||||
|
||||
type GRPCProviderCapabilitiesClient struct {
|
||||
GRPCCoreClient
|
||||
GRPCIOClient
|
||||
client vagrant_caps.ProviderCapabilitiesClient
|
||||
}
|
||||
|
||||
|
@ -286,6 +363,9 @@ func (c *GRPCProviderCapabilitiesClient) ProviderCapability(cap *vagrant.Provide
|
|||
Provider: cap.Provider},
|
||||
Machine: m,
|
||||
Arguments: string(a)})
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
err = json.Unmarshal([]byte(resp.Result), &result)
|
||||
return
|
||||
}
|
||||
|
|
|
@ -0,0 +1,311 @@
|
|||
package plugin
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/hashicorp/go-plugin"
|
||||
"github.com/hashicorp/vagrant/ext/go-plugin/vagrant"
|
||||
)
|
||||
|
||||
func TestCapabilities_GuestCapabilities(t *testing.T) {
|
||||
client, server := plugin.TestPluginGRPCConn(t, map[string]plugin.Plugin{
|
||||
"caps": &GuestCapabilitiesPlugin{Impl: &MockGuestCapabilities{}}})
|
||||
defer server.Stop()
|
||||
defer client.Close()
|
||||
|
||||
raw, err := client.Dispense("caps")
|
||||
if err != nil {
|
||||
t.Fatalf("err: %s", err)
|
||||
}
|
||||
impl, ok := raw.(GuestCapabilities)
|
||||
if !ok {
|
||||
t.Fatalf("bad %#v", raw)
|
||||
}
|
||||
resp, err := impl.GuestCapabilities()
|
||||
if err != nil {
|
||||
t.Fatalf("bad resp: %s", err)
|
||||
}
|
||||
if len(resp) != 1 {
|
||||
t.Fatalf("length %d != 1", len(resp))
|
||||
}
|
||||
if resp[0].Name != "test_cap" {
|
||||
t.Errorf("name - %s != test_cap", resp[0].Name)
|
||||
}
|
||||
if resp[0].Platform != "testOS" {
|
||||
t.Errorf("platform - %s != testOS", resp[0].Platform)
|
||||
}
|
||||
}
|
||||
|
||||
func TestCapabilities_GuestCapability(t *testing.T) {
|
||||
client, server := plugin.TestPluginGRPCConn(t, map[string]plugin.Plugin{
|
||||
"caps": &GuestCapabilitiesPlugin{Impl: &MockGuestCapabilities{}}})
|
||||
defer server.Stop()
|
||||
defer client.Close()
|
||||
|
||||
raw, err := client.Dispense("caps")
|
||||
if err != nil {
|
||||
t.Fatalf("err: %s", err)
|
||||
}
|
||||
impl, ok := raw.(GuestCapabilities)
|
||||
if !ok {
|
||||
t.Fatalf("bad %#v", raw)
|
||||
}
|
||||
|
||||
cap := &vagrant.SystemCapability{
|
||||
Name: "test_cap",
|
||||
Platform: "TestOS"}
|
||||
m := &vagrant.Machine{}
|
||||
args := []string{"test_value", "next_test_value"}
|
||||
|
||||
resp, err := impl.GuestCapability(cap, args, m)
|
||||
if err != nil {
|
||||
t.Fatalf("bad resp: %s", err)
|
||||
}
|
||||
result, ok := resp.([]interface{})
|
||||
if !ok {
|
||||
t.Fatalf("bad %#v", result)
|
||||
}
|
||||
if result[0] != "test_cap" {
|
||||
t.Errorf("%s != test_cap", result[0])
|
||||
}
|
||||
if result[1] != "test_value" {
|
||||
t.Errorf("%s != test_value", result[1])
|
||||
}
|
||||
}
|
||||
|
||||
func TestCapabilities_GuestCapability_noargs(t *testing.T) {
|
||||
client, server := plugin.TestPluginGRPCConn(t, map[string]plugin.Plugin{
|
||||
"caps": &GuestCapabilitiesPlugin{Impl: &MockGuestCapabilities{}}})
|
||||
defer server.Stop()
|
||||
defer client.Close()
|
||||
|
||||
raw, err := client.Dispense("caps")
|
||||
if err != nil {
|
||||
t.Fatalf("err: %s", err)
|
||||
}
|
||||
impl, ok := raw.(GuestCapabilities)
|
||||
if !ok {
|
||||
t.Fatalf("bad %#v", raw)
|
||||
}
|
||||
|
||||
cap := &vagrant.SystemCapability{
|
||||
Name: "test_cap",
|
||||
Platform: "TestOS"}
|
||||
m := &vagrant.Machine{}
|
||||
var args interface{}
|
||||
args = nil
|
||||
|
||||
resp, err := impl.GuestCapability(cap, args, m)
|
||||
if err != nil {
|
||||
t.Fatalf("bad resp: %s", err)
|
||||
}
|
||||
result, ok := resp.([]interface{})
|
||||
if !ok {
|
||||
t.Fatalf("bad %#v", result)
|
||||
}
|
||||
if result[0] != "test_cap" {
|
||||
t.Errorf("%s != test_cap", result[0])
|
||||
}
|
||||
}
|
||||
|
||||
func TestCapabilities_HostCapabilities(t *testing.T) {
|
||||
client, server := plugin.TestPluginGRPCConn(t, map[string]plugin.Plugin{
|
||||
"caps": &HostCapabilitiesPlugin{Impl: &MockHostCapabilities{}}})
|
||||
defer server.Stop()
|
||||
defer client.Close()
|
||||
|
||||
raw, err := client.Dispense("caps")
|
||||
if err != nil {
|
||||
t.Fatalf("err: %s", err)
|
||||
}
|
||||
impl, ok := raw.(HostCapabilities)
|
||||
if !ok {
|
||||
t.Fatalf("bad %#v", raw)
|
||||
}
|
||||
resp, err := impl.HostCapabilities()
|
||||
if err != nil {
|
||||
t.Fatalf("bad resp: %s", err)
|
||||
}
|
||||
if len(resp) != 1 {
|
||||
t.Fatalf("length %d != 1", len(resp))
|
||||
}
|
||||
if resp[0].Name != "test_cap" {
|
||||
t.Errorf("name - %s != test_cap", resp[0].Name)
|
||||
}
|
||||
if resp[0].Platform != "testOS" {
|
||||
t.Errorf("platform - %s != testOS", resp[0].Platform)
|
||||
}
|
||||
}
|
||||
|
||||
func TestCapabilities_HostCapability(t *testing.T) {
|
||||
client, server := plugin.TestPluginGRPCConn(t, map[string]plugin.Plugin{
|
||||
"caps": &HostCapabilitiesPlugin{Impl: &MockHostCapabilities{}}})
|
||||
defer server.Stop()
|
||||
defer client.Close()
|
||||
|
||||
raw, err := client.Dispense("caps")
|
||||
if err != nil {
|
||||
t.Fatalf("err: %s", err)
|
||||
}
|
||||
impl, ok := raw.(HostCapabilities)
|
||||
if !ok {
|
||||
t.Fatalf("bad %#v", raw)
|
||||
}
|
||||
|
||||
cap := &vagrant.SystemCapability{
|
||||
Name: "test_cap",
|
||||
Platform: "TestOS"}
|
||||
e := &vagrant.Environment{}
|
||||
args := []string{"test_value", "next_test_value"}
|
||||
|
||||
resp, err := impl.HostCapability(cap, args, e)
|
||||
if err != nil {
|
||||
t.Fatalf("bad resp: %s", err)
|
||||
}
|
||||
result, ok := resp.([]interface{})
|
||||
if !ok {
|
||||
t.Fatalf("bad %#v", result)
|
||||
}
|
||||
if result[0] != "test_cap" {
|
||||
t.Errorf("%s != test_cap", result[0])
|
||||
}
|
||||
if result[1] != "test_value" {
|
||||
t.Errorf("%s != test_value", result[1])
|
||||
}
|
||||
}
|
||||
|
||||
func TestCapabilities_HostCapability_noargs(t *testing.T) {
|
||||
client, server := plugin.TestPluginGRPCConn(t, map[string]plugin.Plugin{
|
||||
"caps": &HostCapabilitiesPlugin{Impl: &MockHostCapabilities{}}})
|
||||
defer server.Stop()
|
||||
defer client.Close()
|
||||
|
||||
raw, err := client.Dispense("caps")
|
||||
if err != nil {
|
||||
t.Fatalf("err: %s", err)
|
||||
}
|
||||
impl, ok := raw.(HostCapabilities)
|
||||
if !ok {
|
||||
t.Fatalf("bad %#v", raw)
|
||||
}
|
||||
|
||||
cap := &vagrant.SystemCapability{
|
||||
Name: "test_cap",
|
||||
Platform: "TestOS"}
|
||||
e := &vagrant.Environment{}
|
||||
var args interface{}
|
||||
args = nil
|
||||
|
||||
resp, err := impl.HostCapability(cap, args, e)
|
||||
if err != nil {
|
||||
t.Fatalf("bad resp: %s", err)
|
||||
}
|
||||
result, ok := resp.([]interface{})
|
||||
if !ok {
|
||||
t.Fatalf("bad %#v", result)
|
||||
}
|
||||
if result[0] != "test_cap" {
|
||||
t.Errorf("%s != test_cap", result[0])
|
||||
}
|
||||
}
|
||||
|
||||
func TestCapabilities_ProviderCapabilities(t *testing.T) {
|
||||
client, server := plugin.TestPluginGRPCConn(t, map[string]plugin.Plugin{
|
||||
"caps": &ProviderCapabilitiesPlugin{Impl: &MockProviderCapabilities{}}})
|
||||
defer server.Stop()
|
||||
defer client.Close()
|
||||
|
||||
raw, err := client.Dispense("caps")
|
||||
if err != nil {
|
||||
t.Fatalf("err: %s", err)
|
||||
}
|
||||
impl, ok := raw.(ProviderCapabilities)
|
||||
if !ok {
|
||||
t.Fatalf("bad %#v", raw)
|
||||
}
|
||||
resp, err := impl.ProviderCapabilities()
|
||||
if err != nil {
|
||||
t.Fatalf("bad resp: %s", err)
|
||||
}
|
||||
if len(resp) != 1 {
|
||||
t.Fatalf("length %d != 1", len(resp))
|
||||
}
|
||||
if resp[0].Name != "test_cap" {
|
||||
t.Errorf("name - %s != test_cap", resp[0].Name)
|
||||
}
|
||||
if resp[0].Provider != "testProvider" {
|
||||
t.Errorf("provider - %s != testProvdier", resp[0].Provider)
|
||||
}
|
||||
}
|
||||
|
||||
func TestCapabilities_ProviderCapability(t *testing.T) {
|
||||
client, server := plugin.TestPluginGRPCConn(t, map[string]plugin.Plugin{
|
||||
"caps": &ProviderCapabilitiesPlugin{Impl: &MockProviderCapabilities{}}})
|
||||
defer server.Stop()
|
||||
defer client.Close()
|
||||
|
||||
raw, err := client.Dispense("caps")
|
||||
if err != nil {
|
||||
t.Fatalf("err: %s", err)
|
||||
}
|
||||
impl, ok := raw.(ProviderCapabilities)
|
||||
if !ok {
|
||||
t.Fatalf("bad %#v", raw)
|
||||
}
|
||||
|
||||
cap := &vagrant.ProviderCapability{
|
||||
Name: "test_cap",
|
||||
Provider: "test_provider"}
|
||||
m := &vagrant.Machine{}
|
||||
args := []string{"test_value", "next_test_value"}
|
||||
|
||||
resp, err := impl.ProviderCapability(cap, args, m)
|
||||
if err != nil {
|
||||
t.Fatalf("bad resp: %s", err)
|
||||
}
|
||||
result, ok := resp.([]interface{})
|
||||
if !ok {
|
||||
t.Fatalf("bad %#v", result)
|
||||
}
|
||||
if result[0] != "test_cap" {
|
||||
t.Errorf("%s != test_cap", result[0])
|
||||
}
|
||||
if result[1] != "test_value" {
|
||||
t.Errorf("%s != test_value", result[1])
|
||||
}
|
||||
}
|
||||
|
||||
func TestCapabilities_ProviderCapability_noargs(t *testing.T) {
|
||||
client, server := plugin.TestPluginGRPCConn(t, map[string]plugin.Plugin{
|
||||
"caps": &ProviderCapabilitiesPlugin{Impl: &MockProviderCapabilities{}}})
|
||||
defer server.Stop()
|
||||
defer client.Close()
|
||||
|
||||
raw, err := client.Dispense("caps")
|
||||
if err != nil {
|
||||
t.Fatalf("err: %s", err)
|
||||
}
|
||||
impl, ok := raw.(ProviderCapabilities)
|
||||
if !ok {
|
||||
t.Fatalf("bad %#v", raw)
|
||||
}
|
||||
|
||||
cap := &vagrant.ProviderCapability{
|
||||
Name: "test_cap",
|
||||
Provider: "test_provider"}
|
||||
m := &vagrant.Machine{}
|
||||
var args interface{}
|
||||
args = nil
|
||||
|
||||
resp, err := impl.ProviderCapability(cap, args, m)
|
||||
if err != nil {
|
||||
t.Fatalf("bad resp: %s", err)
|
||||
}
|
||||
result, ok := resp.([]interface{})
|
||||
if !ok {
|
||||
t.Fatalf("bad %#v", result)
|
||||
}
|
||||
if result[0] != "test_cap" {
|
||||
t.Errorf("%s != test_cap", result[0])
|
||||
}
|
||||
}
|
|
@ -5,6 +5,8 @@ import (
|
|||
"encoding/json"
|
||||
"errors"
|
||||
|
||||
"google.golang.org/grpc"
|
||||
|
||||
go_plugin "github.com/hashicorp/go-plugin"
|
||||
"github.com/hashicorp/vagrant/ext/go-plugin/vagrant"
|
||||
"github.com/hashicorp/vagrant/ext/go-plugin/vagrant/plugin/proto/vagrant_common"
|
||||
|
@ -21,6 +23,23 @@ type ConfigPlugin struct {
|
|||
Impl Config
|
||||
}
|
||||
|
||||
func (c *ConfigPlugin) GRPCServer(broker *go_plugin.GRPCBroker, s *grpc.Server) error {
|
||||
c.Impl.Init()
|
||||
vagrant_config.RegisterConfigServer(s, &GRPCConfigServer{
|
||||
Impl: c.Impl,
|
||||
GRPCIOServer: GRPCIOServer{
|
||||
Impl: c.Impl}})
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *ConfigPlugin) GRPCClient(ctx context.Context, broker *go_plugin.GRPCBroker, con *grpc.ClientConn) (interface{}, error) {
|
||||
client := vagrant_config.NewConfigClient(con)
|
||||
return &GRPCConfigClient{
|
||||
client: client,
|
||||
GRPCIOClient: GRPCIOClient{
|
||||
client: client}}, nil
|
||||
}
|
||||
|
||||
type GRPCConfigServer struct {
|
||||
GRPCIOServer
|
||||
Impl Config
|
||||
|
@ -104,6 +123,8 @@ func (s *GRPCConfigServer) ConfigFinalize(ctx context.Context, req *vagrant_conf
|
|||
}
|
||||
|
||||
type GRPCConfigClient struct {
|
||||
GRPCCoreClient
|
||||
GRPCIOClient
|
||||
client vagrant_config.ConfigClient
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,131 @@
|
|||
package plugin
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/hashicorp/go-plugin"
|
||||
"github.com/hashicorp/vagrant/ext/go-plugin/vagrant"
|
||||
)
|
||||
|
||||
func TestConfigPlugin_Attributes(t *testing.T) {
|
||||
client, server := plugin.TestPluginGRPCConn(t, map[string]plugin.Plugin{
|
||||
"configs": &ConfigPlugin{Impl: &MockConfig{}}})
|
||||
defer server.Stop()
|
||||
defer client.Close()
|
||||
|
||||
raw, err := client.Dispense("configs")
|
||||
if err != nil {
|
||||
t.Fatalf("err: %s", err)
|
||||
}
|
||||
impl, ok := raw.(Config)
|
||||
if !ok {
|
||||
t.Fatalf("bad %#v", raw)
|
||||
}
|
||||
|
||||
resp, err := impl.ConfigAttributes()
|
||||
if err != nil {
|
||||
t.Fatalf("bad resp %s", err)
|
||||
}
|
||||
if resp[0] != "fubar" {
|
||||
t.Errorf("%s != fubar", resp[0])
|
||||
}
|
||||
if resp[1] != "foobar" {
|
||||
t.Errorf("%s != foobar", resp[1])
|
||||
}
|
||||
}
|
||||
|
||||
func TestConfigPlugin_Load(t *testing.T) {
|
||||
client, server := plugin.TestPluginGRPCConn(t, map[string]plugin.Plugin{
|
||||
"configs": &ConfigPlugin{Impl: &MockConfig{}}})
|
||||
defer server.Stop()
|
||||
defer client.Close()
|
||||
|
||||
raw, err := client.Dispense("configs")
|
||||
if err != nil {
|
||||
t.Fatalf("err: %s", err)
|
||||
}
|
||||
impl, ok := raw.(Config)
|
||||
if !ok {
|
||||
t.Fatalf("bad %#v", raw)
|
||||
}
|
||||
|
||||
data := map[string]interface{}{}
|
||||
|
||||
resp, err := impl.ConfigLoad(data)
|
||||
if err != nil {
|
||||
t.Fatalf("bad resp: %s", err)
|
||||
}
|
||||
if _, ok := resp["test_key"]; !ok {
|
||||
t.Fatalf("bad resp content %#v", resp)
|
||||
}
|
||||
v := resp["test_key"].(string)
|
||||
if v != "test_val" {
|
||||
t.Errorf("%s != test_val", v)
|
||||
}
|
||||
}
|
||||
|
||||
func TestConfigPlugin_Validate(t *testing.T) {
|
||||
client, server := plugin.TestPluginGRPCConn(t, map[string]plugin.Plugin{
|
||||
"configs": &ConfigPlugin{Impl: &MockConfig{}}})
|
||||
defer server.Stop()
|
||||
defer client.Close()
|
||||
|
||||
raw, err := client.Dispense("configs")
|
||||
if err != nil {
|
||||
t.Fatalf("err: %s", err)
|
||||
}
|
||||
impl, ok := raw.(Config)
|
||||
if !ok {
|
||||
t.Fatalf("bad %#v", raw)
|
||||
}
|
||||
|
||||
data := map[string]interface{}{}
|
||||
machine := &vagrant.Machine{}
|
||||
|
||||
resp, err := impl.ConfigValidate(data, machine)
|
||||
if err != nil {
|
||||
t.Fatalf("bad resp: %s", err)
|
||||
}
|
||||
if len(resp) != 1 {
|
||||
t.Fatalf("bad size %d != 1", len(resp))
|
||||
}
|
||||
if resp[0] != "test error" {
|
||||
t.Errorf("%s != test error", resp[0])
|
||||
}
|
||||
}
|
||||
|
||||
func TestConfigPlugin_Finalize(t *testing.T) {
|
||||
client, server := plugin.TestPluginGRPCConn(t, map[string]plugin.Plugin{
|
||||
"configs": &ConfigPlugin{Impl: &MockConfig{}}})
|
||||
defer server.Stop()
|
||||
defer client.Close()
|
||||
|
||||
raw, err := client.Dispense("configs")
|
||||
if err != nil {
|
||||
t.Fatalf("err: %s", err)
|
||||
}
|
||||
impl, ok := raw.(Config)
|
||||
if !ok {
|
||||
t.Fatalf("bad %#v", raw)
|
||||
}
|
||||
|
||||
data := map[string]interface{}{
|
||||
"test_key": "test_val",
|
||||
"other_key": "other_val"}
|
||||
|
||||
resp, err := impl.ConfigFinalize(data)
|
||||
if err != nil {
|
||||
t.Fatalf("bad resp: %s", err)
|
||||
}
|
||||
if _, ok := resp["test_key"]; !ok {
|
||||
t.Fatalf("bad resp content %#v", resp)
|
||||
}
|
||||
v := resp["test_key"].(string)
|
||||
if v != "test_val-updated" {
|
||||
t.Errorf("%s != test_val-updated", v)
|
||||
}
|
||||
v = resp["other_key"].(string)
|
||||
if v != "other_val-updated" {
|
||||
t.Errorf("%s != other_val-updated", v)
|
||||
}
|
||||
}
|
|
@ -11,6 +11,10 @@ import (
|
|||
"github.com/hashicorp/vagrant/ext/go-plugin/vagrant/plugin/proto/vagrant_io"
|
||||
)
|
||||
|
||||
type IO interface {
|
||||
vagrant.StreamIO
|
||||
}
|
||||
|
||||
type IOPlugin struct {
|
||||
go_plugin.NetRPCUnsupportedPlugin
|
||||
Impl vagrant.StreamIO
|
||||
|
|
|
@ -0,0 +1,89 @@
|
|||
package plugin
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/hashicorp/go-plugin"
|
||||
)
|
||||
|
||||
type MockIO struct {
|
||||
Core
|
||||
}
|
||||
|
||||
func TestIO_ReadWrite(t *testing.T) {
|
||||
ioplugin := &MockIO{}
|
||||
ioplugin.Init()
|
||||
client, server := plugin.TestPluginGRPCConn(t, map[string]plugin.Plugin{
|
||||
"io": &IOPlugin{Impl: ioplugin}})
|
||||
defer server.Stop()
|
||||
defer client.Close()
|
||||
|
||||
raw, err := client.Dispense("io")
|
||||
if err != nil {
|
||||
t.Fatalf("err: %s", err)
|
||||
}
|
||||
impl, ok := raw.(IO)
|
||||
if !ok {
|
||||
t.Fatalf("bad %#v", raw)
|
||||
}
|
||||
go func() {
|
||||
length, err := impl.Write("test_message", "stdout")
|
||||
if err != nil {
|
||||
t.Fatalf("bad write: %s", err)
|
||||
}
|
||||
if length != len("test_message") {
|
||||
t.Fatalf("bad length %d != %d", length, len("test_message"))
|
||||
}
|
||||
}()
|
||||
resp, err := impl.Read("stdout")
|
||||
if err != nil {
|
||||
t.Fatalf("bad read: %s", err)
|
||||
}
|
||||
if resp != "test_message" {
|
||||
t.Errorf("%s != test_message", resp)
|
||||
}
|
||||
}
|
||||
|
||||
func TestIO_Write_bad(t *testing.T) {
|
||||
ioplugin := &MockIO{}
|
||||
ioplugin.Init()
|
||||
client, server := plugin.TestPluginGRPCConn(t, map[string]plugin.Plugin{
|
||||
"io": &IOPlugin{Impl: ioplugin}})
|
||||
defer server.Stop()
|
||||
defer client.Close()
|
||||
|
||||
raw, err := client.Dispense("io")
|
||||
if err != nil {
|
||||
t.Fatalf("err: %s", err)
|
||||
}
|
||||
impl, ok := raw.(IO)
|
||||
if !ok {
|
||||
t.Fatalf("bad %#v", raw)
|
||||
}
|
||||
_, err = impl.Write("test_message", "bad-target")
|
||||
if err == nil {
|
||||
t.Fatalf("illegal write")
|
||||
}
|
||||
}
|
||||
|
||||
func TestIO_Read_bad(t *testing.T) {
|
||||
ioplugin := &MockIO{}
|
||||
ioplugin.Init()
|
||||
client, server := plugin.TestPluginGRPCConn(t, map[string]plugin.Plugin{
|
||||
"io": &IOPlugin{Impl: ioplugin}})
|
||||
defer server.Stop()
|
||||
defer client.Close()
|
||||
|
||||
raw, err := client.Dispense("io")
|
||||
if err != nil {
|
||||
t.Fatalf("err: %s", err)
|
||||
}
|
||||
impl, ok := raw.(IO)
|
||||
if !ok {
|
||||
t.Fatalf("bad %#v", raw)
|
||||
}
|
||||
_, err = impl.Read("bad-target")
|
||||
if err == nil {
|
||||
t.Fatalf("illegal read")
|
||||
}
|
||||
}
|
|
@ -0,0 +1,176 @@
|
|||
package plugin
|
||||
|
||||
import (
|
||||
"errors"
|
||||
|
||||
"github.com/hashicorp/vagrant/ext/go-plugin/vagrant"
|
||||
)
|
||||
|
||||
type MockGuestCapabilities struct{ Core }
|
||||
|
||||
func (g *MockGuestCapabilities) GuestCapabilities() (caps []vagrant.SystemCapability, err error) {
|
||||
caps = []vagrant.SystemCapability{
|
||||
vagrant.SystemCapability{Name: "test_cap", Platform: "testOS"}}
|
||||
return
|
||||
}
|
||||
|
||||
func (g *MockGuestCapabilities) GuestCapability(cap *vagrant.SystemCapability, args interface{}, m *vagrant.Machine) (result interface{}, err error) {
|
||||
if args != nil {
|
||||
arguments := args.([]interface{})
|
||||
if len(arguments) > 0 {
|
||||
result = []string{
|
||||
cap.Name,
|
||||
arguments[0].(string)}
|
||||
return
|
||||
}
|
||||
}
|
||||
result = []string{cap.Name}
|
||||
return
|
||||
}
|
||||
|
||||
type MockHostCapabilities struct{ Core }
|
||||
|
||||
func (h *MockHostCapabilities) HostCapabilities() (caps []vagrant.SystemCapability, err error) {
|
||||
caps = []vagrant.SystemCapability{
|
||||
vagrant.SystemCapability{Name: "test_cap", Platform: "testOS"}}
|
||||
return
|
||||
}
|
||||
|
||||
func (h *MockHostCapabilities) HostCapability(cap *vagrant.SystemCapability, args interface{}, e *vagrant.Environment) (result interface{}, err error) {
|
||||
if args != nil {
|
||||
arguments := args.([]interface{})
|
||||
if len(arguments) > 0 {
|
||||
result = []string{
|
||||
cap.Name,
|
||||
arguments[0].(string)}
|
||||
return
|
||||
}
|
||||
}
|
||||
result = []string{cap.Name}
|
||||
return
|
||||
}
|
||||
|
||||
type MockProviderCapabilities struct{ Core }
|
||||
|
||||
func (p *MockProviderCapabilities) ProviderCapabilities() (caps []vagrant.ProviderCapability, err error) {
|
||||
caps = []vagrant.ProviderCapability{
|
||||
vagrant.ProviderCapability{Name: "test_cap", Provider: "testProvider"}}
|
||||
return
|
||||
}
|
||||
|
||||
func (p *MockProviderCapabilities) ProviderCapability(cap *vagrant.ProviderCapability, args interface{}, m *vagrant.Machine) (result interface{}, err error) {
|
||||
if args != nil {
|
||||
arguments := args.([]interface{})
|
||||
if len(arguments) > 0 {
|
||||
result = []string{
|
||||
cap.Name,
|
||||
arguments[0].(string)}
|
||||
return
|
||||
}
|
||||
}
|
||||
result = []string{cap.Name}
|
||||
return
|
||||
}
|
||||
|
||||
type MockConfig struct {
|
||||
Core
|
||||
}
|
||||
|
||||
func (c *MockConfig) ConfigAttributes() (attrs []string, err error) {
|
||||
attrs = []string{"fubar", "foobar"}
|
||||
return
|
||||
}
|
||||
|
||||
func (c *MockConfig) ConfigLoad(data map[string]interface{}) (loaddata map[string]interface{}, err error) {
|
||||
loaddata = map[string]interface{}{
|
||||
"test_key": "test_val"}
|
||||
if data["test_key"] != nil {
|
||||
loaddata["sent_key"] = data["test_key"]
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func (c *MockConfig) ConfigValidate(data map[string]interface{}, m *vagrant.Machine) (errors []string, err error) {
|
||||
errors = []string{"test error"}
|
||||
return
|
||||
}
|
||||
|
||||
func (c *MockConfig) ConfigFinalize(data map[string]interface{}) (finaldata map[string]interface{}, err error) {
|
||||
finaldata = make(map[string]interface{})
|
||||
for key, tval := range data {
|
||||
val := tval.(string)
|
||||
finaldata[key] = val + "-updated"
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
type MockProvider struct {
|
||||
Core
|
||||
vagrant.NoConfig
|
||||
vagrant.NoGuestCapabilities
|
||||
vagrant.NoHostCapabilities
|
||||
vagrant.NoProviderCapabilities
|
||||
}
|
||||
|
||||
func (c *MockProvider) Action(actionName string, m *vagrant.Machine) (actions []string, err error) {
|
||||
if actionName == "valid" {
|
||||
actions = []string{"self::DoTask"}
|
||||
} else {
|
||||
err = errors.New("Unknown action requested")
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func (c *MockProvider) IsInstalled(m *vagrant.Machine) (bool, error) {
|
||||
return true, nil
|
||||
}
|
||||
|
||||
func (c *MockProvider) IsUsable(m *vagrant.Machine) (bool, error) {
|
||||
return true, nil
|
||||
}
|
||||
|
||||
func (c *MockProvider) MachineIdChanged(m *vagrant.Machine) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *MockProvider) Name() string {
|
||||
return "mock_provider"
|
||||
}
|
||||
|
||||
func (c *MockProvider) RunAction(actionName string, args interface{}, m *vagrant.Machine) (r interface{}, err error) {
|
||||
if actionName != "valid" && actionName != "send_output" {
|
||||
err = errors.New("invalid action name")
|
||||
return
|
||||
}
|
||||
if actionName == "send_output" {
|
||||
m.UI.Say("test_output_p")
|
||||
}
|
||||
var arguments []interface{}
|
||||
if args != nil {
|
||||
arguments = args.([]interface{})
|
||||
} else {
|
||||
arguments = []interface{}{"unset"}
|
||||
}
|
||||
r = []string{
|
||||
actionName,
|
||||
arguments[0].(string)}
|
||||
return
|
||||
}
|
||||
|
||||
func (c *MockProvider) SshInfo(m *vagrant.Machine) (*vagrant.SshInfo, error) {
|
||||
return &vagrant.SshInfo{
|
||||
Host: "localhost",
|
||||
Port: 2222}, nil
|
||||
}
|
||||
|
||||
func (c *MockProvider) State(m *vagrant.Machine) (*vagrant.MachineState, error) {
|
||||
return &vagrant.MachineState{
|
||||
Id: "default",
|
||||
ShortDesc: "running"}, nil
|
||||
}
|
||||
|
||||
func (c *MockProvider) Info() *vagrant.ProviderInfo {
|
||||
return &vagrant.ProviderInfo{
|
||||
Description: "Custom",
|
||||
Priority: 10}
|
||||
}
|
|
@ -7,6 +7,7 @@ import proto "github.com/golang/protobuf/proto"
|
|||
import fmt "fmt"
|
||||
import math "math"
|
||||
import vagrant_common "github.com/hashicorp/vagrant/ext/go-plugin/vagrant/plugin/proto/vagrant_common"
|
||||
import vagrant_io "github.com/hashicorp/vagrant/ext/go-plugin/vagrant/plugin/proto/vagrant_io"
|
||||
|
||||
import (
|
||||
context "golang.org/x/net/context"
|
||||
|
@ -535,6 +536,9 @@ const _ = grpc.SupportPackageIsVersion4
|
|||
type GuestCapabilitiesClient interface {
|
||||
GuestCapabilities(ctx context.Context, in *vagrant_common.NullRequest, opts ...grpc.CallOption) (*CapabilitiesResponse, error)
|
||||
GuestCapability(ctx context.Context, in *GuestCapabilityRequest, opts ...grpc.CallOption) (*GuestCapabilityResponse, error)
|
||||
// These are IO helpers for streaming
|
||||
Read(ctx context.Context, in *vagrant_io.ReadRequest, opts ...grpc.CallOption) (*vagrant_io.ReadResponse, error)
|
||||
Write(ctx context.Context, in *vagrant_io.WriteRequest, opts ...grpc.CallOption) (*vagrant_io.WriteResponse, error)
|
||||
}
|
||||
|
||||
type guestCapabilitiesClient struct {
|
||||
|
@ -563,10 +567,31 @@ func (c *guestCapabilitiesClient) GuestCapability(ctx context.Context, in *Guest
|
|||
return out, nil
|
||||
}
|
||||
|
||||
func (c *guestCapabilitiesClient) Read(ctx context.Context, in *vagrant_io.ReadRequest, opts ...grpc.CallOption) (*vagrant_io.ReadResponse, error) {
|
||||
out := new(vagrant_io.ReadResponse)
|
||||
err := c.cc.Invoke(ctx, "/vagrant.caps.GuestCapabilities/Read", in, out, opts...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return out, nil
|
||||
}
|
||||
|
||||
func (c *guestCapabilitiesClient) Write(ctx context.Context, in *vagrant_io.WriteRequest, opts ...grpc.CallOption) (*vagrant_io.WriteResponse, error) {
|
||||
out := new(vagrant_io.WriteResponse)
|
||||
err := c.cc.Invoke(ctx, "/vagrant.caps.GuestCapabilities/Write", in, out, opts...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return out, nil
|
||||
}
|
||||
|
||||
// GuestCapabilitiesServer is the server API for GuestCapabilities service.
|
||||
type GuestCapabilitiesServer interface {
|
||||
GuestCapabilities(context.Context, *vagrant_common.NullRequest) (*CapabilitiesResponse, error)
|
||||
GuestCapability(context.Context, *GuestCapabilityRequest) (*GuestCapabilityResponse, error)
|
||||
// These are IO helpers for streaming
|
||||
Read(context.Context, *vagrant_io.ReadRequest) (*vagrant_io.ReadResponse, error)
|
||||
Write(context.Context, *vagrant_io.WriteRequest) (*vagrant_io.WriteResponse, error)
|
||||
}
|
||||
|
||||
func RegisterGuestCapabilitiesServer(s *grpc.Server, srv GuestCapabilitiesServer) {
|
||||
|
@ -609,6 +634,42 @@ func _GuestCapabilities_GuestCapability_Handler(srv interface{}, ctx context.Con
|
|||
return interceptor(ctx, in, info, handler)
|
||||
}
|
||||
|
||||
func _GuestCapabilities_Read_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
|
||||
in := new(vagrant_io.ReadRequest)
|
||||
if err := dec(in); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if interceptor == nil {
|
||||
return srv.(GuestCapabilitiesServer).Read(ctx, in)
|
||||
}
|
||||
info := &grpc.UnaryServerInfo{
|
||||
Server: srv,
|
||||
FullMethod: "/vagrant.caps.GuestCapabilities/Read",
|
||||
}
|
||||
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
|
||||
return srv.(GuestCapabilitiesServer).Read(ctx, req.(*vagrant_io.ReadRequest))
|
||||
}
|
||||
return interceptor(ctx, in, info, handler)
|
||||
}
|
||||
|
||||
func _GuestCapabilities_Write_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
|
||||
in := new(vagrant_io.WriteRequest)
|
||||
if err := dec(in); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if interceptor == nil {
|
||||
return srv.(GuestCapabilitiesServer).Write(ctx, in)
|
||||
}
|
||||
info := &grpc.UnaryServerInfo{
|
||||
Server: srv,
|
||||
FullMethod: "/vagrant.caps.GuestCapabilities/Write",
|
||||
}
|
||||
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
|
||||
return srv.(GuestCapabilitiesServer).Write(ctx, req.(*vagrant_io.WriteRequest))
|
||||
}
|
||||
return interceptor(ctx, in, info, handler)
|
||||
}
|
||||
|
||||
var _GuestCapabilities_serviceDesc = grpc.ServiceDesc{
|
||||
ServiceName: "vagrant.caps.GuestCapabilities",
|
||||
HandlerType: (*GuestCapabilitiesServer)(nil),
|
||||
|
@ -621,6 +682,14 @@ var _GuestCapabilities_serviceDesc = grpc.ServiceDesc{
|
|||
MethodName: "GuestCapability",
|
||||
Handler: _GuestCapabilities_GuestCapability_Handler,
|
||||
},
|
||||
{
|
||||
MethodName: "Read",
|
||||
Handler: _GuestCapabilities_Read_Handler,
|
||||
},
|
||||
{
|
||||
MethodName: "Write",
|
||||
Handler: _GuestCapabilities_Write_Handler,
|
||||
},
|
||||
},
|
||||
Streams: []grpc.StreamDesc{},
|
||||
Metadata: "vagrant_caps/capabilities.proto",
|
||||
|
@ -632,6 +701,9 @@ var _GuestCapabilities_serviceDesc = grpc.ServiceDesc{
|
|||
type HostCapabilitiesClient interface {
|
||||
HostCapabilities(ctx context.Context, in *vagrant_common.NullRequest, opts ...grpc.CallOption) (*CapabilitiesResponse, error)
|
||||
HostCapability(ctx context.Context, in *HostCapabilityRequest, opts ...grpc.CallOption) (*HostCapabilityResponse, error)
|
||||
// These are IO helpers for streaming
|
||||
Read(ctx context.Context, in *vagrant_io.ReadRequest, opts ...grpc.CallOption) (*vagrant_io.ReadResponse, error)
|
||||
Write(ctx context.Context, in *vagrant_io.WriteRequest, opts ...grpc.CallOption) (*vagrant_io.WriteResponse, error)
|
||||
}
|
||||
|
||||
type hostCapabilitiesClient struct {
|
||||
|
@ -660,10 +732,31 @@ func (c *hostCapabilitiesClient) HostCapability(ctx context.Context, in *HostCap
|
|||
return out, nil
|
||||
}
|
||||
|
||||
func (c *hostCapabilitiesClient) Read(ctx context.Context, in *vagrant_io.ReadRequest, opts ...grpc.CallOption) (*vagrant_io.ReadResponse, error) {
|
||||
out := new(vagrant_io.ReadResponse)
|
||||
err := c.cc.Invoke(ctx, "/vagrant.caps.HostCapabilities/Read", in, out, opts...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return out, nil
|
||||
}
|
||||
|
||||
func (c *hostCapabilitiesClient) Write(ctx context.Context, in *vagrant_io.WriteRequest, opts ...grpc.CallOption) (*vagrant_io.WriteResponse, error) {
|
||||
out := new(vagrant_io.WriteResponse)
|
||||
err := c.cc.Invoke(ctx, "/vagrant.caps.HostCapabilities/Write", in, out, opts...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return out, nil
|
||||
}
|
||||
|
||||
// HostCapabilitiesServer is the server API for HostCapabilities service.
|
||||
type HostCapabilitiesServer interface {
|
||||
HostCapabilities(context.Context, *vagrant_common.NullRequest) (*CapabilitiesResponse, error)
|
||||
HostCapability(context.Context, *HostCapabilityRequest) (*HostCapabilityResponse, error)
|
||||
// These are IO helpers for streaming
|
||||
Read(context.Context, *vagrant_io.ReadRequest) (*vagrant_io.ReadResponse, error)
|
||||
Write(context.Context, *vagrant_io.WriteRequest) (*vagrant_io.WriteResponse, error)
|
||||
}
|
||||
|
||||
func RegisterHostCapabilitiesServer(s *grpc.Server, srv HostCapabilitiesServer) {
|
||||
|
@ -706,6 +799,42 @@ func _HostCapabilities_HostCapability_Handler(srv interface{}, ctx context.Conte
|
|||
return interceptor(ctx, in, info, handler)
|
||||
}
|
||||
|
||||
func _HostCapabilities_Read_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
|
||||
in := new(vagrant_io.ReadRequest)
|
||||
if err := dec(in); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if interceptor == nil {
|
||||
return srv.(HostCapabilitiesServer).Read(ctx, in)
|
||||
}
|
||||
info := &grpc.UnaryServerInfo{
|
||||
Server: srv,
|
||||
FullMethod: "/vagrant.caps.HostCapabilities/Read",
|
||||
}
|
||||
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
|
||||
return srv.(HostCapabilitiesServer).Read(ctx, req.(*vagrant_io.ReadRequest))
|
||||
}
|
||||
return interceptor(ctx, in, info, handler)
|
||||
}
|
||||
|
||||
func _HostCapabilities_Write_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
|
||||
in := new(vagrant_io.WriteRequest)
|
||||
if err := dec(in); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if interceptor == nil {
|
||||
return srv.(HostCapabilitiesServer).Write(ctx, in)
|
||||
}
|
||||
info := &grpc.UnaryServerInfo{
|
||||
Server: srv,
|
||||
FullMethod: "/vagrant.caps.HostCapabilities/Write",
|
||||
}
|
||||
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
|
||||
return srv.(HostCapabilitiesServer).Write(ctx, req.(*vagrant_io.WriteRequest))
|
||||
}
|
||||
return interceptor(ctx, in, info, handler)
|
||||
}
|
||||
|
||||
var _HostCapabilities_serviceDesc = grpc.ServiceDesc{
|
||||
ServiceName: "vagrant.caps.HostCapabilities",
|
||||
HandlerType: (*HostCapabilitiesServer)(nil),
|
||||
|
@ -718,6 +847,14 @@ var _HostCapabilities_serviceDesc = grpc.ServiceDesc{
|
|||
MethodName: "HostCapability",
|
||||
Handler: _HostCapabilities_HostCapability_Handler,
|
||||
},
|
||||
{
|
||||
MethodName: "Read",
|
||||
Handler: _HostCapabilities_Read_Handler,
|
||||
},
|
||||
{
|
||||
MethodName: "Write",
|
||||
Handler: _HostCapabilities_Write_Handler,
|
||||
},
|
||||
},
|
||||
Streams: []grpc.StreamDesc{},
|
||||
Metadata: "vagrant_caps/capabilities.proto",
|
||||
|
@ -729,6 +866,9 @@ var _HostCapabilities_serviceDesc = grpc.ServiceDesc{
|
|||
type ProviderCapabilitiesClient interface {
|
||||
ProviderCapabilities(ctx context.Context, in *vagrant_common.NullRequest, opts ...grpc.CallOption) (*ProviderCapabilitiesResponse, error)
|
||||
ProviderCapability(ctx context.Context, in *ProviderCapabilityRequest, opts ...grpc.CallOption) (*ProviderCapabilityResponse, error)
|
||||
// These are IO helpers for streaming
|
||||
Read(ctx context.Context, in *vagrant_io.ReadRequest, opts ...grpc.CallOption) (*vagrant_io.ReadResponse, error)
|
||||
Write(ctx context.Context, in *vagrant_io.WriteRequest, opts ...grpc.CallOption) (*vagrant_io.WriteResponse, error)
|
||||
}
|
||||
|
||||
type providerCapabilitiesClient struct {
|
||||
|
@ -757,10 +897,31 @@ func (c *providerCapabilitiesClient) ProviderCapability(ctx context.Context, in
|
|||
return out, nil
|
||||
}
|
||||
|
||||
func (c *providerCapabilitiesClient) Read(ctx context.Context, in *vagrant_io.ReadRequest, opts ...grpc.CallOption) (*vagrant_io.ReadResponse, error) {
|
||||
out := new(vagrant_io.ReadResponse)
|
||||
err := c.cc.Invoke(ctx, "/vagrant.caps.ProviderCapabilities/Read", in, out, opts...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return out, nil
|
||||
}
|
||||
|
||||
func (c *providerCapabilitiesClient) Write(ctx context.Context, in *vagrant_io.WriteRequest, opts ...grpc.CallOption) (*vagrant_io.WriteResponse, error) {
|
||||
out := new(vagrant_io.WriteResponse)
|
||||
err := c.cc.Invoke(ctx, "/vagrant.caps.ProviderCapabilities/Write", in, out, opts...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return out, nil
|
||||
}
|
||||
|
||||
// ProviderCapabilitiesServer is the server API for ProviderCapabilities service.
|
||||
type ProviderCapabilitiesServer interface {
|
||||
ProviderCapabilities(context.Context, *vagrant_common.NullRequest) (*ProviderCapabilitiesResponse, error)
|
||||
ProviderCapability(context.Context, *ProviderCapabilityRequest) (*ProviderCapabilityResponse, error)
|
||||
// These are IO helpers for streaming
|
||||
Read(context.Context, *vagrant_io.ReadRequest) (*vagrant_io.ReadResponse, error)
|
||||
Write(context.Context, *vagrant_io.WriteRequest) (*vagrant_io.WriteResponse, error)
|
||||
}
|
||||
|
||||
func RegisterProviderCapabilitiesServer(s *grpc.Server, srv ProviderCapabilitiesServer) {
|
||||
|
@ -803,6 +964,42 @@ func _ProviderCapabilities_ProviderCapability_Handler(srv interface{}, ctx conte
|
|||
return interceptor(ctx, in, info, handler)
|
||||
}
|
||||
|
||||
func _ProviderCapabilities_Read_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
|
||||
in := new(vagrant_io.ReadRequest)
|
||||
if err := dec(in); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if interceptor == nil {
|
||||
return srv.(ProviderCapabilitiesServer).Read(ctx, in)
|
||||
}
|
||||
info := &grpc.UnaryServerInfo{
|
||||
Server: srv,
|
||||
FullMethod: "/vagrant.caps.ProviderCapabilities/Read",
|
||||
}
|
||||
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
|
||||
return srv.(ProviderCapabilitiesServer).Read(ctx, req.(*vagrant_io.ReadRequest))
|
||||
}
|
||||
return interceptor(ctx, in, info, handler)
|
||||
}
|
||||
|
||||
func _ProviderCapabilities_Write_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
|
||||
in := new(vagrant_io.WriteRequest)
|
||||
if err := dec(in); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if interceptor == nil {
|
||||
return srv.(ProviderCapabilitiesServer).Write(ctx, in)
|
||||
}
|
||||
info := &grpc.UnaryServerInfo{
|
||||
Server: srv,
|
||||
FullMethod: "/vagrant.caps.ProviderCapabilities/Write",
|
||||
}
|
||||
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
|
||||
return srv.(ProviderCapabilitiesServer).Write(ctx, req.(*vagrant_io.WriteRequest))
|
||||
}
|
||||
return interceptor(ctx, in, info, handler)
|
||||
}
|
||||
|
||||
var _ProviderCapabilities_serviceDesc = grpc.ServiceDesc{
|
||||
ServiceName: "vagrant.caps.ProviderCapabilities",
|
||||
HandlerType: (*ProviderCapabilitiesServer)(nil),
|
||||
|
@ -815,6 +1012,14 @@ var _ProviderCapabilities_serviceDesc = grpc.ServiceDesc{
|
|||
MethodName: "ProviderCapability",
|
||||
Handler: _ProviderCapabilities_ProviderCapability_Handler,
|
||||
},
|
||||
{
|
||||
MethodName: "Read",
|
||||
Handler: _ProviderCapabilities_Read_Handler,
|
||||
},
|
||||
{
|
||||
MethodName: "Write",
|
||||
Handler: _ProviderCapabilities_Write_Handler,
|
||||
},
|
||||
},
|
||||
Streams: []grpc.StreamDesc{},
|
||||
Metadata: "vagrant_caps/capabilities.proto",
|
||||
|
@ -823,37 +1028,40 @@ var _ProviderCapabilities_serviceDesc = grpc.ServiceDesc{
|
|||
func init() { proto.RegisterFile("vagrant_caps/capabilities.proto", fileDescriptor_591a3013bd09a9cb) }
|
||||
|
||||
var fileDescriptor_591a3013bd09a9cb = []byte{
|
||||
// 510 bytes of a gzipped FileDescriptorProto
|
||||
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xac, 0x95, 0xcf, 0x6e, 0xd3, 0x40,
|
||||
0x10, 0xc6, 0xb5, 0x14, 0x0a, 0x9d, 0x56, 0xfc, 0x59, 0x85, 0x60, 0x4c, 0x25, 0x22, 0x53, 0x44,
|
||||
0x84, 0x84, 0x2d, 0x85, 0x0b, 0x87, 0x1e, 0x90, 0xa8, 0x28, 0xe2, 0x80, 0x50, 0xe0, 0x56, 0x89,
|
||||
0x6a, 0x63, 0x16, 0x7b, 0x91, 0xbd, 0x6b, 0x76, 0xd7, 0x11, 0xe5, 0x11, 0xb8, 0x71, 0xe0, 0x8d,
|
||||
0xb8, 0xf0, 0x16, 0x3c, 0x0a, 0xb2, 0xbd, 0x71, 0xed, 0x7a, 0x5d, 0x97, 0xd2, 0x53, 0x32, 0x93,
|
||||
0x99, 0xf9, 0xe6, 0xfb, 0xd9, 0x9a, 0xc0, 0xfd, 0x25, 0x89, 0x24, 0xe1, 0xfa, 0x30, 0x24, 0x99,
|
||||
0x0a, 0x42, 0x92, 0x91, 0x05, 0x4b, 0x98, 0x66, 0x54, 0xf9, 0x99, 0x14, 0x5a, 0xe0, 0x2d, 0x53,
|
||||
0xe0, 0x17, 0x05, 0xee, 0x41, 0xc4, 0x74, 0x9c, 0x2f, 0xfc, 0x50, 0xa4, 0x41, 0x4c, 0x54, 0xcc,
|
||||
0x42, 0x21, 0xb3, 0xc0, 0x94, 0x04, 0xf4, 0xab, 0x0e, 0x22, 0xf1, 0x24, 0x4b, 0xf2, 0x88, 0xf1,
|
||||
0x3a, 0x6b, 0xc2, 0x72, 0x5c, 0x50, 0xcb, 0x89, 0x34, 0x15, 0x3c, 0xa8, 0x3e, 0x2a, 0x29, 0x6f,
|
||||
0x17, 0xe0, 0xc5, 0x6a, 0x81, 0x23, 0x8c, 0xe1, 0x32, 0x27, 0x29, 0x75, 0xd0, 0x04, 0x4d, 0x37,
|
||||
0xe6, 0xe5, 0x77, 0xec, 0xc2, 0xb5, 0x2c, 0x21, 0xfa, 0x93, 0x90, 0xa9, 0x73, 0xa9, 0xcc, 0xd7,
|
||||
0xb1, 0xb7, 0x07, 0xf8, 0xad, 0x14, 0x4b, 0xf6, 0x91, 0xca, 0x33, 0x4c, 0x31, 0x95, 0xf5, 0x14,
|
||||
0x13, 0x7b, 0xdf, 0x60, 0xbb, 0x33, 0x85, 0x51, 0x35, 0xa7, 0x2a, 0x13, 0x5c, 0x51, 0xbc, 0x07,
|
||||
0x5b, 0x4d, 0x48, 0x0e, 0x9a, 0xac, 0x4d, 0x37, 0x67, 0x13, 0xbf, 0x49, 0xc9, 0xef, 0xee, 0x31,
|
||||
0x6f, 0x75, 0xe1, 0x11, 0x5c, 0xa1, 0x52, 0x8a, 0x95, 0x7c, 0x15, 0x78, 0x3f, 0x11, 0xdc, 0xb5,
|
||||
0xb4, 0xd2, 0x2f, 0x39, 0x55, 0x1a, 0x3f, 0x07, 0xa8, 0x67, 0x1c, 0x95, 0x7e, 0xce, 0xa2, 0xdb,
|
||||
0xe8, 0xc1, 0x0e, 0x5c, 0x4d, 0x49, 0x18, 0x33, 0x4e, 0x8d, 0xee, 0x2a, 0xc4, 0xdb, 0xb0, 0x41,
|
||||
0x64, 0x94, 0xa7, 0x94, 0x6b, 0xe5, 0xac, 0x95, 0xbf, 0x1d, 0x27, 0xbc, 0xd7, 0xe0, 0xda, 0xd6,
|
||||
0x32, 0x44, 0xc6, 0xb0, 0x2e, 0xa9, 0xca, 0x13, 0x6d, 0x18, 0x9b, 0xa8, 0xc7, 0xe3, 0x67, 0x18,
|
||||
0x59, 0xb9, 0xee, 0x5a, 0xb9, 0x3a, 0x6d, 0x7f, 0xff, 0xc8, 0xf3, 0x3b, 0x82, 0xf1, 0x7e, 0xc1,
|
||||
0xae, 0x0b, 0xf3, 0x99, 0x05, 0x66, 0xbf, 0xd8, 0x45, 0x40, 0xdc, 0x87, 0x3b, 0x9d, 0x5d, 0xce,
|
||||
0x45, 0xf0, 0x07, 0x82, 0xdb, 0xaf, 0xc4, 0xc5, 0x9a, 0x9a, 0xc0, 0x26, 0xe5, 0x4b, 0x26, 0x05,
|
||||
0x2f, 0x96, 0x35, 0x7a, 0xcd, 0xd4, 0x80, 0xb9, 0x97, 0x30, 0x3e, 0xb9, 0xd2, 0x79, 0xbc, 0xcd,
|
||||
0x7e, 0x23, 0xb8, 0xd5, 0xa6, 0x54, 0x3c, 0xdd, 0xf7, 0xb6, 0xe4, 0xbd, 0x63, 0x63, 0xd5, 0x0d,
|
||||
0x79, 0x93, 0x27, 0x89, 0x21, 0xe1, 0x7a, 0x3d, 0xae, 0x9b, 0x6f, 0xdc, 0x07, 0xb8, 0x71, 0xe2,
|
||||
0x81, 0xe0, 0x9d, 0x76, 0x9b, 0xfd, 0xdd, 0x71, 0x1f, 0x0e, 0x54, 0x55, 0xf3, 0x67, 0xbf, 0x10,
|
||||
0xdc, 0x6c, 0x41, 0x29, 0xb6, 0x7e, 0x67, 0xc9, 0xfd, 0xb7, 0x93, 0x03, 0xb8, 0xde, 0xa6, 0x8f,
|
||||
0x1f, 0xb4, 0xbb, 0xac, 0xaf, 0x8b, 0xbb, 0x73, 0x7a, 0x91, 0xb1, 0xf1, 0x07, 0xc1, 0xc8, 0x76,
|
||||
0x11, 0xf1, 0x61, 0x4f, 0xfe, 0x54, 0x3b, 0x8f, 0x07, 0x0e, 0x56, 0xd3, 0x56, 0x64, 0x3d, 0xe8,
|
||||
0x8f, 0x06, 0x4f, 0x9e, 0x91, 0x9a, 0x0e, 0x17, 0x56, 0x42, 0x8b, 0xf5, 0xf2, 0xef, 0xe7, 0xe9,
|
||||
0xdf, 0x00, 0x00, 0x00, 0xff, 0xff, 0x7b, 0xfc, 0x96, 0xa9, 0x0c, 0x07, 0x00, 0x00,
|
||||
// 560 bytes of a gzipped FileDescriptorProto
|
||||
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xc4, 0x95, 0x4d, 0x6f, 0xd3, 0x30,
|
||||
0x18, 0xc7, 0x95, 0xee, 0x05, 0xf6, 0x6c, 0xe2, 0xc5, 0x2a, 0x5d, 0x16, 0x26, 0x51, 0x85, 0x21,
|
||||
0x2a, 0x24, 0x12, 0xa9, 0x5c, 0x40, 0xda, 0x01, 0x89, 0x89, 0x21, 0x0e, 0x08, 0x75, 0x48, 0x1c,
|
||||
0x26, 0x31, 0xb9, 0x9d, 0x49, 0x8d, 0x12, 0x3b, 0xd8, 0x4e, 0xc5, 0xf8, 0x08, 0xdc, 0x38, 0xf0,
|
||||
0x71, 0xb8, 0xf0, 0x2d, 0xf8, 0x36, 0x28, 0x89, 0x93, 0x25, 0x8b, 0xbb, 0x8c, 0xad, 0xd2, 0x4e,
|
||||
0xed, 0xf3, 0xf8, 0x79, 0xfb, 0xff, 0xec, 0xd8, 0xf0, 0x60, 0x86, 0x03, 0x81, 0x99, 0x3a, 0x9a,
|
||||
0xe0, 0x58, 0xfa, 0x13, 0x1c, 0xe3, 0x31, 0x0d, 0xa9, 0xa2, 0x44, 0x7a, 0xb1, 0xe0, 0x8a, 0xa3,
|
||||
0x0d, 0x1d, 0xe0, 0xa5, 0x01, 0xce, 0x61, 0x40, 0xd5, 0x34, 0x19, 0x7b, 0x13, 0x1e, 0xf9, 0x53,
|
||||
0x2c, 0xa7, 0x74, 0xc2, 0x45, 0xec, 0xeb, 0x10, 0x9f, 0x7c, 0x53, 0x7e, 0xc0, 0x9f, 0xc6, 0x61,
|
||||
0x12, 0x50, 0x56, 0x7a, 0xb5, 0x99, 0x95, 0xf3, 0xcb, 0x76, 0x3c, 0x8a, 0x38, 0xf3, 0xf3, 0x9f,
|
||||
0xbc, 0x95, 0x73, 0xb0, 0xa8, 0xe2, 0x94, 0xfb, 0x94, 0xe7, 0x45, 0xdd, 0x5d, 0x80, 0x57, 0x85,
|
||||
0xaa, 0x13, 0x84, 0x60, 0x99, 0xe1, 0x88, 0xd8, 0x56, 0xdf, 0x1a, 0xac, 0x8d, 0xb2, 0xff, 0xc8,
|
||||
0x81, 0x9b, 0x71, 0x88, 0xd5, 0x67, 0x2e, 0x22, 0xbb, 0x93, 0xf9, 0x4b, 0xdb, 0xdd, 0x03, 0xf4,
|
||||
0x5e, 0xf0, 0x19, 0x3d, 0x26, 0xe2, 0x02, 0x55, 0x74, 0x64, 0x59, 0x45, 0xdb, 0xee, 0x77, 0xd8,
|
||||
0x6e, 0x54, 0xa1, 0x44, 0x8e, 0x88, 0x8c, 0x39, 0x93, 0x04, 0xed, 0xc1, 0x46, 0x95, 0xbc, 0x6d,
|
||||
0xf5, 0x97, 0x06, 0xeb, 0xc3, 0xbe, 0x57, 0x45, 0xef, 0x35, 0xe7, 0x18, 0xd5, 0xb2, 0x50, 0x17,
|
||||
0x56, 0x88, 0x10, 0xbc, 0x68, 0x9f, 0x1b, 0xee, 0x2f, 0x0b, 0xb6, 0x0c, 0xa9, 0xe4, 0x6b, 0x42,
|
||||
0xa4, 0x42, 0x2f, 0x01, 0xca, 0x1a, 0x27, 0x99, 0x9e, 0x8b, 0xf4, 0xad, 0xe4, 0x20, 0x1b, 0x6e,
|
||||
0x44, 0x78, 0x32, 0xa5, 0x8c, 0xe8, 0xbe, 0x85, 0x89, 0xb6, 0x61, 0x0d, 0x8b, 0x20, 0x89, 0x08,
|
||||
0x53, 0xd2, 0x5e, 0xca, 0xd6, 0x4e, 0x1d, 0xee, 0x5b, 0x70, 0x4c, 0x63, 0x69, 0x22, 0x3d, 0x58,
|
||||
0x15, 0x44, 0x26, 0xa1, 0xd2, 0x8c, 0xb5, 0x35, 0x47, 0xe3, 0x17, 0xe8, 0x1a, 0xb9, 0xee, 0x1a,
|
||||
0xb9, 0xda, 0x75, 0x7d, 0xff, 0xc9, 0xf3, 0x87, 0x05, 0xbd, 0xfd, 0x94, 0x5d, 0x13, 0xe6, 0x73,
|
||||
0x03, 0xcc, 0xf9, 0xcd, 0x16, 0x01, 0x71, 0x1f, 0x36, 0x1b, 0xb3, 0x5c, 0x8a, 0xe0, 0x4f, 0x0b,
|
||||
0xee, 0xbd, 0xe1, 0x8b, 0x15, 0xd5, 0x87, 0x75, 0xc2, 0x66, 0x54, 0x70, 0x96, 0x0e, 0xab, 0xfb,
|
||||
0x55, 0x5d, 0x2d, 0xe2, 0x5e, 0x43, 0xef, 0xec, 0x48, 0x97, 0xd1, 0x36, 0xfc, 0xd3, 0x81, 0xbb,
|
||||
0x75, 0x4a, 0xe9, 0xee, 0x7e, 0x30, 0x39, 0xef, 0x9f, 0x0a, 0xcb, 0x2f, 0xa6, 0x77, 0x49, 0x18,
|
||||
0x6a, 0x12, 0x8e, 0x3b, 0x47, 0x75, 0xf5, 0xc4, 0x7d, 0x82, 0xdb, 0x67, 0x36, 0x04, 0xed, 0xd4,
|
||||
0xd3, 0xcc, 0x67, 0xc7, 0x79, 0xd4, 0x12, 0xa5, 0xeb, 0xbf, 0x80, 0xe5, 0x11, 0xc1, 0xc7, 0x68,
|
||||
0xb3, 0x0c, 0xa7, 0xdc, 0x4b, 0x3d, 0x45, 0x1d, 0xbb, 0xb9, 0x50, 0x7e, 0x0c, 0x2b, 0x1f, 0x05,
|
||||
0x55, 0x04, 0xd5, 0x42, 0x32, 0x57, 0x91, 0xbc, 0x65, 0x58, 0xc9, 0xb3, 0x87, 0xbf, 0x3b, 0x70,
|
||||
0xa7, 0xb6, 0x1b, 0x29, 0xae, 0x03, 0x83, 0xef, 0xca, 0x08, 0x0f, 0xe1, 0x56, 0x7d, 0xdb, 0xd1,
|
||||
0xc3, 0x7a, 0x96, 0xf1, 0x9c, 0x3a, 0x3b, 0xe7, 0x07, 0x5d, 0x37, 0xbf, 0xbf, 0x1d, 0xe8, 0x9a,
|
||||
0xde, 0x00, 0x74, 0x34, 0xc7, 0x7f, 0x2e, 0xc7, 0x27, 0x2d, 0x57, 0x74, 0x95, 0x67, 0x60, 0x7c,
|
||||
0xc2, 0x1e, 0xb7, 0x5e, 0xf2, 0xba, 0xd5, 0xa0, 0x3d, 0xf0, 0x9a, 0xd9, 0x8e, 0x57, 0xb3, 0x97,
|
||||
0xfe, 0xd9, 0xbf, 0x00, 0x00, 0x00, 0xff, 0xff, 0x37, 0xe6, 0x14, 0x9d, 0xcc, 0x08, 0x00, 0x00,
|
||||
}
|
||||
|
|
|
@ -2,6 +2,7 @@ syntax = "proto3";
|
|||
package vagrant.caps;
|
||||
|
||||
import "github.com/hashicorp/vagrant/ext/go-plugin/vagrant/plugin/proto/vagrant_common/common.proto";
|
||||
import "github.com/hashicorp/vagrant/ext/go-plugin/vagrant/plugin/proto/vagrant_io/io.proto";
|
||||
|
||||
message Capability {
|
||||
string name = 1;
|
||||
|
@ -59,14 +60,23 @@ message HostCapabilityResponse {
|
|||
service GuestCapabilities {
|
||||
rpc GuestCapabilities(vagrant.common.NullRequest) returns (CapabilitiesResponse);
|
||||
rpc GuestCapability(GuestCapabilityRequest) returns (GuestCapabilityResponse);
|
||||
// These are IO helpers for streaming
|
||||
rpc Read(vagrant.io.ReadRequest) returns (vagrant.io.ReadResponse);
|
||||
rpc Write(vagrant.io.WriteRequest) returns (vagrant.io.WriteResponse);
|
||||
}
|
||||
|
||||
service HostCapabilities {
|
||||
rpc HostCapabilities(vagrant.common.NullRequest) returns (CapabilitiesResponse);
|
||||
rpc HostCapability(HostCapabilityRequest) returns (HostCapabilityResponse);
|
||||
// These are IO helpers for streaming
|
||||
rpc Read(vagrant.io.ReadRequest) returns (vagrant.io.ReadResponse);
|
||||
rpc Write(vagrant.io.WriteRequest) returns (vagrant.io.WriteResponse);
|
||||
}
|
||||
|
||||
service ProviderCapabilities {
|
||||
rpc ProviderCapabilities(vagrant.common.NullRequest) returns (ProviderCapabilitiesResponse);
|
||||
rpc ProviderCapability(ProviderCapabilityRequest) returns (ProviderCapabilityResponse);
|
||||
// These are IO helpers for streaming
|
||||
rpc Read(vagrant.io.ReadRequest) returns (vagrant.io.ReadResponse);
|
||||
rpc Write(vagrant.io.WriteRequest) returns (vagrant.io.WriteResponse);
|
||||
}
|
|
@ -7,6 +7,7 @@ import proto "github.com/golang/protobuf/proto"
|
|||
import fmt "fmt"
|
||||
import math "math"
|
||||
import vagrant_common "github.com/hashicorp/vagrant/ext/go-plugin/vagrant/plugin/proto/vagrant_common"
|
||||
import vagrant_io "github.com/hashicorp/vagrant/ext/go-plugin/vagrant/plugin/proto/vagrant_io"
|
||||
|
||||
import (
|
||||
context "golang.org/x/net/context"
|
||||
|
@ -356,6 +357,9 @@ type ConfigClient interface {
|
|||
ConfigLoad(ctx context.Context, in *LoadRequest, opts ...grpc.CallOption) (*LoadResponse, error)
|
||||
ConfigValidate(ctx context.Context, in *ValidateRequest, opts ...grpc.CallOption) (*ValidateResponse, error)
|
||||
ConfigFinalize(ctx context.Context, in *FinalizeRequest, opts ...grpc.CallOption) (*FinalizeResponse, error)
|
||||
// These are IO helpers for streaming
|
||||
Read(ctx context.Context, in *vagrant_io.ReadRequest, opts ...grpc.CallOption) (*vagrant_io.ReadResponse, error)
|
||||
Write(ctx context.Context, in *vagrant_io.WriteRequest, opts ...grpc.CallOption) (*vagrant_io.WriteResponse, error)
|
||||
}
|
||||
|
||||
type configClient struct {
|
||||
|
@ -402,12 +406,33 @@ func (c *configClient) ConfigFinalize(ctx context.Context, in *FinalizeRequest,
|
|||
return out, nil
|
||||
}
|
||||
|
||||
func (c *configClient) Read(ctx context.Context, in *vagrant_io.ReadRequest, opts ...grpc.CallOption) (*vagrant_io.ReadResponse, error) {
|
||||
out := new(vagrant_io.ReadResponse)
|
||||
err := c.cc.Invoke(ctx, "/vagrant.config.Config/Read", in, out, opts...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return out, nil
|
||||
}
|
||||
|
||||
func (c *configClient) Write(ctx context.Context, in *vagrant_io.WriteRequest, opts ...grpc.CallOption) (*vagrant_io.WriteResponse, error) {
|
||||
out := new(vagrant_io.WriteResponse)
|
||||
err := c.cc.Invoke(ctx, "/vagrant.config.Config/Write", in, out, opts...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return out, nil
|
||||
}
|
||||
|
||||
// ConfigServer is the server API for Config service.
|
||||
type ConfigServer interface {
|
||||
ConfigAttributes(context.Context, *vagrant_common.NullRequest) (*AttributesResponse, error)
|
||||
ConfigLoad(context.Context, *LoadRequest) (*LoadResponse, error)
|
||||
ConfigValidate(context.Context, *ValidateRequest) (*ValidateResponse, error)
|
||||
ConfigFinalize(context.Context, *FinalizeRequest) (*FinalizeResponse, error)
|
||||
// These are IO helpers for streaming
|
||||
Read(context.Context, *vagrant_io.ReadRequest) (*vagrant_io.ReadResponse, error)
|
||||
Write(context.Context, *vagrant_io.WriteRequest) (*vagrant_io.WriteResponse, error)
|
||||
}
|
||||
|
||||
func RegisterConfigServer(s *grpc.Server, srv ConfigServer) {
|
||||
|
@ -486,6 +511,42 @@ func _Config_ConfigFinalize_Handler(srv interface{}, ctx context.Context, dec fu
|
|||
return interceptor(ctx, in, info, handler)
|
||||
}
|
||||
|
||||
func _Config_Read_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
|
||||
in := new(vagrant_io.ReadRequest)
|
||||
if err := dec(in); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if interceptor == nil {
|
||||
return srv.(ConfigServer).Read(ctx, in)
|
||||
}
|
||||
info := &grpc.UnaryServerInfo{
|
||||
Server: srv,
|
||||
FullMethod: "/vagrant.config.Config/Read",
|
||||
}
|
||||
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
|
||||
return srv.(ConfigServer).Read(ctx, req.(*vagrant_io.ReadRequest))
|
||||
}
|
||||
return interceptor(ctx, in, info, handler)
|
||||
}
|
||||
|
||||
func _Config_Write_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
|
||||
in := new(vagrant_io.WriteRequest)
|
||||
if err := dec(in); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if interceptor == nil {
|
||||
return srv.(ConfigServer).Write(ctx, in)
|
||||
}
|
||||
info := &grpc.UnaryServerInfo{
|
||||
Server: srv,
|
||||
FullMethod: "/vagrant.config.Config/Write",
|
||||
}
|
||||
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
|
||||
return srv.(ConfigServer).Write(ctx, req.(*vagrant_io.WriteRequest))
|
||||
}
|
||||
return interceptor(ctx, in, info, handler)
|
||||
}
|
||||
|
||||
var _Config_serviceDesc = grpc.ServiceDesc{
|
||||
ServiceName: "vagrant.config.Config",
|
||||
HandlerType: (*ConfigServer)(nil),
|
||||
|
@ -506,6 +567,14 @@ var _Config_serviceDesc = grpc.ServiceDesc{
|
|||
MethodName: "ConfigFinalize",
|
||||
Handler: _Config_ConfigFinalize_Handler,
|
||||
},
|
||||
{
|
||||
MethodName: "Read",
|
||||
Handler: _Config_Read_Handler,
|
||||
},
|
||||
{
|
||||
MethodName: "Write",
|
||||
Handler: _Config_Write_Handler,
|
||||
},
|
||||
},
|
||||
Streams: []grpc.StreamDesc{},
|
||||
Metadata: "vagrant_config/config.proto",
|
||||
|
@ -514,28 +583,31 @@ var _Config_serviceDesc = grpc.ServiceDesc{
|
|||
func init() { proto.RegisterFile("vagrant_config/config.proto", fileDescriptor_952629f1a9a7438c) }
|
||||
|
||||
var fileDescriptor_952629f1a9a7438c = []byte{
|
||||
// 363 bytes of a gzipped FileDescriptorProto
|
||||
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x94, 0x92, 0xc1, 0x4b, 0xfb, 0x30,
|
||||
0x14, 0xc7, 0xd9, 0x7e, 0x3f, 0x27, 0x7b, 0xca, 0x36, 0x82, 0x48, 0xe9, 0x44, 0x67, 0x41, 0xd8,
|
||||
0xc5, 0x06, 0xf4, 0xe2, 0x41, 0x50, 0x11, 0x14, 0x44, 0x3c, 0x74, 0xe0, 0xc5, 0x83, 0x64, 0x5d,
|
||||
0x6c, 0x03, 0x6d, 0x52, 0xd3, 0x54, 0xc4, 0xbf, 0xd2, 0x3f, 0x49, 0x4c, 0xd2, 0x75, 0xeb, 0xd6,
|
||||
0x81, 0xa7, 0xe4, 0xbd, 0x7c, 0xf3, 0x79, 0xc9, 0xfb, 0x3e, 0x18, 0x7e, 0x90, 0x48, 0x12, 0xae,
|
||||
0x5e, 0x43, 0xc1, 0xdf, 0x58, 0x84, 0xcd, 0xe2, 0x67, 0x52, 0x28, 0x81, 0x7a, 0xf6, 0xd0, 0x37,
|
||||
0x59, 0xf7, 0x25, 0x62, 0x2a, 0x2e, 0xa6, 0x7e, 0x28, 0x52, 0x1c, 0x93, 0x3c, 0x66, 0xa1, 0x90,
|
||||
0x19, 0xb6, 0x22, 0x4c, 0x3f, 0x15, 0x8e, 0xc4, 0x69, 0x96, 0x14, 0x11, 0xe3, 0xf3, 0xac, 0x0d,
|
||||
0x35, 0x10, 0x57, 0xc5, 0xd2, 0x54, 0x70, 0x6c, 0x16, 0x53, 0xcc, 0x7b, 0x00, 0x74, 0xa3, 0x94,
|
||||
0x64, 0xd3, 0x42, 0xd1, 0x3c, 0xa0, 0x79, 0x26, 0x78, 0x4e, 0xd1, 0x21, 0x00, 0x99, 0x67, 0x9d,
|
||||
0xd6, 0xe8, 0xdf, 0xb8, 0x1b, 0x2c, 0x64, 0xd0, 0x1e, 0x6c, 0x51, 0x29, 0x85, 0x74, 0xda, 0xa3,
|
||||
0xd6, 0xb8, 0x1b, 0x98, 0xc0, 0x3b, 0x86, 0x9d, 0x47, 0x41, 0x66, 0x01, 0x7d, 0x2f, 0x68, 0xae,
|
||||
0x10, 0x82, 0xff, 0x33, 0xa2, 0x88, 0xd3, 0xd2, 0x1a, 0xbd, 0xf7, 0x2e, 0x60, 0xd7, 0x48, 0x6c,
|
||||
0xa1, 0x35, 0x9a, 0x06, 0xf8, 0x15, 0xf4, 0x9f, 0x49, 0xc2, 0x66, 0x44, 0xd1, 0x0d, 0x05, 0x90,
|
||||
0x03, 0xdb, 0x29, 0x09, 0x63, 0xc6, 0xa9, 0xbd, 0x5e, 0x86, 0xde, 0x35, 0x0c, 0x2a, 0x80, 0x2d,
|
||||
0xbf, 0x0f, 0x1d, 0x4d, 0x2f, 0xff, 0x68, 0xa3, 0x86, 0x27, 0x9c, 0x40, 0xff, 0x8e, 0x71, 0x92,
|
||||
0xb0, 0xaf, 0x4d, 0x4f, 0xf0, 0x2e, 0x61, 0x50, 0xc9, 0xfe, 0xfa, 0xcf, 0xb3, 0xef, 0x36, 0x74,
|
||||
0x6e, 0xb5, 0xf1, 0x68, 0x02, 0x03, 0xb3, 0xab, 0x1c, 0x42, 0x43, 0xbf, 0x9a, 0x0e, 0x6d, 0xe3,
|
||||
0x53, 0x91, 0x24, 0xf6, 0x35, 0xae, 0xe7, 0x2f, 0x8f, 0x8e, 0xbf, 0xc6, 0xda, 0x7b, 0x00, 0x03,
|
||||
0xfd, 0xf5, 0x61, 0x09, 0xa7, 0x6f, 0x2c, 0x18, 0xe8, 0x1e, 0xac, 0x3f, 0xb4, 0xa0, 0x09, 0xf4,
|
||||
0x0c, 0xa8, 0xec, 0x2a, 0x3a, 0xaa, 0xeb, 0x6b, 0x86, 0xb9, 0xa3, 0x66, 0x41, 0x1d, 0x5a, 0x76,
|
||||
0x70, 0x15, 0x5a, 0xb3, 0x60, 0x15, 0x5a, 0x6f, 0xfe, 0xb4, 0xa3, 0x47, 0xfd, 0xfc, 0x27, 0x00,
|
||||
0x00, 0xff, 0xff, 0xe0, 0x00, 0xbf, 0x51, 0x76, 0x03, 0x00, 0x00,
|
||||
// 415 bytes of a gzipped FileDescriptorProto
|
||||
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xac, 0x93, 0xdf, 0x6b, 0xdb, 0x30,
|
||||
0x10, 0xc7, 0xc9, 0xf2, 0x63, 0xe4, 0x36, 0x92, 0x20, 0xc6, 0xe6, 0x39, 0x63, 0xcb, 0x0c, 0x83,
|
||||
0xbc, 0xcc, 0x82, 0xed, 0x65, 0x83, 0xc0, 0x56, 0x0a, 0x2d, 0x94, 0xd2, 0x07, 0x07, 0xda, 0x87,
|
||||
0x3e, 0x14, 0xc5, 0x56, 0x6d, 0x81, 0x6d, 0xb9, 0xb2, 0x5c, 0x4a, 0xff, 0xc3, 0xfe, 0x57, 0x25,
|
||||
0x92, 0x1c, 0x27, 0xb6, 0x13, 0x28, 0xf4, 0xc9, 0xba, 0xbb, 0xef, 0x7d, 0x4e, 0xba, 0x3b, 0xc3,
|
||||
0xf4, 0x9e, 0x84, 0x82, 0xa4, 0xf2, 0xc6, 0xe7, 0xe9, 0x2d, 0x0b, 0xb1, 0xfe, 0xb8, 0x99, 0xe0,
|
||||
0x92, 0xa3, 0x91, 0x09, 0xba, 0xda, 0x6b, 0x5f, 0x87, 0x4c, 0x46, 0xc5, 0xca, 0xf5, 0x79, 0x82,
|
||||
0x23, 0x92, 0x47, 0xcc, 0xe7, 0x22, 0xc3, 0x46, 0x84, 0xe9, 0x83, 0xc4, 0x21, 0xff, 0x99, 0xc5,
|
||||
0x45, 0xc8, 0xd2, 0x8d, 0xd7, 0x98, 0x0a, 0x88, 0xab, 0x62, 0x49, 0xc2, 0x53, 0xac, 0x3f, 0xba,
|
||||
0x98, 0xbd, 0x7c, 0x2d, 0x38, 0xe3, 0x98, 0x71, 0x0d, 0x75, 0xce, 0x00, 0x1d, 0x49, 0x29, 0xd8,
|
||||
0xaa, 0x90, 0x34, 0xf7, 0x68, 0x9e, 0xf1, 0x34, 0xa7, 0xe8, 0x2b, 0x00, 0xd9, 0x78, 0xad, 0xce,
|
||||
0xac, 0x3b, 0x1f, 0x7a, 0x5b, 0x1e, 0xf4, 0x01, 0xfa, 0x54, 0x08, 0x2e, 0xac, 0x37, 0xb3, 0xce,
|
||||
0x7c, 0xe8, 0x69, 0xc3, 0xf9, 0x0e, 0xef, 0xce, 0x39, 0x09, 0x3c, 0x7a, 0x57, 0xd0, 0x5c, 0x22,
|
||||
0x04, 0xbd, 0x80, 0x48, 0x62, 0x75, 0x94, 0x46, 0x9d, 0x9d, 0x3f, 0xf0, 0x5e, 0x4b, 0x4c, 0xa1,
|
||||
0x16, 0xcd, 0x1e, 0xf8, 0x3f, 0x18, 0x5f, 0x92, 0x98, 0x05, 0x44, 0xd2, 0x03, 0x05, 0x90, 0x05,
|
||||
0x6f, 0x13, 0xe2, 0x47, 0x2c, 0xa5, 0x26, 0xbd, 0x34, 0x9d, 0xff, 0x30, 0xa9, 0x00, 0xa6, 0xfc,
|
||||
0x47, 0x18, 0x28, 0x7a, 0xf9, 0x46, 0x63, 0xed, 0xb9, 0xc2, 0x0f, 0x18, 0x9f, 0xb0, 0x94, 0xc4,
|
||||
0xec, 0xf1, 0xd0, 0x15, 0x9c, 0x05, 0x4c, 0x2a, 0xd9, 0x4b, 0xdf, 0xf9, 0xeb, 0xa9, 0x0b, 0x83,
|
||||
0x63, 0xb5, 0x4d, 0x68, 0x09, 0x13, 0x7d, 0xaa, 0x26, 0x84, 0xa6, 0x6e, 0xb5, 0x72, 0x6a, 0x37,
|
||||
0x2e, 0x8a, 0x38, 0x36, 0xb7, 0xb1, 0x1d, 0x77, 0x77, 0x1f, 0xdd, 0x96, 0xd1, 0x9e, 0x02, 0x68,
|
||||
0xe8, 0x7a, 0x0e, 0x3b, 0x38, 0x95, 0xb1, 0x35, 0x40, 0xfb, 0x4b, 0x7b, 0xd0, 0x80, 0x96, 0x30,
|
||||
0xd2, 0xa0, 0xb2, 0xab, 0xe8, 0x5b, 0x5d, 0x5f, 0x1b, 0x98, 0x3d, 0xdb, 0x2f, 0xa8, 0x43, 0xcb,
|
||||
0x0e, 0x36, 0xa1, 0xb5, 0x11, 0x34, 0xa1, 0x8d, 0xe6, 0xff, 0x85, 0x9e, 0x47, 0x49, 0x80, 0x3e,
|
||||
0x6d, 0x94, 0x8c, 0xbb, 0x6b, 0x4f, 0x89, 0xb0, 0x9a, 0x01, 0x93, 0xba, 0x80, 0xfe, 0x95, 0x60,
|
||||
0x92, 0xa2, 0x1d, 0x89, 0x72, 0x95, 0xc9, 0x9f, 0x5b, 0x22, 0x3a, 0x7b, 0x35, 0x50, 0xff, 0xd8,
|
||||
0xef, 0xe7, 0x00, 0x00, 0x00, 0xff, 0xff, 0x5f, 0x44, 0xad, 0xc6, 0x44, 0x04, 0x00, 0x00,
|
||||
}
|
||||
|
|
|
@ -2,6 +2,7 @@ syntax = "proto3";
|
|||
package vagrant.config;
|
||||
|
||||
import "github.com/hashicorp/vagrant/ext/go-plugin/vagrant/plugin/proto/vagrant_common/common.proto";
|
||||
import "github.com/hashicorp/vagrant/ext/go-plugin/vagrant/plugin/proto/vagrant_io/io.proto";
|
||||
|
||||
message AttributesResponse {
|
||||
repeated string attributes = 1;
|
||||
|
@ -41,4 +42,7 @@ service Config {
|
|||
rpc ConfigLoad(LoadRequest) returns (LoadResponse);
|
||||
rpc ConfigValidate(ValidateRequest) returns (ValidateResponse);
|
||||
rpc ConfigFinalize(FinalizeRequest) returns (FinalizeResponse);
|
||||
// These are IO helpers for streaming
|
||||
rpc Read(vagrant.io.ReadRequest) returns (vagrant.io.ReadResponse);
|
||||
rpc Write(vagrant.io.WriteRequest) returns (vagrant.io.WriteResponse);
|
||||
}
|
|
@ -2,6 +2,7 @@ package plugin
|
|||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
|
||||
"google.golang.org/grpc"
|
||||
|
@ -110,19 +111,26 @@ func (c *GRPCProviderClient) MachineIdChanged(m *vagrant.Machine) (err error) {
|
|||
return
|
||||
}
|
||||
|
||||
func (c *GRPCProviderClient) RunAction(actName string, runData string, m *vagrant.Machine) (r string, err error) {
|
||||
func (c *GRPCProviderClient) RunAction(actName string, args interface{}, m *vagrant.Machine) (r interface{}, err error) {
|
||||
machData, err := vagrant.DumpMachine(m)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
runData, err := json.Marshal(args)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
resp, err := c.client.RunAction(context.Background(), &vagrant_provider.RunActionRequest{
|
||||
Name: actName,
|
||||
Data: runData,
|
||||
Data: string(runData),
|
||||
Machine: machData})
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
r = resp.Data
|
||||
err = json.Unmarshal([]byte(resp.Data), &r)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
if resp.Error != "" {
|
||||
err = errors.New(resp.Error)
|
||||
}
|
||||
|
@ -178,10 +186,6 @@ func (c *GRPCProviderClient) Name() string {
|
|||
return resp.Name
|
||||
}
|
||||
|
||||
func (p *ProviderPlugin) GRPCServer(broker *go_plugin.GRPCBroker, s *grpc.Server) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (p *ProviderPlugin) GRPCClient(ctx context.Context, broker *go_plugin.GRPCBroker, c *grpc.ClientConn) (interface{}, error) {
|
||||
client := vagrant_provider.NewProviderClient(c)
|
||||
return &GRPCProviderClient{
|
||||
|
@ -199,12 +203,7 @@ func (p *ProviderPlugin) GRPCClient(ctx context.Context, broker *go_plugin.GRPCB
|
|||
}, nil
|
||||
}
|
||||
|
||||
type GRPCProviderPlugin struct {
|
||||
ProviderPlugin
|
||||
Impl Provider
|
||||
}
|
||||
|
||||
func (p *GRPCProviderPlugin) GRPCServer(broker *go_plugin.GRPCBroker, s *grpc.Server) error {
|
||||
func (p *ProviderPlugin) GRPCServer(broker *go_plugin.GRPCBroker, s *grpc.Server) error {
|
||||
p.Impl.Init()
|
||||
vagrant_provider.RegisterProviderServer(s, &GRPCProviderServer{
|
||||
Impl: p.Impl,
|
||||
|
@ -221,10 +220,6 @@ func (p *GRPCProviderPlugin) GRPCServer(broker *go_plugin.GRPCBroker, s *grpc.Se
|
|||
return nil
|
||||
}
|
||||
|
||||
func (p *GRPCProviderPlugin) GRPCClient(context.Context, *go_plugin.GRPCBroker, *grpc.ClientConn) (interface{}, error) {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
type GRPCProviderServer struct {
|
||||
GRPCIOServer
|
||||
GRPCConfigServer
|
||||
|
@ -257,12 +252,21 @@ func (s *GRPCProviderServer) RunAction(ctx context.Context, req *vagrant_provide
|
|||
resp.Error = e.Error()
|
||||
return
|
||||
}
|
||||
r, e := s.Impl.RunAction(req.Name, req.Data, m)
|
||||
var args interface{}
|
||||
err = json.Unmarshal([]byte(req.Data), &args)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
r, e := s.Impl.RunAction(req.Name, args, m)
|
||||
if e != nil {
|
||||
resp.Error = e.Error()
|
||||
return
|
||||
}
|
||||
resp.Data = r
|
||||
result, err := json.Marshal(r)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
resp.Data = string(result)
|
||||
return
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,313 @@
|
|||
package plugin
|
||||
|
||||
import (
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"github.com/hashicorp/go-plugin"
|
||||
"github.com/hashicorp/vagrant/ext/go-plugin/vagrant"
|
||||
)
|
||||
|
||||
func TestProvider_Action(t *testing.T) {
|
||||
client, server := plugin.TestPluginGRPCConn(t, map[string]plugin.Plugin{
|
||||
"provider": &ProviderPlugin{Impl: &MockProvider{}}})
|
||||
defer server.Stop()
|
||||
defer client.Close()
|
||||
|
||||
raw, err := client.Dispense("provider")
|
||||
if err != nil {
|
||||
t.Fatalf("err: %s", err)
|
||||
}
|
||||
impl, ok := raw.(Provider)
|
||||
if !ok {
|
||||
t.Fatalf("bad %#v", raw)
|
||||
}
|
||||
|
||||
resp, err := impl.Action("valid", &vagrant.Machine{})
|
||||
if err != nil {
|
||||
t.Fatalf("bad resp: %s", err)
|
||||
}
|
||||
if resp[0] != "self::DoTask" {
|
||||
t.Errorf("%s != self::DoTask", resp[0])
|
||||
}
|
||||
}
|
||||
|
||||
func TestProvider_Action_invalid(t *testing.T) {
|
||||
client, server := plugin.TestPluginGRPCConn(t, map[string]plugin.Plugin{
|
||||
"provider": &ProviderPlugin{Impl: &MockProvider{}}})
|
||||
defer server.Stop()
|
||||
defer client.Close()
|
||||
|
||||
raw, err := client.Dispense("provider")
|
||||
if err != nil {
|
||||
t.Fatalf("err: %s", err)
|
||||
}
|
||||
impl, ok := raw.(Provider)
|
||||
if !ok {
|
||||
t.Fatalf("bad %#v", raw)
|
||||
}
|
||||
|
||||
_, err = impl.Action("invalid", &vagrant.Machine{})
|
||||
if err == nil {
|
||||
t.Errorf("illegal action")
|
||||
}
|
||||
}
|
||||
|
||||
func TestProvider_IsInstalled(t *testing.T) {
|
||||
client, server := plugin.TestPluginGRPCConn(t, map[string]plugin.Plugin{
|
||||
"provider": &ProviderPlugin{Impl: &MockProvider{}}})
|
||||
defer server.Stop()
|
||||
defer client.Close()
|
||||
|
||||
raw, err := client.Dispense("provider")
|
||||
if err != nil {
|
||||
t.Fatalf("err: %s", err)
|
||||
}
|
||||
impl, ok := raw.(Provider)
|
||||
if !ok {
|
||||
t.Fatalf("bad %#v", raw)
|
||||
}
|
||||
|
||||
installed, err := impl.IsInstalled(&vagrant.Machine{})
|
||||
if err != nil {
|
||||
t.Fatalf("bad resp: %s", err)
|
||||
}
|
||||
if !installed {
|
||||
t.Errorf("bad result")
|
||||
}
|
||||
}
|
||||
|
||||
func TestProvider_IsUsable(t *testing.T) {
|
||||
client, server := plugin.TestPluginGRPCConn(t, map[string]plugin.Plugin{
|
||||
"provider": &ProviderPlugin{Impl: &MockProvider{}}})
|
||||
defer server.Stop()
|
||||
defer client.Close()
|
||||
|
||||
raw, err := client.Dispense("provider")
|
||||
if err != nil {
|
||||
t.Fatalf("err: %s", err)
|
||||
}
|
||||
impl, ok := raw.(Provider)
|
||||
if !ok {
|
||||
t.Fatalf("bad %#v", raw)
|
||||
}
|
||||
|
||||
usable, err := impl.IsUsable(&vagrant.Machine{})
|
||||
if err != nil {
|
||||
t.Fatalf("bad resp: %s", err)
|
||||
}
|
||||
if !usable {
|
||||
t.Errorf("bad result")
|
||||
}
|
||||
}
|
||||
|
||||
func TestProvider_MachineIdChanged(t *testing.T) {
|
||||
client, server := plugin.TestPluginGRPCConn(t, map[string]plugin.Plugin{
|
||||
"provider": &ProviderPlugin{Impl: &MockProvider{}}})
|
||||
defer server.Stop()
|
||||
defer client.Close()
|
||||
|
||||
raw, err := client.Dispense("provider")
|
||||
if err != nil {
|
||||
t.Fatalf("err: %s", err)
|
||||
}
|
||||
impl, ok := raw.(Provider)
|
||||
if !ok {
|
||||
t.Fatalf("bad %#v", raw)
|
||||
}
|
||||
|
||||
err = impl.MachineIdChanged(&vagrant.Machine{})
|
||||
if err != nil {
|
||||
t.Errorf("err: %s", err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestProvider_Name(t *testing.T) {
|
||||
client, server := plugin.TestPluginGRPCConn(t, map[string]plugin.Plugin{
|
||||
"provider": &ProviderPlugin{Impl: &MockProvider{}}})
|
||||
defer server.Stop()
|
||||
defer client.Close()
|
||||
|
||||
raw, err := client.Dispense("provider")
|
||||
if err != nil {
|
||||
t.Fatalf("err: %s", err)
|
||||
}
|
||||
impl, ok := raw.(Provider)
|
||||
if !ok {
|
||||
t.Fatalf("bad %#v", raw)
|
||||
}
|
||||
|
||||
resp := impl.Name()
|
||||
if resp != "mock_provider" {
|
||||
t.Errorf("%s != mock_provider", resp)
|
||||
}
|
||||
}
|
||||
|
||||
func TestProvider_RunAction(t *testing.T) {
|
||||
client, server := plugin.TestPluginGRPCConn(t, map[string]plugin.Plugin{
|
||||
"provider": &ProviderPlugin{Impl: &MockProvider{}}})
|
||||
defer server.Stop()
|
||||
defer client.Close()
|
||||
|
||||
raw, err := client.Dispense("provider")
|
||||
if err != nil {
|
||||
t.Fatalf("err: %s", err)
|
||||
}
|
||||
impl, ok := raw.(Provider)
|
||||
if !ok {
|
||||
t.Fatalf("bad %#v", raw)
|
||||
}
|
||||
|
||||
args := []string{"test_arg", "other_arg"}
|
||||
m := &vagrant.Machine{}
|
||||
|
||||
resp, err := impl.RunAction("valid", args, m)
|
||||
if err != nil {
|
||||
t.Fatalf("bad resp: %s", err)
|
||||
}
|
||||
|
||||
result := resp.([]interface{})
|
||||
if result[0] != "valid" {
|
||||
t.Errorf("%s != valid", result[0])
|
||||
}
|
||||
if result[1] != "test_arg" {
|
||||
t.Errorf("%s != test_arg", result[1])
|
||||
}
|
||||
}
|
||||
|
||||
func TestProvider_RunAction_invalid(t *testing.T) {
|
||||
client, server := plugin.TestPluginGRPCConn(t, map[string]plugin.Plugin{
|
||||
"provider": &ProviderPlugin{Impl: &MockProvider{}}})
|
||||
defer server.Stop()
|
||||
defer client.Close()
|
||||
|
||||
raw, err := client.Dispense("provider")
|
||||
if err != nil {
|
||||
t.Fatalf("err: %s", err)
|
||||
}
|
||||
impl, ok := raw.(Provider)
|
||||
if !ok {
|
||||
t.Fatalf("bad %#v", raw)
|
||||
}
|
||||
|
||||
args := []string{"test_arg", "other_arg"}
|
||||
m := &vagrant.Machine{}
|
||||
|
||||
_, err = impl.RunAction("invalid", args, m)
|
||||
if err == nil {
|
||||
t.Fatalf("illegal action run")
|
||||
}
|
||||
}
|
||||
|
||||
func TestProvider_SshInfo(t *testing.T) {
|
||||
client, server := plugin.TestPluginGRPCConn(t, map[string]plugin.Plugin{
|
||||
"provider": &ProviderPlugin{Impl: &MockProvider{}}})
|
||||
defer server.Stop()
|
||||
defer client.Close()
|
||||
|
||||
raw, err := client.Dispense("provider")
|
||||
if err != nil {
|
||||
t.Fatalf("err: %s", err)
|
||||
}
|
||||
impl, ok := raw.(Provider)
|
||||
if !ok {
|
||||
t.Fatalf("bad %#v", raw)
|
||||
}
|
||||
|
||||
resp, err := impl.SshInfo(&vagrant.Machine{})
|
||||
if err != nil {
|
||||
t.Fatalf("invalid resp: %s", err)
|
||||
}
|
||||
|
||||
if resp.Host != "localhost" {
|
||||
t.Errorf("%s != localhost", resp.Host)
|
||||
}
|
||||
if resp.Port != 2222 {
|
||||
t.Errorf("%d != 2222", resp.Port)
|
||||
}
|
||||
}
|
||||
|
||||
func TestProvider_State(t *testing.T) {
|
||||
client, server := plugin.TestPluginGRPCConn(t, map[string]plugin.Plugin{
|
||||
"provider": &ProviderPlugin{Impl: &MockProvider{}}})
|
||||
defer server.Stop()
|
||||
defer client.Close()
|
||||
|
||||
raw, err := client.Dispense("provider")
|
||||
if err != nil {
|
||||
t.Fatalf("err: %s", err)
|
||||
}
|
||||
impl, ok := raw.(Provider)
|
||||
if !ok {
|
||||
t.Fatalf("bad %#v", raw)
|
||||
}
|
||||
|
||||
resp, err := impl.State(&vagrant.Machine{})
|
||||
if err != nil {
|
||||
t.Fatalf("invalid resp: %s", err)
|
||||
}
|
||||
|
||||
if resp.Id != "default" {
|
||||
t.Errorf("%s != default", resp.Id)
|
||||
}
|
||||
if resp.ShortDesc != "running" {
|
||||
t.Errorf("%s != running", resp.ShortDesc)
|
||||
}
|
||||
}
|
||||
|
||||
func TestProvider_Info(t *testing.T) {
|
||||
client, server := plugin.TestPluginGRPCConn(t, map[string]plugin.Plugin{
|
||||
"provider": &ProviderPlugin{Impl: &MockProvider{}}})
|
||||
defer server.Stop()
|
||||
defer client.Close()
|
||||
|
||||
raw, err := client.Dispense("provider")
|
||||
if err != nil {
|
||||
t.Fatalf("err: %s", err)
|
||||
}
|
||||
impl, ok := raw.(Provider)
|
||||
if !ok {
|
||||
t.Fatalf("bad %#v", raw)
|
||||
}
|
||||
|
||||
resp := impl.Info()
|
||||
|
||||
if resp.Description != "Custom" {
|
||||
t.Errorf("%s != Custom", resp.Description)
|
||||
}
|
||||
if resp.Priority != 10 {
|
||||
t.Errorf("%d != 10", resp.Priority)
|
||||
}
|
||||
}
|
||||
|
||||
func TestProvider_MachineUI_output(t *testing.T) {
|
||||
client, server := plugin.TestPluginGRPCConn(t, map[string]plugin.Plugin{
|
||||
"provider": &ProviderPlugin{Impl: &MockProvider{}}})
|
||||
defer server.Stop()
|
||||
defer client.Close()
|
||||
|
||||
raw, err := client.Dispense("provider")
|
||||
if err != nil {
|
||||
t.Fatalf("err: %s", err)
|
||||
}
|
||||
impl, ok := raw.(Provider)
|
||||
if !ok {
|
||||
t.Fatalf("bad %#v", raw)
|
||||
}
|
||||
|
||||
go func() {
|
||||
_, err = impl.RunAction("send_output", nil, &vagrant.Machine{})
|
||||
if err != nil {
|
||||
t.Fatalf("bad resp: %s", err)
|
||||
}
|
||||
}()
|
||||
|
||||
resp, err := impl.Read("stdout")
|
||||
if err != nil {
|
||||
t.Fatalf("bad resp: %s", err)
|
||||
}
|
||||
|
||||
if !strings.Contains(resp, "test_output_p") {
|
||||
t.Errorf("%s !~ test_output_p", resp)
|
||||
}
|
||||
}
|
|
@ -31,7 +31,7 @@ type GRPCSyncedFolderClient struct {
|
|||
client vagrant_folder.SyncedFolderClient
|
||||
}
|
||||
|
||||
func (c *GRPCSyncedFolderClient) Cleanup(m *vagrant.Machine, o *vagrant.FolderOptions) (err error) {
|
||||
func (c *GRPCSyncedFolderClient) Cleanup(m *vagrant.Machine, o vagrant.FolderOptions) (err error) {
|
||||
machine, err := vagrant.DumpMachine(m)
|
||||
if err != nil {
|
||||
return
|
||||
|
@ -52,7 +52,7 @@ func (c *GRPCSyncedFolderClient) Cleanup(m *vagrant.Machine, o *vagrant.FolderOp
|
|||
return
|
||||
}
|
||||
|
||||
func (c *GRPCSyncedFolderClient) Disable(m *vagrant.Machine, f *vagrant.FolderList, o *vagrant.FolderOptions) (err error) {
|
||||
func (c *GRPCSyncedFolderClient) Disable(m *vagrant.Machine, f vagrant.FolderList, o vagrant.FolderOptions) (err error) {
|
||||
machine, err := vagrant.DumpMachine(m)
|
||||
if err != nil {
|
||||
return
|
||||
|
@ -78,7 +78,7 @@ func (c *GRPCSyncedFolderClient) Disable(m *vagrant.Machine, f *vagrant.FolderLi
|
|||
return
|
||||
}
|
||||
|
||||
func (c *GRPCSyncedFolderClient) Enable(m *vagrant.Machine, f *vagrant.FolderList, o *vagrant.FolderOptions) (err error) {
|
||||
func (c *GRPCSyncedFolderClient) Enable(m *vagrant.Machine, f vagrant.FolderList, o vagrant.FolderOptions) (err error) {
|
||||
machine, err := vagrant.DumpMachine(m)
|
||||
if err != nil {
|
||||
return
|
||||
|
@ -136,7 +136,7 @@ func (c *GRPCSyncedFolderClient) Name() string {
|
|||
return resp.Name
|
||||
}
|
||||
|
||||
func (c *GRPCSyncedFolderClient) Prepare(m *vagrant.Machine, f *vagrant.FolderList, o *vagrant.FolderOptions) (err error) {
|
||||
func (c *GRPCSyncedFolderClient) Prepare(m *vagrant.Machine, f vagrant.FolderList, o vagrant.FolderOptions) (err error) {
|
||||
machine, err := vagrant.DumpMachine(m)
|
||||
if err != nil {
|
||||
return
|
||||
|
@ -171,7 +171,7 @@ type GRPCSyncedFolderServer struct {
|
|||
|
||||
func (s *GRPCSyncedFolderServer) Cleanup(ctx context.Context, req *vagrant_folder.CleanupRequest) (resp *vagrant_common.EmptyResponse, err error) {
|
||||
resp = &vagrant_common.EmptyResponse{}
|
||||
machine, err := vagrant.LoadMachine(req.Machine, nil)
|
||||
machine, err := vagrant.LoadMachine(req.Machine, s.Impl)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
@ -180,7 +180,7 @@ func (s *GRPCSyncedFolderServer) Cleanup(ctx context.Context, req *vagrant_folde
|
|||
if err != nil {
|
||||
return
|
||||
}
|
||||
e := s.Impl.Cleanup(machine, &options)
|
||||
e := s.Impl.Cleanup(machine, options)
|
||||
if e != nil {
|
||||
resp.Error = e.Error()
|
||||
}
|
||||
|
@ -189,7 +189,7 @@ func (s *GRPCSyncedFolderServer) Cleanup(ctx context.Context, req *vagrant_folde
|
|||
|
||||
func (s *GRPCSyncedFolderServer) Disable(ctx context.Context, req *vagrant_folder.Request) (resp *vagrant_common.EmptyResponse, err error) {
|
||||
resp = &vagrant_common.EmptyResponse{}
|
||||
machine, err := vagrant.LoadMachine(req.Machine, nil)
|
||||
machine, err := vagrant.LoadMachine(req.Machine, s.Impl)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
@ -203,7 +203,7 @@ func (s *GRPCSyncedFolderServer) Disable(ctx context.Context, req *vagrant_folde
|
|||
if err != nil {
|
||||
return
|
||||
}
|
||||
e := s.Impl.Disable(machine, &folders, &options)
|
||||
e := s.Impl.Disable(machine, folders, options)
|
||||
if e != nil {
|
||||
resp.Error = e.Error()
|
||||
}
|
||||
|
@ -212,7 +212,7 @@ func (s *GRPCSyncedFolderServer) Disable(ctx context.Context, req *vagrant_folde
|
|||
|
||||
func (s *GRPCSyncedFolderServer) Enable(ctx context.Context, req *vagrant_folder.Request) (resp *vagrant_common.EmptyResponse, err error) {
|
||||
resp = &vagrant_common.EmptyResponse{}
|
||||
machine, err := vagrant.LoadMachine(req.Machine, nil)
|
||||
machine, err := vagrant.LoadMachine(req.Machine, s.Impl)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
@ -226,7 +226,7 @@ func (s *GRPCSyncedFolderServer) Enable(ctx context.Context, req *vagrant_folder
|
|||
if err != nil {
|
||||
return
|
||||
}
|
||||
e := s.Impl.Enable(machine, &folders, &options)
|
||||
e := s.Impl.Enable(machine, folders, options)
|
||||
if e != nil {
|
||||
resp.Error = e.Error()
|
||||
}
|
||||
|
@ -242,7 +242,7 @@ func (s *GRPCSyncedFolderServer) Info(ctx context.Context, req *vagrant_common.N
|
|||
|
||||
func (s *GRPCSyncedFolderServer) IsUsable(ctx context.Context, req *vagrant_common.EmptyRequest) (resp *vagrant_common.IsResponse, err error) {
|
||||
resp = &vagrant_common.IsResponse{}
|
||||
machine, err := vagrant.LoadMachine(req.Machine, nil)
|
||||
machine, err := vagrant.LoadMachine(req.Machine, s.Impl)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
@ -260,7 +260,7 @@ func (s *GRPCSyncedFolderServer) Name(ctx context.Context, req *vagrant_common.N
|
|||
|
||||
func (s *GRPCSyncedFolderServer) Prepare(ctx context.Context, req *vagrant_folder.Request) (resp *vagrant_common.EmptyResponse, err error) {
|
||||
resp = &vagrant_common.EmptyResponse{}
|
||||
machine, err := vagrant.LoadMachine(req.Machine, nil)
|
||||
machine, err := vagrant.LoadMachine(req.Machine, s.Impl)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
@ -274,7 +274,7 @@ func (s *GRPCSyncedFolderServer) Prepare(ctx context.Context, req *vagrant_folde
|
|||
if err != nil {
|
||||
return
|
||||
}
|
||||
e := s.Impl.Prepare(machine, &folders, &options)
|
||||
e := s.Impl.Prepare(machine, folders, options)
|
||||
if e != nil {
|
||||
resp.Error = e.Error()
|
||||
}
|
||||
|
@ -282,10 +282,27 @@ func (s *GRPCSyncedFolderServer) Prepare(ctx context.Context, req *vagrant_folde
|
|||
}
|
||||
|
||||
func (f *SyncedFolderPlugin) GRPCServer(broker *go_plugin.GRPCBroker, s *grpc.Server) error {
|
||||
vagrant_folder.RegisterSyncedFolderServer(s, &GRPCSyncedFolderServer{Impl: f.Impl})
|
||||
f.Impl.Init()
|
||||
vagrant_folder.RegisterSyncedFolderServer(s,
|
||||
&GRPCSyncedFolderServer{
|
||||
Impl: f.Impl,
|
||||
GRPCIOServer: GRPCIOServer{
|
||||
Impl: f.Impl},
|
||||
GRPCGuestCapabilitiesServer: GRPCGuestCapabilitiesServer{
|
||||
Impl: f.Impl},
|
||||
GRPCHostCapabilitiesServer: GRPCHostCapabilitiesServer{
|
||||
Impl: f.Impl}})
|
||||
return nil
|
||||
}
|
||||
|
||||
func (f *SyncedFolderPlugin) GRPCClient(ctx context.Context, broker *go_plugin.GRPCBroker, c *grpc.ClientConn) (interface{}, error) {
|
||||
return &GRPCSyncedFolderClient{client: vagrant_folder.NewSyncedFolderClient(c)}, nil
|
||||
client := vagrant_folder.NewSyncedFolderClient(c)
|
||||
return &GRPCSyncedFolderClient{
|
||||
GRPCIOClient: GRPCIOClient{
|
||||
client: client},
|
||||
GRPCGuestCapabilitiesClient: GRPCGuestCapabilitiesClient{
|
||||
client: client},
|
||||
GRPCHostCapabilitiesClient: GRPCHostCapabilitiesClient{
|
||||
client: client},
|
||||
client: client}, nil
|
||||
}
|
||||
|
|
|
@ -0,0 +1,368 @@
|
|||
package plugin
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"github.com/hashicorp/go-plugin"
|
||||
"github.com/hashicorp/vagrant/ext/go-plugin/vagrant"
|
||||
)
|
||||
|
||||
type MockSyncedFolder struct {
|
||||
Core
|
||||
vagrant.NoGuestCapabilities
|
||||
vagrant.NoHostCapabilities
|
||||
}
|
||||
|
||||
func (s *MockSyncedFolder) Cleanup(m *vagrant.Machine, opts vagrant.FolderOptions) error {
|
||||
if opts != nil {
|
||||
err, _ := opts["error"].(bool)
|
||||
ui, _ := opts["ui"].(bool)
|
||||
if err {
|
||||
return errors.New("cleanup error")
|
||||
}
|
||||
if ui {
|
||||
m.UI.Say("test_output_sf")
|
||||
return nil
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *MockSyncedFolder) Disable(m *vagrant.Machine, f vagrant.FolderList, opts vagrant.FolderOptions) error {
|
||||
if opts != nil && opts["error"].(bool) {
|
||||
return errors.New("disable error")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *MockSyncedFolder) Enable(m *vagrant.Machine, f vagrant.FolderList, opts vagrant.FolderOptions) error {
|
||||
if opts != nil && opts["error"].(bool) {
|
||||
return errors.New("enable error")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *MockSyncedFolder) Info() *vagrant.SyncedFolderInfo {
|
||||
return &vagrant.SyncedFolderInfo{
|
||||
Description: "mock_folder",
|
||||
Priority: 100}
|
||||
}
|
||||
|
||||
func (s *MockSyncedFolder) IsUsable(m *vagrant.Machine) (bool, error) {
|
||||
return true, nil
|
||||
}
|
||||
|
||||
func (s *MockSyncedFolder) Name() string {
|
||||
return "mock_folder"
|
||||
}
|
||||
|
||||
func (s *MockSyncedFolder) Prepare(m *vagrant.Machine, f vagrant.FolderList, opts vagrant.FolderOptions) error {
|
||||
if opts != nil && opts["error"].(bool) {
|
||||
return errors.New("prepare error")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func TestSyncedFolder_Cleanup(t *testing.T) {
|
||||
client, server := plugin.TestPluginGRPCConn(t, map[string]plugin.Plugin{
|
||||
"folder": &SyncedFolderPlugin{Impl: &MockSyncedFolder{}}})
|
||||
defer server.Stop()
|
||||
defer client.Close()
|
||||
|
||||
raw, err := client.Dispense("folder")
|
||||
if err != nil {
|
||||
t.Fatalf("err: %s", err)
|
||||
}
|
||||
impl, ok := raw.(SyncedFolder)
|
||||
if !ok {
|
||||
t.Fatalf("bad %#v", raw)
|
||||
}
|
||||
|
||||
err = impl.Cleanup(&vagrant.Machine{}, nil)
|
||||
if err != nil {
|
||||
t.Fatalf("bad resp: %s", err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestSyncedFolder_Cleanup_error(t *testing.T) {
|
||||
client, server := plugin.TestPluginGRPCConn(t, map[string]plugin.Plugin{
|
||||
"folder": &SyncedFolderPlugin{Impl: &MockSyncedFolder{}}})
|
||||
defer server.Stop()
|
||||
defer client.Close()
|
||||
|
||||
raw, err := client.Dispense("folder")
|
||||
if err != nil {
|
||||
t.Fatalf("err: %s", err)
|
||||
}
|
||||
impl, ok := raw.(SyncedFolder)
|
||||
if !ok {
|
||||
t.Fatalf("bad %#v", raw)
|
||||
}
|
||||
|
||||
args := map[string]interface{}{
|
||||
"error": true}
|
||||
|
||||
err = impl.Cleanup(&vagrant.Machine{}, args)
|
||||
if err == nil {
|
||||
t.Fatalf("illegal cleanup")
|
||||
}
|
||||
if err.Error() != "cleanup error" {
|
||||
t.Errorf("%s != cleanup error", err.Error())
|
||||
}
|
||||
}
|
||||
|
||||
func TestSyncedFolder_Disable(t *testing.T) {
|
||||
client, server := plugin.TestPluginGRPCConn(t, map[string]plugin.Plugin{
|
||||
"folder": &SyncedFolderPlugin{Impl: &MockSyncedFolder{}}})
|
||||
defer server.Stop()
|
||||
defer client.Close()
|
||||
|
||||
raw, err := client.Dispense("folder")
|
||||
if err != nil {
|
||||
t.Fatalf("err: %s", err)
|
||||
}
|
||||
impl, ok := raw.(SyncedFolder)
|
||||
if !ok {
|
||||
t.Fatalf("bad %#v", raw)
|
||||
}
|
||||
|
||||
err = impl.Disable(&vagrant.Machine{}, nil, nil)
|
||||
if err != nil {
|
||||
t.Fatalf("bad resp: %s", err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestSyncedFolder_Disable_error(t *testing.T) {
|
||||
client, server := plugin.TestPluginGRPCConn(t, map[string]plugin.Plugin{
|
||||
"folder": &SyncedFolderPlugin{Impl: &MockSyncedFolder{}}})
|
||||
defer server.Stop()
|
||||
defer client.Close()
|
||||
|
||||
raw, err := client.Dispense("folder")
|
||||
if err != nil {
|
||||
t.Fatalf("err: %s", err)
|
||||
}
|
||||
impl, ok := raw.(SyncedFolder)
|
||||
if !ok {
|
||||
t.Fatalf("bad %#v", raw)
|
||||
}
|
||||
|
||||
folders := map[string]interface{}{
|
||||
"folder_name": "options"}
|
||||
args := map[string]interface{}{
|
||||
"error": true}
|
||||
|
||||
err = impl.Disable(&vagrant.Machine{}, folders, args)
|
||||
if err == nil {
|
||||
t.Fatalf("illegal disable")
|
||||
}
|
||||
if err.Error() != "disable error" {
|
||||
t.Errorf("%s != disable error", err.Error())
|
||||
}
|
||||
}
|
||||
|
||||
func TestSyncedFolder_Enable(t *testing.T) {
|
||||
client, server := plugin.TestPluginGRPCConn(t, map[string]plugin.Plugin{
|
||||
"folder": &SyncedFolderPlugin{Impl: &MockSyncedFolder{}}})
|
||||
defer server.Stop()
|
||||
defer client.Close()
|
||||
|
||||
raw, err := client.Dispense("folder")
|
||||
if err != nil {
|
||||
t.Fatalf("err: %s", err)
|
||||
}
|
||||
impl, ok := raw.(SyncedFolder)
|
||||
if !ok {
|
||||
t.Fatalf("bad %#v", raw)
|
||||
}
|
||||
|
||||
err = impl.Enable(&vagrant.Machine{}, nil, nil)
|
||||
if err != nil {
|
||||
t.Fatalf("bad resp: %s", err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestSyncedFolder_Enable_error(t *testing.T) {
|
||||
client, server := plugin.TestPluginGRPCConn(t, map[string]plugin.Plugin{
|
||||
"folder": &SyncedFolderPlugin{Impl: &MockSyncedFolder{}}})
|
||||
defer server.Stop()
|
||||
defer client.Close()
|
||||
|
||||
raw, err := client.Dispense("folder")
|
||||
if err != nil {
|
||||
t.Fatalf("err: %s", err)
|
||||
}
|
||||
impl, ok := raw.(SyncedFolder)
|
||||
if !ok {
|
||||
t.Fatalf("bad %#v", raw)
|
||||
}
|
||||
|
||||
folders := map[string]interface{}{
|
||||
"folder_name": "options"}
|
||||
args := map[string]interface{}{
|
||||
"error": true}
|
||||
|
||||
err = impl.Enable(&vagrant.Machine{}, folders, args)
|
||||
if err == nil {
|
||||
t.Fatalf("illegal enable")
|
||||
}
|
||||
if err.Error() != "enable error" {
|
||||
t.Errorf("%s != enable error", err.Error())
|
||||
}
|
||||
}
|
||||
|
||||
func TestSyncedFolder_Prepare(t *testing.T) {
|
||||
client, server := plugin.TestPluginGRPCConn(t, map[string]plugin.Plugin{
|
||||
"folder": &SyncedFolderPlugin{Impl: &MockSyncedFolder{}}})
|
||||
defer server.Stop()
|
||||
defer client.Close()
|
||||
|
||||
raw, err := client.Dispense("folder")
|
||||
if err != nil {
|
||||
t.Fatalf("err: %s", err)
|
||||
}
|
||||
impl, ok := raw.(SyncedFolder)
|
||||
if !ok {
|
||||
t.Fatalf("bad %#v", raw)
|
||||
}
|
||||
|
||||
err = impl.Prepare(&vagrant.Machine{}, nil, nil)
|
||||
if err != nil {
|
||||
t.Fatalf("bad resp: %s", err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestSyncedFolder_Prepare_error(t *testing.T) {
|
||||
client, server := plugin.TestPluginGRPCConn(t, map[string]plugin.Plugin{
|
||||
"folder": &SyncedFolderPlugin{Impl: &MockSyncedFolder{}}})
|
||||
defer server.Stop()
|
||||
defer client.Close()
|
||||
|
||||
raw, err := client.Dispense("folder")
|
||||
if err != nil {
|
||||
t.Fatalf("err: %s", err)
|
||||
}
|
||||
impl, ok := raw.(SyncedFolder)
|
||||
if !ok {
|
||||
t.Fatalf("bad %#v", raw)
|
||||
}
|
||||
|
||||
folders := map[string]interface{}{
|
||||
"folder_name": "options"}
|
||||
args := map[string]interface{}{
|
||||
"error": true}
|
||||
|
||||
err = impl.Prepare(&vagrant.Machine{}, folders, args)
|
||||
if err == nil {
|
||||
t.Fatalf("illegal prepare")
|
||||
}
|
||||
if err.Error() != "prepare error" {
|
||||
t.Errorf("%s != prepare error", err.Error())
|
||||
}
|
||||
}
|
||||
|
||||
func TestSyncedFolder_Info(t *testing.T) {
|
||||
client, server := plugin.TestPluginGRPCConn(t, map[string]plugin.Plugin{
|
||||
"folder": &SyncedFolderPlugin{Impl: &MockSyncedFolder{}}})
|
||||
defer server.Stop()
|
||||
defer client.Close()
|
||||
|
||||
raw, err := client.Dispense("folder")
|
||||
if err != nil {
|
||||
t.Fatalf("err: %s", err)
|
||||
}
|
||||
impl, ok := raw.(SyncedFolder)
|
||||
if !ok {
|
||||
t.Fatalf("bad %#v", raw)
|
||||
}
|
||||
|
||||
resp := impl.Info()
|
||||
if resp == nil {
|
||||
t.Fatalf("bad resp")
|
||||
}
|
||||
|
||||
if resp.Description != "mock_folder" {
|
||||
t.Errorf("%s != mock_folder", resp.Description)
|
||||
}
|
||||
if resp.Priority != 100 {
|
||||
t.Errorf("%d != 100", resp.Priority)
|
||||
}
|
||||
}
|
||||
|
||||
func TestSyncedFolder_IsUsable(t *testing.T) {
|
||||
client, server := plugin.TestPluginGRPCConn(t, map[string]plugin.Plugin{
|
||||
"folder": &SyncedFolderPlugin{Impl: &MockSyncedFolder{}}})
|
||||
defer server.Stop()
|
||||
defer client.Close()
|
||||
|
||||
raw, err := client.Dispense("folder")
|
||||
if err != nil {
|
||||
t.Fatalf("err: %s", err)
|
||||
}
|
||||
impl, ok := raw.(SyncedFolder)
|
||||
if !ok {
|
||||
t.Fatalf("bad %#v", raw)
|
||||
}
|
||||
|
||||
resp, err := impl.IsUsable(&vagrant.Machine{})
|
||||
if err != nil {
|
||||
t.Fatalf("bad resp: %s", err)
|
||||
}
|
||||
if !resp {
|
||||
t.Errorf("bad result")
|
||||
}
|
||||
}
|
||||
|
||||
func TestSyncedFolder_Name(t *testing.T) {
|
||||
client, server := plugin.TestPluginGRPCConn(t, map[string]plugin.Plugin{
|
||||
"folder": &SyncedFolderPlugin{Impl: &MockSyncedFolder{}}})
|
||||
defer server.Stop()
|
||||
defer client.Close()
|
||||
|
||||
raw, err := client.Dispense("folder")
|
||||
if err != nil {
|
||||
t.Fatalf("err: %s", err)
|
||||
}
|
||||
impl, ok := raw.(SyncedFolder)
|
||||
if !ok {
|
||||
t.Fatalf("bad %#v", raw)
|
||||
}
|
||||
|
||||
resp := impl.Name()
|
||||
if resp != "mock_folder" {
|
||||
t.Errorf("%s != mock_folder", resp)
|
||||
}
|
||||
}
|
||||
|
||||
func TestSyncedFolder_MachineUI_output(t *testing.T) {
|
||||
client, server := plugin.TestPluginGRPCConn(t, map[string]plugin.Plugin{
|
||||
"folder": &SyncedFolderPlugin{Impl: &MockSyncedFolder{}}})
|
||||
defer server.Stop()
|
||||
defer client.Close()
|
||||
|
||||
raw, err := client.Dispense("folder")
|
||||
if err != nil {
|
||||
t.Fatalf("err: %s", err)
|
||||
}
|
||||
impl, ok := raw.(SyncedFolder)
|
||||
if !ok {
|
||||
t.Fatalf("bad %#v", raw)
|
||||
}
|
||||
|
||||
go func() {
|
||||
err := impl.Cleanup(&vagrant.Machine{}, map[string]interface{}{"ui": true})
|
||||
if err != nil {
|
||||
t.Fatalf("bad resp: %s", err)
|
||||
}
|
||||
}()
|
||||
|
||||
resp, err := impl.Read("stdout")
|
||||
if err != nil {
|
||||
t.Fatalf("bad resp: %s", err)
|
||||
}
|
||||
if !strings.Contains(resp, "test_output") {
|
||||
t.Errorf("%s !~ test_output", resp)
|
||||
}
|
||||
}
|
|
@ -7,7 +7,7 @@ type Provider interface {
|
|||
IsUsable(machData *Machine) (bool, error)
|
||||
MachineIdChanged(machData *Machine) error
|
||||
Name() string
|
||||
RunAction(actionName string, data string, machData *Machine) (string, error)
|
||||
RunAction(actionName string, args interface{}, machData *Machine) (interface{}, error)
|
||||
SshInfo(machData *Machine) (*SshInfo, error)
|
||||
State(machData *Machine) (*MachineState, error)
|
||||
|
||||
|
|
|
@ -1,20 +0,0 @@
|
|||
package vagrant
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
)
|
||||
|
||||
type Response struct {
|
||||
Error error `json:"error"`
|
||||
Result interface{} `json:"result"`
|
||||
}
|
||||
|
||||
// Serialize the response into a JSON string
|
||||
func (r Response) Dump() string {
|
||||
result, err := json.Marshal(r)
|
||||
if err != nil {
|
||||
return fmt.Sprintf(`{"error": "failed to encode response - %s"}`, err)
|
||||
}
|
||||
return string(result[:])
|
||||
}
|
|
@ -9,13 +9,13 @@ type SyncedFolderInfo struct {
|
|||
}
|
||||
|
||||
type SyncedFolder interface {
|
||||
Cleanup(m *Machine, opts *FolderOptions) error
|
||||
Disable(m *Machine, f *FolderList, opts *FolderOptions) error
|
||||
Enable(m *Machine, f *FolderList, opts *FolderOptions) error
|
||||
Cleanup(m *Machine, opts FolderOptions) error
|
||||
Disable(m *Machine, f FolderList, opts FolderOptions) error
|
||||
Enable(m *Machine, f FolderList, opts FolderOptions) error
|
||||
Info() *SyncedFolderInfo
|
||||
IsUsable(m *Machine) (bool, error)
|
||||
Name() string
|
||||
Prepare(m *Machine, f *FolderList, opts *FolderOptions) error
|
||||
Prepare(m *Machine, f FolderList, opts FolderOptions) error
|
||||
|
||||
GuestCapabilities
|
||||
HostCapabilities
|
||||
|
|
|
@ -6,12 +6,12 @@ module Vagrant
|
|||
module CapabilityPlugin
|
||||
# Wrapper class for go-plugin defined capabilities
|
||||
class Capability
|
||||
extend TypedGoPlugin
|
||||
include TypedGoPlugin
|
||||
end
|
||||
|
||||
# @return [Interface]
|
||||
def self.interface
|
||||
unless @_interface
|
||||
if !@_interface
|
||||
@_interface = Interface.new
|
||||
end
|
||||
@_interface
|
||||
|
|
|
@ -90,12 +90,16 @@ module Vagrant
|
|||
|
||||
# Load given data into the provided machine. This is
|
||||
# used to update the machine with data received from
|
||||
# go-plugins
|
||||
# go-plugins. Currently the only modification applied
|
||||
# is an ID change.
|
||||
#
|
||||
# @param [Hash] data Machine data from go-plugin
|
||||
# @param [Vagrant::Machine] machine
|
||||
# @return [Vagrant::Machine]
|
||||
def load_machine(data, machine)
|
||||
if data[:id] != machine.id
|
||||
machine.id = data[:id]
|
||||
end
|
||||
machine
|
||||
end
|
||||
|
||||
|
@ -157,7 +161,7 @@ module Vagrant
|
|||
|
||||
# @return [String]
|
||||
def name
|
||||
go_plugin_name.to_s.capitalize.tr("_", "")
|
||||
go_plugin_name.to_s.split("_").map(&:capitalize).join
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
@ -7,10 +7,9 @@ module Vagrant
|
|||
include Util::Logger
|
||||
|
||||
# @return [Manager]
|
||||
def self.instance(env=nil)
|
||||
@instance ||= self.new
|
||||
if env
|
||||
@instance.envirnoment = env
|
||||
def self.instance
|
||||
if !@instance
|
||||
@instance = self.new
|
||||
end
|
||||
@instance
|
||||
end
|
||||
|
|
|
@ -60,31 +60,11 @@ module Vagrant
|
|||
# provider so that it can be interacted with normally within
|
||||
# Vagrant
|
||||
class Provider < Vagrant.plugin("2", :provider)
|
||||
include DirectGoPlugin
|
||||
|
||||
# @return [Vagrant::Machine]
|
||||
attr_reader :machine
|
||||
|
||||
# @return [String] plugin name associated to this class
|
||||
def self.go_plugin_name
|
||||
@go_plugin_name
|
||||
end
|
||||
|
||||
# Set the plugin name for this class
|
||||
#
|
||||
# @param [String] n plugin name
|
||||
# @return [String]
|
||||
# @note can only be set once
|
||||
def self.go_plugin_name=(n)
|
||||
if @go_plugin_name
|
||||
raise ArgumentError.new("Class plugin name has already been set")
|
||||
end
|
||||
@go_plugin_name = n
|
||||
end
|
||||
|
||||
# @return [String]
|
||||
def self.name
|
||||
go_plugin_name.to_s.capitalize.tr("_", "")
|
||||
end
|
||||
|
||||
def initialize(machine)
|
||||
@machine = machine
|
||||
end
|
||||
|
@ -234,21 +214,6 @@ module Vagrant
|
|||
end
|
||||
end
|
||||
|
||||
def capability
|
||||
end
|
||||
|
||||
# Check if provider has requested capability
|
||||
#
|
||||
# @param [String] provider_name provider name for request
|
||||
# @param [String] capability_name name of the capability
|
||||
# @param [Vagrant::Machine] machine instance of guest
|
||||
# @return [Boolean]
|
||||
def has_capability(provider_name, capability_name, machine)
|
||||
result = load_result { _provider_has_capability(provider_name,
|
||||
capability_name, dump_machine(machine)) }
|
||||
result
|
||||
end
|
||||
|
||||
# Check if provider is installed
|
||||
#
|
||||
# @param [String] provider_name provider name for request
|
||||
|
|
|
@ -0,0 +1,19 @@
|
|||
require_relative "../../base"
|
||||
|
||||
describe Vagrant::GoPlugin::CapabilityPlugin do
|
||||
describe Vagrant::GoPlugin::CapabilityPlugin::Capability do
|
||||
it "should be a TypedGoPlugin" do
|
||||
expect(described_class.ancestors).to include(Vagrant::GoPlugin::TypedGoPlugin)
|
||||
end
|
||||
end
|
||||
|
||||
describe ".interface" do
|
||||
it "should create an interface instance" do
|
||||
expect(described_class.interface).to be_a(Vagrant::GoPlugin::CapabilityHost::Interface)
|
||||
end
|
||||
|
||||
it "should cache generated interface" do
|
||||
expect(described_class.interface).to be(described_class.interface)
|
||||
end
|
||||
end
|
||||
end
|
|
@ -0,0 +1,214 @@
|
|||
require_relative "../../base"
|
||||
|
||||
describe Vagrant::GoPlugin::Core do
|
||||
include_context "unit"
|
||||
|
||||
let(:subject_class) { Class.new.tap { |c| c.include(described_class) } }
|
||||
let(:subject) { subject_class.new }
|
||||
|
||||
let(:name) { "foo" }
|
||||
let(:provider) { new_provider_mock }
|
||||
let(:provider_cls) do
|
||||
obj = double("provider_cls")
|
||||
allow(obj).to receive(:new).and_return(provider)
|
||||
obj
|
||||
end
|
||||
let(:provider_config) { Object.new }
|
||||
let(:provider_name) { :test }
|
||||
let(:provider_options) { {} }
|
||||
let(:base) { false }
|
||||
let(:box) do
|
||||
double("box",
|
||||
name: "foo",
|
||||
provider: :dummy,
|
||||
version: "1.0",
|
||||
directory: "box dir",
|
||||
metadata: nil,
|
||||
metadata_url: nil)
|
||||
end
|
||||
|
||||
let(:config) { env.vagrantfile.config }
|
||||
let(:data_dir) { Pathname.new(Dir.mktmpdir("vagrant-machine-data-dir")) }
|
||||
let(:env) do
|
||||
# We need to create a Vagrantfile so that this test environment
|
||||
# has a proper root path
|
||||
test_env.vagrantfile("")
|
||||
|
||||
# Create the Vagrant::Environment instance
|
||||
test_env.create_vagrant_env
|
||||
end
|
||||
|
||||
let(:test_env) { isolated_environment }
|
||||
let(:machine) {
|
||||
Vagrant::Machine.new(name, provider_name, provider_cls, provider_config,
|
||||
provider_options, config, data_dir, box,
|
||||
env, env.vagrantfile, base)
|
||||
}
|
||||
|
||||
def new_provider_mock
|
||||
double("provider").tap do |obj|
|
||||
allow(obj).to receive(:_initialize)
|
||||
.with(provider_name, anything).and_return(nil)
|
||||
allow(obj).to receive(:machine_id_changed).and_return(nil)
|
||||
allow(obj).to receive(:state).and_return(Vagrant::MachineState.new(
|
||||
:created, "", ""))
|
||||
end
|
||||
end
|
||||
|
||||
describe "#dump_machine" do
|
||||
it "should raise error when argument is not a Vagrant Machine" do
|
||||
expect { subject.dump_machine(:value) }.to raise_error(TypeError)
|
||||
end
|
||||
|
||||
it "should dump machine to JSON string" do
|
||||
expect(subject.dump_machine(machine)).to be_a(String)
|
||||
end
|
||||
|
||||
it "should dump machine information" do
|
||||
val = subject.dump_machine(machine)
|
||||
result = JSON.load(val)
|
||||
expect(result["name"]).to eq(machine.name)
|
||||
expect(result["provider_name"]).to eq(machine.provider_name.to_s)
|
||||
expect(result["data_dir"]).to eq(machine.data_dir.to_s)
|
||||
end
|
||||
|
||||
it "should dump box information" do
|
||||
val = subject.dump_machine(machine)
|
||||
result = JSON.load(val)
|
||||
expect(result["box"]).to_not be_nil
|
||||
expect(result["box"]["name"]).to eq("foo")
|
||||
end
|
||||
|
||||
it "should dump environment information" do
|
||||
val = subject.dump_machine(machine)
|
||||
result = JSON.load(val)
|
||||
expect(result["environment"]).to_not be_nil
|
||||
expect(result["environment"]["cwd"]).to eq(machine.env.cwd.to_s)
|
||||
end
|
||||
end
|
||||
|
||||
describe "#dump_environment" do
|
||||
it "should dump environment to Hash" do
|
||||
expect(subject.dump_environment(env)).to be_a(Hash)
|
||||
end
|
||||
|
||||
it "should include environment information" do
|
||||
result = subject.dump_environment(env)
|
||||
expect(result[:cwd]).to eq(env.cwd)
|
||||
expect(result[:data_dir]).to eq(env.data_dir)
|
||||
end
|
||||
end
|
||||
|
||||
describe "#load_machine" do
|
||||
it "should set ID if ID has changed" do
|
||||
expect(machine).to receive(:id=).with("newid")
|
||||
subject.load_machine({id: "newid"}, machine)
|
||||
end
|
||||
|
||||
it "should not set ID if ID has not changed" do
|
||||
expect(machine).not_to receive(:id=)
|
||||
subject.load_machine({id: machine.id}, machine)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe Vagrant::GoPlugin::DirectGoPlugin do
|
||||
let(:subject_class) { Class.new.tap { |c| c.include(described_class) } }
|
||||
let(:subject) { subject_class.new }
|
||||
|
||||
describe ".go_plugin_name" do
|
||||
it "should return nil by default" do
|
||||
expect(subject_class.go_plugin_name).to be_nil
|
||||
end
|
||||
|
||||
it "should return assigned name when assigned" do
|
||||
subject_class.go_plugin_name = :test
|
||||
expect(subject_class.go_plugin_name).to eq(:test)
|
||||
end
|
||||
end
|
||||
|
||||
describe ".go_plugin_name=" do
|
||||
it "should allow for setting the plugin name" do
|
||||
subject_class.go_plugin_name = :test_plugin
|
||||
expect(subject_class.go_plugin_name).to eq(:test_plugin)
|
||||
end
|
||||
|
||||
it "should raise error when name has already been set" do
|
||||
subject_class.go_plugin_name = :test_plugin
|
||||
expect {
|
||||
subject_class.go_plugin_name = :different_plugin
|
||||
}.to raise_error(ArgumentError)
|
||||
end
|
||||
end
|
||||
|
||||
describe ".plugin_name" do
|
||||
it "should proxy to .go_plugin_name" do
|
||||
expect(subject_class).to receive(:go_plugin_name)
|
||||
subject_class.plugin_name
|
||||
end
|
||||
end
|
||||
|
||||
describe ".name" do
|
||||
it "should default to empty string" do
|
||||
expect(subject_class.name).to eq("")
|
||||
end
|
||||
|
||||
it "should camel case the go_plugin_name" do
|
||||
subject_class.go_plugin_name = "test_vagrant_plugin"
|
||||
expect(subject_class.name).to eq("TestVagrantPlugin")
|
||||
end
|
||||
end
|
||||
|
||||
describe "#plugin_name" do
|
||||
it "should proxy to .go_plugin_name" do
|
||||
expect(subject_class).to receive(:go_plugin_name)
|
||||
subject.plugin_name
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe Vagrant::GoPlugin::TypedGoPlugin do
|
||||
let(:subject_class) { Class.new.tap { |c| c.include(described_class) } }
|
||||
let(:subject) { subject_class.new }
|
||||
|
||||
it "should include DirectGoPlugin" do
|
||||
expect(subject_class.ancestors).to include(Vagrant::GoPlugin::DirectGoPlugin)
|
||||
end
|
||||
|
||||
describe ".go_plugin_type" do
|
||||
it "should be nil by default" do
|
||||
expect(subject_class.go_plugin_type).to be_nil
|
||||
end
|
||||
|
||||
it "should return assigned type when set" do
|
||||
subject_class.go_plugin_type = "provider"
|
||||
expect(subject_class.go_plugin_type).to eq("provider")
|
||||
end
|
||||
end
|
||||
|
||||
describe ".go_plugin_type=" do
|
||||
it "should allow setting plugin type" do
|
||||
subject_class.go_plugin_type = "test_type"
|
||||
expect(subject_class.go_plugin_type).to eq("test_type")
|
||||
end
|
||||
|
||||
it "should convert plugin type value to string" do
|
||||
subject_class.go_plugin_type = :test_type
|
||||
expect(subject_class.go_plugin_type).to eq("test_type")
|
||||
end
|
||||
|
||||
it "should raise an error when type has already been set" do
|
||||
subject_class.go_plugin_type = :test_type
|
||||
expect {
|
||||
subject_class.go_plugin_type = :different_type
|
||||
}.to raise_error(ArgumentError)
|
||||
end
|
||||
end
|
||||
|
||||
describe "#plugin_type" do
|
||||
it "should proxy to .go_plugin_type" do
|
||||
expect(subject_class).to receive(:go_plugin_type)
|
||||
subject.plugin_type
|
||||
end
|
||||
end
|
||||
end
|
|
@ -0,0 +1,56 @@
|
|||
require_relative "../../base"
|
||||
|
||||
describe Vagrant::GoPlugin::Interface do
|
||||
before do
|
||||
allow_any_instance_of(described_class).to receive(:_setup)
|
||||
end
|
||||
|
||||
describe "#load_plugins" do
|
||||
let(:path) { double("path", to_s: "path") }
|
||||
|
||||
it "should raise error if path is not a directory" do
|
||||
expect(File).to receive(:directory?).with(path.to_s).and_return(false)
|
||||
expect { subject.load_plugins(path) }.to raise_error(ArgumentError)
|
||||
end
|
||||
|
||||
it "should load plugins if path is a directory" do
|
||||
expect(File).to receive(:directory?).with(path.to_s).and_return(true)
|
||||
expect(subject).to receive(:_load_plugins).with(path.to_s)
|
||||
subject.load_plugins(path)
|
||||
end
|
||||
end
|
||||
|
||||
describe "#register_plugins" do
|
||||
it "should load Provider and SyncedFolder plugins" do
|
||||
expect(Vagrant::GoPlugin::ProviderPlugin).to receive_message_chain(:interface, :load!)
|
||||
expect(Vagrant::GoPlugin::SyncedFolderPlugin).to receive_message_chain(:interface, :load!)
|
||||
subject.register_plugins
|
||||
end
|
||||
end
|
||||
|
||||
describe "#setup" do
|
||||
after { subject }
|
||||
|
||||
it "should register at_exit action" do
|
||||
expect(Kernel).to receive(:at_exit)
|
||||
subject
|
||||
end
|
||||
|
||||
it "should run the setup action" do
|
||||
expect_any_instance_of(described_class).to receive(:_setup)
|
||||
end
|
||||
|
||||
it "should only run the setup process once" do
|
||||
expect_any_instance_of(described_class).to receive(:_setup).once
|
||||
expect(subject.logger).to receive(:warn)
|
||||
subject.setup
|
||||
end
|
||||
end
|
||||
|
||||
describe "#teardown" do
|
||||
it "should run the teardown action" do
|
||||
expect(subject).to receive(:_teardown)
|
||||
subject.teardown
|
||||
end
|
||||
end
|
||||
end
|
|
@ -0,0 +1,148 @@
|
|||
require_relative "../../base"
|
||||
|
||||
describe Vagrant::GoPlugin::Manager do
|
||||
include_context "unit"
|
||||
|
||||
let(:env) do
|
||||
test_env.vagrantfile("")
|
||||
test_env.create_vagrant_env
|
||||
end
|
||||
|
||||
before do
|
||||
allow(FileUtils).to receive(:mkdir_p)
|
||||
end
|
||||
|
||||
describe ".instance" do
|
||||
it "should return instance of manager" do
|
||||
expect(described_class.instance).to be_a(described_class)
|
||||
end
|
||||
|
||||
it "should cache instance" do
|
||||
expect(described_class.instance).to be(described_class.instance)
|
||||
end
|
||||
end
|
||||
|
||||
describe ".new" do
|
||||
it "should create the installation directory" do
|
||||
expect(FileUtils).to receive(:mkdir_p).with(Vagrant::GoPlugin::INSTALL_DIRECTORY)
|
||||
subject
|
||||
end
|
||||
|
||||
it "should create installation temporary directory" do
|
||||
expect(FileUtils).to receive(:mkdir_p).with(/tmp$/)
|
||||
subject
|
||||
end
|
||||
|
||||
it "should generate user state file" do
|
||||
expect(subject.user_file).to be_a(Vagrant::Plugin::StateFile)
|
||||
end
|
||||
end
|
||||
|
||||
describe "#globalize!" do
|
||||
let(:entries) { [double("entry1"), double("entry2")] }
|
||||
|
||||
before do
|
||||
allow(File).to receive(:directory?).and_return(false)
|
||||
allow(Dir).to receive(:glob).and_return(entries)
|
||||
allow(Vagrant::GoPlugin).to receive_message_chain(:interface, :register_plugins)
|
||||
end
|
||||
|
||||
context "when entries are not directories" do
|
||||
before { allow(File).to receive(:directory?).and_return(false) }
|
||||
|
||||
it "should not load any plugins" do
|
||||
interface = double("interface", register_plugins: nil)
|
||||
allow(Vagrant::GoPlugin).to receive(:interface).and_return(interface)
|
||||
expect(interface).not_to receive(:load_plugins)
|
||||
subject.globalize!
|
||||
end
|
||||
end
|
||||
|
||||
context "when entries are directories" do
|
||||
before { allow(File).to receive(:directory?).and_return(true) }
|
||||
|
||||
it "should load all entries" do
|
||||
expect(Vagrant::GoPlugin).to receive_message_chain(:interface, :load_plugins).with(entries.first)
|
||||
expect(Vagrant::GoPlugin).to receive_message_chain(:interface, :load_plugins).with(entries.last)
|
||||
subject.globalize!
|
||||
end
|
||||
end
|
||||
|
||||
it "should register plugins after loading" do
|
||||
expect(Vagrant::GoPlugin).to receive_message_chain(:interface, :register_plugins)
|
||||
subject.globalize!
|
||||
end
|
||||
end
|
||||
|
||||
describe "#localize!" do
|
||||
end
|
||||
|
||||
describe "#install_plugin" do
|
||||
let(:plugin_name) { "test_plugin_name" }
|
||||
let(:remote_source) { double("remote_source") }
|
||||
let(:downloader) { double("downloader", download!: nil) }
|
||||
|
||||
before do
|
||||
allow(FileUtils).to receive(:mkdir_p)
|
||||
allow(Dir).to receive(:mktmpdir)
|
||||
allow(Vagrant::Util::Downloader).to receive(:new).and_return(downloader)
|
||||
allow(Zip::File).to receive(:open)
|
||||
end
|
||||
|
||||
after { subject.install_plugin(plugin_name, remote_source) }
|
||||
|
||||
it "should create plugin directory for plugin name" do
|
||||
expect(FileUtils).to receive(:mkdir_p).with(/test_plugin_name$/)
|
||||
end
|
||||
|
||||
it "should create a temporary directory to download and unpack" do
|
||||
expect(Dir).to receive(:mktmpdir).with(/go-plugin/, any_args)
|
||||
end
|
||||
|
||||
it "should download the remote file" do
|
||||
expect(Dir).to receive(:mktmpdir).with(any_args).and_yield("tmpdir")
|
||||
expect(downloader).to receive(:download!)
|
||||
end
|
||||
|
||||
it "should unzip the downloaded file" do
|
||||
expect(Dir).to receive(:mktmpdir).with(any_args).and_yield("tmpdir")
|
||||
expect(Zip::File).to receive(:open).with(/plugin.zip/)
|
||||
end
|
||||
|
||||
it "should add the plugin to the user file" do
|
||||
expect(subject.user_file).to receive(:add_go_plugin).and_call_original
|
||||
expect(subject.user_file.has_go_plugin?("test_plugin_name")).to be_truthy
|
||||
end
|
||||
end
|
||||
|
||||
describe "#uninstall_plugin" do
|
||||
let(:plugin_name) { "test_plugin_name" }
|
||||
|
||||
before do
|
||||
allow(File).to receive(:directory?).and_call_original
|
||||
allow(FileUtils).to receive(:rm_rf)
|
||||
end
|
||||
|
||||
after { subject.uninstall_plugin(plugin_name) }
|
||||
|
||||
it "should remove plugin path when installed" do
|
||||
expect(File).to receive(:directory?).with(/test_plugin_name/).and_return(true)
|
||||
expect(FileUtils).to receive(:rm_rf).with(/test_plugin_name/)
|
||||
end
|
||||
|
||||
it "should not remove plugin path when not installed" do
|
||||
expect(File).to receive(:directory?).with(/test_plugin_name/).and_return(false)
|
||||
expect(FileUtils).not_to receive(:rm_rf).with(/test_plugin_name/)
|
||||
end
|
||||
|
||||
it "should have plugin name removed from user file when installed" do
|
||||
expect(File).to receive(:directory?).with(/test_plugin_name/).and_return(true)
|
||||
expect(subject.user_file).to receive(:remove_go_plugin).with(plugin_name)
|
||||
end
|
||||
|
||||
it "should have plugin name removed from user file when not installed" do
|
||||
expect(File).to receive(:directory?).with(/test_plugin_name/).and_return(false)
|
||||
expect(subject.user_file).to receive(:remove_go_plugin).with(plugin_name)
|
||||
end
|
||||
end
|
||||
end
|
|
@ -0,0 +1,29 @@
|
|||
require_relative "../base"
|
||||
|
||||
describe Vagrant::GoPlugin do
|
||||
describe "INSTALL_DIRECTORY constant" do
|
||||
let(:subject) { described_class.const_get(:INSTALL_DIRECTORY) }
|
||||
|
||||
it "should be a String" do
|
||||
expect(subject).to be_a(String)
|
||||
end
|
||||
|
||||
it "should be frozen" do
|
||||
expect(subject).to be_frozen
|
||||
end
|
||||
|
||||
it "should be within the user data path" do
|
||||
expect(subject).to start_with(Vagrant.user_data_path.to_s)
|
||||
end
|
||||
end
|
||||
|
||||
describe ".interface" do
|
||||
it "should return an interface instance" do
|
||||
expect(described_class.interface).to be_a(Vagrant::GoPlugin::Interface)
|
||||
end
|
||||
|
||||
it "should cache the interface instance" do
|
||||
expect(described_class.interface).to be(described_class.interface)
|
||||
end
|
||||
end
|
||||
end
|
Loading…
Reference in New Issue