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.
Files changed (53) hide show
  1. checksums.yaml +7 -0
  2. data/Gemfile +6 -1
  3. data/Gemfile.lock +76 -30
  4. data/Rakefile +1 -1
  5. data/VERSION +1 -1
  6. data/bootstrap/bootstrap.sh +5 -2
  7. data/bootstrap/os/ubuntu/00_base.sh +1 -1
  8. data/bootstrap/os/ubuntu/01_git.sh +9 -0
  9. data/bootstrap/os/ubuntu/05_ruby.sh +7 -4
  10. data/bootstrap/os/ubuntu/06_puppet.sh +2 -2
  11. data/corl.gemspec +23 -9
  12. data/lib/CORL/action/authorize.rb +2 -5
  13. data/lib/CORL/action/bootstrap.rb +1 -5
  14. data/lib/CORL/action/build.rb +2 -10
  15. data/lib/CORL/action/destroy.rb +2 -7
  16. data/lib/CORL/action/exec.rb +1 -5
  17. data/lib/CORL/action/image.rb +1 -5
  18. data/lib/CORL/action/images.rb +12 -10
  19. data/lib/CORL/action/ip.rb +21 -0
  20. data/lib/CORL/action/lookup.rb +5 -3
  21. data/lib/CORL/action/machines.rb +12 -10
  22. data/lib/CORL/action/provision.rb +4 -7
  23. data/lib/CORL/action/regions.rb +12 -10
  24. data/lib/CORL/action/seed.rb +9 -10
  25. data/lib/CORL/action/spawn.rb +29 -15
  26. data/lib/CORL/action/ssh.rb +1 -5
  27. data/lib/CORL/action/start.rb +1 -5
  28. data/lib/CORL/action/stop.rb +1 -5
  29. data/lib/CORL/action/vagrantfile.rb +55 -0
  30. data/lib/CORL/configuration/file.rb +4 -1
  31. data/lib/CORL/machine/physical.rb +1 -1
  32. data/lib/CORL/machine/vagrant.rb +358 -0
  33. data/lib/CORL/node/local.rb +2 -3
  34. data/lib/CORL/node/vagrant.rb +238 -0
  35. data/lib/core/facade.rb +25 -2
  36. data/lib/core/mixin/macro/network_settings.rb +35 -1
  37. data/lib/core/plugin/action.rb +53 -5
  38. data/lib/core/plugin/configuration.rb +19 -5
  39. data/lib/core/plugin/fog_machine.rb +1 -1
  40. data/lib/core/plugin/fog_node.rb +9 -9
  41. data/lib/core/plugin/machine.rb +6 -13
  42. data/lib/core/plugin/network.rb +23 -7
  43. data/lib/core/plugin/node.rb +69 -36
  44. data/lib/core/plugin/provisioner.rb +1 -2
  45. data/lib/core/vagrant/Vagrantfile +7 -0
  46. data/lib/core/vagrant/commands/launcher.rb +66 -0
  47. data/lib/core/vagrant/config.rb +308 -0
  48. data/lib/core/vagrant/plugins.rb +33 -0
  49. data/lib/core/vagrant/provisioner/config.rb +39 -0
  50. data/lib/core/vagrant/provisioner/provisioner.rb +46 -0
  51. data/lib/corl.rb +8 -0
  52. data/locales/en.yml +13 -1
  53. 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: