vagrant-softlayer 0.1.0
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.
- 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
|