corl 0.4.1 → 0.4.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (48) hide show
  1. data/.gitmodules +1 -1
  2. data/Gemfile +1 -1
  3. data/Gemfile.lock +15 -8
  4. data/VERSION +1 -1
  5. data/bootstrap/os/ubuntu/00_base.sh +10 -1
  6. data/bootstrap/os/ubuntu/05_ruby.sh +6 -0
  7. data/bootstrap/os/ubuntu/06_puppet.sh +6 -6
  8. data/bootstrap/os/ubuntu/09_nucleon.sh +14 -0
  9. data/bootstrap/os/ubuntu/10_corl.sh +7 -2
  10. data/corl.gemspec +16 -9
  11. data/lib/CORL/action/authorize.rb +57 -0
  12. data/lib/CORL/action/bootstrap.rb +5 -0
  13. data/lib/CORL/action/destroy.rb +64 -0
  14. data/lib/CORL/action/exec.rb +9 -0
  15. data/lib/CORL/action/image.rb +39 -7
  16. data/lib/CORL/action/images.rb +4 -3
  17. data/lib/CORL/action/lookup.rb +2 -2
  18. data/lib/CORL/action/regions.rb +51 -0
  19. data/lib/CORL/action/seed.rb +1 -1
  20. data/lib/CORL/action/spawn.rb +8 -9
  21. data/lib/CORL/action/ssh.rb +74 -0
  22. data/lib/CORL/action/start.rb +37 -5
  23. data/lib/CORL/action/stop.rb +37 -5
  24. data/lib/CORL/configuration/file.rb +34 -7
  25. data/lib/CORL/event/puppet.rb +1 -1
  26. data/lib/CORL/machine/aws.rb +153 -0
  27. data/lib/CORL/machine/physical.rb +14 -5
  28. data/lib/CORL/machine/rackspace.rb +58 -0
  29. data/lib/CORL/network/default.rb +1 -1
  30. data/lib/CORL/node/aws.rb +40 -16
  31. data/lib/CORL/node/local.rb +4 -3
  32. data/lib/CORL/node/rackspace.rb +25 -7
  33. data/lib/CORL/provisioner/puppetnode.rb +11 -9
  34. data/lib/core/errors.rb +6 -0
  35. data/lib/core/mod/fog_aws_server.rb +38 -0
  36. data/lib/core/plugin/action.rb +3 -11
  37. data/lib/core/plugin/configuration.rb +20 -2
  38. data/lib/{CORL/machine/fog.rb → core/plugin/fog_machine.rb} +92 -92
  39. data/lib/core/plugin/{fog.rb → fog_node.rb} +20 -7
  40. data/lib/core/plugin/machine.rb +58 -37
  41. data/lib/core/plugin/network.rb +76 -111
  42. data/lib/core/plugin/node.rb +271 -87
  43. data/lib/core/plugin/provisioner.rb +1 -1
  44. data/lib/corl.rb +6 -14
  45. data/locales/en.yml +18 -1
  46. metadata +39 -32
  47. data/lib/CORL/node/google.rb +0 -111
  48. data/lib/core/util/ssh.rb +0 -286
@@ -1,10 +1,16 @@
1
1
 
2
2
  module CORL
3
3
  module Node
4
- class Rackspace < Node::Fog
4
+ class Rackspace < Fog
5
5
 
6
6
  #-----------------------------------------------------------------------------
7
7
  # Node plugin interface
8
+
9
+ def normalize(reload)
10
+ super do
11
+ :rackspace
12
+ end
13
+ end
8
14
 
9
15
  #-----------------------------------------------------------------------------
10
16
  # Checks
@@ -41,21 +47,33 @@ class Rackspace < Node::Fog
41
47
  end
42
48
  end
43
49
 
50
+ #---
51
+
52
+ def create_config
53
+ { :name => hostname, :flavor_id => machine_type, :image_id => image }
54
+ end
55
+
44
56
  #-----------------------------------------------------------------------------
45
57
  # Node operations
46
58
 
47
59
  def create(options = {})
48
60
  super do |op, config|
49
61
  if op == :config
50
- config.defaults({
51
- :name => hostname,
52
- :flavor_id => machine_type,
53
- :image_id => image
54
- })
62
+ config.defaults(create_config)
55
63
  end
56
64
  end
57
65
  end
58
-
66
+
67
+ #---
68
+
69
+ def start(options = {})
70
+ super do |op, config|
71
+ if op == :config
72
+ config.defaults(create_config)
73
+ end
74
+ end
75
+ end
76
+
59
77
  #-----------------------------------------------------------------------------
60
78
  # Utilities
61
79
 
@@ -6,20 +6,22 @@ class Puppetnode < CORL.plugin_class(:provisioner)
6
6
  #-----------------------------------------------------------------------------
7
7
  # Provisioner plugin interface
8
8
 
9
- def normalize
9
+ def normalize(reload)
10
10
  super
11
11
 
12
- require 'puppet'
12
+ unless reload
13
+ require 'puppet'
13
14
 
14
- if CORL.log_level == :debug
15
- Puppet.debug = true
16
- end
17
- Puppet.initialize_settings
15
+ if CORL.log_level == :debug
16
+ Puppet.debug = true
17
+ end
18
+ Puppet.initialize_settings
18
19
 
19
- myself.plugin_name = :default if plugin_name.to_sym == :puppetnode
20
+ myself.plugin_name = :default if plugin_name.to_sym == :puppetnode
20
21
 
21
- @env = Puppet::Node::Environment.new
22
- @compiler = Puppet::Parser::Compiler.new(node)
22
+ @env = Puppet::Node::Environment.new
23
+ @compiler = Puppet::Parser::Compiler.new(node)
24
+ end
23
25
 
24
26
  init_scope
25
27
  register
@@ -0,0 +1,6 @@
1
+
2
+ module CORL
3
+ module Errors
4
+
5
+ end
6
+ end
@@ -0,0 +1,38 @@
1
+ module Fog
2
+ module Compute
3
+ class AWS
4
+ class Server
5
+
6
+ def setup(credentials = {})
7
+ requires :ssh_ip_address, :username
8
+
9
+ commands = [
10
+ %{mkdir .ssh},
11
+ %{passwd -l #{username}},
12
+ %{echo "#{Fog::JSON.encode(Fog::JSON.sanitize(attributes))}" >> ~/attributes.json}
13
+ ]
14
+ if public_key
15
+ commands << %{echo "#{public_key}" >> ~/.ssh/authorized_keys}
16
+ end
17
+
18
+ tries = 5
19
+ sleep_secs = 5
20
+
21
+ begin
22
+ Nucleon::Util::SSH.session(ssh_ip_address, username, ssh_port, private_key_path, true)
23
+ results = Nucleon::Util::SSH.exec(ssh_ip_address, username, commands)
24
+
25
+ rescue Exception => error
26
+ if tries > 1
27
+ sleep(sleep_secs)
28
+ tries -= 1
29
+ retry
30
+ else
31
+ raise error
32
+ end
33
+ end
34
+ end
35
+ end
36
+ end
37
+ end
38
+ end
@@ -26,6 +26,7 @@ class CloudAction < CORL.plugin_class(:action)
26
26
  node_plugins = CORL.loaded_plugins(:node)
27
27
 
28
28
  register :parallel, :bool, true, 'corl.core.action.options.parallel'
29
+ register :net_remote, :str, :edit, 'corl.core.action.options.net_remote'
29
30
  register :net_provider, :str, :default, 'corl.core.action.options.net_provider' do |value|
30
31
  value = value.to_sym
31
32
  network_plugins = CORL.loaded_plugins(:network)
@@ -62,7 +63,7 @@ class CloudAction < CORL.plugin_class(:action)
62
63
  #---
63
64
 
64
65
  def node_ignore
65
- [ :parallel, :net_provider, :node_provider, :nodes ]
66
+ [ :parallel, :net_remote, :net_provider, :node_provider, :nodes ]
66
67
  end
67
68
 
68
69
  #-----------------------------------------------------------------------------
@@ -102,16 +103,7 @@ class CloudAction < CORL.plugin_class(:action)
102
103
  exec_config.delete(:node_provider)
103
104
 
104
105
  result = node.action(plugin_provider, exec_config) do |op, data|
105
- ui_group(node.plugin_name) do
106
- case op
107
- when :config # Modify seed execution configurations
108
- render("Starting remote execution of #{plugin_provider} action")
109
- when :process # Process final result
110
- render("Successfully finished remote execution of #{plugin_provider} action")
111
- end
112
- data = execute_remote(node, network, op, data)
113
- end
114
- data
106
+ execute_remote(node, network, op, data)
115
107
  end
116
108
  result.status == code.success
117
109
  end
@@ -8,11 +8,11 @@ class Configuration < CORL.plugin_class(:base)
8
8
  #-----------------------------------------------------------------------------
9
9
  # Configuration plugin interface
10
10
 
11
- def normalize
11
+ def normalize(reload)
12
12
  super
13
13
 
14
14
  logger.debug("Initializing source sub configuration")
15
- init_subconfig(true)
15
+ init_subconfig(true) unless reload
16
16
 
17
17
  _init(:autoload, true)
18
18
  _init(:autosave, false)
@@ -172,6 +172,24 @@ class Configuration < CORL.plugin_class(:base)
172
172
  end
173
173
  new_location
174
174
  end
175
+
176
+ #---
177
+
178
+ def delete_attachments(type, ids, options = {})
179
+ method_config = Config.ensure(options)
180
+ locations = []
181
+
182
+ if can_persist?
183
+ if extension_check(:remove_attachments, { :config => method_config })
184
+ logger.info("Removing attached data from source configuration")
185
+
186
+ locations = yield(method_config) if block_given?
187
+ end
188
+ else
189
+ logger.warn("Can not remove attached data from source configuration")
190
+ end
191
+ locations
192
+ end
175
193
  end
176
194
  end
177
195
  end
@@ -1,4 +1,8 @@
1
1
 
2
+ nucleon_require(File.dirname(__FILE__), :machine)
3
+
4
+ #---
5
+
2
6
  module CORL
3
7
  module Machine
4
8
  class Fog < CORL.plugin_class(:machine)
@@ -25,8 +29,8 @@ class Fog < CORL.plugin_class(:machine)
25
29
 
26
30
  ENV['DEBUG'] = 'true' if CORL.log_level == :debug
27
31
 
28
- require 'fog'
29
-
32
+ require 'fog'
33
+
30
34
  myself.compute = ::Fog::Compute.new(export)
31
35
  end
32
36
  protected :set_connection
@@ -45,28 +49,14 @@ class Fog < CORL.plugin_class(:machine)
45
49
  #---
46
50
 
47
51
  def server=id
52
+ @server = nil
53
+
48
54
  if id.is_a?(String)
49
- @server = compute.servers.get(id)
50
- else
55
+ @server = compute.servers.get(id) unless id.empty?
56
+ elsif ! id.nil?
51
57
  @server = id
52
- end
53
-
54
- unless @server.nil?
55
- myself.name = @server.id
56
-
57
- node[:id] = plugin_name
58
- node[:hostname] = @server.name
59
- node[:public_ip] = @server.public_ip_address
60
- node[:private_ip] = @server.private_ip_address
61
-
62
- node.machine_type = @server.flavor.id
63
- node.image = @server.image.id
64
-
65
- node.user = @server.username unless node.user
66
-
67
- @server.private_key_path = node.private_key if node.private_key
68
- @server.public_key_path = node.public_key if node.public_key
69
- end
58
+ end
59
+ init_server
70
60
  end
71
61
 
72
62
  def server
@@ -81,14 +71,7 @@ class Fog < CORL.plugin_class(:machine)
81
71
  return translate_state(server.state) if server
82
72
  nil
83
73
  end
84
-
85
- #---
86
-
87
- def hostname
88
- return server.name if server
89
- nil
90
- end
91
-
74
+
92
75
  #---
93
76
 
94
77
  def public_ip
@@ -134,18 +117,30 @@ class Fog < CORL.plugin_class(:machine)
134
117
  #-----------------------------------------------------------------------------
135
118
  # Management
136
119
 
120
+ def init_server
121
+ unless @server.nil?
122
+ yield # Implement in fog machine providers
123
+ end
124
+ end
125
+ protected :init_server
126
+
127
+ #---
128
+
137
129
  def load
138
130
  super do
139
- myself.server = plugin_name if compute && ! plugin_name.empty?
140
- server.nil? ? false : true
131
+ myself.server = plugin_name if compute && plugin_name
132
+ ! plugin_name && @server.nil? ? false : true
141
133
  end
142
134
  end
143
135
 
144
136
  #---
145
137
 
146
138
  def create(options = {})
147
- super do
148
- myself.server = compute.servers.bootstrap(Config.ensure(options).export) if compute
139
+ super do |config|
140
+ if compute
141
+ yield(config) if block_given?
142
+ myself.server = compute.servers.bootstrap(config.export)
143
+ end
149
144
  myself.server ? true : false
150
145
  end
151
146
  end
@@ -157,7 +152,7 @@ class Fog < CORL.plugin_class(:machine)
157
152
  logger.debug("Executing SCP download to #{local_path} from #{remote_path} on machine #{name}")
158
153
 
159
154
  begin
160
- if init_ssh_session
155
+ if init_ssh_session(server)
161
156
  Util::SSH.download(node.public_ip, node.user, remote_path, local_path, config.export) do |name, received, total|
162
157
  yield(name, received, total) if block_given?
163
158
  end
@@ -176,10 +171,10 @@ class Fog < CORL.plugin_class(:machine)
176
171
 
177
172
  def upload(local_path, remote_path, options = {})
178
173
  super do |config, success|
179
- logger.debug("Executing SCP upload from #{local_path} to #{remote_path} on machine #{name}")
174
+ logger.debug("Executing SCP upload from #{local_path} to #{remote_path} on machine #{plugin_name}")
180
175
 
181
176
  begin
182
- if init_ssh_session
177
+ if init_ssh_session(server)
183
178
  Util::SSH.upload(node.public_ip, node.user, local_path, remote_path, config.export) do |name, sent, total|
184
179
  yield(name, sent, total) if block_given?
185
180
  end
@@ -199,9 +194,9 @@ class Fog < CORL.plugin_class(:machine)
199
194
  def exec(commands, options = {})
200
195
  super do |config, results|
201
196
  if commands
202
- logger.debug("Executing SSH commands ( #{commands.inspect} ) on machine #{name}")
197
+ logger.debug("Executing SSH commands ( #{commands.inspect} ) on machine #{plugin_name}")
203
198
 
204
- if init_ssh_session
199
+ if init_ssh_session(server)
205
200
  results = Util::SSH.exec(node.public_ip, node.user, commands) do |type, command, data|
206
201
  yield(type, command, data) if block_given?
207
202
  end
@@ -215,72 +210,51 @@ class Fog < CORL.plugin_class(:machine)
215
210
 
216
211
  #---
217
212
 
218
- def start(options = {})
219
- super do
220
- if compute
221
- server_info = compute.servers.create(options)
222
-
223
- logger.info("Waiting for #{plugin_provider} machine to start")
224
- ::Fog.wait_for do
225
- compute.servers.get(server_info.id).ready? ? true : false
226
- end
227
-
228
- logger.debug("Setting machine #{server_info.id}")
229
-
230
- myself.server = compute.servers.get(server_info.id)
231
- myself.server ? true : false
232
- else
233
- false
234
- end
213
+ def terminal(user, options = {})
214
+ super do |config|
215
+ Util::SSH.terminal(node.public_ip, user, config.export)
235
216
  end
236
217
  end
237
218
 
238
219
  #---
239
220
 
240
221
  def reload(options = {})
241
- super do
222
+ super do |config|
223
+ success = false
242
224
  if server
243
- logger.debug("Rebooting machine #{name}")
244
- server.reboot(options)
245
- else
246
- false
247
- end
225
+ success = block_given? ? yield(config) : true
226
+ success = init_ssh_session(server, true, config.get(:tries, 5), config.get(:sleep_time, 5)) if success
227
+ end
228
+ success
248
229
  end
249
230
  end
250
231
 
251
232
  #---
252
233
 
253
- def create_image(name, options = {})
254
- super do
234
+ def create_image(options = {})
235
+ super do |config|
236
+ success = false
255
237
  if server
256
- logger.debug("Imaging machine #{self.name}")
257
- image = server.create_image(name, options)
258
-
259
- if image
260
- node.image = image.id
261
- true
262
- else
263
- false
264
- end
265
- else
266
- false
238
+ logger.debug("Imaging machine #{plugin_name}")
239
+
240
+ image_name = sprintf("%s (%s)", node.plugin_name, Time.now.to_s)
241
+ success = yield(image_name, config, success) if block_given? # Implement in sub classes
242
+ success = init_ssh_session(server, true, config.get(:tries, 5), config.get(:sleep_time, 5)) if success
267
243
  end
244
+ success
268
245
  end
269
246
  end
270
247
 
271
248
  #---
272
249
 
273
250
  def stop(options = {})
274
- super do
251
+ super do |config|
275
252
  success = true
276
- if image_id = create_image(name)
277
- logger.info("Waiting for #{plugin_provider} machine to finish creating image: #{image_id}")
278
- ::Fog.wait_for do
279
- compute.images.get(image_id).ready? ? true : false
280
- end
281
-
282
- logger.debug("Detroying machine #{name}")
283
- success = server.destroy
253
+ if server && create_image(config)
254
+ logger.debug("Stopping machine #{plugin_name}")
255
+ success = destroy(config.import({ :stop => true }))
256
+ else
257
+ success = false
284
258
  end
285
259
  success
286
260
  end
@@ -289,21 +263,47 @@ class Fog < CORL.plugin_class(:machine)
289
263
  #---
290
264
 
291
265
  def destroy(options = {})
292
- super do
266
+ super do |config|
267
+ success = false
293
268
  if server
294
- logger.debug("Destroying machine #{name}")
295
- server.destroy(options)
296
- else
297
- false
298
- end
269
+ logger.debug("Destroying machine #{plugin_name}")
270
+ success = server.destroy
271
+ success = yield(config) if success && block_given?
272
+ end
273
+ close_ssh_session if success
274
+ success
299
275
  end
300
276
  end
301
277
 
302
278
  #-----------------------------------------------------------------------------
303
279
  # Utilities
304
280
 
305
- def init_ssh_session
306
- Util::SSH.session(node.public_ip, node.user, node.ssh_port, node.private_key)
281
+ def init_ssh_session(server, reset = false, tries = 5, sleep_secs = 5)
282
+ server.wait_for { ready? }
283
+
284
+ success = true
285
+
286
+ begin
287
+ Util::SSH.session(node.public_ip, node.user, node.ssh_port, node.private_key, reset)
288
+
289
+ rescue Exception => error
290
+ if tries > 1
291
+ sleep(sleep_secs)
292
+
293
+ tries -= 1
294
+ reset = true
295
+ retry
296
+ else
297
+ success = false
298
+ end
299
+ end
300
+ success
301
+ end
302
+
303
+ #---
304
+
305
+ def close_ssh_session
306
+ Util::SSH.close_session(node.public_ip, node.user)
307
307
  end
308
308
  end
309
309
  end
@@ -10,12 +10,17 @@ class Fog < CORL.plugin_class(:node)
10
10
  #-----------------------------------------------------------------------------
11
11
  # Node plugin interface
12
12
 
13
- def normalize
14
- super
15
- myself.region = region
16
-
17
- yield if block_given?
18
- myself.machine = create_machine(:machine, :fog, machine_config)
13
+ def normalize(reload)
14
+ super do
15
+ myself.region = region
16
+
17
+ unless reload
18
+ machine_provider = :fog
19
+ machine_provider = yield if block_given?
20
+
21
+ myself.machine = create_machine(:machine, machine_provider, machine_config)
22
+ end
23
+ end
19
24
  end
20
25
 
21
26
  #-----------------------------------------------------------------------------
@@ -94,6 +99,12 @@ class Fog < CORL.plugin_class(:node)
94
99
 
95
100
  #---
96
101
 
102
+ def key_config
103
+ { :private_key_path => private_key, :public_key_path => public_key }
104
+ end
105
+
106
+ #---
107
+
97
108
  def exec_options(name, options = {})
98
109
  extended_config(name, options).export
99
110
  end
@@ -105,8 +116,9 @@ class Fog < CORL.plugin_class(:node)
105
116
  super do |op, config|
106
117
  if op == :config
107
118
  config.import(exec_options(:create))
119
+ config.defaults(key_config)
108
120
  end
109
- yield(op, config) if block_given?
121
+ yield(op, config) if block_given?
110
122
  end
111
123
  end
112
124
 
@@ -149,6 +161,7 @@ class Fog < CORL.plugin_class(:node)
149
161
  super do |op, config|
150
162
  if op == :config
151
163
  config.import(exec_options(:start))
164
+ config.defaults(key_config)
152
165
  end
153
166
  yield(op, config) if block_given?
154
167
  end