Add --disable-container-prepare flag

Users may want to skip the container prepare process to ensure they
don't update their containers. This change adds a
--disable-container-prepare flag to the following actions which should
skip the preparation actions.
 - overcloud deploy (and updates)
 - overcloud plan actions
 - undercloud deploy (and upgrades)
 - tripleo deploy (and standalone deploy)

Conflicts:
        tripleoclient/tests/v1/test_overcloud_plan.py
        tripleoclient/tests/workflows/test_plan_management.py
        tripleoclient/v1/overcloud_deploy.py
        tripleoclient/v1/overcloud_plan.py
        tripleoclient/workflows/plan_management.py

Closes-Bug: #1896757
Depends-On: https://review.opendev.org/c/openstack/tripleo-ansible/+/769774
Change-Id: I30b448930f53aef108d9bdb544a6d02b18658b0d
(cherry picked from commit 0d84ac9234)
This commit is contained in:
Alex Schultz 2020-09-22 14:06:34 -06:00
parent a60ec726e4
commit 08d9f082ea
8 changed files with 120 additions and 40 deletions

View File

@ -131,7 +131,8 @@ class TestOvercloudCreatePlan(utils.TestCommand):
extra_vars={
"container": "overcast",
"generate_passwords": True,
"validate": False
"validate": False,
"disable_image_params_prepare": False,
},
verbosity=3,
)
@ -163,7 +164,8 @@ class TestOvercloudCreatePlan(utils.TestCommand):
extra_vars={
"container": "overcast",
"generate_passwords": True,
"validate": False
"validate": False,
"disable_image_params_prepare": False,
},
verbosity=3,
)
@ -204,7 +206,8 @@ class TestOvercloudCreatePlan(utils.TestCommand):
"container": "overcast",
"generate_passwords": True,
"plan_environment": "the_plan_environment.yaml",
"validate": False
"validate": False,
"disable_image_params_prepare": False,
},
verbosity=3,
)
@ -217,11 +220,13 @@ class TestOvercloudCreatePlan(utils.TestCommand):
self, mock_tmp, mock_cd, mock_run_playbook):
# Setup
arglist = ['overcast', '--disable-password-generation']
arglist = ['overcast', '--disable-password-generation',
'--disable-container-prepare']
verifylist = [
('name', 'overcast'),
('templates', None),
('disable_password_generation', True)
('disable_password_generation', True),
('disable_container_prepare', True)
]
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
@ -237,7 +242,8 @@ class TestOvercloudCreatePlan(utils.TestCommand):
extra_vars={
"container": "overcast",
"generate_passwords": False,
"validate": False
"validate": False,
"disable_image_params_prepare": True,
},
verbosity=3,
)

View File

@ -51,7 +51,8 @@ class TestPlanCreationWorkflows(utils.TestCommand):
extra_vars={
"container": "test-overcloud",
"generate_passwords": True,
"validate": False
"validate": False,
"disable_image_params_prepare": False,
},
verbosity=0,
)
@ -83,7 +84,8 @@ class TestPlanCreationWorkflows(utils.TestCommand):
extra_vars={
"container": "test-overcloud",
"generate_passwords": True,
"validate": False
"validate": False,
"disable_image_params_prepare": False,
},
verbosity=0,
)
@ -120,7 +122,8 @@ class TestPlanCreationWorkflows(utils.TestCommand):
"container": "test-overcloud",
"generate_passwords": True,
"plan_environment": "the-plan-environment.yaml",
"validate": False
"validate": False,
"disable_image_params_prepare": False,
},
verbosity=0,
)
@ -155,7 +158,8 @@ class TestPlanCreationWorkflows(utils.TestCommand):
extra_vars={
"container": "test-overcloud",
"generate_passwords": True,
"validate": False
"validate": False,
"disable_image_params_prepare": False,
},
verbosity=0,
)
@ -178,7 +182,8 @@ class TestPlanCreationWorkflows(utils.TestCommand):
'test-overcloud',
'/tht-root/',
generate_passwords=False,
validate_stack=False)
validate_stack=False,
disable_image_params_prepare=True)
mock_run_playbook.assert_called_once_with(
'cli-create-deployment-plan.yaml',
@ -188,7 +193,8 @@ class TestPlanCreationWorkflows(utils.TestCommand):
extra_vars={
"container": "test-overcloud",
"generate_passwords": False,
"validate": False
"validate": False,
"disable_image_params_prepare": True,
},
verbosity=0,
)
@ -274,7 +280,8 @@ class TestPlanUpdateWorkflows(base.TestCommand):
extra_vars={
"container": "test-overcloud",
"generate_passwords": True,
"validate": False
"validate": False,
"disable_image_params_prepare": False,
},
verbosity=1,
)
@ -311,7 +318,8 @@ class TestPlanUpdateWorkflows(base.TestCommand):
extra_vars={
"container": "test-overcloud",
"generate_passwords": True,
"validate": False
"validate": False,
"disable_image_params_prepare": False,
},
verbosity=1,
)
@ -334,7 +342,8 @@ class TestPlanUpdateWorkflows(base.TestCommand):
self.app.client_manager,
'test-overcloud',
'/tht-root/',
validate_stack=False)
validate_stack=False,
disable_image_params_prepare=True)
# A dictionary without the "passwords" key is provided in
# the _load_passwords method.
mock_yaml_safe_load.return_value = {}
@ -349,7 +358,8 @@ class TestPlanUpdateWorkflows(base.TestCommand):
extra_vars={
"container": "test-overcloud",
"generate_passwords": True,
"validate": False
"validate": False,
"disable_image_params_prepare": True,
},
verbosity=1,
)

View File

@ -403,6 +403,7 @@ class DeployOvercloud(command.Command):
plans = plan_management.list_deployment_plans(self.clients)
generate_passwords = not parsed_args.disable_password_generation
disable_prepare = parsed_args.disable_container_prepare
# TODO(d0ugal): We need to put a more robust strategy in place here to
# handle updating plans.
@ -416,7 +417,8 @@ class DeployOvercloud(command.Command):
parsed_args.networks_file,
type(self)._keep_env_on_update,
validate_stack=False,
verbosity_level=utils.playbook_verbosity(self=self)
verbosity_level=utils.playbook_verbosity(self=self),
disable_image_params_prepare=disable_prepare
)
else:
plan_management.create_plan_from_templates(
@ -425,7 +427,8 @@ class DeployOvercloud(command.Command):
parsed_args.plan_environment_file,
parsed_args.networks_file,
validate_stack=False,
verbosity_level=utils.playbook_verbosity(self=self)
verbosity_level=utils.playbook_verbosity(self=self),
disable_image_params_prepare=disable_prepare
)
# Get any missing (e.g j2 rendered) files from the plan to tht_root
@ -676,7 +679,7 @@ class DeployOvercloud(command.Command):
"baremetal_deployment": roles,
"baremetal_deployed_path": output_path,
"ssh_public_keys": ssh_key,
"ssh_user_name": parsed_args.overcloud_ssh_user,
"ssh_user_name": parsed_args.overcloud_ssh_user
}
with utils.TempDirs() as tmp:
@ -1007,6 +1010,16 @@ class DeployOvercloud(command.Command):
help=_('The number of Ansible forks to use for the'
' config-download ansible-playbook command.')
)
parser.add_argument(
'--disable-container-prepare',
action='store_true',
default=False,
help=_('Disable the container preparation actions to prevent '
'container tags from being updated and new containers '
'from being fetched. If you skip this but do not have '
'the container parameters configured, the deployment '
'action may fail.')
)
return parser
def take_action(self, parsed_args):

View File

@ -106,7 +106,16 @@ class CreatePlan(command.Command):
'to deploy. If this or --templates isn\'t provided, the '
'templates packaged on the Undercloud will be used.')
)
parser.add_argument(
'--disable-container-prepare',
action='store_true',
default=False,
help=_('Disable the container preparation actions to prevent '
'container tags from being updated and new containers '
'from being fetched. If you skip this but do not have '
'the container parameters configured, the deployment '
'action may fail.')
)
return parser
def take_action(self, parsed_args):
@ -122,13 +131,17 @@ class CreatePlan(command.Command):
if not parsed_args.templates and not parsed_args.source_url:
use_default_templates = True
# Needs this to avoid too long lines
disable_container_prepare = parsed_args.disable_container_prepare
if parsed_args.templates:
plan_management.create_plan_from_templates(
clients, name, parsed_args.templates,
generate_passwords=generate_passwords,
plan_env_file=parsed_args.plan_environment_file,
validate_stack=False,
verbosity_level=utils.playbook_verbosity(self=self)
verbosity_level=utils.playbook_verbosity(self=self),
disable_image_params_prepare=disable_container_prepare
)
else:
plan_management.create_deployment_plan(
@ -137,7 +150,8 @@ class CreatePlan(command.Command):
source_url=source_url,
use_default_templates=use_default_templates,
validate_stack=False,
verbosity_level=utils.playbook_verbosity(self=self)
verbosity_level=utils.playbook_verbosity(self=self),
disable_image_params_prepare=disable_container_prepare
)

View File

@ -791,7 +791,8 @@ class Deploy(command.Command):
environments, self.tht_render, parsed_args.templates,
cleanup=parsed_args.cleanup)
self._prepare_container_images(env, roles_data)
if not parsed_args.disable_container_prepare:
self._prepare_container_images(env, roles_data)
parameters.convert_docker_params(env)
self.log.debug(_("Getting template contents"))
@ -1092,6 +1093,16 @@ class Deploy(command.Command):
help=_('The number of Ansible forks to use for the'
' config-download ansible-playbook command.')
)
parser.add_argument(
'--disable-container-prepare',
action='store_true',
default=False,
help=_('Disable the container preparation actions to prevent '
'container tags from being updated and new containers '
'from being fetched. If you skip this but do not have '
'the container parameters configured, the deployment '
'action may fail.')
)
stack_action_group = parser.add_mutually_exclusive_group()

View File

@ -122,6 +122,16 @@ class InstallUndercloud(command.Command):
parser.add_argument('-y', '--yes', default=False,
action='store_true',
help=_("Skip yes/no prompt (assume yes)."))
parser.add_argument(
'--disable-container-prepare',
action='store_true',
default=False,
help=_('Disable the container preparation actions to prevent '
'container tags from being updated and new containers '
'from being fetched. If you skip this but do not have '
'the container parameters configured, the deployment '
'action may fail.')
)
return parser
def take_action(self, parsed_args):
@ -140,7 +150,8 @@ class InstallUndercloud(command.Command):
verbose_level=self.app_args.verbose_level,
force_stack_update=parsed_args.force_stack_update,
dry_run=parsed_args.dry_run,
inflight=inflight)
inflight=inflight,
disable_container_prepare=parsed_args.disable_container_prepare)
self.log.warning("Running: %s" % ' '.join(cmd))
if not parsed_args.dry_run:

View File

@ -426,7 +426,8 @@ def _process_chrony_acls(env):
def prepare_undercloud_deploy(upgrade=False, no_validations=True,
verbose_level=1, yes=False,
force_stack_update=False, dry_run=False,
inflight=False):
inflight=False,
disable_container_prepare=False):
"""Prepare Undercloud deploy command based on undercloud.conf"""
if CONF.get('undercloud_hostname'):
@ -826,6 +827,9 @@ def prepare_undercloud_deploy(upgrade=False, no_validations=True,
if inflight:
deploy_args.append('--inflight-validations')
if disable_container_prepare:
deploy_args.append('--disable-container-prepare')
if CONF.get('custom_env_files'):
for custom_file in CONF['custom_env_files']:
deploy_args += ['-e', custom_file]

View File

@ -67,11 +67,13 @@ def _upload_templates(swift_client, container_name, tht_root, roles_file=None,
def create_deployment_plan(container, generate_passwords,
use_default_templates=False, source_url=None,
validate_stack=True, verbosity_level=0,
plan_env_file=None):
plan_env_file=None,
disable_image_params_prepare=False):
extra_vars = {
"container": container,
"validate": validate_stack,
"generate_passwords": generate_passwords
"generate_passwords": generate_passwords,
"disable_image_params_prepare": disable_image_params_prepare
}
if plan_env_file:
@ -107,7 +109,9 @@ def delete_deployment_plan(clients, container):
raise RuntimeError(result)
def update_deployment_plan(clients, verbosity_level=0, **workflow_input):
def update_deployment_plan(clients, verbosity_level=0,
disable_image_params_prepare=False,
**workflow_input):
with utils.TempDirs() as tmp:
utils.run_ansible_playbook(
"cli-update-deployment-plan.yaml",
@ -118,6 +122,7 @@ def update_deployment_plan(clients, verbosity_level=0, **workflow_input):
"container": workflow_input['container'],
"validate": workflow_input['validate_stack'],
"generate_passwords": workflow_input["generate_passwords"],
"disable_image_params_prepare": disable_image_params_prepare
},
verbosity=verbosity_level
)
@ -133,7 +138,8 @@ def list_deployment_plans(clients):
def create_plan_from_templates(clients, name, tht_root, roles_file=None,
generate_passwords=True, plan_env_file=None,
networks_file=None, validate_stack=True,
verbosity_level=0):
verbosity_level=0,
disable_image_params_prepare=False):
swift_client = clients.tripleoclient.object_store
print("Creating Swift container to store the plan")
@ -145,11 +151,13 @@ def create_plan_from_templates(clients, name, tht_root, roles_file=None,
plan_env_file, networks_file)
try:
create_deployment_plan(container=name,
generate_passwords=generate_passwords,
plan_env_file=plan_env_file,
validate_stack=validate_stack,
verbosity_level=verbosity_level)
create_deployment_plan(
container=name,
generate_passwords=generate_passwords,
plan_env_file=plan_env_file,
validate_stack=validate_stack,
verbosity_level=verbosity_level,
disable_image_params_prepare=disable_image_params_prepare)
except exceptions.WorkflowServiceError:
swiftutils.delete_container(swift_client, name)
raise
@ -158,7 +166,8 @@ def create_plan_from_templates(clients, name, tht_root, roles_file=None,
def update_plan_from_templates(clients, name, tht_root, roles_file=None,
generate_passwords=True, plan_env_file=None,
networks_file=None, keep_env=False,
validate_stack=True, verbosity_level=1):
validate_stack=True, verbosity_level=1,
disable_image_params_prepare=False):
swift_client = clients.tripleoclient.object_store
passwords = None
keep_file_contents = {}
@ -210,11 +219,13 @@ def update_plan_from_templates(clients, name, tht_root, roles_file=None,
plan_env_file, networks_file)
_update_passwords(swift_client, name, passwords)
update_deployment_plan(clients, container=name,
generate_passwords=generate_passwords,
source_url=None,
validate_stack=validate_stack,
verbosity_level=verbosity_level)
update_deployment_plan(
clients, container=name,
generate_passwords=generate_passwords,
source_url=None,
validate_stack=validate_stack,
verbosity_level=verbosity_level,
disable_image_params_prepare=disable_image_params_prepare)
def _load_content_or_file(swift_client, container, remote_and_local_map):