From 2d73e083f47c98cea58043ce926cb0075d12520a Mon Sep 17 00:00:00 2001 From: sarah256 Date: Feb 24 2020 16:03:49 +0000 Subject: Populate builds list with reused builds --- diff --git a/freshmaker/logger.py b/freshmaker/logger.py index 570d7ab..3b5d113 100644 --- a/freshmaker/logger.py +++ b/freshmaker/logger.py @@ -88,7 +88,7 @@ def init_logging(conf): log = logging.getLogger() log.propagate = False - log.addHandler(journal.JournalHandler()) + log.addHandler(journal.JournaldLogHandler()) else: logging.basicConfig(filename=conf.log_file, level=conf.log_level, format=log_format) diff --git a/freshmaker/migrations/alembic.ini b/freshmaker/migrations/alembic.ini index f8ed480..d676023 100644 --- a/freshmaker/migrations/alembic.ini +++ b/freshmaker/migrations/alembic.ini @@ -1,6 +1,7 @@ # A generic, single database configuration. [alembic] +script_location = migrations # template used to generate migration files # file_template = %%(rev)s_%%(slug)s diff --git a/freshmaker/migrations/versions/9df9f02e6903_.py b/freshmaker/migrations/versions/9df9f02e6903_.py new file mode 100644 index 0000000..709b56d --- /dev/null +++ b/freshmaker/migrations/versions/9df9f02e6903_.py @@ -0,0 +1,26 @@ +"""Add where reused builds are reused from + +Revision ID: 9df9f02e6903 +Revises: 2358b6f55f24 +Create Date: 2020-02-03 13:48:45.665684 + +""" + +# revision identifiers, used by Alembic. +revision = '9df9f02e6903' +down_revision = '2358b6f55f24' + +from alembic import op +import sqlalchemy as sa + + +def upgrade(): + # ### commands auto generated by Alembic - please adjust! ### + op.add_column('artifact_builds', sa.Column('reused_from', sa.Integer(), nullable=True)) + # ### end Alembic commands ### + + +def downgrade(): + # ### commands auto generated by Alembic - please adjust! ### + op.drop_column('artifact_builds', 'reused_from') + # ### end Alembic commands ### diff --git a/freshmaker/models.py b/freshmaker/models.py index e143b73..3a4adf6 100644 --- a/freshmaker/models.py +++ b/freshmaker/models.py @@ -532,11 +532,15 @@ class ArtifactBuild(FreshmakerBase): composes = db.relationship('ArtifactBuildCompose', back_populates='build') + # If a build has been reused, this will be the ID of the event that it came + # from. If the build has not been reused, this will be None + reused_from = db.Column(db.Integer, nullable=True) + @classmethod def create(cls, session, event, name, type, build_id=None, dep_on=None, state=None, original_nvr=None, rebuilt_nvr=None, - rebuild_reason=0): + rebuild_reason=0, reused_from=None): now = datetime.utcnow() build = cls( @@ -549,7 +553,8 @@ class ArtifactBuild(FreshmakerBase): build_id=build_id, time_submitted=now, dep_on=dep_on, - rebuild_reason=rebuild_reason + rebuild_reason=rebuild_reason, + reused_from=reused_from, ) session.add(build) return build @@ -671,7 +676,8 @@ class ArtifactBuild(FreshmakerBase): "url": build_url, "build_args": build_args, "odcs_composes": [rel.compose.odcs_compose_id for rel in self.composes], - "rebuild_reason": RebuildReason(self.rebuild_reason or 0).name.lower() + "rebuild_reason": RebuildReason(self.rebuild_reason or 0).name.lower(), + "reused_from": self.reused_from, } def get_root_dep_on(self): diff --git a/freshmaker/views.py b/freshmaker/views.py index 7dafffc..ee4c821 100644 --- a/freshmaker/views.py +++ b/freshmaker/views.py @@ -519,7 +519,32 @@ class BuildAPI(MethodView): # event based on the data. Currently it generates just # ManualRebuildWithAdvisoryEvent. parser = FreshmakerManualRebuildParser() - db_event = _create_rebuild_event_from_request(db.session, parser, request) + event = parser.parse_post_data(data) + + # Store the event into database, so it gets the ID which we can return + # to client sending this POST request. The client can then use the ID + # to check for the event status. + db_event = models.Event.get_or_create_from_event(db.session, event) + if db_event: + db_event.requester = g.user.username + db_event.requested_rebuilds = " ".join(event.container_images) + + # We need to check for successful builds, because if they are successful + # then they can be reused. + if dependent_event and dependent_event.builds: + for build in dependent_event.builds: + if build.state == 1: + build.reused_from = dependent_event.id + db_event.builds.append(build) + + if event.requester_metadata_json: + db_event.requester_metadata = json.dumps(event.requester_metadata_json) + if dependent_event: + dependency = db_event.add_event_dependency(db.session, dependent_event) + if not dependency: + log.warn('Dependency between {} and {} could not be added!'.format( + event.freshmaker_event_id, dependent_event.id)) + db.session.commit() # Forward the POST data (including the msg_id of the database event we # added to DB) to backend using UMB messaging. Backend will then diff --git a/tests/test_views.py b/tests/test_views.py index 9b59d8a..2fdea61 100644 --- a/tests/test_views.py +++ b/tests/test_views.py @@ -785,6 +785,40 @@ class TestManualTriggerRebuild(ViewBaseTest): 'from_advisory_id') @patch('freshmaker.parsers.internal.manual_rebuild.time.time') @patch('freshmaker.models.Event.add_event_dependency') + def test_dependent_manual_rebuild_on_existing_event_with_builds(self, add_dependency, time, + from_advisory_id, publish): + event = models.Event.create(db.session, + "2017-00000000-0000-0000-0000-000000000003", + "105", events.TestingEvent) + build = models.ArtifactBuild.create(db.session, name='test-build', state=1, event=event, type=1) + event.builds.append(build) + db.session.commit() + time.return_value = 123 + from_advisory_id.return_value = ErrataAdvisory( + 105, 'name', 'RHEL_PREP', ['rpm']) + + payload = { + 'errata_id': 105, + 'container_images': ['foo-1-2'], + 'freshmaker_event_id': 1, + } + with self.test_request_context(user='root'): + resp = self.client.post('/api/1/builds/', json=payload, content_type='application/json') + data = resp.json + # Other fields are predictible. + self.assertEqual(data['requested_rebuilds'], ["foo-1-2"]) + assert add_dependency.call_count == 1 + assert "105" == add_dependency.call_args[0][1].search_key + publish.assert_called_once_with( + 'manual.rebuild', + {'msg_id': 'manual_rebuild_123', u'errata_id': 105, + 'container_images': ["foo-1-2"], 'freshmaker_event_id': 1}) + + @patch('freshmaker.messaging.publish') + @patch('freshmaker.parsers.internal.manual_rebuild.ErrataAdvisory.' + 'from_advisory_id') + @patch('freshmaker.parsers.internal.manual_rebuild.time.time') + @patch('freshmaker.models.Event.add_event_dependency') def test_dependent_manual_rebuild_on_existing_event_no_errata_id( self, add_dependency, time, from_advisory_id, publish, ):