From 5ee5593cbf5894930b83b22a0198b76ea4423787 Mon Sep 17 00:00:00 2001 From: Will Thames Date: Wed, 18 Jan 2017 00:49:16 +1000 Subject: [PATCH] Improve ansible-galaxy handling of role versions (#12904) * Improve ansible-galaxy handling of role versions Ensure that role versions are considered when deciding whether or not to (re-)install a role. Issue a warning when the version of a dependency conflicts with the version of an already installed role Display what version of a role is being installed Show the versions when upgrading/downgrading a role. Implements #11266 * Improve force logic for galaxy version changes Ensure that force is required to change role versions --- lib/ansible/cli/galaxy.py | 26 ++++++++++++++++++++------ lib/ansible/galaxy/role.py | 11 ++++++++++- 2 files changed, 30 insertions(+), 7 deletions(-) diff --git a/lib/ansible/cli/galaxy.py b/lib/ansible/cli/galaxy.py index 52b1349c9e4..7f2dc6f2128 100644 --- a/lib/ansible/cli/galaxy.py +++ b/lib/ansible/cli/galaxy.py @@ -369,9 +369,19 @@ class GalaxyCLI(CLI): display.vvv('Installing role %s ' % role.name) # query the galaxy API for the role data - if role.install_info is not None and not force: - display.display('- %s is already installed, skipping.' % role.name) - continue + if role.install_info is not None: + if role.install_info['version'] != role.version: + if force: + display.display('- changing role %s from %s to %s' % + (role.name, role.install_info['version'], role.version or "unspecified")) + role.remove() + else: + display.warning('- %s (%s) is already installed - use --force to change version to %s' % + (role.name, role.install_info['version'], role.version or "unspecified")) + continue + else: + display.display('- %s is already installed, skipping.' % str(role)) + continue try: installed = role.install() @@ -392,14 +402,18 @@ class GalaxyCLI(CLI): # we know we can skip this, as it's not going to # be found on galaxy.ansible.com continue - if dep_role.install_info is None or force: + if dep_role.install_info is None: if dep_role not in roles_left: - display.display('- adding dependency: %s' % dep_role.name) + display.display('- adding dependency: %s' % str(dep_role)) roles_left.append(dep_role) else: display.display('- dependency %s already pending installation.' % dep_role.name) else: - display.display('- dependency %s is already installed, skipping.' % dep_role.name) + 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'])) + else: + display.display('- dependency %s is already installed, skipping.' % dep_role.name) if not installed: display.warning("- %s was NOT installed successfully." % role.name) diff --git a/lib/ansible/galaxy/role.py b/lib/ansible/galaxy/role.py index a3498c5e645..da6743bd81d 100644 --- a/lib/ansible/galaxy/role.py +++ b/lib/ansible/galaxy/role.py @@ -82,6 +82,15 @@ class GalaxyRole(object): self.paths = [x for x in galaxy.roles_paths] self.paths = [os.path.join(x, self.name) for x in self.paths] + def __repr__(self): + """ + Returns "rolename (version)" if version is not null + Returns "rolename" otherwise + """ + if self.version: + return "%s (%s)" % (self.name, self.version) + else: + return self.name def __eq__(self, other): return self.name == other.name @@ -321,7 +330,7 @@ class GalaxyRole(object): raise AnsibleError("Could not update files in %s: %s" % (self.path, str(e))) # return the parsed yaml metadata - display.display("- %s was installed successfully" % self.name) + display.display("- %s was installed successfully" % str(self)) if not local_file: try: os.unlink(tmp_file)