예제 #1
0
def new(__context, __type_name, __owner=None, __object_name=None, __extra=None, **parameters):
    object_store = helpers.get_object_store(__context)
    new_context = __context.create_child_context()
    for key, value in parameters.iteritems():
        if helpers.is_keyword(key):
            new_context[key] = value
    return __type_name.murano_class.new(__owner, object_store, name=__object_name)(new_context, **parameters)
예제 #2
0
 def transform(self):
     value = self.value
     object_store = helpers.get_object_store()
     if isinstance(self.value, contracts.ObjRef):
         value = self.value.object_id
     if value is None:
         return None
     if isinstance(value, dsl_types.MuranoObject):
         obj = value
     elif isinstance(value, dsl_types.MuranoObjectInterface):
         obj = value.object
     elif isinstance(value, utils.MappingType):
         obj = object_store.load(value,
                                 self.owner,
                                 context=self.root_context,
                                 default_type=self.default_type,
                                 scope_type=self.calling_type)
     elif isinstance(value, str):
         obj = object_store.get(value)
         if obj is None:
             if not object_store.initializing:
                 raise exceptions.NoObjectFoundError(value)
             else:
                 return contracts.ObjRef(value)
     else:
         raise exceptions.ContractViolationException(
             'Value {0} cannot be represented as class {1}'.format(
                 helpers.format_scalar(value), self.type))
     self.value = obj
     return self.validate()
예제 #3
0
파일: meta.py 프로젝트: AleptNamrata/murano
    def __init__(self, definition, target, scope_type):
        scope_type = weakref.ref(scope_type)
        definition = helpers.list_value(definition)
        factories = []
        used_types = set()
        for d in definition:
            if isinstance(d, dict):
                if len(d) != 1:
                    raise ValueError('Invalid Meta format')
                name = next(iter(d.keys()))
                props = d[name] or {}
            else:
                name = d
                props = {}
            type_obj = helpers.resolve_type(name, scope_type())
            if type_obj.usage != dsl_types.ClassUsages.Meta:
                raise ValueError('Only Meta classes can be attached')
            if target not in type_obj.targets:
                raise ValueError(
                    u'Meta class {} is not applicable here'.format(
                        type_obj.name))
            if type_obj in used_types and (
                    type_obj.cardinality != dsl_types.MetaCardinality.Many):
                raise ValueError('Cannot attach several Meta instances '
                                 'with cardinality One')

            used_types.add(type_obj)
            factory_maker = lambda template: \
                lambda context: helpers.get_object_store().load(
                    template, owner=None,
                    context=context, scope_type=scope_type())

            factories.append(factory_maker({type_obj: props}))
        self._meta_factories = factories
        self._meta = None
예제 #4
0
파일: meta.py 프로젝트: lexplua/murano
 def instantiate(context):
     obj = helpers.get_object_store().load(
         template,
         owner=None,
         context=context,
         scope_type=declaring_type)
     obj.declaring_type = declaring_type
     return obj
예제 #5
0
        def template(engine,
                     value,
                     type_,
                     exclude_properties=None,
                     default_type=None,
                     version_spec=None):
            object_store = helpers.get_object_store()
            passkey = None
            if not default_type:
                default_type = type_
            murano_class = type_.type
            if value is None:
                return None
            if isinstance(value, dsl_types.MuranoObject):
                obj = value
            elif isinstance(value, dsl_types.MuranoObjectInterface):
                obj = value.object
            elif isinstance(value, utils.MappingType):
                passkey = utils.create_marker('<Contract Passkey>')
                if exclude_properties:
                    parsed = helpers.parse_object_definition(
                        value, calling_type, context)
                    props = dsl.to_mutable(parsed['properties'], engine)
                    for p in exclude_properties:
                        helpers.patch_dict(props, p, passkey)
                    parsed['properties'] = props
                    value = helpers.assemble_object_definition(parsed)
                with helpers.thread_local_attribute(
                        constants.TL_CONTRACT_PASSKEY, passkey):
                    with helpers.thread_local_attribute(
                            constants.TL_OBJECTS_DRY_RUN, True):
                        obj = object_store.load(value,
                                                owner,
                                                context=context,
                                                default_type=default_type,
                                                scope_type=calling_type)
            else:
                raise exceptions.ContractViolationException(
                    'Value {0} cannot be represented as class {1}'.format(
                        format_scalar(value), type_))
            if not helpers.is_instance_of(
                    obj, murano_class.name, version_spec
                    or helpers.get_type(root_context)):
                raise exceptions.ContractViolationException(
                    'Object of type {0} is not compatible with '
                    'requested type {1}'.format(obj.type.name, type_))

            with helpers.thread_local_attribute(constants.TL_CONTRACT_PASSKEY,
                                                passkey):
                result = serializer.serialize(obj.real_this,
                                              object_store.executor,
                                              dsl_types.DumpTypes.Mixed)
                if exclude_properties:
                    for p in exclude_properties:
                        helpers.patch_dict(result, p, utils.NO_VALUE)
                return result
예제 #6
0
파일: dsl.py 프로젝트: AleptNamrata/murano
def spawn(func, *args, **kwargs):
    context = helpers.get_context()
    object_store = helpers.get_object_store()

    def wrapper():
        with helpers.with_object_store(object_store):
            with helpers.contextual(context):
                return func(*args, **kwargs)

    return eventlet.spawn(wrapper)
예제 #7
0
def spawn(func, *args, **kwargs):
    context = helpers.get_context()
    object_store = helpers.get_object_store()

    def wrapper():
        with helpers.with_object_store(object_store):
            with helpers.contextual(context):
                return func(*args, **kwargs)

    return eventlet.spawn(wrapper)
예제 #8
0
def new(__context, __type_name, __owner=None, __object_name=None, __extra=None,
        **parameters):
    object_store = helpers.get_object_store(__context)
    executor = helpers.get_executor(__context)
    new_context = __context.create_child_context()
    for key, value in six.iteritems(parameters):
        if utils.is_keyword(key):
            new_context[key] = value
    return __type_name.type.new(
        __owner, object_store, executor, name=__object_name)(
        new_context, **parameters)
예제 #9
0
 def load_dependencies(self, dependencies):
     self._destruction_dependencies = []
     if not dependencies:
         return
     destruction_dependencies = dependencies.get('onDestruction', [])
     object_store = helpers.get_object_store()
     for record in destruction_dependencies:
         subscriber_id = record['subscriber']
         subscriber = object_store.get(subscriber_id)
         if not subscriber:
             continue
         garbage_collector.GarbageCollector.subscribe_destruction(
             self, subscriber, record.get('handler'))
예제 #10
0
def new(__context, __type_name, __owner=None, __object_name=None, __extra=None,
        **parameters):

    data = {
        __type_name: parameters,
        'name': __object_name
    }
    for key, value in six.iteritems(__extra or {}):
        if key.startswith('_'):
            data[key] = value

    object_store = helpers.get_object_store()
    return object_store.load(data, __owner, context=__context,
                             scope_type=helpers.get_names_scope(__context))
예제 #11
0
 def finalize(self):
     if self.value is None:
         return None
     object_store = helpers.get_object_store()
     passkey = getattr(self.value, '__passkey__', None)
     with helpers.thread_local_attribute(constants.TL_CONTRACT_PASSKEY,
                                         passkey):
         result = serializer.serialize(self.value.real_this,
                                       object_store.executor,
                                       dsl_types.DumpTypes.Mixed)
         if self.exclude_properties:
             for p in self.exclude_properties:
                 helpers.patch_dict(result, p, utils.NO_VALUE)
         return result
예제 #12
0
def new(__context,
        __type_name,
        __owner=None,
        __object_name=None,
        __extra=None,
        **parameters):
    object_store = helpers.get_object_store(__context)
    new_context = __context.create_child_context()
    for key, value in parameters.iteritems():
        if helpers.is_keyword(key):
            new_context[key] = value
    return __type_name.murano_class.new(__owner,
                                        object_store,
                                        name=__object_name)(new_context,
                                                            **parameters)
예제 #13
0
    def _push(self, object_store=None):
        template = copy.deepcopy(self._template)
        s_template = token_sanitizer.TokenSanitizer().sanitize(template)
        LOG.debug(
            'Pushing: {template}'.format(template=json.dumps(s_template)))
        object_store = object_store or helpers.get_object_store()
        while True:
            try:
                with helpers.with_object_store(object_store):
                    current_status = self._get_status()
                    resources = template.get('Resources') or template.get(
                        'resources')
                    if current_status == 'NOT_FOUND':
                        if resources is not None:
                            token_client = self._get_token_client()
                            token_client.stacks.create(
                                stack_name=self._name,
                                parameters=self._parameters,
                                template=template,
                                files=self._files,
                                environment=self._hot_environment,
                                disable_rollback=True,
                                tags=self._tags)

                            self._wait_state(
                                lambda status: status == 'CREATE_COMPLETE')
                    else:
                        if resources is not None:
                            self._client.stacks.update(
                                stack_id=self._name,
                                parameters=self._parameters,
                                files=self._files,
                                environment=self._hot_environment,
                                template=template,
                                disable_rollback=True,
                                tags=self._tags)
                            self._wait_state(
                                lambda status: status == 'UPDATE_COMPLETE',
                                True)
                        else:
                            self.delete()
            except heat_exc.HTTPConflict as e:
                LOG.warning('Conflicting operation: {msg}'.format(msg=e))
                eventlet.sleep(3)
            else:
                break

        self._applied = self._template == template
예제 #14
0
def new(__context,
        __type_name,
        __owner=None,
        __object_name=None,
        __extra=None,
        **parameters):

    data = {__type_name: parameters, 'name': __object_name}
    for key, value in (__extra or {}).items():
        if key.startswith('_'):
            data[key] = value

    object_store = helpers.get_object_store()
    return object_store.load(data,
                             __owner,
                             context=__context,
                             scope_type=helpers.get_names_scope(__context))
예제 #15
0
def _new(context, name, *args):
    murano_class = helpers.get_type(context)
    name = murano_class.namespace_resolver.resolve_name(name)
    parameters = {}
    arg_values = [t() for t in args]
    if len(arg_values) == 1 and isinstance(arg_values[0], types.DictionaryType):
        parameters = arg_values[0]
    elif len(arg_values) > 0:
        for p in arg_values:
            if not isinstance(p, types.TupleType) or not isinstance(p[0], types.StringType):
                raise SyntaxError()
            parameters[p[0]] = p[1]

    object_store = helpers.get_object_store(context)
    class_loader = helpers.get_class_loader(context)
    new_context = yaql.context.Context(parent_context=context)
    for key, value in parameters.iteritems():
        new_context.set_data(value, key)
    return class_loader.get_class(name).new(None, object_store, new_context, parameters=parameters)
예제 #16
0
 def class_(value, name, default_name=None, version_spec=None):
     object_store = helpers.get_object_store()
     if not default_name:
         default_name = name
     murano_class = name.type
     if isinstance(value, TypeScheme.ObjRef):
         value = value.object_id
     if value is None:
         return None
     if isinstance(value, dsl_types.MuranoObject):
         obj = value
     elif isinstance(value, dsl_types.MuranoObjectInterface):
         obj = value.object
     elif isinstance(value, utils.MappingType):
         obj = object_store.load(value,
                                 owner,
                                 context=root_context,
                                 default_type=default_name,
                                 scope_type=calling_type)
     elif isinstance(value, six.string_types):
         obj = object_store.get(value)
         if obj is None:
             if not object_store.initializing:
                 raise exceptions.NoObjectFoundError(value)
             else:
                 return TypeScheme.ObjRef(value)
     else:
         raise exceptions.ContractViolationException(
             'Value {0} cannot be represented as class {1}'.format(
                 format_scalar(value), name))
     if not helpers.is_instance_of(
             obj, murano_class.name, version_spec
             or helpers.get_type(root_context)):
         raise exceptions.ContractViolationException(
             'Object of type {0} is not compatible with '
             'requested type {1}'.format(obj.type.name, murano_class))
     return obj
예제 #17
0
 def transform(self):
     object_store = helpers.get_object_store()
     if self.value is None:
         return None
     if isinstance(self.value, dsl_types.MuranoObject):
         obj = self.value
     elif isinstance(self.value, dsl_types.MuranoObjectInterface):
         obj = self.value.object
     elif isinstance(self.value, utils.MappingType):
         passkey = utils.create_marker('<Contract Passkey>')
         if self.exclude_properties:
             parsed = helpers.parse_object_definition(
                 self.value, self.calling_type, self.context)
             props = dsl.to_mutable(parsed['properties'], self.engine)
             for p in self.exclude_properties:
                 helpers.patch_dict(props, p, passkey)
             parsed['properties'] = props
             value = helpers.assemble_object_definition(parsed)
         else:
             value = self.value
         with helpers.thread_local_attribute(constants.TL_CONTRACT_PASSKEY,
                                             passkey):
             with helpers.thread_local_attribute(
                     constants.TL_OBJECTS_DRY_RUN, True):
                 obj = object_store.load(value,
                                         self.owner,
                                         context=self.context,
                                         default_type=self.default_type,
                                         scope_type=self.calling_type)
                 obj.__passkey__ = passkey
     else:
         raise exceptions.ContractViolationException(
             'Value {0} cannot be represented as class {1}'.format(
                 helpers.format_scalar(self.value), self.type))
     self.value = obj
     return self.validate()
예제 #18
0
def _new(context, name, *args):
    murano_class = helpers.get_type(context)
    name = murano_class.namespace_resolver.resolve_name(name)
    parameters = {}
    arg_values = [t() for t in args]
    if len(arg_values) == 1 and isinstance(arg_values[0],
                                           types.DictionaryType):
        parameters = arg_values[0]
    elif len(arg_values) > 0:
        for p in arg_values:
            if not isinstance(p, types.TupleType) or \
                    not isinstance(p[0], types.StringType):
                raise SyntaxError()
            parameters[p[0]] = p[1]

    object_store = helpers.get_object_store(context)
    class_loader = helpers.get_class_loader(context)
    new_context = yaql.context.Context(parent_context=context)
    for key, value in parameters.iteritems():
        new_context.set_data(value, key)
    return class_loader.get_class(name).new(None,
                                            object_store,
                                            new_context,
                                            parameters=parameters)
예제 #19
0
파일: dsl.py 프로젝트: AleptNamrata/murano
 def __init__(self, mpl_object, object_store=None):
     self.__object = mpl_object
     self.__object_store = object_store or helpers.get_object_store()
예제 #20
0
def new(properties, owner=None, type=None):
    context = helpers.get_context()
    return helpers.get_object_store().load(
        properties, owner, type or get_this(context).type, context=context)
예제 #21
0
    def initialize(self, context, params):
        if self.__initialized:
            return
        context = context.create_child_context()
        context[constants.CTX_ALLOW_PROPERTY_WRITES] = True
        object_store = helpers.get_object_store()
        for property_name in self.__type.properties:
            spec = self.__type.properties[property_name]
            if spec.usage == dsl_types.PropertyUsages.Config:
                if property_name in self.__config:
                    property_value = self.__config[property_name]
                else:
                    property_value = dsl.NO_VALUE
                self.set_property(property_name, property_value)

        init = self.type.methods.get('.init')
        used_names = set()
        names = set(self.__type.properties)
        if init:
            names.update(six.iterkeys(init.arguments_scheme))
        last_errors = len(names)
        init_args = {}
        while True:
            errors = 0
            for property_name in names:
                if init and property_name in init.arguments_scheme:
                    spec = init.arguments_scheme[property_name]
                    is_init_arg = True
                else:
                    spec = self.__type.properties[property_name]
                    is_init_arg = False

                if property_name in used_names:
                    continue
                if spec.usage in (dsl_types.PropertyUsages.Config,
                                  dsl_types.PropertyUsages.Static):
                    used_names.add(property_name)
                    continue
                if spec.usage == dsl_types.PropertyUsages.Runtime:
                    if not spec.has_default:
                        used_names.add(property_name)
                        continue
                    property_value = dsl.NO_VALUE
                else:
                    property_value = params.get(property_name, dsl.NO_VALUE)
                try:
                    if is_init_arg:
                        init_args[property_name] = property_value
                    else:
                        self.set_property(
                            property_name, property_value, context)
                    used_names.add(property_name)
                except exceptions.UninitializedPropertyAccessError:
                    errors += 1
                except exceptions.ContractViolationException:
                    if spec.usage != dsl_types.PropertyUsages.Runtime:
                        raise
            if not errors:
                break
            if errors >= last_errors:
                raise exceptions.CircularExpressionDependenciesError()
            last_errors = errors

        if ((object_store is None or not object_store.initializing) and
                self.__extension is None):
            method = self.type.methods.get('__init__')
            if method:
                filtered_params = yaql_integration.filter_parameters(
                    method.body, **params)

                self.__extension = method.invoke(
                    self, filtered_params[0], filtered_params[1], context)

        for parent in self.__parents.values():
            parent.initialize(context, params)

        if not object_store.initializing and init:
            context[constants.CTX_ARGUMENT_OWNER] = self.real_this
            init.invoke(self.real_this, (), init_args,
                        context.create_child_context())
            self.__initialized = True
예제 #22
0
 def __init__(self, mpl_object):
     self._object = mpl_object
     self._object_store = helpers.get_object_store()
예제 #23
0
def new_from_model(context, model, owner=None):
    object_store = helpers.get_object_store()
    return object_store.load(model,
                             owner,
                             context=context,
                             scope_type=helpers.get_names_scope(context))
예제 #24
0
def new_from_model(context, model, owner=None):
    object_store = helpers.get_object_store()
    return object_store.load(model, owner, context=context,
                             scope_type=helpers.get_names_scope(context))
예제 #25
0
 def is_doomed(object_):
     return helpers.get_object_store().is_doomed(object_)
예제 #26
0
    def initialize(self, context, params, used_names=None):
        context = context.create_child_context()
        context[constants.CTX_ALLOW_PROPERTY_WRITES] = True
        object_store = helpers.get_object_store()
        for property_name in self.type.properties:
            spec = self.type.properties[property_name]
            if spec.usage == dsl_types.PropertyUsages.Config:
                if property_name in self._config:
                    property_value = self._config[property_name]
                else:
                    property_value = dsl.NO_VALUE
                self.set_property(property_name,
                                  property_value,
                                  dry_run=self._initialized)

        init = self.type.methods.get('.init')
        used_names = used_names or set()
        names = set(self.type.properties)
        if init:
            names.update(init.arguments_scheme.keys())
        last_errors = len(names)
        init_args = {}
        while True:
            errors = 0
            for property_name in names:
                if init and property_name in init.arguments_scheme:
                    spec = init.arguments_scheme[property_name]
                    is_init_arg = True
                else:
                    spec = self.type.properties[property_name]
                    is_init_arg = False

                if property_name in used_names:
                    continue
                if spec.usage in (dsl_types.PropertyUsages.Config,
                                  dsl_types.PropertyUsages.Static):
                    used_names.add(property_name)
                    continue
                if spec.usage == dsl_types.PropertyUsages.Runtime:
                    if not spec.has_default:
                        used_names.add(property_name)
                        continue
                    property_value = dsl.NO_VALUE
                else:
                    property_value = params.get(property_name, dsl.NO_VALUE)
                try:
                    if is_init_arg:
                        init_args[property_name] = property_value
                    else:
                        self.set_property(property_name,
                                          property_value,
                                          context,
                                          dry_run=self._initialized)
                    used_names.add(property_name)
                except exceptions.UninitializedPropertyAccessError:
                    errors += 1
                except exceptions.ContractViolationException:
                    if spec.usage != dsl_types.PropertyUsages.Runtime:
                        raise
            if not errors:
                break
            if errors >= last_errors:
                raise exceptions.CircularExpressionDependenciesError()
            last_errors = errors

        if (not object_store.initializing and self._extension is None
                and not self._initialized and not self._destroyed
                and not helpers.is_objects_dry_run_mode()):
            method = self.type.methods.get('__init__')
            if method:
                filtered_params = yaql_integration.filter_parameters(
                    method.body, **params)
                yield lambda: method.invoke(self, filtered_params[0],
                                            filtered_params[1], context)

        for parent in self._parents.values():
            for t in parent.initialize(context, params, used_names):
                yield t

        def run_init():
            if init:
                context[constants.CTX_ARGUMENT_OWNER] = self.real_this
                init.invoke(self.real_this, (), init_args,
                            context.create_child_context())
            self._initialized = True

        if (not object_store.initializing
                and not helpers.is_objects_dry_run_mode()
                and not self._initialized and not self._destroyed):
            yield run_init
예제 #27
0
class HeatStack(object):
    def __init__(self, name, description=None, region_name=None):
        self._name = name
        self._template = None
        self._parameters = {}
        self._files = {}
        self._hot_environment = ''
        self._applied = True
        self._description = description
        self._last_stack_timestamps = (None, None)
        self._tags = ''
        self._region_name = region_name
        self._push_thread = None

    def _is_push_thread_alive(self):
        return self._push_thread is not None and not self._push_thread.dead

    def _kill_push_thread(self):
        if self._is_push_thread_alive():
            self._push_thread.cancel()
            self._wait_push_thread()

    def _wait_push_thread(self):
        if not self._is_push_thread_alive():
            return
        self._push_thread.wait()

    @staticmethod
    def _create_client(session, region_name):
        parameters = auth_utils.get_session_client_parameters(
            service_type='orchestration',
            region=region_name,
            conf=CONF.heat,
            session=session)
        return hclient.Client('1', **parameters)

    @property
    def _client(self):
        return self._get_client(self._region_name)

    @staticmethod
    @session_local_storage.execution_session_memoize
    def _get_client(region_name):
        session = auth_utils.get_client_session(conf=CONF.heat)
        return HeatStack._create_client(session, region_name)

    def _get_token_client(self):
        ks_session = auth_utils.get_token_client_session(conf=CONF.heat)
        return self._create_client(ks_session, self._region_name)

    def current(self):
        if self._template is not None:
            return self._template
        try:
            stack_info = self._client.stacks.get(stack_id=self._name)
            template = self._client.stacks.template(stack_id='{0}/{1}'.format(
                stack_info.stack_name, stack_info.id))
            self._template = template
            self._parameters.update(
                HeatStack._remove_system_params(stack_info.parameters))
            self._applied = True
            return self._template.copy()
        except heat_exc.HTTPNotFound:
            self._applied = True
            self._template = {}
            self._parameters.clear()
            return {}

    def parameters(self):
        self.current()
        return self._parameters.copy()

    def reload(self):
        self._template = None
        self._parameters.clear()
        return self.current()

    def set_template(self, template):
        self._template = template
        self._parameters.clear()
        self._applied = False

    def set_parameters(self, parameters):
        self._parameters = parameters
        self._applied = False

    def set_files(self, files):
        self._files = files
        self._applied = False

    def set_hot_environment(self, hot_environment):
        self._hot_environment = hot_environment
        self._applied = False

    def update_template(self, template):
        template_version = template.get('heat_template_version',
                                        HEAT_TEMPLATE_VERSION)
        if template_version != HEAT_TEMPLATE_VERSION:
            err_msg = ("Currently only heat_template_version %s "
                       "is supported." % HEAT_TEMPLATE_VERSION)
            raise HeatStackError(err_msg)
        current = self.current()
        self._template = helpers.merge_dicts(self._template, template)
        self._applied = self._template == current and self._applied

    @staticmethod
    def _remove_system_params(parameters):
        return dict((k, v) for k, v in six.iteritems(parameters)
                    if not k.startswith('OS::'))

    def _get_status(self):
        status = [None]

        def status_func(state_value):
            status[0] = state_value
            return True

        self._wait_state(status_func)
        return status[0]

    def _wait_state(self, status_func, wait_progress=False):
        tries = 4
        delay = 1
        while tries > 0:
            while True:
                try:
                    stack_info = self._client.stacks.get(stack_id=self._name)
                    status = stack_info.stack_status
                    tries = 4
                    delay = 1
                except heat_exc.HTTPNotFound:
                    stack_info = None
                    status = 'NOT_FOUND'
                except Exception:
                    tries -= 1
                    delay *= 2
                    if not tries:
                        raise
                    eventlet.sleep(delay)
                    break

                if 'IN_PROGRESS' in status:
                    eventlet.sleep(2)
                    continue

                last_stack_timestamps = self._last_stack_timestamps
                self._last_stack_timestamps = (None, None) if not stack_info \
                    else(stack_info.creation_time, stack_info.updated_time)

                if (wait_progress and last_stack_timestamps
                        == self._last_stack_timestamps
                        and last_stack_timestamps != (None, None)):
                    eventlet.sleep(2)
                    continue

                if not status_func(status):
                    reason = ': {0}'.format(
                        stack_info.stack_status_reason) if stack_info else ''
                    raise EnvironmentError(
                        "Unexpected stack state {0}{1}".format(status, reason))

                try:
                    return dict([(t['output_key'], t['output_value'])
                                 for t in stack_info.outputs])
                except Exception:
                    return {}
        return {}

    def output(self):
        self._wait_push_thread()
        return self._wait_state(lambda status: True)

    def _push(self, object_store=None):
        template = copy.deepcopy(self._template)
        LOG.debug('Pushing: {template}'.format(template=json.dumps(template)))
        object_store = object_store or helpers.get_object_store()
        while True:
            try:
                with helpers.with_object_store(object_store):
                    current_status = self._get_status()
                    resources = template.get('Resources') or template.get(
                        'resources')
                    if current_status == 'NOT_FOUND':
                        if resources is not None:
                            token_client = self._get_token_client()
                            token_client.stacks.create(
                                stack_name=self._name,
                                parameters=self._parameters,
                                template=template,
                                files=self._files,
                                environment=self._hot_environment,
                                disable_rollback=True,
                                tags=self._tags)

                            self._wait_state(
                                lambda status: status == 'CREATE_COMPLETE')
                    else:
                        if resources is not None:
                            self._client.stacks.update(
                                stack_id=self._name,
                                parameters=self._parameters,
                                files=self._files,
                                environment=self._hot_environment,
                                template=template,
                                disable_rollback=True,
                                tags=self._tags)
                            self._wait_state(
                                lambda status: status == 'UPDATE_COMPLETE',
                                True)
                        else:
                            self.delete()
            except heat_exc.HTTPConflict as e:
                LOG.warning('Conflicting operation: {msg}'.format(msg=e))
                eventlet.sleep(3)
            else:
                break

        self._applied = self._template == template

    def push(self, async=False):
        if self._applied or self._template is None:
            return

        self._tags = ','.join(CONF.heat.stack_tags)
        if 'heat_template_version' not in self._template:
            self._template['heat_template_version'] = HEAT_TEMPLATE_VERSION

        if 'description' not in self._template and self._description:
            self._template['description'] = self._description

        self._kill_push_thread()
        if async:
            if self._push_thread is None:

                def cleanup():
                    try:
                        self._wait_push_thread()
                    finally:
                        self._push_thread = None

                dsl.get_execution_session().on_session_finish(cleanup)

            self._push_thread =\
                eventlet.greenthread.spawn_after(
                    1, self._push, helpers.get_object_store())
        else:
            self._push()
예제 #28
0
 def __init__(self, mpl_object, object_store=None):
     self.__object = mpl_object
     self.__object_store = object_store or helpers.get_object_store()