corl 0.4.15 → 0.4.16

Sign up to get free protection for your applications and to get access to all the features.
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: