-
Notifications
You must be signed in to change notification settings - Fork 433
/
status_controller.rb
266 lines (231 loc) · 7.79 KB
/
status_controller.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
require_dependency 'status_helper'
class StatusController < ApplicationController
class PermissionDeniedError < APIException
setup 403
end
def list_messages
@messages = StatusMessage.alive.limit(params[:limit]).order("created_at DESC").includes(:user)
@count = @messages.size
render xml: render_to_string(partial: "messages")
end
def show_message
@messages = [StatusMessage.find(params[:id])]
@count = 1
render xml: render_to_string(partial: "messages")
end
class CreatingMessagesError < APIException
end
def update_messages
# check permissions
unless permissions.status_message_create
raise PermissionDeniedError.new 'message(s) cannot be created, you have not sufficient permissions'
end
new_messages = ActiveXML::Node.new(request.raw_post)
if new_messages.has_element? 'message'
# message(s) are wrapped in outer xml tag 'status_messages'
new_messages.each_message do |msg|
save_new_message(msg)
end
else
# TODO: make use of a validator
raise CreatingMessagesError.new "no message #{new_messages.dump_xml}" if new_messages.element_name != 'message'
# just one message, NOT wrapped in outer xml tag 'status_messages'
save_new_message(new_messages)
end
render_ok
end
def save_new_message(msg)
message = StatusMessage.new
message.message = msg.to_s
message.severity = msg.value :severity
message.user = User.current
message.save!
end
def delete_message
# check permissions
unless permissions.status_message_create
raise PermissionDeniedError.new "message cannot be deleted, you have not sufficient permissions"
end
StatusMessage.find(params[:id]).delete
render_ok
end
def workerstatus
begin
data = Rails.cache.read('workerstatus')
rescue Zlib::GzipFile::Error
data = nil
end
data=ActiveXML::Node.new(data || update_workerstatus_cache)
prjs=Hash.new
data.each_building do |b|
prjs[b.project] = 1
end
names = Hash.new
# now try to find those we have a match for (the rest are hidden from you
Project.where(name: prjs.keys).pluck(:name).each do |n|
names[n] = 1
end
data.each_building do |b|
# no prj -> we are not allowed
unless names.has_key? b.project
logger.debug "workerstatus2clean: hiding #{b.project} for user #{User.current.login}"
b.set_attribute('project', '---')
b.set_attribute('repository', '---')
b.set_attribute('package', '---')
end
end
send_data data.dump_xml
end
def history
required_parameters :hours, :key
samples = begin
Integer(params[:samples] || '100') rescue 0
end
@samples = [samples, 1].max
hours = begin
Integer(params[:hours] || '24') rescue 24
end
starttime = Time.now.to_i - hours.to_i * 3600
@values = StatusHistory.where("time >= ? AND \`key\` = ?", starttime, params[:key]).pluck(:time, :value).collect { |time, value| [time.to_i, value.to_f] }
end
def save_value_line(e, prefix)
line = StatusHistory.new
line.time = @mytime
line.key = "#{prefix}_#{e['arch']}"
line.value = e['jobs']
line.save
end
def update_workerstatus_cache
# do not add hiding in here - this is purely for statistics
ret=backend_get('/build/_workerstatus')
data=Xmlhash.parse(ret)
@mytime = Time.now.to_i
Rails.cache.write('workerstatus', ret, expires_in: 3.minutes)
Rails.cache.write('workerhash', data, expires_in: 3.minutes)
StatusHistory.transaction do
data.elements('blocked') do |e|
save_value_line(e, 'blocked')
end
data.elements('waiting') do |e|
save_value_line(e, 'waiting')
end
data.elements('partition') do |p|
p.elements('daemon') do |daemon|
parse_daemon_infos(daemon)
end
end
parse_worker_infos(data)
end
ret
end
def parse_daemon_infos(daemon)
return unless daemon['type'] == 'scheduler'
arch = daemon['arch']
# FIXME2.5: The current architecture model is a gross hack, not connected at all
# to the backend config.
a=Architecture.find_by_name(arch)
if a
a.available=true
a.save
end
queue = daemon.get('queue')
return unless queue
StatusHistory.create :time => @mytime, :key => "squeue_high_#{arch}", :value => queue['high'].to_i
StatusHistory.create :time => @mytime, :key => "squeue_next_#{arch}", :value => queue['next'].to_i
StatusHistory.create :time => @mytime, :key => "squeue_med_#{arch}", :value => queue['med'].to_i
StatusHistory.create :time => @mytime, :key => "squeue_low_#{arch}", :value => queue['low'].to_i
end
def parse_worker_infos(data)
allworkers = Hash.new
workers = Hash.new
%w{building idle}.each do |state|
data.elements(state) do |e|
id=e['workerid']
if workers.has_key? id
logger.debug 'building+idle worker'
next
end
workers[id] = 1
key = state + '_' + e['hostarch']
allworkers["building_#{e['hostarch']}"] ||= 0
allworkers["idle_#{e['hostarch']}"] ||= 0
allworkers[key] = allworkers[key] + 1
end
end
allworkers.each do |key, value|
line = StatusHistory.new
line.time = @mytime
line.key = key
line.value = value
line.save
end
end
# move to models?
def role_from_cache(role_id)
@rolecache[role_id] || (@rolecache[role_id] = Role.find(role_id).title)
end
def user_from_cache(user_id)
@usercache[user_id] || (@usercache[user_id] = User.find(user_id).login)
end
def group_from_cache(group_id)
@groupcache[group_id] || (@groupcache[group_id] = Group.find(group_id).title)
end
def find_relationships_for_packages(packages)
package_hash = Hash.new
packages.each_value do |p|
package_hash[p.package_id] = p
if p.develpack
package_hash[p.develpack.package_id] = p.develpack
end
end
@rolecache = {}
@usercache = {}
@groupcache = {}
relationships = Relationship.where(package_id: package_hash.keys).pluck(:package_id, :user_id, :group_id, :role_id)
relationships.each do |package_id, user_id, group_id, role_id|
if user_id
package_hash[package_id].add_person(user_from_cache(user_id),
role_from_cache(role_id))
else
package_hash[package_id].add_group(group_from_cache(group_id),
role_from_cache(role_id))
end
end
end
def project
dbproj = Project.get_by_name(params[:project])
@packages = ProjectStatusCalculator.new(dbproj).calc_status
find_relationships_for_packages(@packages)
end
def bsrequest
required_parameters :id
Suse::Backend.start_test_backend if Rails.env.test?
@id = params[:id]
action = bsrequest_get_action
sproj = Project.find_by_name!(action.source_project)
tproj = Project.find_by_name!(action.target_project)
spkg = sproj.packages.find_by_name!(action.source_package)
dir = Directory.hashed(project: action.source_project,
package: action.source_package,
expand: 1, rev: action.source_rev)
@result = PackageBuildStatus.new(spkg).result(target_project: tproj, srcmd5: dir['srcmd5'])
render xml: render_to_string(partial: "bsrequest")
end
class NotFoundError < APIException
setup 404
end
class MultipleNotSupported < APIException
end
class NotSubmitRequest < APIException
end
def bsrequest_get_action
rel = BsRequestAction.where(bs_request_id: params[:id])
if rel.count > 1
raise MultipleNotSupported.new
end
action = rel.first
raise NotFoundError.new unless action
raise NotSubmitRequest.new 'Not submit' unless action.action_type == :submit
action
end
end