don't return specific xml response (bnc#602001)
[opensuse:yast-web-client.git] / plugins / software / app / controllers / patch_updates_controller.rb
1 #--
2 # Copyright (c) 2009-2010 Novell, Inc.
3
4 # All Rights Reserved.
5
6 # This program is free software; you can redistribute it and/or modify it
7 # under the terms of version 2 of the GNU General Public License
8 # as published by the Free Software Foundation.
9
10 # This program is distributed in the hope that it will be useful,
11 # but WITHOUT ANY WARRANTY; without even the implied warranty of
12 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 # GNU General Public License for more details.
14
15 # You should have received a copy of the GNU General Public License
16 # along with this program; if not, contact Novell, Inc.
17
18 # To contact Novell about this file by physical or electronic mail,
19 # you may find current contact information at www.novell.com
20 #++
21
22 require 'yast/service_resource'
23 require 'client_exception'
24
25 class PatchUpdatesController < ApplicationController
26
27   before_filter :login_required
28   layout 'main'
29   include ProxyLoader
30
31   # Initialize GetText and Content-Type.
32   init_gettext "yast_webclient_software"
33
34 private
35
36   #
37   # Create message output, given from PackageKit
38   #
39   def create_messages(messages)
40     ret=[]
41     messages.each { |message|
42       case message.kind
43         when "system"
44           ret << _("<p>Please reboot your system.</p>") % message.kind
45         when "session"
46           ret << _("<p>Please logout and login again.</p>") % message.kind
47         else
48           ret << "<p><b>#{message.kind}:</b>#{message.details}</p>"
49       end
50     }
51     ret
52   end
53
54 public
55
56   # GET /patch_updates
57   # GET /patch_updates.xml
58   def index
59     begin
60       @patch_updates = load_proxy 'org.opensuse.yast.system.patches', :all
61     rescue ActiveResource::ServerError => e
62       ce = ClientException.new e
63       if ce.backend_exception_type ==  "PACKAGEKIT_ERROR"
64         if ce.message.match /Repository (.*) needs to be signed/
65           flash[:error] = _("Cannot read patch updates: GPG key for repository <em>%s</em> is not trusted.") % $1
66         else
67           flash[:error] = ce.message
68         end
69         @patch_updates = []
70         @error = true
71       else
72         raise e
73       end
74     end
75     logger.debug "Available patches: #{@patch_updates.inspect}"
76   end
77
78   # this action is rendered as a partial, so it can't throw
79   def show_summary
80     error = nil
81     patch_updates = nil
82     begin
83       patch_updates = load_proxy 'org.opensuse.yast.system.patches', :all, {:background => params['background']}
84     rescue ActiveResource::UnauthorizedAccess => e
85       # handle unauthorized error - the session timed out
86       Rails.logger.error "Error: ActiveResource::UnauthorizedAccess"
87       error = e
88       error_string = ''
89     rescue ActiveResource::ClientError => e
90       error = ClientException.new(e)
91       patch_updates = nil
92       error_string = _("A problem occured when loading patch information.")
93     rescue ActiveResource::ServerError => e
94       error = ClientException.new(e)
95       error_string = _("A problem occured when loading patch information.")
96       error_string = error.message if error.backend_exception_type ==  "PACKAGEKIT_ERROR"
97       patch_updates = nil
98     end    
99     patches_summary = nil
100
101     if patch_updates
102       # is it a background progress?
103       if patch_updates.size == 1 && patch_updates.first.respond_to?(:status)
104         bg_stat = patch_updates.first
105
106         patches_status = {:status => bg_stat.status, :progress => bg_stat.progress, :subprogress => bg_stat.subprogress}
107         Rails.logger.debug "Received background patches progress: #{patches_status.inspect}"
108
109         respond_to do |format|
110           format.html { render :partial  => 'patch_progress', :locals => {:status => patches_status, :error => error} }
111           format.json  { render :json => patches_status }
112         end
113
114         return
115       else
116         patches_summary = { :security => 0, :important => 0, :optional => 0}
117         [:security, :important, :optional].each do |patch_type|
118           patches_summary[patch_type] = patch_updates.find_all { |p| p.kind == patch_type.to_s }.size
119         end
120       end
121     else
122       erase_redirect_results #reset all redirects
123       erase_render_results
124       flash.clear #no flash from load_proxy
125     end
126
127     # don't refresh if there was an error
128     ref_timeout = error ? nil : refresh_timeout
129
130     respond_to do |format|
131       format.html { render :partial => "patch_summary", :locals => { :patch => patches_summary, :error => error, :error_string => error_string, :refresh_timeout => ref_timeout } }
132       format.json  { render :json => patches_summary }
133     end    
134   end
135
136   def load_filtered
137     @patch_updates = load_proxy 'org.opensuse.yast.system.patches', :all
138     kind = params[:value]
139     unless kind == "all"
140       @patch_updates = @patch_updates.find_all { |patch| patch.kind == kind }
141     end
142     render :partial => "patches"
143   end
144
145   # POST /patch_updates/start_install_all
146   # Starting installation of all proposed patches
147   def start_install_all
148     logger.debug "Start installation of all patches"
149
150     render :partial => "patch_installation", :locals => { :patch => _("Installing all patches..."), :error => nil  , :go_on => true, :message => "" }
151   end
152
153   def stop_install_all
154     logger.debug "Stopping installation of all patches"
155
156     render :partial => "patch_installation", :locals => { :patch => _("Installation stopped"), :error => nil  , :go_on => false, :message => "" }
157   end
158
159   # POST /patch_updates/install_all
160   # Install each patch. This function will be called periodically from the controll center
161   def install_all
162     logger.debug "Installing one available patch...."
163
164     error = nil
165     patch_updates = nil    
166     begin
167       client = YaST::ServiceResource.proxy_for('org.opensuse.yast.system.patches')
168       patch_updates = client.find :all
169     rescue Exception => e
170       error = e
171       patch_updates = nil
172     end
173
174     flash.clear #no flash from load_proxy
175     last_patch = ""
176     message_array = []
177     unless patch_updates.blank?
178       #installing the first available patch
179       logger.info "Installing patch :#{patch_updates[0].name}"
180       begin
181         ret = client.create({:repo=>nil,
182                              :kind=>nil,
183                              :name=>nil,
184                              :arch=>nil,
185                              :version=>nil,
186                              :summary=>nil,
187                              :resolvable_id=>patch_updates[0].resolvable_id})
188         message_array=create_messages(ret.messages) if ret.respond_to?(:messages) && !ret.messages.blank?
189         logger.debug "updated #{patch_updates[0].name}"
190       rescue ActiveResource::ResourceNotFound => e
191         flash[:error] = YaST::ServiceResource.error(e)
192       rescue ActiveResource::ClientError => e
193         error = e
194       end        
195       last_patch = patch_updates[0].name
196     else
197       erase_redirect_results #reset all redirects
198       erase_render_results
199     end
200
201     respond_to do |format|
202       if last_patch.blank?
203         format.html { render :partial => "patch_installation", :locals => { :patch => _("Installation finished"), :error => error  , :go_on => false, :message => "" }}
204       else
205         format.html { render :partial => "patch_installation", :locals => { :patch => _("%s installed.") % last_patch , :error => error, :message => message_array.uniq.to_s }}
206       end
207     end    
208   end
209
210   # POST /patch_updates/install
211   # Installing one or more patches which has given via param 
212
213   def install    
214     update_array = []
215
216     #search for patches and collect the ids
217     params.each { |key, value|
218       if key =~ /\D*_\d/ || key == "id"
219         update_array << value
220       end
221     }
222     flash_string = ""
223     message_array = []
224     update_array.each do |patch_id|
225       begin
226         client = YaST::ServiceResource.proxy_for('org.opensuse.yast.system.patches')
227         ret = client.create({:repo=>nil,
228                              :kind=>nil,
229                              :name=>nil,
230                              :arch=>nil,
231                              :version=>nil,
232                              :summary=>nil,
233                              :resolvable_id=>patch_id})
234         message_array=create_messages(ret.messages) if ret.respond_to?(:messages) && !ret.messages.blank?
235         logger.debug "updated #{patch_id}"
236         unless message_array.blank?
237           flash[:warning] = _("Patch has been installed. ") + message_array.uniq.to_s
238         else
239           flash[:notice] = _("Patch has been installed. ")
240         end
241       rescue ActiveResource::ResourceNotFound => e
242         flash[:error] = YaST::ServiceResource.error(e)
243       rescue ActiveResource::ClientError => e
244         flash[:error] = YaST::ServiceResource.error(e)
245         redirect_to({:controller=>"controlpanel", :action=>"index"}) and return
246       end        
247     end
248     unless message_array.blank?
249       #show all messages again
250       if update_array.size > 1       
251         flash[:warning] = _("All Patches have been installed. ") + message_array.uniq.to_s 
252       else
253         flash[:warning] = _("Patch has been installed. ") + message_array.uniq.to_s 
254       end
255     end
256   
257     redirect_to({:controller=>"controlpanel", :action=>"index"})
258   end
259
260   private
261
262   def refresh_timeout
263     # the default is 24 hours
264     timeout = ControlPanelConfig.read 'patch_status_timeout', 24*60*60
265
266     if timeout.zero?
267       Rails.logger.info "Patch status autorefresh is disabled"
268     else
269       Rails.logger.info "Autorefresh patch status after #{timeout} seconds"
270     end
271
272     return timeout
273   end
274
275 end