corl 0.4.15 → 0.4.16
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 +7 -0
- data/Gemfile +6 -1
- data/Gemfile.lock +76 -30
- data/Rakefile +1 -1
- data/VERSION +1 -1
- data/bootstrap/bootstrap.sh +5 -2
- data/bootstrap/os/ubuntu/00_base.sh +1 -1
- data/bootstrap/os/ubuntu/01_git.sh +9 -0
- data/bootstrap/os/ubuntu/05_ruby.sh +7 -4
- data/bootstrap/os/ubuntu/06_puppet.sh +2 -2
- data/corl.gemspec +23 -9
- data/lib/CORL/action/authorize.rb +2 -5
- data/lib/CORL/action/bootstrap.rb +1 -5
- data/lib/CORL/action/build.rb +2 -10
- data/lib/CORL/action/destroy.rb +2 -7
- data/lib/CORL/action/exec.rb +1 -5
- data/lib/CORL/action/image.rb +1 -5
- data/lib/CORL/action/images.rb +12 -10
- data/lib/CORL/action/ip.rb +21 -0
- data/lib/CORL/action/lookup.rb +5 -3
- data/lib/CORL/action/machines.rb +12 -10
- data/lib/CORL/action/provision.rb +4 -7
- data/lib/CORL/action/regions.rb +12 -10
- data/lib/CORL/action/seed.rb +9 -10
- data/lib/CORL/action/spawn.rb +29 -15
- data/lib/CORL/action/ssh.rb +1 -5
- data/lib/CORL/action/start.rb +1 -5
- data/lib/CORL/action/stop.rb +1 -5
- data/lib/CORL/action/vagrantfile.rb +55 -0
- data/lib/CORL/configuration/file.rb +4 -1
- data/lib/CORL/machine/physical.rb +1 -1
- data/lib/CORL/machine/vagrant.rb +358 -0
- data/lib/CORL/node/local.rb +2 -3
- data/lib/CORL/node/vagrant.rb +238 -0
- data/lib/core/facade.rb +25 -2
- data/lib/core/mixin/macro/network_settings.rb +35 -1
- data/lib/core/plugin/action.rb +53 -5
- data/lib/core/plugin/configuration.rb +19 -5
- data/lib/core/plugin/fog_machine.rb +1 -1
- data/lib/core/plugin/fog_node.rb +9 -9
- data/lib/core/plugin/machine.rb +6 -13
- data/lib/core/plugin/network.rb +23 -7
- data/lib/core/plugin/node.rb +69 -36
- data/lib/core/plugin/provisioner.rb +1 -2
- data/lib/core/vagrant/Vagrantfile +7 -0
- data/lib/core/vagrant/commands/launcher.rb +66 -0
- data/lib/core/vagrant/config.rb +308 -0
- data/lib/core/vagrant/plugins.rb +33 -0
- data/lib/core/vagrant/provisioner/config.rb +39 -0
- data/lib/core/vagrant/provisioner/provisioner.rb +46 -0
- data/lib/corl.rb +8 -0
- data/locales/en.yml +13 -1
- metadata +120 -59
@@ -0,0 +1,308 @@
|
|
1
|
+
|
2
|
+
#
|
3
|
+
# Because we create configurations and operate on resulting machines during
|
4
|
+
# the course of a single CLI command run we need to be able to reload the
|
5
|
+
# configurations based on updates to fetch Vagrant VMs and run Vagrant machine
|
6
|
+
# actions. TODO: Inquire about some form of inclusion in Vagrant core?
|
7
|
+
#
|
8
|
+
module Vagrant
|
9
|
+
class Vagrantfile
|
10
|
+
|
11
|
+
def reload
|
12
|
+
@loader.clear_config_cache(@keys)
|
13
|
+
@config, _ = @loader.load(@keys)
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
module Config
|
18
|
+
class Loader
|
19
|
+
def clear_config_cache(sources = nil)
|
20
|
+
@config_cache = {}
|
21
|
+
|
22
|
+
if sources
|
23
|
+
keep = {}
|
24
|
+
sources.each do |source|
|
25
|
+
keep[source] = @sources[source] if @sources[source]
|
26
|
+
end
|
27
|
+
@sources = keep
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
#-------------------------------------------------------------------------------
|
35
|
+
|
36
|
+
module CORL
|
37
|
+
module Vagrant
|
38
|
+
module Config
|
39
|
+
|
40
|
+
@@network = nil
|
41
|
+
|
42
|
+
def self.network=network
|
43
|
+
@@network = network
|
44
|
+
end
|
45
|
+
|
46
|
+
def self.network
|
47
|
+
@@network
|
48
|
+
end
|
49
|
+
|
50
|
+
|
51
|
+
#
|
52
|
+
# Gateway CORL configurator for Vagrant.
|
53
|
+
#
|
54
|
+
def self.register(directory, config, &code)
|
55
|
+
::Vagrant.require_version ">= 1.5.0"
|
56
|
+
|
57
|
+
config_network = network
|
58
|
+
config_network = load_network(directory) unless config_network
|
59
|
+
|
60
|
+
if config_network
|
61
|
+
# Vagrant settings
|
62
|
+
unless configure_vagrant(config_network, config.vagrant)
|
63
|
+
raise "Configuration of Vagrant general settings failed"
|
64
|
+
end
|
65
|
+
|
66
|
+
config_network.nodes(:vagrant, true).each do |node_name, node|
|
67
|
+
config.vm.define node.id.to_sym do |machine|
|
68
|
+
# VM settings
|
69
|
+
unless configure_vm(node, machine)
|
70
|
+
raise "Configuration of Vagrant VM failed: #{node_name}"
|
71
|
+
end
|
72
|
+
|
73
|
+
# SSH settings
|
74
|
+
unless configure_ssh(node, machine)
|
75
|
+
raise "Configuration of Vagrant VM SSH settings failed"
|
76
|
+
end
|
77
|
+
|
78
|
+
# Server shares
|
79
|
+
unless configure_shares(node, machine)
|
80
|
+
raise "Configuration of Vagrant shares failed: #{node_name}"
|
81
|
+
end
|
82
|
+
|
83
|
+
# Provisioner configuration
|
84
|
+
unless configure_provisioner(network, node, machine)
|
85
|
+
raise "Configuration of Vagrant provisioner failed: #{node_name}"
|
86
|
+
end
|
87
|
+
|
88
|
+
code.call(network, node, machine) if code
|
89
|
+
end
|
90
|
+
end
|
91
|
+
end
|
92
|
+
end
|
93
|
+
|
94
|
+
#---
|
95
|
+
|
96
|
+
def self.load_network(directory)
|
97
|
+
# Load network if it exists
|
98
|
+
CORL.network(
|
99
|
+
:vagrant,
|
100
|
+
CORL.config(:vagrant_network, { :directory => directory, :name => directory })
|
101
|
+
)
|
102
|
+
end
|
103
|
+
|
104
|
+
#---
|
105
|
+
|
106
|
+
def self.configure_vagrant(network, vagrant)
|
107
|
+
success = true
|
108
|
+
Util::Data.hash(network.settings(:vagrant_config)).each do |name, data|
|
109
|
+
if vagrant.respond_to?("#{name}=")
|
110
|
+
data = Util::Data.value(data)
|
111
|
+
#dbg(name, 'vagrant property')
|
112
|
+
#dbg(data, 'vagrant property data')
|
113
|
+
vagrant.send("#{name}=", data)
|
114
|
+
else
|
115
|
+
params = parse_params(data)
|
116
|
+
#dbg(name, 'vagrant method')
|
117
|
+
#dbg(params, 'vagrant method params')
|
118
|
+
vagrant.send(name, params)
|
119
|
+
end
|
120
|
+
end
|
121
|
+
success
|
122
|
+
end
|
123
|
+
|
124
|
+
#---
|
125
|
+
|
126
|
+
def self.configure_ssh(node, machine)
|
127
|
+
success = true
|
128
|
+
|
129
|
+
#dbg(node.user, 'ssh user')
|
130
|
+
machine.ssh.username = node.user
|
131
|
+
|
132
|
+
#dbg(node.ssh_port, 'ssh port')
|
133
|
+
machine.ssh.guest_port = node.ssh_port
|
134
|
+
|
135
|
+
if node.cache_setting(:use_private_key, false)
|
136
|
+
#dbg(node.private_key, 'ssh private key')
|
137
|
+
machine.ssh.private_key_path = node.private_key
|
138
|
+
end
|
139
|
+
|
140
|
+
Util::Data.hash(node.ssh).each do |name, data|
|
141
|
+
if machine.ssh.respond_to?("#{name}=")
|
142
|
+
data = Util::Data.value(data)
|
143
|
+
#dbg(name, 'ssh property')
|
144
|
+
#dbg(data, 'ssh property data')
|
145
|
+
machine.ssh.send("#{name}=", data)
|
146
|
+
else
|
147
|
+
params = parse_params(data)
|
148
|
+
#dbg(name, 'ssh method')
|
149
|
+
#dbg(params, 'ssh method params')
|
150
|
+
machine.ssh.send(name, params)
|
151
|
+
end
|
152
|
+
end
|
153
|
+
success
|
154
|
+
end
|
155
|
+
|
156
|
+
#---
|
157
|
+
|
158
|
+
def self.configure_vm(node, machine)
|
159
|
+
vm_config = Util::Data.hash(node.vm)
|
160
|
+
success = true
|
161
|
+
|
162
|
+
#dbg(node.hostname, 'VM hostname')
|
163
|
+
machine.vm.hostname = node.hostname
|
164
|
+
|
165
|
+
box = node.cache_setting(:box)
|
166
|
+
box_url = node.cache_setting(:box_url)
|
167
|
+
|
168
|
+
if box && box_url
|
169
|
+
#dbg(box, 'VM box')
|
170
|
+
machine.vm.box = box
|
171
|
+
#dbg(box_url, 'VM box url')
|
172
|
+
machine.vm.box_url = box_url
|
173
|
+
else
|
174
|
+
#dbg(node.image, 'VM box')
|
175
|
+
machine.vm.box = node.image
|
176
|
+
end
|
177
|
+
|
178
|
+
unless vm_config.has_key?(:public_network)
|
179
|
+
if node.public_ip
|
180
|
+
#dbg(node.public_ip, 'private ip address')
|
181
|
+
machine.vm.network :private_network, :ip => node.public_ip
|
182
|
+
else
|
183
|
+
#dbg('dhcp private ip address')
|
184
|
+
machine.vm.network :private_network, :type => "dhcp"
|
185
|
+
end
|
186
|
+
end
|
187
|
+
|
188
|
+
vm_config.each do |name, data|
|
189
|
+
case name.to_sym
|
190
|
+
# Network interfaces
|
191
|
+
when :forwarded_ports
|
192
|
+
data.each do |forward_name, info|
|
193
|
+
forward_config = CORL::Config.new({ :auto_correct => true }).import(info)
|
194
|
+
|
195
|
+
forward_config.keys do |key|
|
196
|
+
forward_config[key] = Util::Data.value(forward_config[key])
|
197
|
+
end
|
198
|
+
#dbg(forward_config.export, 'vm forwarded port config')
|
199
|
+
machine.vm.network :forwarded_port, forward_config.export
|
200
|
+
end
|
201
|
+
when :usable_port_range
|
202
|
+
low, high = data.to_s.split(/\s*--?\s*/)
|
203
|
+
#dbg("#{low} <--> #{high}", 'vm usable port range')
|
204
|
+
machine.vm.usable_port_range = Range.new(low, high)
|
205
|
+
|
206
|
+
when :public_network
|
207
|
+
#dbg('public network')
|
208
|
+
machine.vm.network :public_network
|
209
|
+
|
210
|
+
# Provider specific settings
|
211
|
+
when :providers
|
212
|
+
data.each do |provider, info|
|
213
|
+
#dbg(provider, 'vm provider')
|
214
|
+
machine.vm.provider provider.to_sym do |interface|
|
215
|
+
info.each do |property, item|
|
216
|
+
#dbg(property, 'vm property')
|
217
|
+
#dbg(item, 'vm property item')
|
218
|
+
if interface.respond_to?("#{property}=")
|
219
|
+
interface.send("#{property}=", item)
|
220
|
+
else
|
221
|
+
params = parse_params(item)
|
222
|
+
#dbg(params, 'vm method params')
|
223
|
+
interface.send(property, params)
|
224
|
+
end
|
225
|
+
end
|
226
|
+
end
|
227
|
+
end
|
228
|
+
# All other basic VM settings...
|
229
|
+
else
|
230
|
+
if machine.vm.respond_to?("#{name}=")
|
231
|
+
#dbg(name, 'other property')
|
232
|
+
#dbg(data, 'other property data')
|
233
|
+
machine.vm.send("#{name}=", data)
|
234
|
+
else
|
235
|
+
params = parse_params(data)
|
236
|
+
#dbg(name, 'other method')
|
237
|
+
#dbg(params, 'other method params')
|
238
|
+
machine.vm.send(name, params)
|
239
|
+
end
|
240
|
+
end
|
241
|
+
end
|
242
|
+
success
|
243
|
+
end
|
244
|
+
|
245
|
+
#---
|
246
|
+
|
247
|
+
def self.configure_shares(node, machine)
|
248
|
+
success = true
|
249
|
+
|
250
|
+
Util::Data.hash(node.shares).each do |name, options|
|
251
|
+
config = CORL::Config.ensure(options)
|
252
|
+
local_dir = config.delete(:local, '')
|
253
|
+
remote_dir = config.delete(:remote, '')
|
254
|
+
|
255
|
+
config.init(:create, true)
|
256
|
+
|
257
|
+
unless local_dir.empty? || remote_dir.empty?
|
258
|
+
share_options = {}
|
259
|
+
|
260
|
+
config.keys.each do |key|
|
261
|
+
share_options[key] = Util::Data.value(config[key])
|
262
|
+
end
|
263
|
+
|
264
|
+
#dbg(local_dir, 'vm share local')
|
265
|
+
#dbg(remote_dir, 'vm share remote')
|
266
|
+
#dbg(share_options, 'vm share options')
|
267
|
+
machine.vm.synced_folder local_dir, remote_dir, share_options
|
268
|
+
end
|
269
|
+
end
|
270
|
+
success
|
271
|
+
end
|
272
|
+
|
273
|
+
#---
|
274
|
+
|
275
|
+
def self.configure_provisioner(network, node, machine)
|
276
|
+
success = true
|
277
|
+
|
278
|
+
# CORL provisioning
|
279
|
+
machine.vm.provision :corl do |provisioner|
|
280
|
+
provisioner.network_path = CORL::Config.fact(:corl_network)
|
281
|
+
provisioner.network = network
|
282
|
+
provisioner.node = node
|
283
|
+
end
|
284
|
+
success
|
285
|
+
end
|
286
|
+
|
287
|
+
#---
|
288
|
+
|
289
|
+
def self.parse_params(data)
|
290
|
+
params = data
|
291
|
+
if data.is_a?(Hash)
|
292
|
+
params = []
|
293
|
+
data.each do |key, item|
|
294
|
+
unless Util::Data.undef?(item)
|
295
|
+
params << ( key.match(/^\:/) ? key.gsub(/^\:/, '').to_sym : key.to_s )
|
296
|
+
unless Util::Data.empty?(item)
|
297
|
+
value = item
|
298
|
+
value = ((item.is_a?(String) && item.match(/^\:/)) ? item.gsub(/^\:/, '').to_sym : item)
|
299
|
+
params << Util::Data.value(value)
|
300
|
+
end
|
301
|
+
end
|
302
|
+
end
|
303
|
+
end
|
304
|
+
params
|
305
|
+
end
|
306
|
+
end
|
307
|
+
end
|
308
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
|
2
|
+
if Vagrant::VERSION < "1.2.0"
|
3
|
+
raise "The Vagrant CORL plugin is only compatible with Vagrant 1.2+"
|
4
|
+
end
|
5
|
+
|
6
|
+
module VagrantPlugins
|
7
|
+
module CORL
|
8
|
+
class Plugin < ::Vagrant.plugin('2')
|
9
|
+
|
10
|
+
name '[C]oral [O]rchestration and [R]esearch [L]ibrary'
|
11
|
+
description 'The `corl` plugin provides an easy way to develop and test CORL networks locally from within Vagrant.'
|
12
|
+
|
13
|
+
@@command_dir = File.join(File.dirname(__FILE__), 'commands')
|
14
|
+
@@provisioner_dir = File.join(File.dirname(__FILE__), 'provisioner')
|
15
|
+
|
16
|
+
# Commands (only one, which launches Nucleon actions)
|
17
|
+
command(:corl) do
|
18
|
+
nucleon_require(@@command_dir, :launcher)
|
19
|
+
Command::Launcher # Meta command for action launcher
|
20
|
+
end
|
21
|
+
|
22
|
+
# Provisioner (we handle provisioning internally)
|
23
|
+
config(:corl, :provisioner) do
|
24
|
+
nucleon_require(@@provisioner_dir, :config)
|
25
|
+
Config::CORL
|
26
|
+
end
|
27
|
+
provisioner(:corl) do
|
28
|
+
nucleon_require(@@provisioner_dir, :provisioner)
|
29
|
+
Provisioner::CORL
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
@@ -0,0 +1,39 @@
|
|
1
|
+
|
2
|
+
module VagrantPlugins
|
3
|
+
module CORL
|
4
|
+
module Config
|
5
|
+
class CORL < ::Vagrant.plugin("2", :config)
|
6
|
+
|
7
|
+
#-----------------------------------------------------------------------------
|
8
|
+
# Constructor / Destructor
|
9
|
+
|
10
|
+
def initialize
|
11
|
+
super
|
12
|
+
@network_path = UNSET_VALUE
|
13
|
+
@network = UNSET_VALUE
|
14
|
+
@node = UNSET_VALUE
|
15
|
+
end
|
16
|
+
|
17
|
+
#---
|
18
|
+
|
19
|
+
def finalize!
|
20
|
+
super
|
21
|
+
end
|
22
|
+
|
23
|
+
#-----------------------------------------------------------------------------
|
24
|
+
# Property accessor / modifiers
|
25
|
+
|
26
|
+
attr_accessor :network_path, :network, :node
|
27
|
+
|
28
|
+
#-----------------------------------------------------------------------------
|
29
|
+
# Validation
|
30
|
+
|
31
|
+
def validate(machine)
|
32
|
+
errors = _detected_errors
|
33
|
+
{ "CORL provisioner" => errors }
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
@@ -0,0 +1,46 @@
|
|
1
|
+
|
2
|
+
module VagrantPlugins
|
3
|
+
module CORL
|
4
|
+
module Provisioner
|
5
|
+
class CORL < ::Vagrant.plugin("2", :provisioner)
|
6
|
+
|
7
|
+
#-----------------------------------------------------------------------------
|
8
|
+
# Constructor / Destructor
|
9
|
+
|
10
|
+
def initialize(machine, config)
|
11
|
+
super
|
12
|
+
end
|
13
|
+
|
14
|
+
#-----------------------------------------------------------------------------
|
15
|
+
# Operations
|
16
|
+
|
17
|
+
def configure(root_config)
|
18
|
+
end
|
19
|
+
|
20
|
+
#---
|
21
|
+
|
22
|
+
def provision
|
23
|
+
@machine.communicate.tap do |comm|
|
24
|
+
network_path = config.network_path
|
25
|
+
network = config.network
|
26
|
+
node = config.node
|
27
|
+
|
28
|
+
# Make sure the CORL network directory is properly set up
|
29
|
+
comm.sudo("rm -Rf #{network_path}")
|
30
|
+
comm.sudo("ln -s /vagrant #{network_path}")
|
31
|
+
|
32
|
+
# Make sure the CORL SSH keys are allowed
|
33
|
+
if node.public_key
|
34
|
+
ssh_key = ::CORL::Util::Disk.read(node.public_key)
|
35
|
+
|
36
|
+
if ssh_key && ! ssh_key.empty?
|
37
|
+
comm.execute("echo '#{ssh_key}' > \$HOME/.ssh/authorized_keys")
|
38
|
+
node.set_cache_setting(:use_private_key, true)
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
data/lib/corl.rb
CHANGED
@@ -20,6 +20,7 @@ mixin_action_dir = File.join(mixin_dir, 'action')
|
|
20
20
|
macro_dir = File.join(mixin_dir, 'macro')
|
21
21
|
util_dir = File.join(core_dir, 'util')
|
22
22
|
mod_dir = File.join(core_dir, 'mod')
|
23
|
+
vagrant_dir = File.join(core_dir, 'vagrant')
|
23
24
|
|
24
25
|
#-------------------------------------------------------------------------------
|
25
26
|
# CORL requirements
|
@@ -97,6 +98,13 @@ nucleon_require(core_dir, :facade)
|
|
97
98
|
# Include CORL core plugins
|
98
99
|
nucleon_require(core_dir, :plugin)
|
99
100
|
|
101
|
+
# Include Vagrant plugins (only include if running inside Vagrant)
|
102
|
+
begin
|
103
|
+
require "vagrant"
|
104
|
+
nucleon_require(vagrant_dir, :plugins)
|
105
|
+
rescue LoadError
|
106
|
+
end
|
107
|
+
|
100
108
|
#-------------------------------------------------------------------------------
|
101
109
|
# CORL interface
|
102
110
|
|
data/locales/en.yml
CHANGED
@@ -152,8 +152,20 @@ en:
|
|
152
152
|
Project reference %{value} failed to parse or provider %{provider} isn't loaded >> Possible providers: %{choices}
|
153
153
|
start: |-
|
154
154
|
Now seeding CORL node
|
155
|
+
image:
|
156
|
+
start: |-
|
157
|
+
Starting image of %{provider} machine %{name}
|
158
|
+
start:
|
159
|
+
start: |-
|
160
|
+
Starting %{provider} machine %{name}
|
161
|
+
stop:
|
162
|
+
start: |-
|
163
|
+
Stopping %{provider} machine %{name}
|
164
|
+
destroy:
|
165
|
+
start: |-
|
166
|
+
Destroying %{provider} machine %{name}
|
155
167
|
build:
|
156
|
-
start:
|
168
|
+
start: |-
|
157
169
|
Building provisioner project
|
158
170
|
provision:
|
159
171
|
options:
|