From 6cc5e4c9df08cac930c9d8b4dba4864699b5747f Mon Sep 17 00:00:00 2001
From: Adam Miller <admiller@redhat.com>
Date: Tue, 30 Jan 2018 10:40:25 -0600
Subject: [PATCH] galaxy remove incorrect check for role path before extraction
 (#35259)

* galaxy remove incorrect check for role path before extraction

Fixes #35217

Currently lib/ansible/galaxy/role.py checks roles_path and will
ignore paths that don't currently exist which it should not because
the path will attempt to be created by the role extraction process
(which is valid and expected behavior) and if unable to write at the
time of role extraction into the role_path, that error will be
handled properly at that point in the process.

Signed-off-by: Adam Miller <admiller@redhat.com>

* add test case for galaxy install with rolefile and rolepath

Verify we don't regress GitHub Issue #35217

Signed-off-by: Adam Miller <admiller@redhat.com>

* fix the integration test

Signed-off-by: Adam Miller <admiller@redhat.com>

* double quote for shellcheck glob warning

Signed-off-by: Adam Miller <admiller@redhat.com>

* fix galaxy install tests to not need remote resources

Signed-off-by: Adam Miller <admiller@redhat.com>

* make shellcheck sanity tests happy

Signed-off-by: Adam Miller <admiller@redhat.com>

* prep git global conf for running the galaxy install tests in docker

Signed-off-by: Adam Miller <admiller@redhat.com>

* move ansible-galaxy tests into their own target, make git conf non-global

Signed-off-by: Adam Miller <admiller@redhat.com>

* fix up tests based on feedback

Signed-off-by: Adam Miller <admiller@redhat.com>

* remove extra newline from aliases file

Signed-off-by: Adam Miller <admiller@redhat.com>
---
 lib/ansible/galaxy/role.py                    |  16 +--
 .../targets/ansible-galaxy/aliases            |   1 +
 .../targets/ansible-galaxy/runme.sh           | 105 ++++++++++++++++++
 3 files changed, 111 insertions(+), 11 deletions(-)
 create mode 100644 test/integration/targets/ansible-galaxy/aliases
 create mode 100755 test/integration/targets/ansible-galaxy/runme.sh

diff --git a/lib/ansible/galaxy/role.py b/lib/ansible/galaxy/role.py
index 740631a80b6..dad7002404b 100644
--- a/lib/ansible/galaxy/role.py
+++ b/lib/ansible/galaxy/role.py
@@ -71,17 +71,11 @@ class GalaxyRole(object):
                 path = os.path.join(path, self.name)
             self.path = path
         else:
-            for role_path_dir in galaxy.roles_paths:
-                role_path = os.path.join(role_path_dir, self.name)
-                if os.path.exists(role_path):
-                    self.path = role_path
-                    break
-            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]
+            # 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):
         """
diff --git a/test/integration/targets/ansible-galaxy/aliases b/test/integration/targets/ansible-galaxy/aliases
new file mode 100644
index 00000000000..79d8b9285eb
--- /dev/null
+++ b/test/integration/targets/ansible-galaxy/aliases
@@ -0,0 +1 @@
+posix/ci/group3
diff --git a/test/integration/targets/ansible-galaxy/runme.sh b/test/integration/targets/ansible-galaxy/runme.sh
new file mode 100755
index 00000000000..5372568769e
--- /dev/null
+++ b/test/integration/targets/ansible-galaxy/runme.sh
@@ -0,0 +1,105 @@
+#!/usr/bin/env bash
+
+set -eux -o pipefail
+
+# Need a relative custom roles path for testing various scenarios of -p
+galaxy_relative_rolespath="my/custom/roles/path"
+
+# Prep the local git repo with a role and make a tar archive so we can test
+# different things
+galaxy_local_test_role="test-role"
+galaxy_local_test_role_dir=$(mktemp -d)
+galaxy_local_test_role_git_repo="${galaxy_local_test_role_dir}/${galaxy_local_test_role}"
+galaxy_local_test_role_tar="${galaxy_local_test_role_dir}/${galaxy_local_test_role}.tar"
+pushd "${galaxy_local_test_role_dir}"
+    ansible-galaxy init "${galaxy_local_test_role}"
+    pushd "${galaxy_local_test_role}"
+        git init .
+
+        # Prep git, becuase it doesn't work inside a docker container without it
+        git config user.email "tester@ansible.com"
+        git config user.name "Ansible Tester"
+
+        git add .
+        git commit -m "local testing ansible galaxy role"
+        git archive \
+            --format=tar \
+            --prefix="${galaxy_local_test_role}/" \
+            master > "${galaxy_local_test_role_tar}"
+    popd # "${galaxy_local_test_role}"
+popd # "${galaxy_local_test_role_dir}"
+
+# Status message function (f_ to designate that it's a function)
+f_ansible_galaxy_status()
+{
+
+    printf "### Testing ansible-galaxy: %s\n" "${@}"
+}
+
+# Galaxy install test case
+#
+# Install local git repo
+f_ansible_galaxy_status "install of local git repo"
+galaxy_testdir=$(mktemp -d)
+pushd "${galaxy_testdir}"
+
+    ansible-galaxy install git+file:///"${galaxy_local_test_role_git_repo}"
+
+    # Test that the role was installed to the expected directory
+    [[ -d "${HOME}/.ansible/roles/${galaxy_local_test_role}" ]]
+popd # ${galaxy_testdir}
+rm -fr "${galaxy_testdir}"
+
+# Galaxy install test case
+#
+# Install local git repo and ensure that if a role_path is passed, it is in fact used
+f_ansible_galaxy_status "install of local git repo with -p \$role_path"
+galaxy_testdir=$(mktemp -d)
+pushd "${galaxy_testdir}"
+    mkdir -p "${galaxy_relative_rolespath}"
+
+    ansible-galaxy install git+file:///"${galaxy_local_test_role_git_repo}" -p "${galaxy_relative_rolespath}"
+
+    # Test that the role was installed to the expected directory
+    [[ -d "${galaxy_relative_rolespath}/${galaxy_local_test_role}" ]]
+popd # ${galaxy_testdir}
+rm -fr "${galaxy_testdir}"
+
+# Galaxy install test case
+#
+# Ensure that if both a role_file and role_path is provided, they are both
+# honored
+#
+# Protect against regression (GitHub Issue #35217)
+#   https://github.com/ansible/ansible/issues/35217
+
+f_ansible_galaxy_status \
+    "install of local git repo and local tarball with -p \$role_path and -r \$role_file" \
+    "Protect against regression (Issue #35217)"
+galaxy_testdir=$(mktemp -d)
+pushd "${galaxy_testdir}"
+
+    git clone "${galaxy_local_test_role_git_repo}" "${galaxy_local_test_role}"
+    ansible-galaxy init roles-path-bug
+    pushd roles-path-bug
+        cat <<EOF > ansible.cfg
+[defaults]
+roles_path = ../:../../:../roles:roles/
+EOF
+        cat <<EOF > requirements.yml
+---
+- src: ${galaxy_local_test_role_tar}
+  name: ${galaxy_local_test_role}
+EOF
+
+        ansible-galaxy install -r requirements.yml -p roles/
+    popd # roles-path-bug
+
+    # Test that the role was installed to the expected directory
+    [[ -d "${galaxy_testdir}/roles-path-bug/roles/${galaxy_local_test_role}" ]]
+
+popd # ${galaxy_testdir}
+rm -fr "${galaxy_testdir}"
+
+
+rm -fr "${galaxy_local_test_role_dir}"