zygote 0.2.11 → 0.2.12
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 +4 -4
- data/lib/zygote/cell_queue.rb +39 -37
- data/lib/zygote/http.rb +105 -109
- data/lib/zygote/identifier.rb +35 -0
- data/lib/zygote/memory.rb +19 -16
- data/lib/zygote/server.rb +40 -31
- data/lib/zygote/test.rb +4 -2
- data/lib/zygote/util.rb +1 -1
- data/lib/zygote/version.rb +1 -1
- metadata +17 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 79f6d6d816134c8cfadd3335a62a59c5c199da29
|
4
|
+
data.tar.gz: 95426b7b07578c63f29d74c3eeb54385abe66ba1
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 59fbfb4088ae7fe0adbd49c0b5a172ce943d6cb20b5fa876f37277e01a0b16cce8bfeb905ed27e2281b1c9ceed6998131fb12fe67a8518bcd283f5f7b8577e07
|
7
|
+
data.tar.gz: dc120384aad70375fd37cb4ce71c9ca003f639c0e2b6045b7540cbe4c991862a254064912be1b48d8a9aed299eada522ec578aa2537c473e607c38ded37d0d3d
|
data/lib/zygote/cell_queue.rb
CHANGED
@@ -1,49 +1,51 @@
|
|
1
1
|
require 'zygote/memory'
|
2
2
|
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
3
|
+
module Zygote
|
4
|
+
# An entry into the queue
|
5
|
+
class CellQueueEntry < SuperModel::Base
|
6
|
+
include SuperModel::Marshal::Model
|
7
|
+
end
|
7
8
|
|
8
|
-
# A means of storing Cell queue data for a given sku
|
9
|
-
module CellQueue
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
9
|
+
# A means of storing Cell queue data for a given sku
|
10
|
+
module CellQueue
|
11
|
+
extend self
|
12
|
+
COLLECTION = :assets
|
13
|
+
ARRAY_KEY = :cell_queue
|
14
|
+
Memory.load
|
14
15
|
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
16
|
+
def push(key, data)
|
17
|
+
entry = CellQueueEntry.find_by_name(key)
|
18
|
+
unless entry
|
19
|
+
entry = CellQueueEntry.new(name: key, data: [])
|
20
|
+
entry.save
|
21
|
+
end
|
22
|
+
entry.data << data
|
19
23
|
entry.save
|
24
|
+
Memory.save
|
20
25
|
end
|
21
|
-
entry.data << data
|
22
|
-
entry.save
|
23
|
-
Memory.save
|
24
|
-
end
|
25
26
|
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
27
|
+
def shift(key)
|
28
|
+
entry = CellQueueEntry.find_by_name(key)
|
29
|
+
return nil unless entry
|
30
|
+
first = entry.data.shift
|
31
|
+
entry.save
|
32
|
+
Memory.save
|
33
|
+
first
|
34
|
+
end
|
34
35
|
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
36
|
+
def show(key)
|
37
|
+
entry = CellQueueEntry.find_by_name(key)
|
38
|
+
entry ? entry.data : []
|
39
|
+
end
|
39
40
|
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
41
|
+
def purge(key)
|
42
|
+
entry = CellQueueEntry.find_by_name(key)
|
43
|
+
entry.data = [] if entry
|
44
|
+
entry.save if entry
|
45
|
+
end
|
45
46
|
|
46
|
-
|
47
|
-
|
47
|
+
def all
|
48
|
+
CellQueueEntry.all
|
49
|
+
end
|
48
50
|
end
|
49
51
|
end
|
data/lib/zygote/http.rb
CHANGED
@@ -8,130 +8,126 @@ require 'rack/contrib'
|
|
8
8
|
|
9
9
|
require 'zygote/util'
|
10
10
|
require 'zygote/cell_queue'
|
11
|
+
require 'zygote/identifier'
|
12
|
+
|
13
|
+
# Main zygote container namespace
|
14
|
+
module Zygote
|
15
|
+
# Main HTTP class, handles routing methods
|
16
|
+
# Uses sinatra format (all sinatra docs on routing methods apply)
|
17
|
+
class Web < Sinatra::Base
|
18
|
+
register Sinatra::Async
|
19
|
+
|
20
|
+
use ::Rack::PostBodyContentTypeParser
|
21
|
+
|
22
|
+
# Throw exceptions so we can catch and nicely log them
|
23
|
+
set :raise_errors, true
|
24
|
+
set :show_exceptions, false
|
25
|
+
set :dump_errors, false
|
26
|
+
|
27
|
+
# Requested by iPXE on boot, chains into /boot.
|
28
|
+
# This enables us to customize what details we want iPXE to send us
|
29
|
+
# The iPXE undionly.kpxe should contain an embedded script to call this URL
|
30
|
+
aget '/' do
|
31
|
+
body { erb :boot }
|
32
|
+
end
|
11
33
|
|
12
|
-
#
|
13
|
-
|
14
|
-
class ZygoteWeb < Sinatra::Base
|
15
|
-
register Sinatra::Async
|
16
|
-
|
17
|
-
use ::Rack::PostBodyContentTypeParser
|
18
|
-
|
19
|
-
# Throw exceptions so we can catch and nicely log them
|
20
|
-
set :raise_errors, true
|
21
|
-
set :show_exceptions, false
|
22
|
-
set :dump_errors, false
|
23
|
-
|
24
|
-
# Requested by iPXE on boot, chains into /boot.
|
25
|
-
# This enables us to customize what details we want iPXE to send us
|
26
|
-
# The iPXE undionly.kpxe should contain an embedded script to call this URL
|
27
|
-
aget '/' do
|
28
|
-
body { erb :boot }
|
29
|
-
end
|
30
|
-
|
31
|
-
# Chainload the primary menu
|
32
|
-
aget '/chain' do
|
33
|
-
# Clean params into a simple hash
|
34
|
-
cleaned = clean_params(params.to_h)
|
35
|
-
# Add the request ip into the params
|
36
|
-
ip = request.ip == '127.0.0.1' ? @env['HTTP_X_FORWARDED_FOR'] : request.ip
|
37
|
-
ip = '127.0.0.1' if ENV['TESTING'] || ip.nil? || ip.empty?
|
38
|
-
cleaned['ip'] = ip
|
39
|
-
# Compute SKU from parameters
|
40
|
-
sku = compute_sku(cleaned['manufacturer'], cleaned['serial'], cleaned['board-serial'])
|
41
|
-
cleaned['sku'] = sku
|
42
|
-
# Check if there are is any queued data for this SKU, and if so, merge it in to params
|
43
|
-
queued_data = CellQueue.shift(sku)
|
44
|
-
cleaned.merge!(queued_data) if queued_data
|
45
|
-
body { erb :menu, locals: { opts: ZygoteWeb.cell_config.merge('params' => cleaned || {}) } }
|
46
|
-
end
|
47
|
-
|
48
|
-
[ :aget, :apost ].each do |method|
|
49
|
-
send method, %r{/cell/(?<cell>\S*)/(?<action>\S*)$} do
|
50
|
-
# Render an action for a particular cell
|
34
|
+
# Chainload the primary menu
|
35
|
+
aget '/chain' do
|
51
36
|
# Clean params into a simple hash
|
52
37
|
cleaned = clean_params(params.to_h)
|
53
|
-
# Add the
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
38
|
+
# Add the request ip into the params
|
39
|
+
ip = request.ip == '127.0.0.1' ? @env['HTTP_X_FORWARDED_FOR'] : request.ip
|
40
|
+
ip = '127.0.0.1' if ENV['TESTING'] || ip.nil? || ip.empty?
|
41
|
+
cleaned['ip'] = ip
|
42
|
+
# Compute SKU from parameters
|
43
|
+
sku = compute_sku(cleaned['manufacturer'], cleaned['serial'], cleaned['board-serial'])
|
44
|
+
cleaned['sku'] = sku
|
45
|
+
# Check if there are is any queued data for this SKU, and if so, merge it in to params
|
46
|
+
queued_data = CellQueue.shift(sku)
|
47
|
+
cleaned.merge!(queued_data) if queued_data
|
48
|
+
|
49
|
+
# Provide a hook for an external identifier to alter behavior
|
50
|
+
cleaned = Zygote::Identifier.identify(cleaned)
|
51
|
+
body { erb :menu, locals: { opts: Zygote::Web.cell_config.merge('params' => cleaned || {}) } }
|
59
52
|
end
|
60
|
-
end
|
61
|
-
|
62
|
-
# Show the queue for a SKU
|
63
|
-
aget %r{/queue/(?<sku>\S*)$} do
|
64
|
-
body { JSON.pretty_generate(CellQueue.show(params['sku'])) }
|
65
|
-
end
|
66
53
|
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
54
|
+
[:aget, :apost].each do |method|
|
55
|
+
send method, %r{/cell/(?<cell>\S*)/(?<action>\S*)$} do
|
56
|
+
# Render an action for a particular cell
|
57
|
+
# Clean params into a simple hash
|
58
|
+
cleaned = clean_params(params.to_h)
|
59
|
+
# Add the cell to the parameters
|
60
|
+
cell = cleaned['cell']
|
61
|
+
# Merge the cleaned params in with any cell options
|
62
|
+
cell_opts = Zygote::Web.cell_config['index']['cells'][cell] || {}
|
63
|
+
opts = cell_opts.merge('params' => cleaned || {})
|
64
|
+
body { erb :"#{cell}/#{cleaned['action']}".to_sym, locals: { opts: opts } }
|
65
|
+
end
|
71
66
|
end
|
72
|
-
body { JSON.pretty_generate(response) }
|
73
|
-
end
|
74
|
-
|
75
|
-
# Delete the queue for a SKU
|
76
|
-
adelete %r{/queue$} do
|
77
|
-
CellQueue.purge(params['sku'])
|
78
|
-
body { JSON.pretty_generate(CellQueue.show(params['sku'])) }
|
79
|
-
end
|
80
|
-
|
81
|
-
# Enable push cells (with optional data) to the cell queue for a SKU
|
82
|
-
apost %r{/queue/(?<sku>\S*)/(?<selected_cell>\S*)$} do
|
83
|
-
# Clean params into a simple hash
|
84
|
-
cleaned = clean_params(params.to_h)
|
85
|
-
# Enqueue some data for this sku
|
86
|
-
sku = cleaned.delete('sku')
|
87
|
-
CellQueue.push(sku, cleaned)
|
88
|
-
body { JSON.pretty_generate(CellQueue.show(sku)) }
|
89
|
-
end
|
90
|
-
|
91
|
-
def self::cell_config
|
92
|
-
@@cell_config
|
93
|
-
end
|
94
|
-
|
95
|
-
def self::cell_config=(value)
|
96
|
-
@@cell_config = value
|
97
|
-
end
|
98
67
|
|
99
|
-
|
100
|
-
|
101
|
-
|
68
|
+
# Show the queue for a SKU
|
69
|
+
aget %r{/queue/(?<sku>\S*)$} do
|
70
|
+
body { JSON.pretty_generate(CellQueue.show(params['sku'])) }
|
71
|
+
end
|
102
72
|
|
103
|
-
|
104
|
-
|
105
|
-
|
73
|
+
aget %r{/queue} do
|
74
|
+
response = {}
|
75
|
+
CellQueue.all.each do |queue_entry|
|
76
|
+
response[queue_entry.name] = queue_entry.data
|
77
|
+
end
|
78
|
+
body { JSON.pretty_generate(response) }
|
79
|
+
end
|
106
80
|
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
81
|
+
# Delete the queue for a SKU
|
82
|
+
adelete %r{/queue$} do
|
83
|
+
CellQueue.purge(params['sku'])
|
84
|
+
body { JSON.pretty_generate(CellQueue.show(params['sku'])) }
|
111
85
|
end
|
112
86
|
|
113
|
-
#
|
114
|
-
|
115
|
-
|
87
|
+
# Enable push cells (with optional data) to the cell queue for a SKU
|
88
|
+
apost %r{/queue/(?<sku>\S*)/(?<selected_cell>\S*)$} do
|
89
|
+
# Clean params into a simple hash
|
90
|
+
cleaned = clean_params(params.to_h)
|
91
|
+
# Enqueue some data for this sku
|
92
|
+
sku = cleaned.delete('sku')
|
93
|
+
CellQueue.push(sku, cleaned)
|
94
|
+
body { JSON.pretty_generate(CellQueue.show(sku)) }
|
116
95
|
end
|
117
96
|
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
def native_async_schedule(&b)
|
122
|
-
EM.defer(&b)
|
97
|
+
class << self
|
98
|
+
attr_accessor :cell_config
|
99
|
+
attr_accessor :views
|
123
100
|
end
|
124
101
|
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
102
|
+
helpers do
|
103
|
+
# Enable partial template rendering
|
104
|
+
def partial(template, locals = {})
|
105
|
+
erb(template.to_sym, layout: false, locals: locals)
|
106
|
+
end
|
107
|
+
|
108
|
+
# Override template search directorys to add spells
|
109
|
+
def find_template(_views, *a, &block)
|
110
|
+
Array(Zygote::Web.views).each { |v| super(v, *a, &block) }
|
111
|
+
end
|
112
|
+
|
113
|
+
# Define our asynchronous scheduling mechanism, could be anything
|
114
|
+
# Chose EM.defer for simplicity
|
115
|
+
# This powers our asynchronous requests, and keeps us from blocking the main thread.
|
116
|
+
def native_async_schedule(&b)
|
117
|
+
EM.defer(&b)
|
118
|
+
end
|
119
|
+
|
120
|
+
# Needed to properly catch exceptions in async threads
|
121
|
+
def handle_exception!(context)
|
122
|
+
if context.message == 'Sinatra::NotFound'
|
123
|
+
error_msg = "Resource #{request.path} does not exist"
|
124
|
+
puts error_msg
|
125
|
+
ahalt(404, error_msg)
|
126
|
+
else
|
127
|
+
puts context.message
|
128
|
+
puts context.backtrace.join("\n")
|
129
|
+
ahalt(500, 'Uncaught exception occurred')
|
130
|
+
end
|
135
131
|
end
|
136
132
|
end
|
137
133
|
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
module Zygote
|
2
|
+
# Provides a hook for identifiers to alter boot-time behavior
|
3
|
+
# To do so, extend this class with a new identify method.
|
4
|
+
# You may NOT define more than one identifier - the last one wins.
|
5
|
+
# class MyIdentifier < Zygote::Identifier
|
6
|
+
# def identify
|
7
|
+
# mutate_params(@params)
|
8
|
+
# end
|
9
|
+
# end
|
10
|
+
class Identifier
|
11
|
+
class << self
|
12
|
+
def inherited(subclass)
|
13
|
+
@identifier = subclass
|
14
|
+
end
|
15
|
+
|
16
|
+
def identify(params)
|
17
|
+
@identifier ||= self
|
18
|
+
@identifier.new(params).identify
|
19
|
+
end
|
20
|
+
|
21
|
+
def reset!
|
22
|
+
@identifier = self
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
def initialize(params)
|
27
|
+
@params = params
|
28
|
+
end
|
29
|
+
|
30
|
+
# Called only if this class is never subclassed
|
31
|
+
def identify
|
32
|
+
@params
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
data/lib/zygote/memory.rb
CHANGED
@@ -3,24 +3,27 @@ require 'fileutils'
|
|
3
3
|
|
4
4
|
require 'supermodel'
|
5
5
|
|
6
|
-
#
|
7
|
-
|
8
|
-
#
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
6
|
+
# Zygote container
|
7
|
+
module Zygote
|
8
|
+
# A simple means of persistence
|
9
|
+
# This can easily be swapped out for redis, but file-based is simpler and good enough for now
|
10
|
+
# https://github.com/maccman/supermodel/blob/master/README
|
11
|
+
module Memory
|
12
|
+
extend self
|
13
|
+
DATABASE_PATH = (ENV['DATABASE_PATH'] || File.expand_path('../data/memory.db', $PROGRAM_NAME)).freeze
|
14
|
+
SuperModel::Marshal.path = DATABASE_PATH
|
13
15
|
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
16
|
+
def save
|
17
|
+
FileUtils.mkdir_p(File.dirname(DATABASE_PATH)) # FIXME: - don't make if it already exists
|
18
|
+
SuperModel::Marshal.dump
|
19
|
+
end
|
18
20
|
|
19
|
-
|
20
|
-
|
21
|
+
def load
|
22
|
+
SuperModel::Marshal.load
|
23
|
+
end
|
21
24
|
end
|
22
|
-
end
|
23
25
|
|
24
|
-
at_exit do
|
25
|
-
|
26
|
+
at_exit do
|
27
|
+
Memory.save
|
28
|
+
end
|
26
29
|
end
|
data/lib/zygote/server.rb
CHANGED
@@ -1,44 +1,53 @@
|
|
1
1
|
require 'zygote/http'
|
2
2
|
require 'thin'
|
3
3
|
|
4
|
-
|
5
|
-
|
6
|
-
|
4
|
+
# Main zygote namespace
|
5
|
+
module Zygote
|
6
|
+
# Wrapper around thin / event machine to run zygote sinatra rack app in.
|
7
|
+
class Server
|
8
|
+
def initialize(port: 7000, threads: 1000, host: '0.0.0.0', config_path: nil, cells: [], debug: false)
|
9
|
+
debug ||= ENV['DEBUG']
|
7
10
|
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
11
|
+
cell_config = YAML.load(File.read(config_path || File.join(Dir.pwd, 'config', 'cells.yml')))
|
12
|
+
Zygote::Web.views = [File.expand_path('../../../views', __FILE__), cells].flatten
|
13
|
+
Zygote::Web.cell_config = cell_config
|
14
|
+
if debug
|
15
|
+
$stdout.sync = true
|
16
|
+
$stderr.sync = true
|
17
|
+
end
|
15
18
|
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
19
|
+
app = Zygote::Web.new
|
20
|
+
dispatch = Rack::Builder.app do
|
21
|
+
map '/' do
|
22
|
+
run app
|
23
|
+
end
|
20
24
|
end
|
25
|
+
Thin::Logging.trace = true if debug
|
26
|
+
@server = Thin::Server.new(port, host, dispatch, threadpool_size: threads).backend
|
21
27
|
end
|
22
|
-
Thin::Logging.trace=true if debug
|
23
|
-
@server = Thin::Server.new(port, host, dispatch, threadpool_size: threads).backend
|
24
|
-
end
|
25
28
|
|
26
|
-
|
27
|
-
@server.start
|
28
|
-
rescue => ex
|
29
|
-
puts ex
|
30
|
-
puts ex.backtrace.join("\n")
|
31
|
-
end
|
32
|
-
|
33
|
-
def run
|
34
|
-
EM.run do
|
35
|
-
init_sighandlers
|
29
|
+
def start
|
36
30
|
@server.start
|
31
|
+
rescue => ex
|
32
|
+
puts ex
|
33
|
+
puts ex.backtrace.join("\n")
|
34
|
+
end
|
35
|
+
|
36
|
+
def run
|
37
|
+
EM.run do
|
38
|
+
init_sighandlers
|
39
|
+
@server.start
|
40
|
+
end
|
37
41
|
end
|
38
42
|
end
|
39
|
-
end
|
40
43
|
|
41
|
-
def init_sighandlers
|
42
|
-
|
43
|
-
|
44
|
+
def init_sighandlers
|
45
|
+
clean_quit = lambda do
|
46
|
+
EM.stop
|
47
|
+
exit
|
48
|
+
end
|
49
|
+
|
50
|
+
Signal.trap('INT') { clean_quit.call }
|
51
|
+
Signal.trap('TERM') { clean_quit.call }
|
52
|
+
end
|
44
53
|
end
|
data/lib/zygote/test.rb
CHANGED
@@ -6,7 +6,9 @@ require 'rspec'
|
|
6
6
|
require 'em-synchrony'
|
7
7
|
require 'em-synchrony/em-http'
|
8
8
|
|
9
|
+
# Main zygote class
|
9
10
|
module Zygote
|
11
|
+
# Helper to set up test config
|
10
12
|
module TestConfig
|
11
13
|
extend self
|
12
14
|
attr_reader :config_path, :cells, :port, :fixtures
|
@@ -24,7 +26,7 @@ module Zygote
|
|
24
26
|
mod.class_eval %[
|
25
27
|
around(:each) do |example|
|
26
28
|
EM.synchrony do
|
27
|
-
|
29
|
+
Zygote::Server.new(
|
28
30
|
config_path: TestConfig.config_path,
|
29
31
|
cells: TestConfig.cells
|
30
32
|
).start
|
@@ -70,7 +72,7 @@ module Zygote
|
|
70
72
|
|
71
73
|
# Returns EventMachine::HttpClient
|
72
74
|
def post(uri, params = {})
|
73
|
-
EM::Synchrony.sync(EventMachine::HttpRequest.new("http://127.0.0.1:#{TestConfig.port}/#{uri}").apost(body: JSON.dump(params), head: {'Content-Type' => 'application/json'}))
|
75
|
+
EM::Synchrony.sync(EventMachine::HttpRequest.new("http://127.0.0.1:#{TestConfig.port}/#{uri}").apost(body: JSON.dump(params), head: { 'Content-Type' => 'application/json' }))
|
74
76
|
end
|
75
77
|
|
76
78
|
def parameterize(params)
|
data/lib/zygote/util.rb
CHANGED
@@ -26,7 +26,7 @@ end
|
|
26
26
|
|
27
27
|
def clean_params(params)
|
28
28
|
params.delete_if { |x, _| x == 'splat' || x == 'captures' }
|
29
|
-
params = params.map { |k,v| [k, v.is_a?(Hash) ? encode64(v) : v] }.to_h
|
29
|
+
params = params.map { |k, v| [k, v.is_a?(Hash) ? encode64(v) : v] }.to_h
|
30
30
|
params
|
31
31
|
end
|
32
32
|
|
data/lib/zygote/version.rb
CHANGED
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: zygote
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.2.
|
4
|
+
version: 0.2.12
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Dale Hamel
|
@@ -178,6 +178,20 @@ dependencies:
|
|
178
178
|
- - '='
|
179
179
|
- !ruby/object:Gem::Version
|
180
180
|
version: 3.2.0
|
181
|
+
- !ruby/object:Gem::Dependency
|
182
|
+
name: rubocop
|
183
|
+
requirement: !ruby/object:Gem::Requirement
|
184
|
+
requirements:
|
185
|
+
- - "~>"
|
186
|
+
- !ruby/object:Gem::Version
|
187
|
+
version: 0.40.0
|
188
|
+
type: :development
|
189
|
+
prerelease: false
|
190
|
+
version_requirements: !ruby/object:Gem::Requirement
|
191
|
+
requirements:
|
192
|
+
- - "~>"
|
193
|
+
- !ruby/object:Gem::Version
|
194
|
+
version: 0.40.0
|
181
195
|
description: Automate baremetal server actions with iPXE
|
182
196
|
email: dale.hamel@srvthe.net
|
183
197
|
executables: []
|
@@ -187,6 +201,7 @@ files:
|
|
187
201
|
- lib/zygote.rb
|
188
202
|
- lib/zygote/cell_queue.rb
|
189
203
|
- lib/zygote/http.rb
|
204
|
+
- lib/zygote/identifier.rb
|
190
205
|
- lib/zygote/memory.rb
|
191
206
|
- lib/zygote/server.rb
|
192
207
|
- lib/zygote/test.rb
|
@@ -214,7 +229,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
214
229
|
version: '0'
|
215
230
|
requirements: []
|
216
231
|
rubyforge_project:
|
217
|
-
rubygems_version: 2.
|
232
|
+
rubygems_version: 2.2.3
|
218
233
|
signing_key:
|
219
234
|
specification_version: 4
|
220
235
|
summary: Differentiate servers with iPXE
|