Ejemplo n.º 1
0
    def gather(self):
        self.directory = mkdtemp(prefix="checkbox")
        child_input = create_fifo(os.path.join(self.directory, "input"),
                                  0o600)
        child_output = create_fifo(os.path.join(self.directory, "output"),
                                   0o600)

        self.backend_is_alive = False
        for attempt in range(1, 4):
            self.spawn_backend(child_input, child_output)
            #Only returns if I'm still the parent,
            #so I can do parent stuff here
            self.parent_writer = FifoWriter(child_input, timeout=self.timeout)
            self.parent_reader = FifoReader(child_output,
                                            timeout=self.timeout)
            if self.ping_backend():
                logging.debug("Backend responded, continuing execution.")
                self.backend_is_alive = True
                break
            else:
                logging.debug("Backend didn't respond, "
                              "trying to create again.")

        if not self.backend_is_alive:
            logging.warning("Privileged backend not responding. " +
                            "jobs specifying user will not be run")
Ejemplo n.º 2
0
    def gather(self):
        self.directory = mkdtemp(prefix="checkbox")
        child_input = create_fifo(os.path.join(self.directory, "input"), 0o600)
        child_output = create_fifo(os.path.join(self.directory, "output"),
                                   0o600)

        self.backend_is_alive = False
        for attempt in range(1, 4):
            self.spawn_backend(child_input, child_output)
            #Only returns if I'm still the parent,
            #so I can do parent stuff here
            self.parent_writer = FifoWriter(child_input, timeout=self.timeout)
            self.parent_reader = FifoReader(child_output, timeout=self.timeout)
            if self.ping_backend():
                logging.debug("Backend responded, continuing execution.")
                self.backend_is_alive = True
                break
            else:
                logging.debug("Backend didn't respond, "
                              "trying to create again.")

        if not self.backend_is_alive:
            logging.warning("Privileged backend not responding. " +
                            "jobs specifying user will not be run")
Ejemplo n.º 3
0
class BackendInfo(Plugin):

    # how long to wait for I/O from/to the backend before the call returns.
    # How we behave if I/O times out is dependent on the situation.
    timeout = Float(default=60.0)

    command = Path(default="%(checkbox_share)s/backend")

    def register(self, manager):
        super(BackendInfo, self).register(manager)

        for (rt, rh) in [
             ("message-exec", self.message_exec),
             ("stop", self.stop)]:
            self._manager.reactor.call_on(rt, rh)

        # Backend should run as early as possible
        self._manager.reactor.call_on("gather", self.gather, -100)

    def get_command(self, *args):
        command = [self.command, "--path=%s" % os.environ["PATH"]]

        return command + list(args)

    def get_root_command(self, *args):
        uid = os.getuid()
        if uid == 0:
            prefix = []
        elif os.getenv("DISPLAY") and \
                call(["which", "kdesudo"],
                    stdout=PIPE, stderr=PIPE) == 0 and \
                call(["pgrep", "-x", "-u", str(uid), "ksmserver"],
                    stdout=PIPE, stderr=PIPE) == 0:
            prefix = ["kdesudo", "--desktop", "/usr/share/applications/checkbox-qt.desktop", "--"]
        elif os.getenv("DISPLAY") and \
                call(["which", "gksu"],
                    stdout=PIPE, stderr=PIPE) == 0 and \
                call(["pgrep", "-x", "-u", str(uid), "gnome-panel|gconfd-2"],
                    stdout=PIPE, stderr=PIPE) == 0:
            prefix = ["gksu", "--description", "/usr/share/applications/checkbox-qt.desktop", "--"]
        else:
            prefix = ["sudo"]

        return prefix + self.get_command(*args)

    def spawn_backend(self, input_fifo, output_fifo):
        self.pid = os.fork()
        if self.pid == 0:
            root_command = self.get_root_command(input_fifo, output_fifo)
            os.execvp(root_command[0], root_command)
            # Should never get here

    def ping_backend(self):
        if not self.parent_reader or not self.parent_writer:
            return False
        self.parent_writer.write_object("ping")
        result = self.parent_reader.read_object()
        return result == "pong"


    def gather(self):
        self.directory = mkdtemp(prefix="checkbox")
        child_input = create_fifo(os.path.join(self.directory, "input"), 0600)
        child_output = create_fifo(os.path.join(self.directory, "output"), 0600)

        self.backend_is_alive = False
        for attempt in range(1,4):
            self.spawn_backend(child_input, child_output)
            #Only returns if I'm still the parent, so I can do parent stuff here
            self.parent_writer = FifoWriter(child_input, timeout=self.timeout)
            self.parent_reader = FifoReader(child_output, timeout=self.timeout)
            if self.ping_backend():
                logging.debug("Backend responded, continuing execution.")
                self.backend_is_alive = True
                break
            else:
                logging.debug("Backend didn't respond, trying to create again.")

        if not self.backend_is_alive: 
            logging.warning("Privileged backend not responding. " + 
                            "jobs specifying user will not be run")

    def message_exec(self, message):
        if "user" in message:
            if "environ" in message:
                #Prepare variables to be "exported" from my environment
                #to the backend's.
                backend_environ=["%s=%s" % (key, os.environ[key])
                             for key in message["environ"] 
                             if key in os.environ]
                message=dict(message) #so as to not wreck the
                                      #original message
                message["environ"]=backend_environ

            if (self.backend_is_alive and not self.ping_backend()):
                self.backend_is_alive = False

            if self.backend_is_alive:
                self.parent_writer.write_object(message)
                while True:
                    result = self.parent_reader.read_object()
                    if result:
                        break
                    else:
                        logging.info("Waiting for result...")
            else:
                result = (FAIL, "Unable to test. Privileges are " +
                                "required for this job.", 0,)
            if result:
                self._manager.reactor.fire("message-result", *result)

    def stop(self):
        self.parent_writer.write_object("stop")
        self.parent_writer.close()
        self.parent_reader.close()
        shutil.rmtree(self.directory)

        if self.backend_is_alive:
            os.waitpid(self.pid, 0)
Ejemplo n.º 4
0
class BackendInfo(Plugin):

    # how long to wait for I/O from/to the backend before the call returns.
    # How we behave if I/O times out is dependent on the situation.
    timeout = Float(default=60.0)

    command = Path(default="%(checkbox_share)s/backend")

    next_sequence = 0
    expected_sequence = 0

    def write_to_parent(self, object):
        message = (self.next_sequence, object,)
        logging.debug("Sending message with sequence number %s to backend" %
                       self.next_sequence)
        self.parent_writer.write_object(message)
        self.expected_sequence = self.next_sequence
        self.next_sequence += 1

    def read_from_parent(self):
        correct_sequence = False
        while not correct_sequence:
            ro = self.parent_reader.read_object()
            if ro:
                sequence, result = ro
                logging.debug("Expecting sequence number %s from backend, "
                              "got sequence number %s" %
                       (self.expected_sequence, sequence))
                if (self.expected_sequence == sequence):
                    correct_sequence = True
                else:
                    logging.warning("Backend sent wrong sequence number, "
                                    "Discarding message and re-reading")
            else:
                #If we timed out, just return nothing, the rest of
                #the code knows how to handle this.
                return ro
        return result

    def register(self, manager):
        super(BackendInfo, self).register(manager)

        for (rt, rh) in [
             ("message-exec", self.message_exec),
             ("stop", self.stop)]:
            self._manager.reactor.call_on(rt, rh)

        # Backend should run as early as possible
        self._manager.reactor.call_on("gather", self.gather, -100)

    def get_command(self, *args):
        command = [self.command, "--path=%s" % os.environ["PATH"]]

        return command + list(args)

    def get_root_command(self, *args):
        uid = os.getuid()
        password_text = _("SYSTEM TESTING: Please enter your password. "
                          "Some tests require root access to run properly. "
                          "Your password will never be stored and will never "
                          "be submitted with test results.")
        password_prompt = _("PASSWORD: "******"which", "pkexec"],
                    stdout=PIPE, stderr=PIPE) == 0:
            prefix = ["pkexec"]
        #We fall back to good old sudo if pkexec is not present. Sudo
        #*should* be present in any Ubuntu installation.
        else:
            prefix = ["sudo", "-p", password_text + " " + password_prompt]

        return prefix + self.get_command(*args)

    def spawn_backend(self, input_fifo, output_fifo):
        self.pid = os.fork()
        if self.pid == 0:
            root_command = self.get_root_command(input_fifo, output_fifo)
            os.execvp(root_command[0], root_command)
            # Should never get here

    def ping_backend(self):
        if not self.parent_reader or not self.parent_writer:
            return False
        self.write_to_parent("ping")
        result = self.read_from_parent()
        return result == "pong"

    def gather(self):
        self.directory = mkdtemp(prefix="checkbox")
        child_input = create_fifo(os.path.join(self.directory, "input"),
                                  0o600)
        child_output = create_fifo(os.path.join(self.directory, "output"),
                                   0o600)

        self.backend_is_alive = False
        for attempt in range(1, 4):
            self.spawn_backend(child_input, child_output)
            #Only returns if I'm still the parent,
            #so I can do parent stuff here
            self.parent_writer = FifoWriter(child_input, timeout=self.timeout)
            self.parent_reader = FifoReader(child_output,
                                            timeout=self.timeout)
            if self.ping_backend():
                logging.debug("Backend responded, continuing execution.")
                self.backend_is_alive = True
                break
            else:
                logging.debug("Backend didn't respond, "
                              "trying to create again.")

        if not self.backend_is_alive:
            logging.warning("Privileged backend not responding. " +
                            "jobs specifying user will not be run")

    def message_exec(self, message):
        if "user" in message:
            if "environ" in message:
                #Prepare variables to be "exported" from my environment
                #to the backend's.
                backend_environ = ["%s=%s" % (key, os.environ[key])
                             for key in message["environ"]
                             if key in os.environ]
                message = dict(message)  # so as to not wreck the
                                         # original message
                message["environ"] = backend_environ

            if (self.backend_is_alive and not self.ping_backend()):
                self.backend_is_alive = False

            if self.backend_is_alive:
                self.write_to_parent(message)
                while True:
                    result = self.read_from_parent()
                    if result:
                        break
                    else:
                        logging.info("Waiting for result...")
            else:
                result = (FAIL, "Unable to test. Privileges are " +
                                "required for this job.", 0,)
            if result:
                self._manager.reactor.fire("message-result", *result)

    def stop(self):
        self.write_to_parent("stop")
        self.parent_writer.close()
        self.parent_reader.close()
        shutil.rmtree(self.directory)

        if self.backend_is_alive:
            os.waitpid(self.pid, 0)
Ejemplo n.º 5
0
class BackendInfo(Plugin):

    # how long to wait for I/O from/to the backend before the call returns.
    # How we behave if I/O times out is dependent on the situation.
    timeout = Float(default=60.0)

    command = Path(default="%(checkbox_share)s/backend")

    next_sequence = 0
    expected_sequence = 0

    def write_to_parent(self, object):
        message = (
            self.next_sequence,
            object,
        )
        logging.debug("Sending message with sequence number %s to backend" %
                      self.next_sequence)
        self.parent_writer.write_object(message)
        self.expected_sequence = self.next_sequence
        self.next_sequence += 1

    def read_from_parent(self):
        correct_sequence = False
        while not correct_sequence:
            ro = self.parent_reader.read_object()
            if ro:
                sequence, result = ro
                logging.debug("Expecting sequence number %s from backend, "
                              "got sequence number %s" %
                              (self.expected_sequence, sequence))
                if (self.expected_sequence == sequence):
                    correct_sequence = True
                else:
                    logging.warning("Backend sent wrong sequence number, "
                                    "Discarding message and re-reading")
            else:
                #If we timed out, just return nothing, the rest of
                #the code knows how to handle this.
                return ro
        return result

    def register(self, manager):
        super(BackendInfo, self).register(manager)

        for (rt, rh) in [("message-exec", self.message_exec),
                         ("stop", self.stop)]:
            self._manager.reactor.call_on(rt, rh)

        # Backend should run as early as possible
        self._manager.reactor.call_on("gather", self.gather, -100)

    def get_command(self, *args):
        command = [self.command, "--path=%s" % os.environ["PATH"]]

        return command + list(args)

    def get_root_command(self, *args):
        uid = os.getuid()
        password_text = _("SYSTEM TESTING: Please enter your password. "
                          "Some tests require root access to run properly. "
                          "Your password will never be stored and will never "
                          "be submitted with test results.")
        password_prompt = _("PASSWORD: "******"which", "pkexec"], stdout=PIPE, stderr=PIPE) == 0:
            prefix = ["pkexec"]
        #We fall back to good old sudo if pkexec is not present. Sudo
        #*should* be present in any Ubuntu installation.
        else:
            prefix = ["sudo", "-p", password_text + " " + password_prompt]

        return prefix + self.get_command(*args)

    def spawn_backend(self, input_fifo, output_fifo):
        self.pid = os.fork()
        if self.pid == 0:
            root_command = self.get_root_command(input_fifo, output_fifo)
            os.execvp(root_command[0], root_command)
            # Should never get here

    def ping_backend(self):
        if not self.parent_reader or not self.parent_writer:
            return False
        self.write_to_parent("ping")
        result = self.read_from_parent()
        return result == "pong"

    def gather(self):
        self.directory = mkdtemp(prefix="checkbox")
        child_input = create_fifo(os.path.join(self.directory, "input"), 0o600)
        child_output = create_fifo(os.path.join(self.directory, "output"),
                                   0o600)

        self.backend_is_alive = False
        for attempt in range(1, 4):
            self.spawn_backend(child_input, child_output)
            #Only returns if I'm still the parent,
            #so I can do parent stuff here
            self.parent_writer = FifoWriter(child_input, timeout=self.timeout)
            self.parent_reader = FifoReader(child_output, timeout=self.timeout)
            if self.ping_backend():
                logging.debug("Backend responded, continuing execution.")
                self.backend_is_alive = True
                break
            else:
                logging.debug("Backend didn't respond, "
                              "trying to create again.")

        if not self.backend_is_alive:
            logging.warning("Privileged backend not responding. " +
                            "jobs specifying user will not be run")

    def message_exec(self, message):
        if "user" in message:
            if "environ" in message:
                #Prepare variables to be "exported" from my environment
                #to the backend's.
                backend_environ = [
                    "%s=%s" % (key, os.environ[key])
                    for key in message["environ"] if key in os.environ
                ]
                message = dict(message)  # so as to not wreck the
                # original message
                message["environ"] = backend_environ

            if (self.backend_is_alive and not self.ping_backend()):
                self.backend_is_alive = False

            if self.backend_is_alive:
                self.write_to_parent(message)
                while True:
                    result = self.read_from_parent()
                    if result:
                        break
                    else:
                        logging.info("Waiting for result...")
            else:
                result = (
                    FAIL,
                    "Unable to test. Privileges are " +
                    "required for this job.",
                    0,
                )
            if result:
                self._manager.reactor.fire("message-result", *result)

    def stop(self):
        self.write_to_parent("stop")
        self.parent_writer.close()
        self.parent_reader.close()
        shutil.rmtree(self.directory)

        if self.backend_is_alive:
            os.waitpid(self.pid, 0)