spiderfw 0.6.6 → 0.6.7
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGELOG +4 -0
- data/VERSION +1 -1
- data/apps/master/_init.rb +2 -0
- data/apps/master/controllers/master_controller.rb +81 -24
- data/apps/master/models/command.rb +12 -5
- data/apps/master/models/event.rb +9 -0
- data/apps/master/views/installation.shtml +22 -0
- data/apps/servant/lib/client.rb +21 -7
- data/apps/servant/lib/commands_processor.rb +109 -0
- data/apps/servant/servant.rb +10 -0
- data/lib/spiderfw/cmd/commands/app.rb +25 -82
- data/lib/spiderfw/config/options/spider.rb +1 -1
- data/lib/spiderfw/controller/controller_exceptions.rb +3 -0
- data/lib/spiderfw/controller/first_responder.rb +5 -0
- data/lib/spiderfw/controller/home_controller.rb +1 -1
- data/lib/spiderfw/controller/mixins/http_mixin.rb +5 -2
- data/lib/spiderfw/controller/mixins/visual.rb +27 -12
- data/lib/spiderfw/http/server.rb +0 -1
- data/lib/spiderfw/setup/app_manager.rb +125 -2
- data/lib/spiderfw/spider.rb +23 -4
- data/views/errors/404.shtml +3 -0
- data/views/errors/simple.layout.shtml +16 -0
- data/views/generic.layout.shtml +16 -0
- data/views/maintenance.shtml +6 -0
- metadata +9 -4
data/CHANGELOG
CHANGED
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.6.
|
1
|
+
0.6.7
|
data/apps/master/_init.rb
CHANGED
@@ -14,6 +14,8 @@ require 'apps/master/master'
|
|
14
14
|
require 'apps/master/models/admin'
|
15
15
|
require 'apps/master/models/customer'
|
16
16
|
require 'apps/master/models/installation'
|
17
|
+
require 'apps/master/models/command'
|
18
|
+
require 'apps/master/models/event'
|
17
19
|
require 'apps/master/models/remote_log'
|
18
20
|
require 'apps/master/models/server'
|
19
21
|
require 'apps/master/models/scout_plugin_info'
|
@@ -18,7 +18,7 @@ module Spider; module Master
|
|
18
18
|
#route /servers\/([^\/]+)/, ServerController, :do => lambda{ |id| @request.misc[:server] = Server.new(id) }
|
19
19
|
route 'login', LoginController
|
20
20
|
|
21
|
-
require_user Master::Admin, :unless => [:login, :admin, :ping], :redirect => 'login'
|
21
|
+
require_user Master::Admin, :unless => [:login, :admin, :ping, :servant_event], :redirect => 'login'
|
22
22
|
require_user Spider::Auth::SuperUser, :only => [:admin]
|
23
23
|
|
24
24
|
|
@@ -118,28 +118,34 @@ module Spider; module Master
|
|
118
118
|
@installation = Installation.new(id) unless id == 'new'
|
119
119
|
@scene.edit = (@request.params['_w'] && @request.params['_w'].key?('installation_form')) || @request.params.key?('edit') || id == 'new'
|
120
120
|
@scene.pk = id
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
121
|
+
|
122
|
+
if @request.params['add_command']
|
123
|
+
command = @request.params['command']
|
124
|
+
args = @request.params['arguments']
|
125
|
+
arguments = args
|
126
|
+
# FIXME: move somewhere else
|
127
|
+
case command
|
128
|
+
when 'gems', 'apps'
|
129
|
+
arguments = args.split(/\s*,\s*/).to_json
|
130
|
+
end
|
131
|
+
Master::Command.create(
|
132
|
+
:installation => @installation,
|
133
|
+
:name => @request.params['command'],
|
134
|
+
:arguments => arguments,
|
135
|
+
:status => 'pending'
|
136
|
+
)
|
137
|
+
redirect(@request.path)
|
138
|
+
|
139
|
+
end
|
139
140
|
@scene.install_apps = JSON.parse(@installation.apps) unless @installation.apps.blank?
|
140
141
|
@scene.install_apps ||= []
|
141
142
|
@scene.apps = Spider::AppServer.apps_by_id
|
142
143
|
@scene.logs = RemoteLog.where(:installation => @installation)
|
144
|
+
@scene.commands = Master::Command.where{ |c| (c.installation == @installation) }.order_by(:obj_created)
|
145
|
+
@scene.available_commands = {
|
146
|
+
'gems' => _('Install or update gems'),
|
147
|
+
'apps' => _('Install or update apps')
|
148
|
+
}
|
143
149
|
@scene << {
|
144
150
|
:customer => @customer,
|
145
151
|
:installation => @installation
|
@@ -345,15 +351,66 @@ module Spider; module Master
|
|
345
351
|
RemoteLog.create(:text => desc, :level => level, :time => time, :installation => install)
|
346
352
|
end
|
347
353
|
response = {
|
348
|
-
:pong => DateTime.
|
354
|
+
:pong => DateTime.now
|
349
355
|
}
|
350
|
-
|
351
|
-
|
352
|
-
|
353
|
-
|
356
|
+
commands = []
|
357
|
+
Master::Command.where{ |c| (c.installation == install) & (c.status == 'pending') }.each do |c|
|
358
|
+
commands << {
|
359
|
+
:id => c.uuid,
|
360
|
+
:name => c.name,
|
361
|
+
:arguments => c.arguments ? JSON.parse(c.arguments) : nil
|
362
|
+
}
|
363
|
+
end
|
364
|
+
response[:commands] = commands unless commands.empty?
|
354
365
|
$out << response.to_json
|
366
|
+
Master::Command.where{ |c| (c.installation == install) & (c.status == 'pending') }.each do |c|
|
367
|
+
c.sent = DateTime.now
|
368
|
+
c.status = 'sent'
|
369
|
+
c.save
|
370
|
+
end
|
355
371
|
end
|
356
372
|
|
373
|
+
__.json
|
374
|
+
def servant_event
|
375
|
+
params = @request.params.clone
|
376
|
+
name = params.delete('event')
|
377
|
+
install_id = params.delete('install_id')
|
378
|
+
unless install_id
|
379
|
+
Spider.logger.error("No install_id passed in ping")
|
380
|
+
done
|
381
|
+
end
|
382
|
+
install = Spider::Master::Installation.load_or_create(:uuid => install_id)
|
383
|
+
details = @request.params['details']
|
384
|
+
params = JSON.parse(details)
|
385
|
+
Event.create(
|
386
|
+
:installation => install,
|
387
|
+
:name => name,
|
388
|
+
:details => details
|
389
|
+
)
|
390
|
+
case name.to_sym
|
391
|
+
when :command_done
|
392
|
+
cmd = Master::Command.load(:uuid => params['id'])
|
393
|
+
cmd.done = DateTime.now
|
394
|
+
cmd.result = params['res'].to_json
|
395
|
+
cmd.status = 'success'
|
396
|
+
cmd.save
|
397
|
+
when :plan_done
|
398
|
+
results = params['results']
|
399
|
+
results.each do |res|
|
400
|
+
cmd = Master::Command.load(:uuid => res['command_id'])
|
401
|
+
if res['previous_error']
|
402
|
+
cmd.status = 'not_done'
|
403
|
+
cmd.save
|
404
|
+
elsif res['error']
|
405
|
+
cmd.status = 'error'
|
406
|
+
cmd.save
|
407
|
+
end
|
408
|
+
end
|
409
|
+
end
|
410
|
+
end
|
411
|
+
|
412
|
+
|
413
|
+
|
357
414
|
private
|
358
415
|
|
359
416
|
def decompress_string(str)
|
@@ -1,17 +1,24 @@
|
|
1
1
|
module Spider; module Master
|
2
2
|
|
3
|
-
class Command < Spider::Model::
|
4
|
-
|
5
|
-
element :
|
3
|
+
class Command < Spider::Model::Managed
|
4
|
+
element :installation, Installation, :add_multiple_reverse => :commands
|
5
|
+
element :uuid, UUID
|
6
6
|
element :name, String
|
7
7
|
element :arguments, Text
|
8
8
|
element :status, {
|
9
9
|
'pending' => 'Pending',
|
10
|
+
'sent' => 'Sent',
|
10
11
|
'success' => 'Success',
|
11
|
-
'failure' => 'Failure'
|
12
|
+
'failure' => 'Failure',
|
13
|
+
'not_done' => 'Not done'
|
12
14
|
}, :default => 'pending'
|
13
|
-
element :
|
15
|
+
element :sent, DateTime
|
16
|
+
element :done, DateTime
|
14
17
|
element :result, Text
|
18
|
+
|
19
|
+
def to_s
|
20
|
+
"#{self.name} '#{self.arguments}' - #{self.status}"
|
21
|
+
end
|
15
22
|
end
|
16
23
|
|
17
24
|
end; end
|
@@ -20,6 +20,12 @@
|
|
20
20
|
<h2>_(Installation "%s") % [@installation]</h2>
|
21
21
|
<a href="?edit" class="manage edit">_(Edit)</a>
|
22
22
|
</div>
|
23
|
+
<div class="details">
|
24
|
+
_(Last check-in): { @installation.last_check.lformat(:short) }
|
25
|
+
<tpl:pass sp:if="@installation.interval">
|
26
|
+
_(Next check-in): { (@installation.last_check + @installation.interval).lformat(:short) }
|
27
|
+
</tpl:pass>
|
28
|
+
</div>
|
23
29
|
<core:tabs id="tabs">
|
24
30
|
<tab label="_(Apps)" id="apps">
|
25
31
|
<div class="apps">
|
@@ -43,6 +49,22 @@
|
|
43
49
|
<core:table id="logs_table" queryset="@logs" sort="time,desc" />
|
44
50
|
</div>
|
45
51
|
</tab>
|
52
|
+
<tab label="_(Commands)" id="commands">
|
53
|
+
<div class="commands">
|
54
|
+
<h4>_(Commands)</h4><a href="#" class="manage add">_(Add command)</a>
|
55
|
+
<div id="add_command">
|
56
|
+
<form>
|
57
|
+
<select name="command">
|
58
|
+
<option></option>
|
59
|
+
<option sp:each="@available_commands |k, v|" value="{ k }">{ v }</option>
|
60
|
+
</select>
|
61
|
+
<input type="text" name="arguments">
|
62
|
+
<input type="submit" name="add_command" value="_(Ok)">
|
63
|
+
</form>
|
64
|
+
</div>
|
65
|
+
<core:list id="commands_list" queryset="@commands" delete="true" />
|
66
|
+
</div>
|
67
|
+
</tab>
|
46
68
|
</core:tabs>
|
47
69
|
</div>
|
48
70
|
</div>
|
data/apps/servant/lib/client.rb
CHANGED
@@ -10,9 +10,14 @@ module Spider
|
|
10
10
|
def initialize(url)
|
11
11
|
@url = url
|
12
12
|
end
|
13
|
+
|
14
|
+
def http_client
|
15
|
+
HTTPClient.new
|
16
|
+
end
|
13
17
|
|
14
|
-
def ping_server(url
|
15
|
-
|
18
|
+
def ping_server(url=nil)
|
19
|
+
url ||= @url
|
20
|
+
clnt = self.http_client
|
16
21
|
status = Servant.status
|
17
22
|
status[:apps] = status[:apps].to_json
|
18
23
|
last_check_file = File.join(Spider.paths[:var], 'memory', 'servant_last_check')
|
@@ -29,15 +34,24 @@ module Spider
|
|
29
34
|
end
|
30
35
|
File.open(last_check_file, 'w'){ |f| f << Time.now.to_s }
|
31
36
|
res = JSON.parse(res.content)
|
32
|
-
if res[
|
33
|
-
|
34
|
-
|
35
|
-
clnt.post()
|
36
|
-
end
|
37
|
+
if res['commands']
|
38
|
+
processor = Servant.command_processor.new(url)
|
39
|
+
processor.run_commands(res['commands'])
|
37
40
|
end
|
38
41
|
end
|
39
42
|
|
43
|
+
def process_commands(commands)
|
44
|
+
end
|
45
|
+
|
46
|
+
def send_event(name, details)
|
47
|
+
self.http_client.post("#{@url}/servant_event", {
|
48
|
+
:event => name, :install_id => Servant.install_id, :details => details.to_json
|
49
|
+
})
|
50
|
+
end
|
51
|
+
|
52
|
+
|
40
53
|
private
|
54
|
+
|
41
55
|
|
42
56
|
def compress_string(str)
|
43
57
|
compr = ""
|
@@ -0,0 +1,109 @@
|
|
1
|
+
module Spider; module Servant
|
2
|
+
|
3
|
+
class CommandsProcessor
|
4
|
+
attr_reader :client
|
5
|
+
|
6
|
+
def self.plan_file
|
7
|
+
File.join(Spider.paths[:var], 'servant_command_plan')
|
8
|
+
end
|
9
|
+
|
10
|
+
def self.progress_file
|
11
|
+
File.join(Spider.paths[:var], 'servant_command_progress')
|
12
|
+
end
|
13
|
+
|
14
|
+
def self.save_plan(commands)
|
15
|
+
File.open(self.plan_file, 'w'){ |f| f << commands.to_json }
|
16
|
+
end
|
17
|
+
|
18
|
+
def self.read_plan
|
19
|
+
return nil unless File.exists?(self.plan_file)
|
20
|
+
JSON.parse(File.readfile(self.plan_file))
|
21
|
+
end
|
22
|
+
|
23
|
+
def self.unfinished_plan?
|
24
|
+
File.exists?(self.plan_file)
|
25
|
+
end
|
26
|
+
|
27
|
+
def initialize(master_url)
|
28
|
+
@url = master_url
|
29
|
+
@client = Servant::Client.new(@url)
|
30
|
+
@progress = {}
|
31
|
+
end
|
32
|
+
|
33
|
+
def resume_plan
|
34
|
+
plan = self.class.read_plan
|
35
|
+
progress = JSON.parse(File.read(self.progress_file)) if File.exists?(self.progress_file)
|
36
|
+
progress ||= {}
|
37
|
+
plan.reject!{ |c| progress[c['id']] }
|
38
|
+
process_commands(plan)
|
39
|
+
end
|
40
|
+
|
41
|
+
def save_progress
|
42
|
+
File.open(self.class.progress_file, 'w'){ |f| f << @progress.to_json }
|
43
|
+
end
|
44
|
+
|
45
|
+
def run_commands(commands)
|
46
|
+
self.class.save_plan(commands)
|
47
|
+
process_commands(commands)
|
48
|
+
end
|
49
|
+
|
50
|
+
def process_commands(commands)
|
51
|
+
results = []
|
52
|
+
error = nil
|
53
|
+
commands.each do |command|
|
54
|
+
command_result = {:command_id => command['id']}
|
55
|
+
if error
|
56
|
+
command_result[:previous_error] = true
|
57
|
+
else
|
58
|
+
begin
|
59
|
+
command_result[:res] = execute_command(command)
|
60
|
+
rescue => exc
|
61
|
+
error = exc.message
|
62
|
+
command_result[:error] = error
|
63
|
+
end
|
64
|
+
end
|
65
|
+
results << command_result
|
66
|
+
end
|
67
|
+
self.client.send_event(:plan_done, {:results => results})
|
68
|
+
File.unlink(self.class.plan_file) if File.exists?(self.class.plan_file)
|
69
|
+
File.unlink(self.class.progress_file) if File.exists?(self.class.progress_file)
|
70
|
+
end
|
71
|
+
|
72
|
+
def execute_command(command)
|
73
|
+
args = command["arguments"]
|
74
|
+
res = case command["name"]
|
75
|
+
when "gems"
|
76
|
+
install_gems(args)
|
77
|
+
when "apps"
|
78
|
+
install_apps(args)
|
79
|
+
when "configure"
|
80
|
+
|
81
|
+
end
|
82
|
+
@progress[command['id']] = true
|
83
|
+
save_progress
|
84
|
+
self.client.send_event(:command_done, {:id => command['id'], :res => res})
|
85
|
+
res
|
86
|
+
end
|
87
|
+
|
88
|
+
def install_gems(gems)
|
89
|
+
inst = Gem::DependencyInstaller.new
|
90
|
+
installed = []
|
91
|
+
gems.each do |g|
|
92
|
+
v = g['version'] || Gem::Requirement.default
|
93
|
+
unless Gem.available?(g['name'], v)
|
94
|
+
inst.install g['name'], v
|
95
|
+
installed << g
|
96
|
+
end
|
97
|
+
|
98
|
+
end
|
99
|
+
return {:installed => gems}
|
100
|
+
end
|
101
|
+
|
102
|
+
def install_apps(apps)
|
103
|
+
require 'spiderfw/setup/app_manager'
|
104
|
+
Spider::AppManager.install_or_update(apps)
|
105
|
+
end
|
106
|
+
|
107
|
+
end
|
108
|
+
|
109
|
+
end; end
|
data/apps/servant/servant.rb
CHANGED
@@ -1,9 +1,19 @@
|
|
1
1
|
require 'uuidtools'
|
2
|
+
require 'apps/servant/lib/client'
|
3
|
+
require 'apps/servant/lib/commands_processor'
|
2
4
|
|
3
5
|
module Spider
|
4
6
|
|
5
7
|
module Servant
|
8
|
+
|
9
|
+
def self.command_processor
|
10
|
+
@command_processor ||= Spider::Servant::CommandsProcessor
|
11
|
+
end
|
6
12
|
|
13
|
+
def self.command_processor=(klass)
|
14
|
+
@command_processor = klass
|
15
|
+
end
|
16
|
+
|
7
17
|
def self.install_id
|
8
18
|
uuid_file = File.join(Spider.paths[:var], 'install_id')
|
9
19
|
return File.read(uuid_file) if File.exists?(uuid_file)
|
@@ -5,7 +5,6 @@ class AppCommand < CmdParse::Command
|
|
5
5
|
super('app', true, true )
|
6
6
|
@short_desc = _("Manage apps")
|
7
7
|
|
8
|
-
@server_url = 'http://www.soluzionipa.it/euroservizi/spider/app_server'
|
9
8
|
|
10
9
|
self.options = CmdParse::OptionParserWrapper.new do |opt|
|
11
10
|
opt.on("--proxy [SERVER]", _("Proxy server to use (http://user:pass@host:port)"), "-p"){ |p|
|
@@ -57,6 +56,11 @@ class AppCommand < CmdParse::Command
|
|
57
56
|
end
|
58
57
|
if @remote
|
59
58
|
require 'spiderfw/setup/app_server_client'
|
59
|
+
unless @server_url
|
60
|
+
require 'spiderfw/spider'
|
61
|
+
Spider.init_base
|
62
|
+
@server_url = Spider.config.get('app_server.url')
|
63
|
+
end
|
60
64
|
client = Spider::AppServerClient.new(@server_url)
|
61
65
|
remote = {}
|
62
66
|
client.specs.each do |app|
|
@@ -119,56 +123,26 @@ class AppCommand < CmdParse::Command
|
|
119
123
|
puts _("Please execute this command from the home folder")
|
120
124
|
exit
|
121
125
|
end
|
122
|
-
require 'spiderfw/setup/app_server_client'
|
123
|
-
use_git = false
|
124
|
-
unless @no_git
|
125
|
-
begin
|
126
|
-
require 'grit'
|
127
|
-
use_git = true
|
128
|
-
rescue => exc
|
129
|
-
puts exc.message
|
130
|
-
puts "Grit not available; install Grit for Git support"
|
131
|
-
end
|
132
|
-
end
|
133
|
-
|
134
|
-
apps = args
|
135
|
-
existent = []
|
136
|
-
apps.each do |app|
|
137
|
-
if File.exist?("apps/#{app}")
|
138
|
-
puts _("%s already exists, skipping") % app
|
139
|
-
existent << app
|
140
|
-
end
|
141
|
-
end
|
142
126
|
require 'spiderfw/setup/app_manager'
|
143
|
-
specs = []
|
144
|
-
client = Spider::AppServerClient.new(@server_url)
|
145
|
-
if @no_deps
|
146
|
-
specs = client.get_specs(apps)
|
147
|
-
else
|
148
|
-
specs = client.get_deps(apps, :no_optional => @no_optional)
|
149
|
-
end
|
150
|
-
deps = specs.map{ |s| s.app_id }
|
151
|
-
unless (deps - apps).empty?
|
152
|
-
puts _("The following apps will be installed as a dependency:")
|
153
|
-
puts (deps - apps).inspect
|
154
|
-
end
|
155
127
|
options = {
|
156
|
-
:
|
157
|
-
:no_gems => @no_gems,
|
158
|
-
:no_optional_gems => @no_optional_gems
|
128
|
+
:no_git => @no_git, :all => @all, :no_deps => @no_deps, :no_optional => @no_optional,
|
129
|
+
:no_gems => @no_gems, :no_optional_gems => @no_optional_gems, :no_activate => @no_activate
|
159
130
|
}
|
160
|
-
options[:
|
161
|
-
|
162
|
-
Spider::AppManager.install(inst_specs, Dir.pwd, options)
|
163
|
-
unless @no_activate
|
164
|
-
require 'spiderfw/spider'
|
165
|
-
specs_hash = {}
|
166
|
-
specs.each{ |s| specs_hash[s.app_id] = s }
|
167
|
-
Spider.activate_apps(deps, specs_hash)
|
168
|
-
end
|
131
|
+
options[:url] = @server_url if @server_url
|
132
|
+
Spider::AppManager.install_apps(args, options)
|
169
133
|
end
|
170
134
|
self.add_command(install)
|
171
135
|
|
136
|
+
activate = CmdParse::Command.new('activate', false )
|
137
|
+
activate.short_desc = _("Activate an app")
|
138
|
+
activate.set_execution_block do |args|
|
139
|
+
apps = args
|
140
|
+
require 'spiderfw/spider'
|
141
|
+
apps = Spider.get_app_deps(apps)
|
142
|
+
Spider.activate_apps(apps)
|
143
|
+
end
|
144
|
+
self.add_command(activate)
|
145
|
+
|
172
146
|
update = CmdParse::Command.new( 'update', false )
|
173
147
|
update.short_desc = _("Update an app")
|
174
148
|
update.options = CmdParse::OptionParserWrapper.new do |opt|
|
@@ -188,44 +162,13 @@ class AppCommand < CmdParse::Command
|
|
188
162
|
puts _("Please execute this command from the home folder")
|
189
163
|
exit
|
190
164
|
end
|
191
|
-
require 'spiderfw/setup/app_server_client'
|
192
|
-
use_git = false
|
193
|
-
unless @no_git
|
194
|
-
begin
|
195
|
-
require 'grit'
|
196
|
-
use_git = true
|
197
|
-
rescue
|
198
|
-
puts "Grit not available; install Grit for Git support"
|
199
|
-
end
|
200
|
-
end
|
201
|
-
apps = args
|
202
|
-
if @all
|
203
|
-
require 'spiderfw/home'
|
204
|
-
home = Spider::Home.new(Dir.pwd)
|
205
|
-
apps = home.list_apps
|
206
|
-
end
|
207
|
-
if apps.empty?
|
208
|
-
puts _("No app to update")
|
209
|
-
exit
|
210
|
-
end
|
211
165
|
require 'spiderfw/setup/app_manager'
|
212
|
-
|
213
|
-
|
214
|
-
|
215
|
-
|
216
|
-
|
217
|
-
|
218
|
-
end
|
219
|
-
deps = specs.map{ |s| s.app_id }
|
220
|
-
unless (deps - apps).empty?
|
221
|
-
puts _("The following apps will be updated as a dependency:")
|
222
|
-
puts (deps - apps).inspect
|
223
|
-
end
|
224
|
-
Spider::AppManager.update(specs, Dir.pwd, {
|
225
|
-
:use_git => use_git,
|
226
|
-
:no_gems => @no_gems,
|
227
|
-
:no_optional_gems => @no_optional_gems
|
228
|
-
})
|
166
|
+
options = {
|
167
|
+
:no_git => @no_git, :all => @all, :no_deps => @no_deps, :no_optional => @no_optional,
|
168
|
+
:no_gems => @no_gems, :no_optional_gems => @no_optional_gems
|
169
|
+
}
|
170
|
+
options[:url] = @server_url if @server_url
|
171
|
+
Spider::AppManager.update_apps(args, options)
|
229
172
|
end
|
230
173
|
self.add_command(update)
|
231
174
|
|
@@ -33,7 +33,7 @@ module Spider
|
|
33
33
|
:default => Proc.new{ RUBY_VERSION_PARTS[1] == '8' && !Object.const_defined?(:PhusionPassenger) ? true : false }
|
34
34
|
config_option 'webserver.timeout', _("Time allowed for each request (in seconds)"), :type=> Fixnum, :default => nil
|
35
35
|
config_option 'webserver.respawn_on_change', _("Restart the webserver when application code changes"), :type => Spider::Bool,
|
36
|
-
:default => Proc.new{ Spider.config.get('runmode') == 'devel' ? true : false }
|
36
|
+
:default => Proc.new{ RUBY_PLATFORM !~ /win32|mingw32/ && Spider.config.get('runmode') == 'devel' ? true : false }
|
37
37
|
config_option 'static_content.mode', _("Mode to use for serving static files"), :type => String,
|
38
38
|
:choices => [nil, 'x-sendfile', 'x-accel-redirect', 'published'], :default => nil
|
39
39
|
config_option 'static_content.auto_publish', _("Automatically publish content to the home's public folder"),
|
@@ -89,9 +89,13 @@ module Spider; module ControllerMixins
|
|
89
89
|
super
|
90
90
|
end
|
91
91
|
|
92
|
-
def base_url
|
92
|
+
def self.base_url
|
93
93
|
HTTPMixin.reverse_proxy_mapping("")
|
94
94
|
end
|
95
|
+
|
96
|
+
def base_url
|
97
|
+
self.class.base_url
|
98
|
+
end
|
95
99
|
|
96
100
|
def prepare_scene(scene)
|
97
101
|
scene = super
|
@@ -101,7 +105,6 @@ module Spider; module ControllerMixins
|
|
101
105
|
end
|
102
106
|
|
103
107
|
def try_rescue(exc)
|
104
|
-
self.done = true
|
105
108
|
if (exc.is_a?(Spider::Controller::NotFound))
|
106
109
|
@response.status = Spider::HTTP::NOT_FOUND
|
107
110
|
elsif (exc.is_a?(Spider::Controller::BadRequest))
|
@@ -40,6 +40,9 @@ module Spider; module ControllerMixins
|
|
40
40
|
output_format_headers(format)
|
41
41
|
@executed_format = format
|
42
42
|
@executed_format_params = format_params
|
43
|
+
if Spider.runmode != 'devel' && File.exists?(File.join(Spider.paths[:tmp], 'maintenance.txt'))
|
44
|
+
raise Spider::Controller::Maintenance
|
45
|
+
end
|
43
46
|
super
|
44
47
|
end
|
45
48
|
|
@@ -182,7 +185,7 @@ module Spider; module ControllerMixins
|
|
182
185
|
def render(path=nil, options={})
|
183
186
|
scene = options[:scene] || @scene
|
184
187
|
scene ||= get_scene
|
185
|
-
scene = prepare_scene(scene)
|
188
|
+
scene = prepare_scene(scene) unless options[:no_prepare_scene]
|
186
189
|
request = options[:request] || @request
|
187
190
|
response = options[:response] || @response
|
188
191
|
if (path.is_a?(Spider::Template))
|
@@ -215,6 +218,11 @@ module Spider; module ControllerMixins
|
|
215
218
|
return template
|
216
219
|
end
|
217
220
|
|
221
|
+
def render_error(path, options)
|
222
|
+
options[:no_prepare_scene] = true
|
223
|
+
render(path, options)
|
224
|
+
end
|
225
|
+
|
218
226
|
def find_widget(name)
|
219
227
|
@template.find_widget(name)
|
220
228
|
end
|
@@ -239,19 +247,26 @@ module Spider; module ControllerMixins
|
|
239
247
|
return obj
|
240
248
|
end
|
241
249
|
|
242
|
-
def try_rescue(exc)
|
250
|
+
def try_rescue(exc)
|
243
251
|
exc.uuid = UUIDTools::UUID.random_create.to_s if exc.respond_to?(:uuid=)
|
244
252
|
format = self.class.output_format(:error) || :html
|
245
|
-
|
246
|
-
|
247
|
-
|
253
|
+
unless exc.is_a?(Spider::Controller::Maintenance) || exc.is_a?(Spider::Controller::NotFound)
|
254
|
+
return super unless @executed_format == :html
|
255
|
+
return super unless action_target?
|
256
|
+
return super if target_mode?
|
257
|
+
end
|
248
258
|
output_format_headers(format)
|
249
|
-
|
250
|
-
|
259
|
+
layout = 'errors/error'
|
260
|
+
if exc.is_a?(Spider::Controller::Maintenance)
|
261
|
+
error_page = 'maintenance'
|
262
|
+
layout = 'generic'
|
263
|
+
elsif exc.is_a?(Spider::Controller::NotFound)
|
264
|
+
error_page = 'errors/404'
|
265
|
+
layout = 'errors/simple'
|
251
266
|
@scene.error_msg = _("Page not found")
|
252
267
|
@scene.email_subject = @scene.error_msg
|
253
268
|
else
|
254
|
-
error_page = 'error_generic'
|
269
|
+
error_page = 'errors/error_generic'
|
255
270
|
if (exc.is_a?(HTTPMixin::HTTPStatus))
|
256
271
|
@scene.error_msg = exc.status_message
|
257
272
|
end
|
@@ -259,13 +274,13 @@ module Spider; module ControllerMixins
|
|
259
274
|
@scene.email_subject = @scene.error_msg
|
260
275
|
end
|
261
276
|
|
262
|
-
if
|
277
|
+
if exc.respond_to?(:uuid)
|
263
278
|
exc.extend(UUIDExceptionMessage)
|
264
279
|
@scene.exception_uuid = exc.uuid
|
265
|
-
@scene.email_subject += " (#{exc.uuid})"
|
280
|
+
@scene.email_subject += " (#{exc.uuid})" if @scene.email_subject
|
266
281
|
end
|
267
282
|
@scene.admin_email = Spider.conf.get('site.tech_admin.email')
|
268
|
-
if
|
283
|
+
if Spider.runmode == 'devel'
|
269
284
|
begin
|
270
285
|
@scene.devel = true
|
271
286
|
@scene.backtrace = build_backtrace(exc)
|
@@ -294,7 +309,7 @@ module Spider; module ControllerMixins
|
|
294
309
|
rescue => exc2
|
295
310
|
end
|
296
311
|
end
|
297
|
-
|
312
|
+
render_error "#{error_page}", :layout => layout
|
298
313
|
super
|
299
314
|
end
|
300
315
|
|
data/lib/spiderfw/http/server.rb
CHANGED
@@ -4,6 +4,129 @@ require 'fileutils'
|
|
4
4
|
module Spider
|
5
5
|
|
6
6
|
module AppManager
|
7
|
+
|
8
|
+
def self.install_or_update(apps, options={})
|
9
|
+
require 'spiderfw/home'
|
10
|
+
home = Spider::Home.new(Dir.pwd)
|
11
|
+
installed = {}
|
12
|
+
Spider.init_base
|
13
|
+
active = Spider.config.get('apps')
|
14
|
+
Spider.home.apps.each do |app, info|
|
15
|
+
installed[app] = {
|
16
|
+
:active => active.include?(app)
|
17
|
+
}
|
18
|
+
if spec = info[:spec]
|
19
|
+
installed[app].merge!({
|
20
|
+
:version => spec.version
|
21
|
+
})
|
22
|
+
end
|
23
|
+
end
|
24
|
+
to_inst = apps.select{ |a| !installed[a] }
|
25
|
+
to_upd = apps.select{ |a| installed[a] }
|
26
|
+
install_apps(to_inst, options)
|
27
|
+
update_apps(to_upd, options)
|
28
|
+
return {:installed => to_inst, :updated => to_upd}
|
29
|
+
end
|
30
|
+
|
31
|
+
def self.install_apps(apps, options={})
|
32
|
+
return if apps.empty?
|
33
|
+
require 'spiderfw/setup/app_server_client'
|
34
|
+
use_git = false
|
35
|
+
unless options[:no_git]
|
36
|
+
begin
|
37
|
+
require 'grit'
|
38
|
+
use_git = true
|
39
|
+
rescue => exc
|
40
|
+
puts exc.message
|
41
|
+
puts "Grit not available; install Grit for Git support"
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
existent = []
|
46
|
+
apps.each do |app|
|
47
|
+
if File.exist?("apps/#{app}")
|
48
|
+
puts _("%s already exists, skipping") % app
|
49
|
+
existent << app
|
50
|
+
end
|
51
|
+
end
|
52
|
+
require 'spiderfw/setup/app_manager'
|
53
|
+
specs = []
|
54
|
+
url = options[:url]
|
55
|
+
unless url
|
56
|
+
require 'spiderfw/spider'
|
57
|
+
Spider.init_base
|
58
|
+
url = Spider.config.get('app_server.url')
|
59
|
+
end
|
60
|
+
client = Spider::AppServerClient.new(url)
|
61
|
+
if options[:no_deps]
|
62
|
+
specs = client.get_specs(apps)
|
63
|
+
else
|
64
|
+
specs = client.get_deps(apps, :no_optional => options[:no_optional])
|
65
|
+
end
|
66
|
+
deps = specs.map{ |s| s.app_id }
|
67
|
+
unless (deps - apps).empty?
|
68
|
+
puts _("The following apps will be installed as a dependency:")
|
69
|
+
puts (deps - apps).inspect
|
70
|
+
end
|
71
|
+
i_options = {
|
72
|
+
:use_git => use_git,
|
73
|
+
:no_gems => options[:no_gems],
|
74
|
+
:no_optional_gems => options[:no_optional_gems]
|
75
|
+
}
|
76
|
+
i_options[:ssh_user] = options[:ssh_user] if options[:ssh_user]
|
77
|
+
inst_specs = specs.reject!{ |s| existent.include? s.app_id }
|
78
|
+
Spider::AppManager.install(inst_specs, Dir.pwd, i_options)
|
79
|
+
unless options[:no_activate]
|
80
|
+
require 'spiderfw/spider'
|
81
|
+
specs_hash = {}
|
82
|
+
specs.each{ |s| specs_hash[s.app_id] = s }
|
83
|
+
Spider.activate_apps(deps, specs_hash)
|
84
|
+
end
|
85
|
+
|
86
|
+
end
|
87
|
+
|
88
|
+
def self.update_apps(apps, options={})
|
89
|
+
require 'spiderfw/spider'
|
90
|
+
require 'spiderfw/setup/app_server_client'
|
91
|
+
Spider.init_base
|
92
|
+
url = options[:url] || Spider.conf.get('app_server.url')
|
93
|
+
use_git = false
|
94
|
+
unless options[:no_git]
|
95
|
+
begin
|
96
|
+
require 'grit'
|
97
|
+
use_git = true
|
98
|
+
rescue
|
99
|
+
puts "Grit not available; install Grit for Git support"
|
100
|
+
end
|
101
|
+
end
|
102
|
+
if options[:all]
|
103
|
+
require 'spiderfw/home'
|
104
|
+
home = Spider::Home.new(Dir.pwd)
|
105
|
+
apps = home.list_apps
|
106
|
+
end
|
107
|
+
if apps.empty?
|
108
|
+
puts _("No app to update")
|
109
|
+
exit
|
110
|
+
end
|
111
|
+
require 'spiderfw/setup/app_manager'
|
112
|
+
specs = []
|
113
|
+
client = Spider::AppServerClient.new(url)
|
114
|
+
if options[:no_deps]
|
115
|
+
specs = client.get_specs(apps)
|
116
|
+
else
|
117
|
+
specs = client.get_deps(apps, :no_optional => options[:no_optional])
|
118
|
+
end
|
119
|
+
deps = specs.map{ |s| s.app_id }
|
120
|
+
unless (deps - apps).empty?
|
121
|
+
puts _("The following apps will be updated as a dependency:")
|
122
|
+
puts (deps - apps).inspect
|
123
|
+
end
|
124
|
+
Spider::AppManager.update(specs, Dir.pwd, {
|
125
|
+
:use_git => use_git,
|
126
|
+
:no_gems => options[:no_gems],
|
127
|
+
:no_optional_gems => options[:no_optional_gems]
|
128
|
+
})
|
129
|
+
end
|
7
130
|
|
8
131
|
def self.install(specs, home_path, options)
|
9
132
|
options[:use_git] = true unless options[:use_git] == false
|
@@ -77,7 +200,7 @@ module Spider
|
|
77
200
|
end
|
78
201
|
end
|
79
202
|
|
80
|
-
def pre_update
|
203
|
+
def self.pre_update(specs, options={})
|
81
204
|
end
|
82
205
|
|
83
206
|
def self.post_setup(specs, options={})
|
@@ -89,7 +212,7 @@ module Spider
|
|
89
212
|
options[:use_git] = true unless options[:use_git] == false
|
90
213
|
specs = [specs] unless specs.is_a?(Array)
|
91
214
|
pre_setup(specs, options)
|
92
|
-
pre_update(specs,
|
215
|
+
pre_update(specs, options)
|
93
216
|
specs.each do |spec|
|
94
217
|
if spec.git_repo && options[:use_git]
|
95
218
|
git_update(spec, home_path, options)
|
data/lib/spiderfw/spider.rb
CHANGED
@@ -78,6 +78,11 @@ module Spider
|
|
78
78
|
@home.instance_eval(File.read(init_file), init_file)
|
79
79
|
end
|
80
80
|
|
81
|
+
init_apps
|
82
|
+
@init_done=true
|
83
|
+
end
|
84
|
+
|
85
|
+
def init_apps
|
81
86
|
@apps.each do |name, mod|
|
82
87
|
mod.app_init if mod.respond_to?(:app_init)
|
83
88
|
end
|
@@ -87,7 +92,6 @@ module Spider
|
|
87
92
|
GetText.bindtextdomain(mod.short_name)
|
88
93
|
end
|
89
94
|
end
|
90
|
-
@init_done=true
|
91
95
|
end
|
92
96
|
|
93
97
|
def init_done?
|
@@ -175,9 +179,9 @@ module Spider
|
|
175
179
|
@fssm_thread = Thread.new do
|
176
180
|
monitor.run
|
177
181
|
end
|
178
|
-
Spider.logger.debug("Monitoring restart.txt")
|
182
|
+
Spider.logger.debug("Monitoring restart.txt") if Spider.logger
|
179
183
|
else
|
180
|
-
Spider.logger.debug("FSSM not installed, unable to monitor restart.txt")
|
184
|
+
Spider.logger.debug("FSSM not installed, unable to monitor restart.txt") if Spider.logger
|
181
185
|
end
|
182
186
|
trap('TERM'){ Spider.main_process_shutdown; exit }
|
183
187
|
trap('INT'){ Spider.main_process_shutdown; exit }
|
@@ -314,6 +318,7 @@ module Spider
|
|
314
318
|
@paths[:tmp] = File.join(root, 'tmp')
|
315
319
|
@paths[:data] = File.join(root, 'data')
|
316
320
|
@paths[:log] = File.join(@paths[:var], 'log')
|
321
|
+
@paths[:restart_file] = File.join(@paths[:tmp], 'restart.txt')
|
317
322
|
@paths.each do |k, path|
|
318
323
|
@paths[k] = File.expand_path(File.readlink(path)) if File.symlink?(path)
|
319
324
|
end
|
@@ -422,6 +427,20 @@ module Spider
|
|
422
427
|
return false
|
423
428
|
end
|
424
429
|
|
430
|
+
def get_app_deps(apps, options={})
|
431
|
+
new_apps = apps.clone
|
432
|
+
specs = {}
|
433
|
+
init_base
|
434
|
+
while !new_apps.empty? && curr = new_apps.pop
|
435
|
+
raise "Could not find app #{curr}" unless Spider.home.apps[curr]
|
436
|
+
spec = Spider.home.apps[curr][:spec]
|
437
|
+
specs[curr] = spec
|
438
|
+
new_apps += spec.depends.reject{ |app| specs[app] }
|
439
|
+
new_apps += spec.depends_optional.reject{ |app| specs[app] } if options[:optional]
|
440
|
+
end
|
441
|
+
specs.keys
|
442
|
+
end
|
443
|
+
|
425
444
|
def activate_apps(apps, specs=nil)
|
426
445
|
require 'spiderfw/config/configuration_editor'
|
427
446
|
init_base
|
@@ -448,7 +467,7 @@ module Spider
|
|
448
467
|
apps.each do |a|
|
449
468
|
sort.add(specs[a] ? specs[a] : a)
|
450
469
|
end
|
451
|
-
sort.tsort
|
470
|
+
sort.tsort.reject{ |a| a.nil? }
|
452
471
|
end
|
453
472
|
|
454
473
|
def load_configuration(path)
|
data/views/errors/404.shtml
CHANGED
@@ -0,0 +1,16 @@
|
|
1
|
+
<!DOCTYPE HTML>
|
2
|
+
<html>
|
3
|
+
<tpl:asset type="css" src="css/error_page.css" />
|
4
|
+
<head>
|
5
|
+
<title>{ @error_msg }</title>
|
6
|
+
<script sp:each='@assets[:js] |script|' type="text/javascript" src="{ script }"></script>
|
7
|
+
<link sp:each='@assets[:css] |css_file|' rel='stylesheet' href='{ css_file }' />
|
8
|
+
</head>
|
9
|
+
<body>
|
10
|
+
<div id="header">
|
11
|
+
</div>
|
12
|
+
<div id="content">
|
13
|
+
<sp:yield />
|
14
|
+
</div>
|
15
|
+
</div>
|
16
|
+
</div>
|
@@ -0,0 +1,16 @@
|
|
1
|
+
<!DOCTYPE HTML>
|
2
|
+
<html>
|
3
|
+
<tpl:asset type="css" src="css/error_page.css" />
|
4
|
+
<head>
|
5
|
+
<title>{ @error_msg }</title>
|
6
|
+
<script sp:each='@assets[:js] |script|' type="text/javascript" src="{ script }"></script>
|
7
|
+
<link sp:each='@assets[:css] |css_file|' rel='stylesheet' href='{ css_file }' />
|
8
|
+
</head>
|
9
|
+
<body>
|
10
|
+
<div id="header">
|
11
|
+
</div>
|
12
|
+
<div id="content">
|
13
|
+
<sp:yield />
|
14
|
+
</div>
|
15
|
+
</div>
|
16
|
+
</div>
|
metadata
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: spiderfw
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
hash:
|
4
|
+
hash: 9
|
5
5
|
prerelease:
|
6
6
|
segments:
|
7
7
|
- 0
|
8
8
|
- 6
|
9
|
-
-
|
10
|
-
version: 0.6.
|
9
|
+
- 7
|
10
|
+
version: 0.6.7
|
11
11
|
platform: ruby
|
12
12
|
authors:
|
13
13
|
- Ivan Pirlik
|
@@ -15,7 +15,7 @@ autorequire:
|
|
15
15
|
bindir: bin
|
16
16
|
cert_chain: []
|
17
17
|
|
18
|
-
date: 2011-07-
|
18
|
+
date: 2011-07-26 00:00:00 +02:00
|
19
19
|
default_executable: spider
|
20
20
|
dependencies:
|
21
21
|
- !ruby/object:Gem::Dependency
|
@@ -850,6 +850,7 @@ files:
|
|
850
850
|
- apps/master/models/admin.rb
|
851
851
|
- apps/master/models/command.rb
|
852
852
|
- apps/master/models/customer.rb
|
853
|
+
- apps/master/models/event.rb
|
853
854
|
- apps/master/models/installation.rb
|
854
855
|
- apps/master/models/remote_log.rb
|
855
856
|
- apps/master/models/resource.rb
|
@@ -935,6 +936,7 @@ files:
|
|
935
936
|
- apps/servant/controllers/servant_controller.rb
|
936
937
|
- apps/servant/Gemfile
|
937
938
|
- apps/servant/lib/client.rb
|
939
|
+
- apps/servant/lib/commands_processor.rb
|
938
940
|
- apps/servant/servant.appspec
|
939
941
|
- apps/servant/servant.rb
|
940
942
|
- apps/soap/_init.rb
|
@@ -1211,6 +1213,9 @@ files:
|
|
1211
1213
|
- views/errors/404.shtml
|
1212
1214
|
- views/errors/error.layout.shtml
|
1213
1215
|
- views/errors/error_generic.shtml
|
1216
|
+
- views/errors/simple.layout.shtml
|
1217
|
+
- views/generic.layout.shtml
|
1218
|
+
- views/maintenance.shtml
|
1214
1219
|
has_rdoc: true
|
1215
1220
|
homepage: http://github.com/me/spider
|
1216
1221
|
licenses: []
|