diff --git a/comar-dbus.patch b/comar-dbus.patch deleted file mode 100644 index d5ecd633..00000000 --- a/comar-dbus.patch +++ /dev/null @@ -1,289 +0,0 @@ -Index: pisi/comariface.py -=================================================================== ---- pisi/comariface.py (revision 17303) -+++ pisi/comariface.py (working copy) -@@ -13,6 +13,7 @@ - import os - import time - import select -+import string - - import gettext - __trans = gettext.translation('pisi', fallback=True) -@@ -25,117 +26,147 @@ - pass - - try: -- import comar -+ import dbus - except ImportError: -- raise Error(_("comar package is not fully installed")) -+ raise Error(_("dbus-python package is not fully installed")) - --def get_comar(): -- """Connect to the comar daemon and return the handle""" -+def is_char_valid(char): -+ """Test if char is valid object path character.""" -+ return char in string.ascii_letters + string.digits + "_" -+ -+def make_object_path(package): -+ """Generates DBus object name from package name.""" -+ object = package -+ for char in package: -+ if not is_char_valid(char): -+ object = object.replace(char, '_') -+ if object[0].isdigit(): -+ object = '_%s' % object -+ return object -+ -+def get_iface(package="", model=""): -+ """Connect to the DBus daemon and return the system interface.""" - -- sockname = "/var/run/comar.socket" -+ sockname = "unix:path=/var/run/dbus/system_bus_socket" - # YALI starts comar chrooted in the install target, but uses PiSi outside of - # the chroot environment, so PiSi needs to use a different socket path to be -- # able to connect true comar (usually /mnt/target/var/run/comar.socket). -- if ctx.comar_sockname: -- sockname = ctx.comar_sockname -+ # able to connect true dbus (and comar). -+ # (usually unix:path=/var/run/dbus/system_bus_socket) -+ if ctx.dbus_sockname: -+ sockname = ctx.dbus_sockname - -+ if package: -+ obj_path = "/package/%s" % package -+ else: -+ obj_path = "/" -+ if model: -+ obj_interface = "tr.org.pardus.comar.%s" % model -+ else: -+ obj_interface = "tr.org.pardus.comar" -+ - # This function is sometimes called when comar has recently started - # or restarting after an update. So we give comar a chance to become - # active in a reasonable time. - timeout = 7 - while timeout > 0: - try: -- com = comar.Link(sockname) -- return com -- except comar.CannotConnect: -+ bus = dbus.bus.BusConnection(address_or_type=sockname) -+ obj = bus.get_object(ctx.comar_destination, obj_path, introspect=False) -+ iface = dbus.Interface(obj, dbus_interface=obj_interface) -+ return iface -+ except dbus.DBusException: - pass - time.sleep(0.2) - timeout -= 0.2 -- raise Error(_("cannot connect to comar")) -+ raise Error(_("cannot connect to dbus")) - --def wait_for_result(com, package_name=None): -- multiple = False -- while True: -- try: -- reply = com.read_cmd() -- except select.error: -- if ctx.keyboard_interrupt_pending(): -- return -- raise -- except comar.LinkClosed: -- # Comar postInstall does a "service comar restart" which cuts -- # our precious communication link, so we waitsss -- if package_name == "comar": -- try: -- get_comar() -- except Error: -- raise Error, _("Could not restart comar") -- return -- else: -- if ctx.keyboard_interrupt_pending(): -- return -- raise Error, _("connection with comar unexpectedly closed") -- -- cmd = reply[0] -- if cmd == com.RESULT and not multiple: -- return -- elif cmd == com.NONE and not multiple: -- # no post/pre function, that is ok -- return -- elif cmd == com.RESULT_START: -- multiple = True -- elif cmd == com.RESULT_END: -- return -- elif cmd == com.FAIL: -- raise Error, _("Configuration error: %s") % reply[2] -- elif cmd == com.ERROR: -- raise Error, _("Script error: %s") % reply[2] -- elif cmd == com.DENIED: -- raise Error, _("comar denied our access") -- - def post_install(package_name, provided_scripts, scriptpath, metapath, filepath, fromVersion, fromRelease, toVersion, toRelease): - """Do package's post install operations""" - - ctx.ui.info(_("Configuring %s package") % package_name) - self_post = False -- com = get_comar() -+ sys_service = False -+ sys_iface = get_iface() -+ object_name = make_object_path(package_name) - - for script in provided_scripts: - ctx.ui.debug(_("Registering %s comar script") % script.om) - if script.om == "System.Package": - self_post = True -- com.register(script.om, package_name, os.path.join(scriptpath, script.script)) -- wait_for_result(com) -+ elif script.om == "System.Service": -+ sys_service = False -+ try: -+ sys_iface.register(object_name, script.om, os.path.join(scriptpath, script.script)) -+ except dbus.DBusException, exception: -+ raise Error, _("Script error: %s") % exception -+ if sys_service: -+ try: -+ iface = get_iface(object_name, "System.Service") -+ iface.registerState() -+ except dbus.DBusException, exception: -+ raise Error, _("Script error: %s") % exception - - ctx.ui.debug(_("Calling post install handlers")) -- com.call("System.PackageHandler.setupPackage", [ "metapath", metapath, "filepath", filepath ]) -- wait_for_result(com) -+ for handler in sys_iface.listModelApplications("System.PackageHandler"): -+ iface = get_iface(handler, "System.PackageHandler") -+ try: -+ iface.setupPackage(metapath, filepath, timeout=300) -+ except dbus.DBusException, exception: -+ # Do nothing if setupPackage method is not defined in package script -+ if not (exception._dbus_error_name.startswith("tr.org.pardus.comar") and -+ exception._dbus_error_name.split('tr.org.pardus.comar.')[1] == 'python.missing'): -+ raise Error, _("Script error: %s") % exception - - if self_post: -- args = { -- "fromVersion": fromVersion, -- "fromRelease": fromRelease, -- "toVersion": toVersion, -- "toRelease": toRelease, -- } -+ if not fromVersion: -+ fromVersion = "" -+ if not fromRelease: -+ fromRelease = "" -+ - ctx.ui.debug(_("Running package's post install script")) -- com.call_package("System.Package.postInstall", package_name, args) -- wait_for_result(com, package_name) -+ try: -+ iface = get_iface(object_name, "System.Package") -+ iface.postInstall(fromVersion, fromRelease, toVersion, toRelease, timeout=300) -+ except dbus.DBusException, exception: -+ # Do nothing if postInstall method is not defined in package script -+ if not (exception._dbus_error_name.startswith("tr.org.pardus.comar") and -+ exception._dbus_error_name.split('tr.org.pardus.comar.')[1] == 'python.missing'): -+ raise Error, _("Script error: %s") % exception -+ -+ if package_name == 'comar': -+ pisi.api.set_comar_destination('tr.org.pardus.comar.new') - - def pre_remove(package_name, metapath, filepath): - """Do package's pre removal operations""" - - ctx.ui.info(_("Configuring %s package for removal") % package_name) -- com = get_comar() -+ sys_iface = get_iface() -+ object_name = make_object_path(package_name) - -- ctx.ui.debug(_("Running package's pre remove script")) -- com.call_package("System.Package.preRemove", package_name) -- wait_for_result(com) -+ if "System.Package" in sys_iface.listApplicationModels(object_name): -+ ctx.ui.debug(_("Running package's pre remove script")) -+ iface = get_iface(object_name, "System.Package") -+ try: -+ iface.preRemove(timeout=300) -+ except dbus.DBusException, exception: -+ # Do nothing if preRemove method is not defined in package script -+ if not (exception._dbus_error_name.startswith("tr.org.pardus.comar") and -+ exception._dbus_error_name.split('tr.org.pardus.comar.')[1] == 'python.missing'): -+ raise Error, _("Script error: %s") % exception - - ctx.ui.debug(_("Calling pre remove handlers")) -- com.call("System.PackageHandler.cleanupPackage", [ "metapath", metapath, "filepath", filepath ]) -- wait_for_result(com) -+ for handler in sys_iface.listModelApplications("System.PackageHandler"): -+ iface = get_iface(handler, "System.PackageHandler") -+ try: -+ iface.cleanupPackage(metapath, filepath, timeout=300) -+ except dbus.DBusException, exception: -+ # Do nothing if cleanupPackage method is not defined in package script -+ if not (exception._dbus_error_name.startswith("tr.org.pardus.comar") and -+ exception._dbus_error_name.split('tr.org.pardus.comar.')[1] == 'python.missing'): -+ raise Error, _("Script error: %s") % exception - - ctx.ui.debug(_("Unregistering comar scripts")) -- com.remove(package_name) -- wait_for_result(com) -+ try: -+ sys_iface.remove(object_name) -+ except dbus.DBusException, exception: -+ raise Error, _("Script error: %s") % exception -Index: pisi/api.py -=================================================================== ---- pisi/api.py (revision 17303) -+++ pisi/api.py (working copy) -@@ -72,13 +72,20 @@ - """ - ctx.comar = enable - --def set_comar_sockname(sockname): -+def set_comar_destination(destination): - """ -- Set comar socket file -+ Set comar bus destination -+ @param destination: Path to bus destination of COMAR -+ """ -+ ctx.comar_destination = destination -+ -+def set_dbus_sockname(sockname): -+ """ -+ Set dbus socket file - Used by YALI -- @param sockname: Path to comar socket file -+ @param sockname: Path to dbus socket file - """ -- ctx.comar_sockname = sockname -+ ctx.dbus_sockname = sockname - - def set_options(options): - """ -Index: pisi/atomicoperations.py -=================================================================== ---- pisi/atomicoperations.py (revision 17303) -+++ pisi/atomicoperations.py (working copy) -@@ -152,7 +152,7 @@ - # check comar - if self.metadata.package.providesComar and ctx.comar: - import pisi.comariface as comariface -- comariface.get_comar() -+ comariface.get_iface() - - def check_relations(self): - # check dependencies -Index: pisi/context.py -=================================================================== ---- pisi/context.py (revision 17303) -+++ pisi/context.py (working copy) -@@ -38,7 +38,8 @@ - stderr = None - - comar = True --comar_sockname = None -+comar_destination = "tr.org.pardus.comar" -+dbus_sockname = None - - # Bug #2879 - # FIXME: Maybe we can create a simple rollback mechanism. There are other diff --git a/pisi/api.py b/pisi/api.py index 2c01d937..8980d798 100644 --- a/pisi/api.py +++ b/pisi/api.py @@ -73,13 +73,20 @@ def set_comar(enable): """ ctx.comar = enable -def set_comar_sockname(sockname): +def set_comar_destination(destination): """ - Set comar socket file - Used by YALI - @param sockname: Path to comar socket file + Set comar bus destination + @param destination: Path to bus destination of COMAR """ - ctx.comar_sockname = sockname + ctx.comar_destination = destination + +def set_dbus_sockname(sockname): + """ + Set dbus socket file + Used by YALI + @param sockname: Path to dbus socket file + """ + ctx.dbus_sockname = sockname def set_options(options): """ diff --git a/pisi/atomicoperations.py b/pisi/atomicoperations.py index 5dfaa37f..f3874945 100644 --- a/pisi/atomicoperations.py +++ b/pisi/atomicoperations.py @@ -152,7 +152,7 @@ class Install(AtomicOperation): # check comar if self.metadata.package.providesComar and ctx.comar: import pisi.comariface as comariface - comariface.get_comar() + comariface.get_iface() def check_relations(self): # check dependencies diff --git a/pisi/comariface.py b/pisi/comariface.py index 09efd28a..160be280 100644 --- a/pisi/comariface.py +++ b/pisi/comariface.py @@ -13,6 +13,7 @@ import os import time import select +import string import gettext __trans = gettext.translation('pisi', fallback=True) @@ -25,19 +26,43 @@ class Error(pisi.Error): pass try: - import comar + import dbus except ImportError: - raise Error(_("comar package is not fully installed")) + raise Error(_("dbus-python package is not fully installed")) -def get_comar(): - """Connect to the comar daemon and return the handle""" +def is_char_valid(char): + """Test if char is valid object path character.""" + return char in string.ascii_letters + string.digits + "_" + +def make_object_path(package): + """Generates DBus object name from package name.""" + object = package + for char in package: + if not is_char_valid(char): + object = object.replace(char, '_') + if object[0].isdigit(): + object = '_%s' % object + return object + +def get_iface(package="", model=""): + """Connect to the DBus daemon and return the system interface.""" - sockname = "/var/run/comar.socket" + sockname = "/var/run/dbus/system_bus_socket" # YALI starts comar chrooted in the install target, but uses PiSi outside of # the chroot environment, so PiSi needs to use a different socket path to be - # able to connect true comar (usually /mnt/target/var/run/comar.socket). - if ctx.comar_sockname: - sockname = ctx.comar_sockname + # able to connect true dbus (and comar). + # (usually /var/run/dbus/system_bus_socket) + if ctx.dbus_sockname: + sockname = ctx.dbus_sockname + + if package: + obj_path = "/package/%s" % package + else: + obj_path = "/" + if model: + obj_interface = "tr.org.pardus.comar.%s" % model + else: + obj_interface = "tr.org.pardus.comar" # This function is sometimes called when comar has recently started # or restarting after an update. So we give comar a chance to become @@ -45,97 +70,103 @@ def get_comar(): timeout = 7 while timeout > 0: try: - com = comar.Link(sockname) - return com - except comar.CannotConnect: + bus = dbus.bus.BusConnection(address_or_type="unix:path=%s" % sockname) + obj = bus.get_object(ctx.comar_destination, obj_path, introspect=False) + iface = dbus.Interface(obj, dbus_interface=obj_interface) + return iface + except dbus.DBusException: pass time.sleep(0.2) timeout -= 0.2 - raise Error(_("cannot connect to comar")) - -def wait_for_result(com, package_name=None): - multiple = False - while True: - try: - reply = com.read_cmd() - except select.error: - if ctx.keyboard_interrupt_pending(): - return - raise - except comar.LinkClosed: - # Comar postInstall does a "service comar restart" which cuts - # our precious communication link, so we waitsss - if package_name == "comar": - try: - get_comar() - except Error: - raise Error, _("Could not restart comar") - return - else: - if ctx.keyboard_interrupt_pending(): - return - raise Error, _("connection with comar unexpectedly closed") - - cmd = reply[0] - if cmd == com.RESULT and not multiple: - return - elif cmd == com.NONE and not multiple: - # no post/pre function, that is ok - return - elif cmd == com.RESULT_START: - multiple = True - elif cmd == com.RESULT_END: - return - elif cmd == com.FAIL: - raise Error, _("Configuration error: %s") % reply[2] - elif cmd == com.ERROR: - raise Error, _("Script error: %s") % reply[2] - elif cmd == com.DENIED: - raise Error, _("comar denied our access") + raise Error(_("cannot connect to dbus")) def post_install(package_name, provided_scripts, scriptpath, metapath, filepath, fromVersion, fromRelease, toVersion, toRelease): """Do package's post install operations""" ctx.ui.info(_("Configuring %s package") % package_name) self_post = False - com = get_comar() + sys_service = False + sys_iface = get_iface() + object_name = make_object_path(package_name) for script in provided_scripts: ctx.ui.debug(_("Registering %s comar script") % script.om) if script.om == "System.Package": self_post = True - com.register(script.om, package_name, os.path.join(scriptpath, script.script)) - wait_for_result(com) + elif script.om == "System.Service": + sys_service = False + try: + sys_iface.register(object_name, script.om, os.path.join(scriptpath, script.script)) + except dbus.DBusException, exception: + raise Error, _("Script error: %s") % exception + if sys_service: + try: + iface = get_iface(object_name, "System.Service") + iface.registerState() + except dbus.DBusException, exception: + raise Error, _("Script error: %s") % exception ctx.ui.debug(_("Calling post install handlers")) - com.call("System.PackageHandler.setupPackage", [ "metapath", metapath, "filepath", filepath ]) - wait_for_result(com) + for handler in sys_iface.listModelApplications("System.PackageHandler"): + iface = get_iface(handler, "System.PackageHandler") + try: + iface.setupPackage(metapath, filepath, timeout=300) + except dbus.DBusException, exception: + # Do nothing if setupPackage method is not defined in package script + if not (exception._dbus_error_name.startswith("tr.org.pardus.comar") and + exception._dbus_error_name.split('tr.org.pardus.comar.')[1] == 'python.missing'): + raise Error, _("Script error: %s") % exception if self_post: - args = { - "fromVersion": fromVersion, - "fromRelease": fromRelease, - "toVersion": toVersion, - "toRelease": toRelease, - } + if not fromVersion: + fromVersion = "" + if not fromRelease: + fromRelease = "" + ctx.ui.debug(_("Running package's post install script")) - com.call_package("System.Package.postInstall", package_name, args) - wait_for_result(com, package_name) + try: + iface = get_iface(object_name, "System.Package") + iface.postInstall(fromVersion, fromRelease, toVersion, toRelease, timeout=300) + except dbus.DBusException, exception: + # Do nothing if postInstall method is not defined in package script + if not (exception._dbus_error_name.startswith("tr.org.pardus.comar") and + exception._dbus_error_name.split('tr.org.pardus.comar.')[1] == 'python.missing'): + raise Error, _("Script error: %s") % exception + + if package_name == 'comar': + pisi.api.set_comar_destination('tr.org.pardus.comar.new') def pre_remove(package_name, metapath, filepath): """Do package's pre removal operations""" ctx.ui.info(_("Configuring %s package for removal") % package_name) - com = get_comar() + sys_iface = get_iface() + object_name = make_object_path(package_name) - ctx.ui.debug(_("Running package's pre remove script")) - com.call_package("System.Package.preRemove", package_name) - wait_for_result(com) + if "System.Package" in sys_iface.listApplicationModels(object_name): + ctx.ui.debug(_("Running package's pre remove script")) + iface = get_iface(object_name, "System.Package") + try: + iface.preRemove(timeout=300) + except dbus.DBusException, exception: + # Do nothing if preRemove method is not defined in package script + if not (exception._dbus_error_name.startswith("tr.org.pardus.comar") and + exception._dbus_error_name.split('tr.org.pardus.comar.')[1] == 'python.missing'): + raise Error, _("Script error: %s") % exception ctx.ui.debug(_("Calling pre remove handlers")) - com.call("System.PackageHandler.cleanupPackage", [ "metapath", metapath, "filepath", filepath ]) - wait_for_result(com) + for handler in sys_iface.listModelApplications("System.PackageHandler"): + iface = get_iface(handler, "System.PackageHandler") + try: + iface.cleanupPackage(metapath, filepath, timeout=300) + except dbus.DBusException, exception: + # Do nothing if cleanupPackage method is not defined in package script + if not (exception._dbus_error_name.startswith("tr.org.pardus.comar") and + exception._dbus_error_name.split('tr.org.pardus.comar.')[1] == 'python.missing'): + raise Error, _("Script error: %s") % exception ctx.ui.debug(_("Unregistering comar scripts")) - com.remove(package_name) - wait_for_result(com) + try: + sys_iface.remove(object_name) + except dbus.DBusException, exception: + raise Error, _("Script error: %s") % exception diff --git a/pisi/context.py b/pisi/context.py index 3da73019..4e146ad6 100644 --- a/pisi/context.py +++ b/pisi/context.py @@ -38,7 +38,8 @@ stdout = None stderr = None comar = True -comar_sockname = None +comar_destination = "tr.org.pardus.comar" +dbus_sockname = None # Bug #2879 # FIXME: Maybe we can create a simple rollback mechanism. There are other