Exclude shared directories when creating environments

If we try to create a new environment from a shared configuration inside
the same repository, we can produce an infinite loop by copying the
environment into itself. Ignore any existing environments directory
during environment creation.

Change-Id: Ic9d3d03192f515a055e41351a0bf25da7a7b0684
Story: 2002009
Task: 40038
This commit is contained in:
Pierre Riteau 2021-04-09 17:47:12 +02:00
parent 4ad010a5a6
commit b78218adc6
4 changed files with 29 additions and 14 deletions

View File

@ -261,5 +261,6 @@ configurations.
(kayobe) $ kayobe environment create --source-config-path ~/kayobe-config-staging/etc/kayobe \
--environment staging
This command recursively copies files and directories under the existing
configuration. Merging shared configuration must be done manually.
This command recursively copies files and directories (except the
``environments`` directory if one exists) under the existing configuration to a
new environment. Merging shared configuration must be done manually.

View File

@ -61,4 +61,4 @@ def create_kayobe_environment(parsed_args):
source_config_path = parsed_args.source_config_path
if source_config_path:
utils.copy_dir(source_config_path, env_path)
utils.copy_dir(source_config_path, env_path, exclude=["environments"])

View File

@ -80,4 +80,5 @@ class TestCase(unittest.TestCase):
]
self.assertEqual(expected_calls, mock_mkdir.call_args_list)
mock_copy_dir.assert_called_once_with(
"/path/to/foo", "/path/to/config/environments/foo")
"/path/to/foo", "/path/to/config/environments/foo",
exclude=["environments"])

View File

@ -225,14 +225,27 @@ def intersect_limits(args_limit, cli_limit):
return separator.join(limits)
def copy_dir(src, dest):
def copy_dir(src, dest, exclude=None):
"""Copy recursively a directory.
:param src: path of the source directory
:param dest: destination path, will be created if it does not exist
:param exclude: names of files or directories at the root of the source
directory to exclude during copy
"""
if exclude is None:
exclude = []
if not os.path.isdir(dest):
shutil.copytree(src, dest)
else:
for file in os.listdir(src):
src_path = os.path.join(src, file)
dest_path = os.path.join(dest, file)
if os.path.isdir(src_path):
copy_dir(src_path, dest_path)
else:
shutil.copy2(src_path, dest_path)
os.mkdir(dest)
for file in os.listdir(src):
if file in exclude:
continue
src_path = os.path.join(src, file)
dest_path = os.path.join(dest, file)
if os.path.isdir(src_path):
copy_dir(src_path, dest_path)
else:
shutil.copy2(src_path, dest_path)