| # 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. |
| |
| 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: |
| 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 |
| |
| Supported archive types are: csar, zip, tar, tar.gz and tar.bz2 |
| |
| :param source: Path/URL/github repo to archive/service-template file |
| :type source: str |
| :param service_template_filename: Path to service template (if source is an archive [but |
| not a csar archive - with csars archives, this is read from the metadata file]) |
| :type service_template_filename: str |
| :return: Path to main service template file |
| :rtype: str |
| """ |
| 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: str |
| :param service_template_filename: Path to service template file relative to archive |
| :type service_template_filename: str |
| :return: Absolute path to service template file |
| :rtype: str |
| |
| """ |
| 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 in the format of `org/repo[:tag/branch]`. |
| :type source: str |
| :return: URL to the archive file for the given repo in github |
| :rtype: str |
| |
| """ |
| 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) |