Commit ccc9a33b by Brian Coca

most of galaxy is working, install still needs work

normalized return codes in bin
refactored galaxy classes a bit, ignoring 'compatct' role spec
parent cec4d088
...@@ -25,6 +25,10 @@ import os ...@@ -25,6 +25,10 @@ import os
from ansible.errors import AnsibleError from ansible.errors import AnsibleError
from ansible.utils.display import Display from ansible.utils.display import Display
# default_readme_template
# default_meta_template
class Galaxy(object): class Galaxy(object):
''' Keeps global galaxy info ''' ''' Keeps global galaxy info '''
...@@ -36,13 +40,31 @@ class Galaxy(object): ...@@ -36,13 +40,31 @@ class Galaxy(object):
self.display = display self.display = display
self.options = options self.options = options
self.roles_path = os.path.expanduser(self.options.roles_path) self.roles_path = getattr(self.options, 'roles_path', None)
if self.roles_path:
self.roles_path = os.path.expanduser(self.roles_path)
self.roles = {} self.roles = {}
# load data path for resource usage
this_dir, this_filename = os.path.split(__file__)
self.DATA_PATH = os.path.join(this_dir, "data")
#TODO: move to getter for lazy loading
self.default_readme = self._str_from_data_file('readme')
self.default_meta = self._str_from_data_file('metadata_template.j2')
def add_role(self, role): def add_role(self, role):
self.roles[role.name] = role self.roles[role.name] = role
def remove_role(self, role_name): def remove_role(self, role_name):
del self.roles[role_name] del self.roles[role_name]
def _str_from_data_file(self, filename):
myfile = os.path.join(self.DATA_PATH, filename)
try:
return open(myfile).read()
except Exception as e:
raise AnsibleError("Could not open %s: %s" % (filename, str(e)))
...@@ -38,10 +38,12 @@ class GalaxyAPI(object): ...@@ -38,10 +38,12 @@ class GalaxyAPI(object):
try: try:
urlparse(api_server, scheme='https') urlparse(api_server, scheme='https')
except: except:
raise AnsibleError("Invalid server API url passed: %s" % self.galaxy.api_server) raise AnsibleError("Invalid server API url passed: %s" % api_server)
server_version = self.get_server_api_version('%s/api/' % (api_server))
if not server_version:
raise AnsibleError("Could not retrieve server API version: %s" % api_server)
server_version = self.get_server_api_version(api_server)
self.galaxy.display.vvvvv("Server version: %s" % server_version)
if server_version in self.SUPPORTED_VERSIONS: if server_version in self.SUPPORTED_VERSIONS:
self.baseurl = '%s/api/%s' % (api_server, server_version) self.baseurl = '%s/api/%s' % (api_server, server_version)
self.version = server_version # for future use self.version = server_version # for future use
...@@ -54,22 +56,21 @@ class GalaxyAPI(object): ...@@ -54,22 +56,21 @@ class GalaxyAPI(object):
Fetches the Galaxy API current version to ensure Fetches the Galaxy API current version to ensure
the API server is up and reachable. the API server is up and reachable.
""" """
#TODO: fix galaxy server which returns current_version path (/api/v1) vs actual version (v1)
# also should set baseurl using supported_versions which has path
return 'v1'
try: try:
self.galaxy.display.vvvvv("Querying server version: %s" % api_server)
data = json.load(urlopen(api_server)) data = json.load(urlopen(api_server))
if not data.get("current_version", None): return data.get("current_version", 'v1')
return None except Exception as e:
else: # TODO: report error
return data
except:
return None return None
def lookup_role_by_name(self, role_name, notify=True): def lookup_role_by_name(self, role_name, notify=True):
""" """
Find a role by name Find a role by name
""" """
role_name = urlquote(role_name) role_name = urlquote(role_name)
try: try:
...@@ -82,6 +83,7 @@ class GalaxyAPI(object): ...@@ -82,6 +83,7 @@ class GalaxyAPI(object):
raise AnsibleError("- invalid role name (%s). Specify role as format: username.rolename" % role_name) raise AnsibleError("- invalid role name (%s). Specify role as format: username.rolename" % role_name)
url = '%s/roles/?owner__username=%s&name=%s' % (self.baseurl, user_name, role_name) url = '%s/roles/?owner__username=%s&name=%s' % (self.baseurl, user_name, role_name)
self.galaxy.display.vvvv("- %s" % (url))
try: try:
data = json.load(urlopen(url)) data = json.load(urlopen(url))
if len(data["results"]) != 0: if len(data["results"]) != 0:
......
...@@ -39,30 +39,20 @@ class GalaxyRole(object): ...@@ -39,30 +39,20 @@ class GalaxyRole(object):
ROLE_DIRS = ('defaults','files','handlers','meta','tasks','templates','vars') ROLE_DIRS = ('defaults','files','handlers','meta','tasks','templates','vars')
def __init__(self, galaxy, role_name, role_version=None, role_url=None): def __init__(self, galaxy, name, src=None, version=None, scm=None):
self._metadata = None
self._install_info = None
self.options = galaxy.options self.options = galaxy.options
self.display = galaxy.display self.display = galaxy.display
self.name = role_name self.name = name
self.meta_data = None self.version = version
self.install_info = None self.src = src
self.path = (os.path.join(galaxy.roles_path, self.name)) self.scm = scm
# TODO: possibly parse version and url from role_name
self.version = role_version
self.url = role_url
if self.url is None:
self._spec_parse()
if C.GALAXY_SCMS:
self.scms = self.SUPPORTED_SCMS.intersection(set(C.GALAXY_SCMS))
else:
self.scms = self.SUPPORTED_SCMS
if not self.scms:
self.display.warning("No valid SCMs configured for Galaxy.")
self.path = (os.path.join(galaxy.roles_path, self.name))
def fetch_from_scm_archive(self): def fetch_from_scm_archive(self):
...@@ -112,59 +102,44 @@ class GalaxyRole(object): ...@@ -112,59 +102,44 @@ class GalaxyRole(object):
return temp_file.name return temp_file.name
@property
def get_metadata(self): def metadata(self):
""" """
Returns role metadata Returns role metadata
""" """
if self.meta_data is None: if self._metadata is None:
self._read_metadata
return self.meta_data
def _read_metadata(self):
"""
Reads the metadata as YAML, if the file 'meta/main.yml' exists
"""
meta_path = os.path.join(self.path, self.META_MAIN) meta_path = os.path.join(self.path, self.META_MAIN)
if os.path.isfile(meta_path): if os.path.isfile(meta_path):
try: try:
f = open(meta_path, 'r') f = open(meta_path, 'r')
self.meta_data = yaml.safe_load(f) self._metadata = yaml.safe_load(f)
except: except:
self.display.vvvvv("Unable to load metadata for %s" % self.name) self.display.vvvvv("Unable to load metadata for %s" % self.name)
return False return False
finally: finally:
f.close() f.close()
return self._metadata
def get_galaxy_install_info(self):
"""
Returns role install info
"""
if self.install_info is None:
self._read_galaxy_isntall_info()
return self.install_info @property
def install_info(self):
def _read_galaxy_install_info(self):
""" """
Returns the YAML data contained in 'meta/.galaxy_install_info', Returns role install info
if it exists.
""" """
if self._install_info is None:
info_path = os.path.join(self.path, self.META_INSTALL) info_path = os.path.join(self.path, self.META_INSTALL)
if os.path.isfile(info_path): if os.path.isfile(info_path):
try: try:
f = open(info_path, 'r') f = open(info_path, 'r')
self.install_info = yaml.safe_load(f) self._install_info = yaml.safe_load(f)
except: except:
self.display.vvvvv("Unable to load Galaxy install info for %s" % self.name) self.display.vvvvv("Unable to load Galaxy install info for %s" % self.name)
return False return False
finally: finally:
f.close() f.close()
return self._install_info
def _write_galaxy_install_info(self): def _write_galaxy_install_info(self):
""" """
...@@ -180,7 +155,7 @@ class GalaxyRole(object): ...@@ -180,7 +155,7 @@ class GalaxyRole(object):
info_path = os.path.join(self.path, self.META_INSTALL) info_path = os.path.join(self.path, self.META_INSTALL)
try: try:
f = open(info_path, 'w+') f = open(info_path, 'w+')
self.install_info = yaml.safe_dump(info, f) self._install_info = yaml.safe_dump(info, f)
except: except:
return False return False
finally: finally:
...@@ -194,7 +169,7 @@ class GalaxyRole(object): ...@@ -194,7 +169,7 @@ class GalaxyRole(object):
sanity check to make sure there's a meta/main.yml file at this sanity check to make sure there's a meta/main.yml file at this
path so the user doesn't blow away random directories path so the user doesn't blow away random directories
""" """
if self.read_metadata(): if self.metadata:
try: try:
rmtree(self.path) rmtree(self.path)
return True return True
...@@ -210,8 +185,8 @@ class GalaxyRole(object): ...@@ -210,8 +185,8 @@ class GalaxyRole(object):
""" """
# first grab the file and save it to a temp location # first grab the file and save it to a temp location
if self.url: if self.src:
archive_url = self.url archive_url = self.src
else: else:
archive_url = 'https://github.com/%s/%s/archive/%s.tar.gz' % (role_data["github_user"], role_data["github_repo"], target) archive_url = 'https://github.com/%s/%s/archive/%s.tar.gz' % (role_data["github_user"], role_data["github_repo"], target)
self.display.display("- downloading role from %s" % archive_url) self.display.display("- downloading role from %s" % archive_url)
...@@ -256,7 +231,7 @@ class GalaxyRole(object): ...@@ -256,7 +231,7 @@ class GalaxyRole(object):
return False return False
else: else:
try: try:
self.meta_data = yaml.safe_load(role_tar_file.extractfile(meta_file)) self._metadata = yaml.safe_load(role_tar_file.extractfile(meta_file))
except: except:
self.display.error("this role does not appear to have a valid meta/main.yml file.") self.display.error("this role does not appear to have a valid meta/main.yml file.")
return False return False
...@@ -306,7 +281,8 @@ class GalaxyRole(object): ...@@ -306,7 +281,8 @@ class GalaxyRole(object):
self.display.display("- %s was installed successfully" % self.name) self.display.display("- %s was installed successfully" % self.name)
return True return True
def get_spec(self): @property
def spec(self):
""" """
Returns role spec info Returns role spec info
{ {
...@@ -316,40 +292,4 @@ class GalaxyRole(object): ...@@ -316,40 +292,4 @@ class GalaxyRole(object):
'name': 'repo' 'name': 'repo'
} }
""" """
if self.scm is None and self.url is None: return dict(scm=self.scm, src=self.src, version=self.version, name=self.name)
self._read_galaxy_isntall_info()
return dict(scm=self.scm, src=self.url, version=self.version, role_name=self.name)
def _spec_parse(self):
''' creates separated parts of role spec '''
default_role_versions = dict(git='master', hg='tip')
if not self.url and '://' in self.name:
role_spec = self.name.strip()
if role_spec == "" or role_spec.startswith("#"):
return
tokens = [s.strip() for s in role_spec.split(',')]
# assume https://github.com URLs are git+https:// URLs and not tarballs unless they end in '.zip'
if 'github.com/' in tokens[0] and not tokens[0].startswith("git+") and not tokens[0].endswith('.tar.gz'):
tokens[0] = 'git+' + tokens[0]
if '+' in tokens[0]:
(self.scm, self.url) = tokens[0].split('+')
else:
self.scm = None
self.url = tokens[0]
if len(tokens) >= 2:
self.version = tokens[1]
if len(tokens) == 3:
self.name = tokens[2]
else:
self.name = self._repo_url_to_role_name(tokens[0])
if self.scm and not self.version:
self.version = default_role_versions.get(scm, '')
...@@ -180,9 +180,13 @@ if __name__ == '__main__': ...@@ -180,9 +180,13 @@ if __name__ == '__main__':
cli = AdHocCli(sys.argv, display=display) cli = AdHocCli(sys.argv, display=display)
cli.parse() cli.parse()
sys.exit(cli.run()) sys.exit(cli.run())
except AnsibleError as e: except AnsibleOptionsError as e:
cli.parser.print_help()
display.display(str(e), stderr=True, color='red') display.display(str(e), stderr=True, color='red')
sys.exit(1) sys.exit(1)
except AnsibleError as e:
display.display(str(e), stderr=True, color='red')
sys.exit(2)
except KeyboardInterrupt: except KeyboardInterrupt:
display.error("interrupted") display.error("interrupted")
sys.exit(1) sys.exit(4)
...@@ -201,9 +201,14 @@ if __name__ == "__main__": ...@@ -201,9 +201,14 @@ if __name__ == "__main__":
cli = PlaybookCLI(sys.argv, display=display) cli = PlaybookCLI(sys.argv, display=display)
cli.parse() cli.parse()
sys.exit(cli.run()) sys.exit(cli.run())
except AnsibleError as e: except AnsibleOptionsError as e:
cli.parser.print_help()
display.display(str(e), stderr=True, color='red') display.display(str(e), stderr=True, color='red')
sys.exit(1) sys.exit(1)
except AnsibleError as e:
display.display(str(e), stderr=True, color='red')
sys.exit(2)
except KeyboardInterrupt: except KeyboardInterrupt:
display.error("interrupted") display.error("interrupted")
sys.exit(1) sys.exit(4)
...@@ -33,7 +33,7 @@ import os ...@@ -33,7 +33,7 @@ import os
import sys import sys
import traceback import traceback
from ansible.errors import AnsibleError from ansible.errors import AnsibleError, AnsibleOptionsError
from ansible.parsing.vault import VaultEditor from ansible.parsing.vault import VaultEditor
from ansible.utils.cli import CLI from ansible.utils.cli import CLI
from ansible.utils.display import Display from ansible.utils.display import Display
...@@ -142,9 +142,13 @@ if __name__ == "__main__": ...@@ -142,9 +142,13 @@ if __name__ == "__main__":
cli = VaultCli(sys.argv, display=display) cli = VaultCli(sys.argv, display=display)
cli.parse() cli.parse()
sys.exit(cli.run()) sys.exit(cli.run())
except AnsibleError as e: except AnsibleOptionsError as e:
cli.parser.print_help()
display.display(str(e), stderr=True, color='red') display.display(str(e), stderr=True, color='red')
sys.exit(1) sys.exit(1)
except AnsibleError as e:
display.display(str(e), stderr=True, color='red')
sys.exit(2)
except KeyboardInterrupt: except KeyboardInterrupt:
display.error("interrupted") display.error("interrupted")
sys.exit(1) sys.exit(4)
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment