nucleon 0.1.3 → 0.1.4
Sign up to get free protection for your applications and to get access to all the features.
- data/Gemfile +7 -3
- data/Gemfile.lock +10 -6
- data/VERSION +1 -1
- data/lib/core/config.rb +9 -5
- data/lib/core/errors.rb +6 -0
- data/lib/core/facade.rb +12 -1
- data/lib/core/manager.rb +23 -13
- data/lib/core/mixin/macro/object_interface.rb +42 -36
- data/lib/core/mixin/macro/plugin_interface.rb +13 -18
- data/lib/core/plugin/action.rb +6 -4
- data/lib/core/plugin/base.rb +3 -3
- data/lib/core/plugin/command.rb +1 -1
- data/lib/core/plugin/project.rb +31 -13
- data/lib/core/util/cli.rb +7 -7
- data/lib/core/util/data.rb +3 -2
- data/lib/core/util/disk.rb +4 -1
- data/lib/core/util/shell.rb +15 -11
- data/lib/core/util/ssh.rb +356 -0
- data/lib/nucleon/command/bash.rb +1 -1
- data/lib/nucleon/event/regex.rb +1 -1
- data/lib/nucleon/project/git.rb +3 -3
- data/lib/nucleon/project/github.rb +6 -11
- data/lib/nucleon_base.rb +8 -2
- data/nucleon.gemspec +12 -8
- metadata +55 -43
data/Gemfile
CHANGED
@@ -2,14 +2,18 @@ source "http://rubygems.org"
|
|
2
2
|
|
3
3
|
gem "log4r", "~> 1.1"
|
4
4
|
gem "i18n", "~> 0.6"
|
5
|
-
gem "rgen", "~> 0.6"
|
6
5
|
gem "netrc", "~> 0.7"
|
7
|
-
gem "deep_merge", "~> 1.0"
|
8
6
|
|
7
|
+
gem "deep_merge", "~> 1.0"
|
9
8
|
gem "multi_json", "~> 1.7"
|
9
|
+
|
10
|
+
gem "sshkey", "~> 1.6"
|
11
|
+
|
12
|
+
gem "childprocess", "~> 0.5.0"
|
13
|
+
gem "celluloid", "~> 0.15"
|
14
|
+
|
10
15
|
gem "grit", "~> 2.5"
|
11
16
|
gem "octokit", "~> 2.7"
|
12
|
-
gem "celluloid", "~> 0.15"
|
13
17
|
|
14
18
|
group :development do
|
15
19
|
gem "bundler", "~> 1.2"
|
data/Gemfile.lock
CHANGED
@@ -5,11 +5,14 @@ GEM
|
|
5
5
|
builder (3.2.2)
|
6
6
|
celluloid (0.15.2)
|
7
7
|
timers (~> 1.1.0)
|
8
|
+
childprocess (0.5.1)
|
9
|
+
ffi (~> 1.0, >= 1.0.11)
|
8
10
|
deep_merge (1.0.1)
|
9
11
|
descendants_tracker (0.0.3)
|
10
12
|
diff-lcs (1.2.5)
|
11
13
|
faraday (0.9.0)
|
12
14
|
multipart-post (>= 1.2, < 3)
|
15
|
+
ffi (1.9.3)
|
13
16
|
git (1.2.6)
|
14
17
|
github_api (0.11.3)
|
15
18
|
addressable (~> 2.3)
|
@@ -24,7 +27,7 @@ GEM
|
|
24
27
|
mime-types (~> 1.15)
|
25
28
|
posix-spawn (~> 0.3.6)
|
26
29
|
hashie (2.0.5)
|
27
|
-
highline (1.6.
|
30
|
+
highline (1.6.21)
|
28
31
|
i18n (0.6.9)
|
29
32
|
jeweler (2.0.1)
|
30
33
|
builder
|
@@ -41,7 +44,7 @@ GEM
|
|
41
44
|
log4r (1.1.10)
|
42
45
|
mime-types (1.25.1)
|
43
46
|
mini_portile (0.5.2)
|
44
|
-
multi_json (1.
|
47
|
+
multi_json (1.9.0)
|
45
48
|
multi_xml (0.5.5)
|
46
49
|
multipart-post (2.0.0)
|
47
50
|
netrc (0.7.7)
|
@@ -53,25 +56,25 @@ GEM
|
|
53
56
|
multi_json (~> 1.3)
|
54
57
|
multi_xml (~> 0.5)
|
55
58
|
rack (~> 1.2)
|
56
|
-
octokit (2.7.
|
59
|
+
octokit (2.7.2)
|
57
60
|
sawyer (~> 0.5.2)
|
58
61
|
posix-spawn (0.3.8)
|
59
62
|
rack (1.5.2)
|
60
63
|
rake (10.1.1)
|
61
64
|
rdoc (3.12.2)
|
62
65
|
json (~> 1.4)
|
63
|
-
rgen (0.6.6)
|
64
66
|
rspec (2.14.1)
|
65
67
|
rspec-core (~> 2.14.0)
|
66
68
|
rspec-expectations (~> 2.14.0)
|
67
69
|
rspec-mocks (~> 2.14.0)
|
68
|
-
rspec-core (2.14.
|
70
|
+
rspec-core (2.14.8)
|
69
71
|
rspec-expectations (2.14.5)
|
70
72
|
diff-lcs (>= 1.1.3, < 2.0)
|
71
73
|
rspec-mocks (2.14.6)
|
72
74
|
sawyer (0.5.3)
|
73
75
|
addressable (~> 2.3.5)
|
74
76
|
faraday (~> 0.8, < 0.10)
|
77
|
+
sshkey (1.6.1)
|
75
78
|
timers (1.1.0)
|
76
79
|
yard (0.8.7.3)
|
77
80
|
|
@@ -81,6 +84,7 @@ PLATFORMS
|
|
81
84
|
DEPENDENCIES
|
82
85
|
bundler (~> 1.2)
|
83
86
|
celluloid (~> 0.15)
|
87
|
+
childprocess (~> 0.5.0)
|
84
88
|
deep_merge (~> 1.0)
|
85
89
|
grit (~> 2.5)
|
86
90
|
i18n (~> 0.6)
|
@@ -90,6 +94,6 @@ DEPENDENCIES
|
|
90
94
|
netrc (~> 0.7)
|
91
95
|
octokit (~> 2.7)
|
92
96
|
rdoc (~> 3.12)
|
93
|
-
rgen (~> 0.6)
|
94
97
|
rspec (~> 2.10)
|
98
|
+
sshkey (~> 1.6)
|
95
99
|
yard (~> 0.8)
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.1.
|
1
|
+
0.1.4
|
data/lib/core/config.rb
CHANGED
@@ -80,19 +80,18 @@ class Config
|
|
80
80
|
|
81
81
|
#---
|
82
82
|
|
83
|
-
def fetch(data, keys, default = nil, format = false)
|
83
|
+
def fetch(data, keys, default = nil, format = false)
|
84
84
|
if keys.is_a?(String) || keys.is_a?(Symbol)
|
85
85
|
keys = [ keys ]
|
86
86
|
end
|
87
87
|
key = keys.shift.to_sym
|
88
|
-
|
89
88
|
if data.has_key?(key)
|
90
89
|
value = data[key]
|
91
90
|
|
92
91
|
if keys.empty?
|
93
92
|
return filter(value, format)
|
94
93
|
else
|
95
|
-
return fetch(data[key], keys, default, format)
|
94
|
+
return fetch(data[key], keys, default, format) if data[key].is_a?(Hash)
|
96
95
|
end
|
97
96
|
end
|
98
97
|
return filter(default, format)
|
@@ -105,7 +104,7 @@ class Config
|
|
105
104
|
if keys.is_a?(String) || keys.is_a?(Symbol)
|
106
105
|
keys = [ keys ]
|
107
106
|
end
|
108
|
-
|
107
|
+
|
109
108
|
key = keys.shift.to_sym
|
110
109
|
has_key = data.has_key?(key)
|
111
110
|
existing = {
|
@@ -123,7 +122,12 @@ class Config
|
|
123
122
|
end
|
124
123
|
else
|
125
124
|
data[key] = {} unless has_key
|
126
|
-
|
125
|
+
|
126
|
+
if data[key].is_a?(Hash)
|
127
|
+
existing = modify(data[key], keys, value)
|
128
|
+
else
|
129
|
+
existing[:value] = nil
|
130
|
+
end
|
127
131
|
end
|
128
132
|
|
129
133
|
return existing
|
data/lib/core/errors.rb
CHANGED
data/lib/core/facade.rb
CHANGED
@@ -38,6 +38,13 @@ module Facade
|
|
38
38
|
is_admin || ext_admin ? true : false
|
39
39
|
end
|
40
40
|
|
41
|
+
#---
|
42
|
+
|
43
|
+
def ip_address
|
44
|
+
result = cli_run(value(:ip_address_command, 'curl --silent ifconfig.me'), { :quiet => true })
|
45
|
+
result.output
|
46
|
+
end
|
47
|
+
|
41
48
|
#-----------------------------------------------------------------------------
|
42
49
|
# Status codes
|
43
50
|
|
@@ -157,7 +164,11 @@ module Facade
|
|
157
164
|
end
|
158
165
|
|
159
166
|
def action_config(provider)
|
160
|
-
action(provider, { :settings => {}, :quiet => true })
|
167
|
+
action = action(provider, { :settings => {}, :quiet => true })
|
168
|
+
return {} unless action
|
169
|
+
|
170
|
+
action.configure
|
171
|
+
action.config
|
161
172
|
end
|
162
173
|
|
163
174
|
def action_run(provider, options = {}, quiet = true)
|
data/lib/core/manager.rb
CHANGED
@@ -25,11 +25,11 @@ class Manager
|
|
25
25
|
|
26
26
|
init_manager(name) unless @@supervisors.has_key?(name)
|
27
27
|
|
28
|
-
begin
|
28
|
+
#begin
|
29
29
|
@@supervisors[name].test_connection
|
30
|
-
rescue Celluloid::DeadActorError
|
31
|
-
|
32
|
-
end
|
30
|
+
#rescue Celluloid::DeadActorError
|
31
|
+
# retry
|
32
|
+
#end
|
33
33
|
@@supervisors[name]
|
34
34
|
end
|
35
35
|
|
@@ -291,20 +291,30 @@ class Manager
|
|
291
291
|
|
292
292
|
def load_base(type, provider, options = {})
|
293
293
|
logger.info("Fetching plugin #{type} provider #{provider} at #{Time.now}")
|
294
|
-
|
295
|
-
|
296
|
-
|
294
|
+
|
295
|
+
options = translate_type(type, options)
|
296
|
+
config = Config.ensure(options)
|
297
|
+
name = config.get(:name, nil)
|
297
298
|
|
298
299
|
logger.debug("Plugin options: #{config.export.inspect}")
|
299
300
|
|
300
|
-
if name
|
301
|
+
if name && ! config.delete(:new, false)
|
301
302
|
logger.debug("Looking up existing instance of #{name}")
|
302
303
|
|
303
304
|
existing_instance = get(type, name)
|
304
|
-
|
305
|
+
|
306
|
+
if existing_instance
|
307
|
+
config.export.each do |property_name, value|
|
308
|
+
unless [ :name, :meta ].include?(property_name)
|
309
|
+
existing_instance[property_name] = value
|
310
|
+
end
|
311
|
+
end
|
312
|
+
existing_instance.normalize(true)
|
313
|
+
|
314
|
+
logger.info("Using existing instance of #{type}, #{name}")
|
315
|
+
return existing_instance
|
316
|
+
end
|
305
317
|
end
|
306
|
-
|
307
|
-
return existing_instance if existing_instance
|
308
318
|
create(type, provider, options)
|
309
319
|
end
|
310
320
|
|
@@ -315,7 +325,7 @@ class Manager
|
|
315
325
|
|
316
326
|
# Allow options to override provider
|
317
327
|
config = Config.ensure(options)
|
318
|
-
provider = config.
|
328
|
+
provider = config.delete(:provider, provider)
|
319
329
|
provider = default_provider unless provider
|
320
330
|
|
321
331
|
load_base(type, provider, config)
|
@@ -419,7 +429,7 @@ class Manager
|
|
419
429
|
results = nil
|
420
430
|
|
421
431
|
if Nucleon.log_level == :hook # To save processing on rendering
|
422
|
-
logger.hook("Executing extension hook { #{method} } at #{Time.now}
|
432
|
+
logger.hook("Executing extension hook { #{method} } at #{Time.now}")
|
423
433
|
end
|
424
434
|
|
425
435
|
extensions = plugins(:extension)
|
@@ -275,54 +275,60 @@ module ObjectInterface
|
|
275
275
|
unless respond_to? :search_object
|
276
276
|
logger.debug("Defining object utility method: search_object")
|
277
277
|
|
278
|
-
define_method :search_object do |obj_config, keys, default =
|
278
|
+
define_method :search_object do |obj_config, keys, default = nil, format = false|
|
279
279
|
obj_config = Marshal.load(Marshal.dump(obj_config))
|
280
|
-
|
281
|
-
|
280
|
+
|
282
281
|
logger.debug("Searching object properties: #{obj_config.inspect}")
|
283
282
|
|
284
|
-
|
285
|
-
|
283
|
+
# TODO: Figure out a way to effectively cache this search operation
|
284
|
+
#------------------------------------------------------------------
|
285
|
+
settings = {}
|
286
286
|
|
287
|
-
|
288
|
-
|
289
|
-
|
290
|
-
|
287
|
+
keys = [ keys ] unless keys.is_a?(Array)
|
288
|
+
temp = keys.dup
|
289
|
+
|
290
|
+
logger.debug("Searching object keys: #{keys.inspect}")
|
291
291
|
|
292
|
-
|
293
|
-
|
294
|
-
|
295
|
-
array(obj_settings).each do |group_name|
|
296
|
-
if group_settings = Marshal.load(Marshal.dump(settings(group_name)))
|
297
|
-
settings = Util::Data.merge([ group_settings.dup, settings ], true)
|
298
|
-
end
|
299
|
-
end
|
300
|
-
end
|
301
|
-
temp.pop
|
302
|
-
end
|
303
|
-
|
304
|
-
logger.debug("Specialized settings found: #{settings.inspect}")
|
305
|
-
logger.debug("Searching general settings")
|
306
|
-
|
307
|
-
if obj_settings = obj_config.delete(:settings)
|
292
|
+
logger.debug("Searching specialized settings")
|
293
|
+
until temp.empty? do
|
294
|
+
if obj_settings = obj_config.get([ temp, :settings ])
|
308
295
|
array(obj_settings).each do |group_name|
|
309
296
|
if group_settings = Marshal.load(Marshal.dump(settings(group_name)))
|
310
|
-
settings = Util::Data.merge([ group_settings, settings ], true)
|
297
|
+
settings = Util::Data.merge([ group_settings.dup, settings ], true)
|
311
298
|
end
|
312
299
|
end
|
313
|
-
end
|
314
|
-
|
315
|
-
logger.debug("Final settings found: #{settings.inspect}")
|
316
|
-
|
317
|
-
unless settings.empty?
|
318
|
-
final_config = Config.new(Util::Data.merge([ settings, obj_config.export ], true))
|
319
|
-
value = final_config.get(keys)
|
320
|
-
|
321
|
-
logger.debug("Final configuration: #{final_config.export.inspect}")
|
322
300
|
end
|
301
|
+
temp.pop
|
302
|
+
end
|
323
303
|
|
324
|
-
|
304
|
+
logger.debug("Specialized settings found: #{settings.inspect}")
|
305
|
+
logger.debug("Searching general settings")
|
306
|
+
|
307
|
+
if obj_settings = obj_config.get(:settings)
|
308
|
+
array(obj_settings).each do |group_name|
|
309
|
+
if group_settings = Marshal.load(Marshal.dump(settings(group_name)))
|
310
|
+
settings = Util::Data.merge([ group_settings, settings ], true)
|
311
|
+
end
|
312
|
+
end
|
325
313
|
end
|
314
|
+
#------------------------------------------------------------------
|
315
|
+
# TODO: Cache the above!!!
|
316
|
+
|
317
|
+
logger.debug("Final settings found: #{settings.inspect}")
|
318
|
+
|
319
|
+
if settings.empty?
|
320
|
+
value = obj_config.get(keys)
|
321
|
+
else
|
322
|
+
final_config = Config.new(Util::Data.merge([
|
323
|
+
Util::Data.clean(settings),
|
324
|
+
Util::Data.clean(obj_config.export)
|
325
|
+
], true))
|
326
|
+
value = final_config.get(keys)
|
327
|
+
|
328
|
+
logger.debug("Final configuration: #{final_config.export.inspect}")
|
329
|
+
end
|
330
|
+
|
331
|
+
value = default if Util::Data.undef?(value)
|
326
332
|
|
327
333
|
logger.debug("Final value found (format: #{format.inspect}): #{value.inspect}")
|
328
334
|
filter(value, format)
|
@@ -104,7 +104,7 @@ module PluginInterface
|
|
104
104
|
if _single_instance
|
105
105
|
logger.debug("Initializing single instance plugin: #{instance_settings.inspect}")
|
106
106
|
|
107
|
-
plugin = Nucleon.plugin(_plugin_type, provider, Config.ensure(instance_settings).import({ :meta => { :parent => myself } }))
|
107
|
+
plugin = Nucleon.plugin(_plugin_type, provider, Config.ensure(instance_settings).import({ :meta => { :parent => myself }, :new => true }))
|
108
108
|
|
109
109
|
_set([ _plural, provider ], plugin)
|
110
110
|
else
|
@@ -112,8 +112,7 @@ module PluginInterface
|
|
112
112
|
if name != :settings
|
113
113
|
logger.debug("Initializing plugin #{_plugin_type} #{name}: #{options.inspect}")
|
114
114
|
|
115
|
-
options
|
116
|
-
plugin = Nucleon.plugin(_plugin_type, provider, Config.ensure(options).import({ :meta => { :parent => myself } }))
|
115
|
+
plugin = Nucleon.plugin(_plugin_type, provider, Config.ensure(options).import({ :name => name, :meta => { :parent => myself }, :new => true }))
|
117
116
|
|
118
117
|
_set([ _plural, provider, name ], plugin)
|
119
118
|
end
|
@@ -139,15 +138,14 @@ module PluginInterface
|
|
139
138
|
if _single_instance
|
140
139
|
logger.debug("Setting single #{_plugin_type} #{provider}: #{instance_settings.inspect}")
|
141
140
|
|
142
|
-
plugin = Nucleon.plugin(_plugin_type, provider, Config.ensure(instance_settings).import({ :meta => { :parent => myself } }))
|
141
|
+
plugin = Nucleon.plugin(_plugin_type, provider, Config.ensure(instance_settings).import({ :meta => { :parent => myself }, :new => true }))
|
143
142
|
|
144
143
|
_set([ _plural, provider ], plugin)
|
145
144
|
else
|
146
145
|
instance_settings.each do |name, options|
|
147
146
|
logger.debug("Setting #{_plugin_type} #{provider} #{name}: #{options.inspect}")
|
148
147
|
|
149
|
-
options
|
150
|
-
plugin = Nucleon.plugin(_plugin_type, provider, Config.ensure(options).import({ :meta => { :parent => myself } }))
|
148
|
+
plugin = Nucleon.plugin(_plugin_type, provider, Config.ensure(options).import({ :name => name, :meta => { :parent => myself }, :new => true }))
|
151
149
|
|
152
150
|
_set([ _plural, provider, name ], plugin)
|
153
151
|
end
|
@@ -201,7 +199,7 @@ module PluginInterface
|
|
201
199
|
options = get([ _plural, provider ], nil)
|
202
200
|
|
203
201
|
unless options.nil?
|
204
|
-
plugin = Nucleon.plugin(_plugin_type, provider, Config.ensure(options).import({ :meta => { :parent => myself } }))
|
202
|
+
plugin = Nucleon.plugin(_plugin_type, provider, Config.ensure(options).import({ :meta => { :parent => myself }, :new => true }))
|
205
203
|
|
206
204
|
logger.debug("Initializing plugin #{_plugin_type} #{provider}: #{options.inspect}")
|
207
205
|
|
@@ -220,7 +218,7 @@ module PluginInterface
|
|
220
218
|
|
221
219
|
set([ _plural, provider ], options)
|
222
220
|
|
223
|
-
plugin = Nucleon.plugin(_plugin_type, provider, Config.ensure(options).import({ :meta => { :parent => myself } }))
|
221
|
+
plugin = Nucleon.plugin(_plugin_type, provider, Config.ensure(options).import({ :meta => { :parent => myself }, :new => true }))
|
224
222
|
|
225
223
|
logger.debug("Setting single #{_plugin_type} #{provider}: #{options.inspect}")
|
226
224
|
|
@@ -241,7 +239,7 @@ module PluginInterface
|
|
241
239
|
|
242
240
|
logger.debug("Defining single instance plugin interface method: delete_#{_type}")
|
243
241
|
|
244
|
-
define_method "delete_#{_type}" do |provider|
|
242
|
+
define_method "delete_#{_type}" do |provider, remove_plugin = true|
|
245
243
|
plugin = send(_type, provider)
|
246
244
|
|
247
245
|
logger.debug("Deleting single #{_type} #{provider}")
|
@@ -249,7 +247,7 @@ module PluginInterface
|
|
249
247
|
delete([ _plural, provider ])
|
250
248
|
_delete([ _plural, provider ])
|
251
249
|
|
252
|
-
Nucleon.remove_plugin(plugin)
|
250
|
+
Nucleon.remove_plugin(plugin) if remove_plugin && ! plugin.nil?
|
253
251
|
end
|
254
252
|
|
255
253
|
#---
|
@@ -295,13 +293,12 @@ module PluginInterface
|
|
295
293
|
|
296
294
|
logger.debug("Defining multi instance plugin interface method: #{_type}")
|
297
295
|
|
298
|
-
define_method "#{_type}" do |provider, name|
|
296
|
+
define_method "#{_type}" do |provider, name, reset = false|
|
299
297
|
if reset || _get([ _plural, provider, name ], nil).nil?
|
300
298
|
options = get([ _plural, provider, name ], nil)
|
301
299
|
|
302
300
|
unless options.nil?
|
303
|
-
options
|
304
|
-
plugin = Nucleon.plugin(_plugin_type, provider, Config.ensure(options).import({ :meta => { :parent => myself } }))
|
301
|
+
plugin = Nucleon.plugin(_plugin_type, provider, Config.ensure(options).import({ :name => name, :meta => { :parent => myself }, :new => true }))
|
305
302
|
|
306
303
|
logger.debug("Initializing plugin #{_plugin_type} #{provider}: #{options.inspect}")
|
307
304
|
|
@@ -319,9 +316,7 @@ module PluginInterface
|
|
319
316
|
options = Config.ensure(options).export
|
320
317
|
|
321
318
|
set([ _plural, provider, name ], options)
|
322
|
-
|
323
|
-
options[:name] = name
|
324
|
-
plugin = Nucleon.plugin(_plugin_type, provider, Config.ensure(options).import({ :meta => { :parent => myself } }))
|
319
|
+
plugin = Nucleon.plugin(_plugin_type, provider, Config.ensure(options).import({ :name => name, :meta => { :parent => myself }, :new => true }))
|
325
320
|
|
326
321
|
logger.debug("Setting #{_plugin_type} #{provider} #{name}: #{options.inspect}")
|
327
322
|
|
@@ -342,7 +337,7 @@ module PluginInterface
|
|
342
337
|
|
343
338
|
logger.debug("Defining multi instance plugin interface method: delete_#{_type}")
|
344
339
|
|
345
|
-
define_method "delete_#{_type}" do |provider, name|
|
340
|
+
define_method "delete_#{_type}" do |provider, name, remove_plugin = true|
|
346
341
|
plugin = send(_type, provider, name)
|
347
342
|
|
348
343
|
logger.debug("Deleting #{_type} #{provider} #{name}")
|
@@ -350,7 +345,7 @@ module PluginInterface
|
|
350
345
|
delete([ _plural, provider, name ])
|
351
346
|
_delete([ _plural, provider, name ])
|
352
347
|
|
353
|
-
Nucleon.remove_plugin(plugin)
|
348
|
+
Nucleon.remove_plugin(plugin) if remove_plugin && ! plugin.nil?
|
354
349
|
end
|
355
350
|
|
356
351
|
#---
|