ref: refs/heads/master commit de67300ab7d84426f29207ba33dc55557f0a2581 Author: Bjoern Geuken <bgeuken@suse.de> Date: Mon Aug 24 14:43:25 2009 +0200 patches module: fixed wrong naming, added policy file, updated spec file --- .../patches/app/controllers/packages_controller.rb | 65 +++++++++++ .../patches/app/controllers/patches_controller.rb | 17 +--- plugins/patches/app/models/package.rb | 4 +- plugins/patches/app/models/packagekit.rb | 112 ++++++++++++++++++++ plugins/patches/app/models/patch.rb | 10 +-- plugins/patches/config/resources/packages.yml | 2 + .../org.opensuse.yast.system.packages.policy | 23 ++++ .../patches/package/yast2-webservice-patches.spec | 9 +- 8 files changed, 217 insertions(+), 25 deletions(-) diff --git a/plugins/patches/app/controllers/packages_controller.rb b/plugins/patches/app/controllers/packages_controller.rb new file mode 100644 index 0000000..e3e9718 --- /dev/null +++ b/plugins/patches/app/controllers/packages_controller.rb @@ -0,0 +1,65 @@ +require 'singleton' + +class PackagesController < ApplicationController + + before_filter :login_required + + # always check permissions and cache expiration + # even if the result is already created and cached + before_filter :check_read_permissions, :only => {:index, :show} + before_filter :check_cache_status, :only => :index + + # cache 'index' method result + caches_action :index + + private + + def check_read_permissions + unless permission_check( "org.opensuse.yast.system.patches.read") + render ErrorResult.error(403, 1, "no permission") and return + end + end + + # check whether the cached result is still valid + def check_cache_status + cache_timestamp = Rails.cache.read('patches:timestamp') + + if cache_timestamp.nil? + # this is the first run, the cache is not initialized yet, just return + Rails.cache.write('patches:timestamp', Time.now) + return + # the cache expires after 5 minutes, repository metadata + # or RPM database update invalidates the cache immeditely + # (new patches might be applicable) + elsif cache_timestamp < 5.minutes.ago || cache_timestamp < Patch.mtime + logger.debug "#### Patch cache expired" + expire_action :action => :index, :format => params["format"] + Rails.cache.write('patches:timestamp', Time.now) + end + end + + public + + # GET /patch_updates + # GET /patch_updates.xml + def index + # note: permission check was performed in :before_filter + @packages = Package.find(:installed) + respond_to do |format| + format.html { render :xml => @packages.to_xml( :root => "packages", :dasherize => false ) } + format.xml { render :xml => @packages.to_xml( :root => "packages", :dasherize => false ) } + format.json { render :json => @packages.to_json( :root => "packages", :dasherize => false ) } + end + end + + # GET /patch_updates/1 + # GET /patch_updates/1.xml + def show + end + + # PUT /patch_updates/1 + # PUT /patch_updates/1.xml + def update + end + +end diff --git a/plugins/patches/app/controllers/patches_controller.rb b/plugins/patches/app/controllers/patches_controller.rb index b1077e1..0c61832 100644 --- a/plugins/patches/app/controllers/patches_controller.rb +++ b/plugins/patches/app/controllers/patches_controller.rb @@ -44,20 +44,11 @@ class PatchesController < ApplicationController # GET /patch_updates.xml def index # note: permission check was performed in :before_filter -# @package_kit = Patch.find(:available) - @package_kit = Package.find(:installed) - #case params[:type] - # when "patch" - @package_kit = Patch.find(:available) - # when "package" - # @package_kit = Package.find(:installed) - # else - #error render ErrorResult.error(???, 1, "wrong parameter") and return - #end + @patches = Patch.find(:available) respond_to do |format| - format.html { render :xml => @package_kit.to_xml( :root => "packagekit", :dasherize => false ) } - format.xml { render :xml => @package_kit.to_xml( :root => "packagekit", :dasherize => false ) } - format.json { render :json => @package_kit.to_json( :root => "packagekit", :dasherize => false ) } + format.html { render :xml => @patches.to_xml( :root => "patches", :dasherize => false ) } + format.xml { render :xml => @patches.to_xml( :root => "patches", :dasherize => false ) } + format.json { render :json => @patches.to_json( :root => "patches", :dasherize => false ) } end end diff --git a/plugins/patches/app/models/package.rb b/plugins/patches/app/models/package.rb index dc5c2ae..cd9b67d 100644 --- a/plugins/patches/app/models/package.rb +++ b/plugins/patches/app/models/package.rb @@ -1,6 +1,6 @@ -require 'policykit' +require 'packagekit' -class Package < Policykit +class Package < PackageKitModule attr_accessor :resolvable_id, :name, diff --git a/plugins/patches/app/models/packagekit.rb b/plugins/patches/app/models/packagekit.rb new file mode 100644 index 0000000..2456048 --- /dev/null +++ b/plugins/patches/app/models/packagekit.rb @@ -0,0 +1,112 @@ +require "dbus" +require 'socket' +require 'thread' + +# Used to stop DBus::Main loop +class PKErrorException < Exception; end +# Used to stop DBus::Main loop +class PKFinishedException < Exception; end + +# Model for patches available via package kit +class PackageKitModule + + attr_accessor :resolvable_id, + :kind, + :name, + :arch, + :repo, + :summary + def id + @resolvable_id + end + + def id=(id_val) + @resolvable_id = id_val + end + + # returns the modification time of + # the patch status, which you can use + # for cache policy purposes + def self.mtime + # we look for the most recent (max) modification time + # of either the package database or libzypp cache files + [ File.stat("/var/lib/rpm/Packages").mtime, + File.stat("/var/cache/zypp/solv").mtime, + * Dir["/var/cache/zypp/solv/*/solv"].map{ |x| File.stat(x).mtime } ].max + end + + # default constructor + def initialize(attributes) + attributes.each do |key, value| + instance_variable_set("@#{key}", value) + end + end + + def to_json( options = {} ) + hash = Hash.from_xml(to_xml()) + return hash.to_json + end + + # find patches + # Patch.find(:available) + # Patch.find(212) + def self.execute(method, args, signal, &block) + patch_updates = [] + system_bus = DBus::SystemBus.instance + package_kit = system_bus.service("org.freedesktop.PackageKit") + obj = package_kit.object("/org/freedesktop/PackageKit") + #logger.debug obj.inspect + obj.introspect + obj_with_iface = obj["org.freedesktop.PackageKit"] + tid = obj_with_iface.GetTid + obj_tid = package_kit.object(tid[0]) + obj_tid.introspect + obj_tid_with_iface = obj_tid["org.freedesktop.PackageKit.Transaction"] + obj_tid.default_iface = "org.freedesktop.PackageKit.Transaction" + + obj_tid.on_signal(signal.to_s) do |line1,line2,line3| block.call(line1,line2,line3) end + + obj_tid.on_signal("Error") do |u1,u2| + raise PKErrorException + end + obj_tid.on_signal("Finished") do |u1,u2| + raise PKFinishedException + end + + obj_tid_with_iface.send(method.to_sym, *args) + + if patch_updates.empty? + loop = DBus::Main.new + loop << system_bus + begin + loop.run + rescue PKErrorException + rescue PKFinishedException + end + end + + obj_with_iface.SuggestDaemonQuit + return patch_updates + end + + # installs this + def install + self.class.install(id) + end + + # Patch.install(patch) + # Patch.install(id) + def self.install(patch) + if patch.is_a?(Patch) + update_id = "#{patch.name};#{patch.resolvable_id};#{patch.arch};#{@patch.repo}" + Rails.logger.debug "Install Update: #{update_id}" + self.package_kit_install(update_id) + else + # if is not an object, assume it is an id + patch_id = patch + patch = Patch.find(patch_id) + raise "Can't install update #{patch_id} because it does not exist" if patch.nil? or not patch.is_a?(Patch) + self.install(patch) + end + end +end diff --git a/plugins/patches/app/models/patch.rb b/plugins/patches/app/models/patch.rb index 3659bbb..2a5c856 100644 --- a/plugins/patches/app/models/patch.rb +++ b/plugins/patches/app/models/patch.rb @@ -1,7 +1,4 @@ -#require "dbus" -#require 'socket' -#require 'thread' -require 'policykit' +require 'packagekit' # Used to stop DBus::Main loop class PKErrorException < Exception; end @@ -9,7 +6,7 @@ class PKErrorException < Exception; end class PKFinishedException < Exception; end # Model for patches available via package kit -class Patch < Policykit +class Patch < PackageKitModule attr_accessor :resolvable_id, :kind, @@ -17,6 +14,7 @@ class Patch < Policykit :arch, :repo, :summary + def id @resolvable_id end @@ -41,9 +39,7 @@ class Patch < Policykit xml.instruct! unless options[:skip_instruct] xml.patch_update do - xml.tag!(:id, id ) xml.tag!(:resolvable_id, @resolvable_id, {:type => "integer"} ) - # Patch.find(212) xml.tag!(:kind, @kind ) xml.tag!(:name, @name ) xml.tag!(:arch, @arch ) diff --git a/plugins/patches/config/resources/packages.yml b/plugins/patches/config/resources/packages.yml new file mode 100644 index 0000000..acef05b --- /dev/null +++ b/plugins/patches/config/resources/packages.yml @@ -0,0 +1,2 @@ +interface: org.opensuse.yast.system.packages +controller: packages diff --git a/plugins/patches/package/org.opensuse.yast.system.packages.policy b/plugins/patches/package/org.opensuse.yast.system.packages.policy new file mode 100644 index 0000000..c05c87c --- /dev/null +++ b/plugins/patches/package/org.opensuse.yast.system.packages.policy @@ -0,0 +1,23 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!DOCTYPE policyconfig PUBLIC + "-//freedesktop//DTD PolicyKit Policy Configuration 1.0//EN" + "http://www.freedesktop.org/standards/PolicyKit/1.0/policyconfig.dtd"> +<policyconfig> + + <vendor>YaST Webservice Project</vendor> + <vendor_url>http://en.opensuse.org/YAST</vendor_url> + +<!-- +Rights for patches +--> + + <action id="org.opensuse.yast.system.packages.read"> + <description>Reading patch information</description> + <message>Authentication is required to read package information</message> + <defaults> + <allow_inactive>no</allow_inactive> + <allow_active>no</allow_active> + </defaults> + </action> + +</policyconfig> diff --git a/plugins/patches/package/yast2-webservice-patches.spec b/plugins/patches/package/yast2-webservice-patches.spec index 3cd719a..f3d2874 100644 --- a/plugins/patches/package/yast2-webservice-patches.spec +++ b/plugins/patches/package/yast2-webservice-patches.spec @@ -20,6 +20,7 @@ Release: 0 Summary: YaST2 - Webservice - Patches Source: www.tar.bz2 Source1: org.opensuse.yast.system.patches.policy +Source2: org.opensuse.yast.system.packages.policy BuildRoot: %{_tmppath}/%{name}-%{version}-build BuildArch: noarch @@ -30,7 +31,7 @@ BuildArch: noarch %description -YaST2 - Webservice - REST based interface of YaST in order to handle patches. +YaST2 - Webservice - REST based interface of YaST in order to handle patches and packages. Authors: -------- Stefan Schubert <schubi@opensuse.org> @@ -51,17 +52,18 @@ cp -a * $RPM_BUILD_ROOT/srv/www/%{pkg_user}/vendor/plugins/%{plugin_name} # Policies mkdir -p $RPM_BUILD_ROOT/usr/share/PolicyKit/policy install -m 0644 %SOURCE1 $RPM_BUILD_ROOT/usr/share/PolicyKit/policy/ +install -m 0644 %SOURCE2 $RPM_BUILD_ROOT/usr/share/PolicyKit/policy/ %clean rm -rf $RPM_BUILD_ROOT %post # -# granting all permissions for root +# granting all permissions for root # /etc/yastws/tools/policyKit-rights.rb --user root --action grant >& /dev/null || : -%files +%files %defattr(-,root,root) %dir /srv/www/%{pkg_user} %dir /srv/www/%{pkg_user}/vendor @@ -79,5 +81,6 @@ rm -rf $RPM_BUILD_ROOT /srv/www/%{pkg_user}/vendor/plugins/%{plugin_name}/config /srv/www/%{pkg_user}/vendor/plugins/%{plugin_name}/tasks %attr(644,root,root) %config /usr/share/PolicyKit/policy/org.opensuse.yast.system.%{plugin_name}.policy +%attr(644,root,root) %config /usr/share/PolicyKit/policy/%SOURCE2 %changelog -- To unsubscribe, e-mail: yast-commit+unsubscribe@opensuse.org For additional commands, e-mail: yast-commit+help@opensuse.org