From 4ec8fc5cc86c36dc162882eca7b84534f2a6534f Mon Sep 17 00:00:00 2001 From: Mike McLean Date: May 08 2024 18:10:18 +0000 Subject: [PATCH 1/2] handle volumes when clearing stray build dirs --- diff --git a/kojihub/kojihub.py b/kojihub/kojihub.py index d060484..024f047 100644 --- a/kojihub/kojihub.py +++ b/kojihub/kojihub.py @@ -6221,9 +6221,20 @@ def recycle_build(old, data): update.set(cg_id=data['cg_id']) update.rawset(create_event='get_event()') update.execute() - builddir = koji.pathinfo.build(data) - if os.path.exists(builddir): - koji.util.rmtree(builddir) + + # delete stray files + for check_vol in list_volumes(): + check_binfo = data.copy() + check_binfo['volume_id'] = check_vol['id'] + check_binfo['volume_name'] = check_vol['name'] + checkdir = koji.pathinfo.build(check_binfo) + if os.path.islink(checkdir): + logger.warning(f'Removing stray build symlink: {checkdir}') + os.unlink(checkdir) + elif os.path.exists(checkdir): + logger.warning(f'Removing stray build directory: {checkdir}') + koji.util.rmtree(checkdir) + buildinfo = get_build(data['id'], strict=True) koji.plugin.run_callbacks('postBuildStateChange', attribute='state', old=old['state'], new=data['state'], info=buildinfo) From c2c68ef2a0bd96723ebcf64daebeeac6e953e44a Mon Sep 17 00:00:00 2001 From: Mike McLean Date: May 08 2024 18:39:16 +0000 Subject: [PATCH 2/2] unit test --- diff --git a/tests/test_hub/test_recycle_build.py b/tests/test_hub/test_recycle_build.py index 24d3704..dcc5eb0 100644 --- a/tests/test_hub/test_recycle_build.py +++ b/tests/test_hub/test_recycle_build.py @@ -20,12 +20,16 @@ class TestRecycleBuild(unittest.TestCase): side_effect=self.getUpdate).start() self.run_callbacks = mock.patch('koji.plugin.run_callbacks').start() self.rmtree = mock.patch('koji.util.rmtree').start() - self.exists = mock.patch('os.path.exists').start() + self.unlink = mock.patch('os.unlink').start() + self.islink = mock.patch('os.path.islink', return_value=False).start() + self.exists = mock.patch('os.path.exists', return_value=False).start() self.updates = [] self.DeleteProcessor = mock.patch('kojihub.kojihub.DeleteProcessor', side_effect=self.getDelete).start() self.deletes = [] self.get_build = mock.patch('kojihub.kojihub.get_build').start() + self.list_volumes = mock.patch('kojihub.kojihub.list_volumes').start() + self.list_volumes.return_value = [{'id': 0, 'name': 'DEFAULT'}] def tearDown(self): mock.patch.stopall() @@ -276,3 +280,36 @@ class TestRecycleBuild(unittest.TestCase): self.get_build.assert_called_once_with(new['id'], strict=True) self.assertEqual(self.run_callbacks.call_count, 2) + + # our default data does not include stray files + self.rmtree.assert_not_called() + self.unlink.assert_not_called() + + def test_stray_link(self): + old = self.old.copy() + new = self.new.copy() + old['task_id'] = new['task_id'] = 137 + self.query_execute.side_effect = [[], [], []] + self.get_build.return_value = {'build_id': 2, 'name': 'GConf2', 'version': '3.2.6', + 'release': '15.fc23'} + + self.islink.return_value = True + kojihub.recycle_build(old, new) + self.rmtree.assert_not_called() + self.unlink.assert_called_once_with('/mnt/koji/packages/GConf2/3.2.6/15.fc23') + + def test_stray_dir(self): + old = self.old.copy() + new = self.new.copy() + old['task_id'] = new['task_id'] = 137 + self.query_execute.side_effect = [[], [], []] + self.get_build.return_value = {'build_id': 2, 'name': 'GConf2', 'version': '3.2.6', + 'release': '15.fc23'} + + self.exists.return_value = True + kojihub.recycle_build(old, new) + self.unlink.assert_not_called() + self.rmtree.assert_called_once_with('/mnt/koji/packages/GConf2/3.2.6/15.fc23') + + +# the end