Persisting resources

This commit is contained in:
Chris Alfonso 2012-04-10 16:58:45 -04:00
parent c8868921fa
commit f2f4aff187
8 changed files with 75 additions and 19 deletions

View File

@ -22,7 +22,6 @@ import logging
import os import os
from heat.common import client as base_client from heat.common import client as base_client
from heat.common import exception from heat.common import exception
import pdb
from heat.cloudformations import * from heat.cloudformations import *
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
@ -60,7 +59,6 @@ class V1Client(base_client.BaseClient):
params = self._extract_params(kwargs, SUPPORTED_PARAMS) params = self._extract_params(kwargs, SUPPORTED_PARAMS)
self._insert_common_parameters(params) self._insert_common_parameters(params)
res = self.do_request("POST", "/CreateStack", params=params) res = self.do_request("POST", "/CreateStack", params=params)
pdb.set_trace()
data = json.loads(res.read()) data = json.loads(res.read())
return data return data

View File

@ -64,6 +64,11 @@ def resource_get_all(context):
def resource_create(context, values): def resource_create(context, values):
return IMPL.resource_create(context, values) return IMPL.resource_create(context, values)
def resource_get_all_by_stack(context, stack_id):
return IMPL.resource_get_all_by_stack(context, stack_id)
def resource_get_by_name_and_stack(context, resource_name, stack_id):
return IMPL.resource_get_by_name_and_stack(context, resource_name, stack_id)
def stack_get(context, stack_id): def stack_get(context, stack_id):
return IMPL.stack_get(context, stack_id) return IMPL.stack_get(context, stack_id)

View File

@ -84,6 +84,13 @@ def resource_get(context, resource_id):
return result return result
def resource_get_by_name_and_stack(context, resource_name, stack_id):
result = model_query(context, models.Resource).\
filter_by(name=resource_name).\
filter_by(stack_id=stack_id).first()
return result
def resource_get_all(context): def resource_get_all(context):
results = model_query(context, models.Resource).all() results = model_query(context, models.Resource).all()
@ -98,6 +105,15 @@ def resource_create(context, values):
resource_ref.save() resource_ref.save()
return resource_ref return resource_ref
def resource_get_all_by_stack(context, stack_id):
results = model_query(context, models.Resource).\
filter_by(stack_id=stack_id).all()
if not results:
raise Exception("no resources for stack_id %s were found" % stack_id)
return results
def stack_get(context, stack_id): def stack_get(context, stack_id):
result = model_query(context, models.Stack).\ result = model_query(context, models.Stack).\
filter_by(name=stack_id).first() filter_by(name=stack_id).first()
@ -118,8 +134,8 @@ def stack_delete(context, stack_name):
if not s: if not s:
raise Exception('Attempt to delete a stack with id: %s that does not exist' % stack_name) raise Exception('Attempt to delete a stack with id: %s that does not exist' % stack_name)
for e in s.events: #for e in s.events:
e.delete() # e.delete()
s.delete() s.delete()
def event_get(context, event_id): def event_get(context, event_id):

View File

@ -38,17 +38,26 @@ def upgrade(migrate_engine):
resource = Table( resource = Table(
'resource', meta, 'resource', meta,
Column('id', Integer, primary_key=True), Column('id', Integer, primary_key=True),
Column('instance_id', String(length=255, convert_unicode=False, Column('nova_instance', String(length=255, convert_unicode=False,
assert_unicode=None, assert_unicode=None,
unicode_error=None, _warn_on_bytestring=False)), unicode_error=None, _warn_on_bytestring=False)),
Column('name', String(length=255, convert_unicode=False,
assert_unicode=None,
unicode_error=None, _warn_on_bytestring=False)),
Column('created_at', DateTime(timezone=False)), Column('created_at', DateTime(timezone=False)),
Column('updated_at', DateTime(timezone=False)), Column('updated_at', DateTime(timezone=False)),
Column('state', Integer()), Column('state', String(length=255, convert_unicode=False,
assert_unicode=None,
unicode_error=None,
_warn_on_bytestring=False)),
Column('state_description', String(length=255, convert_unicode=False, Column('state_description', String(length=255, convert_unicode=False,
assert_unicode=None, assert_unicode=None,
unicode_error=None, unicode_error=None,
_warn_on_bytestring=False)), _warn_on_bytestring=False)),
Column('parsed_template_id', Integer, ForeignKey("parsed_template.id"), nullable=False), Column('parsed_template_id', Integer, ForeignKey("parsed_template.id"), nullable=True),
Column('stack_id', Integer, ForeignKey("stack.id"), nullable=False),
Column('depends_on', Integer),
) )
parsedtemplate = Table( parsedtemplate = Table(

View File

@ -16,7 +16,7 @@ SQLAlchemy models for heat data.
""" """
from sqlalchemy import * from sqlalchemy import *
from sqlalchemy.orm import relationship, backref from sqlalchemy.orm import relationship, backref, object_mapper
from sqlalchemy.exc import IntegrityError from sqlalchemy.exc import IntegrityError
from sqlalchemy.ext.declarative import declarative_base from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.schema import ForeignKeyConstraint from sqlalchemy.schema import ForeignKeyConstraint
@ -143,10 +143,17 @@ class Resource(BASE, HeatBase):
__tablename__ = 'resource' __tablename__ = 'resource'
id = Column(Integer, primary_key=True) id = Column(Integer, primary_key=True)
state = Column(String) state = Column('state', String)
name = Column('name', String, nullable=False)
nova_instance = Column('nova_instance', String)
state_description = Column('state_description', String) state_description = Column('state_description', String)
parsed_template_id = Column(Integer, ForeignKey('parsed_template.id'),\ parsed_template_id = Column(Integer, ForeignKey('parsed_template.id'),\
nullable=False) nullable=True)
parsed_template = relationship(ParsedTemplate, parsed_template = relationship(ParsedTemplate,
backref=backref('resources')) backref=backref('resources'))
stack_id = Column(Integer, ForeignKey('stack.id'),\
nullable=False)
stack = relationship(Stack, backref=backref('resources'), cascade="all, delete", passive_deletes=True)
depends_on = Column(Integer)

View File

@ -113,16 +113,19 @@ class EngineManager(manager.Manager):
return res return res
def delete_stack(self, context, stack_name, params): def delete_stack(self, context, stack_name, params):
s = db_api.stack_get(None, stack_name) st = db_api.stack_get(None, stack_name)
if not s: if not st:
return {'Error': 'No stack by that name'} return {'Error': 'No stack by that name'}
logger.info('deleting stack %s' % stack_name) logger.info('deleting stack %s' % stack_name)
ps = parser.Stack(s.name, s.raw_template.template, params) rt = db_api.raw_template_get(None, st.raw_template_id)
ps.stop() ps = parser.Stack(st.name, rt.template, params)
resources = db_api.resource_get_all_by_stack(None, st.id)
for r in ps.resources:
ps.resources[r].stop()
db_api.stack_delete(None, stack_name) db_api.stack_delete(None, stack_name)
return None return list_stacks(context, stack_name, params)
def list_events(self, context, stack_name): def list_events(self, context, stack_name):
return db_api.event_get_all_by_stack(None, stack_name) return db_api.event_get_all_by_stack(None, stack_name)

View File

@ -18,10 +18,11 @@ import json
import logging import logging
from heat.engine import resources from heat.engine import resources
from heat.db import api as db_api
logger = logging.getLogger('heat.engine.parser') logger = logging.getLogger('heat.engine.parser')
class Stack: class Stack(object):
def __init__(self, stack_name, template, parms=None): def __init__(self, stack_name, template, parms=None):
self.id = 0 self.id = 0
self.t = template self.t = template
@ -53,6 +54,10 @@ class Stack:
else: else:
self.creds = parms['KeyStoneCreds'] self.creds = parms['KeyStoneCreds']
stack = db_api.stack_get(None, stack_name)
if stack:
self.id = stack.id
self.resources = {} self.resources = {}
for r in self.t['Resources']: for r in self.t['Resources']:
type = self.t['Resources'][r]['Type'] type = self.t['Resources'][r]['Type']
@ -155,9 +160,11 @@ class Stack:
''' '''
order = self.get_create_order() order = self.get_create_order()
order.reverse() order.reverse()
for r in order: for r in order:
try: try:
self.resources[r].delete() self.resources[r].delete()
db_api.resource_get(None, self.resources[r].id).delete()
except Exception as ex: except Exception as ex:
logger.error('delete: %s' % str(ex)) logger.error('delete: %s' % str(ex))
self.resources[r].state_set(self.resources[r].DELETE_FAILED, str(ex)) self.resources[r].state_set(self.resources[r].DELETE_FAILED, str(ex))

View File

@ -46,6 +46,11 @@ class Resource(object):
self.stack = stack self.stack = stack
self.name = name self.name = name
self.instance_id = None self.instance_id = None
resource = db_api.resource_get_by_name_and_stack(None, name, stack.id)
if resource:
self.instance_id = resource.nova_instance
self.stack_id = stack.id
self._nova = {} self._nova = {}
if not self.t.has_key('Properties'): if not self.t.has_key('Properties'):
# make a dummy entry to prevent having to check all over the # make a dummy entry to prevent having to check all over the
@ -403,7 +408,13 @@ class Instance(Resource):
if server.status == 'ACTIVE': if server.status == 'ACTIVE':
self.state_set(self.CREATE_COMPLETE) self.state_set(self.CREATE_COMPLETE)
self.instance_id = server.id self.instance_id = server.id
rs = {}
rs['state'] = 'ACTIVE'
rs['nova_instance'] = self.instance_id
rs['stack_id'] = self.stack.id
rs['name'] = self.name
new_rs = db_api.resource_create(None, rs)
self.id = new_rs.id
# just record the first ipaddress # just record the first ipaddress
for n in server.networks: for n in server.networks:
self.ipaddress = server.networks[n][0] self.ipaddress = server.networks[n][0]