vagrant-softlayer 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (37) hide show
  1. data/.gitignore +15 -0
  2. data/Gemfile +7 -0
  3. data/LICENSE +20 -0
  4. data/README.md +233 -0
  5. data/Rakefile +6 -0
  6. data/dummy.box +0 -0
  7. data/example_box/README.md +13 -0
  8. data/example_box/metadata.json +3 -0
  9. data/lib/vagrant-softlayer/action/create_instance.rb +54 -0
  10. data/lib/vagrant-softlayer/action/destroy_instance.rb +23 -0
  11. data/lib/vagrant-softlayer/action/is.rb +21 -0
  12. data/lib/vagrant-softlayer/action/message.rb +22 -0
  13. data/lib/vagrant-softlayer/action/read_ssh_info.rb +28 -0
  14. data/lib/vagrant-softlayer/action/read_state.rb +42 -0
  15. data/lib/vagrant-softlayer/action/rebuild_instance.rb +35 -0
  16. data/lib/vagrant-softlayer/action/setup_softlayer.rb +37 -0
  17. data/lib/vagrant-softlayer/action/start_instance.rb +21 -0
  18. data/lib/vagrant-softlayer/action/stop_instance.rb +30 -0
  19. data/lib/vagrant-softlayer/action/sync_folders.rb +99 -0
  20. data/lib/vagrant-softlayer/action/update_dns.rb +96 -0
  21. data/lib/vagrant-softlayer/action/wait_for_provision.rb +40 -0
  22. data/lib/vagrant-softlayer/action/wait_for_rebuild.rb +36 -0
  23. data/lib/vagrant-softlayer/action.rb +200 -0
  24. data/lib/vagrant-softlayer/command/rebuild.rb +34 -0
  25. data/lib/vagrant-softlayer/config.rb +178 -0
  26. data/lib/vagrant-softlayer/errors.rb +25 -0
  27. data/lib/vagrant-softlayer/plugin.rb +77 -0
  28. data/lib/vagrant-softlayer/provider.rb +47 -0
  29. data/lib/vagrant-softlayer/util/network.rb +42 -0
  30. data/lib/vagrant-softlayer/util/warden.rb +38 -0
  31. data/lib/vagrant-softlayer/version.rb +5 -0
  32. data/lib/vagrant-softlayer.rb +22 -0
  33. data/locales/en.yml +146 -0
  34. data/spec/spec_helper.rb +1 -0
  35. data/spec/vagrant-softlayer/config_spec.rb +156 -0
  36. data/vagrant-softlayer.gemspec +53 -0
  37. metadata +152 -0
data/.gitignore ADDED
@@ -0,0 +1,15 @@
1
+ .DS_Store
2
+
3
+ .bundle
4
+ pkg/*
5
+ Gemfile.lock
6
+
7
+ .rspec
8
+
9
+ .vagrant
10
+ .vagrant.d/*
11
+ Vagrantfile
12
+
13
+ # Miscellaneous local stuff
14
+ example_box/*.box
15
+ scripts/*
data/Gemfile ADDED
@@ -0,0 +1,7 @@
1
+ source 'https://rubygems.org'
2
+
3
+ gemspec
4
+
5
+ group :development do
6
+ gem "vagrant", :git => "git://github.com/mitchellh/vagrant.git"
7
+ end
data/LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2013 audiolize
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy of
6
+ this software and associated documentation files (the "Software"), to deal in
7
+ the Software without restriction, including without limitation the rights to
8
+ use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
9
+ the Software, and to permit persons to whom the Software is furnished to do so,
10
+ subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
17
+ FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
18
+ COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
19
+ IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
20
+ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,233 @@
1
+ # Vagrant SoftLayer Provider
2
+
3
+ This is a [Vagrant](http://www.vagrantup.com) 1.3+ plugin that adds a [SoftLayer](http://www.softlayer.com)
4
+ provider to Vagrant, allowing Vagrant to control and provision SoftLayer CCI instances.
5
+
6
+ **NOTE:** This plugin requires Vagrant 1.3+
7
+
8
+ ## Features
9
+
10
+ * Basic lifecycle (boot, halt, reboot) of SoftLayer CCI instances.
11
+ * OS reload on a CCI (`vagrant rebuild`).
12
+ * SSH into the instances.
13
+ * Provision the instances with any built-in Vagrant provisioner.
14
+ * Minimal synced folder support via `rsync`.
15
+
16
+ ## Installation
17
+
18
+ ### Set the `SSL_CERT_FILE` environment variable
19
+
20
+ If you intend to use the public API endpoint, which is the default, you have to
21
+ set the `SSL_CERT_FILE` environment variable.
22
+
23
+ The *net/http* library of the Vagrant's embedded ruby does **not**
24
+ check the validity of an SSL certificate during a TLS handshake. This breaks all
25
+ the calls to the SoftLayer API, making the plugin unusable.
26
+
27
+ For fixing this issue, you have to make ruby aware of a certificate authority
28
+ bundle by setting `SSL_CERT_FILE`:
29
+
30
+ **Linux**
31
+
32
+ * To set this in your current command prompt session, type:
33
+
34
+ `export SSL_CERT_FILE=/opt/vagrant/embedded/cacert.pem`
35
+
36
+ * To make this a permanent setting, add this in `.bashrc` or `.profile`.
37
+
38
+ **Mac OS X**
39
+
40
+ * To set this in your current command prompt session, type:
41
+
42
+ `export SSL_CERT_FILE=/Applications/Vagrant/embedded/cacert.pem`
43
+
44
+ * To make this a permanent setting, add this in `/etc/launchd.conf`.
45
+
46
+ **Windows**
47
+
48
+ * To set this in your current command prompt session, type:
49
+
50
+ `set SSL_CERT_FILE=C:\HashiCorp\Vagrant\embedded\cacert.pem`
51
+
52
+ * To make this a permanent setting, add this in your [control panel](http://www.microsoft.com/resources/documentation/windows/xp/all/proddocs/en-us/environment_variables.mspx?mfr=true).
53
+
54
+ ### Plugin installation
55
+
56
+ Installation is performed in the prescribed manner for Vagrant 1.1+ plugins.
57
+ After installing, `vagrant up` and specify the `softlayer` provider. An example is
58
+ shown below.
59
+
60
+ ```
61
+ $ vagrant plugin install vagrant-softlayer
62
+ ...
63
+ $ vagrant up --provider=softlayer
64
+ ...
65
+ ```
66
+
67
+ Of course prior to doing this, you'll need to obtain an SoftLayer-compatible
68
+ box file for Vagrant.
69
+
70
+ ## Box File Format
71
+
72
+ Every provider in Vagrant must introduce a custom box format. This
73
+ provider introduces `softlayer` boxes. You can view an example box in
74
+ the `example_box/` directory. That directory also contains instructions
75
+ on how to build a box.
76
+
77
+ The box format is basically just the required `metadata.json` file
78
+ along with a `Vagrantfile` that does default settings for the
79
+ provider-specific configuration for this provider.
80
+
81
+ ## Configuration
82
+
83
+ This provider exposes quite a few provider-specific configuration options:
84
+
85
+ ### Authentication
86
+
87
+ Parameter | Description | Default | Required
88
+ -------------- | ------------------------------------ | ---------------------------------- | --------
89
+ `api_key` | The API key for accessing SoftLayer | | yes
90
+ `endpoint_url` | The endpoint SoftLayer API url | SoftLayer::API_PUBLIC_ENDPOINT | yes
91
+ `username` | The username for accessing SoftLayer | | yes
92
+
93
+ > **NOTE**
94
+ >
95
+ > In place of the API key and username you can use environment variables, respectively `SL_API_KEY` and `SL_USERNAME`.
96
+
97
+ ### DNS Management
98
+
99
+ If the DNS zone of the configured domain is hosted by SoftLayer, you can automatically manage it.
100
+
101
+ Parameter | Description | Default | Required
102
+ ------------ | ------------------------------------- | ------- | --------
103
+ `manage_dns` | Add/remove A record on create/destroy | false | no
104
+
105
+ ### Instance Configuration
106
+
107
+ Parameter | Description | Default | Required
108
+ ------------------ | ------------------------------------------- | ----------------------- | --------
109
+ `datacenter` | Datacenter shortname | First available | no
110
+ `dedicated` | Allocate a dedicated CCI (non-shared host) | false | no
111
+ `domain` | The domain of the instance | | yes
112
+ `hostname` | The hostname of the instance | | yes *
113
+ `hourly_billing` | Hourly billing type (false for monthly) | true | no
114
+ `local_disk` | Use a local disk (false for SAN) | true | no
115
+ `max_memory` | The amount of RAM of the instance in Mb | 1024 | no
116
+ `network_speed` | Network port speed in Mbps | 10 | no
117
+ `operating_system` | The instance operating system identifier | UBUNTU_LATEST | no
118
+ `post_install` | URI of Post-install script to download | | no
119
+ `private_only` | Only create access to the private network | false | no
120
+ `ssh_key` | ID or label of the SSH key(s) to provision | | yes
121
+ `start_cpus` | The number of processors of the instance | 1 | no
122
+ `user_data` | User defined metadata string | | no
123
+ `vlan_private` | The ID of the private VLAN | Automatically generated | no
124
+ `vlan_public` | The ID of the public VLAN | Automatically generated | no
125
+
126
+ \* The `hostname` could be specified either using `config.vm.hostname` or the provider parameter.
127
+
128
+ These can be set like typical provider-specific configuration:
129
+
130
+ ```
131
+ Vagrant.configure("2") do |config|
132
+ # ... other stuff
133
+
134
+ config.vm.provider :softlayer do |sl|
135
+ sl.api_key = "foo"
136
+ sl.username = "bar"
137
+ sl.ssh_key = "Vagrant insecure key"
138
+ end
139
+ end
140
+ ```
141
+
142
+ ## OS Reload
143
+
144
+ Reload of an instance's operating system is performed with the `vagrant rebuild` command.
145
+ The primary disk of the instance will be formatted and a fresh copy of the underlying OS
146
+ will be applied. Note that only `ssh_key` and `post_install` parameter will be read
147
+ during rebuild, all the other parameters will be ignored. Provisioners will always run
148
+ after rebuild.
149
+
150
+ ## Synced Folders
151
+
152
+ There is minimal support for synced folders. Upon `vagrant up`,
153
+ `vagrant reload`, and `vagrant provision`, the SoftLayer provider will use
154
+ `rsync` (if available) to uni-directionally sync the folder to
155
+ the remote machine over SSH.
156
+
157
+ This is good enough for all built-in Vagrant provisioners (shell, ansible,
158
+ chef, and puppet) to work!
159
+
160
+ ## Other Examples
161
+
162
+ ### Override SSH Username
163
+
164
+ If you're running Vagrant with an user different from root, probably you need
165
+ to override the username used for ssh connection. You can do it using the standard
166
+ Vagrant syntax:
167
+
168
+ ```
169
+ Vagrant.configure("2") do |config|
170
+ # ... other stuff
171
+
172
+ config.vm.provider :softlayer do |sl, override|
173
+ # ... other stuff
174
+
175
+ override.ssh.username = "root"
176
+ end
177
+ end
178
+ ```
179
+
180
+ ### Multiple SSH keys
181
+
182
+ Multiple SSH keys to be provisioned could be specified using an array:
183
+
184
+ ```
185
+ Vagrant.configure("2") do |config|
186
+ # ... other stuff
187
+
188
+ config.vm.provider :softlayer do |sl|
189
+ sl.api_key = "foo"
190
+ sl.username = "bar"
191
+ # ssh_keys is just an alias of ssh_key
192
+ sl.ssh_keys = ["Vagrant insecure key", "My personal key"]
193
+ end
194
+ end
195
+ ```
196
+
197
+ Also, a bunch of aliases for the `ssh_key` parameter are provided for better semantic:
198
+
199
+ * `ssh_keys`
200
+ * `ssh_key_id`
201
+ * `ssh_key_ids`
202
+ * `ssh_key_name`
203
+ * `ssh_key_names`
204
+
205
+ ## Development
206
+
207
+ To work on the `vagrant-softlayer` plugin, clone this repository out, and use
208
+ [Bundler](http://gembundler.com) to get the dependencies:
209
+
210
+ ```
211
+ $ bundle
212
+ ```
213
+
214
+ Once you have the dependencies, verify the unit tests pass with `rake`:
215
+
216
+ ```
217
+ $ bundle exec rake
218
+ ```
219
+
220
+ If those pass, you're ready to start developing the plugin. You can test
221
+ the plugin without installing it into your Vagrant environment by just
222
+ creating a `Vagrantfile` in the top level of this directory (it is gitignored)
223
+ and add the following line to your `Vagrantfile`:
224
+
225
+ ```
226
+ Vagrant.require_plugin "vagrant-softlayer"
227
+ ```
228
+
229
+ Use bundler to execute Vagrant:
230
+
231
+ ```
232
+ $ bundle exec vagrant up --provider=softlayer
233
+ ```
data/Rakefile ADDED
@@ -0,0 +1,6 @@
1
+ require "bundler/gem_tasks"
2
+ require 'rspec/core/rake_task'
3
+
4
+ RSpec::Core::RakeTask.new
5
+
6
+ task :default => "spec"
data/dummy.box ADDED
Binary file
@@ -0,0 +1,13 @@
1
+ # Vagrant SoftLayer 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 `softlayer` provider.
5
+ To turn this into a box:
6
+
7
+ ```
8
+ $ tar cvzf softlayer.box ./metadata.json [./Vagrantfile]
9
+ ```
10
+
11
+ A Vagrantfile with default configuration values for SoftLayer could be added.
12
+ These defaults can easily be overwritten by higher-level
13
+ Vagrantfiles (such as project root Vagrantfiles).
@@ -0,0 +1,3 @@
1
+ {
2
+ "provider": "softlayer"
3
+ }
@@ -0,0 +1,54 @@
1
+ module VagrantPlugins
2
+ module SoftLayer
3
+ module Action
4
+ # This creates a new instance.
5
+ class CreateInstance
6
+ include Util::Network
7
+ include Util::Warden
8
+
9
+ def initialize(app, env)
10
+ @app = app
11
+ end
12
+
13
+ def call(env)
14
+ @env = env
15
+
16
+ @env[:ui].info I18n.t("vagrant_softlayer.vm.creating")
17
+
18
+ result = sl_warden { env[:sl_connection].createObject(order_template) }
19
+ @env[:machine].id = result["id"].to_s
20
+
21
+ @app.call(@env)
22
+ end
23
+
24
+ def get_hostname
25
+ @env[:machine].provider_config.hostname || @env[:machine].config.vm.hostname
26
+ end
27
+
28
+ def order_template
29
+ template = {
30
+ "dedicatedAccountHostOnlyFlag" => @env[:machine].provider_config.dedicated,
31
+ "domain" => @env[:machine].provider_config.domain,
32
+ "hostname" => get_hostname,
33
+ "hourlyBillingFlag" => @env[:machine].provider_config.hourly_billing,
34
+ "localDiskFlag" => @env[:machine].provider_config.local_disk,
35
+ "maxMemory" => @env[:machine].provider_config.max_memory,
36
+ "networkComponents" => [ { :maxSpeed => @env[:machine].provider_config.network_speed } ],
37
+ "operatingSystemReferenceCode" => @env[:machine].provider_config.operating_system,
38
+ "privateNetworkOnlyFlag" => @env[:machine].provider_config.private_only,
39
+ "sshKeys" => ssh_keys(@env),
40
+ "startCpus" => @env[:machine].provider_config.start_cpus
41
+ }
42
+
43
+ template["datacenter"] = { :name => @env[:machine].provider_config.datacenter } if @env[:machine].provider_config.datacenter
44
+ template["postInstallScriptUri"] = @env[:machine].provider_config.post_install if @env[:machine].provider_config.post_install
45
+ template["primaryNetworkComponent"] = { :networkVlan => { :id => @env[:machine].provider_config.vlan_public } } if @env[:machine].provider_config.vlan_public
46
+ template["primaryBackendNetworkComponent"] = { :networkVlan => { :id => @env[:machine].provider_config.vlan_private } } if @env[:machine].provider_config.vlan_private
47
+ template["userData"] = [ { :value => @env[:machine].provider_config.user_data } ] if @env[:machine].provider_config.user_data
48
+
49
+ return template
50
+ end
51
+ end
52
+ end
53
+ end
54
+ end
@@ -0,0 +1,23 @@
1
+ module VagrantPlugins
2
+ module SoftLayer
3
+ module Action
4
+ # This deletes the running instance.
5
+ class DestroyInstance
6
+ include Util::Warden
7
+
8
+ def initialize(app, env)
9
+ @app = app
10
+ end
11
+
12
+ def call(env)
13
+ @app.call(env)
14
+
15
+ env[:ui].info I18n.t("vagrant_softlayer.vm.destroying")
16
+
17
+ sl_warden { env[:sl_machine].deleteObject }
18
+ env[:machine].id = nil
19
+ end
20
+ end
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,21 @@
1
+ module VagrantPlugins
2
+ module SoftLayer
3
+ module Action
4
+ # This can be used with "Call" built-in to check if the machine
5
+ # is in the given status.
6
+ class Is
7
+ def initialize(app, env, status)
8
+ @app = app
9
+ @status = status
10
+ end
11
+
12
+ def call(env)
13
+ env[:result] = env[:machine].state.id == @status
14
+
15
+ # Carry on, just in case
16
+ @app.call(env)
17
+ end
18
+ end
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,22 @@
1
+ module VagrantPlugins
2
+ module SoftLayer
3
+ module Action
4
+ # This action sends a message to the UI,
5
+ # with given level and text.
6
+ class Message
7
+ def initialize(app, env, level, message)
8
+ @app = app
9
+ @level = level
10
+ @message = message
11
+ end
12
+
13
+ def call(env)
14
+ env[:ui].send(@level, I18n.t(@message))
15
+
16
+ # Carry on
17
+ @app.call(env)
18
+ end
19
+ end
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,28 @@
1
+ module VagrantPlugins
2
+ module SoftLayer
3
+ module Action
4
+ # This action reads the SSH info for the machine and puts it into the
5
+ # `:machine_ssh_info` key in the environment.
6
+ class ReadSSHInfo
7
+ include Util::Network
8
+ include Util::Warden
9
+
10
+ def initialize(app, env)
11
+ @app = app
12
+ end
13
+
14
+ def call(env)
15
+ env[:machine_ssh_info] = read_ssh_info(env)
16
+
17
+ @app.call(env)
18
+ end
19
+
20
+ def read_ssh_info(env)
21
+ return nil unless env[:sl_machine]
22
+
23
+ return { :host => ip_address(env), :port => 22 }
24
+ end
25
+ end
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,42 @@
1
+ require "log4r"
2
+
3
+ module VagrantPlugins
4
+ module SoftLayer
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
+ include Util::Warden
10
+
11
+ def initialize(app, env)
12
+ @app = app
13
+ @logger = Log4r::Logger.new("vagrant_softlayer::action::read_state")
14
+ end
15
+
16
+ def call(env)
17
+ env[:machine_state_id] = read_state(env)
18
+
19
+ # Carry on
20
+ @app.call(env)
21
+ end
22
+
23
+ def read_state(env)
24
+ return :not_created unless env[:sl_machine]
25
+
26
+ wipe_id = lambda do
27
+ @logger.info("Machine not found, assuming it got destroyed.")
28
+ env[:machine].id = nil
29
+ next :not_created
30
+ end
31
+
32
+ state = sl_warden(wipe_id) { env[:sl_machine].getPowerState }
33
+ if state && ["Halted", "Paused", "Running"].include?(state["name"])
34
+ return state["name"].downcase.to_sym
35
+ else
36
+ return :unknown
37
+ end
38
+ end
39
+ end
40
+ end
41
+ end
42
+ end
@@ -0,0 +1,35 @@
1
+ module VagrantPlugins
2
+ module SoftLayer
3
+ module Action
4
+ # This rebuilds the running instance.
5
+ class RebuildInstance
6
+ include Util::Network
7
+ include Util::Warden
8
+
9
+ def initialize(app, env)
10
+ @app = app
11
+ @logger = Log4r::Logger.new("vagrant_softlayer::action::rebuild_instance")
12
+ end
13
+
14
+ def call(env)
15
+ env[:ui].info I18n.t("vagrant_softlayer.vm.rebuilding")
16
+
17
+ # Wipe out provision sentinel file, we need to run provisioning after rebuild
18
+ @logger.debug("Looking for provision sentinel file.")
19
+ provision_file = env[:machine].data_dir.join("action_provision")
20
+ if provision_file.file?
21
+ @logger.debug("Removing provision sentinel file.")
22
+ provision_file.delete
23
+ end
24
+
25
+ template = { "sshKeyIds" => ssh_keys(env, true) }
26
+ template["customProvisionScriptUri"] = env[:machine].provider_config.post_install if env[:machine].provider_config.post_install
27
+
28
+ sl_warden { env[:sl_machine].reloadOperatingSystem("FORCE", template) }
29
+
30
+ @app.call(env)
31
+ end
32
+ end
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,37 @@
1
+ require "log4r"
2
+
3
+ module VagrantPlugins
4
+ module SoftLayer
5
+ module Action
6
+ # This action creates the SoftLayer connection object and
7
+ # puts it into the `:sl_connection` key in the environment.
8
+ # Also, if a machine id is found, another key called
9
+ # `:sl_machine` and containing the masked object is created.
10
+ class SetupSoftLayer
11
+ def initialize(app, env)
12
+ @app = app
13
+ @logger = Log4r::Logger.new("vagrant_softlayer::action::connect_softlayer")
14
+ end
15
+
16
+ def call(env)
17
+ @logger.info("Creating the SoftLayer connection object...")
18
+
19
+ env[:sl_credentials] = {
20
+ :api_key => env[:machine].provider_config.api_key,
21
+ :endpoint_url => env[:machine].provider_config.endpoint_url,
22
+ :username => env[:machine].provider_config.username
23
+ }
24
+
25
+ env[:sl_connection] = ::SoftLayer::Service.new("SoftLayer_Virtual_Guest", env[:sl_credentials])
26
+
27
+ unless env[:machine].id.nil? || env[:machine].id.empty?
28
+ env[:sl_machine] = env[:sl_connection].object_with_id(env[:machine].id.to_i)
29
+ end
30
+
31
+ # Carry on
32
+ @app.call(env)
33
+ end
34
+ end
35
+ end
36
+ end
37
+ end
@@ -0,0 +1,21 @@
1
+ module VagrantPlugins
2
+ module SoftLayer
3
+ module Action
4
+ # This starts a stopped instance.
5
+ class StartInstance
6
+ include Util::Warden
7
+
8
+ def initialize(app, env)
9
+ @app = app
10
+ end
11
+
12
+ def call(env)
13
+ env[:ui].info I18n.t("vagrant_softlayer.vm.starting")
14
+ sl_warden { env[:sl_machine].powerOn }
15
+
16
+ @app.call(env)
17
+ end
18
+ end
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,30 @@
1
+ module VagrantPlugins
2
+ module SoftLayer
3
+ module Action
4
+ # This stops the running instance.
5
+ class StopInstance
6
+ include Util::Warden
7
+
8
+ def initialize(app, env)
9
+ @app = app
10
+ end
11
+
12
+ def call(env)
13
+ if env[:machine].state.id == :halted
14
+ env[:ui].info I18n.t("vagrant_softlayer.vm.already_stopped")
15
+ else
16
+ if env[:force_halt]
17
+ env[:ui].info I18n.t("vagrant_softlayer.vm.stopping_force")
18
+ sl_warden { env[:sl_machine].powerOff }
19
+ else
20
+ env[:ui].info I18n.t("vagrant_softlayer.vm.stopping")
21
+ sl_warden { env[:sl_machine].powerOffSoft }
22
+ end
23
+ end
24
+
25
+ @app.call(env)
26
+ end
27
+ end
28
+ end
29
+ end
30
+ end