vagrant-skytap 0.1.5 → 0.1.6
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 +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")
|