zygote 0.1.5 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 2994a2e5d4616b4b1b0c39f9796f733a65ef5d76
4
- data.tar.gz: 591d695efd51df62d38be73844ef4555fe21ccee
3
+ metadata.gz: b78db9a651e1cda67167ffa88e926df3cab9fd62
4
+ data.tar.gz: ba8540429aa499f8613f0b1964d2a50886bf9155
5
5
  SHA512:
6
- metadata.gz: d09fd0845bb835e317aa70f84658abf38e6ae41066ef15a0c57f59ecc1eab924e2e2626aab4580a2a43e2754f4ddae5fd3ccfe026d899e3df2705f9310721256
7
- data.tar.gz: 697211d6109bdb7607b55fba918cc417b9012f12f475e12ccd1bf2b613178ca3959f31d4264505668042782be15254c857634e02d0c5ed3bab4bc420402eec54
6
+ metadata.gz: e792b386ece097ebdbe99cc518d2ae714389d04637bf8c24f8185ce4b830b2e3f78705c70c7721d7b1a153afb0cae3f8c3d8e14a7de04346b0d9316db0a18243
7
+ data.tar.gz: c02407331e5644fba8699cb9f98e5388f85923abb1dea8f83a2c05ed1ffdec42f206a5f338eec9258486b079d8a105041d718574d37157c3d34518fb18c59c23
@@ -2,3 +2,4 @@ $LOAD_PATH.unshift(File.expand_path('../lib', __FILE__))
2
2
 
3
3
  require 'zygote/version'
4
4
  require 'zygote/http'
5
+ require 'zygote/server'
@@ -1,24 +1,28 @@
1
1
  require 'yaml'
2
2
  require 'json'
3
- require 'genesisreactor'
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 < Genesis::Http::Handler
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
- get '/' do
20
+ aget '/' do
17
21
  body { erb :boot }
18
22
  end
19
23
 
20
24
  # Chainload the primary menu
21
- get '/chain' do
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
- get %r{/cell/(?<cell>\S*)/(?<action>\S*)$} do
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
- get %r{/queue/(?<sku>\S*)$} do
54
+ aget %r{/queue/(?<sku>\S*)$} do
53
55
  body { JSON.pretty_generate(CellQueue.show(params['sku'])) }
54
56
  end
55
57
 
56
- get %r{/queue} do
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
- delete %r{/queue$} do
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
- post %r{/queue/bulk$} do
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
- post %r{/queue/(?<sku>\S*)/(?<selected_cell>\S*)$} do
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 zygote(port: 7000, threads:1000, config_path: nil, cells: [], debug:false)
106
- debug ||= ENV['DEBUG']
107
-
108
- cell_config = YAML.load(File.read(config_path || File.join(Dir.pwd, 'config', 'cells.yml')))
109
- ZygoteWeb.cell_config = cell_config
110
- zygote = Genesis::Reactor.new(
111
- threads: threads,
112
- protocols: {
113
- Genesis::Http::Protocol => port
114
- },
115
- handlers: [ZygoteWeb],
116
- views: [File.expand_path('../../../views', __FILE__), cells].flatten,
117
- debug: debug
118
- )
119
- if debug
120
- $stdout.sync = true
121
- $stderr.sync = true
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
@@ -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', $0)).freeze
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
@@ -24,7 +24,7 @@ module Zygote
24
24
  mod.class_eval %[
25
25
  around(:each) do |example|
26
26
  EM.synchrony do
27
- zygote(
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://#{Socket.gethostname}:#{TestConfig.port}/", uriq)).aget(query: params))
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://#{Socket.gethostname}:#{TestConfig.port}/", uriq)).adelete(query: params))
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://#{Socket.gethostname}:#{TestConfig.port}/#{uri}").apost(body: params))
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)
@@ -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
- when 'DellInc'
14
- sku = 'DEL'
15
- when 'Supermicro'
16
- sku = 'SPM'
17
- else
18
- sku = 'UKN' # unknown manufacturer
19
- end
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
@@ -1,4 +1,4 @@
1
1
  # Namespace for our gem
2
2
  module Zygote
3
- VERSION = '0.1.5'
3
+ VERSION = '0.2.0'.freeze
4
4
  end
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.1.5
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: genesisreactor
28
+ name: supermodel
29
29
  requirement: !ruby/object:Gem::Requirement
30
30
  requirements:
31
31
  - - '='
32
32
  - !ruby/object:Gem::Version
33
- version: 0.0.5
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.0.5
40
+ version: 0.1.6
41
41
  - !ruby/object:Gem::Dependency
42
- name: supermodel
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: 0.1.6
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: 0.1.6
54
+ version: 1.1.2
55
55
  - !ruby/object:Gem::Dependency
56
- name: em-http-request
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.2
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.2
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