vagrant-lxc-ng/lib/vagrant-lxc/action/forward_ports.rb
Francisco Soto 21725d3bb8 Fix redir version fetching.
"" || "something" doesn't really work. Have to check for the actual string
length to determine if got something or not out of the pipe.
2018-09-27 14:48:44 -04:00

121 lines
3.7 KiB
Ruby

require 'open3'
module Vagrant
module LXC
module Action
class ForwardPorts
def initialize(app, env)
@app = app
@logger = Log4r::Logger.new("vagrant::lxc::action::forward_ports")
end
def call(env)
@env = env
# Get the ports we're forwarding
env[:forwarded_ports] = compile_forwarded_ports(env[:machine].config)
if @env[:forwarded_ports].any? and not redir_installed?
raise Errors::RedirNotInstalled
end
# Warn if we're port forwarding to any privileged ports
env[:forwarded_ports].each do |fp|
if fp[:host] <= 1024
env[:ui].warn I18n.t("vagrant.actions.vm.forward_ports.privileged_ports")
break
end
end
# Continue, we need the VM to be booted in order to grab its IP
@app.call env
if @env[:forwarded_ports].any?
env[:ui].info I18n.t("vagrant.actions.vm.forward_ports.forwarding")
forward_ports
end
end
def forward_ports
@env[:forwarded_ports].each do |fp|
message_attributes = {
# TODO: Add support for multiple adapters
:adapter => 'eth0',
:guest_port => fp[:guest],
:host_port => fp[:host]
}
# TODO: Remove adapter from logging
@env[:ui].info(I18n.t("vagrant.actions.vm.forward_ports.forwarding_entry",
message_attributes))
redir_pid = redirect_port(
fp[:host_ip],
fp[:host],
fp[:guest_ip] || @env[:machine].provider.ssh_info[:host],
fp[:guest]
)
store_redir_pid(fp[:host], redir_pid)
end
end
private
def compile_forwarded_ports(config)
mappings = {}
config.vm.networks.each do |type, options|
next if options[:disabled]
# TODO: Deprecate this behavior of "automagically" skipping ssh forwarded ports
if type == :forwarded_port && options[:id] != 'ssh'
if options.fetch(:host_ip, '').to_s.strip.empty?
options[:host_ip] = '127.0.0.1'
end
mappings[options[:host]] = options
end
end
mappings.values
end
def redirect_port(host_ip, host_port, guest_ip, guest_port)
if redir_version >= 3
params = %W( -n #{host_ip}:#{host_port} #{guest_ip}:#{guest_port} )
else
params = %W( --lport=#{host_port} --caddr=#{guest_ip} --cport=#{guest_port} )
params.unshift "--laddr=#{host_ip}" if host_ip
end
params << '--syslog' if ENV['REDIR_LOG']
if host_port < 1024
redir_cmd = "sudo redir #{params.join(' ')} 2>/dev/null"
else
redir_cmd = "redir #{params.join(' ')} 2>/dev/null"
end
@logger.debug "Forwarding port with `#{redir_cmd}`"
spawn redir_cmd
end
def store_redir_pid(host_port, redir_pid)
data_dir = @env[:machine].data_dir.join('pids')
data_dir.mkdir unless data_dir.directory?
data_dir.join("redir_#{host_port}.pid").open('w') do |pid_file|
pid_file.write(redir_pid)
end
end
def redir_version
stdout, stderr, _ = Open3.capture3 "redir --version"
# For some weird reason redir printed version information in STDERR prior to 3.2
version = stdout.empty? ? stderr : stdout
version.split('.')[0].to_i
end
def redir_installed?
system "which redir > /dev/null"
end
end
end
end
end