| # Licensed to the Apache Software Foundation (ASF) under one or more |
| # contributor license agreements. See the NOTICE file distributed with |
| # this work for additional information regarding copyright ownership. |
| # The ASF licenses this file to You under the Apache License, Version 2.0 |
| # (the "License"); you may not use this file except in compliance with |
| # the License. You may obtain a copy of the License at |
| # |
| # http://www.apache.org/licenses/LICENSE-2.0 |
| # |
| # Unless required by applicable law or agreed to in writing, software |
| # distributed under the License is distributed on an "AS IS" BASIS, |
| # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| # See the License for the specific language governing permissions and |
| # limitations under the License. |
| |
| """ |
| Loading mechanism for service templates. |
| """ |
| |
| import os |
| from urlparse import urlparse |
| |
| from . import csar |
| from . import utils |
| from .exceptions import AriaCliError |
| from ..utils import archive as archive_utils |
| |
| |
| def get(source, service_template_filename): |
| """ |
| Get a source and return a path to the main service template file |
| |
| The behavior based on then source argument content is: |
| |
| * local ``.yaml`` file: return the file |
| * local archive (``.csar``, ``.zip``, ``.tar``, ``.tar.gz``, and ``.tar.bz2``): extract it |
| locally and return path service template file |
| * URL: download and get service template from downloaded archive |
| * GitHub repo: download and get service template from downloaded archive |
| |
| :param source: path/URL/GitHub repo to archive/service-template file |
| :type source: basestring |
| :param service_template_filename: path to service template if source is a non-CSAR archive |
| with CSAR archives, this is read from the metadata file) |
| :type service_template_filename: basestring |
| :return: path to main service template file |
| :rtype: basestring |
| """ |
| if urlparse(source).scheme: |
| downloaded_file = utils.download_file(source) |
| return _get_service_template_file_from_archive( |
| downloaded_file, service_template_filename) |
| elif os.path.isfile(source): |
| if _is_archive(source): |
| return _get_service_template_file_from_archive(source, service_template_filename) |
| else: |
| # Maybe check if yaml. |
| return os.path.abspath(source) |
| elif len(source.split('/')) == 2: |
| url = _map_to_github_url(source) |
| downloaded_file = utils.download_file(url) |
| return _get_service_template_file_from_archive( |
| downloaded_file, service_template_filename) |
| else: |
| raise AriaCliError( |
| 'You must provide either a path to a local file, a remote URL ' |
| 'or a GitHub `organization/repository[:tag/branch]`') |
| |
| |
| def _get_service_template_file_from_archive(archive, service_template_filename): |
| """ |
| Extract archive to temporary location and get path to service template file. |
| |
| :param archive: path to archive file |
| :type archive: basestring |
| :param service_template_filename: path to service template file relative to archive |
| :type service_template_filename: basestring |
| :return: absolute path to service template file |
| :rtype: basestring |
| |
| """ |
| if csar.is_csar_archive(archive): |
| service_template_file = _extract_csar_archive(archive) |
| else: |
| extract_directory = archive_utils.extract_archive(archive) |
| service_template_dir = os.path.join( |
| extract_directory, |
| os.listdir(extract_directory)[0], |
| ) |
| service_template_file = os.path.join(service_template_dir, service_template_filename) |
| |
| if not os.path.isfile(service_template_file): |
| raise AriaCliError( |
| 'Could not find `{0}`. Please provide the name of the main ' |
| 'service template file by using the `-n/--service-template-filename` flag' |
| .format(service_template_filename)) |
| return service_template_file |
| |
| |
| def _map_to_github_url(source): |
| """ |
| Returns a path to a downloaded GitHub archive. |
| |
| :param source: GitHub repo: ``org/repo[:tag/branch]`` |
| :type source: basestring |
| :return: URL to the archive file for the given repo in GitHub |
| :rtype: basestring |
| |
| """ |
| source_parts = source.split(':', 1) |
| repo = source_parts[0] |
| tag = source_parts[1] if len(source_parts) == 2 else 'master' |
| url = 'https://github.com/{0}/archive/{1}.tar.gz'.format(repo, tag) |
| return url |
| |
| |
| def _is_archive(source): |
| return archive_utils.is_archive(source) or csar.is_csar_archive(source) |
| |
| |
| def _extract_csar_archive(archive): |
| reader = csar.read(source=archive) |
| main_service_template_file_name = os.path.basename(reader.entry_definitions) |
| return os.path.join(reader.destination, |
| main_service_template_file_name) |