123 lines
4.5 KiB
Ruby
123 lines
4.5 KiB
Ruby
$LOAD_PATH << Vagrant.source_root.join("lib/vagrant/protobufs").to_s
|
|
$LOAD_PATH << Vagrant.source_root.join("lib/vagrant/protobufs/proto").to_s
|
|
$LOAD_PATH << Vagrant.source_root.join("lib/vagrant/protobufs/proto/vagrant_plugin_sdk").to_s
|
|
|
|
require 'vagrant/protobufs/proto/vagrant_server/server_pb'
|
|
require 'vagrant/protobufs/proto/vagrant_server/server_services_pb'
|
|
require 'vagrant/protobufs/proto/ruby_vagrant/ruby-server_pb'
|
|
require 'vagrant/protobufs/proto/ruby_vagrant/ruby-server_services_pb'
|
|
require 'vagrant/protobufs/proto/vagrant_plugin_sdk/plugin_pb'
|
|
require 'vagrant/protobufs/proto/vagrant_plugin_sdk/plugin_services_pb'
|
|
require 'vagrant/protobufs/proto/plugin/grpc_broker_pb'
|
|
require 'vagrant/protobufs/proto/plugin/grpc_broker_services_pb'
|
|
|
|
require "optparse"
|
|
require 'grpc'
|
|
require 'grpc/health/checker'
|
|
require 'grpc/health/v1/health_services_pb'
|
|
|
|
module VagrantPlugins
|
|
module CommandServe
|
|
# Simple constant aliases to reduce namespace typing
|
|
SDK = Hashicorp::Vagrant::Sdk
|
|
SRV = Hashicorp::Vagrant
|
|
Empty = Google::Protobuf::Empty
|
|
|
|
autoload :Broker, Vagrant.source_root.join("plugins/commands/serve/broker").to_s
|
|
autoload :Client, Vagrant.source_root.join("plugins/commands/serve/client").to_s
|
|
autoload :Mappers, Vagrant.source_root.join("plugins/commands/serve/mappers").to_s
|
|
autoload :Service, Vagrant.source_root.join("plugins/commands/serve/service").to_s
|
|
autoload :Types, Vagrant.source_root.join("plugins/commands/serve/types").to_s
|
|
autoload :Util, Vagrant.source_root.join("plugins/commands/serve/util").to_s
|
|
|
|
class Command < Vagrant.plugin("2", :command)
|
|
|
|
DEFAULT_BIND = "localhost"
|
|
DEFAULT_PORT_RANGE = 40000..50000
|
|
|
|
include Util::HasLogger
|
|
|
|
def self.synopsis
|
|
"start Vagrant server"
|
|
end
|
|
|
|
def execute
|
|
options = {
|
|
bind: DEFAULT_BIND,
|
|
min_port: DEFAULT_PORT_RANGE.first,
|
|
max_port: DEFAULT_PORT_RANGE.last,
|
|
}
|
|
|
|
opts = OptionParser.new do |o|
|
|
o.banner = "Usage: vagrant serve"
|
|
o.separator ""
|
|
o.separator "Options:"
|
|
o.separator ""
|
|
|
|
o.on("--bind ADDR", "Bind to specific address. Default: #{DEFAULT_BIND}") do |addr|
|
|
options[:bind] = addr
|
|
end
|
|
|
|
o.on("--min-port PORT", "Minimum port number to use. Default: #{DEFAULT_PORT_RANGE.first}") do |port|
|
|
options[:min_port] = port
|
|
end
|
|
|
|
o.on("--max-port PORT", "Maximum port number to use. Default: #{DEFAULT_PORT_RANGE.last}") do |port|
|
|
options[:max_port] = port
|
|
end
|
|
end
|
|
|
|
# Parse the options
|
|
argv = parse_options(opts)
|
|
return if !argv
|
|
|
|
ports = options[:min_port].to_i .. options[:max_port].to_i
|
|
serve(options[:bind], ports)
|
|
end
|
|
|
|
private
|
|
|
|
def serve(bind_addr = "localhost", ports = DEFAULT_PORT_RANGE)
|
|
logger.info("Starting Vagrant GRPC service addr=#{bind_addr.inspect} ports=#{ports.inspect}")
|
|
s = GRPC::RpcServer.new
|
|
port = nil
|
|
ports.each do |p|
|
|
begin
|
|
port = s.add_http2_port("#{bind_addr}:#{p}", :this_port_is_insecure)
|
|
break
|
|
rescue RuntimeError
|
|
# Assuming port in use, trying next
|
|
end
|
|
end
|
|
raise "Failed to bind GRPC server listener" if port.nil?
|
|
|
|
health_checker = Grpc::Health::Checker.new
|
|
broker = Broker.new(bind: bind_addr, ports: ports)
|
|
logger.debug("vagrant grpc broker started for grpc service addr=#{bind_addr} ports=#{ports.inspect}")
|
|
|
|
|
|
[Service::InternalService, Service::ProviderService, Service::GuestService,
|
|
Service::HostService, Service::CommandService, Service::SyncedFolderService,
|
|
Service::CommunicatorService,
|
|
Broker::Streamer].each do |service_klass|
|
|
service = service_klass.new(broker: broker)
|
|
s.handle(service)
|
|
health_checker.add_status(service_klass,
|
|
Grpc::Health::V1::HealthCheckResponse::ServingStatus::SERVING)
|
|
logger.debug("enabled Vagrant GRPC service: #{service_klass.name.split('::').last}")
|
|
end
|
|
|
|
s.handle(health_checker)
|
|
|
|
logger.debug("writing connection informatation to stdout for go-plugin")
|
|
STDOUT.puts "1|1|tcp|#{bind_addr}:#{port}|grpc"
|
|
STDOUT.flush
|
|
logger.info("Vagrant GRPC service is now running addr=#{bind_addr.inspect} port=#{port.inspect}")
|
|
s.run_till_terminated_or_interrupted([1, 'int', 'SIGQUIT', 'SIGINT'])
|
|
ensure
|
|
logger.info("Vagrant GRPC service is shutting down")
|
|
end
|
|
end
|
|
end
|
|
end
|