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,358 @@
1
+
2
+ module CORL
3
+ module Machine
4
+ class Vagrant < CORL.plugin_class(:machine)
5
+
6
+ @@lock = Mutex.new
7
+
8
+ #-----------------------------------------------------------------------------
9
+ # Checks
10
+
11
+ def created?
12
+ server && state != :not_created
13
+ end
14
+
15
+ #---
16
+
17
+ def running?
18
+ server && state == :running
19
+ end
20
+
21
+ #-----------------------------------------------------------------------------
22
+ # Property accessors / modifiers
23
+
24
+ def set_command
25
+ @command = nil
26
+
27
+ begin
28
+ # Ensure we are running within Vagrant from the corl base command
29
+ require 'vagrant'
30
+
31
+ logger.info("Setting up Vagrant for machine")
32
+ @command = CORL::Vagrant.command
33
+
34
+ rescue LoadError
35
+ end
36
+ end
37
+ protected :set_command
38
+
39
+ #---
40
+
41
+ def command
42
+ set_command unless @command
43
+ @command
44
+ end
45
+
46
+ #---
47
+
48
+ def env
49
+ return command.env if command
50
+ nil
51
+ end
52
+
53
+ #---
54
+
55
+ def server=id
56
+ @server = nil
57
+
58
+ if id.is_a?(String)
59
+ @server = new_machine(id)
60
+ elsif ! id.nil?
61
+ @server = id
62
+ end
63
+ end
64
+
65
+ def server
66
+ command
67
+ load unless @server
68
+ @server
69
+ end
70
+
71
+ #---
72
+
73
+ def state
74
+ return server.state.id if server
75
+ :not_loaded
76
+ end
77
+
78
+ #---
79
+
80
+ def machine_types
81
+ [ :virtualbox, :vmware_fusion, :hyperv ]
82
+ end
83
+
84
+ #-----------------------------------------------------------------------------
85
+ # Management
86
+
87
+ def load
88
+ super do
89
+ myself.server = plugin_name if command && plugin_name
90
+ ! plugin_name && @server.nil? ? false : true
91
+ end
92
+ end
93
+
94
+ #---
95
+
96
+ def create(options = {})
97
+ super do |config|
98
+ start_machine(config)
99
+ end
100
+ end
101
+
102
+ #---
103
+
104
+ def download(remote_path, local_path, options = {})
105
+ super do |config, success|
106
+ begin
107
+ server.communicate.tap do |comm|
108
+ comm.download(remote_path, local_path)
109
+ end
110
+ success = true
111
+
112
+ rescue Exception => error
113
+ ui.error(error.message)
114
+ success = false
115
+ end
116
+ success
117
+ end
118
+ end
119
+
120
+ #---
121
+
122
+ def upload(local_path, remote_path, options = {})
123
+ super do |config, success|
124
+ begin
125
+ server.communicate.tap do |comm|
126
+ comm.upload(local_path, remote_path)
127
+ end
128
+ success = true
129
+
130
+ rescue Exception => error
131
+ ui.error(error.message)
132
+ success = false
133
+ end
134
+ success
135
+ end
136
+ end
137
+
138
+ #---
139
+
140
+ def exec(commands, options = {})
141
+ super do |config, results|
142
+ codes :vagrant_exec_failed
143
+
144
+ begin
145
+ server.communicate.tap do |comm|
146
+ commands.each do |command|
147
+ as_admin = command.match(/^sudo\s+/) ? true : false
148
+ result = Util::Shell::Result.new(command.gsub(/^sudo\s+/, '').strip)
149
+
150
+ result.status = comm.execute(result.command, { :sudo => as_admin }) do |type, data|
151
+ case type
152
+ when :stdout
153
+ result.append_output(data)
154
+ yield(:output, result.command, data) if block_given?
155
+ when :stderr
156
+ result.append_errors(data)
157
+ yield(:error, result.command, data) if block_given?
158
+ end
159
+ end
160
+ results << result
161
+ end
162
+ end
163
+
164
+ rescue Exception => error
165
+ ui.error(error.message)
166
+ results << Util::Shell::Result.new(command, code.vagrant_exec_failed)
167
+ end
168
+ results
169
+ end
170
+ end
171
+
172
+ #---
173
+
174
+ def terminal(user, options = {})
175
+ super do |config|
176
+ run(:ssh, { :ssh_opts => config.export })
177
+ end
178
+ end
179
+
180
+ #---
181
+
182
+ def reload(options = {})
183
+ super do |config|
184
+ run(:reload, config)
185
+ end
186
+ end
187
+
188
+ #---
189
+
190
+ def create_image(options = {})
191
+ super do |config|
192
+ stop = config.delete(:stop, false)
193
+
194
+ # TODO: Decide how to handle versions??
195
+ # Timestamps stink since these things are huge (>600MB)
196
+ box_name = sprintf("%s", node.id).gsub(/\s+/, '-')
197
+ box_path = File.join(node.network.directory, 'boxes', "#{box_name}.box")
198
+ box_url = "file://#{box_path}"
199
+ FileUtils.mkdir_p(File.dirname(box_path))
200
+ FileUtils.rm_f(box_path)
201
+
202
+ begin
203
+ success = run(:package, config.defaults({ 'package.output' => box_path }), false)
204
+
205
+ node.set_cache_setting(:box, box_name)
206
+ node.set_cache_setting(:box_url, box_url)
207
+
208
+ if success
209
+ env.action_runner.run(::Vagrant::Action.action_box_add, {
210
+ :box_name => box_name,
211
+ :box_url => box_url,
212
+ :box_clean => false,
213
+ :box_force => true,
214
+ :ui => ::Vagrant::UI::Prefixed.new(env.ui, "box")
215
+ })
216
+ load
217
+ end
218
+
219
+ rescue Exception => error
220
+ ui.error(error.message)
221
+ success = false
222
+ end
223
+
224
+ success = run(:up, config) if success && ! stop
225
+ success
226
+ end
227
+ end
228
+
229
+ #---
230
+
231
+ def stop(options = {})
232
+ super do |config|
233
+ create_image(config.import({ :stop => true }))
234
+ end
235
+ end
236
+
237
+ #---
238
+
239
+ def start(options = {})
240
+ super do |config|
241
+ start_machine(config)
242
+ end
243
+ end
244
+
245
+ #---
246
+
247
+ def destroy(options = {})
248
+ super do |config|
249
+ # We should handle prompting internally to keep it consistent
250
+ success = run(:destroy, config.defaults({ :force_confirm_destroy => true }))
251
+
252
+ if success
253
+ box_name = sprintf("%s", node.id).gsub(/\s+/, '-')
254
+ found = false
255
+
256
+ # TODO: Figure out box versions.
257
+
258
+ env.boxes.all.each do |info|
259
+ registered_box_name = info[0]
260
+ registered_box_version = info[1]
261
+ registered_box_provider = info[2]
262
+
263
+ if box_name == registered_box_name
264
+ found = true
265
+ break
266
+ end
267
+ end
268
+
269
+ if found
270
+ env.action_runner.run(::Vagrant::Action.action_box_remove, {
271
+ :box_name => box_name,
272
+ :box_provider => node.machine_type
273
+ })
274
+
275
+ box_name = sprintf("%s", node.id).gsub(/\s+/, '-')
276
+ box_path = File.join(node.network.directory, 'boxes', "#{box_name}.box")
277
+ Util::Disk.delete(box_path)
278
+ end
279
+ end
280
+ success
281
+ end
282
+ end
283
+
284
+ #-----------------------------------------------------------------------------
285
+ # Utilities
286
+
287
+ def refresh_config
288
+ if env
289
+ @@lock.synchronize do
290
+ begin
291
+ CORL::Vagrant::Config.network = node.network
292
+ env.vagrantfile.reload
293
+ ensure
294
+ CORL::Vagrant::Config.network = nil
295
+ end
296
+ end
297
+ end
298
+ end
299
+ protected :refresh_config
300
+
301
+ #---
302
+
303
+ def new_machine(id)
304
+ server = nil
305
+ if command && ! id.empty?
306
+ refresh_config
307
+ if env.vagrantfile.machine_names.include?(id.to_sym)
308
+ server = command.vm_machine(id.to_sym, node.machine_type, true)
309
+ end
310
+ end
311
+ server
312
+ end
313
+ protected :new_machine
314
+
315
+ #---
316
+
317
+ def start_machine(options)
318
+ success = false
319
+
320
+ if server
321
+ load
322
+ success = run(:up, options)
323
+
324
+ # Make sure provisioner changes (key changes) are accounted for
325
+ # TODO: Is there a better way?
326
+ load if success
327
+ end
328
+ success
329
+ end
330
+ protected :start_machine
331
+
332
+ #---
333
+
334
+ def run(action, options = {}, symbolize_keys = true)
335
+ config = Config.ensure(options)
336
+
337
+ if server
338
+ logger.debug("Running Vagrant action #{action} on machine #{node.id}")
339
+
340
+ success = true
341
+ begin
342
+ params = config.export
343
+ params = string_map(params) unless symbolize_keys
344
+
345
+ server.send(:action, action.to_sym, params)
346
+
347
+ rescue Exception => error
348
+ ui.error(error)
349
+ ui.error(Util::Data.to_yaml(error.backtrace))
350
+ success = false
351
+ end
352
+ end
353
+ success
354
+ end
355
+ protected :run
356
+ end
357
+ end
358
+ end
@@ -7,9 +7,8 @@ class Local < CORL.plugin_class(:node)
7
7
  # Node plugin interface
8
8
 
9
9
  def normalize(reload)
10
- super do
11
- myself.machine = create_machine(:machine, :physical, machine_config)
12
- end
10
+ super
11
+ myself.machine = create_machine(:machine, :physical, machine_config)
13
12
  end
14
13
 
15
14
  #-----------------------------------------------------------------------------
@@ -0,0 +1,238 @@
1
+
2
+ module CORL
3
+ module Node
4
+ class Vagrant < CORL.plugin_class(:node)
5
+
6
+ #-----------------------------------------------------------------------------
7
+ # Node plugin interface
8
+
9
+ def normalize(reload)
10
+ super
11
+
12
+ unless reload
13
+ machine_provider = :vagrant
14
+ machine_provider = yield if block_given?
15
+
16
+ myself.machine = create_machine(:machine, machine_provider, machine_config)
17
+ end
18
+
19
+ network.ignore([ '.vagrant', 'boxes' ])
20
+ init_shares
21
+ end
22
+
23
+ #-----------------------------------------------------------------------------
24
+ # Checks
25
+
26
+ #-----------------------------------------------------------------------------
27
+ # Property accessors / modifiers
28
+
29
+ def state(reset = false)
30
+ machine.state
31
+ end
32
+
33
+ #---
34
+
35
+ def vm=vm
36
+ myself[:vm] = vm
37
+ end
38
+
39
+ def vm
40
+ hash(myself[:vm])
41
+ end
42
+
43
+ #---
44
+
45
+ def ssh=ssh
46
+ myself[:ssh] = ssh
47
+ end
48
+
49
+ def ssh
50
+ hash(myself[:ssh])
51
+ end
52
+
53
+ #---
54
+
55
+ def shares=shares
56
+ myself[:shares] = shares
57
+ init_shares
58
+ end
59
+
60
+ def shares
61
+ hash(myself[:shares])
62
+ end
63
+
64
+ #-----------------------------------------------------------------------------
65
+ # Settings groups
66
+
67
+ def machine_config
68
+ super do |config|
69
+ config[:vm] = vm
70
+ config[:shares] = shares
71
+
72
+ yield(config) if block_given?
73
+ end
74
+ end
75
+
76
+ #---
77
+
78
+ def exec_options(name, options = {})
79
+ extended_config(name, options).export
80
+ end
81
+
82
+ #-----------------------------------------------------------------------------
83
+ # Node operations
84
+
85
+ def create(options = {})
86
+ super do |op, config|
87
+ if op == :config
88
+ config.import(exec_options(:create))
89
+ end
90
+ end
91
+ end
92
+
93
+ #---
94
+
95
+ def download(remote_path, local_path, options = {})
96
+ super do |op, config|
97
+ if op == :config
98
+ config.import(exec_options(:download))
99
+ end
100
+ end
101
+ end
102
+
103
+ #---
104
+
105
+ def upload(local_path, remote_path, options = {})
106
+ super do |op, config|
107
+ if op == :config
108
+ config.import(exec_options(:upload))
109
+ end
110
+ end
111
+ end
112
+
113
+ #---
114
+
115
+ def exec(options = {})
116
+ super do |op, config|
117
+ if op == :config
118
+ config.import(exec_options(:exec))
119
+ end
120
+ end
121
+ end
122
+
123
+ #---
124
+
125
+ def save(options = {})
126
+ super do
127
+ id(true)
128
+ delete_setting(:machine_type)
129
+ end
130
+ end
131
+
132
+ #---
133
+
134
+ def start(options = {})
135
+ super do |op, config|
136
+ if op == :config
137
+ config.import(exec_options(:start))
138
+ end
139
+ end
140
+ end
141
+
142
+ #---
143
+
144
+ def reload(options = {})
145
+ super do |op, config|
146
+ if op == :config
147
+ config.import(exec_options(:reload))
148
+ end
149
+ end
150
+ end
151
+
152
+ #---
153
+
154
+ def create_image(options = {})
155
+ super do |op, config|
156
+ if op == :config
157
+ config.import(exec_options(:image))
158
+ end
159
+ end
160
+ end
161
+
162
+ #---
163
+
164
+ def stop(options = {})
165
+ super do |op, config|
166
+ if op == :config
167
+ config.import(exec_options(:stop))
168
+ elsif op == :finalize
169
+ true
170
+ end
171
+ end
172
+ end
173
+
174
+ #---
175
+
176
+ def destroy(options = {})
177
+ super do |op, config|
178
+ if op == :config
179
+ config.import(exec_options(:destroy))
180
+ end
181
+ end
182
+ end
183
+
184
+ #-----------------------------------------------------------------------------
185
+ # Utilities
186
+
187
+ def init_shares
188
+ shares.each do |name, info|
189
+ local_dir = info[:local]
190
+ network.ignore(local_dir)
191
+ end
192
+ end
193
+
194
+ #---
195
+
196
+ def filter_output(type, data)
197
+ if type == :error
198
+ if data.include?('stdin: is not a tty') || data.include?('unable to re-open stdin')
199
+ data = ''
200
+ end
201
+ end
202
+ data
203
+ end
204
+
205
+ #-----------------------------------------------------------------------------
206
+ # Machine type utilities
207
+
208
+ def machine_type_id(machine_type)
209
+ machine_type
210
+ end
211
+
212
+ #---
213
+
214
+ def render_machine_type(machine_type)
215
+ machine_type.to_s
216
+ end
217
+
218
+ #-----------------------------------------------------------------------------
219
+ # Image utilities
220
+
221
+ def image_id(image)
222
+ image.id
223
+ end
224
+
225
+ #---
226
+
227
+ def render_image(image)
228
+ ''
229
+ end
230
+
231
+ #---
232
+
233
+ def image_search_text(image)
234
+ image.to_s
235
+ end
236
+ end
237
+ end
238
+ end
data/lib/core/facade.rb CHANGED
@@ -1,6 +1,31 @@
1
1
 
2
2
  module CORL
3
3
  module Facade
4
+
5
+ #-----------------------------------------------------------------------------
6
+ # Local identification
7
+
8
+ def public_ip
9
+ if Config.fact(:vagrant_exists)
10
+ Config.fact(:ipaddress_eth1)
11
+ else
12
+ CORL.ip_address
13
+ end
14
+ end
15
+
16
+ #-----------------------------------------------------------------------------
17
+ # Vagrant related
18
+
19
+ def vagrant?
20
+ Vagrant.command ? true : false
21
+ end
22
+
23
+ #---
24
+
25
+ def vagrant_config(directory, config)
26
+ require File.join(File.dirname(__FILE__), 'vagrant', 'config.rb')
27
+ Vagrant::Config.register(directory, config)
28
+ end
4
29
 
5
30
  #-----------------------------------------------------------------------------
6
31
  # Core plugin type facade
@@ -40,8 +65,6 @@ module Facade
40
65
  plugin(:provisioner, provider, options)
41
66
  end
42
67
 
43
- #---
44
-
45
68
  def provisioners(data, build_hash = false, keep_array = false)
46
69
  plugins(:provisioner, data, build_hash, keep_array)
47
70
  end
@@ -48,9 +48,43 @@ module NetworkSettings
48
48
 
49
49
  #---
50
50
 
51
+ define_method :cache do
52
+ network.cache
53
+ end
54
+
55
+ define_method :cache_setting do |keys, default = nil, format = false|
56
+ cache.get([ _type, plugin_provider, plugin_name, keys ].flatten, default, format)
57
+ end
58
+
59
+ define_method :set_cache_setting do |keys, value|
60
+ cache.set([ _type, plugin_provider, plugin_name, keys ].flatten, value)
61
+ end
62
+
63
+ define_method :delete_cache_setting do |keys|
64
+ cache.delete([ _type, plugin_provider, plugin_name, keys ].flatten)
65
+ end
66
+
67
+ define_method :clear_cache do
68
+ cache.delete([ _type, plugin_provider, plugin_name ])
69
+ end
70
+
71
+ #---
72
+
51
73
  define_method :groups do
52
74
  array(myself[:settings])
53
- end
75
+ end
76
+
77
+ #---
78
+
79
+ define_method :add_groups do |groups|
80
+ myself[:settings] = array(myself[:settings]) | array(groups)
81
+ end
82
+
83
+ #---
84
+
85
+ define_method :remove_groups do |groups|
86
+ myself[:settings] = array(myself[:settings]) - array(groups)
87
+ end
54
88
  end
55
89
  end
56
90
  end