vagrant-hostmanager 1.5.0 → 1.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +16 -2
- data/README.md +3 -3
- data/lib/vagrant-hostmanager/action/update_all.rb +6 -12
- data/lib/vagrant-hostmanager/action/update_guest.rb +4 -13
- data/lib/vagrant-hostmanager/action/update_host.rb +9 -15
- data/lib/vagrant-hostmanager/command.rb +5 -1
- data/lib/vagrant-hostmanager/hosts_file/updater.rb +205 -0
- data/lib/vagrant-hostmanager/provisioner.rb +7 -13
- data/lib/vagrant-hostmanager/util.rb +14 -0
- data/lib/vagrant-hostmanager/version.rb +1 -1
- metadata +5 -4
- data/lib/vagrant-hostmanager/hosts_file.rb +0 -195
    
        checksums.yaml
    CHANGED
    
    | @@ -1,7 +1,7 @@ | |
| 1 1 | 
             
            ---
         | 
| 2 2 | 
             
            SHA1:
         | 
| 3 | 
            -
              metadata.gz:  | 
| 4 | 
            -
              data.tar.gz:  | 
| 3 | 
            +
              metadata.gz: a4140a59a7a487a11e115847cd60c1d6d1ca2ca4
         | 
| 4 | 
            +
              data.tar.gz: 93c851ddc092c8720c523db1b59848830864d6c0
         | 
| 5 5 | 
             
            SHA512:
         | 
| 6 | 
            -
              metadata.gz:  | 
| 7 | 
            -
              data.tar.gz:  | 
| 6 | 
            +
              metadata.gz: 2f5f80c76f81ac426dd3f253ba64ea62b9f9b29b82c8aec5b516844ae7d752ec1252db1a067146e298c997364f616d5e5da639d250f7969ecf042f4f7573d1d0
         | 
| 7 | 
            +
              data.tar.gz: 110477f3d3ac045f8fd673242bc24588a0627409befcfcc928999593adeb7867d1a3d94209e32f5ea98946669dd05838c54fe3109ae7be59981bc771d1816284
         | 
    
        data/CHANGELOG.md
    CHANGED
    
    | @@ -1,5 +1,19 @@ | |
| 1 1 | 
             
            # Changelog
         | 
| 2 2 |  | 
| 3 | 
            +
            ## 1.6.0
         | 
| 4 | 
            +
            ### Features
         | 
| 5 | 
            +
            * splits hostnames across many lines [[#67](https://github.com/smdahlen/vagrant-hostmanager/pull/103)]
         | 
| 6 | 
            +
             | 
| 7 | 
            +
            ### Bug fixes
         | 
| 8 | 
            +
            * show description for hostmanager when vagrant list-commands is triggered [[#105](https://github.com/smdahlen/vagrant-hostmanager/pull/105)]
         | 
| 9 | 
            +
             | 
| 10 | 
            +
            ### Miscelaneous
         | 
| 11 | 
            +
            * extract old vagrant version compatibility code into util method [[#97](https://github.com/smdahlen/vagrant-hostmanager/pull/97)]
         | 
| 12 | 
            +
            * migrate HostsFile code into its own class [[#98](https://github.com/smdahlen/vagrant-hostmanager/pull/97)]
         | 
| 13 | 
            +
             | 
| 14 | 
            +
            [Full diff](https://github.com/smdahlen/vagrant-hostmanager/compare/v1.5.0...v1.6.0)
         | 
| 15 | 
            +
             | 
| 16 | 
            +
             | 
| 3 17 | 
             
            ## 1.5.0
         | 
| 4 18 | 
             
            ### Features
         | 
| 5 19 | 
             
            * hostmanager now runs *before* provisioning takes place, on `up` action [[#73](https://github.com/smdahlen/vagrant-hostmanager/issues/73)]
         | 
| @@ -13,7 +27,7 @@ | |
| 13 27 | 
             
            ### Miscelaneous
         | 
| 14 28 | 
             
            * add passwordless sudo instructions to README [[#95](https://github.com/smdahlen/vagrant-hostmanager/pull/95)]
         | 
| 15 29 |  | 
| 16 | 
            -
            [Full diff](https://github.com/smdahlen/vagrant-hostmanager/compare/v1.4.0...v1.5.0) | 
| 30 | 
            +
            [Full diff](https://github.com/smdahlen/vagrant-hostmanager/compare/v1.4.0...v1.5.0)
         | 
| 17 31 |  | 
| 18 32 |  | 
| 19 33 | 
             
            ## 1.4.0
         | 
| @@ -27,7 +41,7 @@ | |
| 27 41 | 
             
            * when multiple private_networks are configured, the first one is used [[#64](https://github.com/smdahlen/vagrant-hostmanager/pull/64)]
         | 
| 28 42 | 
             
            * destroyed machines are now removed from hosts file [[#52](https://github.com/smdahlen/vagrant-hostmanager/pull/52)]
         | 
| 29 43 |  | 
| 30 | 
            -
            [Full diff](https://github.com/smdahlen/vagrant-hostmanager/compare/v1.3.0...v1.4.0) | 
| 44 | 
            +
            [Full diff](https://github.com/smdahlen/vagrant-hostmanager/compare/v1.3.0...v1.4.0)
         | 
| 31 45 |  | 
| 32 46 |  | 
| 33 47 | 
             
            ## 1.3.0
         | 
    
        data/README.md
    CHANGED
    
    | @@ -42,7 +42,7 @@ attribute to `true`. | |
| 42 42 |  | 
| 43 43 | 
             
            A machine's IP address is defined by either the static IP for a private
         | 
| 44 44 | 
             
            network configuration or by the SSH host configuration. To disable
         | 
| 45 | 
            -
            using the private network IP address, set `config. | 
| 45 | 
            +
            using the private network IP address, set `config.hostmanager.ignore_private_ip`
         | 
| 46 46 | 
             
            to true.
         | 
| 47 47 |  | 
| 48 48 | 
             
            A machine's host name is defined by `config.vm.hostname`. If this is not
         | 
| @@ -72,8 +72,8 @@ end | |
| 72 72 |  | 
| 73 73 | 
             
            ### Provisioner
         | 
| 74 74 |  | 
| 75 | 
            -
            Starting at version 1.5.0,  | 
| 76 | 
            -
            would like hostmanager to run after or during your provisioning stage, 
         | 
| 75 | 
            +
            Starting at version 1.5.0, `vagrant up` runs hostmanager before any provisioning occurs. 
         | 
| 76 | 
            +
            If you would like hostmanager to run after or during your provisioning stage, 
         | 
| 77 77 | 
             
            you can use hostmanager as a provisioner.  This allows you to use the provisioning 
         | 
| 78 78 | 
             
            order to ensure that hostmanager runs when desired. The provisioner will collect
         | 
| 79 79 | 
             
            hosts from boxes with the same provider as the running box.
         | 
| @@ -1,24 +1,18 @@ | |
| 1 | 
            -
            require 'vagrant-hostmanager/hosts_file'
         | 
| 1 | 
            +
            require 'vagrant-hostmanager/hosts_file/updater'
         | 
| 2 | 
            +
            require 'vagrant-hostmanager/util'
         | 
| 2 3 |  | 
| 3 4 | 
             
            module VagrantPlugins
         | 
| 4 5 | 
             
              module HostManager
         | 
| 5 6 | 
             
                module Action
         | 
| 6 7 | 
             
                  class UpdateAll
         | 
| 7 | 
            -
                    include HostsFile
         | 
| 8 8 |  | 
| 9 9 | 
             
                    def initialize(app, env)
         | 
| 10 10 | 
             
                      @app = app
         | 
| 11 11 | 
             
                      @machine = env[:machine]
         | 
| 12 12 | 
             
                      @global_env = @machine.env
         | 
| 13 13 | 
             
                      @provider = @machine.provider_name
         | 
| 14 | 
            -
             | 
| 15 | 
            -
                       | 
| 16 | 
            -
                      if Gem::Version.new(::Vagrant::VERSION) >= Gem::Version.new('1.5')
         | 
| 17 | 
            -
                        @config = @global_env.vagrantfile.config
         | 
| 18 | 
            -
                      else
         | 
| 19 | 
            -
                        @config = @global_env.config_global
         | 
| 20 | 
            -
                      end
         | 
| 21 | 
            -
             | 
| 14 | 
            +
                      @config = Util.get_config(@global_env)
         | 
| 15 | 
            +
                      @updater = HostsFile::Updater.new(@global_env, @provider)
         | 
| 22 16 | 
             
                      @logger = Log4r::Logger.new('vagrant::hostmanager::update_all')
         | 
| 23 17 | 
             
                    end
         | 
| 24 18 |  | 
| @@ -37,14 +31,14 @@ module VagrantPlugins | |
| 37 31 | 
             
                      @global_env.active_machines.each do |name, p|
         | 
| 38 32 | 
             
                        if p == @provider
         | 
| 39 33 | 
             
                          machine = @global_env.machine(name, p)
         | 
| 40 | 
            -
                          update_guest(machine)
         | 
| 34 | 
            +
                          @updater.update_guest(machine)
         | 
| 41 35 | 
             
                        end
         | 
| 42 36 | 
             
                      end
         | 
| 43 37 |  | 
| 44 38 | 
             
                      # update /etc/hosts files on host if enabled
         | 
| 45 39 | 
             
                      if @machine.config.hostmanager.manage_host?
         | 
| 46 40 | 
             
                        env[:ui].info I18n.t('vagrant_hostmanager.action.update_host')
         | 
| 47 | 
            -
                        update_host
         | 
| 41 | 
            +
                        @updater.update_host
         | 
| 48 42 | 
             
                      end
         | 
| 49 43 | 
             
                    end
         | 
| 50 44 | 
             
                  end
         | 
| @@ -1,24 +1,15 @@ | |
| 1 | 
            -
            require 'vagrant-hostmanager/hosts_file'
         | 
| 1 | 
            +
            require 'vagrant-hostmanager/hosts_file/updater'
         | 
| 2 | 
            +
            require 'vagrant-hostmanager/util'
         | 
| 2 3 |  | 
| 3 4 | 
             
            module VagrantPlugins
         | 
| 4 5 | 
             
              module HostManager
         | 
| 5 6 | 
             
                module Action
         | 
| 6 7 | 
             
                  class UpdateGuest
         | 
| 7 | 
            -
                    include HostsFile
         | 
| 8 8 |  | 
| 9 9 | 
             
                    def initialize(app, env)
         | 
| 10 10 | 
             
                      @app = app
         | 
| 11 11 | 
             
                      @machine = env[:machine]
         | 
| 12 | 
            -
                      @ | 
| 13 | 
            -
                      @provider = env[:provider]
         | 
| 14 | 
            -
             | 
| 15 | 
            -
                      # config_global is deprecated from v1.5
         | 
| 16 | 
            -
                      if Gem::Version.new(::Vagrant::VERSION) >= Gem::Version.new('1.5')
         | 
| 17 | 
            -
                        @config = @global_env.vagrantfile.config
         | 
| 18 | 
            -
                      else
         | 
| 19 | 
            -
                        @config = @global_env.config_global
         | 
| 20 | 
            -
                      end
         | 
| 21 | 
            -
                      
         | 
| 12 | 
            +
                      @updater = HostsFile::Updater.new(@machine.env, env[:provider])
         | 
| 22 13 | 
             
                      @logger = Log4r::Logger.new('vagrant::hostmanager::update_guest')
         | 
| 23 14 | 
             
                    end
         | 
| 24 15 |  | 
| @@ -26,7 +17,7 @@ module VagrantPlugins | |
| 26 17 | 
             
                      env[:ui].info I18n.t('vagrant_hostmanager.action.update_guest', {
         | 
| 27 18 | 
             
                        :name => @machine.name
         | 
| 28 19 | 
             
                      })
         | 
| 29 | 
            -
                      update_guest(@machine)
         | 
| 20 | 
            +
                      @updater.update_guest(@machine)
         | 
| 30 21 |  | 
| 31 22 | 
             
                      @app.call(env)
         | 
| 32 23 | 
             
                    end
         | 
| @@ -1,30 +1,25 @@ | |
| 1 | 
            -
            require 'vagrant-hostmanager/hosts_file'
         | 
| 1 | 
            +
            require 'vagrant-hostmanager/hosts_file/updater'
         | 
| 2 | 
            +
            require 'vagrant-hostmanager/util'
         | 
| 2 3 |  | 
| 3 4 | 
             
            module VagrantPlugins
         | 
| 4 5 | 
             
              module HostManager
         | 
| 5 6 | 
             
                module Action
         | 
| 6 7 | 
             
                  class UpdateHost
         | 
| 7 | 
            -
                    include HostsFile
         | 
| 8 8 |  | 
| 9 9 | 
             
                    def initialize(app, env)
         | 
| 10 10 | 
             
                      @app = app
         | 
| 11 | 
            -
                       | 
| 12 | 
            -
                       | 
| 13 | 
            -
             | 
| 14 | 
            -
                       | 
| 15 | 
            -
                       | 
| 16 | 
            -
                        @config = @global_env.vagrantfile.config
         | 
| 17 | 
            -
                      else
         | 
| 18 | 
            -
                        @config = @global_env.config_global
         | 
| 19 | 
            -
                      end
         | 
| 20 | 
            -
             | 
| 11 | 
            +
                      
         | 
| 12 | 
            +
                      global_env = env[:global_env]
         | 
| 13 | 
            +
                      @config = Util.get_config(global_env)
         | 
| 14 | 
            +
                      @updater = HostsFile::Updater.new(global_env, env[:provider])
         | 
| 15 | 
            +
                      
         | 
| 21 16 | 
             
                      @logger = Log4r::Logger.new('vagrant::hostmanager::update_host')
         | 
| 22 17 | 
             
                    end
         | 
| 23 18 |  | 
| 24 19 | 
             
                    def call(env)
         | 
| 25 20 | 
             
                      if @config.hostmanager.manage_host?
         | 
| 26 21 | 
             
                        env[:ui].info I18n.t('vagrant_hostmanager.action.update_host')
         | 
| 27 | 
            -
                        update_host
         | 
| 22 | 
            +
                        @updater.update_host
         | 
| 28 23 | 
             
                      end
         | 
| 29 24 |  | 
| 30 25 | 
             
                      @app.call(env)
         | 
| @@ -32,5 +27,4 @@ module VagrantPlugins | |
| 32 27 | 
             
                  end
         | 
| 33 28 | 
             
                end
         | 
| 34 29 | 
             
              end
         | 
| 35 | 
            -
            end
         | 
| 36 | 
            -
             | 
| 30 | 
            +
            end
         | 
| @@ -1,7 +1,11 @@ | |
| 1 1 | 
             
            module VagrantPlugins
         | 
| 2 2 | 
             
              module HostManager
         | 
| 3 3 | 
             
                class Command < Vagrant.plugin('2', :command)
         | 
| 4 | 
            -
             | 
| 4 | 
            +
             | 
| 5 | 
            +
                  # Show description when `vagrant list-commands` is triggered
         | 
| 6 | 
            +
                  def self.synopsis
         | 
| 7 | 
            +
                    "manages the /etc/hosts file within a multi-machine environment"
         | 
| 8 | 
            +
                  end
         | 
| 5 9 |  | 
| 6 10 | 
             
                  def execute
         | 
| 7 11 | 
             
                    options = {}
         | 
| @@ -0,0 +1,205 @@ | |
| 1 | 
            +
            require 'tempfile'
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            module VagrantPlugins
         | 
| 4 | 
            +
              module HostManager
         | 
| 5 | 
            +
                module HostsFile
         | 
| 6 | 
            +
             | 
| 7 | 
            +
                  class Updater
         | 
| 8 | 
            +
             | 
| 9 | 
            +
                    def initialize(global_env, provider)
         | 
| 10 | 
            +
                      @global_env = global_env
         | 
| 11 | 
            +
                      @config = Util.get_config(@global_env)
         | 
| 12 | 
            +
                      @provider = provider
         | 
| 13 | 
            +
                    end
         | 
| 14 | 
            +
             | 
| 15 | 
            +
                    def update_guest(machine)
         | 
| 16 | 
            +
                      return unless machine.communicate.ready?
         | 
| 17 | 
            +
             | 
| 18 | 
            +
                      if (machine.communicate.test("uname -s | grep SunOS"))
         | 
| 19 | 
            +
                        realhostfile = '/etc/inet/hosts'
         | 
| 20 | 
            +
                        move_cmd = 'mv'
         | 
| 21 | 
            +
                      elsif (machine.communicate.test("test -d $Env:SystemRoot"))
         | 
| 22 | 
            +
                        windir = ""
         | 
| 23 | 
            +
                        machine.communicate.execute("echo %SYSTEMROOT%", {:shell => :cmd}) do |type, contents|
         | 
| 24 | 
            +
                          windir << contents.gsub("\r\n", '') if type == :stdout
         | 
| 25 | 
            +
                        end
         | 
| 26 | 
            +
                        realhostfile = "#{windir}\\System32\\drivers\\etc\\hosts"
         | 
| 27 | 
            +
                        move_cmd = 'mv -force'
         | 
| 28 | 
            +
                      else
         | 
| 29 | 
            +
                        realhostfile = '/etc/hosts'
         | 
| 30 | 
            +
                        move_cmd = 'mv -f'
         | 
| 31 | 
            +
                      end
         | 
| 32 | 
            +
                      # download and modify file with Vagrant-managed entries
         | 
| 33 | 
            +
                      file = @global_env.tmp_path.join("hosts.#{machine.name}")
         | 
| 34 | 
            +
                      machine.communicate.download(realhostfile, file)
         | 
| 35 | 
            +
                      if update_file(file, machine, false)
         | 
| 36 | 
            +
             | 
| 37 | 
            +
                        # upload modified file and remove temporary file
         | 
| 38 | 
            +
                        machine.communicate.upload(file, '/tmp/hosts')
         | 
| 39 | 
            +
                        machine.communicate.sudo("#{move_cmd} /tmp/hosts #{realhostfile}")
         | 
| 40 | 
            +
                      end
         | 
| 41 | 
            +
             | 
| 42 | 
            +
                      # i have no idea if this is a windows competibility issue or not, but sometimes it dosen't work on my machine
         | 
| 43 | 
            +
                      begin
         | 
| 44 | 
            +
                        FileUtils.rm(file)
         | 
| 45 | 
            +
                      rescue Exception => e
         | 
| 46 | 
            +
                      end
         | 
| 47 | 
            +
                    end
         | 
| 48 | 
            +
             | 
| 49 | 
            +
                    def update_host
         | 
| 50 | 
            +
                      # copy and modify hosts file on host with Vagrant-managed entries
         | 
| 51 | 
            +
                      file = @global_env.tmp_path.join('hosts.local')
         | 
| 52 | 
            +
             | 
| 53 | 
            +
                      if WindowsSupport.windows?
         | 
| 54 | 
            +
                        # lazily include windows Module
         | 
| 55 | 
            +
                        class << self
         | 
| 56 | 
            +
                          include WindowsSupport unless include? WindowsSupport
         | 
| 57 | 
            +
                        end
         | 
| 58 | 
            +
             | 
| 59 | 
            +
                        hosts_location = "#{ENV['WINDIR']}\\System32\\drivers\\etc\\hosts"
         | 
| 60 | 
            +
                        copy_proc = Proc.new { windows_copy_file(file, hosts_location) }
         | 
| 61 | 
            +
                      else
         | 
| 62 | 
            +
                        hosts_location = '/etc/hosts'
         | 
| 63 | 
            +
                        copy_proc = Proc.new { `sudo cp #{file} #{hosts_location}` }
         | 
| 64 | 
            +
                      end
         | 
| 65 | 
            +
             | 
| 66 | 
            +
                      FileUtils.cp(hosts_location, file)
         | 
| 67 | 
            +
                      if update_file(file)
         | 
| 68 | 
            +
                        copy_proc.call
         | 
| 69 | 
            +
                      end
         | 
| 70 | 
            +
                    end
         | 
| 71 | 
            +
             | 
| 72 | 
            +
                    private
         | 
| 73 | 
            +
             | 
| 74 | 
            +
                    def update_file(file, resolving_machine = nil, include_id = true)
         | 
| 75 | 
            +
                      file = Pathname.new(file)
         | 
| 76 | 
            +
                      old_file_content = file.read
         | 
| 77 | 
            +
                      new_file_content = update_content(old_file_content, resolving_machine, include_id)
         | 
| 78 | 
            +
                      file.open('w') { |io| io.write(new_file_content) }
         | 
| 79 | 
            +
                      old_file_content != new_file_content
         | 
| 80 | 
            +
                    end
         | 
| 81 | 
            +
             | 
| 82 | 
            +
                    def update_content(file_content, resolving_machine, include_id)
         | 
| 83 | 
            +
                      id = include_id ? " id: #{read_or_create_id}" : ""
         | 
| 84 | 
            +
                      header = "## vagrant-hostmanager-start#{id}\n"
         | 
| 85 | 
            +
                      footer = "## vagrant-hostmanager-end\n"
         | 
| 86 | 
            +
                      body = get_machines
         | 
| 87 | 
            +
                        .map { |machine| get_hosts_file_entry(machine, resolving_machine) }
         | 
| 88 | 
            +
                        .join
         | 
| 89 | 
            +
                      get_new_content(header, footer, body, file_content)
         | 
| 90 | 
            +
                    end
         | 
| 91 | 
            +
             | 
| 92 | 
            +
                    def get_hosts_file_entry(machine, resolving_machine)
         | 
| 93 | 
            +
                      ip = get_ip_address(machine, resolving_machine)
         | 
| 94 | 
            +
                      host = machine.config.vm.hostname || machine.name
         | 
| 95 | 
            +
                      aliases = machine.config.hostmanager.aliases
         | 
| 96 | 
            +
                      if ip != nil
         | 
| 97 | 
            +
                        "#{ip}\t#{host}\n" + aliases.map{|a| "#{ip}\t#{a}"}.join("\n") + "\n"
         | 
| 98 | 
            +
                      end
         | 
| 99 | 
            +
                    end
         | 
| 100 | 
            +
             | 
| 101 | 
            +
                    def get_ip_address(machine, resolving_machine)
         | 
| 102 | 
            +
                      custom_ip_resolver = machine.config.hostmanager.ip_resolver
         | 
| 103 | 
            +
                      if custom_ip_resolver
         | 
| 104 | 
            +
                        custom_ip_resolver.call(machine, resolving_machine)
         | 
| 105 | 
            +
                      else
         | 
| 106 | 
            +
                        ip = nil
         | 
| 107 | 
            +
                        if machine.config.hostmanager.ignore_private_ip != true
         | 
| 108 | 
            +
                          machine.config.vm.networks.each do |network|
         | 
| 109 | 
            +
                            key, options = network[0], network[1]
         | 
| 110 | 
            +
                            ip = options[:ip] if key == :private_network
         | 
| 111 | 
            +
                            break if ip
         | 
| 112 | 
            +
                          end
         | 
| 113 | 
            +
                        end
         | 
| 114 | 
            +
                        ip || (machine.ssh_info ? machine.ssh_info[:host] : nil)
         | 
| 115 | 
            +
                      end
         | 
| 116 | 
            +
                    end
         | 
| 117 | 
            +
             | 
| 118 | 
            +
                    def get_machines
         | 
| 119 | 
            +
                      if @config.hostmanager.include_offline?
         | 
| 120 | 
            +
                        machines = @global_env.machine_names
         | 
| 121 | 
            +
                      else
         | 
| 122 | 
            +
                        machines = @global_env.active_machines
         | 
| 123 | 
            +
                          .select { |name, provider| provider == @provider }
         | 
| 124 | 
            +
                          .collect { |name, provider| name }
         | 
| 125 | 
            +
                      end
         | 
| 126 | 
            +
                      # Collect only machines that exist for the current provider
         | 
| 127 | 
            +
                      machines.collect do |name|
         | 
| 128 | 
            +
                            begin
         | 
| 129 | 
            +
                              machine = @global_env.machine(name, @provider)
         | 
| 130 | 
            +
                            rescue Vagrant::Errors::MachineNotFound
         | 
| 131 | 
            +
                              # ignore
         | 
| 132 | 
            +
                            end
         | 
| 133 | 
            +
                            machine
         | 
| 134 | 
            +
                          end
         | 
| 135 | 
            +
                        .reject(&:nil?)
         | 
| 136 | 
            +
                    end
         | 
| 137 | 
            +
             | 
| 138 | 
            +
                    def get_new_content(header, footer, body, old_content)
         | 
| 139 | 
            +
                      if body.empty?
         | 
| 140 | 
            +
                        block = "\n"
         | 
| 141 | 
            +
                      else
         | 
| 142 | 
            +
                        block = "\n\n" + header + body + footer + "\n"
         | 
| 143 | 
            +
                      end
         | 
| 144 | 
            +
                      # Pattern for finding existing block
         | 
| 145 | 
            +
                      header_pattern = Regexp.quote(header)
         | 
| 146 | 
            +
                      footer_pattern = Regexp.quote(footer)
         | 
| 147 | 
            +
                      pattern = Regexp.new("\n*#{header_pattern}.*?#{footer_pattern}\n*", Regexp::MULTILINE)
         | 
| 148 | 
            +
                      # Replace existing block or append
         | 
| 149 | 
            +
                      old_content.match(pattern) ? old_content.sub(pattern, block) : old_content.rstrip + block
         | 
| 150 | 
            +
                    end
         | 
| 151 | 
            +
             | 
| 152 | 
            +
                    def read_or_create_id
         | 
| 153 | 
            +
                      file = Pathname.new("#{@global_env.local_data_path}/hostmanager/id")
         | 
| 154 | 
            +
                      if (file.file?)
         | 
| 155 | 
            +
                        id = file.read.strip
         | 
| 156 | 
            +
                      else
         | 
| 157 | 
            +
                        id = SecureRandom.uuid
         | 
| 158 | 
            +
                        file.dirname.mkpath
         | 
| 159 | 
            +
                        file.open('w') { |io| io.write(id) }
         | 
| 160 | 
            +
                      end
         | 
| 161 | 
            +
                      id
         | 
| 162 | 
            +
                    end
         | 
| 163 | 
            +
             | 
| 164 | 
            +
                    ## Windows support for copying files, requesting elevated privileges if necessary
         | 
| 165 | 
            +
                    module WindowsSupport
         | 
| 166 | 
            +
                      require 'rbconfig'
         | 
| 167 | 
            +
             | 
| 168 | 
            +
                      def self.windows?
         | 
| 169 | 
            +
                        RbConfig::CONFIG['host_os'] =~ /mswin|mingw|cygwin/
         | 
| 170 | 
            +
                      end
         | 
| 171 | 
            +
             | 
| 172 | 
            +
                      require 'win32ole' if windows?
         | 
| 173 | 
            +
             | 
| 174 | 
            +
                      def windows_copy_file(source, dest)
         | 
| 175 | 
            +
                        begin
         | 
| 176 | 
            +
                          # First, try Ruby copy
         | 
| 177 | 
            +
                          FileUtils.cp(source, dest)
         | 
| 178 | 
            +
                        rescue Errno::EACCES
         | 
| 179 | 
            +
                          # Access denied, try with elevated privileges
         | 
| 180 | 
            +
                          windows_copy_file_elevated(source, dest)
         | 
| 181 | 
            +
                        end
         | 
| 182 | 
            +
                      end
         | 
| 183 | 
            +
             | 
| 184 | 
            +
                      private
         | 
| 185 | 
            +
             | 
| 186 | 
            +
                      def windows_copy_file_elevated(source, dest)
         | 
| 187 | 
            +
                        # copy command only supports backslashes as separators
         | 
| 188 | 
            +
                        source, dest = [source, dest].map { |s| s.to_s.gsub(/\//, '\\') }
         | 
| 189 | 
            +
             | 
| 190 | 
            +
                        # run 'cmd /C copy ...' with elevated privilege, minimized
         | 
| 191 | 
            +
                        copy_cmd = "copy \"#{source}\" \"#{dest}\""
         | 
| 192 | 
            +
                        WIN32OLE.new('Shell.Application').ShellExecute('cmd', "/C #{copy_cmd}", nil, 'runas', 7)
         | 
| 193 | 
            +
             | 
| 194 | 
            +
                        # Unfortunately, ShellExecute does not give us a status code,
         | 
| 195 | 
            +
                        # and it is non-blocking so we can't reliably compare the file contents
         | 
| 196 | 
            +
                        # to see if they were copied.
         | 
| 197 | 
            +
                        #
         | 
| 198 | 
            +
                        # If the user rejects the UAC prompt, vagrant will silently continue
         | 
| 199 | 
            +
                        # without updating the hostsfile.
         | 
| 200 | 
            +
                      end
         | 
| 201 | 
            +
                    end
         | 
| 202 | 
            +
                  end
         | 
| 203 | 
            +
                end
         | 
| 204 | 
            +
              end
         | 
| 205 | 
            +
            end
         | 
| @@ -1,26 +1,20 @@ | |
| 1 | 
            +
            require 'vagrant-hostmanager/hosts_file/updater'
         | 
| 2 | 
            +
             | 
| 1 3 | 
             
            module VagrantPlugins
         | 
| 2 4 | 
             
              module HostManager
         | 
| 3 5 | 
             
                class Provisioner < Vagrant.plugin('2', :provisioner)
         | 
| 4 | 
            -
                  include HostsFile
         | 
| 5 6 |  | 
| 6 7 | 
             
                  def initialize(machine, config)
         | 
| 7 8 | 
             
                    super(machine, config)
         | 
| 8 | 
            -
                     | 
| 9 | 
            -
                    @ | 
| 10 | 
            -
             | 
| 11 | 
            -
                    # config_global is deprecated from v1.5
         | 
| 12 | 
            -
                    if Gem::Version.new(::Vagrant::VERSION) >= Gem::Version.new('1.5')
         | 
| 13 | 
            -
                      @config = @global_env.vagrantfile.config
         | 
| 14 | 
            -
                    else
         | 
| 15 | 
            -
                      @config = @global_env.config_global
         | 
| 16 | 
            -
                    end
         | 
| 17 | 
            -
             | 
| 9 | 
            +
                    global_env = machine.env
         | 
| 10 | 
            +
                    @config = Util.get_config(global_env)
         | 
| 11 | 
            +
                    @updater = HostsFile::Updater.new(global_env, machine.provider_name)
         | 
| 18 12 | 
             
                  end
         | 
| 19 13 |  | 
| 20 14 | 
             
                  def provision
         | 
| 21 | 
            -
                    update_guest(@machine)
         | 
| 15 | 
            +
                    @updater.update_guest(@machine)
         | 
| 22 16 | 
             
                    if @config.hostmanager.manage_host?
         | 
| 23 | 
            -
                      update_host
         | 
| 17 | 
            +
                      @updater.update_host
         | 
| 24 18 | 
             
                    end
         | 
| 25 19 | 
             
                  end
         | 
| 26 20 | 
             
                end
         | 
| @@ -0,0 +1,14 @@ | |
| 1 | 
            +
            module VagrantPlugins
         | 
| 2 | 
            +
              module HostManager
         | 
| 3 | 
            +
                module Util
         | 
| 4 | 
            +
                  def self.get_config(env)
         | 
| 5 | 
            +
                    # config_global has been removed from v1.5
         | 
| 6 | 
            +
                    if Gem::Version.new(::Vagrant::VERSION) >= Gem::Version.new('1.5')
         | 
| 7 | 
            +
                      env.vagrantfile.config
         | 
| 8 | 
            +
                    else
         | 
| 9 | 
            +
                      env.config_global
         | 
| 10 | 
            +
                    end
         | 
| 11 | 
            +
                  end
         | 
| 12 | 
            +
                end
         | 
| 13 | 
            +
              end
         | 
| 14 | 
            +
            end
         | 
    
        metadata
    CHANGED
    
    | @@ -1,14 +1,14 @@ | |
| 1 1 | 
             
            --- !ruby/object:Gem::Specification
         | 
| 2 2 | 
             
            name: vagrant-hostmanager
         | 
| 3 3 | 
             
            version: !ruby/object:Gem::Version
         | 
| 4 | 
            -
              version: 1. | 
| 4 | 
            +
              version: 1.6.0
         | 
| 5 5 | 
             
            platform: ruby
         | 
| 6 6 | 
             
            authors:
         | 
| 7 7 | 
             
            - Shawn Dahlen
         | 
| 8 8 | 
             
            autorequire: 
         | 
| 9 9 | 
             
            bindir: bin
         | 
| 10 10 | 
             
            cert_chain: []
         | 
| 11 | 
            -
            date:  | 
| 11 | 
            +
            date: 2015-07-20 00:00:00.000000000 Z
         | 
| 12 12 | 
             
            dependencies:
         | 
| 13 13 | 
             
            - !ruby/object:Gem::Dependency
         | 
| 14 14 | 
             
              name: bundler
         | 
| @@ -60,9 +60,10 @@ files: | |
| 60 60 | 
             
            - lib/vagrant-hostmanager/command.rb
         | 
| 61 61 | 
             
            - lib/vagrant-hostmanager/config.rb
         | 
| 62 62 | 
             
            - lib/vagrant-hostmanager/errors.rb
         | 
| 63 | 
            -
            - lib/vagrant-hostmanager/hosts_file.rb
         | 
| 63 | 
            +
            - lib/vagrant-hostmanager/hosts_file/updater.rb
         | 
| 64 64 | 
             
            - lib/vagrant-hostmanager/plugin.rb
         | 
| 65 65 | 
             
            - lib/vagrant-hostmanager/provisioner.rb
         | 
| 66 | 
            +
            - lib/vagrant-hostmanager/util.rb
         | 
| 66 67 | 
             
            - lib/vagrant-hostmanager/version.rb
         | 
| 67 68 | 
             
            - locales/en.yml
         | 
| 68 69 | 
             
            - test/Vagrantfile
         | 
| @@ -88,7 +89,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement | |
| 88 89 | 
             
                  version: '0'
         | 
| 89 90 | 
             
            requirements: []
         | 
| 90 91 | 
             
            rubyforge_project: 
         | 
| 91 | 
            -
            rubygems_version: 2. | 
| 92 | 
            +
            rubygems_version: 2.4.6
         | 
| 92 93 | 
             
            signing_key: 
         | 
| 93 94 | 
             
            specification_version: 4
         | 
| 94 95 | 
             
            summary: A Vagrant plugin that manages the /etc/hosts file within a multi-machine
         | 
| @@ -1,195 +0,0 @@ | |
| 1 | 
            -
            require 'tempfile'
         | 
| 2 | 
            -
             | 
| 3 | 
            -
            module VagrantPlugins
         | 
| 4 | 
            -
              module HostManager
         | 
| 5 | 
            -
                module HostsFile
         | 
| 6 | 
            -
                  def update_guest(machine)
         | 
| 7 | 
            -
                    return unless machine.communicate.ready?
         | 
| 8 | 
            -
             | 
| 9 | 
            -
                    if (machine.communicate.test("uname -s | grep SunOS"))
         | 
| 10 | 
            -
                      realhostfile = '/etc/inet/hosts'
         | 
| 11 | 
            -
                      move_cmd = 'mv'
         | 
| 12 | 
            -
                    elsif (machine.communicate.test("test -d $Env:SystemRoot"))
         | 
| 13 | 
            -
                      windir = ""
         | 
| 14 | 
            -
                      machine.communicate.execute("echo %SYSTEMROOT%", {:shell => :cmd}) do |type, contents|
         | 
| 15 | 
            -
                        windir << contents.gsub("\r\n", '') if type == :stdout
         | 
| 16 | 
            -
                      end
         | 
| 17 | 
            -
                      realhostfile = "#{windir}\\System32\\drivers\\etc\\hosts"
         | 
| 18 | 
            -
                      move_cmd = 'mv -force'
         | 
| 19 | 
            -
                    else 
         | 
| 20 | 
            -
                      realhostfile = '/etc/hosts'
         | 
| 21 | 
            -
                      move_cmd = 'mv -f'
         | 
| 22 | 
            -
                    end
         | 
| 23 | 
            -
                    # download and modify file with Vagrant-managed entries
         | 
| 24 | 
            -
                    file = @global_env.tmp_path.join("hosts.#{machine.name}")
         | 
| 25 | 
            -
                    machine.communicate.download(realhostfile, file)
         | 
| 26 | 
            -
                    if update_file(file, machine, false)
         | 
| 27 | 
            -
             | 
| 28 | 
            -
                      # upload modified file and remove temporary file
         | 
| 29 | 
            -
                      machine.communicate.upload(file, '/tmp/hosts')
         | 
| 30 | 
            -
                      machine.communicate.sudo("#{move_cmd} /tmp/hosts #{realhostfile}")
         | 
| 31 | 
            -
                    end
         | 
| 32 | 
            -
             | 
| 33 | 
            -
                    # i have no idea if this is a windows competibility issue or not, but sometimes it dosen't work on my machine
         | 
| 34 | 
            -
                    begin
         | 
| 35 | 
            -
                      FileUtils.rm(file) 
         | 
| 36 | 
            -
                    rescue Exception => e
         | 
| 37 | 
            -
                    end
         | 
| 38 | 
            -
                  end
         | 
| 39 | 
            -
             | 
| 40 | 
            -
                  def update_host
         | 
| 41 | 
            -
                    # copy and modify hosts file on host with Vagrant-managed entries
         | 
| 42 | 
            -
                    file = @global_env.tmp_path.join('hosts.local')
         | 
| 43 | 
            -
             | 
| 44 | 
            -
                    if WindowsSupport.windows?
         | 
| 45 | 
            -
                      # lazily include windows Module
         | 
| 46 | 
            -
                      class << self
         | 
| 47 | 
            -
                        include WindowsSupport unless include? WindowsSupport
         | 
| 48 | 
            -
                      end
         | 
| 49 | 
            -
             | 
| 50 | 
            -
                      hosts_location = "#{ENV['WINDIR']}\\System32\\drivers\\etc\\hosts"
         | 
| 51 | 
            -
                      copy_proc = Proc.new { windows_copy_file(file, hosts_location) }
         | 
| 52 | 
            -
                    else
         | 
| 53 | 
            -
                      hosts_location = '/etc/hosts'
         | 
| 54 | 
            -
                      copy_proc = Proc.new { `sudo cp #{file} #{hosts_location}` }
         | 
| 55 | 
            -
                    end
         | 
| 56 | 
            -
             | 
| 57 | 
            -
                    FileUtils.cp(hosts_location, file)
         | 
| 58 | 
            -
                    if update_file(file)
         | 
| 59 | 
            -
                      copy_proc.call
         | 
| 60 | 
            -
                    end
         | 
| 61 | 
            -
                  end
         | 
| 62 | 
            -
             | 
| 63 | 
            -
                  private
         | 
| 64 | 
            -
             | 
| 65 | 
            -
                  def update_file(file, resolving_machine = nil, include_id = true)
         | 
| 66 | 
            -
                    file = Pathname.new(file)
         | 
| 67 | 
            -
                    old_file_content = file.read
         | 
| 68 | 
            -
                    new_file_content = update_content(old_file_content, resolving_machine, include_id)
         | 
| 69 | 
            -
                    file.open('w') { |io| io.write(new_file_content) }
         | 
| 70 | 
            -
                    old_file_content != new_file_content
         | 
| 71 | 
            -
                  end
         | 
| 72 | 
            -
             | 
| 73 | 
            -
                  def update_content(file_content, resolving_machine, include_id)
         | 
| 74 | 
            -
                    id = include_id ? " id: #{read_or_create_id}" : ""
         | 
| 75 | 
            -
                    header = "## vagrant-hostmanager-start#{id}\n"
         | 
| 76 | 
            -
                    footer = "## vagrant-hostmanager-end\n"
         | 
| 77 | 
            -
                    body = get_machines
         | 
| 78 | 
            -
                      .map { |machine| get_hosts_file_entry(machine, resolving_machine) }
         | 
| 79 | 
            -
                      .join
         | 
| 80 | 
            -
                    get_new_content(header, footer, body, file_content) 
         | 
| 81 | 
            -
                  end
         | 
| 82 | 
            -
             | 
| 83 | 
            -
                  def get_hosts_file_entry(machine, resolving_machine)
         | 
| 84 | 
            -
                    ip = get_ip_address(machine, resolving_machine)
         | 
| 85 | 
            -
                    host = machine.config.vm.hostname || machine.name
         | 
| 86 | 
            -
                    aliases = machine.config.hostmanager.aliases.join(' ').chomp
         | 
| 87 | 
            -
                    if ip != nil
         | 
| 88 | 
            -
                      "#{ip}\t#{host} #{aliases}\n"
         | 
| 89 | 
            -
                    end
         | 
| 90 | 
            -
                  end
         | 
| 91 | 
            -
             | 
| 92 | 
            -
                  def get_ip_address(machine, resolving_machine)
         | 
| 93 | 
            -
                    custom_ip_resolver = machine.config.hostmanager.ip_resolver
         | 
| 94 | 
            -
                    if custom_ip_resolver
         | 
| 95 | 
            -
                      custom_ip_resolver.call(machine, resolving_machine)
         | 
| 96 | 
            -
                    else
         | 
| 97 | 
            -
                      ip = nil
         | 
| 98 | 
            -
                      if machine.config.hostmanager.ignore_private_ip != true
         | 
| 99 | 
            -
                        machine.config.vm.networks.each do |network|
         | 
| 100 | 
            -
                          key, options = network[0], network[1]
         | 
| 101 | 
            -
                          ip = options[:ip] if key == :private_network
         | 
| 102 | 
            -
                          break if ip
         | 
| 103 | 
            -
                        end
         | 
| 104 | 
            -
                      end
         | 
| 105 | 
            -
                      ip || (machine.ssh_info ? machine.ssh_info[:host] : nil)
         | 
| 106 | 
            -
                    end
         | 
| 107 | 
            -
                  end
         | 
| 108 | 
            -
             | 
| 109 | 
            -
                  def get_machines
         | 
| 110 | 
            -
                    if @config.hostmanager.include_offline?
         | 
| 111 | 
            -
                      machines = @global_env.machine_names
         | 
| 112 | 
            -
                    else
         | 
| 113 | 
            -
                      machines = @global_env.active_machines
         | 
| 114 | 
            -
                        .select { |name, provider| provider == @provider }
         | 
| 115 | 
            -
                        .collect { |name, provider| name }
         | 
| 116 | 
            -
                    end
         | 
| 117 | 
            -
                    # Collect only machines that exist for the current provider
         | 
| 118 | 
            -
                    machines.collect do |name|
         | 
| 119 | 
            -
                          begin
         | 
| 120 | 
            -
                            machine = @global_env.machine(name, @provider)
         | 
| 121 | 
            -
                          rescue Vagrant::Errors::MachineNotFound
         | 
| 122 | 
            -
                            # ignore
         | 
| 123 | 
            -
                          end
         | 
| 124 | 
            -
                          machine
         | 
| 125 | 
            -
                        end
         | 
| 126 | 
            -
                      .reject(&:nil?)
         | 
| 127 | 
            -
                  end
         | 
| 128 | 
            -
             | 
| 129 | 
            -
                  def get_new_content(header, footer, body, old_content)
         | 
| 130 | 
            -
                    if body.empty?
         | 
| 131 | 
            -
                      block = "\n"
         | 
| 132 | 
            -
                    else
         | 
| 133 | 
            -
                      block = "\n\n" + header + body + footer + "\n"
         | 
| 134 | 
            -
                    end
         | 
| 135 | 
            -
                    # Pattern for finding existing block
         | 
| 136 | 
            -
                    header_pattern = Regexp.quote(header)
         | 
| 137 | 
            -
                    footer_pattern = Regexp.quote(footer)
         | 
| 138 | 
            -
                    pattern = Regexp.new("\n*#{header_pattern}.*?#{footer_pattern}\n*", Regexp::MULTILINE)
         | 
| 139 | 
            -
                    # Replace existing block or append
         | 
| 140 | 
            -
                    old_content.match(pattern) ? old_content.sub(pattern, block) : old_content.rstrip + block
         | 
| 141 | 
            -
                  end
         | 
| 142 | 
            -
             | 
| 143 | 
            -
                  def read_or_create_id
         | 
| 144 | 
            -
                    file = Pathname.new("#{@global_env.local_data_path}/hostmanager/id")
         | 
| 145 | 
            -
                    if (file.file?)
         | 
| 146 | 
            -
                      id = file.read.strip
         | 
| 147 | 
            -
                    else
         | 
| 148 | 
            -
                      id = SecureRandom.uuid
         | 
| 149 | 
            -
                      file.dirname.mkpath
         | 
| 150 | 
            -
                      file.open('w') { |io| io.write(id) }
         | 
| 151 | 
            -
                    end
         | 
| 152 | 
            -
                    id
         | 
| 153 | 
            -
                  end
         | 
| 154 | 
            -
             | 
| 155 | 
            -
                  ## Windows support for copying files, requesting elevated privileges if necessary
         | 
| 156 | 
            -
                  module WindowsSupport
         | 
| 157 | 
            -
                    require 'rbconfig'
         | 
| 158 | 
            -
             | 
| 159 | 
            -
                    def self.windows?
         | 
| 160 | 
            -
                      RbConfig::CONFIG['host_os'] =~ /mswin|mingw|cygwin/
         | 
| 161 | 
            -
                    end
         | 
| 162 | 
            -
             | 
| 163 | 
            -
                    require 'win32ole' if windows?
         | 
| 164 | 
            -
             | 
| 165 | 
            -
                    def windows_copy_file(source, dest)
         | 
| 166 | 
            -
                      begin
         | 
| 167 | 
            -
                        # First, try Ruby copy
         | 
| 168 | 
            -
                        FileUtils.cp(source, dest)
         | 
| 169 | 
            -
                      rescue Errno::EACCES
         | 
| 170 | 
            -
                        # Access denied, try with elevated privileges
         | 
| 171 | 
            -
                        windows_copy_file_elevated(source, dest)
         | 
| 172 | 
            -
                      end
         | 
| 173 | 
            -
                    end
         | 
| 174 | 
            -
             | 
| 175 | 
            -
                    private 
         | 
| 176 | 
            -
             | 
| 177 | 
            -
                    def windows_copy_file_elevated(source, dest)
         | 
| 178 | 
            -
                      # copy command only supports backslashes as separators
         | 
| 179 | 
            -
                      source, dest = [source, dest].map { |s| s.to_s.gsub(/\//, '\\') }
         | 
| 180 | 
            -
                      
         | 
| 181 | 
            -
                      # run 'cmd /C copy ...' with elevated privilege, minimized
         | 
| 182 | 
            -
                      copy_cmd = "copy \"#{source}\" \"#{dest}\""        
         | 
| 183 | 
            -
                      WIN32OLE.new('Shell.Application').ShellExecute('cmd', "/C #{copy_cmd}", nil, 'runas', 7)
         | 
| 184 | 
            -
             | 
| 185 | 
            -
                      # Unfortunately, ShellExecute does not give us a status code,
         | 
| 186 | 
            -
                      # and it is non-blocking so we can't reliably compare the file contents
         | 
| 187 | 
            -
                      # to see if they were copied.
         | 
| 188 | 
            -
                      #
         | 
| 189 | 
            -
                      # If the user rejects the UAC prompt, vagrant will silently continue 
         | 
| 190 | 
            -
                      # without updating the hostsfile.
         | 
| 191 | 
            -
                    end
         | 
| 192 | 
            -
                  end
         | 
| 193 | 
            -
                end
         | 
| 194 | 
            -
              end
         | 
| 195 | 
            -
            end
         |