vagrant-hostmanager-docker 1.6.1

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.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 0124b76857be3d5c46152d25538438b14bf30f15
4
+ data.tar.gz: 5e2f2b12e029f7df8a69c0f024ced1e84cfb8952
5
+ SHA512:
6
+ metadata.gz: 90ea7d7b7d6ae4a7a3df319daef6af12059621af2afb9b4c63f876bb1a434ab45e435f40236b463836298010fb2f629428e96f93b29811eeaf00cd960012052c
7
+ data.tar.gz: 0388f2198670eb1bfdd21e9a8feb62c9255506a567a1104904f21471e5169d5077347dbd10194d8a1273acc00bd5e4182a51f15c14e3a16bcf857afa90e1aea0
@@ -0,0 +1,4 @@
1
+ *.gem
2
+ pkg
3
+ Gemfile.lock
4
+ test/.vagrant
@@ -0,0 +1,67 @@
1
+ # Changelog
2
+
3
+ ## 1.6.1
4
+ ### Bug fixes
5
+ * Retain tmp hosts file and fix a bug where powershell mv does not move folder contents, in that context it's moving a file. [[#157](https://github.com/smdahlen/vagrant-hostmanager/issues/157)]
6
+
7
+ [Full diff](https://github.com/smdahlen/vagrant-hostmanager/compare/v1.6.0...v1.6.1)
8
+
9
+
10
+ ## 1.6.0
11
+ ### Features
12
+ * splits hostnames across many lines [[#67](https://github.com/smdahlen/vagrant-hostmanager/pull/103)]
13
+
14
+ ### Bug fixes
15
+ * show description for hostmanager when vagrant list-commands is triggered [[#105](https://github.com/smdahlen/vagrant-hostmanager/pull/105)]
16
+
17
+ ### Miscelaneous
18
+ * extract old vagrant version compatibility code into util method [[#97](https://github.com/smdahlen/vagrant-hostmanager/pull/97)]
19
+ * migrate HostsFile code into its own class [[#98](https://github.com/smdahlen/vagrant-hostmanager/pull/97)]
20
+
21
+ [Full diff](https://github.com/smdahlen/vagrant-hostmanager/compare/v1.5.0...v1.6.0)
22
+
23
+
24
+ ## 1.5.0
25
+ ### Features
26
+ * hostmanager now runs *before* provisioning takes place, on `up` action [[#73](https://github.com/smdahlen/vagrant-hostmanager/issues/73)]
27
+
28
+ ### Bug fixes
29
+ * properly detect hosts file location on Windows guests [[#67](https://github.com/smdahlen/vagrant-hostmanager/pull/67)]
30
+ * do not add host if IP cannot be determined [[#85](https://github.com/smdahlen/vagrant-hostmanager/pull/85)]
31
+ * force moving of hosts file on Linux guests [[#93](https://github.com/smdahlen/vagrant-hostmanager/pull/93)]
32
+ * allow top-level config options (eg. `ip_resolver`) to propagate to machine configs [[#91](https://github.com/smdahlen/vagrant-hostmanager/issues/91)]
33
+
34
+ ### Miscelaneous
35
+ * add passwordless sudo instructions to README [[#95](https://github.com/smdahlen/vagrant-hostmanager/pull/95)]
36
+
37
+ [Full diff](https://github.com/smdahlen/vagrant-hostmanager/compare/v1.4.0...v1.5.0)
38
+
39
+
40
+ ## 1.4.0
41
+ ### Features
42
+ * supports vagrant 1.5 [[#80](https://github.com/smdahlen/vagrant-hostmanager/issues/80), [#81](https://github.com/smdahlen/vagrant-hostmanager/pull/81)]
43
+ * only updates hosts file if contents have changed [[#78](https://github.com/smdahlen/vagrant-hostmanager/pull/78)]
44
+ * custom ip resolver now has access to the machine whose hosts file is being updated [[#62](https://github.com/smdahlen/vagrant-hostmanager/pull/62)]
45
+
46
+ ### Bug fixes
47
+ * custom IP resolver result no longer ignored [[#57](https://github.com/smdahlen/vagrant-hostmanager/pull/57)]
48
+ * when multiple private_networks are configured, the first one is used [[#64](https://github.com/smdahlen/vagrant-hostmanager/pull/64)]
49
+ * destroyed machines are now removed from hosts file [[#52](https://github.com/smdahlen/vagrant-hostmanager/pull/52)]
50
+
51
+ [Full diff](https://github.com/smdahlen/vagrant-hostmanager/compare/v1.3.0...v1.4.0)
52
+
53
+
54
+ ## 1.3.0
55
+ ### Features
56
+ * allow defining a custom IP resolver block [[#15](https://github.com/smdahlen/vagrant-hostmanager/pull/15)]
57
+ * handle removing destroyed machines from hosts file (currently only works with `include_offline = true`) [[#45](https://github.com/smdahlen/vagrant-hostmanager/pull/45)]
58
+ * attempt to elevate privileges when needed in Windows hosts [[#48](https://github.com/smdahlen/vagrant-hostmanager/pull/48)]
59
+
60
+ ### Bug fixes
61
+ * `--provider` command-line option now finds machines as expected [[#46](https://github.com/smdahlen/vagrant-hostmanager/pull/46)]
62
+ * uses proper `hosts` file location in Windows under cygwin [[#49](https://github.com/smdahlen/vagrant-hostmanager/pull/49)]
63
+
64
+ ### Miscelaneous
65
+ * MIT license added to gemspec
66
+
67
+ [Full diff](https://github.com/smdahlen/vagrant-hostmanager/compare/v1.2.3...v1.3.0)
data/Gemfile ADDED
@@ -0,0 +1,9 @@
1
+ source 'https://rubygems.org'
2
+
3
+ group :development do
4
+ gem 'vagrant', :git => 'git://github.com/mitchellh/vagrant.git', :tag => 'v1.6.2'
5
+ end
6
+
7
+ group :plugins do
8
+ gemspec
9
+ end
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2013 Shawn Dahlen
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,168 @@
1
+ Vagrant Host Manager
2
+ ====================
3
+
4
+ [![Gem](https://img.shields.io/gem/dt/vagrant-hostmanager.svg)](https://rubygems.org/gems/vagrant-hostmanager)
5
+ [![Gem](https://img.shields.io/gem/dtv/vagrant-hostmanager.svg)](https://rubygems.org/gems/vagrant-hostmanager)
6
+ [![Twitter](https://img.shields.io/twitter/url/https/github.com/smdahlen/vagrant-hostmanager.svg?style=social)](https://twitter.com/intent/tweet?text=Check%20out%20this%20awesome%20Vagrant%20plugin%21&url=https%3A%2F%2Fgithub.com%2Fsmdahlen%2Fvagrant-hostmanager&hashtags=vagrant%hostmanager&original_referer=)
7
+
8
+ `vagrant-hostmanager` is a Vagrant 1.1+ plugin that manages the `/etc/hosts`
9
+ file on guest machines (and optionally the host). Its goal is to enable
10
+ resolution of multi-machine environments deployed with a cloud provider
11
+ where IP addresses are not known in advance.
12
+
13
+ *NOTE:* Version 1.1 of the plugin prematurely introduced a feature to hook into
14
+ commands other than `vagrant up` and `vagrant destroy`. Version 1.1 broke support
15
+ for some providers. Version 1.2 reverts this feature until a suitable implementation
16
+ supporting all providers is available.
17
+
18
+ ***Potentially breaking change in v1.5.0:*** the running order on `vagrant up` has changed
19
+ so that hostmanager runs before provisioning takes place. This ensures all hostnames are
20
+ available to the guest when it is being provisioned
21
+ (see [#73](https://github.com/smdahlen/vagrant-hostmanager/issues/73)).
22
+ Previously, hostmanager would run as the very last action. If you depend on the old behavior,
23
+ see the [provisioner](#provisioner) section.
24
+
25
+ Installation
26
+ ------------
27
+ Install the plugin following the typical Vagrant 1.1 procedure:
28
+
29
+ $ vagrant plugin install vagrant-hostmanager
30
+
31
+ Usage
32
+ -----
33
+ To update the `/etc/hosts` file on each active machine, run the following
34
+ command:
35
+
36
+ $ vagrant hostmanager
37
+
38
+ The plugin hooks into the `vagrant up` and `vagrant destroy` commands
39
+ automatically.
40
+ When a machine enters or exits the running state , all active
41
+ machines with the same provider will have their `/etc/hosts` file updated
42
+ accordingly. Set the `hostmanager.enabled` attribute to `true` in the
43
+ Vagrantfile to activate this behavior.
44
+
45
+ To update the host's `/etc/hosts` file, set the `hostmanager.manage_host`
46
+ attribute to `true`.
47
+
48
+ A machine's IP address is defined by either the static IP for a private
49
+ network configuration or by the SSH host configuration. To disable
50
+ using the private network IP address, set `config.hostmanager.ignore_private_ip`
51
+ to true.
52
+
53
+ A machine's host name is defined by `config.vm.hostname`. If this is not
54
+ set, it falls back to the symbol defining the machine in the Vagrantfile.
55
+
56
+ If the `hostmanager.include_offline` attribute is set to `true`, boxes that are
57
+ up or have a private ip configured will be added to the hosts file.
58
+
59
+ In addition, the `hostmanager.aliases` configuration attribute can be used
60
+ to provide aliases for your host names.
61
+
62
+ Example configuration:
63
+
64
+ ```ruby
65
+ Vagrant.configure("2") do |config|
66
+ config.hostmanager.enabled = true
67
+ config.hostmanager.manage_host = true
68
+ config.hostmanager.ignore_private_ip = false
69
+ config.hostmanager.include_offline = true
70
+ config.vm.define 'example-box' do |node|
71
+ node.vm.hostname = 'example-box-hostname'
72
+ node.vm.network :private_network, ip: '192.168.42.42'
73
+ node.hostmanager.aliases = %w(example-box.localdomain example-box-alias)
74
+ end
75
+ end
76
+ ```
77
+
78
+ ### Provisioner
79
+
80
+ Starting at version 1.5.0, `vagrant up` runs hostmanager before any provisioning occurs.
81
+ If you would like hostmanager to run after or during your provisioning stage,
82
+ you can use hostmanager as a provisioner. This allows you to use the provisioning
83
+ order to ensure that hostmanager runs when desired. The provisioner will collect
84
+ hosts from boxes with the same provider as the running box.
85
+
86
+ Example:
87
+
88
+ ```ruby
89
+ # Disable the default hostmanager behavior
90
+ config.hostmanager.enabled = false
91
+
92
+ # ... possible provisioner config before hostmanager ...
93
+
94
+ # hostmanager provisioner
95
+ config.vm.provision :hostmanager
96
+
97
+ # ... possible provisioning config after hostmanager ...
98
+ ```
99
+
100
+ Custom IP resolver
101
+ ------------------
102
+
103
+ You can customize way, how host manager resolves IP address
104
+ for each machine. This might be handy in case of aws provider,
105
+ where host name is stored in ssh_info hash of each machine.
106
+ This causes generation of invalid /etc/hosts file.
107
+
108
+ Custom IP resolver gives you oportunity to calculate IP address
109
+ for each machine by yourself, giving You also access to the machine that is
110
+ updating /etc/hosts. For example:
111
+
112
+ ```ruby
113
+ config.hostmanager.ip_resolver = proc do |vm, resolving_vm|
114
+ if hostname = (vm.ssh_info && vm.ssh_info[:host])
115
+ `host #{hostname}`.split("\n").last[/(\d+\.\d+\.\d+\.\d+)/, 1]
116
+ end
117
+ end
118
+ ```
119
+
120
+ Passwordless sudo
121
+ -----------------
122
+
123
+ Add the following snippet to the sudoers file (for example, to
124
+ ```/etc/sudoers.d/vagrant_hostmanager```) to make it stop asking
125
+ password when updating hosts file (replace ```/home/user``` with your
126
+ actual home directory):
127
+
128
+ Cmnd_Alias VAGRANT_HOSTMANAGER_UPDATE = /bin/cp /home/user/.vagrant.d/tmp/hosts.local /etc/hosts
129
+ %sudo ALL=(root) NOPASSWD: VAGRANT_HOSTMANAGER_UPDATE
130
+
131
+ Windows support
132
+ ---------------
133
+
134
+ Hostmanager will detect Windows guests and hosts and use the appropriate
135
+ path for the ```hosts``` file: ```%WINDIR%\System32\drivers\etc\hosts```
136
+
137
+ By default on a Windows host, the ```hosts``` file is not writable without
138
+ elevated privileges. If hostmanager detects that it cannot overwrite the file,
139
+ it will attempt to do so with elevated privileges, causing the
140
+ [UAC](http://en.wikipedia.org/wiki/User_Account_Control) prompt to appear.
141
+
142
+ ### UAC limitations
143
+
144
+ Due to limitations caused by UAC, cancelling out of the UAC prompt will not cause any
145
+ visible errors, however the ```hosts``` file will not be updated.
146
+
147
+ Installing development version
148
+ ------------------------------
149
+
150
+ If you want to install the bleeding version of vagrant-hostmanager (*at your own risk*), you can do the following
151
+ (requires ruby and git):
152
+
153
+ ```
154
+ git clone https://github.com/smdahlen/vagrant-hostmanager.git
155
+ cd vagrant-hostmanager
156
+ rake gem:build
157
+ vagrant plugin install pkg/vagrant-hostmanager-*.gem
158
+ ```
159
+
160
+ Contribute
161
+ ----------
162
+ Contributions are welcome.
163
+
164
+ 1. Fork it
165
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
166
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
167
+ 4. Push to the branch (`git push origin my-new-feature`)
168
+ 5. Create new Pull Request
@@ -0,0 +1,12 @@
1
+ require 'bundler/gem_helper'
2
+
3
+ # Change to the directory of this file.
4
+ Dir.chdir(File.expand_path("../", __FILE__))
5
+
6
+ namespace :gem do
7
+ Bundler::GemHelper.install_tasks
8
+ end
9
+
10
+ task :test do
11
+ sh 'bash test/test.sh'
12
+ end
@@ -0,0 +1,14 @@
1
+ require 'vagrant-hostmanager/plugin'
2
+ require 'vagrant-hostmanager/version'
3
+ require 'vagrant-hostmanager/errors'
4
+
5
+ module VagrantPlugins
6
+ module HostManager
7
+ def self.source_root
8
+ @source_root ||= Pathname.new(File.expand_path('../../', __FILE__))
9
+ end
10
+
11
+ I18n.load_path << File.expand_path('locales/en.yml', source_root)
12
+ I18n.reload!
13
+ end
14
+ end
@@ -0,0 +1,31 @@
1
+ require 'vagrant-hostmanager/action/update_all'
2
+ require 'vagrant-hostmanager/action/update_guest'
3
+ require 'vagrant-hostmanager/action/update_host'
4
+
5
+ module VagrantPlugins
6
+ module HostManager
7
+ module Action
8
+ include Vagrant::Action::Builtin
9
+
10
+ def self.update_all
11
+ Vagrant::Action::Builder.new.tap do |builder|
12
+ builder.use ConfigValidate
13
+ builder.use UpdateAll
14
+ end
15
+ end
16
+
17
+ def self.update_guest
18
+ Vagrant::Action::Builder.new.tap do |builder|
19
+ builder.use ConfigValidate
20
+ builder.use UpdateGuest
21
+ end
22
+ end
23
+
24
+ def self.update_host
25
+ Vagrant::Action::Builder.new.tap do |builder|
26
+ builder.use UpdateHost
27
+ end
28
+ end
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,47 @@
1
+ require 'vagrant-hostmanager/hosts_file/updater'
2
+ require 'vagrant-hostmanager/util'
3
+
4
+ module VagrantPlugins
5
+ module HostManager
6
+ module Action
7
+ class UpdateAll
8
+
9
+ def initialize(app, env)
10
+ @app = app
11
+ @machine = env[:machine]
12
+ @global_env = @machine.env
13
+ @provider = @machine.provider_name
14
+ @config = Util.get_config(@global_env)
15
+ @updater = HostsFile::Updater.new(@global_env, @provider)
16
+ @logger = Log4r::Logger.new('vagrant::hostmanager::update_all')
17
+ end
18
+
19
+ def call(env)
20
+ # skip if machine is not active on destroy action
21
+ return @app.call(env) if !@machine.id && env[:machine_action] == :destroy
22
+
23
+ # check config to see if the hosts file should be update automatically
24
+ return @app.call(env) unless @config.hostmanager.enabled?
25
+ @logger.info 'Updating /etc/hosts file automatically'
26
+
27
+ @app.call(env)
28
+
29
+ # update /etc/hosts file on active machines
30
+ env[:ui].info I18n.t('vagrant_hostmanager.action.update_guests')
31
+ @global_env.active_machines.each do |name, p|
32
+ if p == @provider
33
+ machine = @global_env.machine(name, p)
34
+ @updater.update_guest(machine)
35
+ end
36
+ end
37
+
38
+ # update /etc/hosts files on host if enabled
39
+ if @machine.config.hostmanager.manage_host?
40
+ env[:ui].info I18n.t('vagrant_hostmanager.action.update_host')
41
+ @updater.update_host
42
+ end
43
+ end
44
+ end
45
+ end
46
+ end
47
+ end
@@ -0,0 +1,27 @@
1
+ require 'vagrant-hostmanager/hosts_file/updater'
2
+ require 'vagrant-hostmanager/util'
3
+
4
+ module VagrantPlugins
5
+ module HostManager
6
+ module Action
7
+ class UpdateGuest
8
+
9
+ def initialize(app, env)
10
+ @app = app
11
+ @machine = env[:machine]
12
+ @updater = HostsFile::Updater.new(@machine.env, env[:provider])
13
+ @logger = Log4r::Logger.new('vagrant::hostmanager::update_guest')
14
+ end
15
+
16
+ def call(env)
17
+ env[:ui].info I18n.t('vagrant_hostmanager.action.update_guest', {
18
+ :name => @machine.name
19
+ })
20
+ @updater.update_guest(@machine)
21
+
22
+ @app.call(env)
23
+ end
24
+ end
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,30 @@
1
+ require 'vagrant-hostmanager/hosts_file/updater'
2
+ require 'vagrant-hostmanager/util'
3
+
4
+ module VagrantPlugins
5
+ module HostManager
6
+ module Action
7
+ class UpdateHost
8
+
9
+ def initialize(app, env)
10
+ @app = app
11
+
12
+ global_env = env[:global_env]
13
+ @config = Util.get_config(global_env)
14
+ @updater = HostsFile::Updater.new(global_env, env[:provider])
15
+
16
+ @logger = Log4r::Logger.new('vagrant::hostmanager::update_host')
17
+ end
18
+
19
+ def call(env)
20
+ if @config.hostmanager.manage_host?
21
+ env[:ui].info I18n.t('vagrant_hostmanager.action.update_host')
22
+ @updater.update_host
23
+ end
24
+
25
+ @app.call(env)
26
+ end
27
+ end
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,43 @@
1
+ module VagrantPlugins
2
+ module HostManager
3
+ class Command < Vagrant.plugin('2', :command)
4
+
5
+ # Show description when `vagrant list-commands` is triggered
6
+ def self.synopsis
7
+ "plugin: vagrant-hostmanager: manages the /etc/hosts file within a multi-machine environment"
8
+ end
9
+
10
+ def execute
11
+ options = {}
12
+ opts = OptionParser.new do |o|
13
+ o.banner = 'Usage: vagrant hostmanager [vm-name]'
14
+ o.separator ''
15
+ o.version = VagrantPlugins::HostManager::VERSION
16
+ o.program_name = 'vagrant hostmanager'
17
+
18
+ o.on('--provider provider', String,
19
+ 'Update machines with the specific provider.') do |provider|
20
+ options[:provider] = provider.to_sym
21
+ end
22
+ end
23
+
24
+ argv = parse_options(opts)
25
+ options[:provider] ||= @env.default_provider
26
+
27
+ # update /etc/hosts file for specified guest machines
28
+ with_target_vms(argv, options) do |machine|
29
+ @env.action_runner.run(Action.update_guest, {
30
+ :machine => machine,
31
+ :provider => options[:provider]
32
+ })
33
+ end
34
+
35
+ # update /etc/hosts file for host
36
+ @env.action_runner.run(Action.update_host, {
37
+ :global_env => @env,
38
+ :provider => options[:provider]
39
+ })
40
+ end
41
+ end
42
+ end
43
+ end
@@ -0,0 +1,80 @@
1
+ module VagrantPlugins
2
+ module HostManager
3
+ class Config < Vagrant.plugin('2', :config)
4
+ attr_accessor :enabled
5
+ attr_accessor :manage_host
6
+ attr_accessor :ignore_private_ip
7
+ attr_accessor :aliases
8
+ attr_accessor :include_offline
9
+ attr_accessor :ip_resolver
10
+
11
+ alias_method :enabled?, :enabled
12
+ alias_method :include_offline?, :include_offline
13
+ alias_method :manage_host?, :manage_host
14
+
15
+ def initialize
16
+ @enabled = UNSET_VALUE
17
+ @manage_host = UNSET_VALUE
18
+ @ignore_private_ip = UNSET_VALUE
19
+ @include_offline = UNSET_VALUE
20
+ @aliases = UNSET_VALUE
21
+ @ip_resolver = UNSET_VALUE
22
+ end
23
+
24
+ def finalize!
25
+ @enabled = false if @enabled == UNSET_VALUE
26
+ @manage_host = false if @manage_host == UNSET_VALUE
27
+ @ignore_private_ip = false if @ignore_private_ip == UNSET_VALUE
28
+ @include_offline = false if @include_offline == UNSET_VALUE
29
+ @aliases = [] if @aliases == UNSET_VALUE
30
+ @ip_resolver = nil if @ip_resolver == UNSET_VALUE
31
+
32
+ @aliases = [ @aliases ].flatten
33
+ end
34
+
35
+ def validate(machine)
36
+ errors = []
37
+
38
+ errors << validate_bool('hostmanager.enabled', @enabled)
39
+ errors << validate_bool('hostmanager.manage_host', @manage_host)
40
+ errors << validate_bool('hostmanager.ignore_private_ip', @ignore_private_ip)
41
+ errors << validate_bool('hostmanager.include_offline', @include_offline)
42
+ errors.compact!
43
+
44
+ # check if aliases option is an Array
45
+ if !machine.config.hostmanager.aliases.kind_of?(Array) &&
46
+ !machine.config.hostmanager.aliases.kind_of?(String)
47
+ errors << I18n.t('vagrant_hostmanager.config.not_an_array_or_string', {
48
+ :config_key => 'hostmanager.aliases',
49
+ :is_class => aliases.class.to_s,
50
+ })
51
+ end
52
+
53
+ if !machine.config.hostmanager.ip_resolver.nil? &&
54
+ !machine.config.hostmanager.ip_resolver.kind_of?(Proc)
55
+ errors << I18n.t('vagrant_hostmanager.config.not_a_proc', {
56
+ :config_key => 'hostmanager.ip_resolver',
57
+ :is_class => ip_resolver.class.to_s,
58
+ })
59
+ end
60
+
61
+ errors.compact!
62
+ { "HostManager configuration" => errors }
63
+ end
64
+
65
+ private
66
+
67
+ def validate_bool(key, value)
68
+ if ![TrueClass, FalseClass].include?(value.class) &&
69
+ value != UNSET_VALUE
70
+ I18n.t('vagrant_hostmanager.config.not_a_bool', {
71
+ :config_key => key,
72
+ :value => value.class.to_s
73
+ })
74
+ else
75
+ nil
76
+ end
77
+ end
78
+ end
79
+ end
80
+ end
@@ -0,0 +1,6 @@
1
+ module VagrantPlugins
2
+ module HostManager
3
+ module Errors
4
+ end
5
+ end
6
+ end
@@ -0,0 +1,206 @@
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
+ if windir
40
+ machine.communicate.sudo("#{move_cmd} /tmp/hosts/hosts.#{machine.name} #{realhostfile}")
41
+ elsif machine.communicate.test('test -f /.dockerinit')
42
+ machine.communicate.sudo("cat /tmp/hosts > #{realhostfile}")
43
+ else
44
+ machine.communicate.sudo("#{move_cmd} /tmp/hosts #{realhostfile}")
45
+ end
46
+ end
47
+
48
+ end
49
+
50
+ def update_host
51
+ # copy and modify hosts file on host with Vagrant-managed entries
52
+ file = @global_env.tmp_path.join('hosts.local')
53
+
54
+ if WindowsSupport.windows?
55
+ # lazily include windows Module
56
+ class << self
57
+ include WindowsSupport unless include? WindowsSupport
58
+ end
59
+
60
+ hosts_location = "#{ENV['WINDIR']}\\System32\\drivers\\etc\\hosts"
61
+ copy_proc = Proc.new { windows_copy_file(file, hosts_location) }
62
+ else
63
+ hosts_location = '/etc/hosts'
64
+ copy_proc = Proc.new { `sudo cp #{file} #{hosts_location}` }
65
+ end
66
+
67
+ FileUtils.cp(hosts_location, file)
68
+ if update_file(file)
69
+ copy_proc.call
70
+ end
71
+ end
72
+
73
+ private
74
+
75
+ def update_file(file, resolving_machine = nil, include_id = true)
76
+ file = Pathname.new(file)
77
+ old_file_content = file.read
78
+ new_file_content = update_content(old_file_content, resolving_machine, include_id)
79
+ file.open('wb') { |io| io.write(new_file_content) }
80
+ old_file_content != new_file_content
81
+ end
82
+
83
+ def update_content(file_content, resolving_machine, include_id)
84
+ id = include_id ? " id: #{read_or_create_id}" : ""
85
+ header = "## vagrant-hostmanager-start#{id}\n"
86
+ footer = "## vagrant-hostmanager-end\n"
87
+ body = get_machines
88
+ .map { |machine| get_hosts_file_entry(machine, resolving_machine) }
89
+ .join
90
+ get_new_content(header, footer, body, file_content)
91
+ end
92
+
93
+ def get_hosts_file_entry(machine, resolving_machine)
94
+ ip = get_ip_address(machine, resolving_machine)
95
+ host = machine.config.vm.hostname || machine.name
96
+ aliases = machine.config.hostmanager.aliases
97
+ if ip != nil
98
+ "#{ip}\t#{host}\n" + aliases.map{|a| "#{ip}\t#{a}"}.join("\n") + "\n"
99
+ end
100
+ end
101
+
102
+ def get_ip_address(machine, resolving_machine)
103
+ custom_ip_resolver = machine.config.hostmanager.ip_resolver
104
+ if custom_ip_resolver
105
+ custom_ip_resolver.call(machine, resolving_machine)
106
+ else
107
+ ip = nil
108
+ if machine.config.hostmanager.ignore_private_ip != true
109
+ machine.config.vm.networks.each do |network|
110
+ key, options = network[0], network[1]
111
+ ip = options[:ip] if key == :private_network
112
+ break if ip
113
+ end
114
+ end
115
+ ip || (machine.ssh_info ? machine.ssh_info[:host] : nil)
116
+ end
117
+ end
118
+
119
+ def get_machines
120
+ if @config.hostmanager.include_offline?
121
+ machines = @global_env.machine_names
122
+ else
123
+ machines = @global_env.active_machines
124
+ .select { |name, provider| provider == @provider }
125
+ .collect { |name, provider| name }
126
+ end
127
+ # Collect only machines that exist for the current provider
128
+ machines.collect do |name|
129
+ begin
130
+ machine = @global_env.machine(name, @provider)
131
+ rescue Vagrant::Errors::MachineNotFound
132
+ # ignore
133
+ end
134
+ machine
135
+ end
136
+ .reject(&:nil?)
137
+ end
138
+
139
+ def get_new_content(header, footer, body, old_content)
140
+ if body.empty?
141
+ block = "\n"
142
+ else
143
+ block = "\n\n" + header + body + footer + "\n"
144
+ end
145
+ # Pattern for finding existing block
146
+ header_pattern = Regexp.quote(header)
147
+ footer_pattern = Regexp.quote(footer)
148
+ pattern = Regexp.new("\n*#{header_pattern}.*?#{footer_pattern}\n*", Regexp::MULTILINE)
149
+ # Replace existing block or append
150
+ old_content.match(pattern) ? old_content.sub(pattern, block) : old_content.rstrip + block
151
+ end
152
+
153
+ def read_or_create_id
154
+ file = Pathname.new("#{@global_env.local_data_path}/hostmanager/id")
155
+ if (file.file?)
156
+ id = file.read.strip
157
+ else
158
+ id = SecureRandom.uuid
159
+ file.dirname.mkpath
160
+ file.open('w') { |io| io.write(id) }
161
+ end
162
+ id
163
+ end
164
+
165
+ ## Windows support for copying files, requesting elevated privileges if necessary
166
+ module WindowsSupport
167
+ require 'rbconfig'
168
+
169
+ def self.windows?
170
+ RbConfig::CONFIG['host_os'] =~ /mswin|mingw|cygwin/
171
+ end
172
+
173
+ require 'win32ole' if windows?
174
+
175
+ def windows_copy_file(source, dest)
176
+ begin
177
+ # First, try Ruby copy
178
+ FileUtils.cp(source, dest)
179
+ rescue Errno::EACCES
180
+ # Access denied, try with elevated privileges
181
+ windows_copy_file_elevated(source, dest)
182
+ end
183
+ end
184
+
185
+ private
186
+
187
+ def windows_copy_file_elevated(source, dest)
188
+ # copy command only supports backslashes as separators
189
+ source, dest = [source, dest].map { |s| s.to_s.gsub(/\//, '\\') }
190
+
191
+ # run 'cmd /C copy ...' with elevated privilege, minimized
192
+ copy_cmd = "copy \"#{source}\" \"#{dest}\""
193
+ WIN32OLE.new('Shell.Application').ShellExecute('cmd', "/C #{copy_cmd}", nil, 'runas', 7)
194
+
195
+ # Unfortunately, ShellExecute does not give us a status code,
196
+ # and it is non-blocking so we can't reliably compare the file contents
197
+ # to see if they were copied.
198
+ #
199
+ # If the user rejects the UAC prompt, vagrant will silently continue
200
+ # without updating the hostsfile.
201
+ end
202
+ end
203
+ end
204
+ end
205
+ end
206
+ end
@@ -0,0 +1,44 @@
1
+ require 'vagrant-hostmanager/action'
2
+
3
+ module VagrantPlugins
4
+ module HostManager
5
+ class Plugin < Vagrant.plugin('2')
6
+ name 'HostManager'
7
+ description <<-DESC
8
+ This plugin manages the /etc/hosts file for the host and guest machines.
9
+ An entry is created for each running machine using the hostname attribute.
10
+
11
+ You can also use the hostmanager provisioner to update the hosts file.
12
+ DESC
13
+
14
+ config(:hostmanager) do
15
+ require_relative 'config'
16
+ Config
17
+ end
18
+
19
+ action_hook(:hostmanager, :machine_action_up) do |hook|
20
+ hook.after(Vagrant::Action::Builtin::Provision, Action.update_all)
21
+ end
22
+
23
+ action_hook(:hostmanager, :machine_action_destroy) do |hook|
24
+ hook.prepend(Action.update_all)
25
+ end
26
+
27
+ provisioner(:hostmanager) do
28
+ require_relative 'provisioner'
29
+ Provisioner
30
+ end
31
+
32
+ # Work-around for vagrant >= 1.5
33
+ # It breaks without a provisioner config, so we provide a dummy one
34
+ config(:hostmanager, :provisioner) do
35
+ ::Vagrant::Config::V2::DummyConfig.new
36
+ end
37
+
38
+ command(:hostmanager) do
39
+ require_relative 'command'
40
+ Command
41
+ end
42
+ end
43
+ end
44
+ end
@@ -0,0 +1,22 @@
1
+ require 'vagrant-hostmanager/hosts_file/updater'
2
+
3
+ module VagrantPlugins
4
+ module HostManager
5
+ class Provisioner < Vagrant.plugin('2', :provisioner)
6
+
7
+ def initialize(machine, config)
8
+ super(machine, config)
9
+ global_env = machine.env
10
+ @config = Util.get_config(global_env)
11
+ @updater = HostsFile::Updater.new(global_env, machine.provider_name)
12
+ end
13
+
14
+ def provision
15
+ @updater.update_guest(@machine)
16
+ if @config.hostmanager.manage_host?
17
+ @updater.update_host
18
+ end
19
+ end
20
+ end
21
+ end
22
+ 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
@@ -0,0 +1,5 @@
1
+ module VagrantPlugins
2
+ module HostManager
3
+ VERSION = '1.6.1'
4
+ end
5
+ end
@@ -0,0 +1,10 @@
1
+ en:
2
+ vagrant_hostmanager:
3
+ action:
4
+ update_guests: "Updating /etc/hosts file on active guest machines..."
5
+ update_guest: "[%{name}] Updating /etc/hosts file..."
6
+ update_host: "Updating /etc/hosts file on host machine (password may be required)..."
7
+ config:
8
+ not_a_bool: "A value for %{config_key} can only be true or false, not type '%{value}'"
9
+ not_an_array_or_string: "A value for %{config_key} must be an Array or String, not type '%{is_class}'"
10
+ not_a_proc: "A value for %{config_key} must be a Proc, not type '%{is_class}'"
@@ -0,0 +1,41 @@
1
+ # -*- mode: ruby -*-
2
+ # vi: set ft=ruby :
3
+
4
+ if Gem::Version.new(::Vagrant::VERSION) < Gem::Version.new('1.5')
5
+ Vagrant.require_plugin('vagrant-hostmanager')
6
+ end
7
+
8
+ Vagrant.configure('2') do |config|
9
+
10
+ if ENV.key? 'VAGRANT_BOX'
11
+ config.vm.box = ENV['VAGRANT_BOX']
12
+ else
13
+ config.vm.box = 'precise64'
14
+ config.vm.box_url = 'http://cloud-images.ubuntu.com/precise/current/precise-server-cloudimg-vagrant-amd64-disk1.box'
15
+ end
16
+
17
+ config.hostmanager.enabled = true
18
+ config.hostmanager.manage_host = true
19
+
20
+ config.vm.define :server1 do |server|
21
+ server.vm.hostname = 'fry'
22
+ server.vm.network :private_network, :ip => '10.0.5.2'
23
+ server.hostmanager.aliases = %w(test-alias)
24
+ end
25
+
26
+ config.vm.define :server2 do |server|
27
+ server.vm.hostname = 'bender'
28
+ server.vm.network :private_network, :ip => '10.0.5.3'
29
+ end
30
+
31
+ config.vm.define :server3 do |server|
32
+ server.vm.hostname = 'leena'
33
+ server.vm.network :private_network, :ip => '10.0.5.4'
34
+ server.vm.provision :hostmanager
35
+ end
36
+
37
+ config.vm.define :server4 do |server|
38
+ server.vm.hostname = 'scruffy'
39
+ server.vm.provision :hostmanager
40
+ end
41
+ end
@@ -0,0 +1,14 @@
1
+ cd test
2
+
3
+ vagrant up
4
+
5
+ vagrant hostmanager
6
+
7
+ echo "[server1] /etc/hosts file:"
8
+ vagrant ssh server1 -c 'cat /etc/hosts'
9
+ echo "[server2] /etc/hosts file:"
10
+ vagrant ssh server2 -c 'cat /etc/hosts'
11
+
12
+ vagrant destroy -f
13
+
14
+ cd ..
@@ -0,0 +1,22 @@
1
+ # -*- encoding: utf-8 -*-
2
+
3
+ lib = File.expand_path('../lib', __FILE__)
4
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
5
+ require 'vagrant-hostmanager/version'
6
+
7
+ Gem::Specification.new do |gem|
8
+ gem.name = 'vagrant-hostmanager-docker'
9
+ gem.version = VagrantPlugins::HostManager::VERSION
10
+ gem.authors = ['Shawn Dahlen']
11
+ gem.email = ['shawn@dahlen.me']
12
+ gem.description = %q{A Vagrant plugin that manages the /etc/hosts file within a multi-machine environment}
13
+ gem.summary = gem.description
14
+ gem.license = 'MIT'
15
+
16
+ gem.files = `git ls-files`.split($/)
17
+ gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
18
+ gem.require_paths = ['lib']
19
+
20
+ gem.add_development_dependency 'bundler', '~> 1.3'
21
+ gem.add_development_dependency 'rake'
22
+ end
metadata ADDED
@@ -0,0 +1,99 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: vagrant-hostmanager-docker
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.6.1
5
+ platform: ruby
6
+ authors:
7
+ - Shawn Dahlen
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2015-10-10 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: bundler
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '1.3'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '1.3'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rake
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ description: A Vagrant plugin that manages the /etc/hosts file within a multi-machine
42
+ environment
43
+ email:
44
+ - shawn@dahlen.me
45
+ executables: []
46
+ extensions: []
47
+ extra_rdoc_files: []
48
+ files:
49
+ - ".gitignore"
50
+ - CHANGELOG.md
51
+ - Gemfile
52
+ - LICENSE.txt
53
+ - README.md
54
+ - Rakefile
55
+ - lib/vagrant-hostmanager.rb
56
+ - lib/vagrant-hostmanager/action.rb
57
+ - lib/vagrant-hostmanager/action/update_all.rb
58
+ - lib/vagrant-hostmanager/action/update_guest.rb
59
+ - lib/vagrant-hostmanager/action/update_host.rb
60
+ - lib/vagrant-hostmanager/command.rb
61
+ - lib/vagrant-hostmanager/config.rb
62
+ - lib/vagrant-hostmanager/errors.rb
63
+ - lib/vagrant-hostmanager/hosts_file/updater.rb
64
+ - lib/vagrant-hostmanager/plugin.rb
65
+ - lib/vagrant-hostmanager/provisioner.rb
66
+ - lib/vagrant-hostmanager/util.rb
67
+ - lib/vagrant-hostmanager/version.rb
68
+ - locales/en.yml
69
+ - test/Vagrantfile
70
+ - test/test.sh
71
+ - vagrant-hostmanager.gemspec
72
+ homepage:
73
+ licenses:
74
+ - MIT
75
+ metadata: {}
76
+ post_install_message:
77
+ rdoc_options: []
78
+ require_paths:
79
+ - lib
80
+ required_ruby_version: !ruby/object:Gem::Requirement
81
+ requirements:
82
+ - - ">="
83
+ - !ruby/object:Gem::Version
84
+ version: '0'
85
+ required_rubygems_version: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - ">="
88
+ - !ruby/object:Gem::Version
89
+ version: '0'
90
+ requirements: []
91
+ rubyforge_project:
92
+ rubygems_version: 2.4.5.1
93
+ signing_key:
94
+ specification_version: 4
95
+ summary: A Vagrant plugin that manages the /etc/hosts file within a multi-machine
96
+ environment
97
+ test_files:
98
+ - test/Vagrantfile
99
+ - test/test.sh