nucleon 0.2.4 → 0.2.5
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.
- checksums.yaml +7 -7
- data/VERSION +1 -1
- data/lib/core/environment.rb +2 -2
- data/lib/core/manager.rb +1 -1
- data/lib/core/mixin/macro/object_interface.rb +1 -1
- data/lib/core/mixin/macro/plugin_interface.rb +2 -2
- data/lib/core/plugin/project.rb +1 -1
- data/lib/core/util/ssh.rb +128 -128
- data/lib/nucleon_base.rb +2 -0
- data/nucleon.gemspec +4 -4
- metadata +226 -163
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
---
|
|
2
|
-
SHA1:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
5
|
-
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
1
|
+
---
|
|
2
|
+
SHA1:
|
|
3
|
+
metadata.gz: 603d0e71de8c01d2bcf419e4b3738256cea4a190
|
|
4
|
+
data.tar.gz: 1d673bd001130914d7adf48510e012722dba78dd
|
|
5
|
+
SHA512:
|
|
6
|
+
metadata.gz: c82d37027c3f4e450d7f83c757b1f56aa078de79f2ee5b601b1b9a8ee08c1fbdcddf6507e84818cee3be51f0abb97cc72987ab8f5e5a3845d335066b122f6674
|
|
7
|
+
data.tar.gz: 05eab733dbdf59e8a11d51bd3da83c172fcbaeafe8d85ce5956d119b86c2587074928be3c0e2ba6f0844934a949e5885a227268ec72e5660a9dbba40f072782e
|
data/VERSION
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
0.2.
|
|
1
|
+
0.2.5
|
data/lib/core/environment.rb
CHANGED
|
@@ -440,7 +440,7 @@ class Environment < Core
|
|
|
440
440
|
|
|
441
441
|
if type_info = Util::Data.clone(loaded_plugin(namespace, plugin_type, provider))
|
|
442
442
|
ids = array(type_info[:class].register_ids).flatten
|
|
443
|
-
instance_config = Config.new(options)
|
|
443
|
+
instance_config = Config.new(options, {}, true, false)
|
|
444
444
|
ensure_new = instance_config.delete(:new, false)
|
|
445
445
|
|
|
446
446
|
instance_options = Util::Data.subset(instance_config.export, ids, true)
|
|
@@ -453,7 +453,7 @@ class Environment < Core
|
|
|
453
453
|
result = code.call(type_info, options) if code
|
|
454
454
|
options = result if result.is_a?(Hash)
|
|
455
455
|
|
|
456
|
-
options[:meta] = Config.new(type_info).import(hash(options[:meta]))
|
|
456
|
+
options[:meta] = Config.new(type_info, {}, true, false).import(hash(options[:meta]))
|
|
457
457
|
|
|
458
458
|
options.delete(:new)
|
|
459
459
|
|
data/lib/core/manager.rb
CHANGED
|
@@ -698,7 +698,7 @@ class Manager
|
|
|
698
698
|
|
|
699
699
|
logger.debug("Generating #{type} extended configuration")
|
|
700
700
|
|
|
701
|
-
exec("#{type}_config", Config.new(config.export)) do |op, data|
|
|
701
|
+
exec("#{type}_config", Config.new(config.export, {}, true, false)) do |op, data|
|
|
702
702
|
if op == :reduce
|
|
703
703
|
data.each do |provider, result|
|
|
704
704
|
config.import(result)
|
|
@@ -37,7 +37,7 @@ module ObjectInterface
|
|
|
37
37
|
logger.debug("Defining object interface method: #{_type}_config")
|
|
38
38
|
|
|
39
39
|
define_method "#{_type}_config" do |name = nil|
|
|
40
|
-
Config.new(
|
|
40
|
+
Config.new((name ? get([ _plural, name ], {}) : get(_plural, {})), {}, true, false)
|
|
41
41
|
end
|
|
42
42
|
|
|
43
43
|
#---
|
|
@@ -174,7 +174,7 @@ module PluginInterface
|
|
|
174
174
|
define_method "#{_type}_config" do |provider = nil|
|
|
175
175
|
keys = [ _plural ]
|
|
176
176
|
keys << provider unless provider.nil?
|
|
177
|
-
Config.new(get(keys, {}))
|
|
177
|
+
Config.new(get(keys, {}), {}, true, false)
|
|
178
178
|
end
|
|
179
179
|
|
|
180
180
|
#---
|
|
@@ -273,7 +273,7 @@ module PluginInterface
|
|
|
273
273
|
keys = [ _plural ]
|
|
274
274
|
keys << provider unless provider.nil?
|
|
275
275
|
keys << name unless name.nil?
|
|
276
|
-
Config.new(get(keys, {}))
|
|
276
|
+
Config.new(get(keys, {}), {}, true, false)
|
|
277
277
|
end
|
|
278
278
|
|
|
279
279
|
#---
|
data/lib/core/plugin/project.rb
CHANGED
|
@@ -581,7 +581,7 @@ class Project < Nucleon.plugin_class(:nucleon, :base)
|
|
|
581
581
|
|
|
582
582
|
if can_persist?
|
|
583
583
|
localize do
|
|
584
|
-
config = Config.new({ :path => path })
|
|
584
|
+
config = Config.new({ :path => path }, {}, true, false)
|
|
585
585
|
|
|
586
586
|
if extension_check(:delete_project, { :config => config })
|
|
587
587
|
logger.info("Deleting a sub project at #{config[:path]}")
|
data/lib/core/util/ssh.rb
CHANGED
|
@@ -2,84 +2,84 @@
|
|
|
2
2
|
module Nucleon
|
|
3
3
|
module Util
|
|
4
4
|
class SSH < Core
|
|
5
|
-
|
|
5
|
+
|
|
6
6
|
#-----------------------------------------------------------------------------
|
|
7
7
|
# User key home
|
|
8
|
-
|
|
8
|
+
|
|
9
9
|
@@key_path = nil
|
|
10
|
-
|
|
10
|
+
|
|
11
11
|
#---
|
|
12
|
-
|
|
12
|
+
|
|
13
13
|
def self.key_path
|
|
14
14
|
unless @@key_path
|
|
15
15
|
home_path = ( ENV['USER'] == 'root' ? '/root' : ENV['HOME'] ) # In case we are using sudo
|
|
16
16
|
@@key_path = File.join(home_path, '.ssh')
|
|
17
|
-
|
|
17
|
+
|
|
18
18
|
FileUtils.mkdir(@@key_path) unless File.directory?(@@key_path)
|
|
19
19
|
end
|
|
20
20
|
@@key_path
|
|
21
21
|
end
|
|
22
|
-
|
|
22
|
+
|
|
23
23
|
#-----------------------------------------------------------------------------
|
|
24
24
|
# Instance generators
|
|
25
|
-
|
|
25
|
+
|
|
26
26
|
def self.generate(options = {})
|
|
27
27
|
config = Config.ensure(options)
|
|
28
|
-
|
|
28
|
+
|
|
29
29
|
private_key = config.get(:private_key, nil)
|
|
30
30
|
original_key = nil
|
|
31
31
|
key_comment = config.get(:comment, '')
|
|
32
32
|
passphrase = config.get(:passphrase, nil)
|
|
33
|
-
force = config.get(:force, false)
|
|
34
|
-
|
|
33
|
+
force = config.get(:force, false)
|
|
34
|
+
|
|
35
35
|
if private_key.nil?
|
|
36
36
|
key_type = config.get(:type, "RSA")
|
|
37
37
|
key_bits = config.get(:bits, 2048)
|
|
38
|
-
|
|
38
|
+
|
|
39
39
|
key_data = SSHKey.generate({
|
|
40
|
-
:type => key_type,
|
|
41
|
-
:bits => key_bits,
|
|
42
|
-
:comment => key_comment,
|
|
40
|
+
:type => key_type,
|
|
41
|
+
:bits => key_bits,
|
|
42
|
+
:comment => key_comment,
|
|
43
43
|
:passphrase => passphrase
|
|
44
44
|
})
|
|
45
45
|
is_new = true
|
|
46
|
-
|
|
46
|
+
|
|
47
47
|
else
|
|
48
48
|
if private_key.include?('PRIVATE KEY')
|
|
49
|
-
original_key = private_key
|
|
49
|
+
original_key = private_key
|
|
50
50
|
else
|
|
51
51
|
original_key = Disk.read(private_key)
|
|
52
52
|
end
|
|
53
|
-
|
|
53
|
+
|
|
54
54
|
if original_key
|
|
55
55
|
encrypted = original_key.include?('ENCRYPTED')
|
|
56
|
-
key_data = SSHKey.new(original_key, {
|
|
57
|
-
:comment => key_comment,
|
|
58
|
-
:passphrase => passphrase
|
|
59
|
-
}) if force || ! encrypted || passphrase
|
|
60
|
-
end
|
|
56
|
+
key_data = SSHKey.new(original_key, {
|
|
57
|
+
:comment => key_comment,
|
|
58
|
+
:passphrase => passphrase
|
|
59
|
+
}) if force || ! encrypted || passphrase
|
|
60
|
+
end
|
|
61
61
|
is_new = false
|
|
62
62
|
end
|
|
63
|
-
|
|
63
|
+
|
|
64
64
|
return nil unless key_data && ! key_data.ssh_public_key.empty?
|
|
65
65
|
Keypair.new(key_data, is_new, original_key, passphrase)
|
|
66
66
|
end
|
|
67
|
-
|
|
67
|
+
|
|
68
68
|
#-----------------------------------------------------------------------------
|
|
69
69
|
# Checks
|
|
70
|
-
|
|
70
|
+
|
|
71
71
|
def self.valid?(public_ssh_key)
|
|
72
72
|
SSHKey.valid_ssh_public_key?(public_ssh_key)
|
|
73
73
|
end
|
|
74
|
-
|
|
74
|
+
|
|
75
75
|
#-----------------------------------------------------------------------------
|
|
76
76
|
# Keypair interface
|
|
77
|
-
|
|
77
|
+
|
|
78
78
|
class Keypair
|
|
79
79
|
attr_reader :type, :private_key, :encrypted_key, :public_key, :ssh_key, :passphrase
|
|
80
|
-
|
|
80
|
+
|
|
81
81
|
#---
|
|
82
|
-
|
|
82
|
+
|
|
83
83
|
def initialize(key_data, is_new, original_key, passphrase = nil)
|
|
84
84
|
@type = key_data.type
|
|
85
85
|
@private_key = key_data.private_key
|
|
@@ -88,118 +88,118 @@ class SSH < Core
|
|
|
88
88
|
@ssh_key = key_data.ssh_public_key
|
|
89
89
|
@passphrase = passphrase
|
|
90
90
|
end
|
|
91
|
-
|
|
91
|
+
|
|
92
92
|
#---
|
|
93
|
-
|
|
93
|
+
|
|
94
94
|
def private_key_file(key_path = nil, key_base = 'id')
|
|
95
95
|
key_path = SSH.key_path if key_path.nil?
|
|
96
96
|
key_name = render(key_base)
|
|
97
|
-
|
|
98
|
-
File.join(key_path, "#{key_name}")
|
|
97
|
+
|
|
98
|
+
File.join(key_path, "#{key_name}")
|
|
99
99
|
end
|
|
100
|
-
|
|
100
|
+
|
|
101
101
|
def public_key_file(key_path = nil, key_base = 'id')
|
|
102
|
-
private_key_file(key_path, key_base) + '.pub'
|
|
102
|
+
private_key_file(key_path, key_base) + '.pub'
|
|
103
103
|
end
|
|
104
|
-
|
|
104
|
+
|
|
105
105
|
#---
|
|
106
|
-
|
|
106
|
+
|
|
107
107
|
def store(key_path = nil, key_base = 'id', secure = true)
|
|
108
108
|
private_key_file = private_key_file(key_path, key_base)
|
|
109
109
|
public_key_file = public_key_file(key_path, key_base)
|
|
110
|
-
|
|
110
|
+
|
|
111
111
|
if secure
|
|
112
112
|
private_success = Disk.write(private_key_file, encrypted_key)
|
|
113
113
|
else
|
|
114
|
-
private_success = Disk.write(private_key_file, private_key)
|
|
114
|
+
private_success = Disk.write(private_key_file, private_key)
|
|
115
115
|
end
|
|
116
116
|
FileUtils.chmod(0600, private_key_file) if private_success
|
|
117
|
-
|
|
117
|
+
|
|
118
118
|
public_success = Disk.write(public_key_file, ssh_key)
|
|
119
|
-
|
|
119
|
+
|
|
120
120
|
if private_success && public_success
|
|
121
121
|
return { :private_key => private_key_file, :public_key => public_key_file }
|
|
122
122
|
end
|
|
123
123
|
false
|
|
124
124
|
end
|
|
125
|
-
|
|
125
|
+
|
|
126
126
|
#---
|
|
127
|
-
|
|
127
|
+
|
|
128
128
|
def render(key_base = 'id')
|
|
129
129
|
self.class.render(type, key_base)
|
|
130
130
|
end
|
|
131
|
-
|
|
131
|
+
|
|
132
132
|
def self.render(type, key_base = 'id')
|
|
133
|
-
"#{key_base}_#{type.downcase}"
|
|
133
|
+
"#{key_base}_#{type.downcase}"
|
|
134
134
|
end
|
|
135
135
|
end
|
|
136
|
-
|
|
136
|
+
|
|
137
137
|
#-----------------------------------------------------------------------------
|
|
138
138
|
# SSH Execution interface
|
|
139
|
-
|
|
139
|
+
|
|
140
140
|
@@sessions = {}
|
|
141
141
|
@@auth = {}
|
|
142
|
-
|
|
142
|
+
|
|
143
143
|
@@session_lock = Mutex.new
|
|
144
|
-
|
|
144
|
+
|
|
145
145
|
#---
|
|
146
|
-
|
|
146
|
+
|
|
147
147
|
def self.session_id(hostname, user)
|
|
148
|
-
"#{hostname}-#{user}"
|
|
148
|
+
"#{hostname}-#{user}"
|
|
149
149
|
end
|
|
150
|
-
|
|
150
|
+
|
|
151
151
|
#---
|
|
152
|
-
|
|
152
|
+
|
|
153
153
|
def self.session(hostname, user, port = 22, private_key = nil, reset = false, options = {})
|
|
154
154
|
require 'net/ssh'
|
|
155
|
-
|
|
155
|
+
|
|
156
156
|
session_id = session_id(hostname, user)
|
|
157
|
-
|
|
158
|
-
@@session_lock.synchronize do
|
|
157
|
+
|
|
158
|
+
@@session_lock.synchronize do
|
|
159
159
|
config = Config.ensure(options)
|
|
160
|
-
|
|
160
|
+
|
|
161
161
|
ssh_options = Config.new({
|
|
162
162
|
:user_known_hosts_file => [ File.join(key_path, 'known_hosts'), File.join(key_path, 'known_hosts2') ],
|
|
163
163
|
:auth_methods => [ 'publickey' ],
|
|
164
164
|
:paranoid => :very
|
|
165
|
-
}).import(Util::Data.subset(config, config.keys - [ :keypair, :key_dir, :key_name ]))
|
|
166
|
-
|
|
165
|
+
}, {}, true, false).import(Util::Data.subset(config, config.keys - [ :keypair, :key_dir, :key_name ]))
|
|
166
|
+
|
|
167
167
|
if private_key
|
|
168
|
-
auth_id = [ session_id, private_key ].join('_')
|
|
169
|
-
|
|
168
|
+
auth_id = [ session_id, private_key ].join('_')
|
|
169
|
+
|
|
170
170
|
if ! @@auth[auth_id] && keypair = unlock_private_key(private_key, config)
|
|
171
171
|
@@auth[auth_id] = keypair
|
|
172
172
|
end
|
|
173
|
-
config[:keypair] = @@auth[auth_id] # Reset so caller can access updated keypair
|
|
174
|
-
|
|
173
|
+
config[:keypair] = @@auth[auth_id] # Reset so caller can access updated keypair
|
|
174
|
+
|
|
175
175
|
if @@auth[auth_id].is_a?(String)
|
|
176
176
|
ssh_options[:keys_only] = false
|
|
177
|
-
ssh_options[:keys] = [ @@auth[auth_id] ]
|
|
177
|
+
ssh_options[:keys] = [ @@auth[auth_id] ]
|
|
178
178
|
else
|
|
179
179
|
ssh_options[:keys_only] = true
|
|
180
180
|
ssh_options[:key_data] = [ @@auth[auth_id].private_key ]
|
|
181
181
|
end
|
|
182
182
|
end
|
|
183
|
-
|
|
184
|
-
ssh_options[:port] = port
|
|
185
|
-
|
|
183
|
+
|
|
184
|
+
ssh_options[:port] = port
|
|
185
|
+
|
|
186
186
|
if reset || ! @@sessions.has_key?(session_id)
|
|
187
187
|
@@sessions[session_id] = Net::SSH.start(hostname, user, ssh_options.export)
|
|
188
188
|
end
|
|
189
189
|
end
|
|
190
190
|
yield(@@sessions[session_id]) if block_given? && @@sessions[session_id]
|
|
191
|
-
@@sessions[session_id]
|
|
191
|
+
@@sessions[session_id]
|
|
192
192
|
end
|
|
193
|
-
|
|
193
|
+
|
|
194
194
|
def self.init_session(hostname, user, port = 22, private_key = nil, options = {})
|
|
195
|
-
session(hostname, user, port, private_key, true, options)
|
|
195
|
+
session(hostname, user, port, private_key, true, options)
|
|
196
196
|
end
|
|
197
|
-
|
|
197
|
+
|
|
198
198
|
#---
|
|
199
|
-
|
|
199
|
+
|
|
200
200
|
def self.close_session(hostname, user)
|
|
201
201
|
session_id = session_id(hostname, user)
|
|
202
|
-
|
|
202
|
+
|
|
203
203
|
if @@sessions.has_key?(session_id)
|
|
204
204
|
begin # Don't care about errors here
|
|
205
205
|
@@sessions[session_id].close
|
|
@@ -208,46 +208,46 @@ class SSH < Core
|
|
|
208
208
|
@@sessions.delete(session_id)
|
|
209
209
|
end
|
|
210
210
|
end
|
|
211
|
-
|
|
211
|
+
|
|
212
212
|
#---
|
|
213
|
-
|
|
213
|
+
|
|
214
214
|
def self.close(hostname = nil, user = nil)
|
|
215
215
|
if hostname && user.nil? # Assume we entered a session id
|
|
216
216
|
if @@sessions.has_key?(hostname)
|
|
217
217
|
@@sessions[hostname].close
|
|
218
|
-
@@sessions.delete(hostname)
|
|
218
|
+
@@sessions.delete(hostname)
|
|
219
219
|
end
|
|
220
|
-
|
|
220
|
+
|
|
221
221
|
elsif hostname && user # Generate session id from args
|
|
222
222
|
session_id = session_id(hostname, user)
|
|
223
|
-
|
|
223
|
+
|
|
224
224
|
if @@sessions.has_key?(session_id)
|
|
225
225
|
@@sessions[session_id].close
|
|
226
|
-
@@sessions.delete(session_id)
|
|
226
|
+
@@sessions.delete(session_id)
|
|
227
227
|
end
|
|
228
|
-
|
|
228
|
+
|
|
229
229
|
else # Close all connections
|
|
230
230
|
@@sessions.keys.each do |id|
|
|
231
231
|
@@sessions[id].close
|
|
232
|
-
@@sessions.delete(id)
|
|
232
|
+
@@sessions.delete(id)
|
|
233
233
|
end
|
|
234
234
|
end
|
|
235
235
|
end
|
|
236
|
-
|
|
236
|
+
|
|
237
237
|
#---
|
|
238
|
-
|
|
238
|
+
|
|
239
239
|
def self.exec(hostname, user, commands)
|
|
240
240
|
results = []
|
|
241
|
-
|
|
241
|
+
|
|
242
242
|
begin
|
|
243
243
|
session(hostname, user) do |ssh|
|
|
244
244
|
Data.array(commands).each do |command|
|
|
245
245
|
command = command.flatten.join(' ') if command.is_a?(Array)
|
|
246
246
|
command = command.to_s
|
|
247
247
|
result = Shell::Result.new(command)
|
|
248
|
-
|
|
248
|
+
|
|
249
249
|
logger.info(">> running SSH: #{command}")
|
|
250
|
-
|
|
250
|
+
|
|
251
251
|
ssh.open_channel do |ssh_channel|
|
|
252
252
|
ssh_channel.exec(command) do |channel, success|
|
|
253
253
|
unless success
|
|
@@ -275,9 +275,9 @@ class SSH < Core
|
|
|
275
275
|
end
|
|
276
276
|
logger.warn("`#{command}` messages: #{result.errors}") if result.errors.length > 0
|
|
277
277
|
logger.warn("`#{command}` status: #{result.status}") unless result.status == 0
|
|
278
|
-
|
|
278
|
+
|
|
279
279
|
results << result
|
|
280
|
-
ssh.loop
|
|
280
|
+
ssh.loop
|
|
281
281
|
end
|
|
282
282
|
end
|
|
283
283
|
rescue Net::SSH::HostKeyMismatch => error
|
|
@@ -285,16 +285,16 @@ class SSH < Core
|
|
|
285
285
|
sleep 0.2
|
|
286
286
|
retry
|
|
287
287
|
end
|
|
288
|
-
results
|
|
288
|
+
results
|
|
289
289
|
end
|
|
290
|
-
|
|
290
|
+
|
|
291
291
|
#---
|
|
292
|
-
|
|
292
|
+
|
|
293
293
|
def self.download(hostname, user, remote_path, local_path, options = {})
|
|
294
294
|
config = Config.ensure(options)
|
|
295
|
-
|
|
295
|
+
|
|
296
296
|
require 'net/scp'
|
|
297
|
-
|
|
297
|
+
|
|
298
298
|
# Accepted options:
|
|
299
299
|
# * :recursive - the +remote+ parameter refers to a remote directory, which
|
|
300
300
|
# should be downloaded to a new directory named +local+ on the local
|
|
@@ -306,9 +306,9 @@ class SSH < Core
|
|
|
306
306
|
config.init(:recursive, true)
|
|
307
307
|
config.init(:preserve, true)
|
|
308
308
|
config.init(:verbose, true)
|
|
309
|
-
|
|
309
|
+
|
|
310
310
|
blocking = config.delete(:blocking, true)
|
|
311
|
-
|
|
311
|
+
|
|
312
312
|
session(hostname, user) do |ssh|
|
|
313
313
|
if blocking
|
|
314
314
|
ssh.scp.download!(remote_path, local_path, config.export) do |ch, name, received, total|
|
|
@@ -319,14 +319,14 @@ class SSH < Core
|
|
|
319
319
|
end
|
|
320
320
|
end
|
|
321
321
|
end
|
|
322
|
-
|
|
322
|
+
|
|
323
323
|
#---
|
|
324
|
-
|
|
324
|
+
|
|
325
325
|
def self.upload(hostname, user, local_path, remote_path, options = {})
|
|
326
326
|
config = Config.ensure(options)
|
|
327
|
-
|
|
327
|
+
|
|
328
328
|
require 'net/scp'
|
|
329
|
-
|
|
329
|
+
|
|
330
330
|
# Accepted options:
|
|
331
331
|
# * :recursive - the +local+ parameter refers to a local directory, which
|
|
332
332
|
# should be uploaded to a new directory named +remote+ on the remote
|
|
@@ -342,9 +342,9 @@ class SSH < Core
|
|
|
342
342
|
config.init(:preserve, true)
|
|
343
343
|
config.init(:verbose, true)
|
|
344
344
|
config.init(:chunk_size, 2048)
|
|
345
|
-
|
|
345
|
+
|
|
346
346
|
blocking = config.delete(:blocking, true)
|
|
347
|
-
|
|
347
|
+
|
|
348
348
|
session(hostname, user) do |ssh|
|
|
349
349
|
if blocking
|
|
350
350
|
ssh.scp.upload!(local_path, remote_path, config.export) do |ch, name, sent, total|
|
|
@@ -355,24 +355,24 @@ class SSH < Core
|
|
|
355
355
|
end
|
|
356
356
|
end
|
|
357
357
|
end
|
|
358
|
-
|
|
358
|
+
|
|
359
359
|
#---
|
|
360
|
-
|
|
360
|
+
|
|
361
361
|
#
|
|
362
362
|
# Inspired by vagrant ssh implementation
|
|
363
363
|
#
|
|
364
364
|
# See: https://github.com/mitchellh/vagrant/blob/master/lib/vagrant/util/ssh.rb
|
|
365
365
|
#
|
|
366
|
-
|
|
366
|
+
|
|
367
367
|
def self.terminal(hostname, user, options = {})
|
|
368
368
|
config = Config.ensure(options)
|
|
369
369
|
ssh_path = nucleon_locate("ssh")
|
|
370
|
-
|
|
370
|
+
|
|
371
371
|
raise Errors::SSHUnavailable unless ssh_path
|
|
372
|
-
|
|
372
|
+
|
|
373
373
|
port = config.get(:port, 22)
|
|
374
374
|
private_keys = config.get(:private_keys, File.join(ENV['HOME'], '.ssh', 'id_rsa'))
|
|
375
|
-
|
|
375
|
+
|
|
376
376
|
command_options = [
|
|
377
377
|
"#{user}@#{hostname}",
|
|
378
378
|
"-p", port.to_s,
|
|
@@ -387,7 +387,7 @@ class SSH < Core
|
|
|
387
387
|
Util::Data.array(private_keys).each do |path|
|
|
388
388
|
command_options += [ "-i", File.expand_path(path) ]
|
|
389
389
|
end
|
|
390
|
-
|
|
390
|
+
|
|
391
391
|
if config.get(:forward_x11, false)
|
|
392
392
|
command_options += [
|
|
393
393
|
"-o", "ForwardX11=yes",
|
|
@@ -397,58 +397,58 @@ class SSH < Core
|
|
|
397
397
|
|
|
398
398
|
command_options += [ "-o", "ProxyCommand=#{config[:proxy_command]}" ] if config.get(:proxy_command, false)
|
|
399
399
|
command_options += [ "-o", "ForwardAgent=yes" ] if config.get(:forward_agent, false)
|
|
400
|
-
|
|
400
|
+
|
|
401
401
|
command_options.concat(Util::Data.array(config[:extra_args])) if config.get(:extra_args, false)
|
|
402
402
|
|
|
403
403
|
#---
|
|
404
404
|
|
|
405
405
|
logger.info("Executing SSH in subprocess: #{command_options.inspect}")
|
|
406
|
-
|
|
406
|
+
|
|
407
407
|
process = ChildProcess.build('ssh', *command_options)
|
|
408
408
|
process.io.inherit!
|
|
409
|
-
|
|
409
|
+
|
|
410
410
|
process.start
|
|
411
411
|
process.wait
|
|
412
412
|
process.exit_code
|
|
413
413
|
end
|
|
414
|
-
|
|
414
|
+
|
|
415
415
|
#-----------------------------------------------------------------------------
|
|
416
416
|
# SSH utilities
|
|
417
|
-
|
|
417
|
+
|
|
418
418
|
def self.unlock_private_key(private_key, options = {})
|
|
419
419
|
require 'net/ssh'
|
|
420
|
-
|
|
420
|
+
|
|
421
421
|
config = Config.ensure(options)
|
|
422
422
|
keypair = config.get(:keypair, nil)
|
|
423
423
|
key_dir = config.get(:key_dir, nil)
|
|
424
424
|
key_name = config.get(:key_name, 'default')
|
|
425
425
|
no_file = ENV['NUCLEON_NO_SSH_KEY_SAVE']
|
|
426
|
-
|
|
426
|
+
|
|
427
427
|
password = nil
|
|
428
428
|
tmp_key_dir = nil
|
|
429
|
-
|
|
429
|
+
|
|
430
430
|
if private_key
|
|
431
431
|
keypair = nil if keypair && ! keypair.private_key
|
|
432
|
-
|
|
432
|
+
|
|
433
433
|
unless no_file
|
|
434
434
|
if key_dir && key_name && File.exists?(private_key) && loaded_private_key = Util::Disk.read(private_key)
|
|
435
435
|
FileUtils.mkdir_p(key_dir)
|
|
436
|
-
|
|
436
|
+
|
|
437
437
|
loaded_private_key =~ /BEGIN\s+([A-Z]+)\s+/
|
|
438
|
-
|
|
438
|
+
|
|
439
439
|
local_key_type = $1
|
|
440
440
|
local_key_name = Keypair.render(local_key_type, key_name)
|
|
441
441
|
local_key_path = File.join(key_dir, local_key_name)
|
|
442
|
-
|
|
442
|
+
|
|
443
443
|
keypair = generate({ :private_key => local_key_path }) if File.exists?(local_key_path)
|
|
444
444
|
end
|
|
445
445
|
end
|
|
446
|
-
|
|
446
|
+
|
|
447
447
|
unless keypair
|
|
448
448
|
key_manager_logger = ::Logger.new(STDERR)
|
|
449
449
|
key_manager_logger.level = ::Logger::FATAL
|
|
450
|
-
key_manager = Net::SSH::Authentication::KeyManager.new(key_manager_logger)
|
|
451
|
-
|
|
450
|
+
key_manager = Net::SSH::Authentication::KeyManager.new(key_manager_logger)
|
|
451
|
+
|
|
452
452
|
key_manager.each_identity do |identity|
|
|
453
453
|
if identity.comment == private_key
|
|
454
454
|
# Feed the key to the system password manager if it exists
|
|
@@ -456,19 +456,19 @@ class SSH < Core
|
|
|
456
456
|
end
|
|
457
457
|
end
|
|
458
458
|
key_manager.finish
|
|
459
|
-
|
|
459
|
+
|
|
460
460
|
until keypair
|
|
461
461
|
keypair = generate({
|
|
462
462
|
:private_key => private_key,
|
|
463
463
|
:passphrase => password
|
|
464
|
-
})
|
|
464
|
+
})
|
|
465
465
|
password = ui.ask("Enter passphrase for #{private_key}: ", { :echo => false }) unless keypair
|
|
466
466
|
end
|
|
467
|
-
|
|
467
|
+
|
|
468
468
|
unless no_file
|
|
469
469
|
if key_dir && key_name && ! keypair.is_a?(String)
|
|
470
470
|
key_files = keypair.store(key_dir, key_name, false)
|
|
471
|
-
|
|
471
|
+
|
|
472
472
|
if key_files && File.exists?(key_files[:private_key])
|
|
473
473
|
keypair = generate({ :private_key => key_files[:private_key] })
|
|
474
474
|
end
|
|
@@ -476,7 +476,7 @@ class SSH < Core
|
|
|
476
476
|
end
|
|
477
477
|
end
|
|
478
478
|
end
|
|
479
|
-
keypair
|
|
479
|
+
keypair
|
|
480
480
|
end
|
|
481
481
|
end
|
|
482
482
|
end
|
data/lib/nucleon_base.rb
CHANGED
data/nucleon.gemspec
CHANGED
|
@@ -2,16 +2,16 @@
|
|
|
2
2
|
# DO NOT EDIT THIS FILE DIRECTLY
|
|
3
3
|
# Instead, edit Jeweler::Tasks in Rakefile, and run 'rake gemspec'
|
|
4
4
|
# -*- encoding: utf-8 -*-
|
|
5
|
-
# stub: nucleon 0.2.
|
|
5
|
+
# stub: nucleon 0.2.5 ruby lib
|
|
6
6
|
|
|
7
7
|
Gem::Specification.new do |s|
|
|
8
8
|
s.name = "nucleon"
|
|
9
|
-
s.version = "0.2.
|
|
9
|
+
s.version = "0.2.5"
|
|
10
10
|
|
|
11
11
|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
|
12
12
|
s.require_paths = ["lib"]
|
|
13
13
|
s.authors = ["Adrian Webb"]
|
|
14
|
-
s.date = "
|
|
14
|
+
s.date = "2015-01-16"
|
|
15
15
|
s.description = "\nA framework that provides a simple foundation for building Ruby applications that are:\n\n* Highly configurable (with both distributed and persistent configurations)\n* Extremely pluggable and extendable\n* Easily parallel\n\nNote: This framework is still very early in development!\n"
|
|
16
16
|
s.email = "adrian.webb@coralnexus.com"
|
|
17
17
|
s.executables = ["nucleon"]
|
|
@@ -111,7 +111,7 @@ Gem::Specification.new do |s|
|
|
|
111
111
|
s.rdoc_options = ["--title", "Nucleon", "--main", "README.rdoc", "--line-numbers"]
|
|
112
112
|
s.required_ruby_version = Gem::Requirement.new(">= 1.9.1")
|
|
113
113
|
s.rubyforge_project = "nucleon"
|
|
114
|
-
s.rubygems_version = "2.4.
|
|
114
|
+
s.rubygems_version = "2.4.3"
|
|
115
115
|
s.summary = "Easy and minimal framework for building extensible distributed applications"
|
|
116
116
|
|
|
117
117
|
if s.respond_to? :specification_version then
|
metadata
CHANGED
|
@@ -1,192 +1,258 @@
|
|
|
1
|
-
--- !ruby/object:Gem::Specification
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: nucleon
|
|
3
|
-
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.2.
|
|
3
|
+
version: !ruby/object:Gem::Version
|
|
4
|
+
version: 0.2.5
|
|
5
5
|
platform: ruby
|
|
6
|
-
authors:
|
|
6
|
+
authors:
|
|
7
7
|
- Adrian Webb
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: bin
|
|
10
10
|
cert_chain: []
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
- !ruby/object:Gem::Dependency
|
|
11
|
+
date: 2015-01-16 00:00:00.000000000 Z
|
|
12
|
+
dependencies:
|
|
13
|
+
- !ruby/object:Gem::Dependency
|
|
15
14
|
name: log4r
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
version: "1.1"
|
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
|
16
|
+
requirements:
|
|
17
|
+
- - "~>"
|
|
18
|
+
- !ruby/object:Gem::Version
|
|
19
|
+
version: '1.1'
|
|
22
20
|
type: :runtime
|
|
23
|
-
version_requirements: *id001
|
|
24
|
-
- !ruby/object:Gem::Dependency
|
|
25
|
-
name: i18n
|
|
26
21
|
prerelease: false
|
|
27
|
-
|
|
28
|
-
requirements:
|
|
29
|
-
- - ~>
|
|
30
|
-
- !ruby/object:Gem::Version
|
|
31
|
-
version:
|
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
23
|
+
requirements:
|
|
24
|
+
- - "~>"
|
|
25
|
+
- !ruby/object:Gem::Version
|
|
26
|
+
version: '1.1'
|
|
27
|
+
- !ruby/object:Gem::Dependency
|
|
28
|
+
name: i18n
|
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
|
30
|
+
requirements:
|
|
31
|
+
- - "~>"
|
|
32
|
+
- !ruby/object:Gem::Version
|
|
33
|
+
version: '0.6'
|
|
32
34
|
type: :runtime
|
|
33
|
-
version_requirements: *id002
|
|
34
|
-
- !ruby/object:Gem::Dependency
|
|
35
|
-
name: netrc
|
|
36
35
|
prerelease: false
|
|
37
|
-
|
|
38
|
-
requirements:
|
|
39
|
-
- - ~>
|
|
40
|
-
- !ruby/object:Gem::Version
|
|
41
|
-
version:
|
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
37
|
+
requirements:
|
|
38
|
+
- - "~>"
|
|
39
|
+
- !ruby/object:Gem::Version
|
|
40
|
+
version: '0.6'
|
|
41
|
+
- !ruby/object:Gem::Dependency
|
|
42
|
+
name: netrc
|
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
|
44
|
+
requirements:
|
|
45
|
+
- - "~>"
|
|
46
|
+
- !ruby/object:Gem::Version
|
|
47
|
+
version: '0.9'
|
|
42
48
|
type: :runtime
|
|
43
|
-
version_requirements: *id003
|
|
44
|
-
- !ruby/object:Gem::Dependency
|
|
45
|
-
name: highline
|
|
46
49
|
prerelease: false
|
|
47
|
-
|
|
48
|
-
requirements:
|
|
49
|
-
- - ~>
|
|
50
|
-
-
|
|
51
|
-
version:
|
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
51
|
+
requirements:
|
|
52
|
+
- - "~>"
|
|
53
|
+
- !ruby/object:Gem::Version
|
|
54
|
+
version: '0.9'
|
|
55
|
+
- !ruby/object:Gem::Dependency
|
|
56
|
+
name: highline
|
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
|
58
|
+
requirements:
|
|
59
|
+
- - "~>"
|
|
60
|
+
- !ruby/object:Gem::Version
|
|
61
|
+
version: '1.6'
|
|
52
62
|
type: :runtime
|
|
53
|
-
version_requirements: *id004
|
|
54
|
-
- !ruby/object:Gem::Dependency
|
|
55
|
-
name: erubis
|
|
56
63
|
prerelease: false
|
|
57
|
-
|
|
58
|
-
requirements:
|
|
59
|
-
- - ~>
|
|
60
|
-
- !ruby/object:Gem::Version
|
|
61
|
-
version:
|
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
65
|
+
requirements:
|
|
66
|
+
- - "~>"
|
|
67
|
+
- !ruby/object:Gem::Version
|
|
68
|
+
version: '1.6'
|
|
69
|
+
- !ruby/object:Gem::Dependency
|
|
70
|
+
name: erubis
|
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
|
72
|
+
requirements:
|
|
73
|
+
- - "~>"
|
|
74
|
+
- !ruby/object:Gem::Version
|
|
75
|
+
version: '2.7'
|
|
62
76
|
type: :runtime
|
|
63
|
-
version_requirements: *id005
|
|
64
|
-
- !ruby/object:Gem::Dependency
|
|
65
|
-
name: deep_merge
|
|
66
77
|
prerelease: false
|
|
67
|
-
|
|
68
|
-
requirements:
|
|
69
|
-
- - ~>
|
|
70
|
-
- !ruby/object:Gem::Version
|
|
71
|
-
version:
|
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
79
|
+
requirements:
|
|
80
|
+
- - "~>"
|
|
81
|
+
- !ruby/object:Gem::Version
|
|
82
|
+
version: '2.7'
|
|
83
|
+
- !ruby/object:Gem::Dependency
|
|
84
|
+
name: deep_merge
|
|
85
|
+
requirement: !ruby/object:Gem::Requirement
|
|
86
|
+
requirements:
|
|
87
|
+
- - "~>"
|
|
88
|
+
- !ruby/object:Gem::Version
|
|
89
|
+
version: '1.0'
|
|
72
90
|
type: :runtime
|
|
73
|
-
version_requirements: *id006
|
|
74
|
-
- !ruby/object:Gem::Dependency
|
|
75
|
-
name: multi_json
|
|
76
91
|
prerelease: false
|
|
77
|
-
|
|
78
|
-
requirements:
|
|
79
|
-
- - ~>
|
|
80
|
-
- !ruby/object:Gem::Version
|
|
81
|
-
version:
|
|
92
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
93
|
+
requirements:
|
|
94
|
+
- - "~>"
|
|
95
|
+
- !ruby/object:Gem::Version
|
|
96
|
+
version: '1.0'
|
|
97
|
+
- !ruby/object:Gem::Dependency
|
|
98
|
+
name: multi_json
|
|
99
|
+
requirement: !ruby/object:Gem::Requirement
|
|
100
|
+
requirements:
|
|
101
|
+
- - "~>"
|
|
102
|
+
- !ruby/object:Gem::Version
|
|
103
|
+
version: '1.10'
|
|
82
104
|
type: :runtime
|
|
83
|
-
version_requirements: *id007
|
|
84
|
-
- !ruby/object:Gem::Dependency
|
|
85
|
-
name: sshkey
|
|
86
105
|
prerelease: false
|
|
87
|
-
|
|
88
|
-
requirements:
|
|
89
|
-
- - ~>
|
|
90
|
-
-
|
|
106
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
107
|
+
requirements:
|
|
108
|
+
- - "~>"
|
|
109
|
+
- !ruby/object:Gem::Version
|
|
110
|
+
version: '1.10'
|
|
111
|
+
- !ruby/object:Gem::Dependency
|
|
112
|
+
name: sshkey
|
|
113
|
+
requirement: !ruby/object:Gem::Requirement
|
|
114
|
+
requirements:
|
|
115
|
+
- - "~>"
|
|
116
|
+
- !ruby/object:Gem::Version
|
|
117
|
+
version: '1.6'
|
|
91
118
|
type: :runtime
|
|
92
|
-
version_requirements: *id009
|
|
93
|
-
- !ruby/object:Gem::Dependency
|
|
94
|
-
name: childprocess
|
|
95
119
|
prerelease: false
|
|
96
|
-
|
|
97
|
-
requirements:
|
|
98
|
-
- - ~>
|
|
99
|
-
- !ruby/object:Gem::Version
|
|
100
|
-
version:
|
|
120
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
121
|
+
requirements:
|
|
122
|
+
- - "~>"
|
|
123
|
+
- !ruby/object:Gem::Version
|
|
124
|
+
version: '1.6'
|
|
125
|
+
- !ruby/object:Gem::Dependency
|
|
126
|
+
name: childprocess
|
|
127
|
+
requirement: !ruby/object:Gem::Requirement
|
|
128
|
+
requirements:
|
|
129
|
+
- - "~>"
|
|
130
|
+
- !ruby/object:Gem::Version
|
|
131
|
+
version: '0.5'
|
|
101
132
|
type: :runtime
|
|
102
|
-
version_requirements: *id010
|
|
103
|
-
- !ruby/object:Gem::Dependency
|
|
104
|
-
name: celluloid
|
|
105
133
|
prerelease: false
|
|
106
|
-
|
|
107
|
-
requirements:
|
|
108
|
-
- - ~>
|
|
109
|
-
- !ruby/object:Gem::Version
|
|
110
|
-
version:
|
|
134
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
135
|
+
requirements:
|
|
136
|
+
- - "~>"
|
|
137
|
+
- !ruby/object:Gem::Version
|
|
138
|
+
version: '0.5'
|
|
139
|
+
- !ruby/object:Gem::Dependency
|
|
140
|
+
name: celluloid
|
|
141
|
+
requirement: !ruby/object:Gem::Requirement
|
|
142
|
+
requirements:
|
|
143
|
+
- - "~>"
|
|
144
|
+
- !ruby/object:Gem::Version
|
|
145
|
+
version: '0.16'
|
|
111
146
|
type: :runtime
|
|
112
|
-
version_requirements: *id011
|
|
113
|
-
- !ruby/object:Gem::Dependency
|
|
114
|
-
name: rugged
|
|
115
147
|
prerelease: false
|
|
116
|
-
|
|
117
|
-
requirements:
|
|
118
|
-
- - ~>
|
|
119
|
-
- !ruby/object:Gem::Version
|
|
120
|
-
version:
|
|
148
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
149
|
+
requirements:
|
|
150
|
+
- - "~>"
|
|
151
|
+
- !ruby/object:Gem::Version
|
|
152
|
+
version: '0.16'
|
|
153
|
+
- !ruby/object:Gem::Dependency
|
|
154
|
+
name: rugged
|
|
155
|
+
requirement: !ruby/object:Gem::Requirement
|
|
156
|
+
requirements:
|
|
157
|
+
- - "~>"
|
|
158
|
+
- !ruby/object:Gem::Version
|
|
159
|
+
version: '0.21'
|
|
121
160
|
type: :runtime
|
|
122
|
-
version_requirements: *id012
|
|
123
|
-
- !ruby/object:Gem::Dependency
|
|
124
|
-
name: octokit
|
|
125
161
|
prerelease: false
|
|
126
|
-
|
|
127
|
-
requirements:
|
|
128
|
-
- - ~>
|
|
129
|
-
- !ruby/object:Gem::Version
|
|
130
|
-
version:
|
|
162
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
163
|
+
requirements:
|
|
164
|
+
- - "~>"
|
|
165
|
+
- !ruby/object:Gem::Version
|
|
166
|
+
version: '0.21'
|
|
167
|
+
- !ruby/object:Gem::Dependency
|
|
168
|
+
name: octokit
|
|
169
|
+
requirement: !ruby/object:Gem::Requirement
|
|
170
|
+
requirements:
|
|
171
|
+
- - "~>"
|
|
172
|
+
- !ruby/object:Gem::Version
|
|
173
|
+
version: '3.6'
|
|
131
174
|
type: :runtime
|
|
132
|
-
version_requirements: *id013
|
|
133
|
-
- !ruby/object:Gem::Dependency
|
|
134
|
-
name: bundler
|
|
135
175
|
prerelease: false
|
|
136
|
-
|
|
137
|
-
requirements:
|
|
138
|
-
- - ~>
|
|
139
|
-
- !ruby/object:Gem::Version
|
|
140
|
-
version:
|
|
176
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
177
|
+
requirements:
|
|
178
|
+
- - "~>"
|
|
179
|
+
- !ruby/object:Gem::Version
|
|
180
|
+
version: '3.6'
|
|
181
|
+
- !ruby/object:Gem::Dependency
|
|
182
|
+
name: bundler
|
|
183
|
+
requirement: !ruby/object:Gem::Requirement
|
|
184
|
+
requirements:
|
|
185
|
+
- - "~>"
|
|
186
|
+
- !ruby/object:Gem::Version
|
|
187
|
+
version: '1.7'
|
|
141
188
|
type: :development
|
|
142
|
-
version_requirements: *id014
|
|
143
|
-
- !ruby/object:Gem::Dependency
|
|
144
|
-
name: jeweler
|
|
145
189
|
prerelease: false
|
|
146
|
-
|
|
147
|
-
requirements:
|
|
148
|
-
- - ~>
|
|
149
|
-
- !ruby/object:Gem::Version
|
|
150
|
-
version:
|
|
190
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
191
|
+
requirements:
|
|
192
|
+
- - "~>"
|
|
193
|
+
- !ruby/object:Gem::Version
|
|
194
|
+
version: '1.7'
|
|
195
|
+
- !ruby/object:Gem::Dependency
|
|
196
|
+
name: jeweler
|
|
197
|
+
requirement: !ruby/object:Gem::Requirement
|
|
198
|
+
requirements:
|
|
199
|
+
- - "~>"
|
|
200
|
+
- !ruby/object:Gem::Version
|
|
201
|
+
version: '2.0'
|
|
151
202
|
type: :development
|
|
152
|
-
version_requirements: *id015
|
|
153
|
-
- !ruby/object:Gem::Dependency
|
|
154
|
-
name: rspec
|
|
155
203
|
prerelease: false
|
|
156
|
-
|
|
157
|
-
requirements:
|
|
158
|
-
- - ~>
|
|
159
|
-
- !ruby/object:Gem::Version
|
|
160
|
-
version:
|
|
204
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
205
|
+
requirements:
|
|
206
|
+
- - "~>"
|
|
207
|
+
- !ruby/object:Gem::Version
|
|
208
|
+
version: '2.0'
|
|
209
|
+
- !ruby/object:Gem::Dependency
|
|
210
|
+
name: rspec
|
|
211
|
+
requirement: !ruby/object:Gem::Requirement
|
|
212
|
+
requirements:
|
|
213
|
+
- - "~>"
|
|
214
|
+
- !ruby/object:Gem::Version
|
|
215
|
+
version: '3.1'
|
|
161
216
|
type: :development
|
|
162
|
-
version_requirements: *id016
|
|
163
|
-
- !ruby/object:Gem::Dependency
|
|
164
|
-
name: rdoc
|
|
165
217
|
prerelease: false
|
|
166
|
-
|
|
167
|
-
requirements:
|
|
168
|
-
- - ~>
|
|
169
|
-
- !ruby/object:Gem::Version
|
|
170
|
-
version:
|
|
218
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
219
|
+
requirements:
|
|
220
|
+
- - "~>"
|
|
221
|
+
- !ruby/object:Gem::Version
|
|
222
|
+
version: '3.1'
|
|
223
|
+
- !ruby/object:Gem::Dependency
|
|
224
|
+
name: rdoc
|
|
225
|
+
requirement: !ruby/object:Gem::Requirement
|
|
226
|
+
requirements:
|
|
227
|
+
- - "~>"
|
|
228
|
+
- !ruby/object:Gem::Version
|
|
229
|
+
version: '3.12'
|
|
171
230
|
type: :development
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
231
|
+
prerelease: false
|
|
232
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
233
|
+
requirements:
|
|
234
|
+
- - "~>"
|
|
235
|
+
- !ruby/object:Gem::Version
|
|
236
|
+
version: '3.12'
|
|
237
|
+
description: |2
|
|
238
|
+
|
|
239
|
+
A framework that provides a simple foundation for building Ruby applications that are:
|
|
240
|
+
|
|
241
|
+
* Highly configurable (with both distributed and persistent configurations)
|
|
242
|
+
* Extremely pluggable and extendable
|
|
243
|
+
* Easily parallel
|
|
244
|
+
|
|
245
|
+
Note: This framework is still very early in development!
|
|
179
246
|
email: adrian.webb@coralnexus.com
|
|
180
|
-
executables:
|
|
247
|
+
executables:
|
|
181
248
|
- nucleon
|
|
182
249
|
extensions: []
|
|
183
|
-
|
|
184
|
-
extra_rdoc_files:
|
|
250
|
+
extra_rdoc_files:
|
|
185
251
|
- LICENSE.txt
|
|
186
252
|
- README.rdoc
|
|
187
|
-
files:
|
|
188
|
-
- .gitignore
|
|
189
|
-
- .gitmodules
|
|
253
|
+
files:
|
|
254
|
+
- ".gitignore"
|
|
255
|
+
- ".gitmodules"
|
|
190
256
|
- ARCHITECTURE.rdoc
|
|
191
257
|
- Gemfile
|
|
192
258
|
- Gemfile.lock
|
|
@@ -271,36 +337,33 @@ files:
|
|
|
271
337
|
- spec/nucleon_test.rb
|
|
272
338
|
- spec/spec_helper.rb
|
|
273
339
|
homepage: http://github.com/coralnexus/nucleon
|
|
274
|
-
licenses:
|
|
340
|
+
licenses:
|
|
275
341
|
- Apache License, Version 2.0
|
|
276
342
|
metadata: {}
|
|
277
|
-
|
|
278
343
|
post_install_message:
|
|
279
|
-
rdoc_options:
|
|
280
|
-
- --title
|
|
344
|
+
rdoc_options:
|
|
345
|
+
- "--title"
|
|
281
346
|
- Nucleon
|
|
282
|
-
- --main
|
|
347
|
+
- "--main"
|
|
283
348
|
- README.rdoc
|
|
284
|
-
- --line-numbers
|
|
285
|
-
require_paths:
|
|
349
|
+
- "--line-numbers"
|
|
350
|
+
require_paths:
|
|
286
351
|
- lib
|
|
287
|
-
required_ruby_version: !ruby/object:Gem::Requirement
|
|
288
|
-
requirements:
|
|
352
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
|
353
|
+
requirements:
|
|
289
354
|
- - ">="
|
|
290
|
-
- !ruby/object:Gem::Version
|
|
355
|
+
- !ruby/object:Gem::Version
|
|
291
356
|
version: 1.9.1
|
|
292
|
-
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
293
|
-
requirements:
|
|
357
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
358
|
+
requirements:
|
|
294
359
|
- - ">="
|
|
295
|
-
- !ruby/object:Gem::Version
|
|
296
|
-
version:
|
|
360
|
+
- !ruby/object:Gem::Version
|
|
361
|
+
version: '0'
|
|
297
362
|
requirements: []
|
|
298
|
-
|
|
299
363
|
rubyforge_project: nucleon
|
|
300
|
-
rubygems_version: 2.4.
|
|
364
|
+
rubygems_version: 2.4.3
|
|
301
365
|
signing_key:
|
|
302
366
|
specification_version: 4
|
|
303
367
|
summary: Easy and minimal framework for building extensible distributed applications
|
|
304
368
|
test_files: []
|
|
305
|
-
|
|
306
369
|
has_rdoc:
|