import libxml2
from urlparse import urlparse
-
# If ../heat/__init__.py exists, add ../ to Python search path, so that
# it will override what happens to be installed in /usr/(local/)lib/python...
possible_topdir = os.path.normpath(os.path.join(os.path.abspath(sys.argv[0]),
fi
#create the schema using sqlalchemy-migrate
-if test $1 == "rpm"; then
- pushd /usr/lib/python2.7/site-packages/heat/db/sqlalchemy
-else
+#if [ $1='rpm' ];
+#then
+# pushd /usr/lib/python2.7/site-packages/heat/db/sqlalchemy
+#else
pushd /usr/lib/python2.7/site-packages/heat-0.0.1-py2.7.egg/heat/db/sqlalchemy/
-fi
+#fi
python migrate_repo/manage.py version_control mysql://heat:heat@localhost/heat migrate_repo
python manage.py upgrade
import socket
import sys
import urlparse
-
import webob
from webob.exc import (HTTPNotFound,
HTTPConflict,
HTTPBadRequest)
-
from heat.common import wsgi
from heat.common import config
from heat import rpc
from heat import context
-
logger = logging.getLogger('heat.api.v1.stacks')
Returns the following information for all stacks:
"""
con = context.get_admin_context()
- stack_list = rpc.call(con, 'engine', {'method': 'list_stacks'})
+ stack_list = rpc.call(con, 'engine',
+ {'method': 'list_stacks',
+ 'args': {'params': dict(req.params)}})
res = {'ListStacksResponse': {'ListStacksResult': {'StackSummaries': [] } } }
summaries = res['ListStacksResponse']['ListStacksResult']['StackSummaries']
stack_list = rpc.call(con, 'engine',
{'method': 'show_stack',
- 'args': {'stack_name': req.params['StackName']}})
+ 'args': {'stack_name': req.params['StackName'],
+ 'params': dict(req.params)}})
res = {'DescribeStacksResult': {'Stacks': [] } }
stacks = res['DescribeStacksResult']['Stacks']
for s in stack_list['stacks']:
res = rpc.call(con, 'engine',
{'method': 'delete_stack',
- 'args': {'stack_name': req.params['StackName']}})
+ 'args': {'stack_name': req.params['StackName'],
+ 'params': dict(req.params)}})
if res == None:
return {'DeleteStackResult': ''}
import json
import logging
import os
-
from heat.common import client as base_client
from heat.common import exception
from heat.cloudformations import *
-
logger = logging.getLogger(__name__)
from heat.openstack.common import cfg
from heat.openstack.common import utils
-
bind_opts = [
cfg.StrOpt('bind_host', default='0.0.0.0'),
cfg.IntOpt('bind_port'),
method = getattr(obj, action)
except AttributeError:
method = getattr(obj, 'default')
-
return method(*args, **kwargs)
def get_action_args(self, request_environment):
d[event['event_id']] = json.dumps(event)
d.close()
-
'''
from heat.openstack.common import utils
-
def configure(conf):
global IMPL
global SQL_CONNECTION
def stack_get(context, stack_id):
- return IMPL.resource_get(context, resource_id)
+ return IMPL.stack_get(context, stack_id)
def stack_get_all(context):
return IMPL.stack_get_all(context)
def stack_create(context, values):
return IMPL.stack_create(context, values)
+def stack_delete(context, stack_name):
+ return IMPL.stack_delete(context, stack_name)
def event_get(context, event_id):
return IMPL.event_get(context, event_id)
from heat.db.sqlalchemy.session import get_session
def model_query(context, *args, **kwargs):
- """Query helper that accounts for context's `read_deleted` field.
-
- :param context: context to query under
+ """
:param session: if present, the session to use
- :param read_deleted: if present, overrides context's read_deleted field.
- :param project_only: if present and context is user-type, then restrict
- query to match the context's project_id.
"""
session = kwargs.get('session') or get_session()
- read_deleted = kwargs.get('read_deleted') or context.read_deleted
- project_only = kwargs.get('project_only')
query = session.query(*args)
- if read_deleted == 'no':
- query = query.filter_by(deleted=False)
- elif read_deleted == 'yes':
- pass # omit the filter to include deleted and active
- elif read_deleted == 'only':
- query = query.filter_by(deleted=True)
- else:
- raise Exception(
- _("Unrecognized read_deleted value '%s'") % read_deleted)
-
- if project_only and is_user_context(context):
- query = query.filter_by(project_id=context.project_id)
-
return query
def raw_template_get(context, template_id):
def stack_get(context, stack_id):
result = model_query(context, models.Stack).\
- filter_by(id=stack_id).first()
-
- if not result:
- raise Exception("stack with id %s not found" % stack_id)
-
+ filter_by(name=stack_id).first()
return result
def stack_get_all(context):
results = model_query(context, models.Stack).all()
-
- if not results:
- raise Exception('no stacks were found')
-
return results
def stack_create(context, values):
stack_ref.update(values)
stack_ref.save()
return stack_ref
+
+def stack_delete(context, stack_name):
+ s = stack_get(context, stack_name)
+ if not s:
+ raise Exception('Attempt to delete a stack with id: %s that does not exist' % stack_name)
+
+ for e in s.events:
+ e.delete()
+ s.delete()
def event_get(context, event_id):
result = model_query(context, models.Event).\
Column('name', String(length=255, convert_unicode=False,
assert_unicode=None,
unicode_error=None, _warn_on_bytestring=False)),
+ Column('raw_template_id', Integer, ForeignKey("raw_template.id"), nullable=False),
)
event = Table(
assert_unicode=None,
unicode_error=None,
_warn_on_bytestring=False)),
+ Column('parsed_template_id', Integer, ForeignKey("parsed_template.id"), nullable=False),
)
parsedtemplate = Table(
'parsed_template', meta,
Column('id', Integer, primary_key=True),
- Column('resource_id', Integer, ForeignKey("resource.id"),\
- nullable=False),
+ Column('raw_template_id', Integer, ForeignKey("raw_template.id"), nullable=False),
Column('template', Text()),
)
- tables = [rawtemplate, stack, event, resource, parsedtemplate]
+ tables = [rawtemplate, stack, event, parsedtemplate, resource]
for table in tables:
try:
table.create()
event = Table('event', meta, autoload=True)
resource = Table('resource', meta, autoload=True)
parsedtemplate = Table('parsed_template', meta, autoload=True)
+ stack = Table('stack', meta, autoload=True)
- for table in (rawtemplate, event, stack, parsedtemplate, resource):
+ for table in (event, stack, resource, parsedtemplate, rawtemplate):
table.drop()
"""
from sqlalchemy import *
+from sqlalchemy.orm import relationship, backref
from sqlalchemy.exc import IntegrityError
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.schema import ForeignKeyConstraint
-
+from sqlalchemy import types as types
+from json import dumps, loads
from nova import utils
from heat.db.sqlalchemy.session import get_session
BASE = declarative_base()
+class Json(types.TypeDecorator, types.MutableType):
+ impl=types.Text
+
+ def process_bind_param(self, value, dialect):
+ return dumps(value)
+
+ def process_result_value(self, value, dialect):
+ return loads(value)
+
class HeatBase(object):
"""Base class for Heat Models."""
__table_args__ = {'mysql_engine': 'InnoDB'}
__tablename__ = 'raw_template'
id = Column(Integer, primary_key=True)
- template = Text()
+ template = Column(Json)
+ parsed_template = relationship("ParsedTemplate",\
+ uselist=False, backref="raw_template", cascade="all, delete", passive_deletes=True)
class ParsedTemplate(BASE, HeatBase):
"""Represents a parsed template."""
__tablename__ = 'parsed_template'
id = Column(Integer, primary_key=True)
- resource_id = Column('resource_id', Integer)
+ template = Column(Json)
+ raw_template_id = Column(Integer, ForeignKey('raw_template.id'),\
+ nullable=False)
class Stack(BASE, HeatBase):
"""Represents an generated by the heat engine."""
__tablename__ = 'stack'
id = Column(Integer, primary_key=True)
- name = Column(String)
+ name = Column(String, unique=True)
+ raw_template_id = Column(Integer, ForeignKey('raw_template.id'),\
+ nullable=False)
+ raw_template = relationship(RawTemplate,
+ backref=backref('stack'), cascade="all, delete", passive_deletes=True)
class Event(BASE, HeatBase):
"""Represents an event generated by the heat engine."""
__tablename__ = 'event'
id = Column(Integer, primary_key=True)
- stack_id = Column(Integer)
+ stack_id = Column(Integer, ForeignKey('stack.id'),\
+ nullable=False)
+ stack = relationship(Stack,
+ backref=backref('events'), cascade="all, delete", passive_deletes=True)
+
name = Column(String)
class Resource(BASE, HeatBase):
id = Column(Integer, primary_key=True)
state = Column(String)
state_description = Column('state_description', String)
+ parsed_template_id = Column(Integer, ForeignKey('parsed_template.id'),\
+ nullable=False)
+ parsed_template = relationship(ParsedTemplate,
+ backref=backref('resources'))
+
import time
import traceback
import logging
-
-from eventlet import greenthread
-
-import heat.context
-from heat.common import exception
+import webob
from heat import manager
-from heat.openstack.common import cfg
-from heat import rpc
from heat.engine import parser
from heat.db import api as db_api
-
logger = logging.getLogger('heat.engine.manager')
-stack_db = {}
-
class EngineManager(manager.Manager):
"""Manages the running instances from creation to destruction."""
"""Load configuration options and connect to the hypervisor."""
pass
- def list_stacks(self, context):
+ def list_stacks(self, context, params):
logger.info('context is %s' % context)
res = {'stacks': [] }
- for s in stack_db:
+ stacks = db_api.stack_get_all(None)
+ for s in stacks:
+ ps = parser.Stack(s.name, s.raw_template.template, params)
mem = {}
- mem['stack_id'] = s
- mem['stack_name'] = s
- mem['created_at'] = 'now'
+ mem['stack_id'] = s.id
+ mem['stack_name'] = s.name
+ mem['created_at'] = str(s.created_at)
try:
- mem['template_description'] = stack_db[s].t['Description']
- mem['stack_status'] = stack_db[s].t['StackStatus']
+ mem['template_description'] = s.template.description
+ mem['stack_status'] = ps.t['StackStatus']
except:
mem['template_description'] = 'No description'
mem['stack_status'] = 'unknown'
res['stacks'].append(mem)
return res
-
- def show_stack(self, context, stack_name):
-
+
+ def show_stack(self, context, stack_name, params):
res = {'stacks': [] }
- if stack_db.has_key(stack_name):
+ s = db_api.stack_get(None, id)
+ if s:
+ ps = parser.Stack(s.name, s.raw_template.template, params)
mem = {}
- mem['stack_id'] = stack_name
- mem['stack_name'] = stack_name
- mem['creation_at'] = 'TODO'
- mem['updated_at'] = 'TODO'
+ mem['stack_id'] = s.id
+ mem['stack_name'] = s.name
+ mem['creation_at'] = s.created_at
+ mem['updated_at'] = s.updated_at
mem['NotificationARNs'] = 'TODO'
- mem['Outputs'] = stack_db[stack_name].get_outputs()
- mem['Parameters'] = stack_db[stack_name].t['Parameters']
+ mem['Outputs'] = ps.get_outputs()
+ mem['Parameters'] = ps.t['Parameters']
mem['StackStatusReason'] = 'TODO'
mem['TimeoutInMinutes'] = 'TODO'
try:
- mem['TemplateDescription'] = stack_db[stack_name].t['Description']
- mem['StackStatus'] = stack_db[stack_name].t['StackStatus']
+ mem['TemplateDescription'] = ps.t['Description']
+ mem['StackStatus'] = ps.t['StackStatus']
except:
mem['TemplateDescription'] = 'No description'
mem['StackStatus'] = 'unknown'
res['stacks'].append(mem)
return res
-
+
def create_stack(self, context, stack_name, template, params):
- if stack_db.has_key(stack_name):
- return {'Error': 'Stack already exists with that name.'}
-
logger.info('template is %s' % template)
- stack_db[stack_name] = parser.Stack(stack_name, template, params)
- stack_db[stack_name].create()
+ if db_api.stack_get(None, stack_name):
+ return {'Error': 'Stack already exists with that name.'}
- return {'stack': {'id': stack_name}}
+ stack = parser.Stack(stack_name, template, params)
+ rt = {}
+ rt['template'] = template
+ new_rt = db_api.raw_template_create(None, rt)
+ s = {}
+ s['name'] = stack_name
+ s['raw_template_id'] = new_rt.id
+ new_s = db_api.stack_create(None, s)
+ stack.id = new_s.id
+ stack.start()
+
+ return {'stack': {'id': new_s.id, 'name': new_s.name,\
+ 'created_at': new_s.created_at}}
def validate_template(self, req, body=None):
return res
- def delete_stack(self, context, stack_name):
- if not stack_db.has_key(stack_name):
- return {'Error': 'No stack by that name'}
+ def delete_stack(self, context, stack_name, params):
+ s = db_api.stack_get(None, stack_name)
+ if not s:
+ return {'Error': 'No stack by that name'}
logger.info('deleting stack %s' % stack_name)
- stack_db[stack_name].delete()
- del stack_db[stack_name]
+
+ ps = parser.Stack(s.name, s.raw_template.template, params)
+ ps.stop()
+ db_api.stack_delete(None, stack_name)
return None
def list_events(self, context, stack_name):
from heat.common import exception
from heat.db import api as db_api
+from heat.common.config import HeatEngineConfigOpts
logger = logging.getLogger('heat.engine.resources')
ev['stack_id'] = self.stack.id
ev['stack_name'] = self.stack.name
ev['resource_status'] = new_state
+ ev['name'] = new_state
ev['resource_status_reason'] = reason
ev['resource_type'] = self.t['Type']
ev['resource_properties'] = self.t['Properties']
- new_stack = db_api.stack_create(None, ev)
- ev['stack_id'] = new_stack.id
db_api.event_create(None, ev)
self.state = new_state
self.state_set(self.CREATE_FAILED)
def delete(self):
-
- if self.state == self.DELETE_IN_PROGRESS or self.state == self.DELETE_COMPLETE:
- return
- self.state_set(self.DELETE_IN_PROGRESS)
- Resource.delete(self)
-
- if self.instance_id == None:
- self.state_set(self.DELETE_COMPLETE)
- return
-
+ Resource.stop(self)
server = self.nova().servers.get(self.instance_id)
server.delete()
self.instance_id = None
- self.state_set(self.DELETE_COMPLETE)
-
def insert_package_and_services(self, r, new_script):