vagrant-skytap 0.1.5 → 0.1.6
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +35 -30
- data/boxes/README.md +13 -0
- data/boxes/empty.box +0 -0
- data/boxes/metadata.json +3 -0
- data/eng-10369.diff +208 -0
- data/lib/vagrant-skytap/action/wait_for_communicator.rb +49 -0
- data/lib/vagrant-skytap/action.rb +1 -0
- data/lib/vagrant-skytap/api/environment.rb +11 -1
- data/lib/vagrant-skytap/api/vm.rb +11 -0
- data/lib/vagrant-skytap/config.rb +9 -0
- data/lib/vagrant-skytap/errors.rb +8 -0
- data/lib/vagrant-skytap/setup_helper.rb +9 -0
- data/lib/vagrant-skytap/version.rb +1 -1
- data/locales/en.yml +6 -0
- data/spec/unit/base.rb +5 -0
- data/spec/unit/config_spec.rb +2 -1
- data/spec/unit/environment_spec.rb +43 -4
- data/spec/unit/setup_helper_spec.rb +128 -0
- data/spec/unit/skeletons/network1.json +1 -20
- data/spec/unit/skeletons/vm1.json +5 -5
- data/spec/unit/skeletons/vpn1.json +26 -0
- data/spec/unit/skeletons/vpn_attachment1.json +18 -0
- data/spec/unit/vm_spec.rb +12 -0
- metadata +10 -8
- data/1-2.diff +0 -965
- data/dummy.box +0 -0
- data/example_box/README.md +0 -13
- data/example_box/metadata.json +0 -3
- data/f.diff +0 -38
- data/skytap-dummy.box +0 -0
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: ceceed9ec84e4a2e257efda672066914f42565b6
|
4
|
+
data.tar.gz: 8e6d45f0509e3c3e20869a13c94f3911b17badf3
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 78b09574cd57c6f4db5f4a1ce3fcb2e387835e46b2144fa155ec2a32579b077dd16be073c9200ae343fb3a89d183281721c0e2f148726e0ed4b4ccb407f3d992
|
7
|
+
data.tar.gz: 63eadbcf913068240b787bc8e787ae8877650f99627ad56beff65de94a1de06010ba205a70b707107eccfe41a98fd3d9dc31a6704bdda648e24d8f75881cb742
|
data/README.md
CHANGED
@@ -33,7 +33,8 @@ Before you begin, make sure you have:
|
|
33
33
|
`vagrant plugin install vagrant-skytap`
|
34
34
|
1. Create a new directory.
|
35
35
|
1. Create a file called Vagrantfile (with no file extension) containing the following. This Vagrantfile describes a Skytap environment containing a single VM, using the source VM indicated by the `vm_url` setting (a generic Ubuntu 14.04 server in the US-West region) and upgrading it to 2 CPUs.
|
36
|
-
|
36
|
+
|
37
|
+
```ruby
|
37
38
|
Vagrant.configure(2) do |config|
|
38
39
|
config.vm.box = "skytap/empty"
|
39
40
|
|
@@ -50,6 +51,7 @@ Before you begin, make sure you have:
|
|
50
51
|
end
|
51
52
|
end
|
52
53
|
```
|
54
|
+
|
53
55
|
1. Update the `username` and `api_token` settings and save the file.
|
54
56
|
If you don't want to store your username and API token in the Vagrantfile, you can set them in the environment variables `VAGRANT_SKYTAP_USERNAME` and `VAGRANT_SKYTAP_API_TOKEN`.
|
55
57
|
1. Navigate to the directory containing the Vagrantfile and enter the following at the command line:
|
@@ -106,39 +108,42 @@ Notes:
|
|
106
108
|
### Sync Local Folders with the VM's Folders using NFS
|
107
109
|
|
108
110
|
The Skytap Vagrant provider supports Vagrant's built-in NFS sharing facility. In the following example, a local directory `~/web_files` will be visible on the VM at the path `/synced`.
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
server.vm.synced_folder "~/web_files", "/synced", type: :nfs
|
111
|
+
|
112
|
+
```ruby
|
113
|
+
config.vm.define "web" do |server|
|
114
|
+
server.vm.provider :skytap do |box|
|
115
|
+
box.vm_url = "https://cloud.skytap.com/vms/3157858"
|
116
|
+
# ...
|
116
117
|
end
|
118
|
+
server.vm.synced_folder "~/web_files", "/synced", type: :nfs
|
119
|
+
end
|
117
120
|
```
|
121
|
+
|
118
122
|
For more information, see Vagrant's documentation at [https://docs.vagrantup.com/v2/synced-folders/index.html](https://docs.vagrantup.com/v2/synced-folders/index.html).
|
119
123
|
|
120
124
|
## Multi-machine Example
|
121
125
|
The following defines two VMs in a single environment. Both are based on the same Ubuntu template as above, but have different hardware settings. Since the source VM in the public library template is connected to a network, both of the VMs in the new environment will be connected to a single network.
|
122
|
-
```
|
123
|
-
config.vm.define "web" do |server|
|
124
|
-
server.vm.provider :skytap do |box|
|
125
|
-
box.vm_url = "https://cloud.skytap.com/vms/3157858"
|
126
|
-
box.cpus = 2
|
127
|
-
box.cpuspersocket = 1
|
128
|
-
box.ram = 1024
|
129
|
-
end
|
130
|
-
server.vm.synced_folder "~/web_files", "/synced", type: :nfs
|
131
|
-
end
|
132
126
|
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
127
|
+
```ruby
|
128
|
+
config.vm.define "web" do |server|
|
129
|
+
server.vm.provider :skytap do |box|
|
130
|
+
box.vm_url = "https://cloud.skytap.com/vms/3157858"
|
131
|
+
box.cpus = 2
|
132
|
+
box.cpuspersocket = 1
|
133
|
+
box.ram = 1024
|
134
|
+
end
|
135
|
+
server.vm.synced_folder "~/web_files", "/synced", type: :nfs
|
136
|
+
end
|
137
|
+
|
138
|
+
config.vm.define "db" do |server|
|
139
|
+
server.vm.provider :skytap do |box|
|
140
|
+
box.vm_url = "https://cloud.skytap.com/vms/3157858"
|
141
|
+
box.cpus = 8
|
142
|
+
box.cpuspersocket = 4
|
143
|
+
box.ram = 8192
|
141
144
|
end
|
145
|
+
server.vm.synced_folder "~/db_files", "/synced", type: :nfs
|
146
|
+
end
|
142
147
|
```
|
143
148
|
|
144
149
|
## Skytap-specific Vagrantfile Settings
|
@@ -168,10 +173,10 @@ To enable logging while troubleshooting, see [https://docs.vagrantup.com/v2/othe
|
|
168
173
|
|
169
174
|
### Known issues
|
170
175
|
|
171
|
-
*
|
172
|
-
*
|
173
|
-
*
|
174
|
-
*
|
176
|
+
* Vagrant must be able to connect to the new VM over the selected Skytap VPN.
|
177
|
+
* The source VM must have an SSH service configured to run on startup, or (for Windows VMs) be configured for WinRM access. For more information about WinRM configuration, see [https://docs.vagrantup.com/v2/boxes/base.html](https://docs.vagrantup.com/v2/boxes/base.html), under "Windows Boxes".
|
178
|
+
* At this time, WinRM credentials stored in Skytap VMs will be ignored. The username and password for WinRM connections must be stored in the Vagrantfile (`config.winrm.username` and `config.winrm.password`).
|
179
|
+
* Running, reloading, or destroying a Skytap VM can result in "stale NFS file handle" errors on other providers' VMs. This is a known issue when using multiple providers on the same host machine. The workaround is to use `vagrant reload` on the affected VM to refresh that VM's NFS mount(s).
|
175
180
|
* At this time, `vagrant share` is not supported.
|
176
181
|
* Private networks are currently unsupported.
|
177
182
|
* Although several Skytap public library VMs include credentials for the `root` login, its use is not recommended.
|
data/boxes/README.md
ADDED
@@ -0,0 +1,13 @@
|
|
1
|
+
# Vagrant Skytap Example Box
|
2
|
+
|
3
|
+
Vagrant providers each require a custom provider-specific box format.
|
4
|
+
This folder shows the example contents of a box for the `skytap` provider.
|
5
|
+
To turn this into a box:
|
6
|
+
|
7
|
+
```
|
8
|
+
$ tar cvzf skytap.box ./metadata.json ./Vagrantfile
|
9
|
+
```
|
10
|
+
|
11
|
+
This box works by using Vagrant's built-in Vagrantfile merging to setup
|
12
|
+
defaults for Skytap. These defaults can easily be overwritten by higher-level
|
13
|
+
Vagrantfiles (such as project root Vagrantfiles).
|
data/boxes/empty.box
ADDED
Binary file
|
data/boxes/metadata.json
ADDED
data/eng-10369.diff
ADDED
@@ -0,0 +1,208 @@
|
|
1
|
+
# HG changeset patch
|
2
|
+
# Parent d55067c6de25d1b7ff712f9a8a934dc122e82e14
|
3
|
+
# Parent d55067c6de25d1b7ff712f9a8a934dc122e82e14
|
4
|
+
ENG-10369 Detect errors in 200 response. Assume all are fatal.
|
5
|
+
|
6
|
+
diff -r d55067c6de25 Vagrantfile
|
7
|
+
--- a/Vagrantfile Mon Nov 09 18:52:55 2015 -0800
|
8
|
+
+++ b/Vagrantfile Mon Nov 09 19:28:06 2015 -0800
|
9
|
+
@@ -3,20 +3,20 @@
|
10
|
+
config.vm.synced_folder ".", "/vagrant", disabled: true
|
11
|
+
|
12
|
+
config.vm.provider :skytap do |skytap, override|
|
13
|
+
- skytap.username = "etrue"
|
14
|
+
- skytap.api_token = "fcb2620b72efddbc8239e25db9d812f510c7e166"
|
15
|
+
- skytap.base_url = "https://cloud.skytap.com/"
|
16
|
+
- #skytap.username = "vagrant_provider_admin"
|
17
|
+
- #skytap.api_token = "7c5718531a32eb90e92c804ce1f73da98be22cdf"
|
18
|
+
- #skytap.base_url = "https://test.skytap.com/"
|
19
|
+
+# skytap.username = "etrue"
|
20
|
+
+# skytap.api_token = "fcb2620b72efddbc8239e25db9d812f510c7e166"
|
21
|
+
+# skytap.base_url = "https://cloud.skytap.com/"
|
22
|
+
+ skytap.username = "vagrant_provider_admin"
|
23
|
+
+ skytap.api_token = "7c5718531a32eb90e92c804ce1f73da98be22cdf"
|
24
|
+
+ skytap.base_url = "https://test.skytap.com/"
|
25
|
+
#skytap.username = "jsmith"
|
26
|
+
#skytap.api_token = "754be5220955f35840498340606b4dfa89f7eb61"
|
27
|
+
#skytap.base_url = "https://cloud.skytap.dev/"
|
28
|
+
end
|
29
|
+
|
30
|
+
- GENERIC_UBUNTU = 'https://cloud.skytap.com/vms/6869434'
|
31
|
+
+# GENERIC_UBUNTU = 'https://cloud.skytap.com/vms/6869434'
|
32
|
+
# for test user
|
33
|
+
- #GENERIC_UBUNTU = 'https://cloud.skytap.com/vms/4840008'
|
34
|
+
+ GENERIC_UBUNTU = 'https://test.skytap.com/vms/4840008'
|
35
|
+
# local user
|
36
|
+
#GENERIC_UBUNTU = 'https://cloud.skytap.dev/vms/374'
|
37
|
+
|
38
|
+
@@ -33,6 +33,8 @@
|
39
|
+
UBUNTU_STOPPED_ENVIRONMENT_SOURCE_VM_A = "https://cloud.skytap.com/vms/7457184"
|
40
|
+
UBUNTU_STOPPED_ENVIRONMENT_SOURCE_VM_B = "https://cloud.skytap.com/vms/7468766"
|
41
|
+
|
42
|
+
+ VAGRANT_CUSTOMER_VPN = "https://cloud.skytap.com/vpns/vpn-3195669"
|
43
|
+
+
|
44
|
+
# separate template
|
45
|
+
# another ubuntu = 'https://cloud.skytap.com/vms/7242466'
|
46
|
+
WINDOWS_WINRM_CONFIGURED = 'https://cloud.skytap.com/vms/7242468'
|
47
|
+
@@ -40,12 +42,13 @@
|
48
|
+
config.vm.define "vm1" do |ubuntu|
|
49
|
+
ubuntu.vm.hostname = "vm1"
|
50
|
+
ubuntu.vm.provider :skytap do |box|
|
51
|
+
- box.vm_url = UBUNTU1#GENERIC_UBUNTU
|
52
|
+
+ box.vm_url = GENERIC_UBUNTU
|
53
|
+
#box.cpus = 1
|
54
|
+
#box.cpuspersocket = 1
|
55
|
+
#box.ram = 1024
|
56
|
+
#box.guestos = "ubuntu"
|
57
|
+
#box.vpn_url = "cloud.skytap.com/vpns/vpn-711360"
|
58
|
+
+ box.vpn_url = VAGRANT_CUSTOMER_VPN
|
59
|
+
end
|
60
|
+
ubuntu.vm.synced_folder "vm1", "/synced", type: :nfs
|
61
|
+
ubuntu.vm.communicator = :ssh
|
62
|
+
diff -r d55067c6de25 lib/vagrant-skytap/api/client.rb
|
63
|
+
--- a/lib/vagrant-skytap/api/client.rb Mon Nov 09 18:52:55 2015 -0800
|
64
|
+
+++ b/lib/vagrant-skytap/api/client.rb Mon Nov 09 19:28:06 2015 -0800
|
65
|
+
@@ -67,7 +67,11 @@
|
66
|
+
tries += 1
|
67
|
+
http.send_request(method, URI.encode(path), body, headers).tap do |ret|
|
68
|
+
@logger.debug("REST API response: #{ret.body}")
|
69
|
+
- unless ret.code =~ /^2\d\d/
|
70
|
+
+ if ret.code =~ /^2\d\d/
|
71
|
+
+ if options[:raise_on_error_field] && err = error_string_from_body(ret)
|
72
|
+
+ raise Errors::OperationSucceededWithErrors, err: err
|
73
|
+
+ end
|
74
|
+
+ else
|
75
|
+
raise Errors::DoesNotExist, object_name: "Object '#{path}'" if ret.code == '404'
|
76
|
+
error_class = case ret.code
|
77
|
+
when '403'
|
78
|
+
@@ -96,7 +100,7 @@
|
79
|
+
def error_string_from_body(resp)
|
80
|
+
resp = resp.body if resp.respond_to?(:body)
|
81
|
+
begin
|
82
|
+
- resp = JSON.load(resp)
|
83
|
+
+ resp = JSON.load(resp) unless resp.is_a?(Hash)
|
84
|
+
errors = resp['error'] || resp['errors']
|
85
|
+
errors = errors.join('; ') if errors.respond_to? :join
|
86
|
+
rescue
|
87
|
+
diff -r d55067c6de25 lib/vagrant-skytap/api/resource.rb
|
88
|
+
--- a/lib/vagrant-skytap/api/resource.rb Mon Nov 09 18:52:55 2015 -0800
|
89
|
+
+++ b/lib/vagrant-skytap/api/resource.rb Mon Nov 09 19:28:06 2015 -0800
|
90
|
+
@@ -23,8 +23,8 @@
|
91
|
+
"/#{self.class.resource_name.downcase}s/#{id}"
|
92
|
+
end
|
93
|
+
|
94
|
+
- def reload
|
95
|
+
- resp = api_client.get(url)
|
96
|
+
+ def reload(options={})
|
97
|
+
+ resp = api_client.get(url, options)
|
98
|
+
refresh(JSON.load(resp.body))
|
99
|
+
end
|
100
|
+
|
101
|
+
diff -r d55067c6de25 lib/vagrant-skytap/api/runstate_operations.rb
|
102
|
+
--- a/lib/vagrant-skytap/api/runstate_operations.rb Mon Nov 09 18:52:55 2015 -0800
|
103
|
+
+++ b/lib/vagrant-skytap/api/runstate_operations.rb Mon Nov 09 19:28:06 2015 -0800
|
104
|
+
@@ -36,12 +36,16 @@
|
105
|
+
def wait_for_runstate(expected_runstate)
|
106
|
+
expected_runstate = expected_runstate.to_s
|
107
|
+
retry_while_resource_busy do
|
108
|
+
- unless reload.busy?
|
109
|
+
+ unless reload_with_error_handling.busy?
|
110
|
+
break if runstate == expected_runstate || expected_runstate == 'ready'
|
111
|
+
end
|
112
|
+
end
|
113
|
+
end
|
114
|
+
|
115
|
+
+ def reload_with_error_handling
|
116
|
+
+ reload(raise_on_error_field: true)
|
117
|
+
+ end
|
118
|
+
+
|
119
|
+
def runstate
|
120
|
+
get_api_attribute('runstate')
|
121
|
+
end
|
122
|
+
diff -r d55067c6de25 lib/vagrant-skytap/api/vm.rb
|
123
|
+
--- a/lib/vagrant-skytap/api/vm.rb Mon Nov 09 18:52:55 2015 -0800
|
124
|
+
+++ b/lib/vagrant-skytap/api/vm.rb Mon Nov 09 19:28:06 2015 -0800
|
125
|
+
@@ -1,4 +1,4 @@
|
126
|
+
-require 'vagrant-skytap/api/resource'
|
127
|
+
+ require 'vagrant-skytap/api/resource'
|
128
|
+
require 'vagrant-skytap/api/interface'
|
129
|
+
require 'vagrant-skytap/api/credentials'
|
130
|
+
require_relative 'runstate_operations'
|
131
|
+
@@ -20,12 +20,6 @@
|
132
|
+
resp = env[:api_client].get(url)
|
133
|
+
new(JSON.load(resp.body), env[:environment], env)
|
134
|
+
end
|
135
|
+
-
|
136
|
+
- def current_vm(env)
|
137
|
+
- if (environment = env[:environment]) && (machine = env[:machine]) && machine.id
|
138
|
+
- environment.get_vm_by_id(machine.id)
|
139
|
+
- end
|
140
|
+
- end
|
141
|
+
end
|
142
|
+
|
143
|
+
def initialize(attrs, environment, env)
|
144
|
+
@@ -40,6 +34,19 @@
|
145
|
+
super
|
146
|
+
end
|
147
|
+
|
148
|
+
+ def refresh_from_environment
|
149
|
+
+ raise VmVanished, name: machine.name unless vm = environment.get_vm_by_id(id)
|
150
|
+
+ refresh(vm.attrs)
|
151
|
+
+ end
|
152
|
+
+
|
153
|
+
+ def reload_with_error_handling
|
154
|
+
+ environment.reload_with_error_handling
|
155
|
+
+ refresh_from_environment.tap do |ret|
|
156
|
+
+ err = api_client.error_string_from_body(ret.attrs)
|
157
|
+
+ raise Errors::OperationSucceededWithErrors, err: err if err
|
158
|
+
+ end
|
159
|
+
+ end
|
160
|
+
+
|
161
|
+
def interfaces
|
162
|
+
@interfaces ||= (get_api_attribute('interfaces') || []).collect do |iface_attrs|
|
163
|
+
Interface.new(iface_attrs, self, env)
|
164
|
+
diff -r d55067c6de25 lib/vagrant-skytap/errors.rb
|
165
|
+
--- a/lib/vagrant-skytap/errors.rb Mon Nov 09 18:52:55 2015 -0800
|
166
|
+
+++ b/lib/vagrant-skytap/errors.rb Mon Nov 09 19:28:06 2015 -0800
|
167
|
+
@@ -27,6 +27,10 @@
|
168
|
+
error_key(:does_not_exist)
|
169
|
+
end
|
170
|
+
|
171
|
+
+ class VmVanished < VagrantSkytapError
|
172
|
+
+ error_key(:vm_vanished)
|
173
|
+
+ end
|
174
|
+
+
|
175
|
+
class BadVmUrl < VagrantSkytapError
|
176
|
+
error_key(:bad_vm_url)
|
177
|
+
end
|
178
|
+
@@ -51,6 +55,11 @@
|
179
|
+
error_key(:operation_failed)
|
180
|
+
end
|
181
|
+
|
182
|
+
+ # Raised when a 200 response contains errors
|
183
|
+
+ class OperationSucceededWithErrors < VagrantSkytapError
|
184
|
+
+ error_key(:operation_succeeded_with_errors)
|
185
|
+
+ end
|
186
|
+
+
|
187
|
+
class VpnConnectionFailed < VagrantSkytapError
|
188
|
+
error_key(:vpn_connection_failed)
|
189
|
+
end
|
190
|
+
diff -r d55067c6de25 locales/en.yml
|
191
|
+
--- a/locales/en.yml Mon Nov 09 18:52:55 2015 -0800
|
192
|
+
+++ b/locales/en.yml Mon Nov 09 19:28:06 2015 -0800
|
193
|
+
@@ -76,9 +76,15 @@
|
194
|
+
does_not_exist: |-
|
195
|
+
%{object_name} was not found.
|
196
|
+
|
197
|
+
+ vm_vanished: |-
|
198
|
+
+ The VM '%{name}' no longer exists on Skytap.
|
199
|
+
+
|
200
|
+
operation_failed: |-
|
201
|
+
The operation failed: %{err}
|
202
|
+
|
203
|
+
+ operation_succeeded_with_errors: |-
|
204
|
+
+ An error occurred: %{err}
|
205
|
+
+
|
206
|
+
vpn_connection_failed: |-
|
207
|
+
Could not connect to the VPN.
|
208
|
+
|
@@ -0,0 +1,49 @@
|
|
1
|
+
require 'timeout'
|
2
|
+
require "log4r"
|
3
|
+
|
4
|
+
module VagrantPlugins
|
5
|
+
module Skytap
|
6
|
+
module Action
|
7
|
+
# Extends the builtin WaitForCommunicator action to retry on
|
8
|
+
# "network unreachable" errors, which can sometimes occur when
|
9
|
+
# a Skytap environment is started.
|
10
|
+
class WaitForCommunicator < Vagrant::Action::Builtin::WaitForCommunicator
|
11
|
+
|
12
|
+
def initialize(app, env, states=nil)
|
13
|
+
super
|
14
|
+
@logger = Log4r::Logger.new("vagrant_skytap::action::wait_for_communicator")
|
15
|
+
end
|
16
|
+
|
17
|
+
alias_method :builtin_action_call, :call
|
18
|
+
|
19
|
+
def call(env)
|
20
|
+
# The SSH communicator handles certain exceptions by raising a
|
21
|
+
# corresponding VagrantError which can be handled gracefully,
|
22
|
+
# i.e. by the #wait_for_ready method, which continues to retry
|
23
|
+
# until the boot_timeout expires.
|
24
|
+
#
|
25
|
+
# The communicator does a limited number of retries for
|
26
|
+
# Errno::ENETUNREACH, but then allows the exception to bubble up
|
27
|
+
# to the user. Here we swallow this exception and essentially
|
28
|
+
# retry the original WaitForCommunicator action.
|
29
|
+
begin
|
30
|
+
Timeout.timeout(env[:machine].config.vm.boot_timeout) do
|
31
|
+
while true do
|
32
|
+
begin
|
33
|
+
# TODO Is there a clean way to just invoke the built-in action?
|
34
|
+
break builtin_action_call(env)
|
35
|
+
rescue Errno::ENETUNREACH
|
36
|
+
@logger.info("Rescued Errno::ENETUNREACH and retrying original WaitForCommunicator action.")
|
37
|
+
env[:ui].detail("Warning: The network was unreachable. Retrying...")
|
38
|
+
end
|
39
|
+
return if env[:interrupted]
|
40
|
+
end
|
41
|
+
end
|
42
|
+
rescue Timeout::Error
|
43
|
+
raise Errors::VMBootTimeout
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
@@ -271,6 +271,7 @@ module VagrantPlugins
|
|
271
271
|
autoload :SuspendVm, action_root.join("suspend_vm")
|
272
272
|
autoload :TimedProvision, action_root.join("timed_provision") # some plugins now expect this action to exist
|
273
273
|
autoload :UpdateHardware, action_root.join("update_hardware")
|
274
|
+
autoload :WaitForCommunicator, action_root.join("wait_for_communicator")
|
274
275
|
end
|
275
276
|
end
|
276
277
|
end
|
@@ -32,6 +32,7 @@ module VagrantPlugins
|
|
32
32
|
end
|
33
33
|
|
34
34
|
def check_vm_before_adding(env, vm)
|
35
|
+
raise Errors::NotTemplateVm, url: vm.url unless vm.from_template?
|
35
36
|
raise Errors::SourceVmNotStopped, name: env[:machine].name, url: vm.url unless vm.stopped?
|
36
37
|
end
|
37
38
|
end
|
@@ -67,6 +68,10 @@ module VagrantPlugins
|
|
67
68
|
end
|
68
69
|
end
|
69
70
|
|
71
|
+
def region
|
72
|
+
get_api_attribute('region')
|
73
|
+
end
|
74
|
+
|
70
75
|
def refresh(attrs)
|
71
76
|
@vms = nil
|
72
77
|
@networks = nil
|
@@ -82,7 +87,7 @@ module VagrantPlugins
|
|
82
87
|
|
83
88
|
def add_vm(vm_url)
|
84
89
|
vm = Vm.fetch(env, vm_url)
|
85
|
-
|
90
|
+
check_vm_before_adding(env, vm)
|
86
91
|
vm_ids = vms.collect(&:id)
|
87
92
|
|
88
93
|
update_with_retry(template_id: vm.template_id, vm_ids: [vm.id])
|
@@ -90,6 +95,11 @@ module VagrantPlugins
|
|
90
95
|
get_vm_by_id(new_vm_ids.last)
|
91
96
|
end
|
92
97
|
|
98
|
+
def check_vm_before_adding(env, vm)
|
99
|
+
raise Errors::RegionMismatch, environment_region: region, vm_region: vm.region unless vm.region == region
|
100
|
+
self.class.check_vm_before_adding(env, vm)
|
101
|
+
end
|
102
|
+
|
93
103
|
def properties
|
94
104
|
@properties ||= EnvironmentProperties.new(env[:machine].env.local_data_path)
|
95
105
|
end
|
@@ -56,11 +56,22 @@ module VagrantPlugins
|
|
56
56
|
get_api_attribute('hardware')
|
57
57
|
end
|
58
58
|
|
59
|
+
def from_template?
|
60
|
+
!!get_api_attribute('template_url')
|
61
|
+
end
|
62
|
+
|
59
63
|
def template_id
|
60
64
|
get_api_attribute('template_url') =~ /templates\/(\d+)/
|
61
65
|
$1
|
62
66
|
end
|
63
67
|
|
68
|
+
def region
|
69
|
+
return @region if @region
|
70
|
+
resp = env[:api_client].get(get_api_attribute('template_url'))
|
71
|
+
template_attrs = JSON.load(resp.body)
|
72
|
+
@region = template_attrs['region']
|
73
|
+
end
|
74
|
+
|
64
75
|
def delete
|
65
76
|
begin
|
66
77
|
retry_while_resource_busy do
|
@@ -23,6 +23,11 @@ module VagrantPlugins
|
|
23
23
|
# @return [String]
|
24
24
|
attr_accessor :vm_url
|
25
25
|
|
26
|
+
# The url of the VPN to use for connecting to the VM.
|
27
|
+
#
|
28
|
+
# @return [String]
|
29
|
+
attr_accessor :vpn_url
|
30
|
+
|
26
31
|
# The timeout to wait for a VM to become ready.
|
27
32
|
#
|
28
33
|
# @return [Fixnum]
|
@@ -53,6 +58,7 @@ module VagrantPlugins
|
|
53
58
|
@api_token = UNSET_VALUE
|
54
59
|
@base_url = UNSET_VALUE
|
55
60
|
@vm_url = UNSET_VALUE
|
61
|
+
@vpn_url = UNSET_VALUE
|
56
62
|
@instance_ready_timeout = UNSET_VALUE
|
57
63
|
@region = UNSET_VALUE
|
58
64
|
|
@@ -78,6 +84,9 @@ module VagrantPlugins
|
|
78
84
|
# Source VM url must be set.
|
79
85
|
@vm_url = nil if @vm_url == UNSET_VALUE
|
80
86
|
|
87
|
+
# VPN to use for connection to VM
|
88
|
+
@vpn_url = nil if @vpn_url == UNSET_VALUE
|
89
|
+
|
81
90
|
# Set the default timeout for waiting for an instance to be ready
|
82
91
|
@instance_ready_timeout = 120 if @instance_ready_timeout == UNSET_VALUE
|
83
92
|
|
@@ -31,6 +31,10 @@ module VagrantPlugins
|
|
31
31
|
error_key(:bad_vm_url)
|
32
32
|
end
|
33
33
|
|
34
|
+
class RegionMismatch < VagrantSkytapError
|
35
|
+
error_key(:region_mismatch)
|
36
|
+
end
|
37
|
+
|
34
38
|
class ResourceBusy < VagrantSkytapError
|
35
39
|
error_key(:resource_busy)
|
36
40
|
end
|
@@ -55,6 +59,10 @@ module VagrantPlugins
|
|
55
59
|
error_key(:source_vm_not_stopped)
|
56
60
|
end
|
57
61
|
|
62
|
+
class NotTemplateVm < VagrantSkytapError
|
63
|
+
error_key(:not_template_vm)
|
64
|
+
end
|
65
|
+
|
58
66
|
class NoConnectionOptions < VagrantSkytapError
|
59
67
|
error_key(:no_connection_options)
|
60
68
|
end
|
@@ -97,6 +97,15 @@ module VagrantPlugins
|
|
97
97
|
choices = connection_choices(iface).select(&:valid?)
|
98
98
|
raise Errors::NoConnectionOptions unless choices.present?
|
99
99
|
|
100
|
+
if vpn_url = @provider_config.vpn_url
|
101
|
+
choice = choices.detect do |choice|
|
102
|
+
choice.vpn && vpn_url.include?(choice.vpn.id)
|
103
|
+
end
|
104
|
+
raise Errors::DoesNotExist, object_name: vpn_url unless choice
|
105
|
+
@host, @port = choice.choose
|
106
|
+
return
|
107
|
+
end
|
108
|
+
|
100
109
|
question = "How do you want to connect to machine '#{@machine.name}'?"
|
101
110
|
ask_from_list(question, choices, 0) do |i, choice|
|
102
111
|
@host, @port = choice.choose
|
data/locales/en.yml
CHANGED
@@ -101,6 +101,12 @@ en:
|
|
101
101
|
bad_vm_url: |-
|
102
102
|
The specified vm_url was invalid: %{url}
|
103
103
|
|
104
|
+
not_template_vm: |-
|
105
|
+
The specified VM %{url} belongs to an environment, not a template. Using environment VMs is not currently supported.
|
106
|
+
|
107
|
+
region_mismatch: |-
|
108
|
+
A VM from the '%{vm_region}' region cannot be added to an environment in the '%{environment_region}' region.
|
109
|
+
|
104
110
|
states:
|
105
111
|
short_not_created: |-
|
106
112
|
not created
|
data/spec/unit/base.rb
CHANGED
@@ -23,6 +23,11 @@ require "unit/support/shared/capability_helpers_context"
|
|
23
23
|
require "unit/support/shared/plugin_command_context"
|
24
24
|
require "unit/support/shared/skytap_context"
|
25
25
|
|
26
|
+
require "vagrant-skytap/core_ext/object/blank"
|
27
|
+
require "vagrant-skytap/core_ext/object/tap"
|
28
|
+
require "vagrant-skytap/core_ext/try"
|
29
|
+
require "vagrant-skytap/plugin"
|
30
|
+
|
26
31
|
# Do not buffer output
|
27
32
|
$stdout.sync = true
|
28
33
|
$stderr.sync = true
|
data/spec/unit/config_spec.rb
CHANGED
@@ -19,6 +19,7 @@ describe VagrantPlugins::Skytap::Config do
|
|
19
19
|
its("api_token") { should be_nil }
|
20
20
|
its("base_url") { should == "https://cloud.skytap.com/" }
|
21
21
|
its("vm_url") { should be_nil }
|
22
|
+
its("vpn_url") { should be_nil }
|
22
23
|
its("instance_ready_timeout") { should == 120 }
|
23
24
|
its("cpus") { should be_nil }
|
24
25
|
its("cpuspersocket") { should be_nil }
|
@@ -32,7 +33,7 @@ describe VagrantPlugins::Skytap::Config do
|
|
32
33
|
# each of these attributes to "foo" in isolation, and reads the value
|
33
34
|
# and asserts the proper result comes back out.
|
34
35
|
[:username, :api_token, :base_url, :vm_url,
|
35
|
-
:instance_ready_timeout,
|
36
|
+
:vpn_url, :instance_ready_timeout,
|
36
37
|
:cpus, :cpuspersocket, :ram, :guestos].each do |attribute|
|
37
38
|
it "should not default #{attribute} if overridden" do
|
38
39
|
instance.send("#{attribute}=".to_sym, "foo")
|