Example #1
0
 def cancel_build(self, build_id):
     response = self.get_build(build_id)
     br = BuildResponse(response.json())
     br.cancelled = True
     url = self._build_url(OCP_BUILD_API_V1, "builds/%s/" % build_id)
     return self._put(url, data=json.dumps(br.json),
                      headers={"Content-Type": "application/json"})
Example #2
0
 def cancel_build(self, build_id):
     response = self.get_build(build_id)
     br = BuildResponse(response.json())
     br.status = BUILD_CANCELLED_STATE
     url = self._build_url("builds/%s/" % build_id)
     return self._put(url, data=json.dumps(br.json),
                      headers={"Content-Type": "application/json"})
Example #3
0
 def cancel_build(self, build_id, namespace=DEFAULT_NAMESPACE):
     response = self.get_build(build_id, namespace=namespace)
     br = BuildResponse(response)
     br.status = BUILD_CANCELLED_STATE
     url = self._build_url("namespaces/%s/builds/%s/" % (namespace, build_id))
     return self._put(url, data=json.dumps(br.json),
                      headers={"Content-Type": "application/json"})
Example #4
0
 def cancel_build(self, build_id):
     response = self.get_build(build_id)
     br = BuildResponse(response.json())
     br.status = BUILD_CANCELLED_STATE
     url = self._build_url("builds/%s/" % build_id)
     return self._put(url,
                      data=json.dumps(br.json),
                      headers={"Content-Type": "application/json"})
Example #5
0
 def _get_running_builds_for_build_config(self, build_config_id):
     all_builds_for_bc = self.os.list_builds(build_config_id=build_config_id).json()['items']
     running = []
     for b in all_builds_for_bc:
         br = BuildResponse(b)
         if br.is_pending() or br.is_running():
             running.append(br)
     return running
Example #6
0
 def _get_running_builds_for_build_config(self, build_config_id):
     all_builds_for_bc = self.os.list_builds(build_config_id=build_config_id).json()['items']
     running = []
     for b in all_builds_for_bc:
         br = BuildResponse(b)
         if br.is_pending() or br.is_running():
             running.append(br)
     return running
 def test_get_koji_build_id(self):
     koji_build_id = '123'
     build_response = BuildResponse({
         'metadata': {
             'labels': {
                 'koji-build-id': koji_build_id,
              },
         },
     })
     assert build_response.get_koji_build_id() == koji_build_id
Example #8
0
 def test_get_koji_build_id(self):
     koji_build_id = '123'
     build_response = BuildResponse({
         'metadata': {
             'labels': {
                 'koji-build-id': koji_build_id,
              },
         },
     })
     assert build_response.get_koji_build_id() == koji_build_id
Example #9
0
 def _get_running_builds_for_build_config(self, build_config_id, namespace=DEFAULT_NAMESPACE):
     all_builds_for_bc = self.os.list_builds(
         build_config_id=build_config_id,
         namespace=namespace).json()['items']
     running = []
     for b in all_builds_for_bc:
         br = BuildResponse(request=None, build_json=b)
         if br.is_pending() or br.is_running():
             running.append(br)
     return running
 def test_build_cancel(self):
     build_response = BuildResponse({'status': {'phase': 'Running'}})
     assert not build_response.cancelled
     build_response.cancelled = True
     assert build_response.cancelled
     assert 'cancelled' in build_response.json['status']
     assert build_response.json['status']['cancelled']
     build_response.cancelled = False
     assert not build_response.cancelled
     assert 'cancelled' in build_response.json['status']
     assert not build_response.json['status'].get('cancelled')
Example #11
0
    def _create_build_config_and_build(self, build_request):
        build = None

        build_json = build_request.render()
        api_version = build_json['apiVersion']
        if api_version != self.os_conf.get_openshift_api_version():
            raise OsbsValidationException(
                'BuildConfig template has incorrect apiVersion (%s)' %
                api_version)

        build_config_name = build_json['metadata']['name']
        logger.debug('build config to be named "%s"', build_config_name)
        existing_bc = self._get_existing_build_config(build_json)

        if existing_bc is not None:
            self._verify_labels_match(build_json, existing_bc)
            # Existing build config may have a different name if matched by
            # git-repo-name and git-branch labels. Continue using existing
            # build config name.
            build_config_name = existing_bc['metadata']['name']
            logger.debug('existing build config name to be used "%s"',
                         build_config_name)
            self._verify_no_running_builds(build_config_name)

            utils.buildconfig_update(existing_bc, build_json)
            # Reset name change that may have occurred during
            # update above, since renaming is not supported.
            existing_bc['metadata']['name'] = build_config_name
            logger.debug('build config for %s already exists, updating...',
                         build_config_name)
            self.os.update_build_config(build_config_name,
                                        json.dumps(existing_bc))

        else:
            # if it doesn't exist, then create it
            logger.debug('build config for %s doesn\'t exist, creating...',
                         build_config_name)
            bc = self.os.create_build_config(json.dumps(build_json)).json()
            # if there's an "ImageChangeTrigger" on the BuildConfig and "From" is of type
            #  "ImageStreamTag", the build will be scheduled automatically
            #  see https://github.com/projectatomic/osbs-client/issues/205
            if build_request.is_auto_instantiated():
                prev_version = bc['status']['lastVersion']
                build_id = self.os.wait_for_new_build_config_instance(
                    build_config_name, prev_version)
                build = BuildResponse(self.os.get_build(build_id).json())

        if build is None:
            response = self.os.start_build(build_config_name)
            build = BuildResponse(response.json())
        return build
Example #12
0
    def _create_build_config_and_build(self, build_request):
        # TODO: test this method more thoroughly
        build_json = build_request.render()
        api_version = build_json['apiVersion']
        if api_version != self.os_conf.get_openshift_api_version():
            raise OsbsValidationException("BuildConfig template has incorrect apiVersion (%s)" %
                                          api_version)

        build_config_name = build_json['metadata']['name']

        # check if a build already exists for this config; if so then raise
        running_builds = self._get_running_builds_for_build_config(build_config_name)
        rb_len = len(running_builds)
        if rb_len > 0:
            if rb_len == 1:
                rb = running_builds[0]
                msg = 'Build %s for %s in state %s, can\'t proceed.' % \
                    (rb.get_build_name(), build_config_name, rb.status)
            else:
                msg = self._panic_msg_for_more_running_builds(build_config_name, running_builds)
            raise OsbsException(msg)

        try:
            # see if there's already a build config
            existing_bc = self.os.get_build_config(build_config_name)
        except OsbsException:
            # doesn't exist
            existing_bc = None

        build = None
        if existing_bc is not None:
            utils.buildconfig_update(existing_bc, build_json)
            logger.debug('build config for %s already exists, updating...', build_config_name)
            self.os.update_build_config(build_config_name, json.dumps(existing_bc))
        else:
            # if it doesn't exist, then create it
            logger.debug('build config for %s doesn\'t exist, creating...', build_config_name)
            bc = self.os.create_build_config(json.dumps(build_json)).json()
            # if there's an "ImageChangeTrigger" on the BuildConfig and "From" is of type
            #  "ImageStreamTag", the build will be scheduled automatically
            #  see https://github.com/projectatomic/osbs-client/issues/205
            if build_request.is_auto_instantiated():
                prev_version = bc['status']['lastVersion']
                build_id = self.os.wait_for_new_build_config_instance(build_config_name,
                                                                      prev_version)
                build = BuildResponse(self.os.get_build(build_id).json())

        if build is None:
            response = self.os.start_build(build_config_name)
            build = BuildResponse(response.json())
        return build
Example #13
0
    def _create_build_config_and_build(self, build_request):
        build_json = build_request.render()
        api_version = build_json['apiVersion']
        if api_version != self.os_conf.get_openshift_api_version():
            raise OsbsValidationException('BuildConfig template has incorrect apiVersion (%s)' %
                                          api_version)

        build_config_name = build_json['metadata']['name']
        logger.debug('build config to be named "%s"', build_config_name)
        existing_bc = self._get_existing_build_config(build_json)

        image_stream, image_stream_tag_name = \
            self._get_image_stream_info_for_build_request(build_request)

        # Remove triggers in BuildConfig to avoid accidental
        # auto instance of Build. If defined, triggers will
        # be added to BuildConfig after ImageStreamTag object
        # is properly configured.
        triggers = build_json['spec'].pop('triggers', None)

        if existing_bc:
            build_config_name = existing_bc['metadata']['name']
            existing_bc = self._update_build_config_when_exist(build_json)

        else:
            logger.debug("build config for %s doesn't exist, creating...",
                         build_config_name)
            existing_bc = self.os.create_build_config(json.dumps(build_json)).json()

        if image_stream:
            changed_ist = self.ensure_image_stream_tag(image_stream,
                                                       image_stream_tag_name,
                                                       scheduled=True)
            logger.debug('Changed parent ImageStreamTag? %s', changed_ist)

        if triggers:
            existing_bc = self._update_build_config_with_triggers(build_json, triggers)

        if image_stream and triggers:
            prev_version = existing_bc['status']['lastVersion']
            build_id = self.os.wait_for_new_build_config_instance(
                build_config_name, prev_version)
            build = BuildResponse(self.os.get_build(build_id).json())
        else:
            response = self.os.start_build(build_config_name)
            build = BuildResponse(response.json())

        return build
Example #14
0
    def _create_build_directly(self, build_request, unique=None):
        logger.debug(build_request)
        build_json = build_request.render()
        build_json['kind'] = 'Build'
        build_json['spec']['serviceAccount'] = 'builder'

        builder_img = build_json['spec']['strategy']['customStrategy']['from']
        kind = builder_img['kind']
        if kind == 'ImageStreamTag':
            # Only BuildConfigs get to specify an ImageStreamTag. When
            # creating Builds directly we need to specify a
            # DockerImage.
            response = self.get_image_stream_tag(builder_img['name'])
            ref = response.json()['image']['dockerImageReference']
            builder_img['kind'] = 'DockerImage'
            builder_img['name'] = ref

        if unique:
            unique_labels = {}
            for u in unique:
                unique_labels[u] = build_json['metadata']['labels'][u]
            running_builds = self.list_builds(running=True, labels=unique_labels)
            if running_builds:
                raise RuntimeError('Matching build(s) already running: {0}'
                                   .format(', '.join(x.get_build_name() for x in running_builds)))

        return BuildResponse(self.os.create_build(build_json).json())
Example #15
0
def cmd_list_builds(args, osbs):
    kwargs = {}
    if args.running:
        kwargs['running'] = args.running

    if args.from_json:
        with open(args.from_json) as fp:
            builds = [BuildResponse(build) for build in json.load(fp)]
    else:
        builds = osbs.list_builds(**kwargs)

    if args.output == 'json':
        json_output = []
        for build in builds:
            json_output.append(build.json)
        print_json_nicely(json_output)
    elif args.output == 'text':
        if args.columns:
            cols_to_display = args.columns.split(",")
        else:
            cols_to_display = CLI_LIST_BUILDS_DEFAULT_COLS
        data = [{
            "base_image": "BASE IMAGE NAME",
            "base_image_id": "BASE IMAGE ID",
            "commit": "COMMIT",
            "image": "IMAGE NAME",
            "unique_image": "UNIQUE IMAGE NAME",
            "image_id": "IMAGE ID",
            "koji_build_id": "KOJI BUILD ID",
            "name": "BUILD ID",
            "status": "STATUS",
            "time_created": "TIME CREATED",
        }]
        for build in sorted(builds,
                            key=lambda x: x.get_time_created_in_seconds()):
            unique_image = build.get_image_tag()
            try:
                image = strip_registry_from_image(
                    build.get_repositories()["primary"][0])
            except (TypeError, KeyError, IndexError):
                image = ""  # "" or unique_image? failed builds don't have that ^
            if args.FILTER and args.FILTER not in image:
                continue
            if args.running and not build.is_in_progress():
                continue
            b = {
                "base_image": build.get_base_image_name() or '',
                "base_image_id": build.get_base_image_id() or '',
                "commit": build.get_commit_id(),
                "image": image,
                "unique_image": unique_image,
                "image_id": build.get_image_id() or '',
                "koji_build_id": build.get_koji_build_id() or '',
                "name": build.get_build_name(),
                "status": build.status,
                "time_created": build.get_time_created(),
            }
            data.append(b)
        tp = TablePrinter(data, cols_to_display)
        tp.render()
Example #16
0
 def test_error_message(self, plugin, message, expected_error_message):
     plugins_metadata = json.dumps({
         'errors': {
             plugin: message,
         },
     })
     if not plugin:
         plugins_metadata = ''
     build_response = BuildResponse({
         'metadata': {
             'annotations': {
                 'plugins-metadata': plugins_metadata
             }
         }
     })
     assert build_response.get_error_message() == expected_error_message
Example #17
0
    def _create_scratch_build(self, build_request):
        logger.debug(build_request)
        build_json = build_request.render()
        build_json['kind'] = 'Build'
        build_json['spec']['serviceAccount'] = 'builder'
        build_json['metadata']['labels']['scratch'] = 'true'

        if build_request.low_priority_node_selector:
            build_json['spec'][
                'nodeSelector'] = build_request.low_priority_node_selector

        builder_img = build_json['spec']['strategy']['customStrategy']['from']
        kind = builder_img['kind']
        if kind == 'ImageStreamTag':
            # Only BuildConfigs get to specify an ImageStreamTag. When
            # creating Builds directly we need to specify a
            # DockerImage.
            response = self.get_image_stream_tag(builder_img['name'])
            ref = response.json()['image']['dockerImageReference']
            builder_img['kind'] = 'DockerImage'
            builder_img['name'] = ref

        output_image_name = build_json['spec']['output']['to']['name']
        # Reuse random string and timestamp values.
        build_config_name = 'scratch-%s-%s' % tuple(
            output_image_name.rsplit('-', 2)[-2:])
        logger.debug('starting scratch build %s', build_config_name)
        build_json['metadata']['name'] = build_config_name
        return BuildResponse(self.os.create_build(build_json).json())
 def test_error_message(self, plugin, message, expected_error_message):
     plugins_metadata = json.dumps({
         'errors': {
             plugin: message,
         },
     })
     if not plugin:
         plugins_metadata = ''
     build_response = BuildResponse({
         'metadata': {
             'annotations': {
                 'plugins-metadata': plugins_metadata
             }
         }
     })
     assert build_response.get_error_message() == expected_error_message
 def test_build_cancel(self):
     build_response = BuildResponse({
         'status': {
             'phase': 'Running'
         }
     })
     assert not build_response.cancelled
     build_response.cancelled = True
     assert build_response.cancelled
     assert 'cancelled' in build_response.json['status']
     assert build_response.json['status']['cancelled']
     build_response.cancelled = False
     assert not build_response.cancelled
     assert 'cancelled' in build_response.json['status']
     assert not build_response.json['status'].get('cancelled')
     assert not build_response.is_cancelled()
Example #20
0
    def list_builds(self, field_selector=None, koji_task_id=None, running=None,
                    labels=None):
        """
        List builds with matching fields

        :param field_selector: str, field selector for Builds
        :param koji_task_id: str, only list builds for Koji Task ID
        :return: BuildResponse list
        """

        if running:
            running_fs = ",".join(["status!={status}".format(status=status.capitalize())
                                  for status in BUILD_FINISHED_STATES])
            if not field_selector:
                field_selector = running_fs
            else:
                field_selector = ','.join([field_selector, running_fs])
        response = self.os.list_builds(field_selector=field_selector,
                                       koji_task_id=koji_task_id, labels=labels)
        serialized_response = response.json()
        build_list = []
        for build in serialized_response["items"]:
            build_list.append(BuildResponse(build))

        return build_list
Example #21
0
    def _create_scratch_build(self, build_request):
        logger.debug(build_request)
        build_json = build_request.render()
        build_json['kind'] = 'Build'
        if 'spec' not in build_json.keys():
            build_json['spec'] = {}
        build_json['spec']['serviceAccount'] = 'builder'
        build_json['metadata']['labels']['scratch'] = 'true'

        if build_request.low_priority_node_selector:
            build_json['spec'][
                'nodeSelector'] = build_request.low_priority_node_selector

        builder_img = build_json['spec']['strategy']['customStrategy']['from']
        kind = builder_img['kind']
        if kind == 'ImageStreamTag':
            # Only BuildConfigs get to specify an ImageStreamTag. When
            # creating Builds directly we need to specify a
            # DockerImage.
            response = self.get_image_stream_tag(builder_img['name'])
            ref = response.json()['image']['dockerImageReference']
            builder_img['kind'] = 'DockerImage'
            builder_img['name'] = ref

        build_config_name = 'scratch-%s' % datetime.datetime.now().strftime(
            '%Y%m%d%H%M%S')
        logger.debug('starting scratch build %s', build_config_name)
        build_json['metadata']['name'] = build_config_name
        return BuildResponse(self.os.create_build(build_json).json())
Example #22
0
    def logs(self, build_id, follow=False, build_json=None, wait_if_missing=False,
             namespace=DEFAULT_NAMESPACE):
        """
        provide logs from build

        :param build_id: str
        :param follow: bool, fetch logs as they come?
        :param build_json: dict, to save one get-build query
        :param wait_if_missing: bool, if build doesn't exist, wait
        :param namespace: str
        :return: None, str or iterator
        """
        # does build exist?
        try:
            build_json = build_json or self.get_build(build_id, namespace=namespace).json()
        except OsbsResponseException as ex:
            if ex.status_code == 404:
                if not wait_if_missing:
                    raise OsbsException("Build '%s' doesn't exist." % build_id)
            else:
                raise

        if follow or wait_if_missing:
            build_json = self.wait_for_build_to_get_scheduled(build_id, namespace=namespace)

        br = BuildResponse(None, build_json=build_json)

        # When build is in new or pending state, openshift responds with 500
        if br.is_pending():
            return

        # 0.5+
        buildlogs_url = self._build_url("buildLogs/%s/" % build_id,
                                        follow=(1 if follow else 0),
                                        namespace=namespace)
        response = self._get(buildlogs_url, stream=follow, headers={'Connection': 'close'})
        if response.status_code in (403, 404):
            # 0.4.3
            # FIXME: remove this once 0.5.? is deployed everywhere
            buildlogs_url = self._build_url("proxy/buildLogs/%s/" % build_id,
                                            follow=(1 if follow else 0),
                                            namespace=namespace)
            response.close_multi()
            response = self._get(buildlogs_url, stream=follow, headers={'Connection': 'close'})
        if follow:
            return response.iter_lines()
        return response.content
Example #23
0
    def __init__(self, v1_image_id=None, unset_annotations=False):
        annotations = {'meta': 'test'}
        if v1_image_id:
            annotations['v1-image-id'] = v1_image_id
        if unset_annotations:
            annotations = None

        self.build = BuildResponse({'metadata': {'annotations': annotations}})
    def test_get_logs(self):
        msg = "This is an error message"
        error = json.dumps({
            'errorDetail': {
                'code': 1,
                'message': msg,
                'error': msg,
            },
        })
        build_response = BuildResponse({
            'metadata': {
                'annotations': {
                    'logs': error,
                },
            },
        })

        assert msg in build_response.get_logs()
Example #25
0
    def test_get_logs(self):
        msg = "This is an error message"
        error = json.dumps({
            'errorDetail': {
                'code': 1,
                'message': msg,
                'error': msg,
            },
        })
        build_response = BuildResponse({
            'metadata': {
                'annotations': {
                    'logs': error,
                },
            },
        })

        assert msg in build_response.get_logs()
Example #26
0
    def logs(self,
             build_id,
             follow=False,
             build_json=None,
             wait_if_missing=False):
        """
        provide logs from build

        :param build_id: str
        :param follow: bool, fetch logs as they come?
        :param build_json: dict, to save one get-build query
        :param wait_if_missing: bool, if build doesn't exist, wait
        :return: None, str or iterator
        """
        # does build exist?
        try:
            build_json = build_json or self.get_build(build_id).json()
        except OsbsResponseException as ex:
            if ex.status_code == 404:
                if not wait_if_missing:
                    raise OsbsException("Build '%s' doesn't exist." % build_id)
            else:
                raise

        if follow or wait_if_missing:
            build_json = self.wait_for_build_to_get_scheduled(build_id)

        br = BuildResponse(build_json)

        # When build is in new or pending state, openshift responds with 500
        if br.is_pending():
            return

        buildlogs_url = self._build_url("builds/%s/log/" % build_id,
                                        follow=(1 if follow else 0))
        response = self._get(buildlogs_url,
                             stream=follow,
                             headers={'Connection': 'close'})
        check_response(response)

        if follow:
            return response.iter_lines()
        return response.content
Example #27
0
    def get_build_logs(self, build_id, follow=False, namespace=DEFAULT_NAMESPACE):
        if follow:
            return self.os.logs(build_id, follow, namespace=namespace)
        try:
            build = self.os.get_build(build_id, namespace=namespace)
        except OsbsResponseException as ex:
            if ex.status_code != 404:
                raise
        else:
            build_response = BuildResponse(build)
            logs = None
            if build_response.is_finished():
                metadata = build_response.json.get("metadata", {})
                md = metadata.get("annotations", metadata.get("labels", {}))
                logs = md.get("logs", None)

            if logs:
                return logs

            return self.os.logs(build_id, follow=False, namespace=namespace)
    def test_error_message(self, osbs, pod, plugin, message,
                           expected_error_message):
        class MockOsbsPod:
            def __init__(self, error):
                self.error = error

            def get_pod_for_build(self, build_id):
                return self

            def get_failure_reason(self):
                if self.error:
                    return self.error
                raise OsbsException

        if pod or osbs:
            mock_pod = MockOsbsPod(pod)
        else:
            mock_pod = None
        if plugin:
            plugins_metadata = json.dumps({
                'errors': {
                    plugin: message,
                },
            })
            build = {
                'metadata': {
                    'annotations': {
                        'plugins-metadata': plugins_metadata,
                    },
                },
            }
        else:
            build = {
                'metadata': {
                    'annotations': {},
                },
            }

        build_response = BuildResponse(build, mock_pod)

        assert build_response.get_error_message() == expected_error_message
Example #29
0
    def get_docker_build_logs(self, build_id, decode_logs=True, build_json=None):
        """
        get logs provided by "docker build"

        :param build_id: str
        :param decode_logs: bool, docker by default output logs in simple json structure:
            { "stream": "line" }
            if this arg is set to True, it decodes logs to human readable form
        :param build_json: dict, to save one get-build query
        :return: str
        """
        if not build_json:
            build = self.os.get_build(build_id)
            build_response = BuildResponse(build.json())
        else:
            build_response = BuildResponse(build_json)

        if build_response.is_finished():
            logs = build_response.get_logs(decode_logs=decode_logs)
            return logs
        logger.warning("build haven't finished yet")
Example #30
0
    def create_build_from_buildrequest(self, build_request):
        """
        render provided build_request and submit build from it

        :param build_request: instance of build.build_request.BuildRequest
        :return: instance of build.build_response.BuildResponse
        """
        build_request.set_openshift_required_version(self.os_conf.get_openshift_required_version())
        build = build_request.render()
        response = self.os.create_build(json.dumps(build))
        build_response = BuildResponse(response.json())
        return build_response
Example #31
0
def make_build_response(name, status, annotations=None, labels=None):
    build_response = {
        'metadata': {
            'name': name,
            'annotations': annotations or {},
            'labels': labels or {},
        },
        'status': {
            'phase': status
        }
    }

    return BuildResponse(build_response)
Example #32
0
 def _create_scratch_build(self, build_request):
     logger.debug(build_request)
     build_json = build_request.render()
     build_json['kind'] = 'Build'
     if 'spec' not in build_json.keys():
         build_json['spec'] = {}
     build_json['spec']['serviceAccount'] = 'builder'
     build_json['metadata']['labels']['scratch'] = 'true'
     build_config_name = 'scratch-%s' % datetime.datetime.now().strftime(
         '%Y%m%d%H%M%S')
     logger.debug('starting scratch build %s', build_config_name)
     build_json['metadata']['name'] = build_config_name
     return BuildResponse(self.os.create_build(build_json).json())
Example #33
0
    def list_builds(self, field_selector=None):
        """
        List builds with matching fields

        :param field_selector: str, field selector for Builds
        :return: BuildResponse list
        """

        response = self.os.list_builds(field_selector=field_selector)
        serialized_response = response.json()
        build_list = []
        for build in serialized_response["items"]:
            build_list.append(BuildResponse(build))
        return build_list
Example #34
0
    def logs(self, build_id, follow=False, build_json=None, wait_if_missing=False):
        """
        provide logs from build

        :param build_id: str
        :param follow: bool, fetch logs as they come?
        :param build_json: dict, to save one get-build query
        :param wait_if_missing: bool, if build doesn't exist, wait
        :return: None, str or iterator
        """
        # does build exist?
        try:
            build_json = build_json or self.get_build(build_id).json()
        except OsbsResponseException as ex:
            if ex.status_code == 404:
                if not wait_if_missing:
                    raise OsbsException("Build '%s' doesn't exist." % build_id)
            else:
                raise

        if follow or wait_if_missing:
            build_json = self.wait_for_build_to_get_scheduled(build_id)

        br = BuildResponse(build_json)

        # When build is in new or pending state, openshift responds with 500
        if br.is_pending():
            return

        buildlogs_url = self._build_url("builds/%s/log/" % build_id,
                                        follow=(1 if follow else 0))
        response = self._get(buildlogs_url, stream=follow, headers={'Connection': 'close'})
        check_response(response)

        if follow:
            return response.iter_lines()
        return response.content
Example #35
0
    def list_builds(self, field_selector=None, koji_task_id=None):
        """
        List builds with matching fields

        :param field_selector: str, field selector for Builds
        :param koji_task_id: str, only list builds for Koji Task ID
        :return: BuildResponse list
        """

        response = self.os.list_builds(field_selector=field_selector,
                                       koji_task_id=koji_task_id)
        serialized_response = response.json()
        build_list = []
        for build in serialized_response["items"]:
            build_list.append(BuildResponse(build))
        return build_list
Example #36
0
    def _create_scratch_build(self, build_request):
        logger.debug(build_request)
        build_json = build_request.render()
        build_json['kind'] = 'Build'
        build_json['spec']['serviceAccount'] = 'builder'
        build_json['metadata']['labels']['scratch'] = 'true'

        builder_img = build_json['spec']['strategy']['customStrategy']['from']
        kind = builder_img['kind']
        if kind == 'ImageStreamTag':
            # Only BuildConfigs get to specify an ImageStreamTag. When
            # creating Builds directly we need to specify a
            # DockerImage.
            response = self.get_image_stream_tag(builder_img['name'])
            ref = response.json()['image']['dockerImageReference']
            builder_img['kind'] = 'DockerImage'
            builder_img['name'] = ref

        return BuildResponse(self.os.create_build(build_json).json())
Example #37
0
    def get_docker_build_logs(self, build_id, decode_logs=True, build_json=None):
        """
        get logs provided by "docker build"

        :param build_id: str
        :param decode_logs: bool, docker by default output logs in simple json structure:
            { "stream": "line" }
            if this arg is set to True, it decodes logs to human readable form
        :param build_json: dict, to save one get-build query
        :return: str
        """
        if not build_json:
            build = self.os.get_build(build_id)
            build_response = BuildResponse(build.json())
        else:
            build_response = BuildResponse(build_json)

        if build_response.is_finished():
            logs = build_response.get_logs(decode_logs=decode_logs)
            return logs
        logger.warning("build haven't finished yet")
    def test_state_checkers(self):
        build_response = BuildResponse({
            'status': {
                'phase': 'Complete'
            }
        })

        build_response.status = 'complete'
        assert build_response.is_finished()
        assert build_response.is_succeeded()
        assert not build_response.is_failed()
        assert not build_response.is_cancelled()
        assert not build_response.is_running()
        assert not build_response.is_pending()
        assert not build_response.is_in_progress()

        build_response.status = 'failed'
        assert build_response.is_failed()
        assert build_response.is_finished()
        assert not build_response.is_succeeded()
        assert not build_response.is_cancelled()
        assert not build_response.is_running()
        assert not build_response.is_pending()
        assert not build_response.is_in_progress()

        build_response.status = 'cancelled'
        assert build_response.is_cancelled()
        assert build_response.is_failed()
        assert build_response.is_finished()
        assert not build_response.is_succeeded()
        assert not build_response.is_running()
        assert not build_response.is_pending()
        assert not build_response.is_in_progress()

        build_response.status = 'running'
        assert build_response.is_running()
        assert build_response.is_in_progress()
        assert not build_response.is_cancelled()
        assert not build_response.is_failed()
        assert not build_response.is_finished()
        assert not build_response.is_succeeded()
        assert not build_response.is_pending()

        build_response.status = 'pending'
        assert build_response.is_pending()
        assert build_response.is_in_progress()
        assert not build_response.is_running()
        assert not build_response.is_cancelled()
        assert not build_response.is_failed()
        assert not build_response.is_finished()
        assert not build_response.is_succeeded()
Example #39
0
 def wait_for_build_to_get_scheduled(self, build_id):
     response = self.os.wait_for_build_to_get_scheduled(build_id)
     build_response = BuildResponse(response)
     return build_response
Example #40
0
 def wait_for_build_to_finish(self, build_id):
     response = self.os.wait_for_build_to_finish(build_id)
     build_response = BuildResponse(response)
     return build_response
Example #41
0
 def cancel_build(self, build_id):
     response = self.os.cancel_build(build_id)
     build_response = BuildResponse(response.json())
     return build_response
Example #42
0
 def get_build(self, build_id):
     response = self.os.get_build(build_id)
     build_response = BuildResponse(response.json())
     return build_response
Example #43
0
    def _create_build_config_and_build(self, build_request):
        build_json = build_request.render()
        api_version = build_json['apiVersion']
        if api_version != self.os_conf.get_openshift_api_version():
            raise OsbsValidationException(
                'BuildConfig template has incorrect apiVersion (%s)' %
                api_version)

        build_config_name = build_json['metadata']['name']
        logger.debug('build config to be named "%s"', build_config_name)
        existing_bc = self._get_existing_build_config(build_json)

        image_stream, image_stream_tag_name = \
            self._get_image_stream_info_for_build_request(build_request)

        # Remove triggers in BuildConfig to avoid accidental
        # auto instance of Build. If defined, triggers will
        # be added to BuildConfig after ImageStreamTag object
        # is properly configured.
        triggers = build_json['spec'].pop('triggers', None)

        if existing_bc:
            self._verify_labels_match(build_json, existing_bc)
            # Existing build config may have a different name if matched by
            # git-repo-name and git-branch labels. Continue using existing
            # build config name.
            build_config_name = existing_bc['metadata']['name']
            logger.debug('existing build config name to be used "%s"',
                         build_config_name)
            self._verify_no_running_builds(build_config_name)

            utils.buildconfig_update(existing_bc, build_json)
            # Reset name change that may have occurred during
            # update above, since renaming is not supported.
            existing_bc['metadata']['name'] = build_config_name
            logger.debug('build config for %s already exists, updating...',
                         build_config_name)

            self.os.update_build_config(build_config_name,
                                        json.dumps(existing_bc))
            if triggers:
                # Retrieve updated version to pick up lastVersion
                existing_bc = self._get_existing_build_config(existing_bc)

        else:
            logger.debug('build config for %s doesn\'t exist, creating...',
                         build_config_name)
            existing_bc = self.os.create_build_config(
                json.dumps(build_json)).json()

        if image_stream:
            changed_ist = self.ensure_image_stream_tag(image_stream,
                                                       image_stream_tag_name,
                                                       scheduled=True)
            logger.debug('Changed parent ImageStreamTag? %s', changed_ist)

        if triggers:
            existing_bc['spec']['triggers'] = triggers
            self.os.update_build_config(build_config_name,
                                        json.dumps(existing_bc))

        if image_stream and triggers:
            prev_version = existing_bc['status']['lastVersion']
            build_id = self.os.wait_for_new_build_config_instance(
                build_config_name, prev_version)
            build = BuildResponse(self.os.get_build(build_id).json())
        else:
            response = self.os.start_build(build_config_name)
            build = BuildResponse(response.json())

        return build