コード例 #1
0
  def test_show_job_update_diff_with_task_diff(self):
    config = self.get_job_config()
    self._fake_context.get_job_config = Mock(return_value=config)
    formatter = DiffFormatter(self._fake_context, config)
    local_task = self.create_scheduled_tasks()[0].assignedTask.task
    self._mock_api.get_job_update_diff.return_value = self.get_job_update_diff_result()

    with contextlib.nested(
        patch('subprocess.call', return_value=0),
        patch('json.loads', return_value={})) as (subprocess_patch, _):

      formatter.show_job_update_diff(self._mock_options.instance_spec.instance, local_task)

      assert self._mock_api.get_job_update_diff.mock_calls == [
          call(config, self._mock_options.instance_spec.instance)
      ]
      assert "\n".join(self._fake_context.get_out()) == textwrap.dedent("""\
        This job update will:
        add instances: [10], [12-14]
        update instances: [11]
        with diff:\n\n
        not change instances: [0-9]""")
      assert subprocess_patch.call_count == 1
      assert subprocess_patch.call_args[0][0].startswith(
          os.environ.get('DIFF_VIEWER', 'diff') + ' ')
コード例 #2
0
ファイル: jobs.py プロジェクト: reneploetz/aurora
    def execute(self, context):
        config = context.get_job_config(context.options.instance_spec.jobkey, context.options.config_file)
        if context.options.rename_from is not None:
            cluster = context.options.rename_from.cluster
            role = context.options.rename_from.role
            env = context.options.rename_from.environment
            name = context.options.rename_from.name
        else:
            cluster = config.cluster()
            role = config.role()
            env = config.environment()
            name = config.name()
        api = context.get_api(cluster)

        resp = api.populate_job_config(config)
        context.log_response_and_raise(resp, err_code=EXIT_INVALID_CONFIGURATION, err_msg="Error loading configuration")
        local_task = resp.result.populateJobResult.taskConfig
        # Deepcopy is important here as tasks will be modified for printing.
        local_tasks = [deepcopy(local_task) for _ in range(config.instances())]
        instances = (
            None if context.options.instance_spec.instance == ALL_INSTANCES else context.options.instance_spec.instance
        )
        formatter = DiffFormatter(context, config, cluster, role, env, name)

        if config.raw().has_cron_schedule():
            formatter.diff_no_update_details(local_tasks)
        else:
            formatter.show_job_update_diff(instances, local_task)

        return EXIT_OK
コード例 #3
0
  def test_show_job_update_diff_with_task_diff(self):
    config = self.get_job_config()
    self._fake_context.get_job_config = Mock(return_value=config)
    formatter = DiffFormatter(self._fake_context, config)
    local_task = self.create_scheduled_tasks()[0].assignedTask.task
    local_task.constraints = set([Constraint(name='host'), Constraint(name='rack')])
    self._mock_api.get_job_update_diff.return_value = self.get_job_update_diff_result()

    formatter.show_job_update_diff(self._mock_options.instance_spec.instance, local_task)

    assert self._mock_api.get_job_update_diff.mock_calls == [
        call(config, self._mock_options.instance_spec.instance)
    ]
    assert "\n".join(self._fake_context.get_out()) == textwrap.dedent("""\
      This job update will:
      add instances: [10], [12-14]
      update instances: [11]
      with diff:\n
      2c2,3
      <   'constraints': None,
      ---
      >   'constraints': [ Constraint(name='host', constraint=None),
      >                    Constraint(name='rack', constraint=None)],
      \n
      not change instances: [0-9]""")
コード例 #4
0
    def test_show_job_update_diff_with_task_diff(self):
        config = self.get_job_config()
        self._fake_context.get_job_config = Mock(return_value=config)
        formatter = DiffFormatter(self._fake_context, config)
        local_task = self.create_scheduled_tasks()[0].assignedTask.task
        self._mock_api.get_job_update_diff.return_value = self.get_job_update_diff_result(
        )

        with contextlib.nested(patch('subprocess.call', return_value=0),
                               patch('json.loads',
                                     return_value={})) as (subprocess_patch,
                                                           _):

            formatter.show_job_update_diff(
                self._mock_options.instance_spec.instance, local_task)

            assert self._mock_api.get_job_update_diff.mock_calls == [
                call(config, self._mock_options.instance_spec.instance)
            ]
            assert "\n".join(
                self._fake_context.get_out()) == textwrap.dedent("""\
        This job update will:
        add instances: [10], [12-14]
        update instances: [11]
        with diff:\n\n
        not change instances: [0-9]""")
            assert subprocess_patch.call_count == 1
            assert subprocess_patch.call_args[0][0].startswith(
                os.environ.get('DIFF_VIEWER', 'diff') + ' ')
コード例 #5
0
ファイル: update.py プロジェクト: AltanAlpay/aurora
  def execute(self, context):
    job = context.options.instance_spec.jobkey
    instances = (None if context.options.instance_spec.instance == ALL_INSTANCES else
        context.options.instance_spec.instance)
    config = context.get_job_config(job, context.options.config_file)
    if config.raw().has_cron_schedule():
      raise context.CommandError(
          EXIT_COMMAND_FAILURE,
          "Cron jobs may only be updated with \"aurora cron schedule\" command")

    api = context.get_api(config.cluster())
    formatter = DiffFormatter(context, config)
    formatter.show_job_update_diff(instances)
    try:
      resp = api.start_job_update(config, context.options.message, instances)
    except AuroraClientAPI.UpdateConfigError as e:
      raise context.CommandError(EXIT_INVALID_CONFIGURATION, e.message)

    context.log_response_and_raise(resp, err_code=EXIT_API_ERROR,
        err_msg="Failed to start update due to error:")

    if resp.result:
      update_key = resp.result.startJobUpdateResult.key
      url = get_update_page(
        api,
        AuroraJobKey.from_thrift(config.cluster(), update_key.job),
        resp.result.startJobUpdateResult.key.id)
      context.print_out(self.UPDATE_MSG_TEMPLATE % url)

      if context.options.wait:
        return wait_for_update(context, self._clock, api, update_key)
    else:
      context.print_out(combine_messages(resp))

    return EXIT_OK
コード例 #6
0
  def test_diff_no_update_details_success(self):
    config = self.get_job_config(is_cron=True)
    self._fake_context.get_job_config = Mock(return_value=config)
    formatter = DiffFormatter(self._fake_context, config)
    self._mock_api.query.return_value = self.create_empty_task_result()
    query = TaskQuery(
      jobKeys=[self.TEST_JOBKEY.to_thrift()],
      statuses=ACTIVE_STATES)
    self._mock_api.build_query.return_value = query
    local_tasks = []

    formatter.diff_no_update_details(local_tasks)
コード例 #7
0
  def test_get_job_update_diff_error(self):
    mock_config = self.get_job_config()
    self._fake_context.get_job_config = Mock(return_value=mock_config)
    formatter = DiffFormatter(self._fake_context, mock_config)
    self._mock_api.get_job_update_diff.return_value = self.create_error_response()

    with pytest.raises(Context.CommandError):
      formatter.show_job_update_diff(self._mock_options.instance_spec.instance)

    assert self._mock_api.get_job_update_diff.mock_calls == [
      call(mock_config, self._mock_options.instance_spec.instance)
    ]
    assert self._fake_context.get_out() == []
    assert self._fake_context.get_err() == ["Error getting diff info from scheduler", "\tWhoops"]
コード例 #8
0
  def test_show_job_update_diff_no_change(self):
    config = self.get_job_config()
    self._fake_context.get_job_config = Mock(return_value=config)
    formatter = DiffFormatter(self._fake_context, config)
    self._mock_api.get_job_update_diff.return_value = self.get_job_update_no_change_diff_result()

    formatter.show_job_update_diff(self._mock_options.instance_spec.instance)

    assert self._mock_api.get_job_update_diff.mock_calls == [
        call(config, self._mock_options.instance_spec.instance)
    ]
    assert "\n".join(self._fake_context.get_out()) == textwrap.dedent("""\
      This job update will:
      not change instances: [0-3]""")
コード例 #9
0
  def test_get_job_update_diff_error(self):
    mock_config = self.get_job_config()
    self._fake_context.get_job_config = Mock(return_value=mock_config)
    formatter = DiffFormatter(self._fake_context, mock_config)
    self._mock_api.get_job_update_diff.return_value = self.create_error_response()

    with pytest.raises(Context.CommandError):
      formatter.show_job_update_diff(self._mock_options.instance_spec.instance)

    assert self._mock_api.get_job_update_diff.mock_calls == [
      call(mock_config, self._mock_options.instance_spec.instance)
    ]
    assert self._fake_context.get_out() == []
    assert self._fake_context.get_err() == ["Error getting diff info from scheduler", "\tWhoops"]
コード例 #10
0
  def test_show_job_update_diff_no_change(self):
    config = self.get_job_config()
    self._fake_context.get_job_config = Mock(return_value=config)
    formatter = DiffFormatter(self._fake_context, config)
    self._mock_api.get_job_update_diff.return_value = self.get_job_update_no_change_diff_result()

    formatter.show_job_update_diff(self._mock_options.instance_spec.instance)

    assert self._mock_api.get_job_update_diff.mock_calls == [
        call(config, self._mock_options.instance_spec.instance)
    ]
    assert "\n".join(self._fake_context.get_out()) == textwrap.dedent("""\
      This job update will:
      not change instances: [0-3]""")
コード例 #11
0
ファイル: update.py プロジェクト: Flaque/aurora-1
    def execute(self, context):
        job = context.options.instance_spec.jobkey
        instances = (None
                     if context.options.instance_spec.instance == ALL_INSTANCES
                     else context.options.instance_spec.instance)
        update_id = str(uuid.uuid4())
        config = context.get_job_config(job, context.options.config_file)
        if config.raw().has_cron_schedule():
            raise context.CommandError(
                EXIT_COMMAND_FAILURE,
                "Cron jobs may only be updated with \"aurora cron schedule\" command"
            )

        api = context.get_api(config.cluster())
        formatter = DiffFormatter(context, config)
        formatter.show_job_update_diff(instances)

        try:
            resp = api.start_job_update(config, context.options.message,
                                        instances,
                                        {CLIENT_UPDATE_ID: update_id})
        except AuroraClientAPI.UpdateConfigError as e:
            raise context.CommandError(EXIT_INVALID_CONFIGURATION, e.message)

        if not self._is_update_already_in_progress(resp, update_id):
            context.log_response_and_raise(
                resp,
                err_code=EXIT_API_ERROR,
                err_msg=self.FAILED_TO_START_UPDATE_ERROR_MSG)

        if resp.result:
            update_key = resp.result.startJobUpdateResult.key
            url = get_update_page(
                api, AuroraJobKey.from_thrift(config.cluster(),
                                              update_key.job),
                resp.result.startJobUpdateResult.key.id)
            context.print_out(self.UPDATE_MSG_TEMPLATE % url)

            if context.options.open_browser:
                webbrowser.open_new_tab(url)

            if context.options.wait:
                return wait_for_update(context, self._clock, api, update_key,
                                       update_state_to_err_code)
        else:
            context.print_out(combine_messages(resp))

        return EXIT_OK
コード例 #12
0
ファイル: update.py プロジェクト: ssalevan/aurora
  def execute(self, context):
    job = context.options.instance_spec.jobkey
    instances = (None if context.options.instance_spec.instance == ALL_INSTANCES else
        context.options.instance_spec.instance)
    update_id = str(uuid.uuid4())
    config = context.get_job_config(job, context.options.config_file)
    if config.raw().has_cron_schedule():
      raise context.CommandError(
          EXIT_COMMAND_FAILURE,
          "Cron jobs may only be updated with \"aurora cron schedule\" command")

    api = context.get_api(config.cluster())
    formatter = DiffFormatter(context, config)
    formatter.show_job_update_diff(instances)

    try:
      resp = api.start_job_update(config, context.options.message, instances,
          {CLIENT_UPDATE_ID: update_id})
    except AuroraClientAPI.UpdateConfigError as e:
      raise context.CommandError(EXIT_INVALID_CONFIGURATION, e.message)

    if not self._is_update_already_in_progress(resp, update_id):
      context.log_response_and_raise(resp, err_code=EXIT_API_ERROR,
          err_msg=self.FAILED_TO_START_UPDATE_ERROR_MSG)

    if resp.result:
      update_key = resp.result.startJobUpdateResult.key
      url = get_update_page(
        api,
        AuroraJobKey.from_thrift(config.cluster(), update_key.job),
        resp.result.startJobUpdateResult.key.id)
      context.print_out(self.UPDATE_MSG_TEMPLATE % url)

      if context.options.open_browser:
        webbrowser.open_new_tab(url)

      if context.options.wait:
        return wait_for_update(context, self._clock, api, update_key, update_state_to_err_code)
    else:
      context.print_out(combine_messages(resp))

    return EXIT_OK
コード例 #13
0
  def test_diff_no_update_details_success(self):
    config = self.get_job_config(is_cron=True)
    self._fake_context.get_job_config = Mock(return_value=config)
    formatter = DiffFormatter(self._fake_context, config)
    self._mock_api.query.return_value = self.create_empty_task_result()
    query = TaskQuery(
      jobKeys=[self.TEST_JOBKEY.to_thrift()],
      statuses=ACTIVE_STATES)
    self._mock_api.build_query.return_value = query
    local_tasks = []

    with contextlib.nested(
        patch('subprocess.call', return_value=0),
        patch('json.loads', return_value={})) as (subprocess_patch, _):

      formatter.diff_no_update_details(local_tasks)

      assert subprocess_patch.call_count == 1
      assert subprocess_patch.call_args[0][0].startswith(
          os.environ.get('DIFF_VIEWER', 'diff') + ' ')
コード例 #14
0
    def test_diff_no_update_details_success(self):
        config = self.get_job_config(is_cron=True)
        self._fake_context.get_job_config = Mock(return_value=config)
        formatter = DiffFormatter(self._fake_context, config)
        self._mock_api.query.return_value = self.create_empty_task_result()
        query = TaskQuery(jobKeys=[self.TEST_JOBKEY.to_thrift()],
                          statuses=ACTIVE_STATES)
        self._mock_api.build_query.return_value = query
        local_tasks = []

        with contextlib.nested(patch('subprocess.call', return_value=0),
                               patch('json.loads',
                                     return_value={})) as (subprocess_patch,
                                                           _):

            formatter.diff_no_update_details(local_tasks)

            assert subprocess_patch.call_count == 1
            assert subprocess_patch.call_args[0][0].startswith(
                os.environ.get('DIFF_VIEWER', 'diff') + ' ')
コード例 #15
0
    def execute(self, context):
        config = context.get_job_config(context.options.instance_spec.jobkey,
                                        context.options.config_file)
        if context.options.rename_from is not None:
            cluster = context.options.rename_from.cluster
            role = context.options.rename_from.role
            env = context.options.rename_from.environment
            name = context.options.rename_from.name
        else:
            cluster = config.cluster()
            role = config.role()
            env = config.environment()
            name = config.name()
        api = context.get_api(cluster)

        resp = api.populate_job_config(config)
        context.log_response_and_raise(resp,
                                       err_code=EXIT_INVALID_CONFIGURATION,
                                       err_msg="Error loading configuration")
        local_task = resp.result.populateJobResult.taskConfig
        # Deepcopy is important here as tasks will be modified for printing.
        local_tasks = [deepcopy(local_task) for _ in range(config.instances())]
        instances = (None
                     if context.options.instance_spec.instance == ALL_INSTANCES
                     else context.options.instance_spec.instance)
        formatter = DiffFormatter(context, config, cluster, role, env, name)

        if config.raw().has_cron_schedule():
            formatter.diff_no_update_details(local_tasks)
        else:
            formatter.show_job_update_diff(instances, local_task)

        return EXIT_OK
コード例 #16
0
    def execute(self, context):
        job = context.options.instance_spec.jobkey
        instances = (None
                     if context.options.instance_spec.instance == ALL_INSTANCES
                     else context.options.instance_spec.instance)
        config = context.get_job_config(job, context.options.config_file)
        if config.raw().has_cron_schedule():
            raise context.CommandError(
                EXIT_COMMAND_FAILURE,
                "Cron jobs may only be updated with \"aurora cron schedule\" command"
            )

        api = context.get_api(config.cluster())
        formatter = DiffFormatter(context, config)
        formatter.show_job_update_diff(instances)
        try:
            resp = api.start_job_update(config, context.options.message,
                                        instances)
        except AuroraClientAPI.UpdateConfigError as e:
            raise context.CommandError(EXIT_INVALID_CONFIGURATION, e.message)

        context.log_response_and_raise(
            resp,
            err_code=EXIT_API_ERROR,
            err_msg="Failed to start update due to error:")

        if resp.result:
            update_key = resp.result.startJobUpdateResult.key
            url = get_update_page(
                api, AuroraJobKey.from_thrift(config.cluster(),
                                              update_key.job),
                resp.result.startJobUpdateResult.key.id)
            context.print_out(self.UPDATE_MSG_TEMPLATE % url)

            if context.options.wait:
                return wait_for_update(context, self._clock, api, update_key)
        else:
            context.print_out(combine_messages(resp))

        return EXIT_OK