vagrant-softlayer 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +15 -0
- data/Gemfile +7 -0
- data/LICENSE +20 -0
- data/README.md +233 -0
- data/Rakefile +6 -0
- data/dummy.box +0 -0
- data/example_box/README.md +13 -0
- data/example_box/metadata.json +3 -0
- data/lib/vagrant-softlayer/action/create_instance.rb +54 -0
- data/lib/vagrant-softlayer/action/destroy_instance.rb +23 -0
- data/lib/vagrant-softlayer/action/is.rb +21 -0
- data/lib/vagrant-softlayer/action/message.rb +22 -0
- data/lib/vagrant-softlayer/action/read_ssh_info.rb +28 -0
- data/lib/vagrant-softlayer/action/read_state.rb +42 -0
- data/lib/vagrant-softlayer/action/rebuild_instance.rb +35 -0
- data/lib/vagrant-softlayer/action/setup_softlayer.rb +37 -0
- data/lib/vagrant-softlayer/action/start_instance.rb +21 -0
- data/lib/vagrant-softlayer/action/stop_instance.rb +30 -0
- data/lib/vagrant-softlayer/action/sync_folders.rb +99 -0
- data/lib/vagrant-softlayer/action/update_dns.rb +96 -0
- data/lib/vagrant-softlayer/action/wait_for_provision.rb +40 -0
- data/lib/vagrant-softlayer/action/wait_for_rebuild.rb +36 -0
- data/lib/vagrant-softlayer/action.rb +200 -0
- data/lib/vagrant-softlayer/command/rebuild.rb +34 -0
- data/lib/vagrant-softlayer/config.rb +178 -0
- data/lib/vagrant-softlayer/errors.rb +25 -0
- data/lib/vagrant-softlayer/plugin.rb +77 -0
- data/lib/vagrant-softlayer/provider.rb +47 -0
- data/lib/vagrant-softlayer/util/network.rb +42 -0
- data/lib/vagrant-softlayer/util/warden.rb +38 -0
- data/lib/vagrant-softlayer/version.rb +5 -0
- data/lib/vagrant-softlayer.rb +22 -0
- data/locales/en.yml +146 -0
- data/spec/spec_helper.rb +1 -0
- data/spec/vagrant-softlayer/config_spec.rb +156 -0
- data/vagrant-softlayer.gemspec +53 -0
- metadata +152 -0
@@ -0,0 +1,99 @@
|
|
1
|
+
require "log4r"
|
2
|
+
|
3
|
+
require "vagrant/util/scoped_hash_override"
|
4
|
+
require "vagrant/util/subprocess"
|
5
|
+
require "vagrant/util/which"
|
6
|
+
|
7
|
+
module VagrantPlugins
|
8
|
+
module SoftLayer
|
9
|
+
module Action
|
10
|
+
# This middleware uses `rsync` to sync the folders over to the
|
11
|
+
# SoftLayer instance.
|
12
|
+
class SyncFolders
|
13
|
+
include Vagrant::Util::ScopedHashOverride
|
14
|
+
|
15
|
+
def initialize(app, env)
|
16
|
+
@app = app
|
17
|
+
@logger = Log4r::Logger.new("vagrant_softlayer::action::sync_folders")
|
18
|
+
end
|
19
|
+
|
20
|
+
def call(env)
|
21
|
+
@app.call(env)
|
22
|
+
|
23
|
+
ssh_info = env[:machine].ssh_info
|
24
|
+
|
25
|
+
unless Vagrant::Util::Which.which("rsync")
|
26
|
+
env[:ui].warn(I18n.t("vagrant_softlayer.sync_folders.rsync_not_found", :side => "host"))
|
27
|
+
return
|
28
|
+
end
|
29
|
+
|
30
|
+
if env[:machine].communicate.execute("which rsync", :error_check => false) != 0
|
31
|
+
env[:ui].warn(I18n.t("vagrant_softlayer.sync_folders.rsync_not_found", :side => "guest"))
|
32
|
+
return
|
33
|
+
end
|
34
|
+
|
35
|
+
env[:machine].config.vm.synced_folders.each do |id, data|
|
36
|
+
data = scoped_hash_override(data, :softlayer)
|
37
|
+
|
38
|
+
# Ignore disabled shared folders
|
39
|
+
next if data[:disabled]
|
40
|
+
|
41
|
+
hostpath = File.expand_path(data[:hostpath], env[:root_path])
|
42
|
+
guestpath = data[:guestpath]
|
43
|
+
|
44
|
+
# Make sure there is a trailing slash on the host path to
|
45
|
+
# avoid creating an additional directory with rsync
|
46
|
+
hostpath = "#{hostpath}/" if hostpath !~ /\/$/
|
47
|
+
|
48
|
+
# on windows rsync.exe requires cygdrive-style paths
|
49
|
+
if Vagrant::Util::Platform.windows?
|
50
|
+
hostpath = hostpath.gsub(/^(\w):/) { "/cygdrive/#{$1}" }
|
51
|
+
end
|
52
|
+
|
53
|
+
env[:ui].info(I18n.t("vagrant_softlayer.sync_folders.rsync_folder",
|
54
|
+
:hostpath => hostpath,
|
55
|
+
:guestpath => guestpath))
|
56
|
+
|
57
|
+
# Create the host path if it doesn't exist and option flag is set
|
58
|
+
if data[:create]
|
59
|
+
begin
|
60
|
+
FileUtils::mkdir_p(hostpath)
|
61
|
+
rescue => err
|
62
|
+
raise Errors::MkdirError,
|
63
|
+
:hostpath => hostpath,
|
64
|
+
:err => err
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
# Create the guest path
|
69
|
+
env[:machine].communicate.sudo("mkdir -p '#{guestpath}'")
|
70
|
+
env[:machine].communicate.sudo(
|
71
|
+
"chown #{ssh_info[:username]} '#{guestpath}'")
|
72
|
+
|
73
|
+
# Rsync over to the guest path using the SSH info
|
74
|
+
command = [
|
75
|
+
"rsync", "--verbose", "--archive", "-z",
|
76
|
+
"--exclude", ".vagrant/", "--exclude", "Vagrantfile",
|
77
|
+
"-e", "ssh -p #{ssh_info[:port]} -o StrictHostKeyChecking=no -i '#{ssh_info[:private_key_path]}'",
|
78
|
+
hostpath,
|
79
|
+
"#{ssh_info[:username]}@#{ssh_info[:host]}:#{guestpath}"]
|
80
|
+
|
81
|
+
# we need to fix permissions when using rsync.exe on windows, see
|
82
|
+
# http://stackoverflow.com/questions/5798807/rsync-permission-denied-created-directories-have-no-permissions
|
83
|
+
if Vagrant::Util::Platform.windows?
|
84
|
+
command.insert(1, "--chmod", "ugo=rwX")
|
85
|
+
end
|
86
|
+
|
87
|
+
r = Vagrant::Util::Subprocess.execute(*command)
|
88
|
+
if r.exit_code != 0
|
89
|
+
raise Errors::RsyncError,
|
90
|
+
:guestpath => guestpath,
|
91
|
+
:hostpath => hostpath,
|
92
|
+
:stderr => r.stderr
|
93
|
+
end
|
94
|
+
end
|
95
|
+
end
|
96
|
+
end
|
97
|
+
end
|
98
|
+
end
|
99
|
+
end
|
@@ -0,0 +1,96 @@
|
|
1
|
+
module VagrantPlugins
|
2
|
+
module SoftLayer
|
3
|
+
module Action
|
4
|
+
# Look for the DNS zone relative to the configured domain and,
|
5
|
+
# on return path, perform an API call to add or remove the A
|
6
|
+
# resource record for the host.
|
7
|
+
class UpdateDNS
|
8
|
+
include Util::Network
|
9
|
+
include Util::Warden
|
10
|
+
|
11
|
+
def initialize(app, env)
|
12
|
+
@app = app
|
13
|
+
@logger = Log4r::Logger.new("vagrant_softlayer::action::update_dns")
|
14
|
+
end
|
15
|
+
|
16
|
+
def call(env)
|
17
|
+
@env = env
|
18
|
+
|
19
|
+
@env[:dns_zone] = setup_dns
|
20
|
+
|
21
|
+
@app.call(@env)
|
22
|
+
|
23
|
+
update_dns
|
24
|
+
end
|
25
|
+
|
26
|
+
def dns_id
|
27
|
+
id = nil
|
28
|
+
id_file = @env[:machine].data_dir.join("dns_id")
|
29
|
+
id = id_file.read.chomp.to_i if id_file.file?
|
30
|
+
return id
|
31
|
+
end
|
32
|
+
|
33
|
+
def dns_id=(value)
|
34
|
+
@logger.info("New machine DNS ID: #{value.inspect}")
|
35
|
+
|
36
|
+
# The file that will store the id if we have one. This allows the
|
37
|
+
# ID to persist across Vagrant runs.
|
38
|
+
id_file = @env[:machine].data_dir.join("dns_id")
|
39
|
+
|
40
|
+
if value
|
41
|
+
# Write the "id" file with the id given.
|
42
|
+
id_file.open("w+") do |f|
|
43
|
+
f.write(value)
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
def setup_dns
|
49
|
+
unless @env[:machine].provider_config.manage_dns
|
50
|
+
@logger.debug("Not managing DNS. Going ahead.")
|
51
|
+
return
|
52
|
+
end
|
53
|
+
|
54
|
+
dns_zone = ::SoftLayer::Service.new("SoftLayer_Dns_Domain", @env[:sl_credentials])
|
55
|
+
|
56
|
+
domain = @env[:machine].provider_config.domain
|
57
|
+
@logger.debug("Looking for #{domain} zone into the SoftLayer zone list.")
|
58
|
+
dns_zone_obj = sl_warden { dns_zone.getByDomainName(domain).first }
|
59
|
+
raise Errors::SLDNSZoneNotFound, :zone => domain unless dns_zone_obj
|
60
|
+
@logger.debug("Found DNS zone: #{dns_zone_obj.inspect}")
|
61
|
+
return dns_zone_obj
|
62
|
+
end
|
63
|
+
|
64
|
+
def update_dns
|
65
|
+
unless @env[:machine].provider_config.manage_dns
|
66
|
+
@logger.debug("Not managing DNS. Going ahead.")
|
67
|
+
return
|
68
|
+
end
|
69
|
+
|
70
|
+
dns_resource = ::SoftLayer::Service.new("SoftLayer_Dns_Domain_ResourceRecord", @env[:sl_credentials])
|
71
|
+
|
72
|
+
case @env[:action_name]
|
73
|
+
when :machine_action_up
|
74
|
+
hostname = @env[:machine].provider_config.hostname || @env[:machine].config.vm.hostname
|
75
|
+
@env[:sl_machine] = @env[:sl_connection].object_with_id(@env[:machine].id.to_i)
|
76
|
+
res_template = {
|
77
|
+
"data" => ip_address(@env),
|
78
|
+
"domainId" => @env[:dns_zone]["id"],
|
79
|
+
"host" => hostname,
|
80
|
+
"ttl" => 86400,
|
81
|
+
"type" => "a"
|
82
|
+
}
|
83
|
+
@env[:ui].info I18n.t("vagrant_softlayer.vm.creating_dns_record")
|
84
|
+
@logger.debug("Creating DNS A record for #{hostname}.#{@env[:dns_zone][:name]} (IP address #{res_template['data']}).")
|
85
|
+
new_rr = sl_warden { dns_resource.createObject(res_template) }
|
86
|
+
self.dns_id = new_rr["id"]
|
87
|
+
when :machine_action_destroy
|
88
|
+
@env[:ui].info I18n.t("vagrant_softlayer.vm.deleting_dns_record")
|
89
|
+
@logger.debug("Deleting stored DNS A record (ID #{self.dns_id}).")
|
90
|
+
sl_warden { dns_resource.object_with_id(self.dns_id).deleteObject }
|
91
|
+
end
|
92
|
+
end
|
93
|
+
end
|
94
|
+
end
|
95
|
+
end
|
96
|
+
end
|
@@ -0,0 +1,40 @@
|
|
1
|
+
require "log4r"
|
2
|
+
|
3
|
+
module VagrantPlugins
|
4
|
+
module SoftLayer
|
5
|
+
module Action
|
6
|
+
# Waits until the new machine has been provisioned.
|
7
|
+
class WaitForProvision
|
8
|
+
include Util::Warden
|
9
|
+
|
10
|
+
def initialize(app, env)
|
11
|
+
@app = app
|
12
|
+
@logger = Log4r::Logger.new("vagrant_softlayer::action::wait_for_provision")
|
13
|
+
end
|
14
|
+
|
15
|
+
def call(env)
|
16
|
+
env[:ui].info I18n.t("vagrant_softlayer.vm.wait_for_provision")
|
17
|
+
|
18
|
+
env[:sl_machine] = env[:sl_connection].object_with_id(env[:machine].id.to_i)
|
19
|
+
|
20
|
+
retry_msg = lambda { @logger.debug("Object not found, retrying in 10 seconds.") }
|
21
|
+
|
22
|
+
# 20 minutes timeout
|
23
|
+
Timeout::timeout(1200) do
|
24
|
+
@logger.debug("Checking if the newly ordered machine has been provisioned.")
|
25
|
+
sl_warden(retry_msg, 10) do
|
26
|
+
while env[:sl_machine].getPowerState["name"] != "Running" || env[:sl_machine].object_mask( { "provisionDate" => "" } ).getObject == {}
|
27
|
+
@logger.debug("The machine is still provisioning. Retrying in 10 seconds.")
|
28
|
+
sleep 10
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
env[:ui].info I18n.t("vagrant_softlayer.vm.provisioned")
|
34
|
+
|
35
|
+
@app.call(env)
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
@@ -0,0 +1,36 @@
|
|
1
|
+
require "log4r"
|
2
|
+
|
3
|
+
module VagrantPlugins
|
4
|
+
module SoftLayer
|
5
|
+
module Action
|
6
|
+
# Waits until the new machine has been rebuilt.
|
7
|
+
class WaitForRebuild
|
8
|
+
include Util::Warden
|
9
|
+
|
10
|
+
def initialize(app, env)
|
11
|
+
@app = app
|
12
|
+
@logger = Log4r::Logger.new("vagrant_softlayer::action::wait_for_rebuild")
|
13
|
+
end
|
14
|
+
|
15
|
+
def call(env)
|
16
|
+
env[:ui].info I18n.t("vagrant_softlayer.vm.wait_for_rebuild")
|
17
|
+
|
18
|
+
# 20 minutes timeout
|
19
|
+
Timeout::timeout(1200) do
|
20
|
+
@logger.debug("Checking if the instance has been rebuilt.")
|
21
|
+
sl_warden do
|
22
|
+
while env[:sl_machine].object_mask("activeTransactionCount").getObject["activeTransactionCount"] > 0
|
23
|
+
@logger.debug("The machine is still being rebuilt. Retrying in 10 seconds.")
|
24
|
+
sleep 10
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
env[:ui].info I18n.t("vagrant_softlayer.vm.rebuilt")
|
30
|
+
|
31
|
+
@app.call(env)
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
@@ -0,0 +1,200 @@
|
|
1
|
+
require "pathname"
|
2
|
+
require "vagrant-softlayer/util/network"
|
3
|
+
require "vagrant-softlayer/util/warden"
|
4
|
+
|
5
|
+
module VagrantPlugins
|
6
|
+
module SoftLayer
|
7
|
+
module Action
|
8
|
+
# Include the built-in modules so we can use them as top-level things.
|
9
|
+
include Vagrant::Action::Builtin
|
10
|
+
|
11
|
+
# This action is called to terminate the remote machine.
|
12
|
+
def self.action_destroy
|
13
|
+
Vagrant::Action::Builder.new.tap do |b|
|
14
|
+
b.use Call, DestroyConfirm do |env, b2|
|
15
|
+
if env[:result]
|
16
|
+
b2.use ConfigValidate
|
17
|
+
b.use Call, Is, :not_created do |env2, b3|
|
18
|
+
if env2[:result]
|
19
|
+
b3.use Message, :error, "vagrant_softlayer.vm.not_created"
|
20
|
+
next
|
21
|
+
end
|
22
|
+
end
|
23
|
+
b2.use SetupSoftLayer
|
24
|
+
b2.use DestroyInstance
|
25
|
+
b2.use UpdateDNS
|
26
|
+
else
|
27
|
+
b2.use Message, :warn, "vagrant_softlayer.vm.not_destroying"
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
# This action is called to halt the remote machine.
|
34
|
+
def self.action_halt
|
35
|
+
Vagrant::Action::Builder.new.tap do |b|
|
36
|
+
b.use ConfigValidate
|
37
|
+
b.use Call, Is, :running do |env, b2|
|
38
|
+
if !env[:result]
|
39
|
+
b2.use Message, :error, "vagrant_softlayer.vm.not_running"
|
40
|
+
next
|
41
|
+
end
|
42
|
+
|
43
|
+
b2.use SetupSoftLayer
|
44
|
+
b2.use StopInstance
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
# This action is called to run provisioners on the machine.
|
50
|
+
def self.action_provision
|
51
|
+
Vagrant::Action::Builder.new.tap do |b|
|
52
|
+
b.use ConfigValidate
|
53
|
+
b.use Call, Is, :running do |env, b2|
|
54
|
+
if !env[:result]
|
55
|
+
b2.use Message, :error, "vagrant_softlayer.vm.not_running"
|
56
|
+
next
|
57
|
+
end
|
58
|
+
|
59
|
+
b2.use Provision
|
60
|
+
b2.use SyncFolders
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
# This action is called to read the SSH info of the machine. The
|
66
|
+
# resulting state is expected to be put into the `:machine_ssh_info`
|
67
|
+
# key.
|
68
|
+
def self.action_read_ssh_info
|
69
|
+
Vagrant::Action::Builder.new.tap do |b|
|
70
|
+
b.use ConfigValidate
|
71
|
+
b.use SetupSoftLayer
|
72
|
+
b.use ReadSSHInfo
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
# This action is called to read the state of the machine. The
|
77
|
+
# resulting state is expected to be put into the `:machine_state_id`
|
78
|
+
# key.
|
79
|
+
def self.action_read_state
|
80
|
+
Vagrant::Action::Builder.new.tap do |b|
|
81
|
+
b.use ConfigValidate
|
82
|
+
b.use SetupSoftLayer
|
83
|
+
b.use ReadState
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
87
|
+
# This action is called to rebuild the machine OS from scratch.
|
88
|
+
def self.action_rebuild
|
89
|
+
Vagrant::Action::Builder.new.tap do |b|
|
90
|
+
b.use Call, Confirm, I18n.t("vagrant_softlayer.vm.rebuild_confirmation"), :force_rebuild do |env, b2|
|
91
|
+
if env[:result]
|
92
|
+
b2.use ConfigValidate
|
93
|
+
b.use Call, Is, :not_created do |env2, b3|
|
94
|
+
if env2[:result]
|
95
|
+
b3.use Message, :error, "vagrant_softlayer.vm.not_created"
|
96
|
+
next
|
97
|
+
end
|
98
|
+
end
|
99
|
+
b2.use SetupSoftLayer
|
100
|
+
b2.use RebuildInstance
|
101
|
+
b2.use Provision
|
102
|
+
b2.use SyncFolders
|
103
|
+
b2.use WaitForRebuild
|
104
|
+
b2.use WaitForCommunicator
|
105
|
+
else
|
106
|
+
b2.use Message, :warn, "vagrant_softlayer.vm.not_rebuilding"
|
107
|
+
end
|
108
|
+
end
|
109
|
+
end
|
110
|
+
end
|
111
|
+
|
112
|
+
# This action is called to reload the machine.
|
113
|
+
def self.action_reload
|
114
|
+
Vagrant::Action::Builder.new.tap do |b|
|
115
|
+
b.use action_halt
|
116
|
+
b.use action_up
|
117
|
+
end
|
118
|
+
end
|
119
|
+
|
120
|
+
# This action is called to SSH into the machine.
|
121
|
+
def self.action_ssh
|
122
|
+
Vagrant::Action::Builder.new.tap do |b|
|
123
|
+
b.use ConfigValidate
|
124
|
+
b.use Call, Is, :running do |env, b2|
|
125
|
+
if !env[:result]
|
126
|
+
b2.use Message, :error, "vagrant_softlayer.vm.not_running"
|
127
|
+
next
|
128
|
+
end
|
129
|
+
|
130
|
+
b2.use SSHExec
|
131
|
+
end
|
132
|
+
end
|
133
|
+
end
|
134
|
+
|
135
|
+
def self.action_ssh_run
|
136
|
+
Vagrant::Action::Builder.new.tap do |b|
|
137
|
+
b.use ConfigValidate
|
138
|
+
b.use Call, Is, :running do |env, b2|
|
139
|
+
if !env[:result]
|
140
|
+
b2.use Message, :error, "vagrant_softlayer.vm.not_running"
|
141
|
+
next
|
142
|
+
end
|
143
|
+
|
144
|
+
b2.use SSHRun
|
145
|
+
end
|
146
|
+
end
|
147
|
+
end
|
148
|
+
|
149
|
+
# This action is called to bring the box up from nothing.
|
150
|
+
def self.action_up
|
151
|
+
Vagrant::Action::Builder.new.tap do |b|
|
152
|
+
b.use HandleBoxUrl
|
153
|
+
b.use ConfigValidate
|
154
|
+
b.use SetupSoftLayer
|
155
|
+
b.use Call, Is, :not_created do |env1, b1|
|
156
|
+
if env1[:result]
|
157
|
+
b1.use SetupSoftLayer
|
158
|
+
b1.use Provision
|
159
|
+
b1.use SyncFolders
|
160
|
+
b1.use UpdateDNS
|
161
|
+
b1.use CreateInstance
|
162
|
+
b1.use WaitForProvision
|
163
|
+
b1.use WaitForCommunicator
|
164
|
+
else
|
165
|
+
b1.use Call, Is, :halted do |env2, b2|
|
166
|
+
if env2[:result]
|
167
|
+
b2.use SetupSoftLayer
|
168
|
+
b2.use Provision
|
169
|
+
b2.use SyncFolders
|
170
|
+
b2.use StartInstance
|
171
|
+
b2.use WaitForCommunicator
|
172
|
+
else
|
173
|
+
b2.use Message, :warn, "vagrant_softlayer.vm.already_running"
|
174
|
+
end
|
175
|
+
end
|
176
|
+
end
|
177
|
+
end
|
178
|
+
end
|
179
|
+
end
|
180
|
+
|
181
|
+
# The autoload farm
|
182
|
+
action_root = Pathname.new(File.expand_path("../action", __FILE__))
|
183
|
+
|
184
|
+
autoload :CreateInstance, action_root.join("create_instance")
|
185
|
+
autoload :DestroyInstance, action_root.join("destroy_instance")
|
186
|
+
autoload :Is, action_root.join("is")
|
187
|
+
autoload :Message, action_root.join("message")
|
188
|
+
autoload :ReadSSHInfo, action_root.join("read_ssh_info")
|
189
|
+
autoload :ReadState, action_root.join("read_state")
|
190
|
+
autoload :RebuildInstance, action_root.join("rebuild_instance")
|
191
|
+
autoload :SetupSoftLayer, action_root.join("setup_softlayer")
|
192
|
+
autoload :StartInstance, action_root.join("start_instance")
|
193
|
+
autoload :StopInstance, action_root.join("stop_instance")
|
194
|
+
autoload :SyncFolders, action_root.join("sync_folders")
|
195
|
+
autoload :UpdateDNS, action_root.join("update_dns")
|
196
|
+
autoload :WaitForProvision, action_root.join("wait_for_provision")
|
197
|
+
autoload :WaitForRebuild, action_root.join("wait_for_rebuild")
|
198
|
+
end
|
199
|
+
end
|
200
|
+
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
require 'optparse'
|
2
|
+
|
3
|
+
module VagrantPlugins
|
4
|
+
module SoftLayer
|
5
|
+
module Command
|
6
|
+
class Rebuild < Vagrant.plugin('2', :command)
|
7
|
+
def execute
|
8
|
+
options = {}
|
9
|
+
options[:force] = false
|
10
|
+
|
11
|
+
opts = OptionParser.new do |o|
|
12
|
+
o.banner = "Usage: vagrant rebuild [vm-name]"
|
13
|
+
o.separator ""
|
14
|
+
|
15
|
+
o.on("-f", "--force", "Rebuild without confirmation.") do |f|
|
16
|
+
options[:force] = f
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
argv = parse_options(opts)
|
21
|
+
return if !argv
|
22
|
+
|
23
|
+
declined = false
|
24
|
+
with_target_vms(argv) do |vm|
|
25
|
+
action_env = vm.action(:rebuild, :force_rebuild => options[:force], :provision_ignore_sentinel => false)
|
26
|
+
declined = true if action_env.has_key?(:force_rebuild_result) && action_env[:force_rebuild_result] == false
|
27
|
+
end
|
28
|
+
|
29
|
+
declined ? 1 : 0
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
@@ -0,0 +1,178 @@
|
|
1
|
+
module VagrantPlugins
|
2
|
+
module SoftLayer
|
3
|
+
class Config < Vagrant.plugin("2", :config)
|
4
|
+
# The API key to access SoftLayer.
|
5
|
+
attr_accessor :api_key
|
6
|
+
|
7
|
+
# The endpoint SoftLayer API url.
|
8
|
+
attr_accessor :endpoint_url
|
9
|
+
|
10
|
+
# The username to access SoftLayer.
|
11
|
+
attr_accessor :username
|
12
|
+
|
13
|
+
# The datacenter shortname.
|
14
|
+
attr_accessor :datacenter
|
15
|
+
|
16
|
+
# Whether to allocate a dedicated instance.
|
17
|
+
attr_accessor :dedicated
|
18
|
+
|
19
|
+
# The domain of the instance.
|
20
|
+
attr_accessor :domain
|
21
|
+
|
22
|
+
# The hostname of the instance.
|
23
|
+
attr_accessor :hostname
|
24
|
+
|
25
|
+
# The billing type of the instance (true for hourly, false for monthly).
|
26
|
+
attr_accessor :hourly_billing
|
27
|
+
|
28
|
+
# The disk type of the instance (true for local, false for SAN).
|
29
|
+
attr_accessor :local_disk
|
30
|
+
|
31
|
+
# The amount of RAM of the instance.
|
32
|
+
attr_accessor :max_memory
|
33
|
+
|
34
|
+
# Network port speed in Mbps.
|
35
|
+
attr_accessor :network_speed
|
36
|
+
|
37
|
+
# The instance operating system identifier.
|
38
|
+
attr_accessor :operating_system
|
39
|
+
|
40
|
+
# URI of post-install script to download.
|
41
|
+
attr_accessor :post_install
|
42
|
+
|
43
|
+
# Whether or not the instance only has access to the private network.
|
44
|
+
attr_accessor :private_only
|
45
|
+
|
46
|
+
# The id or name of the ssh key to be provisioned.
|
47
|
+
attr_accessor :ssh_key
|
48
|
+
|
49
|
+
# The number of processors of the instance.
|
50
|
+
attr_accessor :start_cpus
|
51
|
+
|
52
|
+
# User defined metadata string.
|
53
|
+
attr_accessor :user_data
|
54
|
+
|
55
|
+
# The ID of the private VLAN.
|
56
|
+
attr_accessor :vlan_private
|
57
|
+
|
58
|
+
# The ID of the public VLAN.
|
59
|
+
attr_accessor :vlan_public
|
60
|
+
|
61
|
+
# Automatically update DNS on create and destroy.
|
62
|
+
attr_accessor :manage_dns
|
63
|
+
|
64
|
+
def initialize
|
65
|
+
@api_key = UNSET_VALUE
|
66
|
+
@endpoint_url = UNSET_VALUE
|
67
|
+
@username = UNSET_VALUE
|
68
|
+
|
69
|
+
@datacenter = UNSET_VALUE
|
70
|
+
@dedicated = UNSET_VALUE
|
71
|
+
@domain = UNSET_VALUE
|
72
|
+
@hostname = UNSET_VALUE
|
73
|
+
@hourly_billing = UNSET_VALUE
|
74
|
+
@local_disk = UNSET_VALUE
|
75
|
+
@max_memory = UNSET_VALUE
|
76
|
+
@network_speed = UNSET_VALUE
|
77
|
+
@operating_system = UNSET_VALUE
|
78
|
+
@post_install = UNSET_VALUE
|
79
|
+
@private_only = UNSET_VALUE
|
80
|
+
@ssh_key = UNSET_VALUE
|
81
|
+
@start_cpus = UNSET_VALUE
|
82
|
+
@user_data = UNSET_VALUE
|
83
|
+
@vlan_private = UNSET_VALUE
|
84
|
+
@vlan_public = UNSET_VALUE
|
85
|
+
|
86
|
+
@manage_dns = UNSET_VALUE
|
87
|
+
end
|
88
|
+
|
89
|
+
def finalize!
|
90
|
+
# Try to get username and api key from environment variables.
|
91
|
+
# They will default to nil if the environment variables are not present.
|
92
|
+
@api_key = ENV["SL_API_KEY"] if @api_key == UNSET_VALUE
|
93
|
+
@username = ENV["SL_USERNAME"] if @username == UNSET_VALUE
|
94
|
+
|
95
|
+
# Endpoint url defaults to public SoftLayer API url.
|
96
|
+
@endpoint_url = API_PUBLIC_ENDPOINT if @endpoint_url == UNSET_VALUE
|
97
|
+
|
98
|
+
# No default datacenter.
|
99
|
+
@datacenter = nil if @datacenter == UNSET_VALUE
|
100
|
+
|
101
|
+
# Shared instance by default.
|
102
|
+
@dedicated = false if @dedicated == UNSET_VALUE
|
103
|
+
|
104
|
+
# Domain should be specified in Vagrantfile, so we set default to nil.
|
105
|
+
@domain = nil if @domain == UNSET_VALUE
|
106
|
+
|
107
|
+
# Hostname should be specified in Vagrantfile, either using `config.vm.hostname`
|
108
|
+
# or the provider specific configuration entry.
|
109
|
+
@hostname = nil if @hostname == UNSET_VALUE
|
110
|
+
|
111
|
+
# Bill hourly by default.
|
112
|
+
@hourly_billing = true if @hourly_billing == UNSET_VALUE
|
113
|
+
|
114
|
+
# Use local disk by default.
|
115
|
+
@local_disk = true if @local_disk == UNSET_VALUE
|
116
|
+
|
117
|
+
# 1Gb of RAM by default.
|
118
|
+
@max_memory = 1024 if @max_memory == UNSET_VALUE
|
119
|
+
|
120
|
+
# 10Mbps by default.
|
121
|
+
@network_speed = 10 if @network_speed == UNSET_VALUE
|
122
|
+
|
123
|
+
# Provision with the latest Ubuntu by default.
|
124
|
+
@operating_system = "UBUNTU_LATEST" if @operating_system == UNSET_VALUE
|
125
|
+
|
126
|
+
# No post install script by default.
|
127
|
+
@post_install = nil if @post_install == UNSET_VALUE
|
128
|
+
|
129
|
+
# Private-network only is false by default.
|
130
|
+
@private_only = false if @private_only == UNSET_VALUE
|
131
|
+
|
132
|
+
# SSH key should be specified in Vagrantfile, so we set default to nil.
|
133
|
+
@ssh_key = nil if @ssh_key == UNSET_VALUE
|
134
|
+
|
135
|
+
# One processor by default.
|
136
|
+
@start_cpus = 1 if @start_cpus == UNSET_VALUE
|
137
|
+
|
138
|
+
# No user metadata by default.
|
139
|
+
@user_data = nil if @user_data == UNSET_VALUE
|
140
|
+
|
141
|
+
# No specific private VLAN by default.
|
142
|
+
@vlan_private = nil if @vlan_private == UNSET_VALUE
|
143
|
+
|
144
|
+
# No specific public VLAN by default.
|
145
|
+
@vlan_public = nil if @vlan_public == UNSET_VALUE
|
146
|
+
|
147
|
+
# DNS management off by default
|
148
|
+
@manage_dns = false if @manage_dns == UNSET_VALUE
|
149
|
+
end
|
150
|
+
|
151
|
+
# Aliases for ssh_key for beautiful semantic
|
152
|
+
def ssh_keys=(value)
|
153
|
+
@ssh_key = value
|
154
|
+
end
|
155
|
+
alias_method :ssh_key_id=, :ssh_keys=
|
156
|
+
alias_method :ssh_key_ids=, :ssh_keys=
|
157
|
+
alias_method :ssh_key_name=, :ssh_keys=
|
158
|
+
alias_method :ssh_key_names=, :ssh_keys=
|
159
|
+
|
160
|
+
def validate(machine)
|
161
|
+
errors = []
|
162
|
+
|
163
|
+
errors << I18n.t("vagrant_softlayer.config.api_key_required") if !@api_key
|
164
|
+
errors << I18n.t("vagrant_softlayer.config.username_required") if !@username
|
165
|
+
|
166
|
+
errors << I18n.t("vagrant_softlayer.config.domain_required") if !@domain
|
167
|
+
errors << I18n.t("vagrant_softlayer.config.ssh_key_required") if !@ssh_key
|
168
|
+
|
169
|
+
# Fail if both `vm.hostname` and `provider.hostname` are nil.
|
170
|
+
if !@hostname && !machine.config.vm.hostname
|
171
|
+
errors << I18n.t("vagrant_softlayer.config.hostname_required")
|
172
|
+
end
|
173
|
+
|
174
|
+
{ "SoftLayer" => errors }
|
175
|
+
end
|
176
|
+
end
|
177
|
+
end
|
178
|
+
end
|