vagrant-vmware-appcatalyst 1.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (39) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +38 -0
  3. data/.rubocop.yml +34 -0
  4. data/Gemfile +7 -0
  5. data/LICENSE +177 -0
  6. data/README.md +72 -0
  7. data/lib/vagrant-vmware-appcatalyst.rb +30 -0
  8. data/lib/vagrant-vmware-appcatalyst/action.rb +249 -0
  9. data/lib/vagrant-vmware-appcatalyst/action/connect_appcatalyst.rb +45 -0
  10. data/lib/vagrant-vmware-appcatalyst/action/destroy_vm.rb +33 -0
  11. data/lib/vagrant-vmware-appcatalyst/action/import.rb +101 -0
  12. data/lib/vagrant-vmware-appcatalyst/action/is_created.rb +34 -0
  13. data/lib/vagrant-vmware-appcatalyst/action/is_paused.rb +33 -0
  14. data/lib/vagrant-vmware-appcatalyst/action/is_running.rb +32 -0
  15. data/lib/vagrant-vmware-appcatalyst/action/message_already_running.rb +29 -0
  16. data/lib/vagrant-vmware-appcatalyst/action/message_not_created.rb +29 -0
  17. data/lib/vagrant-vmware-appcatalyst/action/message_not_running.rb +29 -0
  18. data/lib/vagrant-vmware-appcatalyst/action/message_not_supported.rb +29 -0
  19. data/lib/vagrant-vmware-appcatalyst/action/message_will_not_destroy.rb +30 -0
  20. data/lib/vagrant-vmware-appcatalyst/action/power_off.rb +40 -0
  21. data/lib/vagrant-vmware-appcatalyst/action/power_on.rb +34 -0
  22. data/lib/vagrant-vmware-appcatalyst/action/read_ssh_info.rb +56 -0
  23. data/lib/vagrant-vmware-appcatalyst/action/read_state.rb +72 -0
  24. data/lib/vagrant-vmware-appcatalyst/action/resume.rb +31 -0
  25. data/lib/vagrant-vmware-appcatalyst/action/suspend.rb +31 -0
  26. data/lib/vagrant-vmware-appcatalyst/cap/mount_appcatalyst_shared_folder.rb +100 -0
  27. data/lib/vagrant-vmware-appcatalyst/cap/public_address.rb +31 -0
  28. data/lib/vagrant-vmware-appcatalyst/config.rb +40 -0
  29. data/lib/vagrant-vmware-appcatalyst/driver/base.rb +131 -0
  30. data/lib/vagrant-vmware-appcatalyst/driver/meta.rb +106 -0
  31. data/lib/vagrant-vmware-appcatalyst/driver/version_1_0.rb +223 -0
  32. data/lib/vagrant-vmware-appcatalyst/errors.rb +44 -0
  33. data/lib/vagrant-vmware-appcatalyst/plugin.rb +111 -0
  34. data/lib/vagrant-vmware-appcatalyst/provider.rb +60 -0
  35. data/lib/vagrant-vmware-appcatalyst/synced_folder.rb +123 -0
  36. data/lib/vagrant-vmware-appcatalyst/version.rb +18 -0
  37. data/locales/en.yml +29 -0
  38. data/vagrant-vmware-appcatalyst.gemspec +40 -0
  39. metadata +165 -0
@@ -0,0 +1,34 @@
1
+ # encoding: utf-8
2
+ # Copyright (c) 2015 VMware, Inc. All Rights Reserved.
3
+ #
4
+ # Licensed under the Apache License, Version 2.0 (the "License"); you may not
5
+ # use this file except in compliance with the License. You may obtain a copy of
6
+ # the License at http://www.apache.org/licenses/LICENSE-2.0
7
+ #
8
+ # Unless required by applicable law or agreed to in writing, software
9
+ # distributed under the License is distributed on an "AS IS" BASIS, without
10
+ # warranties or conditions of any kind, EITHER EXPRESS OR IMPLIED. See the
11
+ # License for the specific language governing permissions and limitations under
12
+ # the License.
13
+
14
+ module VagrantPlugins
15
+ module AppCatalyst
16
+ module Action
17
+ class PowerOn
18
+ def initialize(app, env)
19
+ @app = app
20
+ @logger = Log4r::Logger.new('vagrant_appcatalyst::action::power_on')
21
+ end
22
+
23
+ def call(env)
24
+ begin
25
+ env[:appcatalyst_cnx].set_vm_power(env[:machine].id, 'on')
26
+ rescue Errors::UnattendedCodeError
27
+ raise Errors::PowerOnNotAllowed
28
+ end
29
+ @app.call(env)
30
+ end
31
+ end
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,56 @@
1
+ # encoding: utf-8
2
+ # Copyright (c) 2015 VMware, Inc. All Rights Reserved.
3
+ #
4
+ # Licensed under the Apache License, Version 2.0 (the "License"); you may not
5
+ # use this file except in compliance with the License. You may obtain a copy of
6
+ # the License at http://www.apache.org/licenses/LICENSE-2.0
7
+ #
8
+ # Unless required by applicable law or agreed to in writing, software
9
+ # distributed under the License is distributed on an "AS IS" BASIS, without
10
+ # warranties or conditions of any kind, EITHER EXPRESS OR IMPLIED. See the
11
+ # License for the specific language governing permissions and limitations under
12
+ # the License.
13
+
14
+ module VagrantPlugins
15
+ module AppCatalyst
16
+ module Action
17
+ class ReadSSHInfo
18
+ def initialize(app, env, port = 22)
19
+ @app = app
20
+ @port = port
21
+ @logger = Log4r::Logger.new('vagrant_appcatalyst::action::read_ssh_info')
22
+ end
23
+
24
+ def call(env)
25
+ env[:machine_ssh_info] = read_ssh_info(env)
26
+
27
+ @app.call env
28
+ end
29
+
30
+ def read_ssh_info(env)
31
+ return nil if env[:machine].id.nil?
32
+
33
+ begin
34
+ ipaddress = env[:appcatalyst_cnx].get_vm_ipaddress(env[:machine].id)
35
+ rescue Errors::UnattendedCodeError
36
+ @retries ||= 0
37
+ if @retries < 60
38
+ @retries += 1
39
+ sleep 2
40
+ retry
41
+ else
42
+ raise Errors::UnattendedCodeError,
43
+ :message => "Can't look up ip address for this VM"
44
+ end
45
+ end
46
+
47
+ # If we are here, then SSH is ready, continue
48
+ {
49
+ :host => ipaddress['message'],
50
+ :port => 22
51
+ }
52
+ end
53
+ end
54
+ end
55
+ end
56
+ end
@@ -0,0 +1,72 @@
1
+ # encoding: utf-8
2
+ # Copyright (c) 2015 VMware, Inc. All Rights Reserved.
3
+ #
4
+ # Licensed under the Apache License, Version 2.0 (the "License"); you may not
5
+ # use this file except in compliance with the License. You may obtain a copy of
6
+ # the License at http://www.apache.org/licenses/LICENSE-2.0
7
+ #
8
+ # Unless required by applicable law or agreed to in writing, software
9
+ # distributed under the License is distributed on an "AS IS" BASIS, without
10
+ # warranties or conditions of any kind, EITHER EXPRESS OR IMPLIED. See the
11
+ # License for the specific language governing permissions and limitations under
12
+ # the License.
13
+
14
+ module VagrantPlugins
15
+ module AppCatalyst
16
+ module Action
17
+ class ReadState
18
+ def initialize(app, env)
19
+ @app = app
20
+ @logger = Log4r::Logger.new('vagrant_appcatalyst::action::read_state')
21
+ end
22
+
23
+ def call(env)
24
+ env[:machine_state_id] = read_state(env)
25
+
26
+ @app.call env
27
+ end
28
+
29
+ def read_state(env)
30
+ vm_name = env[:machine].name
31
+
32
+ if env[:machine].id.nil?
33
+ @logger.info("VM [#{vm_name}] is not created yet")
34
+ return :not_created
35
+ end
36
+
37
+ power_state = env[:appcatalyst_cnx].get_vm_power(env[:machine].id)
38
+
39
+ case power_state['message']
40
+ when 'powering on'
41
+ @logger.info("VM [#{vm_name}] is running")
42
+ return :running
43
+ when 'powered on'
44
+ @logger.info("VM [#{vm_name}] is running")
45
+ return :running
46
+ when 'powering off'
47
+ @logger.info("VM [#{vm_name}] is stopped")
48
+ return :stopped
49
+ when 'powered off'
50
+ @logger.info("VM [#{vm_name}] is stopped")
51
+ return :stopped
52
+ when 'suspended'
53
+ @logger.info("VM [#{vm_name}] is suspended")
54
+ return :suspended
55
+ when 'suspending'
56
+ @logger.info("VM [#{vm_name}] is suspended")
57
+ return :suspended
58
+ when 'tools_running'
59
+ @logger.info("VM [#{vm_name}] is running")
60
+ return :running
61
+ when 'blocked on msg'
62
+ @logger.info("VM [#{vm_name}] is stopped")
63
+ return :stopped
64
+ else
65
+ @logger.info("VM [#{vm_name}] is in an unknown state")
66
+ return :unknown
67
+ end
68
+ end
69
+ end
70
+ end
71
+ end
72
+ end
@@ -0,0 +1,31 @@
1
+ # encoding: utf-8
2
+ # Copyright (c) 2015 VMware, Inc. All Rights Reserved.
3
+ #
4
+ # Licensed under the Apache License, Version 2.0 (the "License"); you may not
5
+ # use this file except in compliance with the License. You may obtain a copy of
6
+ # the License at http://www.apache.org/licenses/LICENSE-2.0
7
+ #
8
+ # Unless required by applicable law or agreed to in writing, software
9
+ # distributed under the License is distributed on an "AS IS" BASIS, without
10
+ # warranties or conditions of any kind, EITHER EXPRESS OR IMPLIED. See the
11
+ # License for the specific language governing permissions and limitations under
12
+ # the License.
13
+
14
+ module VagrantPlugins
15
+ module AppCatalyst
16
+ module Action
17
+ class Resume
18
+ def initialize(app, env)
19
+ @app = app
20
+ @logger = Log4r::Logger.new('vagrant_appcatalyst::action::resume')
21
+ end
22
+
23
+ def call(env)
24
+ env[:appcatalyst_cnx].set_vm_power(env[:machine].id, 'resume')
25
+
26
+ @app.call(env)
27
+ end
28
+ end
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,31 @@
1
+ # encoding: utf-8
2
+ # Copyright (c) 2015 VMware, Inc. All Rights Reserved.
3
+ #
4
+ # Licensed under the Apache License, Version 2.0 (the "License"); you may not
5
+ # use this file except in compliance with the License. You may obtain a copy of
6
+ # the License at http://www.apache.org/licenses/LICENSE-2.0
7
+ #
8
+ # Unless required by applicable law or agreed to in writing, software
9
+ # distributed under the License is distributed on an "AS IS" BASIS, without
10
+ # warranties or conditions of any kind, EITHER EXPRESS OR IMPLIED. See the
11
+ # License for the specific language governing permissions and limitations under
12
+ # the License.
13
+
14
+ module VagrantPlugins
15
+ module AppCatalyst
16
+ module Action
17
+ class Suspend
18
+ def initialize(app, env)
19
+ @app = app
20
+ @logger = Log4r::Logger.new('vagrant_appcatalyst::action::suspend')
21
+ end
22
+
23
+ def call(env)
24
+ env[:appcatalyst_cnx].set_vm_power(env[:machine].id, 'suspend')
25
+
26
+ @app.call(env)
27
+ end
28
+ end
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,100 @@
1
+ # encoding: utf-8
2
+ # Copyright (c) 2015 VMware, Inc. All Rights Reserved.
3
+ #
4
+ # Licensed under the Apache License, Version 2.0 (the "License"); you may not
5
+ # use this file except in compliance with the License. You may obtain a copy of
6
+ # the License at http://www.apache.org/licenses/LICENSE-2.0
7
+ #
8
+ # Unless required by applicable law or agreed to in writing, software distributed
9
+ # under the License is distributed on an "AS IS" BASIS, without warranties or
10
+ # conditions of any kind, EITHER EXPRESS OR IMPLIED. See the License for the
11
+ # specific language governing permissions and limitations under the License.
12
+
13
+ module VagrantPlugins
14
+ module AppCatalyst
15
+ module Cap
16
+ class MountAppCatalystSharedFolder
17
+ def self.mount_appcatalyst_shared_folder(machine, name, guestpath, options)
18
+ expanded_guest_path = machine.guest.capability(
19
+ :shell_expand_guest_path, guestpath)
20
+
21
+ mount_commands = []
22
+
23
+ if options[:owner].is_a? Integer
24
+ mount_uid = options[:owner]
25
+ else
26
+ mount_uid = "`id -u #{options[:owner]}`"
27
+ end
28
+
29
+ if options[:group].is_a? Integer
30
+ mount_gid = options[:group]
31
+ mount_gid_old = options[:group]
32
+ else
33
+ mount_gid = "`getent group #{options[:group]} | cut -d: -f3`"
34
+ mount_gid_old = "`id -g #{options[:group]}`"
35
+ end
36
+
37
+ # First mount command uses getent to get the group
38
+ mount_options = "-o uid=#{mount_uid},gid=#{mount_gid}"
39
+ mount_options += ",#{options[:mount_options].join(",")}" if options[:mount_options]
40
+ mount_commands << "mount -t vmhgfs #{mount_options} .host:/#{name} #{expanded_guest_path}"
41
+
42
+ # Second mount command uses the old style `id -g`
43
+ mount_options = "-o uid=#{mount_uid},gid=#{mount_gid_old}"
44
+ mount_options += ",#{options[:mount_options].join(",")}" if options[:mount_options]
45
+ mount_commands << "mount -t vmhgfs #{mount_options} .host:/#{name} #{expanded_guest_path}"
46
+
47
+ # Create the guest path if it doesn't exist
48
+ machine.communicate.sudo("mkdir -p #{expanded_guest_path}")
49
+
50
+ # Attempt to mount the folder. We retry here a few times because
51
+ # it can fail early on.
52
+ attempts = 0
53
+ loop do
54
+ success = true
55
+
56
+ stderr = ""
57
+ mount_commands.each do |command|
58
+ no_such_device = false
59
+ stderr = ""
60
+ status = machine.communicate.sudo(command, error_check: false) do |type, data|
61
+ if type == :stderr
62
+ no_such_device = true if data =~ /No such device/i
63
+ stderr += data.to_s
64
+ end
65
+ end
66
+
67
+ success = status == 0 && !no_such_device
68
+ break if success
69
+ end
70
+
71
+ break if success
72
+
73
+ attempts += 1
74
+ if attempts > 10
75
+ raise Vagrant::Errors::LinuxMountFailed,
76
+ command: mount_commands.join("\n"),
77
+ output: stderr
78
+ end
79
+
80
+ sleep(2*attempts)
81
+ end
82
+
83
+ # Emit an upstart event if we can
84
+ if machine.communicate.test("test -x /sbin/initctl")
85
+ machine.communicate.sudo(
86
+ "/sbin/initctl emit --no-wait vagrant-mounted MOUNTPOINT=#{expanded_guest_path}")
87
+ end
88
+ end
89
+
90
+ def self.unmount_appcatalyst_shared_folder(machine, guestpath, options)
91
+ result = machine.communicate.sudo(
92
+ "umount #{guestpath}", error_check: false)
93
+ if result == 0
94
+ machine.communicate.sudo("rmdir #{guestpath}", error_check: false)
95
+ end
96
+ end
97
+ end
98
+ end
99
+ end
100
+ end
@@ -0,0 +1,31 @@
1
+ # encoding: utf-8
2
+ # Copyright (c) 2015 VMware, Inc. All Rights Reserved.
3
+ #
4
+ # Licensed under the Apache License, Version 2.0 (the "License"); you may not
5
+ # use this file except in compliance with the License. You may obtain a copy of
6
+ # the License at http://www.apache.org/licenses/LICENSE-2.0
7
+ #
8
+ # Unless required by applicable law or agreed to in writing, software
9
+ # distributed under the License is distributed on an "AS IS" BASIS, without
10
+ # warranties or conditions of any kind, EITHER EXPRESS OR IMPLIED. See the
11
+ # License for the specific language governing permissions and limitations under
12
+ # the License.
13
+
14
+ module VagrantPlugins
15
+ module AppCatalyst
16
+ module Cap
17
+ module PublicAddress
18
+ def self.public_address(machine)
19
+ # Initial try for vagrant share feature.
20
+ # It seems ssh_info[:port] is given automatically.
21
+ # I think this feature was built planning that the port forwarding
22
+ # and networking was done on the vagrant machine, which isn't the
23
+ # case in vagrant-vmware-appcatalyst
24
+
25
+ ssh_info = machine.ssh_info
26
+ ssh_info[:host]
27
+ end
28
+ end
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,40 @@
1
+ # encoding: utf-8
2
+ # Copyright (c) 2015 VMware, Inc. All Rights Reserved.
3
+ #
4
+ # Licensed under the Apache License, Version 2.0 (the "License"); you may not
5
+ # use this file except in compliance with the License. You may obtain a copy of
6
+ # the License at http://www.apache.org/licenses/LICENSE-2.0
7
+ #
8
+ # Unless required by applicable law or agreed to in writing, software
9
+ # distributed under the License is distributed on an "AS IS" BASIS, without
10
+ # warranties or conditions of any kind, EITHER EXPRESS OR IMPLIED. See the
11
+ # License for the specific language governing permissions and limitations under
12
+ # the License.
13
+
14
+ require 'vagrant'
15
+
16
+ module VagrantPlugins
17
+ module AppCatalyst
18
+ class Config < Vagrant.plugin('2', :config)
19
+ # login attributes
20
+
21
+ # Add extra configuration K/V pairs to VMX
22
+ #
23
+ # @return [Hash]
24
+ attr_accessor :vmx
25
+
26
+ # REST API daemon port, default 8080
27
+ #
28
+ # @return [String]
29
+ attr_accessor :rest_port
30
+
31
+ def initialize
32
+ self.vmx = {}
33
+ end
34
+
35
+ def validate(machine)
36
+
37
+ end
38
+ end
39
+ end
40
+ end
@@ -0,0 +1,131 @@
1
+ # encoding: utf-8
2
+ # Copyright (c) 2015 VMware, Inc. All Rights Reserved.
3
+ #
4
+ # Licensed under the Apache License, Version 2.0 (the "License"); you may not
5
+ # use this file except in compliance with the License. You may obtain a copy of
6
+ # the License at http://www.apache.org/licenses/LICENSE-2.0
7
+ #
8
+ # Unless required by applicable law or agreed to in writing, software
9
+ # distributed under the License is distributed on an "AS IS" BASIS, without
10
+ # warranties or conditions of any kind, EITHER EXPRESS OR IMPLIED. See the
11
+ # License for the specific language governing permissions and limitations under
12
+ # the License.
13
+
14
+ require 'log4r'
15
+ require 'vagrant/util/busy'
16
+ require 'vagrant/util/platform'
17
+ require 'vagrant/util/retryable'
18
+ require 'vagrant/util/subprocess'
19
+
20
+ module VagrantPlugins
21
+ module AppCatalyst
22
+ module Driver
23
+ # Main class to access AppCatalyst rest APIs
24
+ class Base
25
+ include Vagrant::Util::Retryable
26
+
27
+ def initialize
28
+ @logger = Log4r::Logger.new('vagrant::provider::appcatalyst::base')
29
+ @interrupted = false
30
+ end
31
+
32
+ # Fetch details about a given VM
33
+ def get_vm(vm_id)
34
+ end
35
+
36
+ def get_vm_power(vm_id)
37
+ end
38
+
39
+ def get_vm_ipaddress(vm_id)
40
+ end
41
+
42
+ def set_vm_power(vm_id, operation)
43
+ end
44
+
45
+ def delete_vm(vm_id)
46
+ end
47
+
48
+ def import_vm(vm_id, name, source_reference, tag)
49
+ end
50
+
51
+ def list_vms
52
+ end
53
+
54
+ def get_vm_shared_folders(vm_id)
55
+ end
56
+
57
+ def set_vm_shared_folders(vm_id, operation)
58
+ end
59
+
60
+ def add_vm_shared_folder(vm_id, guest_path, host_path, flags)
61
+ end
62
+
63
+ def get_vm_shared_folder(vm_id, shared_folder_id)
64
+ end
65
+
66
+ def delete_vm_shared_folder(vm_id, shared_folder_id)
67
+ end
68
+
69
+ def clone_vm_in_directory(src, dest)
70
+ end
71
+
72
+ def set_vmx_value(vmx_file, key, value)
73
+ end
74
+
75
+ private
76
+
77
+ ##
78
+ # Sends a synchronous request to the AppCatalyst API and returns the
79
+ # response as parsed XML + headers using HTTPClient.
80
+ def send_request(params, payload = nil, content_type = nil)
81
+ # Create a new HTTP client
82
+ clnt = HTTPClient.new
83
+
84
+ extheader = {}
85
+ extheader['accept'] = "application/json"
86
+ extheader['Content-Type'] = content_type unless content_type.nil?
87
+
88
+ url = "#{@endpoint}#{params['command']}"
89
+
90
+ @logger.debug("[#{Time.now.ctime}] -> SEND #{params['method'].upcase} #{url}")
91
+ if payload
92
+ @logger.debug('SEND HEADERS')
93
+ @logger.debug(extheader)
94
+ @logger.debug('SEND BODY')
95
+ @logger.debug(payload)
96
+ end
97
+
98
+ begin
99
+ response = clnt.request(
100
+ params['method'],
101
+ url,
102
+ nil,
103
+ payload,
104
+ extheader
105
+ )
106
+
107
+ @logger.debug("[#{Time.now.ctime}] <- RECV #{response.status}")
108
+ @logger.debug('RECV HEADERS')
109
+ @logger.debug(response.headers)
110
+ @logger.debug('RECV BODY') if response.body.length > 0
111
+ @logger.debug(response.body) if response.body.length > 0
112
+
113
+ unless response.ok?
114
+ error_response = JSON.parse(response.body)
115
+ fail Errors::UnattendedCodeError,
116
+ :message => "#{error_response['code']}: #{error_response['message']}"
117
+ end
118
+
119
+ if response.body.length > 0
120
+ [JSON.parse(response.body), response.headers]
121
+ else
122
+ ['', response.headers]
123
+ end
124
+ rescue SocketError, Errno::EADDRNOTAVAIL, Errno::ETIMEDOUT, Errno::ECONNREFUSED
125
+ raise Errors::EndpointUnavailable
126
+ end
127
+ end
128
+ end # class
129
+ end
130
+ end
131
+ end