91fd92c136
`Scope` keyword is introduced to declare method visibility. For that package format version is incremented to 1.4. `Scope` attribute can have two possible values: * `Session` - regular method that is accessible from anywhere in the current execution session. This is the default if the attribute is omitted; * `Public` - accessible anywhere, both within the session and from outside through the API call (i.e. it is an action in current terminology). It allows to declare static actions with the following syntax: methodName: Usage: Static Scope: Public For backward compatibility `Usage: Action` remains valid and acceptable but it is deprecated for format versions > 1.3. An exception is raised if both `Usage: Action` and `Scope: Session` are specified. Change-Id: I5a6d664d017d5ea99a5159d7eb2e111143c7b0a3 Partially-implements: blueprint static-actions
109 lines
3.7 KiB
Python
109 lines
3.7 KiB
Python
# Copyright (c) 2014 Mirantis, Inc.
|
|
#
|
|
# Licensed 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 contextlib
|
|
import os
|
|
import shutil
|
|
import sys
|
|
import tempfile
|
|
import zipfile
|
|
|
|
import six
|
|
import yaml
|
|
|
|
from murano.common.plugins import package_types_loader
|
|
import murano.packages.exceptions as e
|
|
import murano.packages.hot_package
|
|
import murano.packages.mpl_package
|
|
|
|
|
|
PLUGIN_LOADER = None
|
|
|
|
|
|
def get_plugin_loader():
|
|
global PLUGIN_LOADER
|
|
|
|
if PLUGIN_LOADER is None:
|
|
PLUGIN_LOADER = package_types_loader.PluginLoader()
|
|
for runtime_version in ('1.0', '1.1', '1.2', '1.3', '1.4'):
|
|
format_string = 'MuranoPL/' + runtime_version
|
|
PLUGIN_LOADER.register_format(
|
|
format_string, murano.packages.mpl_package.MuranoPlPackage)
|
|
PLUGIN_LOADER.register_format(
|
|
'Heat.HOT/1.0', murano.packages.hot_package.HotPackage)
|
|
return PLUGIN_LOADER
|
|
|
|
|
|
@contextlib.contextmanager
|
|
def load_from_file(archive_path, target_dir=None, drop_dir=False):
|
|
if not os.path.isfile(archive_path):
|
|
raise e.PackageLoadError('Unable to find package file')
|
|
created = False
|
|
if not target_dir:
|
|
target_dir = tempfile.mkdtemp()
|
|
created = True
|
|
elif not os.path.exists(target_dir):
|
|
os.makedirs(target_dir)
|
|
created = True
|
|
else:
|
|
if os.listdir(target_dir):
|
|
raise e.PackageLoadError('Target directory is not empty')
|
|
|
|
try:
|
|
if not zipfile.is_zipfile(archive_path):
|
|
raise e.PackageFormatError("Uploaded file {0} is not a "
|
|
"zip archive".format(archive_path))
|
|
package = zipfile.ZipFile(archive_path)
|
|
package.extractall(path=target_dir)
|
|
yield load_from_dir(target_dir)
|
|
except ValueError as err:
|
|
raise e.PackageLoadError("Couldn't load package from file: "
|
|
"{0}".format(err))
|
|
finally:
|
|
if drop_dir:
|
|
if created:
|
|
shutil.rmtree(target_dir)
|
|
else:
|
|
for f in os.listdir(target_dir):
|
|
os.unlink(os.path.join(target_dir, f))
|
|
|
|
|
|
def load_from_dir(source_directory, filename='manifest.yaml'):
|
|
if not os.path.isdir(source_directory) or not os.path.exists(
|
|
source_directory):
|
|
raise e.PackageLoadError('Invalid package directory')
|
|
full_path = os.path.join(source_directory, filename)
|
|
if not os.path.isfile(full_path):
|
|
raise e.PackageLoadError('Unable to find package manifest')
|
|
|
|
try:
|
|
with open(full_path) as stream:
|
|
content = yaml.safe_load(stream)
|
|
except Exception as ex:
|
|
trace = sys.exc_info()[2]
|
|
six.reraise(
|
|
e.PackageLoadError,
|
|
e.PackageLoadError("Unable to load due to '{0}'".format(ex)),
|
|
trace)
|
|
else:
|
|
format_spec = str(content.get('Format') or 'MuranoPL/1.0')
|
|
if format_spec[0].isdigit():
|
|
format_spec = 'MuranoPL/' + format_spec
|
|
plugin_loader = get_plugin_loader()
|
|
handler = plugin_loader.get_package_handler(format_spec)
|
|
if handler is None:
|
|
raise e.PackageFormatError(
|
|
'Unsupported format {0}'.format(format_spec))
|
|
return handler(source_directory, content)
|