From f309c7f763e724767f9832b1b52c81e303e7e6a8 Mon Sep 17 00:00:00 2001 From: Jiri Prokes Date: Wed, 26 Jul 2017 14:50:49 -0700 Subject: [PATCH] Fix for git clone issue during kolla image build When the first build attempt fail for any reason (e.g. short network outage, proxy outage,...) then the second attempt always fail for git source type. Git can't clone repository because destination directory exists and is not empty. Current fix checks destination directory and if it exists then it is removed before cloning. Change-Id: I949140c49a64baea579d61047e3b2f1240da2771 Closes-Bug: #1706369 --- kolla/image/build.py | 5 +++++ kolla/tests/test_build.py | 22 ++++++++++++++++++++++ 2 files changed, 27 insertions(+) diff --git a/kolla/image/build.py b/kolla/image/build.py index 8cbefad184..062a0096e3 100755 --- a/kolla/image/build.py +++ b/kolla/image/build.py @@ -309,6 +309,11 @@ class BuildTask(DockerTask): elif source.get('type') == 'git': clone_dir = '{}-{}'.format(dest_archive, source['reference'].replace('/', '-')) + if os.path.exists(clone_dir): + self.logger.info("Clone dir %s exists. Removing it.", + clone_dir) + shutil.rmtree(clone_dir) + try: self.logger.debug("Cloning from %s", source['source']) git.Git().clone(source['source'], clone_dir) diff --git a/kolla/tests/test_build.py b/kolla/tests/test_build.py index 40722b779f..b7aa0c29e8 100644 --- a/kolla/tests/test_build.py +++ b/kolla/tests/test_build.py @@ -192,6 +192,28 @@ class TasksTest(base.TestCase): else: self.assertIsNotNone(get_result) + @mock.patch('os.path.exists') + @mock.patch('os.utime') + @mock.patch('shutil.rmtree') + def test_process_git_source_existing_dir(self, mock_rmtree, mock_utime, + mock_path_exists): + source = {'source': 'http://fake/source1', 'type': 'git', + 'name': 'fake-image1', + 'reference': 'fake/reference1'} + + self.image.source = source + self.image.path = "fake_image_path" + mock_path_exists.return_value = True + push_queue = mock.Mock() + builder = build.BuildTask(self.conf, self.image, push_queue) + get_result = builder.process_source(self.image, self.image.source) + + mock_rmtree.assert_called_with( + "fake_image_path/fake-image1-archive-fake-reference1") + self.assertEqual(self.image.status, build.STATUS_ERROR) + self.assertFalse(builder.success) + self.assertIsNone(get_result) + @mock.patch('docker.APIClient') def test_followups_docker_image(self, mock_client): self.imageChild.source = {