Example #1
0
    def serve_build(self):
        """This is the main function of the ``DeployAgent``.
        """
        log.info('The deploy agent is starting.')
        if not self._executor:
            self._executor = Executor(callback=PingServer(self),
                                      config=self._config)

        # start to ping server to get the latest deploy goal
        response = self._client.send_reports(self._envs)

        self._response = response
        if self._response:
            report = self._update_internal_deploy_goal(self._response)
            # failed to update
            if report.status_code != AgentStatus.SUCCEEDED:
                self._update_ping_reports(deploy_report=report)
                self._client.send_reports(self._envs)
                return

        while self._response and self._response.opCode and self._response.opCode != OpCode.NOOP:
            try:
                # update the current deploy goal
                if self._response.deployGoal:
                    deploy_report = self.process_deploy(self._response)
                else:
                    log.info('No new deploy goal to get updated')
                    deploy_report = DeployReport(AgentStatus.SUCCEEDED)

                if deploy_report.status_code == AgentStatus.ABORTED_BY_SERVER:
                    log.info('switch to the new deploy goal: {}'.format(
                        self._response.deployGoal))
                    continue

            except Exception:
                # anything catch-up here should be treated as agent failure
                deploy_report = DeployReport(
                    status_code=AgentStatus.AGENT_FAILED,
                    error_code=1,
                    output_msg=traceback.format_exc(),
                    retry_times=1)

            self.update_deploy_status(deploy_report)
            if deploy_report.status_code in [
                    AgentStatus.AGENT_FAILED, AgentStatus.TOO_MANY_RETRY,
                    AgentStatus.SCRIPT_TIMEOUT
            ]:
                log.error('Unexpeted exceptions: {}, error message {}'.format(
                    deploy_report.status_code, deploy_report.output_msg))
                return

        self.clean_stale_builds()
        if self._response and self._response.deployGoal:
            self._update_internal_deploy_goal(self._response)

        if self._response:
            log.info('Complete the current deploy with response: {}.'.format(
                self._response))
        else:
            log.info('Failed to get response from server, exit.')
Example #2
0
 def test_run_command_with_timeout(self):
     cmd = ['ls', '-ltr', '/abc']
     ping_server = mock.Mock(return_value=True)
     executor = Executor(callback=ping_server)
     executor.LOG_FILENAME = self.fdout_fn
     executor.MAX_RUNNING_TIME = 4
     executor.MIN_RUNNING_TIME = 2
     executor.DEFAULT_TAIL_LINES = 1
     executor.MAX_RETRY = 3
     executor.PROCESS_POLL_INTERVAL = 2
     executor.MAX_TAIL_BYTES = 10240
     deploy_report = executor.run_cmd(cmd=cmd)
     self.assertEqual(deploy_report.status_code,
                      AgentStatus.ABORTED_BY_SERVER)
Example #3
0
 def test_run_command_with_timeout_error(self):
     cmd = ['sleep', '20']
     ping_server = mock.Mock(return_value=False)
     executor = Executor(callback=ping_server)
     executor.LOG_FILENAME = self.fdout_fn
     executor.MAX_RUNNING_TIME = 4
     executor.MIN_RUNNING_TIME = 2
     executor.DEFAULT_TAIL_LINES = 1
     executor.MAX_RETRY = 3
     executor.PROCESS_POLL_INTERVAL = 2
     executor.BACK_OFF = 2
     executor.MAX_SLEEP_INTERVAL = 60
     executor.MAX_TAIL_BYTES = 10240
     deploy_report = executor.run_cmd(cmd=cmd)
     self.assertTrue(ping_server.called)
     self.assertEqual(deploy_report.status_code, AgentStatus.SCRIPT_TIMEOUT)
Example #4
0
 def test_run_command_with_max_retry(self):
     cmd = ['ls', '-ltr', '/abc']
     ping_server = mock.Mock(return_value=False)
     executor = Executor(callback=ping_server)
     executor.LOG_FILENAME = self.fdout_fn
     executor.MAX_RUNNING_TIME = 5
     executor.MIN_RUNNING_TIME = 2
     executor.MAX_RETRY = 3
     executor.DEFAULT_TAIL_LINES = 1
     executor.PROCESS_POLL_INTERVAL = 2
     executor.BACK_OFF = 2
     executor.MAX_SLEEP_INTERVAL = 60
     executor.MAX_TAIL_BYTES = 10240
     deploy_report = executor.run_cmd(cmd=cmd)
     self.assertEqual(deploy_report.status_code, AgentStatus.TOO_MANY_RETRY)
     # in ubuntu: error message is 'ls: cannot access /abc: No such file or directory'
     # in mac osx: error message is 'ls: /abc: No such file or directory'
     self.assertEqual(deploy_report.retry_times, 3)
Example #5
0
    def test_run_bad_script(self):
        fdout_fn = tempfile.mkstemp()[1]
        with open(fdout_fn, 'w') as f:
            f.write('echo hello')
        os.chmod(fdout_fn, 0755)

        ping_server = mock.Mock(return_value=True)
        executor = Executor(callback=ping_server)
        executor.LOG_FILENAME = self.fdout_fn
        executor.MAX_RUNNING_TIME = 4
        executor.MIN_RUNNING_TIME = 2
        executor.DEFAULT_TAIL_LINES = 1
        executor.PROCESS_POLL_INTERVAL = 2
        executor.MAX_RETRY = 3
        deploy_report = executor.run_cmd(cmd=fdout_fn)
        self.assertTrue(ping_server.called)
        self.assertEqual(deploy_report.status_code,
                         AgentStatus.ABORTED_BY_SERVER)
        os.remove(fdout_fn)
Example #6
0
 def setUpClass(cls):
     cls.fdout, cls.fdout_fn = tempfile.mkstemp()
     cls.pingServer = mock.Mock()
     cls.pingServer.__call__ = mock.Mock(return_value=False)
     cls.executor = Executor(callback=cls.pingServer)
     cls.executor.LOG_FILENAME = cls.fdout_fn