vagrant-vmware-esxi 1.0.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.
- checksums.yaml +7 -0
- data/Gemfile +14 -0
- data/LICENSE +674 -0
- data/README.md +175 -0
- data/Rakefile +4 -0
- data/example_box/metadata.json +4 -0
- data/lib/vagrant-vmware-esxi.rb +18 -0
- data/lib/vagrant-vmware-esxi/action.rb +119 -0
- data/lib/vagrant-vmware-esxi/action/boot.rb +59 -0
- data/lib/vagrant-vmware-esxi/action/connect_esxi.rb +58 -0
- data/lib/vagrant-vmware-esxi/action/createvm.rb +302 -0
- data/lib/vagrant-vmware-esxi/action/destroy.rb +58 -0
- data/lib/vagrant-vmware-esxi/action/halt.rb +52 -0
- data/lib/vagrant-vmware-esxi/action/read_ssh_info.rb +63 -0
- data/lib/vagrant-vmware-esxi/action/read_state.rb +67 -0
- data/lib/vagrant-vmware-esxi/action/resume.rb +63 -0
- data/lib/vagrant-vmware-esxi/action/suspend.rb +61 -0
- data/lib/vagrant-vmware-esxi/action/wait_for_state.rb +40 -0
- data/lib/vagrant-vmware-esxi/config.rb +56 -0
- data/lib/vagrant-vmware-esxi/errors.rb +22 -0
- data/lib/vagrant-vmware-esxi/plugin.rb +61 -0
- data/lib/vagrant-vmware-esxi/provider.rb +44 -0
- data/lib/vagrant-vmware-esxi/version.rb +6 -0
- data/locales/en.yml +65 -0
- data/vagrant-vmware-esxi.gemspec +27 -0
- metadata +151 -0
@@ -0,0 +1,58 @@
|
|
1
|
+
require 'log4r'
|
2
|
+
require 'net/ssh/simple'
|
3
|
+
|
4
|
+
module VagrantPlugins
|
5
|
+
module ESXi
|
6
|
+
module Action
|
7
|
+
# This action will Destroy VM. unregister and delete the VM from disk.
|
8
|
+
class Destroy
|
9
|
+
def initialize(app, _env)
|
10
|
+
@app = app
|
11
|
+
@logger = Log4r::Logger.new('vagrant_vmware_esxi::action::destroy')
|
12
|
+
end
|
13
|
+
|
14
|
+
def call(env)
|
15
|
+
destroy(env)
|
16
|
+
@app.call(env)
|
17
|
+
end
|
18
|
+
|
19
|
+
def destroy(env)
|
20
|
+
@logger.info('vagrant-vmware-esxi, destroy: start...')
|
21
|
+
|
22
|
+
# Get config.
|
23
|
+
machine = env[:machine]
|
24
|
+
config = env[:machine].provider_config
|
25
|
+
|
26
|
+
@logger.info("vagrant-vmware-esxi, destroy: machine id: #{machine.id}")
|
27
|
+
@logger.info('vagrant-vmware-esxi, destroy: current state: '\
|
28
|
+
"#{env[:machine_state]}")
|
29
|
+
|
30
|
+
if env[:machine_state].to_s == 'not_created'
|
31
|
+
env[:ui].info I18n.t('vagrant_vmware_esxi.already_destroyed')
|
32
|
+
elsif env[:machine_state].to_s != 'powered_off'
|
33
|
+
raise Errors::ESXiError,
|
34
|
+
message: 'Guest VM should have been powered off...'
|
35
|
+
else
|
36
|
+
Net::SSH::Simple.sync(
|
37
|
+
user: config.esxi_username,
|
38
|
+
password: config.esxi_password,
|
39
|
+
port: config.esxi_hostport,
|
40
|
+
keys: config.esxi_private_keys
|
41
|
+
) do
|
42
|
+
|
43
|
+
r = ssh config.esxi_hostname,
|
44
|
+
"vim-cmd vmsvc/destroy #{machine.id}"
|
45
|
+
if r.exit_code != 0
|
46
|
+
raise Errors::ESXiError,
|
47
|
+
message => "Unable to destroy the VM:\n"\
|
48
|
+
" #{r.stdout}\n#{r.stderr}"
|
49
|
+
end
|
50
|
+
env[:ui].info I18n.t('vagrant_vmware_esxi.vagrant_vmware_esxi_message',
|
51
|
+
message: 'VM has been destroyed...')
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
@@ -0,0 +1,52 @@
|
|
1
|
+
require 'log4r'
|
2
|
+
require 'net/ssh/simple'
|
3
|
+
|
4
|
+
module VagrantPlugins
|
5
|
+
module ESXi
|
6
|
+
module Action
|
7
|
+
# This action will halt (power off) the VM
|
8
|
+
class Halt
|
9
|
+
def initialize(app, env)
|
10
|
+
@app = app
|
11
|
+
@logger = Log4r::Logger.new('vagrant_vmware_esxi::action::halt')
|
12
|
+
end
|
13
|
+
|
14
|
+
def call(env)
|
15
|
+
halt(env)
|
16
|
+
@app.call(env)
|
17
|
+
end
|
18
|
+
|
19
|
+
def halt(env)
|
20
|
+
@logger.info('vagrant-vmware-esxi, halt: start...')
|
21
|
+
|
22
|
+
# Get config.
|
23
|
+
machine = env[:machine]
|
24
|
+
config = env[:machine].provider_config
|
25
|
+
|
26
|
+
if env[:machine_state].to_s == 'powered_off'
|
27
|
+
env[:ui].info I18n.t('vagrant_vmware_esxi.already_powered_off')
|
28
|
+
elsif env[:machine_state].to_s == 'not_created'
|
29
|
+
env[:ui].info I18n.t('vagrant_vmware_esxi.already_destroyed')
|
30
|
+
else
|
31
|
+
Net::SSH::Simple.sync(
|
32
|
+
user: config.esxi_username,
|
33
|
+
password: config.esxi_password,
|
34
|
+
port: config.esxi_hostport,
|
35
|
+
keys: config.esxi_private_keys
|
36
|
+
) do
|
37
|
+
|
38
|
+
r = ssh config.esxi_hostname,
|
39
|
+
"vim-cmd vmsvc/power.off #{machine.id}"
|
40
|
+
if r.exit_code != 0
|
41
|
+
raise Errors::ESXiError,
|
42
|
+
message: "Unable to power off the VM:\n"
|
43
|
+
" #{r.stdout}\n#{r.stderr}"
|
44
|
+
end
|
45
|
+
env[:ui].info I18n.t('vagrant_vmware_esxi.states.powered_off.short')
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
@@ -0,0 +1,63 @@
|
|
1
|
+
require 'log4r'
|
2
|
+
|
3
|
+
module VagrantPlugins
|
4
|
+
module ESXi
|
5
|
+
module Action
|
6
|
+
# This action will get the SSH "availability".
|
7
|
+
class ReadSSHInfo
|
8
|
+
def initialize(app, _env)
|
9
|
+
@app = app
|
10
|
+
@logger = Log4r::Logger.new('vagrant_vmware_esxi::action::read_ssh_info')
|
11
|
+
end
|
12
|
+
|
13
|
+
def call(env)
|
14
|
+
env[:machine_ssh_info] = read_ssh_info(env)
|
15
|
+
@app.call(env)
|
16
|
+
end
|
17
|
+
|
18
|
+
def read_ssh_info(env)
|
19
|
+
@logger.info('vagrant-vmware-esxi, read_ssh_info: start...')
|
20
|
+
|
21
|
+
# Get config.
|
22
|
+
machine = env[:machine]
|
23
|
+
config = env[:machine].provider_config
|
24
|
+
|
25
|
+
return :not_created if machine.id.nil?
|
26
|
+
|
27
|
+
@logger.info("vagrant-vmware-esxi, read_ssh_info: machine id: #{machine.id}")
|
28
|
+
@logger.info('vagrant-vmware-esxi, read_ssh_info: current state:'\
|
29
|
+
" #{env[:machine_state]}")
|
30
|
+
|
31
|
+
# Figure out vm_ipaddress
|
32
|
+
Net::SSH::Simple.sync(
|
33
|
+
user: config.esxi_username,
|
34
|
+
password: config.esxi_password,
|
35
|
+
port: config.esxi_hostport,
|
36
|
+
keys: config.esxi_private_keys
|
37
|
+
) do
|
38
|
+
|
39
|
+
@logger = Log4r::Logger.new('vagrant_vmware_esxi::action::'\
|
40
|
+
'read_ssh_info-net_ssh')
|
41
|
+
|
42
|
+
# ugly, but it works...
|
43
|
+
ssh_execute_cmd = "vim-cmd vmsvc/get.guest #{machine.id} |"
|
44
|
+
ssh_execute_cmd << 'grep -i "^ ipAddress"|'
|
45
|
+
ssh_execute_cmd << 'grep -oE "((1?[0-9][0-9]?|2[0-4][0-9]|25[0-5])\.){3}(1?[0-9][0-9]?|2[0-4][0-9]|25[0-5])"'
|
46
|
+
r = ssh config.esxi_hostname, ssh_execute_cmd
|
47
|
+
|
48
|
+
ipaddress = r.stdout.strip
|
49
|
+
@logger.info('vagrant-vmware-esxi, read_ssh_info: ipaddress: '\
|
50
|
+
"#{ipaddress}")
|
51
|
+
|
52
|
+
return nil if (ipaddress == '') || (r.exit_code != 0)
|
53
|
+
|
54
|
+
return {
|
55
|
+
host: ipaddress,
|
56
|
+
port: 22
|
57
|
+
}
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
@@ -0,0 +1,67 @@
|
|
1
|
+
require 'log4r'
|
2
|
+
|
3
|
+
module VagrantPlugins
|
4
|
+
module ESXi
|
5
|
+
module Action
|
6
|
+
# This action reads the state of the machine and puts it in the
|
7
|
+
# `:machine_state_id` key in the environment.
|
8
|
+
class ReadState
|
9
|
+
def initialize(app, env)
|
10
|
+
@app = app
|
11
|
+
@logger = Log4r::Logger.new('vagrant_vmware_esxi::action::read_state')
|
12
|
+
end
|
13
|
+
|
14
|
+
def call(env)
|
15
|
+
env[:machine_state] = read_state(env)
|
16
|
+
@app.call(env)
|
17
|
+
end
|
18
|
+
|
19
|
+
def read_state(env)
|
20
|
+
@logger.info('vagrant-vmware-esxi, read_state: start...')
|
21
|
+
|
22
|
+
# Get config.
|
23
|
+
machine = env[:machine]
|
24
|
+
config = env[:machine].provider_config
|
25
|
+
|
26
|
+
return :not_created if machine.id.to_i < 1
|
27
|
+
|
28
|
+
@logger.info("vagrant-vmware-esxi, read_state: machine id: #{machine.id}")
|
29
|
+
@logger.info("vagrant-vmware-esxi, read_state: current state: #{env[:machine_state]}")
|
30
|
+
|
31
|
+
Net::SSH::Simple.sync(
|
32
|
+
user: config.esxi_username,
|
33
|
+
password: config.esxi_password,
|
34
|
+
port: config.esxi_hostport,
|
35
|
+
keys: config.esxi_private_keys
|
36
|
+
) do
|
37
|
+
|
38
|
+
r = ssh config.esxi_hostname,
|
39
|
+
"vim-cmd vmsvc/getallvms|grep -q \"^#{machine.id} \" && "\
|
40
|
+
"vim-cmd vmsvc/power.getstate #{machine.id} || return 254"
|
41
|
+
power_status = r.stdout
|
42
|
+
|
43
|
+
return :not_created if r.exit_code == 254
|
44
|
+
if power_status == "" or r.exit_code != 0
|
45
|
+
raise Errors::ESXiError,
|
46
|
+
message: 'Unable to get VM Power State!'
|
47
|
+
end
|
48
|
+
|
49
|
+
if (power_status.include? "Powered on") && !env[:machine].ssh_info.nil?
|
50
|
+
return :running
|
51
|
+
elsif power_status.include? "Powered on"
|
52
|
+
return :powered_on
|
53
|
+
elsif power_status.include? "Powered off"
|
54
|
+
return :powered_off
|
55
|
+
elsif power_status.include? "Suspended"
|
56
|
+
return :suspended
|
57
|
+
end
|
58
|
+
|
59
|
+
return nil
|
60
|
+
end
|
61
|
+
|
62
|
+
return :not_created
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
@@ -0,0 +1,63 @@
|
|
1
|
+
require 'log4r'
|
2
|
+
require 'net/ssh/simple'
|
3
|
+
|
4
|
+
module VagrantPlugins
|
5
|
+
module ESXi
|
6
|
+
module Action
|
7
|
+
# This action will Resume (power on) the VM
|
8
|
+
class Resume
|
9
|
+
def initialize(app, _env)
|
10
|
+
@app = app
|
11
|
+
@logger = Log4r::Logger.new('vagrant_vmware_esxi::action::resume')
|
12
|
+
end
|
13
|
+
|
14
|
+
def call(env)
|
15
|
+
resume(env)
|
16
|
+
@app.call(env)
|
17
|
+
end
|
18
|
+
|
19
|
+
def resume(env)
|
20
|
+
@logger.info('vagrant-vmware-esxi, resume: start...')
|
21
|
+
|
22
|
+
# Get config.
|
23
|
+
machine = env[:machine]
|
24
|
+
config = env[:machine].provider_config
|
25
|
+
|
26
|
+
@logger.info("vagrant-vmware-esxi, resume: machine id: #{machine.id}")
|
27
|
+
@logger.info("vagrant-vmware-esxi, resume: current state: #{env[:machine_state]}")
|
28
|
+
|
29
|
+
if (env[:machine_state].to_s == 'powered_on') ||
|
30
|
+
(env[:machine_state].to_s == 'running')
|
31
|
+
env[:ui].info I18n.t('vagrant_vmware_esxi.already_powered_on')
|
32
|
+
elsif env[:machine_state].to_s == 'not_created'
|
33
|
+
env[:ui].info I18n.t('vagrant_vmware_esxi.vagrant_vmware_esxi_message',
|
34
|
+
message: 'Cannot resume in this state')
|
35
|
+
elsif (env[:machine_state].to_s == 'powered_off') ||
|
36
|
+
(env[:machine_state].to_s == 'suspended')
|
37
|
+
env[:ui].info I18n.t('vagrant_vmware_esxi.vagrant_vmware_esxi_message',
|
38
|
+
message: 'Attempting to resume')
|
39
|
+
|
40
|
+
Net::SSH::Simple.sync(
|
41
|
+
user: config.esxi_username,
|
42
|
+
password: config.esxi_password,
|
43
|
+
port: config.esxi_hostport,
|
44
|
+
keys: config.esxi_private_keys
|
45
|
+
) do
|
46
|
+
|
47
|
+
r = ssh config.esxi_hostname, "vim-cmd vmsvc/power.on #{machine.id}"
|
48
|
+
if r.exit_code != 0
|
49
|
+
raise Errors::ESXiError,
|
50
|
+
message: "Unable to resume the VM:\n"\
|
51
|
+
" #{r.stdout}\n#{r.stderr}"
|
52
|
+
end
|
53
|
+
env[:ui].info I18n.t('vagrant_vmware_esxi.vagrant_vmware_esxi_message',
|
54
|
+
message: 'VM has been resumed...')
|
55
|
+
end
|
56
|
+
else
|
57
|
+
raise Errors::ESXiError, message: 'Unknown state to resume...'
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
@@ -0,0 +1,61 @@
|
|
1
|
+
require 'log4r'
|
2
|
+
require 'net/ssh/simple'
|
3
|
+
|
4
|
+
module VagrantPlugins
|
5
|
+
module ESXi
|
6
|
+
module Action
|
7
|
+
# This action will Suspend the VM
|
8
|
+
class Suspend
|
9
|
+
def initialize(app, _env)
|
10
|
+
@app = app
|
11
|
+
@logger = Log4r::Logger.new('vagrant_vmware_esxi::action::suspend')
|
12
|
+
end
|
13
|
+
|
14
|
+
def call(env)
|
15
|
+
suspend(env)
|
16
|
+
@app.call(env)
|
17
|
+
end
|
18
|
+
|
19
|
+
def suspend(env)
|
20
|
+
@logger.info('vagrant-vmware-esxi, suspend: start...')
|
21
|
+
|
22
|
+
# Get config.
|
23
|
+
machine = env[:machine]
|
24
|
+
config = env[:machine].provider_config
|
25
|
+
|
26
|
+
@logger.info("vagrant-vmware-esxi, suspend: machine id: #{machine.id}")
|
27
|
+
@logger.info("vagrant-vmware-esxi, suspend: current state: #{env[:machine_state]}")
|
28
|
+
|
29
|
+
if env[:machine_state].to_s == 'suspended'
|
30
|
+
env[:ui].info I18n.t('vagrant_vmware_esxi.already_suspended')
|
31
|
+
elsif (env[:machine_state].to_s == 'powered_off') ||
|
32
|
+
(env[:machine_state].to_s == 'not_created')
|
33
|
+
env[:ui].info I18n.t('vagrant_vmware_esxi.vagrant_vmware_esxi_message',
|
34
|
+
message: 'Cannot suspend in this state')
|
35
|
+
else
|
36
|
+
env[:ui].info I18n.t('vagrant_vmware_esxi.vagrant_vmware_esxi_message',
|
37
|
+
message: 'Attempting to suspend')
|
38
|
+
|
39
|
+
Net::SSH::Simple.sync(
|
40
|
+
user: config.esxi_username,
|
41
|
+
password: config.esxi_password,
|
42
|
+
port: config.esxi_hostport,
|
43
|
+
keys: config.esxi_private_keys,
|
44
|
+
timeout: 300
|
45
|
+
) do
|
46
|
+
|
47
|
+
r = ssh config.esxi_hostname, "vim-cmd vmsvc/power.suspend #{machine.id}"
|
48
|
+
if r.exit_code != 0
|
49
|
+
raise Errors::ESXiError,
|
50
|
+
message: "Unable to suspend the VM:\n"\
|
51
|
+
" #{r.stdout}\n#{r.stderr}"
|
52
|
+
end
|
53
|
+
env[:ui].info I18n.t('vagrant_vmware_esxi.support')
|
54
|
+
env[:ui].info I18n.t('vagrant_vmware_esxi.states.suspended.short')
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
@@ -0,0 +1,40 @@
|
|
1
|
+
require 'log4r'
|
2
|
+
require 'timeout'
|
3
|
+
|
4
|
+
module VagrantPlugins
|
5
|
+
module ESXi
|
6
|
+
module Action
|
7
|
+
# This action will wait for a machine to reach a specific state or quit
|
8
|
+
# by timeout
|
9
|
+
class WaitForState
|
10
|
+
# env[:result] will be false in case of timeout.
|
11
|
+
# @param [Symbol] state Target machine state.
|
12
|
+
# @param [Number] timeout Timeout in seconds.
|
13
|
+
def initialize(app, _env, state, timeout)
|
14
|
+
@app = app
|
15
|
+
@logger = Log4r::Logger.new('vagrant_vmware_esxi::action::wait_for_state')
|
16
|
+
@state = state
|
17
|
+
@timeout = timeout
|
18
|
+
end
|
19
|
+
|
20
|
+
def call(env)
|
21
|
+
env[:result] = 'True'
|
22
|
+
if env[:machine].state.id != @state
|
23
|
+
env[:ui].info I18n.t('vagrant_vmware_esxi.vagrant_vmware_esxi_message',
|
24
|
+
message: "Waiting for state \"#{@state}\"")
|
25
|
+
begin
|
26
|
+
Timeout.timeout(@timeout) do
|
27
|
+
until env[:machine].state.id == @state
|
28
|
+
sleep 4
|
29
|
+
end
|
30
|
+
end
|
31
|
+
rescue Timeout::Error
|
32
|
+
env[:result] = 'False' # couldn't reach state in time
|
33
|
+
end
|
34
|
+
end
|
35
|
+
@app.call(env)
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
@@ -0,0 +1,56 @@
|
|
1
|
+
# Config
|
2
|
+
|
3
|
+
module VagrantPlugins
|
4
|
+
module ESXi
|
5
|
+
# Config class
|
6
|
+
class Config < Vagrant.plugin('2', :config)
|
7
|
+
attr_accessor :esxi_hostname
|
8
|
+
attr_accessor :esxi_hostport
|
9
|
+
attr_accessor :esxi_username
|
10
|
+
attr_accessor :esxi_password
|
11
|
+
attr_accessor :esxi_private_keys
|
12
|
+
attr_accessor :ssh_username
|
13
|
+
attr_accessor :private_key_path
|
14
|
+
attr_accessor :vmname
|
15
|
+
attr_accessor :vmname_prefix
|
16
|
+
attr_accessor :vm_disk_store
|
17
|
+
attr_accessor :virtual_network
|
18
|
+
attr_accessor :resource_pool
|
19
|
+
attr_accessor :memsize
|
20
|
+
attr_accessor :numvcpus
|
21
|
+
attr_accessor :custom_vmx_settings
|
22
|
+
attr_accessor :allow_overwrite
|
23
|
+
attr_accessor :system_private_keys_path
|
24
|
+
def initialize
|
25
|
+
@esxi_hostname = nil
|
26
|
+
@esxi_hostport = 22
|
27
|
+
@esxi_username = 'root'
|
28
|
+
@esxi_password = nil
|
29
|
+
@esxi_private_keys = UNSET_VALUE
|
30
|
+
@ssh_username = 'vagrant'
|
31
|
+
@private_key_path = UNSET_VALUE
|
32
|
+
@vmname = nil
|
33
|
+
@vmname_prefix = 'V-'
|
34
|
+
@vm_disk_store = nil
|
35
|
+
@virtual_network = nil
|
36
|
+
@resource_pool = nil
|
37
|
+
@memsize = UNSET_VALUE
|
38
|
+
@numvcpus = UNSET_VALUE
|
39
|
+
@custom_vmx_settings = UNSET_VALUE
|
40
|
+
@allow_overwrite = 'False'
|
41
|
+
@system_private_keys_path = [
|
42
|
+
'~/.ssh/id_rsa',
|
43
|
+
'~/.ssh/id_ecdsa',
|
44
|
+
'~/.ssh/id_ed25519',
|
45
|
+
'~/.ssh/id_dsa'
|
46
|
+
]
|
47
|
+
end
|
48
|
+
|
49
|
+
def finalize!
|
50
|
+
@private_key_path = nil if @private_key_path == UNSET_VALUE
|
51
|
+
@ssh_username = nil if @ssh_username == UNSET_VALUE
|
52
|
+
@esxi_private_keys = @system_private_keys_path if @esxi_private_keys == UNSET_VALUE
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|