diff --git a/lib/ansible/cli/galaxy.py b/lib/ansible/cli/galaxy.py index f8e812cac13..6f9bf612ff0 100644 --- a/lib/ansible/cli/galaxy.py +++ b/lib/ansible/cli/galaxy.py @@ -38,7 +38,6 @@ from ansible.galaxy.api import GalaxyAPI from ansible.galaxy.role import GalaxyRole from ansible.playbook.role.requirement import RoleRequirement - class GalaxyCLI(CLI): VALID_ACTIONS = ("init", "info", "install", "list", "remove", "search") @@ -360,6 +359,7 @@ class GalaxyCLI(CLI): if role_file: self.display.debug('Getting roles from %s' % role_file) try: + self.display.debug('Processing role file: %s' % role_file) f = open(role_file, 'r') if role_file.endswith('.yaml') or role_file.endswith('.yml'): try: @@ -389,13 +389,14 @@ class GalaxyCLI(CLI): role = roles_left.pop(0) role_path = role.path - self.display.debug('Installing role %s' % role_path) if role_path: self.options.roles_path = role_path else: self.options.roles_path = roles_path + self.display.debug('Installing role %s from %s' % (role.name, self.options.roles_path)) + tmp_file = None installed = False if role.src and os.path.isfile(role.src): @@ -404,7 +405,7 @@ class GalaxyCLI(CLI): else: if role.scm: # create tar file from scm url - tmp_file = scm_archive_role(role.scm, role.src, role.version, role.name) + tmp_file = GalaxyRole.scm_archive_role(role.scm, role.src, role.version, role.name) if role.src: if '://' not in role.src: role_data = self.api.lookup_role_by_name(role.src) diff --git a/lib/ansible/galaxy/role.py b/lib/ansible/galaxy/role.py index 3a58ccb6d1a..439ba665b7a 100644 --- a/lib/ansible/galaxy/role.py +++ b/lib/ansible/galaxy/role.py @@ -312,3 +312,49 @@ class GalaxyRole(object): trailing_path = trailing_path.split(',')[0] return trailing_path + @staticmethod + def scm_archive_role(scm, role_url, role_version, role_name): + if scm not in ['hg', 'git']: + self.display.display("- scm %s is not currently supported" % scm) + return False + tempdir = tempfile.mkdtemp() + clone_cmd = [scm, 'clone', role_url, role_name] + with open('/dev/null', 'w') as devnull: + try: + self.display.display("- executing: %s" % " ".join(clone_cmd)) + popen = subprocess.Popen(clone_cmd, cwd=tempdir, stdout=devnull, stderr=devnull) + except: + raise AnsibleError("error executing: %s" % " ".join(clone_cmd)) + rc = popen.wait() + if rc != 0: + self.display.display("- command %s failed" % ' '.join(clone_cmd)) + self.display.display(" in directory %s" % tempdir) + return False + + temp_file = tempfile.NamedTemporaryFile(delete=False, suffix='.tar') + if scm == 'hg': + archive_cmd = ['hg', 'archive', '--prefix', "%s/" % role_name] + if role_version: + archive_cmd.extend(['-r', role_version]) + archive_cmd.append(temp_file.name) + if scm == 'git': + archive_cmd = ['git', 'archive', '--prefix=%s/' % role_name, '--output=%s' % temp_file.name] + if role_version: + archive_cmd.append(role_version) + else: + archive_cmd.append('HEAD') + + with open('/dev/null', 'w') as devnull: + self.display.display("- executing: %s" % " ".join(archive_cmd)) + popen = subprocess.Popen(archive_cmd, cwd=os.path.join(tempdir, role_name), + stderr=devnull, stdout=devnull) + rc = popen.wait() + if rc != 0: + self.display.display("- command %s failed" % ' '.join(archive_cmd)) + self.display.display(" in directory %s" % tempdir) + return False + + shutil.rmtree(tempdir, ignore_errors=True) + + return temp_file.name + diff --git a/lib/ansible/inventory/__init__.py b/lib/ansible/inventory/__init__.py index 1e6efeefdd4..8b12823b988 100644 --- a/lib/ansible/inventory/__init__.py +++ b/lib/ansible/inventory/__init__.py @@ -45,10 +45,6 @@ class Inventory(object): Host inventory for ansible. """ - #__slots__ = [ 'host_list', 'groups', '_restriction', '_subset', - # 'parser', '_vars_per_host', '_vars_per_group', '_hosts_cache', '_groups_list', - # '_pattern_cache', '_vault_password', '_vars_plugins', '_playbook_basedir'] - def __init__(self, loader, variable_manager, host_list=C.DEFAULT_HOST_LIST): # the host file file, or script path, or list of hosts diff --git a/lib/ansible/playbook/role/requirement.py b/lib/ansible/playbook/role/requirement.py index 03ffc3d7107..863f393409e 100644 --- a/lib/ansible/playbook/role/requirement.py +++ b/lib/ansible/playbook/role/requirement.py @@ -164,3 +164,36 @@ class RoleRequirement(RoleDefinition): return dict(scm=scm, src=role_url, version=role_version, role_name=role_name) +def role_yaml_parse(role): + if 'role' in role: + # Old style: {role: "galaxy.role,version,name", other_vars: "here" } + role_info = role_spec_parse(role['role']) + if isinstance(role_info, dict): + # Warning: Slight change in behaviour here. name may be being + # overloaded. Previously, name was only a parameter to the role. + # Now it is both a parameter to the role and the name that + # ansible-galaxy will install under on the local system. + if 'name' in role and 'name' in role_info: + del role_info['name'] + role.update(role_info) + else: + # New style: { src: 'galaxy.role,version,name', other_vars: "here" } + if 'github.com' in role["src"] and 'http' in role["src"] and '+' not in role["src"] and not role["src"].endswith('.tar.gz'): + role["src"] = "git+" + role["src"] + + if '+' in role["src"]: + (scm, src) = role["src"].split('+') + role["scm"] = scm + role["src"] = src + + if 'name' not in role: + role["name"] = repo_url_to_role_name(role["src"]) + + if 'version' not in role: + role['version'] = '' + + if 'scm' not in role: + role['scm'] = None + + return role + diff --git a/test/integration/galaxy_roles.yml b/test/integration/galaxy_roles.yml index 76b385191cd..5a1f8eba86d 100644 --- a/test/integration/galaxy_roles.yml +++ b/test/integration/galaxy_roles.yml @@ -1,3 +1,7 @@ +# change these to some ansible owned test roles +- src: briancoca.oracle_java7 + name: oracle_java7 + - src: git+http://bitbucket.org/willthames/git-ansible-galaxy version: v1.4