zygote 0.1.5 → 0.2.0
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.rb +1 -0
- data/lib/zygote/http.rb +53 -36
- data/lib/zygote/memory.rb +2 -2
- data/lib/zygote/server.rb +41 -0
- data/lib/zygote/test.rb +4 -4
- data/lib/zygote/util.rb +9 -9
- data/lib/zygote/version.rb +1 -1
- metadata +39 -10
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: b78db9a651e1cda67167ffa88e926df3cab9fd62
|
4
|
+
data.tar.gz: ba8540429aa499f8613f0b1964d2a50886bf9155
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: e792b386ece097ebdbe99cc518d2ae714389d04637bf8c24f8185ce4b830b2e3f78705c70c7721d7b1a153afb0cae3f8c3d8e14a7de04346b0d9316db0a18243
|
7
|
+
data.tar.gz: c02407331e5644fba8699cb9f98e5388f85923abb1dea8f83a2c05ed1ffdec42f206a5f338eec9258486b079d8a105041d718574d37157c3d34518fb18c59c23
|
data/lib/zygote.rb
CHANGED
data/lib/zygote/http.rb
CHANGED
@@ -1,24 +1,28 @@
|
|
1
1
|
require 'yaml'
|
2
2
|
require 'json'
|
3
|
-
|
4
|
-
require 'genesis/protocol/http'
|
3
|
+
|
5
4
|
require 'active_support/all'
|
5
|
+
require 'sinatra/async'
|
6
|
+
require 'tilt/erubis'
|
6
7
|
|
7
8
|
require 'zygote/util'
|
8
9
|
require 'zygote/cell_queue'
|
9
10
|
|
10
11
|
# Main HTTP class, handles routing methods
|
11
12
|
# Uses sinatra format (all sinatra docs on routing methods apply)
|
12
|
-
class ZygoteWeb <
|
13
|
+
class ZygoteWeb < Sinatra::Base
|
14
|
+
register Sinatra::Async
|
15
|
+
|
16
|
+
set :show_exceptions, ENV['DEBUG'] || false
|
13
17
|
# Requested by iPXE on boot, chains into /boot.
|
14
18
|
# This enables us to customize what details we want iPXE to send us
|
15
19
|
# The iPXE undionly.kpxe should contain an embedded script to call this URL
|
16
|
-
|
20
|
+
aget '/' do
|
17
21
|
body { erb :boot }
|
18
22
|
end
|
19
23
|
|
20
24
|
# Chainload the primary menu
|
21
|
-
|
25
|
+
aget '/chain' do
|
22
26
|
# Clean params into a simple hash
|
23
27
|
cleaned = clean_params(params.to_h)
|
24
28
|
# Add the request ip into the params
|
@@ -31,12 +35,11 @@ class ZygoteWeb < Genesis::Http::Handler
|
|
31
35
|
# Check if there are is any queued data for this SKU, and if so, merge it in to params
|
32
36
|
queued_data = CellQueue.shift(sku)
|
33
37
|
cleaned.merge!(queued_data) if queued_data
|
34
|
-
@channel << cleaned
|
35
38
|
body { erb :menu, locals: { opts: ZygoteWeb.cell_config.merge('params' => cleaned || {}) } }
|
36
39
|
end
|
37
40
|
|
38
41
|
# Render an action for a particular cell
|
39
|
-
|
42
|
+
aget %r{/cell/(?<cell>\S*)/(?<action>\S*)$} do
|
40
43
|
# Clean params into a simple hash
|
41
44
|
cleaned = clean_params(params.to_h)
|
42
45
|
# Add the cell to the parameters
|
@@ -44,16 +47,15 @@ class ZygoteWeb < Genesis::Http::Handler
|
|
44
47
|
# Merge the cleaned params in with any cell options
|
45
48
|
cell_opts = ZygoteWeb.cell_config['index']['cells'][cell] || {}
|
46
49
|
opts = cell_opts.merge('params' => cleaned || {})
|
47
|
-
@channel << opts # for debugging
|
48
50
|
body { erb :"#{cell}/#{cleaned['action']}".to_sym, locals: { opts: opts } }
|
49
51
|
end
|
50
52
|
|
51
53
|
# Show the queue for a SKU
|
52
|
-
|
54
|
+
aget %r{/queue/(?<sku>\S*)$} do
|
53
55
|
body { JSON.pretty_generate(CellQueue.show(params['sku'])) }
|
54
56
|
end
|
55
57
|
|
56
|
-
|
58
|
+
aget %r{/queue} do
|
57
59
|
response = {}
|
58
60
|
CellQueue.all.each do |queue_entry|
|
59
61
|
response[queue_entry.name] = queue_entry.data
|
@@ -62,12 +64,12 @@ class ZygoteWeb < Genesis::Http::Handler
|
|
62
64
|
end
|
63
65
|
|
64
66
|
# Delete the queue for a SKU
|
65
|
-
|
67
|
+
adelete %r{/queue$} do
|
66
68
|
CellQueue.purge(params['sku'])
|
67
69
|
body { JSON.pretty_generate(CellQueue.show(params['sku'])) }
|
68
70
|
end
|
69
71
|
|
70
|
-
|
72
|
+
apost %r{/queue/bulk$} do
|
71
73
|
bulk_queue = JSON.parse(request.body.read)
|
72
74
|
bulk_queue.each do |asset, queue|
|
73
75
|
queue = [queue] unless queue.is_a?(Array)
|
@@ -80,7 +82,7 @@ class ZygoteWeb < Genesis::Http::Handler
|
|
80
82
|
end
|
81
83
|
|
82
84
|
# Enable push cells (with optional data) to the cell queue for a SKU
|
83
|
-
|
85
|
+
apost %r{/queue/(?<sku>\S*)/(?<selected_cell>\S*)$} do
|
84
86
|
# Clean params into a simple hash
|
85
87
|
cleaned = clean_params(params.to_h)
|
86
88
|
# Enqueue some data for this sku
|
@@ -89,10 +91,6 @@ class ZygoteWeb < Genesis::Http::Handler
|
|
89
91
|
body { JSON.pretty_generate(CellQueue.show(sku)) }
|
90
92
|
end
|
91
93
|
|
92
|
-
subscribe do |args|
|
93
|
-
puts args if ENV['DEBUG']
|
94
|
-
end
|
95
|
-
|
96
94
|
def self::cell_config
|
97
95
|
@@cell_config
|
98
96
|
end
|
@@ -100,25 +98,44 @@ class ZygoteWeb < Genesis::Http::Handler
|
|
100
98
|
def self::cell_config=(value)
|
101
99
|
@@cell_config = value
|
102
100
|
end
|
103
|
-
end
|
104
101
|
|
105
|
-
def
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
102
|
+
def self::views
|
103
|
+
@@views
|
104
|
+
end
|
105
|
+
|
106
|
+
def self::views=(value)
|
107
|
+
@@views = value
|
108
|
+
end
|
109
|
+
|
110
|
+
helpers do
|
111
|
+
# Enable partial template rendering
|
112
|
+
def partial(template, locals = {})
|
113
|
+
erb(template, layout: false, locals: locals)
|
114
|
+
end
|
115
|
+
|
116
|
+
# Override template search directorys to add spells
|
117
|
+
def find_template(_views, *a, &block)
|
118
|
+
Array(ZygoteWeb.views).each { |v| super(v, *a, &block) }
|
119
|
+
end
|
120
|
+
|
121
|
+
# Define our asynchronous scheduling mechanism, could be anything
|
122
|
+
# Chose EM.defer for simplicity
|
123
|
+
# This powers our asynchronous requests, and keeps us from blocking the main thread.
|
124
|
+
def native_async_schedule(&b)
|
125
|
+
EM.defer(&b)
|
126
|
+
end
|
127
|
+
|
128
|
+
# Needed to properly catch exceptions in async threads
|
129
|
+
def handle_exception!(context)
|
130
|
+
if context.message == 'Sinatra::NotFound'
|
131
|
+
error_msg = "Resource #{request.path} does not exist"
|
132
|
+
puts error_msg
|
133
|
+
ahalt(404, error_msg)
|
134
|
+
else
|
135
|
+
puts context.message
|
136
|
+
puts context.backtrace.join("\n")
|
137
|
+
ahalt(500, 'Uncaught exception occurred')
|
138
|
+
end
|
139
|
+
end
|
122
140
|
end
|
123
|
-
zygote
|
124
141
|
end
|
data/lib/zygote/memory.rb
CHANGED
@@ -8,11 +8,11 @@ require 'supermodel'
|
|
8
8
|
# https://github.com/maccman/supermodel/blob/master/README
|
9
9
|
module Memory
|
10
10
|
extend self
|
11
|
-
DATABASE_PATH = (ENV['DATABASE_PATH'] || File.expand_path('../data/memory.db', $
|
11
|
+
DATABASE_PATH = (ENV['DATABASE_PATH'] || File.expand_path('../data/memory.db', $PROGRAM_NAME)).freeze
|
12
12
|
SuperModel::Marshal.path = DATABASE_PATH
|
13
13
|
|
14
14
|
def save
|
15
|
-
FileUtils.mkdir_p(File.dirname(DATABASE_PATH)) # FIXME - don't make if it already exists
|
15
|
+
FileUtils.mkdir_p(File.dirname(DATABASE_PATH)) # FIXME: - don't make if it already exists
|
16
16
|
SuperModel::Marshal.dump
|
17
17
|
end
|
18
18
|
|
@@ -0,0 +1,41 @@
|
|
1
|
+
require 'zygote/http'
|
2
|
+
require 'thin'
|
3
|
+
|
4
|
+
class ZygoteServer
|
5
|
+
def initialize(port: 7000, threads:1000, host: '0.0.0.0', config_path: nil, cells: [], debug:false)
|
6
|
+
debug ||= ENV['DEBUG']
|
7
|
+
|
8
|
+
cell_config = YAML.load(File.read(config_path || File.join(Dir.pwd, 'config', 'cells.yml')))
|
9
|
+
ZygoteWeb.views = [File.expand_path('../../../views', __FILE__), cells].flatten
|
10
|
+
ZygoteWeb.cell_config = cell_config
|
11
|
+
if debug
|
12
|
+
$stdout.sync = true
|
13
|
+
$stderr.sync = true
|
14
|
+
end
|
15
|
+
|
16
|
+
app = ZygoteWeb.new
|
17
|
+
dispatch = Rack::Builder.app do
|
18
|
+
map '/' do
|
19
|
+
run app
|
20
|
+
end
|
21
|
+
end
|
22
|
+
@server = Thin::Server.new(port, host, dispatch, threadpool_size: threads).backend
|
23
|
+
end
|
24
|
+
|
25
|
+
def start
|
26
|
+
@server.start
|
27
|
+
end
|
28
|
+
|
29
|
+
def run
|
30
|
+
EM.run do
|
31
|
+
init_sighandlers
|
32
|
+
@server.start
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
def init_sighandlers
|
38
|
+
trap(:INT) { 'Got interrupt'; EM.stop; exit }
|
39
|
+
trap(:TERM) { 'Got term'; EM.stop; exit }
|
40
|
+
trap(:KILL) { 'Got kill'; EM.stop; exit }
|
41
|
+
end
|
data/lib/zygote/test.rb
CHANGED
@@ -24,7 +24,7 @@ module Zygote
|
|
24
24
|
mod.class_eval %[
|
25
25
|
around(:each) do |example|
|
26
26
|
EM.synchrony do
|
27
|
-
|
27
|
+
ZygoteServer.new(
|
28
28
|
config_path: TestConfig.config_path,
|
29
29
|
cells: TestConfig.cells
|
30
30
|
).start
|
@@ -59,18 +59,18 @@ module Zygote
|
|
59
59
|
# Returns EventMachine::HttpClient
|
60
60
|
def get(uri, params = {})
|
61
61
|
uriq = "#{uri}#{parameterize(params)}"
|
62
|
-
EM::Synchrony.sync(EventMachine::HttpRequest.new(File.join("http
|
62
|
+
EM::Synchrony.sync(EventMachine::HttpRequest.new(File.join("http://127.0.0.1:#{TestConfig.port}/", uriq)).aget(query: params))
|
63
63
|
end
|
64
64
|
|
65
65
|
# Returns EventMachine::HttpClient
|
66
66
|
def delete(uri, params = {})
|
67
67
|
uriq = "#{uri}#{parameterize(params)}"
|
68
|
-
EM::Synchrony.sync(EventMachine::HttpRequest.new(File.join("http
|
68
|
+
EM::Synchrony.sync(EventMachine::HttpRequest.new(File.join("http://127.0.0.1:#{TestConfig.port}/", uriq)).adelete(query: params))
|
69
69
|
end
|
70
70
|
|
71
71
|
# Returns EventMachine::HttpClient
|
72
72
|
def post(uri, params = {})
|
73
|
-
EM::Synchrony.sync(EventMachine::HttpRequest.new("http
|
73
|
+
EM::Synchrony.sync(EventMachine::HttpRequest.new("http://127.0.0.1:#{TestConfig.port}/#{uri}").apost(body: params))
|
74
74
|
end
|
75
75
|
|
76
76
|
def parameterize(params)
|
data/lib/zygote/util.rb
CHANGED
@@ -9,14 +9,14 @@ def compute_sku(vendor, serial, board_serial)
|
|
9
9
|
|
10
10
|
serial = board_serial unless board_serial.empty?
|
11
11
|
|
12
|
-
case vendor
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
12
|
+
sku = case vendor
|
13
|
+
when 'DellInc'
|
14
|
+
'DEL'
|
15
|
+
when 'Supermicro'
|
16
|
+
'SPM'
|
17
|
+
else
|
18
|
+
'UKN' # unknown manufacturer
|
19
|
+
end
|
20
20
|
|
21
21
|
sku = "#{sku}-#{serial}"
|
22
22
|
sku
|
@@ -36,5 +36,5 @@ def discover_domain
|
|
36
36
|
end
|
37
37
|
|
38
38
|
def kernel_params(hash)
|
39
|
-
hash.map{ |k,v| v == true ? k : "#{k}=#{v}" }.join(' ')
|
39
|
+
hash.map { |k, v| v == true ? k : "#{k}=#{v}" }.join(' ')
|
40
40
|
end
|
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.
|
4
|
+
version: 0.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Dale Hamel
|
@@ -25,47 +25,75 @@ dependencies:
|
|
25
25
|
- !ruby/object:Gem::Version
|
26
26
|
version: 0.2.0
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
|
-
name:
|
28
|
+
name: supermodel
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
30
30
|
requirements:
|
31
31
|
- - '='
|
32
32
|
- !ruby/object:Gem::Version
|
33
|
-
version: 0.
|
33
|
+
version: 0.1.6
|
34
34
|
type: :runtime
|
35
35
|
prerelease: false
|
36
36
|
version_requirements: !ruby/object:Gem::Requirement
|
37
37
|
requirements:
|
38
38
|
- - '='
|
39
39
|
- !ruby/object:Gem::Version
|
40
|
-
version: 0.
|
40
|
+
version: 0.1.6
|
41
41
|
- !ruby/object:Gem::Dependency
|
42
|
-
name:
|
42
|
+
name: em-http-request
|
43
43
|
requirement: !ruby/object:Gem::Requirement
|
44
44
|
requirements:
|
45
45
|
- - '='
|
46
46
|
- !ruby/object:Gem::Version
|
47
|
-
version:
|
47
|
+
version: 1.1.2
|
48
48
|
type: :runtime
|
49
49
|
prerelease: false
|
50
50
|
version_requirements: !ruby/object:Gem::Requirement
|
51
51
|
requirements:
|
52
52
|
- - '='
|
53
53
|
- !ruby/object:Gem::Version
|
54
|
-
version:
|
54
|
+
version: 1.1.2
|
55
55
|
- !ruby/object:Gem::Dependency
|
56
|
-
name:
|
56
|
+
name: async_sinatra
|
57
57
|
requirement: !ruby/object:Gem::Requirement
|
58
58
|
requirements:
|
59
59
|
- - '='
|
60
60
|
- !ruby/object:Gem::Version
|
61
|
-
version: 1.1
|
61
|
+
version: 1.2.1
|
62
62
|
type: :runtime
|
63
63
|
prerelease: false
|
64
64
|
version_requirements: !ruby/object:Gem::Requirement
|
65
65
|
requirements:
|
66
66
|
- - '='
|
67
67
|
- !ruby/object:Gem::Version
|
68
|
-
version: 1.1
|
68
|
+
version: 1.2.1
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: em-synchrony
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - '='
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: 1.0.4
|
76
|
+
type: :runtime
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - '='
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: 1.0.4
|
83
|
+
- !ruby/object:Gem::Dependency
|
84
|
+
name: thin
|
85
|
+
requirement: !ruby/object:Gem::Requirement
|
86
|
+
requirements:
|
87
|
+
- - ">="
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
version: 1.6.4
|
90
|
+
type: :runtime
|
91
|
+
prerelease: false
|
92
|
+
version_requirements: !ruby/object:Gem::Requirement
|
93
|
+
requirements:
|
94
|
+
- - ">="
|
95
|
+
- !ruby/object:Gem::Version
|
96
|
+
version: 1.6.4
|
69
97
|
- !ruby/object:Gem::Dependency
|
70
98
|
name: pry
|
71
99
|
requirement: !ruby/object:Gem::Requirement
|
@@ -146,6 +174,7 @@ files:
|
|
146
174
|
- lib/zygote/cell_queue.rb
|
147
175
|
- lib/zygote/http.rb
|
148
176
|
- lib/zygote/memory.rb
|
177
|
+
- lib/zygote/server.rb
|
149
178
|
- lib/zygote/test.rb
|
150
179
|
- lib/zygote/util.rb
|
151
180
|
- lib/zygote/version.rb
|