Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ansible-galaxy - fix listing specific role and role description #67409

Merged
merged 8 commits into from Apr 15, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
@@ -0,0 +1,6 @@
bugfixes:
- >
ansible-galaxy - fix a bug where listing a specific role if it was not in the first
path failed to find the role

- ansible-galaxy - properly show the role description when running offline (https://github.com/ansible/ansible/issues/60167)
13 changes: 8 additions & 5 deletions lib/ansible/cli/galaxy.py
Expand Up @@ -580,7 +580,11 @@ def exit_without_ignore(rc=1):
def _display_role_info(role_info):

text = [u"", u"Role: %s" % to_text(role_info['name'])]
text.append(u"\tdescription: %s" % role_info.get('description', ''))

# Get the top-level 'description' first, falling back to galaxy_info['galaxy_info']['description'].
galaxy_info = role_info.get('galaxy_info', {})
description = role_info.get('description', galaxy_info.get('description', ''))
text.append(u"\tdescription: %s" % description)

for k in sorted(role_info.keys()):

Expand Down Expand Up @@ -854,6 +858,9 @@ def execute_info(self):

role_info = {'path': roles_path}
gr = GalaxyRole(self.galaxy, self.api, role)
if not gr._exists:
data = u"- the role %s was not found" % role
break

install_info = gr.install_info
if install_info:
Expand All @@ -878,10 +885,6 @@ def execute_info(self):
role_info.update(role_spec)

data = self._display_role_info(role_info)
# FIXME: This is broken in both 1.9 and 2.0 as
# _display_role_info() always returns something
if not data:
data = u"\n- the role %s was not found" % role

self.pager(data)

Expand Down
34 changes: 20 additions & 14 deletions lib/ansible/galaxy/role.py
Expand Up @@ -64,6 +64,7 @@ def __init__(self, galaxy, api, name, src=None, version=None, scm=None, path=Non
self.version = version
self.src = src or name
self.scm = scm
self.paths = [os.path.join(x, self.name) for x in galaxy.roles_paths]

if path is not None:
if not path.endswith(os.path.join(os.path.sep, self.name)):
Expand All @@ -82,9 +83,6 @@ def __init__(self, galaxy, api, name, src=None, version=None, scm=None, path=Non
else:
# use the first path by default
self.path = os.path.join(galaxy.roles_paths[0], self.name)
# create list of possible paths
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):
"""
Expand All @@ -105,17 +103,17 @@ def metadata(self):
Returns role metadata
"""
if self._metadata is None:
for meta_main in self.META_MAIN:
meta_path = os.path.join(self.path, meta_main)
if os.path.isfile(meta_path):
try:
f = open(meta_path, 'r')
self._metadata = yaml.safe_load(f)
except Exception:
display.vvvvv("Unable to load metadata for %s" % self.name)
return False
finally:
f.close()
for path in self.paths:
for meta_main in self.META_MAIN:
meta_path = os.path.join(path, meta_main)
if os.path.isfile(meta_path):
try:
with open(meta_path, 'r') as f:
self._metadata = yaml.safe_load(f)
except Exception:
display.vvvvv("Unable to load metadata for %s" % self.name)
return False
break

return self._metadata

Expand All @@ -138,6 +136,14 @@ def install_info(self):
f.close()
return self._install_info

@property
def _exists(self):
for path in self.paths:
if os.path.isdir(path):
return True

return False

def _write_galaxy_install_info(self):
"""
Writes a YAML-formatted file to the role's meta/ directory
Expand Down
65 changes: 65 additions & 0 deletions test/integration/targets/ansible-galaxy/runme.sh
Expand Up @@ -120,6 +120,71 @@ f_ansible_galaxy_status \

[[ $(grep -c '^- test-role' out.txt ) -eq 2 ]]

# Galaxy role test case
#
# Test listing a specific role that is not in the first path in ANSIBLE_ROLES_PATH.
# https://github.com/ansible/ansible/issues/60167#issuecomment-585460706

f_ansible_galaxy_status \
"list specific role not in the first path in ANSIBLE_ROLES_PATHS"

role_testdir=$(mktemp -d)
pushd "${role_testdir}"

mkdir testroles
ansible-galaxy role init --init-path ./local-roles quark
ANSIBLE_ROLES_PATH=./local-roles:${HOME}/.ansible/roles ansible-galaxy role list quark | tee out.txt

[[ $(grep -c 'not found' out.txt) -eq 0 ]]

ANSIBLE_ROLES_PATH=${HOME}/.ansible/roles:./local-roles ansible-galaxy role list quark | tee out.txt

[[ $(grep -c 'not found' out.txt) -eq 0 ]]

popd # ${role_testdir}
rm -fr "${role_testdir}"


# Galaxy role info tests

f_ansible_galaxy_status \
"role info non-existant role"

role_testdir=$(mktemp -d)
pushd "${role_testdir}"

ansible-galaxy role info notaroll | tee out.txt

grep -- '- the role notaroll was not found' out.txt

f_ansible_galaxy_status \
"role info description offline"

mkdir testroles
ansible-galaxy role init testdesc --init-path ./testroles

# Only galaxy_info['description'] exists in file
sed -i -e 's#[[:space:]]\{1,\}description:.*$# description: Description in galaxy_info#' ./testroles/testdesc/meta/main.yml
ansible-galaxy role info -p ./testroles --offline testdesc | tee out.txt
grep 'description: Description in galaxy_info' out.txt

# Both top level 'description' and galaxy_info['description'] exist in file
# Use shell-fu instead of sed to prepend a line to a file because BSD
# and macOS sed don't work the same as GNU sed.
echo 'description: Top level' | \
cat - ./testroles/testdesc/meta/main.yml > tmp.yml && \
mv tmp.yml ./testroles/testdesc/meta/main.yml
ansible-galaxy role info -p ./testroles --offline testdesc | tee out.txt
grep 'description: Top level' out.txt

# Only top level 'description' exists in file
sed -i.bak '/^[[:space:]]\{1,\}description: Description in galaxy_info/d' ./testroles/testdesc/meta/main.yml
ansible-galaxy role info -p ./testroles --offline testdesc | tee out.txt
grep 'description: Top level' out.txt

popd # ${role_testdir}
rm -fr "${role_testdir}"


# Properly list roles when the role name is a subset of the path, or the role
# name is the same name as the parent directory of the role. Issue #67365
Expand Down