vagrant-vmware-esxi 1.0.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -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