merged cont.
[opensuse:yast-rest-service.git] / webyast / lib / tasks / checks.rake
1 #--
2 # Webyast Webservice framework
3 #
4 # Copyright (C) 2009, 2010 Novell, Inc. 
5 #   This library is free software; you can redistribute it and/or modify
6 # it only under the terms of version 2.1 of the GNU Lesser General Public
7 # License as published by the Free Software Foundation. 
8 #
9 #   This library is distributed in the hope that it will be useful, but WITHOUT
10 # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
11 # FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more 
12 # details. 
13 #
14 #   You should have received a copy of the GNU Lesser General Public
15 # License along with this library; if not, write to the Free Software 
16 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
17 #++
18
19 ###
20 # Helpers
21 #
22
23 class Error
24   @@errors = 0
25   def self.inc
26     @@errors += 1
27   end
28   def self.errors
29     @@errors
30   end
31 end
32
33 def escape why, fix = nil
34   $stderr.puts "*** ERROR: #{why}"
35   $stderr.puts "Please #{fix}" if fix
36   exit(1) unless ENV["SYSTEM_CHECK_NON_STRICT"]
37   Error.inc
38 end
39
40 def warn why, fix = nil
41   $stderr.puts "*** WARNING: #{why}"
42   $stderr.puts "Please #{fix}" if fix
43 end
44
45 def test what
46   escape "(internal error) wrong use of 'test'" unless block_given?
47   puts "Testing if #{what}"
48   yield
49 end
50
51 def test_module name, package
52   puts "Testing if #{package} is installed"
53   begin
54     require name
55   rescue Exception => e
56     escape "#{package} not installed", "install #{package}"
57   end
58 end
59
60 def test_version package, version = nil
61   old_lang = ENV['LANG']
62   ENV['LANG'] = 'C'
63   v = `rpm -q #{package}`
64   ENV['LANG'] = old_lang
65   if v =~ /is not installed/
66     escape v, "install #{package} >= #{version}" if version
67     escape v, "install #{package}"
68   end
69   return unless version # just check package, not version
70   nvr = v.split "-"
71   rel = nvr.pop
72   ver = nvr.pop
73   escape "#{package} not up-to-date", "upgrade to #{package}-#{version}"  if ver < version
74 end
75
76 ###
77 # Tests
78 #
79
80 desc "Check that your build environment is set up correctly for WebYaST"
81 task :system_check do
82
83   # check if openSUSE 11.2 or SLE11
84
85   os_version = "unknown"
86   begin
87     suse_release = File.read "/etc/SuSE-release"
88     suse_release.scan( /VERSION = ([\d\.]*)/ ) do |v|
89       os_version = v[0]
90     end if suse_release
91   rescue
92   end
93   
94   #
95   # check needed needed packages
96   #
97   version = "0.0.1" # do not take care
98   test_version "libsqlite3-0", version
99   test_version "PolicyKit", version
100   test_version "PackageKit", version
101   test_version "rubygem-locale"
102   test_version "rubygem-locale_rails"
103   test_version "rubygem-gettext"
104   test_version "rubygem-gettext_rails"
105
106   # development package
107   test_version "tidy"
108
109   #
110   # check needed modules
111   # 
112   test_module "rake", "rubygem-rake"
113   test_module "sqlite3", "rubygem-sqlite3"
114   test_module "rake", "rubygem-rake"
115   test_module "rpam", "ruby-rpam"
116   test_module "polkit", "ruby-polkit"
117   test_module "dbus", "ruby-dbus"
118
119   # check that policies are all installed
120   not_needed = ['org.opensuse.yast.scr.policy']
121   policy_files = File.expand_path(File.join(File.dirname(__FILE__), '../../..', "**/*.policy"))
122   Dir.glob(policy_files) do |fname|
123     policy = File.basename(fname)
124     next if not_needed.include?(policy)
125     plugin = if fname =~ %r{plugins/([^/]*)}
126                $1
127              else
128                File.dirname fname
129              end
130     dest_policy = File.join('/usr/share/PolicyKit/policy', policy)
131     if not File.exists?(dest_policy)
132       escape "Policy '#{policy}' of plugin '#{plugin}' is not installed",
133              "Run \"sudo rake install_policies\" in plugin '#{plugin}'\n or run\nsudo cp #{fname} #{dest_policy}"
134     end
135   end
136
137   user = ENV['USER']
138   policykit_conf = <<EOF
139 <match user="#{user}">
140     <match action="org.opensuse.yast.scr.*">
141       <return result="yes"/>
142     </match>
143   </match>
144   <match user="#{user}">
145     <match action="org.freedesktop.packagekit.system-update">
146       <return result="yes"/>
147     </match>
148   </match>
149   <match user="#{user}">
150     <match action="org.freedesktop.packagekit.package-install">
151       <return result="yes"/>
152     </match>
153   </match>
154   <match user="#{user}">
155     <match action="org.freedesktop.policykit.read">
156       <return result="yes"/>
157     </match>
158   </match>
159 EOF
160
161   # will the webservice be able to run?
162   webservice_permissions_ok = false
163
164   # get all granted policies
165   granted = `polkit-auth --user #{user}`.split
166
167   # check that the user running the web service has permissions to yast
168   # scr and others. This can be achieved in 2 ways:
169   # manually polkit-auth, or as pattern matching in /etc/PolicyKit/PolicyKit.conf
170
171   scr_actions = `polkit-action`.split.reject { |item| not item.include?('org.opensuse.yast.') }.reject { |item| item.include? "org.opensuse.yast.scr."}
172   webservice_actions = [ 'org.freedesktop.packagekit.system-update', 'org.freedesktop.packagekit.package-install',  'org.freedesktop.policykit.read', *scr_actions]
173
174   hint_message = "Use utility script grantwebyastrights to grant them all. See http://en.opensuse.org/YaST/Web/Development\nAlternatively, you can add the following to /etc/PolicyKit/PolicyKit.conf config tag section:\n#{policykit_conf}\n"
175
176   webservice_actions.each do | action|
177     if not granted.include?(action)
178       escape "policy #{action} is not granted and it is needed to run the webservice as #{user}.", "Run 'polkit-auth --user #{user} --grant #{action}' to grant the permission.\n"+hint_message
179       hint_message = ""
180     end
181   end
182
183   # now check that all permission in each policy is granted
184   hint_message = "\nUse utility script grantwebyastrights.rb to grant them all.\nSee http://en.opensuse.org/YaST/Web/Development\nYou can also grant them to the root user and login as root to the YaST web client.\n\n"
185   Dir.glob(File.join(File.dirname(__FILE__), '../../..', "**/*.policy")).each do |policy|
186     doc = REXML::Document.new(File.open(policy))
187     doc.elements.each("/policyconfig/action") do |action|
188       id = action.attributes['id']
189       if not granted.include?(id)
190         warn "policy #{id} is not granted for current user.", "fix it if you plan to login to YaST as '#{user}', run\n  polkit-auth --user #{user} --grant #{id}\nto grant it." + hint_message
191         hint_message = ""
192       end
193     end
194   end
195
196   #
197   # yast-dbus
198   #
199
200   test "YaST D-Bus service available" do
201     begin
202       require "dbus"
203       bus = DBus::SystemBus.instance
204     rescue Exception => e
205     end
206     escape "System error, cannot access D-Bus SystemBus" unless bus
207
208     package = "yast2-dbus-server"
209     version = (os_version == "11.2")?"2.18.1":"2.17.0"
210     test_version package, version
211   end
212
213   #
214   # plugin-specific tests
215   #
216   
217   # mailsettings
218   test "Mail YaPI existance" do
219     unless File.exists? "/usr/share/YaST2/modules/YaPI/MailSettings.pm"
220       warn "mail_settings incomplete", "Install /usr/share/YaST2/modules/YaPI/MailSettings.pm from plugins/mail_settings"
221     end
222   end
223
224   test_version "yast2-mail"
225   test_version "yast2", (os_version == "11.2")?"2.18.24":"2.17.72"
226
227   #
228   # plugin test. Each plugin will be tested for a "GET show" call OR a "GET index" call. This call should return success.
229   # If not an warning will be reported only.
230   #
231
232   test "all available plugins are working" do
233      # Disabled, "Dir.glob" is *waaay* too slow
234
235      Dir.glob(File.join(File.dirname(__FILE__), '../../../plugins', "*","app/controllers","*_controller.rb")).each do |controller|
236        # go over all plugin controllers and call "GET show" or "GET index" (if show does not work)
237        modulename = File.basename(controller, ".rb").split("_").collect { |i| i.capitalize }.join
238        modulepath = File.dirname(controller).split("/")
239        # add Namespaces to the modulename. 
240        # They are defined as subdirectories in the controller directory
241        while modulepath
242          namespace = modulepath.pop
243          if namespace == "controllers"
244            modulepath = nil
245          else
246            modulename = namespace.capitalize + "::" + modulename
247          end
248        end
249        puts "Checking plugin #{modulename} via HTTP GET requests..."
250        ok = system %(cd #{File.dirname(__FILE__)}; export RAILS_PARENT=../../; ruby plugin_test/functional/plugin_show_test.rb --plugin #{modulename} > /dev/null)
251        if !ok
252 #          puts "Trying \"GET index\" cause some plugins do not support \"GET show\"..."
253           ok = system %(cd #{File.dirname(__FILE__)}; export RAILS_PARENT=../../; ruby plugin_test/functional/plugin_index_test.rb --plugin #{modulename} > /dev/null)
254        end
255        unless ok
256          warn "plugin #{modulename} does not work correctly.", "Have a look to log/test.log for additional information" 
257        else
258          puts "plugin #{modulename} works correctly."
259        end
260      end 
261   end
262   
263   if Error.errors == 0
264     puts ""
265     puts "**************************************"
266     puts "All fine, rest-service is ready to run"
267     puts "**************************************"
268   else
269     puts ""
270     puts "*******************************************************"
271     puts "Please, fix the above errors before running the service"
272     puts "*******************************************************"
273   end
274 end