From ad57efff8f99f8b59408d0d815f69a9c6a4c1bfa Mon Sep 17 00:00:00 2001 From: Brian Coca Date: Wed, 23 Jan 2019 12:34:26 -0500 Subject: [PATCH] [WIP] force install role and its deps (#49347) --- changelogs/fragments/force_role_with_deps.yml | 2 ++ lib/ansible/cli/galaxy.py | 29 +++++++++++++++---- 2 files changed, 25 insertions(+), 6 deletions(-) create mode 100644 changelogs/fragments/force_role_with_deps.yml diff --git a/changelogs/fragments/force_role_with_deps.yml b/changelogs/fragments/force_role_with_deps.yml new file mode 100644 index 0000000000..ab4acd8af7 --- /dev/null +++ b/changelogs/fragments/force_role_with_deps.yml @@ -0,0 +1,2 @@ +minor_changes: + - allow user to force install a role and it's dependencies diff --git a/lib/ansible/cli/galaxy.py b/lib/ansible/cli/galaxy.py index a93bc11abb..f1837ad064 100644 --- a/lib/ansible/cli/galaxy.py +++ b/lib/ansible/cli/galaxy.py @@ -115,6 +115,9 @@ class GalaxyCLI(CLI): ' file (/etc/ansible/roles if not configured)', type='str') if self.action in ("init", "install"): self.parser.add_option('-f', '--force', dest='force', action='store_true', default=False, help='Force overwriting an existing role') + if self.action == "install": + self.parser.add_option('--force-with-deps', dest='force_with_deps', action='store_true', default=False, + help="Force overwriting an existing role and it's dependencies") def init_parser(self): ''' create an options parser for bin/ansible ''' @@ -311,7 +314,12 @@ class GalaxyCLI(CLI): raise AnsibleOptionsError("- you must specify a user/role name or a roles file") no_deps = context.CLIARGS['no_deps'] - force = context.CLIARGS['force'] + force_deps = context.CLIARGS['force_with_deps'] + + if no_deps and force_deps: + raise AnsibleOptionsError("You cannot both force dependencies and no dependencies") + + force = context.CLIARGS['force'] or force_deps roles_left = [] if role_file: @@ -321,7 +329,7 @@ class GalaxyCLI(CLI): try: required_roles = yaml.safe_load(f.read()) except Exception as e: - raise AnsibleError("Unable to load data from the requirements file: %s" % role_file) + raise AnsibleError("Unable to load data from the requirements file (%s): %s" % (role_file, to_native(e))) if required_roles is None: raise AnsibleError("No roles found in file: %s" % role_file) @@ -404,16 +412,25 @@ class GalaxyCLI(CLI): continue if dep_role.install_info is None: if dep_role not in roles_left: - display.display('- adding dependency: %s' % str(dep_role)) + display.display('- adding dependency: %s' % to_text(dep_role)) roles_left.append(dep_role) else: display.display('- dependency %s already pending installation.' % dep_role.name) else: if dep_role.install_info['version'] != dep_role.version: - display.warning('- dependency %s from role %s differs from already installed version (%s), skipping' % - (str(dep_role), role.name, dep_role.install_info['version'])) + if force_deps: + display.display('- changing dependant role %s from %s to %s' % + (dep_role.name, dep_role.install_info['version'], dep_role.version or "unspecified")) + dep_role.remove() + roles_left.append(dep_role) + else: + display.warning('- dependency %s from role %s differs from already installed version (%s), skipping' % + (to_text(dep_role), role.name, dep_role.install_info['version'])) else: - display.display('- dependency %s is already installed, skipping.' % dep_role.name) + if force_deps: + roles_left.append(dep_role) + else: + display.display('- dependency %s is already installed, skipping.' % dep_role.name) if not installed: display.warning("- %s was NOT installed successfully." % role.name)