示例#1
0
    def __init__(self, parent, name, type_name, directory, settings,
                 *args, **kwargs):
        """The DBUS_INTERFACE_ROLE_INSTANCE implementation.

        :param parent: The DBusRole Object this is attached to
        :param name: Instance name
        :param type_name: Role name
        :param directory: FIXME: unused???
        :param settings: RoleSettings for the role
        :param path: (Implicit in *args) FIXME: unused???
        """
        super(RoleBase, self).__init__(*args, **kwargs)
        self.busname = args[0]
        self.path = args[1]
        self._bus = slip.dbus.SystemBus()
        self._parent = parent
        self._name = name
        self._escaped_name = dbus_label_escape(name)
        self._type = type_name
        self._escaped_type = dbus_label_escape(type_name)
        self._log_prefix = "role.%s.%s" % (self._escaped_type,
                                           self._escaped_name)
        self._directory = directory
        self._settings = settings
        self._settings.connect("changed", self._emit_property_changed)
        # TODO: place target_unit in settings
        self.target_unit = get_target_unit_name(self.get_type(),
                                                self.get_name())

        # No loaded self._settings, set state to NASCENT
        if not "state" in self._settings:
            self._settings["state"] = NASCENT
        elif self._settings["state"] == SYSTEMD:
            # We need to get the current state from systemd
            try:
                self._settings["state"] = target_unit_state(self.target_unit)
            except:
                # If we couldn't get the target state, we need to assume that
                # it is ERROR
                self._settings["state"] = ERROR
                self.timeout_restart()
                return

            # Then we need to set up a signal monitor to update this state
            # if it changes in systemd
            self.monitor_unit()


        self.timeout_restart()
示例#2
0
    def __init__(self, parent, name, type_name, directory, settings, *args,
                 **kwargs):
        """The DBUS_INTERFACE_ROLE_INSTANCE implementation.

        :param parent: The DBusRole Object this is attached to
        :param name: Instance name
        :param type_name: Role name
        :param directory: FIXME: unused???
        :param settings: RoleSettings for the role
        :param path: (Implicit in *args) FIXME: unused???
        """
        super(RoleBase, self).__init__(*args, **kwargs)
        self.busname = args[0]
        self.path = args[1]
        self._bus = slip.dbus.SystemBus()
        self._parent = parent
        self._name = name
        self._escaped_name = dbus_label_escape(name)
        self._type = type_name
        self._escaped_type = dbus_label_escape(type_name)
        self._log_prefix = "role.%s.%s" % (self._escaped_type,
                                           self._escaped_name)
        self._directory = directory
        self._settings = settings
        self._settings.connect("changed", self._emit_property_changed)
        # TODO: place target_unit in settings
        self.target_unit = get_target_unit_name(self.get_type(),
                                                self.get_name())

        # No loaded self._settings, set state to NASCENT
        if not "state" in self._settings:
            self._settings["state"] = NASCENT
        elif self._settings["state"] == SYSTEMD:
            # We need to get the current state from systemd
            try:
                self._settings["state"] = target_unit_state(self.target_unit)
            except:
                # If we couldn't get the target state, we need to assume that
                # it is ERROR
                self._settings["state"] = ERROR
                self.timeout_restart()
                return

            # Then we need to set up a signal monitor to update this state
            # if it changes in systemd
            self.monitor_unit()

        self.timeout_restart()
示例#3
0
    def start(self):
        """ starts rolekit """
        log.debug1("start()")

        try:
            os.makedirs(ETC_ROLEKIT_ROLES)
        except OSError as e:
            if e.errno == errno.EEXIST:
                if not os.path.isdir(ETC_ROLEKIT_ROLES):
                    log.fatal("'%s' is not a directory.", e.strerror)
            else:
                log.fatal("Failed to create '%s': %s", e.strerror)
                raise
        else:
            log.info1("Created missing '%s'.", ETC_ROLEKIT_ROLES)

        path = ROLEKIT_ROLES

        if not os.path.exists(path) or not os.path.isdir(path):
            log.error("Role directory '%s' does not exist.", path)
            return

        for name in sorted(os.listdir(path)):
            directory = "%s/%s" % (path, name)
            if not os.path.isdir(directory):
                continue

            if not os.path.exists(os.path.join(directory, "role.py")):
                continue

            log.debug1("Loading role '%s'", name)
            escaped_name = dbus_label_escape(name)

            try:
                if os.path.exists(os.path.join(directory, "role.py")):
                    mod = imp.load_source(name, "%s/role.py" % directory)

                # get Role from module
                role = getattr(mod, "Role")

                # create role object that contains the role instance class
                obj = DBusRole(role,
                               name,
                               directory,
                               self._path,
                               "%s/%s" % (DBUS_PATH_ROLES, escaped_name),
                               persistent=self.persistent)

                if obj in self._roles:
                    log.error("Duplicate role '%s'", obj.name)
                else:
                    self._roles.append(obj)
            except RolekitError as msg:
                log.error("Failed to load role '%s': %s", name, msg)
                continue
            except Exception as msg:
                log.error("Failed to load role '%s':", name)
                log.exception()
                continue
示例#4
0
 def getNamedInstance(self, name, sender=None):
     """ return the role with the name, otherwise raise error """
     name = dbus_to_python(name)
     log.debug1("%s.getNamedInstance('%s')", self._log_prefix, name)
     instance_escaped_name = dbus_label_escape(name)
     if instance_escaped_name in self._instances:
         return self._instances[instance_escaped_name]
     raise RolekitError(INVALID_INSTANCE, name)
示例#5
0
 def getNamedInstance(self, name, sender=None):
     """ return the role with the name, otherwise raise error """
     name = dbus_to_python(name)
     log.debug1("%s.getNamedInstance('%s')", self._log_prefix, name)
     instance_escaped_name = dbus_label_escape(name)
     if instance_escaped_name in self._instances:
         return self._instances[instance_escaped_name]
     raise RolekitError(INVALID_INSTANCE, name)
示例#6
0
    def start(self):
        """ starts rolekit """
        log.debug1("start()")

        try:
            os.makedirs(ETC_ROLEKIT_ROLES)
        except OSError as e:
            if e.errno == errno.EEXIST:
                if not os.path.isdir(ETC_ROLEKIT_ROLES):
                    log.fatal("'%s' is not a directory.", e.strerror)
            else:
                log.fatal("Failed to create '%s': %s", e.strerror)
                raise
        else:
            log.info1("Created missing '%s'.", ETC_ROLEKIT_ROLES)

        path = ROLEKIT_ROLES

        if not os.path.exists(path) or not os.path.isdir(path):
            log.error("Role directory '%s' does not exist.", path)
            return

        for name in sorted(os.listdir(path)):
            directory = "%s/%s" % (path, name)
            if not os.path.isdir(directory):
                continue

            if not os.path.exists(os.path.join(directory, "role.py")):
                continue

            log.debug1("Loading role '%s'", name)
            escaped_name = dbus_label_escape(name)

            try:
                if os.path.exists(os.path.join(directory, "role.py")):
                    mod = imp.load_source(name, "%s/role.py" % directory)

                    # get Role from module
                    role = getattr(mod, "Role")

                    # create role object that contains the role instance class
                    obj = DBusRole(role, name, directory, self.busname,
                                    "%s/%s" % (DBUS_PATH_ROLES, escaped_name),
                                   persistent=self.persistent)

                    if obj in self._roles:
                        log.error("Duplicate role '%s'", obj.get_name())
                    else:
                        self._roles.append(obj)
            except RolekitError as msg:
                log.error("Failed to load role '%s': %s", name, msg)
                continue
            except Exception as msg:
                log.error("Failed to load role '%s':", name)
                log.exception()
                continue
示例#7
0
    def remove_instance(self, instance):
        """Remove an instance from our list.

        Note that this neither undeploys it nor deletes the settings file.
        """
        name = instance.get_name()
        escaped_name = dbus_label_escape(name)

        if escaped_name in self._instances:
            del self._instances[escaped_name]
            self.InstanceRemoved(escaped_name)
示例#8
0
    def remove_instance(self, instance):
        """Remove an instance from our list.

        Note that this neither undeploys it nor deletes the settings file.
        """
        name = instance.get_name()
        escaped_name = dbus_label_escape(name)

        if escaped_name in self._instances:
            del self._instances[escaped_name]
            self.InstanceRemoved(escaped_name)
示例#9
0
    def __deploy_async(self, name, values):
        values = dbus_to_python(values)
        name = dbus_to_python(name)
        log.debug1("%s.deploy('%s', %s)", self._log_prefix, name, values)

        # limit role instances to max instances per role
        if len(self._instances) >= self._role._MAX_INSTANCES:
            raise RolekitError(TOO_MANY_INSTANCES, "> %d" % \
                               self._role._MAX_INSTANCES)

        # TODO: lock

        # Create the settings object. If no name has been passed in,
        # this function will create one from the next available value.
        # Note: this isn't protected by a lock, so name-generation
        # might be racy.
        settings = RoleSettings(self.get_name(), name)

        # create escaped name and check if it is already in use
        instance_escaped_name = dbus_label_escape(settings.get_name())
        if instance_escaped_name in self._instances:
            raise RolekitError(NAME_CONFLICT, instance_escaped_name)

        try:
            settings.read()
        except ValueError:
            raise RolekitError(NAME_CONFLICT, settings.filename)
        except IOError:
            pass
        else:
            raise RolekitError(NAME_CONFLICT, settings.filename)

        # create role
        role = self._role(
            self,
            settings.get_name(),
            self.get_name(),
            self._directory,
            settings,
            self.busname,
            "%s/%s/%s" %
            (DBUS_PATH_ROLES, self._escaped_name, instance_escaped_name),
            persistent=self.persistent)
        self._instances[instance_escaped_name] = role
        self.InstanceAdded(instance_escaped_name)

        # TODO: unlock

        # deploy role, lock in role now
        result = yield async .call_future(role.deploy_async(values))
        yield result
示例#10
0
    def __deploy_async(self, name, values):
        values = dbus_to_python(values)
        name = dbus_to_python(name)
        log.debug1("%s.deploy('%s', %s)", self._log_prefix, name, values)

        # limit role instances to max instances per role
        if len(self._instances) >= self._role._MAX_INSTANCES:
            raise RolekitError(TOO_MANY_INSTANCES, "> %d" % \
                               self._role._MAX_INSTANCES)

        # TODO: lock

        # Create the settings object. If no name has been passed in,
        # this function will create one from the next available value.
        # Note: this isn't protected by a lock, so name-generation
        # might be racy.
        settings = RoleSettings(self.get_name(), name)

        # create escaped name and check if it is already in use
        instance_escaped_name = dbus_label_escape(settings.get_name())
        if instance_escaped_name in self._instances:
            raise RolekitError(NAME_CONFLICT, instance_escaped_name)

        try:
            settings.read()
        except ValueError:
            raise RolekitError(NAME_CONFLICT, settings.filename)
        except IOError:
            pass
        else:
            raise RolekitError(NAME_CONFLICT, settings.filename)

        # create role
        role = self._role(self, settings.get_name(), self.get_name(),
                          self._directory, settings, self.busname,
                          "%s/%s/%s" % (DBUS_PATH_ROLES, self._escaped_name,
                                        instance_escaped_name),
                          persistent=self.persistent)
        self._instances[instance_escaped_name] = role
        self.InstanceAdded(instance_escaped_name)

        # TODO: unlock

        # deploy role, lock in role now
        result = yield async.call_future(role.deploy_async(values))
        yield result
示例#11
0
    def __init__(self, role, name, directory, *args, **kwargs):
        """The DBUS_INTERFACE_ROLE implementation

        :param role: RoleBase descendant
        :param name: Role name
        :param directory: FIXME: unused???
        :param path: (Implicit in *args) FIXME: unused???
        """
        super(DBusRole, self).__init__(*args, **kwargs)
        self.busname = args[0]
        self.path = args[1]
        self._role = role
        self._name = name
        self._escaped_name = dbus_label_escape(name)
        self._log_prefix = "role.%s" % self._escaped_name
        self._directory = directory
        self._instances = { }

        # create instances for stored instance settings

        path = "%s/%s" % (ETC_ROLEKIT_ROLES, self.get_name())
        if os.path.exists(path) and os.path.isdir(path):
            for name in sorted(os.listdir(path)):
                if not name.endswith(".json"):
                    continue
                instance = name[:-5]
                log.debug1("Loading '%s' instance '%s'", self.get_name(),
                           instance)

                settings = RoleSettings(self.get_name(), instance)
                try:
                    settings.read()
                except ValueError as e:
                    log.error("Failed to load '%s' instance '%s': %s",
                              self.get_name(), instance, e)
                    continue

                instance_escaped_name = dbus_label_escape(instance)
                if instance_escaped_name in self._instances:
                    raise RolekitError(NAME_CONFLICT, instance_escaped_name)

                role = self._role(self, instance, self.get_name(),
                                  self._directory, settings, self.busname,
                                  "%s/%s/%s" % (DBUS_PATH_ROLES,
                                                self._escaped_name,
                                                instance_escaped_name),
                                  persistent=self.persistent)

                # During roled startup (the only time this function should be
                # called), if any role is in a transitional state, it can only
                # mean that roled was terminated while it was still supposed
                # to be doing something.
                # Always set the state to ERROR here if it's in a transitional state,
                # otherwise we won't be able to clean it up.
                if role._settings["state"] in TRANSITIONAL_STATES:
                    role.change_state(state=ERROR,
                                      write=True,
                                      error="roled terminated unexpectedly")

                self._instances[instance_escaped_name] = role

        self.timeout_restart()
示例#12
0
    def __init__(self, role, name, directory, *args, **kwargs):
        """The DBUS_INTERFACE_ROLE implementation

        :param role: RoleBase descendant
        :param name: Role name
        :param directory: FIXME: unused???
        :param path: (Implicit in *args) FIXME: unused???
        """
        super(DBusRole, self).__init__(*args, **kwargs)
        self.busname = args[0]
        self.path = args[1]
        self._role = role
        self._name = name
        self._escaped_name = dbus_label_escape(name)
        self._log_prefix = "role.%s" % self._escaped_name
        self._directory = directory
        self._instances = {}

        # create instances for stored instance settings

        path = "%s/%s" % (ETC_ROLEKIT_ROLES, self.get_name())
        if os.path.exists(path) and os.path.isdir(path):
            for name in sorted(os.listdir(path)):
                if not name.endswith(".json"):
                    continue
                instance = name[:-5]
                log.debug1("Loading '%s' instance '%s'", self.get_name(),
                           instance)

                settings = RoleSettings(self.get_name(), instance)
                try:
                    settings.read()
                except ValueError as e:
                    log.error("Failed to load '%s' instance '%s': %s",
                              self.get_name(), instance, e)
                    continue

                instance_escaped_name = dbus_label_escape(instance)
                if instance_escaped_name in self._instances:
                    raise RolekitError(NAME_CONFLICT, instance_escaped_name)

                role = self._role(self,
                                  instance,
                                  self.get_name(),
                                  self._directory,
                                  settings,
                                  self.busname,
                                  "%s/%s/%s" %
                                  (DBUS_PATH_ROLES, self._escaped_name,
                                   instance_escaped_name),
                                  persistent=self.persistent)

                # During roled startup (the only time this function should be
                # called), if any role is in a transitional state, it can only
                # mean that roled was terminated while it was still supposed
                # to be doing something.
                # Always set the state to ERROR here if it's in a transitional state,
                # otherwise we won't be able to clean it up.
                if role._settings["state"] in TRANSITIONAL_STATES:
                    role.change_state(state=ERROR,
                                      write=True,
                                      error="roled terminated unexpectedly")

                self._instances[instance_escaped_name] = role

        self.timeout_restart()