コード例 #1
0
    def test_fetch_attachment_failure(self, mock_fetch):
        """
        If the plugin fails to retrieve the attachments with a
        L{HTTPCodeError}, a specific error code is shown.
        """
        self.manager.config.url = "https://localhost/message-system"
        persist = Persist(
            filename=os.path.join(self.config.data_path, "broker.bpickle"))
        registration_persist = persist.root_at("registration")
        registration_persist.set("secure-id", "secure_id")
        persist.save()
        headers = {
            "User-Agent": "landscape-client/%s" % VERSION,
            "Content-Type": "application/octet-stream",
            "X-Computer-ID": "secure_id"
        }

        mock_fetch.return_value = fail(HTTPCodeError(404, "Not found"))

        self.manager.add(ScriptExecutionPlugin())
        result = self._send_script("/bin/sh",
                                   "echo hi",
                                   attachments={u"file1": 14})

        def got_result(ignored):
            self.assertMessages(
                self.broker_service.message_store.get_pending_messages(),
                [{
                    "type": "operation-result",
                    "operation-id": 123,
                    "result-text": "Server returned HTTP code 404",
                    "result-code": FETCH_ATTACHMENTS_FAILED_RESULT,
                    "status": FAILED
                }])
            mock_fetch.assert_called_with("https://localhost/attachment/14",
                                          headers=headers,
                                          cainfo=None)

        return result.addCallback(got_result)
コード例 #2
0
    def run_script(self,
                   shell,
                   code,
                   user=None,
                   time_limit=None,
                   attachments=None,
                   server_supplied_env=None):
        """
        Run a script based on a shell and the code.

        A file will be written with #!<shell> as the first line, as executable,
        and run as the given user.

        XXX: Handle the 'reboot' and 'killall landscape-client' commands
        gracefully.

        @param shell: The interpreter to use.
        @param code: The code to run.
        @param user: The username to run the process as.
        @param time_limit: The number of seconds to allow the process to run
            before killing it and failing the returned Deferred with a
            L{ProcessTimeLimitReachedError}.
        @param attachments: C{dict} of filename/data attached to the script.

        @return: A deferred that will fire with the data printed by the process
            or fail with a L{ProcessTimeLimitReachedError}.
        """
        if not os.path.exists(shell.split()[0]):
            return fail(UnknownInterpreterError(shell))

        uid, gid, path = get_user_info(user)

        fd, filename = tempfile.mkstemp()
        script_file = os.fdopen(fd, "wb")
        self.write_script_file(script_file, filename, shell, code, uid, gid)

        env = {
            "PATH": UBUNTU_PATH,
            "USER": user or "",
            "HOME": path or "",
        }
        for locale_var in ("LANG", "LC_ALL", "LC_CTYPE"):
            if locale_var in os.environ:
                env[locale_var] = os.environ[locale_var]
        if server_supplied_env:
            env.update(server_supplied_env)
        old_umask = os.umask(0o022)

        if attachments:
            persist = Persist(filename=os.path.join(
                self.registry.config.data_path, "broker.bpickle"))
            persist = persist.root_at("registration")
            computer_id = persist.get("secure-id")
            try:
                computer_id = computer_id.decode("ascii")
            except AttributeError:
                pass
            d = self._save_attachments(attachments, uid, gid, computer_id, env)
        else:
            d = succeed(None)

        def prepare_script(attachment_dir):

            return self._run_script(filename, uid, gid, path, env, time_limit)

        d.addCallback(prepare_script)
        return d.addBoth(self._cleanup, filename, env, old_umask)