[DRE-commits] [vagrant-libvirt] 02/17: Add support for port forwarding.

Antonio Terceiro terceiro at moszumanska.debian.org
Sun Apr 24 13:56:16 UTC 2016


This is an automated email from the git hooks/post-receive script.

terceiro pushed a commit to annotated tag 0.0.15
in repository vagrant-libvirt.

commit bb5d0817894b54f8ecabe1fb9a8496f13b4adaf8
Author: Ryan Petrello <lists at ryanpetrello.com>
Date:   Thu Jan 23 15:35:11 2014 -0800

    Add support for port forwarding.
---
 README.md                                   |   2 +-
 lib/vagrant-libvirt/action.rb               |   8 ++
 lib/vagrant-libvirt/action/forward_ports.rb | 145 ++++++++++++++++++++++++++++
 3 files changed, 154 insertions(+), 1 deletion(-)

diff --git a/README.md b/README.md
index a8d3380..1fae222 100644
--- a/README.md
+++ b/README.md
@@ -162,7 +162,7 @@ Vagrant goes through steps below when creating new project:
 ## Networks
 
 Networking features in the form of `config.vm.network` support private networks
-concept. Port Forwarding is currently not supported.
+concept.
 
 Public Network interfaces are currently implemented using the macvtap driver. The macvtap
 driver is only available with the Linux Kernel version >= 2.6.24. See the following libvirt
diff --git a/lib/vagrant-libvirt/action.rb b/lib/vagrant-libvirt/action.rb
index 164476b..26e37ec 100644
--- a/lib/vagrant-libvirt/action.rb
+++ b/lib/vagrant-libvirt/action.rb
@@ -32,6 +32,8 @@ module VagrantPlugins
                 b2.use SyncedFolders
               end
 
+              b2.use ForwardPorts
+
               b2.use PrepareNFSSettings
               b2.use ShareFolders
               b2.use SetHostname
@@ -75,6 +77,8 @@ module VagrantPlugins
                 b3.use SyncedFolderCleanup
                 b3.use SyncedFolders
               end
+
+              b3.use ForwardPorts
               b3.use PrepareNFSSettings
               b3.use ShareFolders
 
@@ -95,6 +99,7 @@ module VagrantPlugins
         Vagrant::Action::Builder.new.tap do |b|
           b.use ConfigValidate
           b.use ConnectLibvirt
+          b.use ClearForwardedPorts
           b.use Call, IsCreated do |env, b2|
             if !env[:result]
               b2.use MessageNotCreated
@@ -144,6 +149,7 @@ module VagrantPlugins
             end
 
             b2.use ConnectLibvirt
+            b2.use ClearForwardedPorts
             b2.use PruneNFSExports
             b2.use DestroyDomain
             b2.use DestroyNetworks
@@ -297,6 +303,8 @@ module VagrantPlugins
       autoload :CreateNetworks, action_root.join('create_networks')
       autoload :DestroyDomain, action_root.join('destroy_domain')
       autoload :DestroyNetworks, action_root.join('destroy_networks')
+      autoload :ForwardPorts, action_root.join('forward_ports')
+      autoload :ClearForwardedPorts, action_root.join('forward_ports')
       autoload :HaltDomain, action_root.join('halt_domain')
       autoload :HandleBoxImage, action_root.join('handle_box_image')
       autoload :HandleStoragePool, action_root.join('handle_storage_pool')
diff --git a/lib/vagrant-libvirt/action/forward_ports.rb b/lib/vagrant-libvirt/action/forward_ports.rb
new file mode 100644
index 0000000..82995a1
--- /dev/null
+++ b/lib/vagrant-libvirt/action/forward_ports.rb
@@ -0,0 +1,145 @@
+module VagrantPlugins
+  module ProviderLibvirt
+    module Action
+      class ForwardPorts
+        def initialize(app, env)
+          @app    = app
+          @logger = Log4r::Logger.new("vagrant_libvirt::action::forward_ports")
+        end
+
+        def call(env)
+          @env = env
+
+          # Get the ports we're forwarding
+          env[:forwarded_ports] = compile_forwarded_ports(env[:machine].config)
+
+          # 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 = {
+              :adapter    => 'eth0',
+              :guest_port => fp[:guest],
+              :host_port  => fp[:host]
+            }
+
+            @env[:ui].info(I18n.t("vagrant.actions.vm.forward_ports.forwarding_entry",
+                                  message_attributes))
+
+            ssh_pid = redirect_port(
+              @env[:machine].name,
+              fp[:host_ip] || '0.0.0.0',
+              fp[:host],
+              fp[:guest_ip] || @env[:machine].provider.ssh_info[:host],
+              fp[:guest]
+            )
+            store_ssh_pid(fp[:host], ssh_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'
+              options.delete(:host_ip) if options.fetch(:host_ip, '').to_s.strip.empty?
+              mappings[options[:host]] = options
+            end
+          end
+
+          mappings.values
+        end
+
+        def redirect_port(machine_name, host_ip, host_port, guest_ip, guest_port)
+          params = %W( #{machine_name} -L #{host_ip}:#{host_port}:#{guest_ip}:#{guest_port} -N ).join(" ")
+          ssh_cmd = "ssh $(vagrant ssh-config #{machine_name} | awk '{print \" -o \"$1\"=\"$2}') #{params} 2>/dev/null"
+
+          @logger.debug "Forwarding port with `#{ssh_cmd}`"
+          spawn ssh_cmd
+        end
+
+        def store_ssh_pid(host_port, ssh_pid)
+          data_dir = @env[:machine].data_dir.join('pids')
+          data_dir.mkdir unless data_dir.directory?
+
+          data_dir.join("ssh_#{host_port}.pid").open('w') do |pid_file|
+            pid_file.write(ssh_pid)
+          end
+        end
+
+      end
+    end
+  end
+end
+
+module VagrantPlugins
+  module ProviderLibvirt
+    module Action
+      class ClearForwardedPorts
+        def initialize(app, env)
+          @app = app
+          @logger = Log4r::Logger.new("vagrant_libvirt::action::clear_forward_ports")
+        end
+
+        def call(env)
+          @env = env
+
+          if ssh_pids.any?
+            env[:ui].info I18n.t("vagrant.actions.vm.clear_forward_ports.deleting")
+            ssh_pids.each do |pid|
+              next unless is_ssh_pid?(pid)
+              @logger.debug "Killing pid #{pid}"
+              system "pkill -TERM -P #{pid}"
+            end
+
+            @logger.info "Removing ssh pid files"
+            remove_ssh_pids
+          else
+            @logger.info "No ssh pids found"
+          end
+
+          @app.call env
+        end
+
+        protected
+
+        def ssh_pids
+          @ssh_pids = Dir[@env[:machine].data_dir.join('pids').to_s + "/ssh_*.pid"].map do |file|
+            File.read(file).strip.chomp
+          end
+        end
+
+        def is_ssh_pid?(pid)
+          @logger.debug "Checking if #{pid} is an ssh process with `ps -o cmd= #{pid}`"
+          `ps -o cmd= #{pid}`.strip.chomp =~ /ssh/
+        end
+
+        def remove_ssh_pids
+          Dir[@env[:machine].data_dir.join('pids').to_s + "/ssh_*.pid"].each do |file|
+            File.delete file
+          end
+        end
+      end
+    end
+  end
+end

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-ruby-extras/vagrant-libvirt.git



More information about the Pkg-ruby-extras-commits mailing list