350 lines
11 KiB
Ruby
350 lines
11 KiB
Ruby
require "google/protobuf/well_known_types"
|
|
|
|
module VagrantPlugins
|
|
module CommandServe
|
|
module Service
|
|
class CommunicatorService < Hashicorp::Vagrant::Sdk::CommunicatorService::Service
|
|
include Util::ServiceInfo
|
|
|
|
prepend Util::HasMapper
|
|
prepend Util::HasBroker
|
|
prepend Util::ExceptionLogger
|
|
prepend Util::HasLogger
|
|
include Util::HasSeeds::Service
|
|
|
|
def initialize(*args, **opts, &block)
|
|
super()
|
|
end
|
|
|
|
def ready_spec(*_)
|
|
logger.debug("generating ready spec")
|
|
SDK::FuncSpec.new(
|
|
name: "ready_spec",
|
|
args: [
|
|
SDK::FuncSpec::Value.new(
|
|
type: "hashicorp.vagrant.sdk.Args.Target.Machine",
|
|
name: "",
|
|
)
|
|
],
|
|
result: [
|
|
type: "hashicorp.vagrant.sdk.Communicator.ReadyResp",
|
|
name: "",
|
|
]
|
|
)
|
|
end
|
|
|
|
def ready(req, ctx)
|
|
with_info(ctx) do |info|
|
|
plugin_name = info.plugin_name
|
|
machine = mapper.funcspec_map(
|
|
req, mapper, broker,
|
|
expect: [Vagrant::Machine]
|
|
)
|
|
plugin = Vagrant.plugin("2").manager.communicators[plugin_name.to_s.to_sym]
|
|
communicator = plugin.new(machine)
|
|
ready = communicator.ready?
|
|
SDK::Communicator::ReadyResp.new(
|
|
ready: ready
|
|
)
|
|
end
|
|
end
|
|
|
|
def wait_for_ready_spec(*_)
|
|
SDK::FuncSpec.new(
|
|
name: "ready_spec",
|
|
args: [
|
|
SDK::FuncSpec::Value.new(
|
|
type: "hashicorp.vagrant.sdk.Args.Target.Machine",
|
|
name: "",
|
|
),
|
|
SDK::FuncSpec::Value.new(
|
|
type: "hashicorp.vagrant.sdk.Args.TimeDuration",
|
|
name: "",
|
|
)
|
|
],
|
|
result: [
|
|
type: "hashicorp.vagrant.sdk.Communicator.ReadyResp",
|
|
name: "",
|
|
]
|
|
)
|
|
end
|
|
|
|
def wait_for_ready(req, ctx)
|
|
with_info(ctx) do |info|
|
|
plugin_name = info.plugin_name
|
|
machine, wait_duration = mapper.funcspec_map(
|
|
req, mapper, broker,
|
|
expect: [Vagrant::Machine, SDK::Args::TimeDuration]
|
|
)
|
|
plugin = Vagrant.plugin("2").manager.communicators[plugin_name.to_s.to_sym]
|
|
|
|
begin
|
|
ready = plugin.new(machine).wait_for_ready(wait_duration.duration)
|
|
rescue => err
|
|
logger.error(err)
|
|
logger.debug("#{err.class}: #{err}\n#{err.backtrace.join("\n")}")
|
|
raise
|
|
end
|
|
logger.debug("ready? #{ready}")
|
|
SDK::Communicator::ReadyResp.new(
|
|
ready: ready
|
|
)
|
|
end
|
|
end
|
|
|
|
def download_spec(*_)
|
|
SDK::FuncSpec.new(
|
|
name: "download_spec",
|
|
args: [
|
|
SDK::FuncSpec::Value.new(
|
|
type: "hashicorp.vagrant.sdk.Args.Target.Machine",
|
|
name: "",
|
|
),
|
|
SDK::FuncSpec::Value.new(
|
|
name: "source"
|
|
),
|
|
SDK::FuncSpec::Value.new(
|
|
name: "destination"
|
|
),
|
|
],
|
|
result: []
|
|
)
|
|
end
|
|
|
|
def download(req, ctx)
|
|
logger.debug("Downloading")
|
|
with_info(ctx) do |info|
|
|
plugin_name = info.plugin_name
|
|
dest_proto = req.args.select{ |a| a.name == "destination" }.first
|
|
to = mapper.map(dest_proto.value, to: Pathname).to_s
|
|
source_proto = req.args.select{ |a| a.name == "source" }.first
|
|
from = mapper.map(source_proto.value, to: Pathname).to_s
|
|
req.args.reject!{ |a| a.name == "source" || a.name == "destination" }
|
|
machine = mapper.funcspec_map(
|
|
req, mapper, broker,
|
|
expect: [Vagrant::Machine]
|
|
)
|
|
|
|
plugin = Vagrant.plugin("2").manager.communicators[plugin_name.to_s.to_sym]
|
|
communicator = plugin.new(machine)
|
|
communicator.download(from, to)
|
|
Empty.new
|
|
end
|
|
end
|
|
|
|
def upload_spec(*_)
|
|
SDK::FuncSpec.new(
|
|
name: "upload_spec",
|
|
args: [
|
|
SDK::FuncSpec::Value.new(
|
|
type: "hashicorp.vagrant.sdk.Args.Target.Machine",
|
|
name: "",
|
|
),
|
|
SDK::FuncSpec::Value.new(
|
|
name: "source"
|
|
),
|
|
SDK::FuncSpec::Value.new(
|
|
name: "destination"
|
|
),
|
|
],
|
|
result: []
|
|
)
|
|
end
|
|
|
|
def upload(req, ctx)
|
|
logger.debug("Uploading")
|
|
with_info(ctx) do |info|
|
|
plugin_name = info.plugin_name
|
|
dest_proto = req.args.select{ |a| a.name == "destination" }.first
|
|
to = mapper.map(dest_proto.value, to: Pathname).to_s
|
|
source_proto = req.args.select{ |a| a.name == "source" }.first
|
|
from = mapper.map(source_proto.value, to: Pathname).to_s
|
|
req.args.reject!{ |a| a.name == "source" || a.name == "destination" }
|
|
machine = mapper.funcspec_map(
|
|
req, mapper, broker,
|
|
expect: [Vagrant::Machine]
|
|
)
|
|
|
|
plugin = Vagrant.plugin("2").manager.communicators[plugin_name.to_s.to_sym]
|
|
communicator = plugin.new(machine)
|
|
communicator.upload(from, to)
|
|
Empty.new
|
|
end
|
|
end
|
|
|
|
def execute_spec(*_)
|
|
SDK::FuncSpec.new(
|
|
name: "execute_spec",
|
|
args: [
|
|
SDK::FuncSpec::Value.new(
|
|
type: "hashicorp.vagrant.sdk.Args.Target.Machine",
|
|
name: "",
|
|
),
|
|
SDK::FuncSpec::Value.new(
|
|
type: "hashicorp.vagrant.sdk.Communicator.Command",
|
|
name: "",
|
|
),
|
|
SDK::FuncSpec::Value.new(
|
|
type: "hashicorp.vagrant.sdk.Args.Hash",
|
|
name: "",
|
|
)
|
|
],
|
|
result: [
|
|
type: "hashicorp.vagrant.sdk.Communicator.ExecuteResp",
|
|
name: "",
|
|
]
|
|
)
|
|
end
|
|
|
|
def execute(req, ctx)
|
|
with_info(ctx) do |info|
|
|
plugin_name = info.plugin_name
|
|
logger.debug("got req: #{req}")
|
|
machine, cmd, opts = mapper.funcspec_map(
|
|
req, mapper, broker,
|
|
expect: [Vagrant::Machine, SDK::Communicator::Command, Hash]
|
|
)
|
|
|
|
plugin = Vagrant.plugin("2").manager.communicators[plugin_name.to_s.to_sym]
|
|
communicator = plugin.new(machine)
|
|
opts.transform_keys!(&:to_sym)
|
|
output = {stdout: '', stderr: ''}
|
|
exit_code = communicator.execute(cmd.command, opts) {
|
|
|type, data| output[type] << data if output[type]
|
|
}
|
|
|
|
SDK::Communicator::ExecuteResp.new(
|
|
exit_code: exit_code,
|
|
stdout: output[:stdout],
|
|
stderr: output[:stderr]
|
|
)
|
|
end
|
|
end
|
|
|
|
def privileged_execute_spec(*_)
|
|
SDK::FuncSpec.new(
|
|
name: "privileged_execute_spec",
|
|
args: [
|
|
SDK::FuncSpec::Value.new(
|
|
type: "hashicorp.vagrant.sdk.Args.Target.Machine",
|
|
name: "",
|
|
),
|
|
SDK::FuncSpec::Value.new(
|
|
type: "hashicorp.vagrant.sdk.Communicator.Command",
|
|
name: "",
|
|
),
|
|
SDK::FuncSpec::Value.new(
|
|
type: "hashicorp.vagrant.sdk.Args.Hash",
|
|
name: "",
|
|
)
|
|
],
|
|
result: [
|
|
type: "hashicorp.vagrant.sdk.Communicator.ExecuteResp",
|
|
name: "",
|
|
]
|
|
)
|
|
end
|
|
|
|
def privileged_execute(req, ctx)
|
|
with_info(ctx) do |info|
|
|
plugin_name = info.plugin_name
|
|
machine, cmd, opts = mapper.funcspec_map(
|
|
req, mapper, broker,
|
|
expect: [Vagrant::Machine, SDK::Communicator::Command, Hash]
|
|
)
|
|
|
|
plugin = Vagrant.plugin("2").manager.communicators[plugin_name.to_s.to_sym]
|
|
communicator = plugin.new(machine)
|
|
opts.transform_keys!(&:to_sym)
|
|
output = {stdout: '', stderr: ''}
|
|
exit_code = communicator.sudo(cmd.command, opts) {
|
|
|type, data| output[type] << data if output[type]
|
|
}
|
|
|
|
SDK::Communicator::ExecuteResp.new(
|
|
exit_code: exit_code,
|
|
stdout: output[:stdout],
|
|
stderr: output[:stderr]
|
|
)
|
|
end
|
|
end
|
|
|
|
def test_spec(*_)
|
|
SDK::FuncSpec.new(
|
|
name: "test_spec",
|
|
args: [
|
|
SDK::FuncSpec::Value.new(
|
|
type: "hashicorp.vagrant.sdk.Args.Target.Machine",
|
|
name: "",
|
|
),
|
|
SDK::FuncSpec::Value.new(
|
|
type: "hashicorp.vagrant.sdk.Communicator.Command",
|
|
name: "",
|
|
),
|
|
SDK::FuncSpec::Value.new(
|
|
type: "hashicorp.vagrant.sdk.Args.Hash",
|
|
name: "",
|
|
)
|
|
],
|
|
result: [
|
|
type: "hashicorp.vagrant.sdk.Communicator.TestResp",
|
|
name: "",
|
|
]
|
|
)
|
|
end
|
|
|
|
def test(req, ctx)
|
|
with_info(ctx) do |info|
|
|
plugin_name = info.plugin_name
|
|
machine, cmd, opts = mapper.funcspec_map(
|
|
req, mapper, broker,
|
|
expect: [Vagrant::Machine, SDK::Communicator::Command, Hash]
|
|
)
|
|
|
|
plugin = Vagrant.plugin("2").manager.communicators[plugin_name.to_s.to_sym]
|
|
communicator = plugin.new(machine)
|
|
opts.transform_keys!(&:to_sym)
|
|
valid = communicator.test(cmd.command, opts)
|
|
logger.debug("command is valid?: #{valid}")
|
|
|
|
SDK::Communicator::TestResp.new(
|
|
valid: valid
|
|
)
|
|
end
|
|
end
|
|
|
|
def reset_spec(*_)
|
|
SDK::FuncSpec.new(
|
|
name: "reset_spec",
|
|
args: [
|
|
SDK::FuncSpec::Value.new(
|
|
type: "hashicorp.vagrant.sdk.Args.Target.Machine",
|
|
name: "",
|
|
),
|
|
],
|
|
result: [
|
|
type: "hashicorp.vagrant.sdk.Communicator.ResetResp",
|
|
name: "",
|
|
]
|
|
)
|
|
end
|
|
|
|
def reset(req, ctx)
|
|
with_info(ctx) do |info|
|
|
plugin_name = info.plugin_name
|
|
machine = mapper.funcspec_map(
|
|
req, mapper, broker,
|
|
expect: [Vagrant::Machine]
|
|
)
|
|
|
|
plugin = Vagrant.plugin("2").manager.communicators[plugin_name.to_s.to_sym]
|
|
communicator = plugin.new(machine)
|
|
communicator.reset
|
|
Empty.new
|
|
end
|
|
end
|
|
end
|
|
end
|
|
end
|
|
end
|