Update component clients to use FuncSpec module

This commit is contained in:
Chris Roberts 2022-01-21 14:11:52 -08:00 committed by Paul Hinze
parent 6e16a8835c
commit ad402fd6d0
No known key found for this signature in database
GPG Key ID: B69DEDF2D55501C0
7 changed files with 301 additions and 345 deletions

View File

@ -2,57 +2,58 @@ require "google/protobuf/well_known_types"
module VagrantPlugins
module CommandServe
module Client
class Client
module CapabilityPlatform
def self.included(klass)
return if klass.ancestors.include?(Util::HasMapper)
klass.prepend(Util::HasMapper)
# Generate callback and spec for required arguments
#
# @return [SDK::FuncSpec, Proc]
def has_capability_func
spec = client.has_capability_spec
cb = proc do |args|
client.has_capability(args).has_capability
end
[spec, cb]
end
# @param [Symbol] cap_name Capability name
# @return [Boolean]
def has_capability?(cap_name)
logger.debug("checking for capability #{cap_name}")
val = SDK::Args::NamedCapability.new(capability: cap_name.to_s)
req = SDK::FuncSpec::Args.new(
args: [SDK::FuncSpec::Value.new(
name: "",
type: "hashicorp.vagrant.sdk.Args.NamedCapability",
value: Google::Protobuf::Any.pack(val)
)]
run_func(
SDK::Args::NamedCapability.new(
capability: cap_name.to_s
)
)
end
res = client.has_capability(req)
logger.debug("got result #{res}")
res.has_capability
# Generate callback and spec for required arguments
#
# @param cap_name [String] Name of capability
# @return [SDK::FuncSpec, Proc]
def capability_func(cap_name)
spec = client.capability_spec(
SDK::Platform::Capability::NamedRequest.new(
name: cap_name,
)
)
cb = proc do |name, args|
result = client.capability(
SDK::Platform::Capability::NamedRequest.new(
name: name,
func_args: args,
)
)
return nil if result.nil?
mapper.map(result.result)
end
[spec, cb]
end
# @param [Symbol] cap_name Name of the capability
def capability(cap_name, *args)
logger.debug("executing capability #{cap_name}")
arg_protos = seed_protos
d = Type::Direct.new(arguments: args)
da = mapper.map(d, to: Google::Protobuf::Any)
arg_protos << SDK::FuncSpec::Value.new(
name: "",
type: "hashicorp.vagrant.sdk.Args.Direct",
value: Google::Protobuf::Any.pack(da),
)
req = SDK::Platform::Capability::NamedRequest.new(
name: cap_name.to_s,
func_args: SDK::FuncSpec::Args.new(
args: arg_protos,
)
)
result = client.capability(req)
if result.result.nil?
return nil
end
unmapped = mapper.map(result.result)
unmapped
spec, cb = capability_func(cap_name)
args << Type::Direct.new(value: args)
cb.call(cap_name, generate_funcspec_args(spec, *args))
end
end
end

View File

@ -1,33 +1,55 @@
require "ostruct"
module VagrantPlugins
module CommandServe
module Client
class Command
prepend Util::ClientSetup
prepend Util::HasLogger
include Util::HasSeeds::Client
def command_info
result = client.command_info(
SDK::FuncSpec::Args.new(args: seed_protos)
)
OpenStruct.new(result.command_info.to_hash)
class Client
class Command < Client
# Generate callback and spec for required arguments
#
# @return [SDK::FuncSpec, Proc]
def command_info_func
spec = client.command_info_spec(Empty.new)
cb = proc do |args|
v = client.command_info(args)
mapper.map(v, to: Type::CommandInfo)
end
[spec, cb]
end
def execute(args=[])
result = client.execute(
SDK::Command::ExecuteReq.new(
command_args: args,
spec: SDK::FuncSpec::Args.new(
args: seed_protos,
),
# Get command information
#
# @return [Type::CommandInfo]
def command_info
run_func
end
# Generate callback and spec for required arguments
#
# @param args [Array<String>] Command to execute
# @return [SDK::FuncSpec, Proc]
def execute_func(args=[])
spec = client.execute_spec(
SDK::Command::ExecuteSpecReq.new(
command_args: args
)
)
result.exit_code.to_i
cb = proc do |execute_args, funcspec_args|
req = SDK::Command::ExecuteReq.new(
command_args: execute_args,
spec: funcspec_args,
)
result = client.execute(req)
result.exit_code.to_i
end
[spec, cb]
end
# Execute command
#
# @param args [Array<String>] Command to execute
# @return [Integer] exit code
def execute(args=[])
spec, cb = execute_func(args)
cb.call(args, generate_funcspec_args(spec))
end
end
end

View File

@ -1,69 +1,52 @@
module VagrantPlugins
module CommandServe
module Client
class Communicator
prepend Util::HasMapper
extend Util::Connector
include Util::HasSeeds::Client
attr_reader :broker
attr_reader :client
attr_reader :proto
def initialize(conn, proto, broker=nil)
@logger = Log4r::Logger.new("vagrant::command::serve::client::communicator")
@logger.debug("connecting to communicator service on #{conn}")
@client = SDK::CommunicatorService::Stub.new(conn, :this_channel_is_insecure)
@broker = broker
@proto = proto
end
def self.load(raw_communicator, broker:)
c = raw_communicator.is_a?(String) ? SDK::Args::Communicator.decode(raw_communicator) : raw_communicator
self.new(connect(proto: c, broker: broker), c, broker)
class Client
class Communicator < Client
# Generate callback and spec for required arguments
#
# @return [SDK::FuncSpec, Proc]
def ready_func
spec = client.ready_spec(Empty.new)
cb = proc do |args|
client.ready(args).ready
end
[spec, cb]
end
# @param [Vagrant::Machine]
# @return [bool]
def ready(machine)
req = SDK::FuncSpec::Args.new(
args: [SDK::FuncSpec::Value.new(
name: "",
type: "hashicorp.vagrant.sdk.Args.Target.Machine",
value: Google::Protobuf::Any.pack(machine.to_proto)
)]
)
@logger.debug("checking if communicator is ready")
@logger.debug("Sending request #{req}")
res = client.ready(req)
@logger.debug("ready? #{res}")
res.ready
run_func(machine)
end
# Generate callback and spec for required arguments
#
# @return [SDK::FuncSpec, Proc]
def wait_for_ready_func
spec = client.wait_for_ready_spec
cb = proc do |args|
client.wait_for_ready(args).ready
end
[spec, cb]
end
# @param [Vagrant::Machine]
# @param [Integer] duration Timeout in seconds.
# @return [Boolean]
def wait_for_ready(machine, time)
req = SDK::FuncSpec::Args.new(
args: [SDK::FuncSpec::Value.new(
name: "",
type: "hashicorp.vagrant.sdk.Args.Target.Machine",
value: Google::Protobuf::Any.pack(machine.to_proto)
),
SDK::FuncSpec::Value.new(
type: "hashicorp.vagrant.sdk.Args.TimeDuration",
value: Google::Protobuf::Any.pack(
SDK::Args::TimeDuration.new(duration: time)
),
)
]
)
@logger.debug("(waiting) checking if communicator is ready")
res = client.wait_for_ready(req)
@logger.debug("ready? #{res}")
res.ready
run_func(machine, Type::Duration.new(time))
end
# Generate callback and spec for required arguments
#
# @return [SDK::FuncSpec, Proc]
def download_func
spec = client.download_spec(Empty.new)
cb = proc do |args|
client.download(args)
end
[spec, cb]
end
# @param [Vagrant::Machine]
@ -72,28 +55,23 @@ module VagrantPlugins
def download(machine, from, to)
from = Pathname.new(from.to_s) if !from.is_a?(Pathname)
to = Pathname.new(to.to_s) if !to.is_a?(Pathname)
from_val = mapper.map(from, to: SDK::Args::Path)
to_val = mapper.map(to, to: SDK::Args::Path)
req = SDK::FuncSpec::Args.new(
args: [
SDK::FuncSpec::Value.new(
name: "",
type: "hashicorp.vagrant.sdk.Args.Target.Machine",
value: Google::Protobuf::Any.pack(machine.to_proto)
),
SDK::FuncSpec::Value.new(
name: "source",
value: Google::Protobuf::Any.pack(from_val)
),
SDK::FuncSpec::Value.new(
name: "destination",
value: Google::Protobuf::Any.pack(to_val)
),
]
)
@logger.debug("downloading #{from} -> #{to}")
client.download(req)
run_func(
Type::NamedArgument(name: "to", value: to),
Type::NamedArgument(name: "from", value: from),
machine
)
end
# Generate callback and spec for required arguments
#
# @return [SDK::FuncSpec, Proc]
def upload_func
spec = client.upload_spec(Empty.new)
cb = proc do |args|
client.upload(args)
end
[spec, cb]
end
# @param [Vagrant::Machine]
@ -102,28 +80,23 @@ module VagrantPlugins
def upload(machine, from, to)
from = Pathname.new(from.to_s) if !from.is_a?(Pathname)
to = Pathname.new(to.to_s) if !to.is_a?(Pathname)
from_val = mapper.map(from, to: SDK::Args::Path)
to_val = mapper.map(to, to: SDK::Args::Path)
req = SDK::FuncSpec::Args.new(
args: [
SDK::FuncSpec::Value.new(
name: "",
type: "hashicorp.vagrant.sdk.Args.Target.Machine",
value: Google::Protobuf::Any.pack(machine.to_proto)
),
SDK::FuncSpec::Value.new(
name: "source",
value: Google::Protobuf::Any.pack(from_val)
),
SDK::FuncSpec::Value.new(
name: "destination",
value: Google::Protobuf::Any.pack(to_val)
),
]
)
@logger.debug("uploading #{from} -> #{to}")
client.upload(req)
run_func(
Type::NamedArgument(name: "to", value: to),
Type::NamedArgument(name: "from", value: from),
machine
)
end
# Generate callback and spec for required arguments
#
# @return [SDK::FuncSpec, Proc]
def execute_func
spec = client.execute_spec(Empty.new)
cb = proc do |args|
client.execute(args).exit_code
end
[spec, cb]
end
# @param [Vagrant::Machine]
@ -131,11 +104,18 @@ module VagrantPlugins
# @param [Hash] options
# @return [Integer]
def execute(machine, cmd, opts)
req = generate_execution_request(machine, cmd, opts)
@logger.debug("excuting")
res = client.execute(req)
@logger.debug("excution result: #{res}")
res
run_func(machine, opts, Type::CommunicatorCommandArguments.new(value: cmd))
end
# Generate callback and spec for required arguments
#
# @return [SDK::FuncSpec, Proc]
def privileged_execute_func(machine, cmd, opts)
spec = client.privileged_execute_spec(Empty.new)
cb = proc do |args|
client.privileged_execute(args).exit_code
end
[spec, cb]
end
# @param [Vagrant::Machine]
@ -143,11 +123,18 @@ module VagrantPlugins
# @param [Hash] options
# @return [Integer]
def privileged_execute(machine, cmd, opts)
req = generate_execution_request(machine, cmd, opts)
@logger.debug("privleged excuting")
res = client.privileged_execute(req)
@logger.debug("privleged excution result: #{res}")
res
run_func(machine, opts, Type::CommunicatorCommandArguments.new(value: cmd))
end
# Generate callback and spec for required arguments
#
# @return [SDK::FuncSpec, Proc]
def test_func
spec = client.test_spec
cb = proc do |args|
client.test(args).valid
end
[spec, cb]
end
# @param [Vagrant::Machine]
@ -155,50 +142,25 @@ module VagrantPlugins
# @param [Hash] options
# @return [Boolean]
def test(machine, cmd, opts)
req = generate_execution_request(machine, cmd, opts)
@logger.debug("testing")
@logger.debug("Sending request #{req}")
res = client.test(req)
@logger.debug("test result? #{res}")
res.valid
run_func(machine, opts, Type::CommunicatorCommandArguments.new(value: cmd))
end
# Generate callback and spec for required arguments
#
# @return [SDK::FuncSpec, Proc]
def reset_func
spec = client.reset_spec
cb = proc do |args|
client.reset(args)
end
[spec, cb]
end
# Reset the communicator connection
#
# @param machine [Vagrant::Machine] Guest to reset connection on
def reset(machine)
req = SDK::FuncSpec::Args.new(
args: [SDK::FuncSpec::Value.new(
name: "",
type: "hashicorp.vagrant.sdk.Args.Target.Machine",
value: Google::Protobuf::Any.pack(machine.to_proto)
)]
)
@logger.debug("reseting communicator")
client.reset(req)
end
protected
def generate_execution_request(machine, cmd, opts={})
opts = {} if opts.nil?
opts_proto = mapper.map(opts, to: SDK::Args::Hash)
opts_any = Google::Protobuf::Any.pack(opts_proto)
SDK::FuncSpec::Args.new(
args: [
SDK::FuncSpec::Value.new(
name: "",
type: "hashicorp.vagrant.sdk.Args.Target.Machine",
value: Google::Protobuf::Any.pack(machine.to_proto)
),
SDK::FuncSpec::Value.new(
type: "hashicorp.vagrant.sdk.Communicator.Command",
value: Google::Protobuf::Any.pack(SDK::Communicator::Command.new(command: cmd)),
),
SDK::FuncSpec::Value.new(
type: "hashicorp.vagrant.sdk.Args.Hash",
value: opts_any,
),
]
)
run_func(machine)
end
end
end

View File

@ -2,21 +2,23 @@ require "google/protobuf/well_known_types"
module VagrantPlugins
module CommandServe
module Client
class Guest
prepend Util::ClientSetup
prepend Util::HasLogger
class Client
class Guest < Client
include CapabilityPlatform
include Util::HasSeeds::Client
# Generate callback and spec for required arguments
#
# @return [SDK::FuncSpec, Proc]
def parent_func
spec = client.parent_spec(Empty.new)
cb = proc do |args|
client.parent(args).parent
end
[spec, cb]
end
# @return [<String>] parents
# @return [Array<String>] parents
def parent
req = SDK::FuncSpec::Args.new(
args: []
)
res = client.parent(req)
res.parent
run_func
end
end
end

View File

@ -1,24 +1,22 @@
require "google/protobuf/well_known_types"
module VagrantPlugins
module CommandServe
module Client
class Host
prepend Util::ClientSetup
prepend Util::HasLogger
class Client
class Host < Client
include CapabilityPlatform
include Util::HasSeeds::Client
# Generate callback and spec for required arguments
#
# @return [SDK::FuncSpec, Proc]
def parent_func
spec = client.parent_spec
cb = proc do |args|
client.parent(args).parent
end
[spec, cb]
end
# @return [<String>] parents
def parents
logger.debug("getting parents")
req = SDK::FuncSpec::Args.new(
args: []
)
res = client.parents(req)
logger.debug("got parents #{res}")
res.parents
# @return [String] parent
def parent
run_func
end
end
end

View File

@ -1,18 +1,21 @@
module VagrantPlugins
module CommandServe
module Client
class Push
prepend Util::ClientSetup
prepend Util::HasLogger
include Util::HasSeeds::Client
class Client
class Push < Client
# Generate callback and spec for required arguments
#
# @return [SDK::FuncSpec, Proc]
def push_func
spec = client.push_spec
cb = proc do |args|
client.push(args)
end
[spec, cb]
end
# Execute push
def push
logger.debug("doing push")
req = SDK::FuncSpec::Args.new(args: seed_protos)
res = client.push(req)
logger.debug("got response #{res}")
res
run_func
end
end
end

View File

@ -1,113 +1,81 @@
require "google/protobuf/well_known_types"
module VagrantPlugins
module CommandServe
module Client
class SyncedFolder
prepend Util::ClientSetup
prepend Util::HasLogger
class Client
class SyncedFolder < Client
include CapabilityPlatform
include Util::HasSeeds::Client
# Generate callback and spec for required arguments
#
# @return [SDK::FuncSpec, Proc]
def usable_func
spec = client.usable_spec
cb = proc do |args|
client.usable(args).usable
end
[spec, cb]
end
# @param [Sdk::Args::Machine]
# Check if synced folders are usable for guest
#
# @param machine [Vagrant::Machine] Guest machine
# @return [Boolean]
def usable(machine)
req = SDK::FuncSpec::Args.new(
args: [
SDK::FuncSpec::Value.new(
type: "hashicorp.vagrant.sdk.Args.Target.Machine",
value: Google::Protobuf::Any.pack(machine),
)
]
)
res = client.usable(req)
res.usable
run_func(machine)
end
# @param [Sdk::Args::Machine]
def enable(machine, folders, opts)
folder_proto = folder_proto(folders)
direct_any = direct_opts_proto(opts)
req = SDK::FuncSpec::Args.new(
args: [
SDK::FuncSpec::Value.new(
type: "hashicorp.vagrant.sdk.Args.Target.Machine",
value: Google::Protobuf::Any.pack(machine),
),
SDK::FuncSpec::Value.new(
type: "hashicorp.vagrant.sdk.Args.Folder",
value: Google::Protobuf::Any.pack(folder_proto),
),
SDK::FuncSpec::Value.new(
name: "",
type: "hashicorp.vagrant.sdk.Args.Direct",
value: Google::Protobuf::Any.pack(direct_any),
)
]
)
client.enable(req)
end
# @param [Sdk::Args::Machine]
def disable(machine, folders, opts)
folders_proto = folder_proto(folders)
direct_any = direct_opts_proto(opts)
req = SDK::FuncSpec::Args.new(
args: [
SDK::FuncSpec::Value.new(
type: "hashicorp.vagrant.sdk.Args.Target.Machine",
value: Google::Protobuf::Any.pack(machine),
),
SDK::FuncSpec::Value.new(
type: "hashicorp.vagrant.sdk.Args.Folder",
value: Google::Protobuf::Any.pack(folders_proto),
),
SDK::FuncSpec::Value.new(
name: "",
type: "hashicorp.vagrant.sdk.Args.Direct",
value: Google::Protobuf::Any.pack(direct_any),
)
]
)
client.disable(req)
end
# @param [Sdk::Args::Machine]
def cleanup(machine, opts)
direct_any = direct_opts_proto(opts)
req = SDK::FuncSpec::Args.new(
args: [
SDK::FuncSpec::Value.new(
type: "hashicorp.vagrant.sdk.Args.Target.Machine",
value: Google::Protobuf::Any.pack(machine),
),
SDK::FuncSpec::Value.new(
name: "",
type: "hashicorp.vagrant.sdk.Args.Direct",
value: Google::Protobuf::Any.pack(direct_any),
)
]
)
client.cleanup(req)
end
private
def folder_proto(folders)
folders_proto = {}
folders.each do |k, v|
folder_proto[k] = mapper.map(v, to: Google::Protobuf::Any)
# Generate callback and spec for required arguments
#
# @return [SDK::FuncSpec, Proc]
def enable_func
spec = client.enable_spec
cb = proc do |args|
client.enable(args)
end
folders_proto
[spec, cb]
end
def direct_opts_proto(opts)
direct_proto = Type::Direct.new(arguments: opts)
mapper.map(direct_proto, to: Google::Protobuf::Any)
# Enable synced folders on guest
#
# @param machine [Vagrant::Machine] Guest machine
# @param folders [Array] Synced folders
# @param opts [Hash] Options for folders
def enable(machine, folders, opts)
run_func(machine, folders, opts)
end
def disable_func
spec = client.disable_spec
cb = proc do |args|
client.disable(args)
end
[spec, cb]
end
# Disable synced folders on guest
#
# @param machine [Vagrant::Machine] Guest machine
# @param folders [Array] Synced folders
# @param opts [Hash] Options for folders
def disable(machine, folders, opts)
run_func(machine, folders, opts)
end
# Generate callback and spec for required arguments
#
# @return [SDK::FuncSpec, Proc]
def cleanup_func
spec = client.cleanup_spec
cb = proc do |args|
client.cleanup(args)
end
[spec, cb]
end
# Cleanup synced folders on guest
#
# @param machine [Vagrant::Machine] Guest machine
# @param opts [Hash] Options for folders
def cleanup(machine, opts)
run_func(machine, opts)
end
end
end