Merge pull request #68 from ed-/root

Mering in ed-'s Root history code.
This commit is contained in:
Tim Simpson 2012-05-03 12:13:00 -07:00
commit 6527d65118
11 changed files with 106 additions and 10 deletions

View File

@ -267,8 +267,9 @@ class ContextMiddleware(openstack_wsgi.Middleware):
def process_request(self, request):
tenant_id = request.headers.get('X-Tenant-Id', None)
auth_tok = request.headers["X-Auth-Token"]
context = rd_context.ReddwarfContext(auth_tok=auth_tok,
auth_tok = request.headers['X-Auth-Token']
user = request.headers.get('X-User', None)
context = rd_context.ReddwarfContext(auth_tok=auth_tok, user=user,
tenant=tenant_id)
request.environ[CONTEXT_KEY] = context

View File

@ -28,6 +28,8 @@ def map(engine, models):
return
orm.mapper(models['instance'], Table('instances', meta, autoload=True))
orm.mapper(models['root_enabled_history'],
Table('root_enabled_history', meta, autoload=True))
orm.mapper(models['service_image'],
Table('service_images', meta, autoload=True))
orm.mapper(models['service_statuses'],

View File

@ -0,0 +1,45 @@
# vim: tabstop=4 shiftwidth=4 softtabstop=4
# Copyright 2012 OpenStack LLC.
# All Rights Reserved.
#
# 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.
from sqlalchemy import ForeignKey
from sqlalchemy.schema import Column
from sqlalchemy.schema import MetaData
from sqlalchemy.schema import UniqueConstraint
from reddwarf.db.sqlalchemy.migrate_repo.schema import create_tables
from reddwarf.db.sqlalchemy.migrate_repo.schema import DateTime
from reddwarf.db.sqlalchemy.migrate_repo.schema import drop_tables
from reddwarf.db.sqlalchemy.migrate_repo.schema import String
from reddwarf.db.sqlalchemy.migrate_repo.schema import Table
meta = MetaData()
root_enabled_history = Table('root_enabled_history', meta,
Column('id', String(36), primary_key=True, nullable=False),
Column('user', String(length=255)),
Column('created', DateTime()),
)
def upgrade(migrate_engine):
meta.bind = migrate_engine
create_tables([root_enabled_history])
def downgrade(migrate_engine):
meta.bind = migrate_engine
drop_tables([root_enabled_history])

View File

@ -15,7 +15,7 @@
# License for the specific language governing permissions and limitations
# under the License.
"""Model classes that form the core of instances functionality."""
"""Model classes that extend the instances functionality for MySQL instances.."""
import logging
@ -88,7 +88,7 @@ class User(object):
@classmethod
def create(cls, context, instance_id, users):
# Load InstanceServiceStatus to verify if its running
# Load InstanceServiceStatus to verify if it's running
load_and_verify(context, instance_id)
create_guest_client(context, instance_id).create_user(users)
@ -106,11 +106,12 @@ class Root(object):
return create_guest_client(context, instance_id).is_root_enabled()
@classmethod
def create(cls, context, instance_id):
def create(cls, context, instance_id, user):
load_and_verify(context, instance_id)
root = create_guest_client(context, instance_id).enable_root()
root_user = guest_models.MySQLUser()
root_user.deserialize(root)
root_history = base_models.RootHistory.create(context, instance_id, user)
return root_user

View File

@ -74,7 +74,8 @@ class RootController(BaseController):
LOG.info(_("Enabling root for instance '%s'") % instance_id)
LOG.info(_("req : '%s'\n\n") % req)
context = req.environ[wsgi.CONTEXT_KEY]
root = models.Root.create(context, instance_id)
user_name = context.user
root = models.Root.create(context, instance_id, user_name)
return wsgi.Result(views.RootCreatedView(root).data(), 200)

View File

@ -19,6 +19,7 @@ import routes
import webob.exc
from reddwarf.common import exception
from reddwarf.common import utils
from reddwarf.common import wsgi
from reddwarf.flavor import models
from reddwarf.flavor import views

View File

@ -81,6 +81,7 @@ class InstanceStatus(object):
BUILD = "BUILD"
FAILED = "FAILED"
SHUTDOWN = "SHUTDOWN"
ERROR = "ERROR"
# If the compute server is in any of these states we can't perform any
@ -473,6 +474,7 @@ def persisted_models():
'instance': DBInstance,
'service_image': ServiceImage,
'service_statuses': InstanceServiceStatus,
'root_enabled_history': RootHistory,
}
@ -550,6 +552,36 @@ class ServiceStatus(object):
return self._description
class RootHistory(ModelBase):
_auto_generated_attrs = ['id']
_data_fields = ['instance_id', 'user', 'created']
_table_name = 'root_enabled_history'
def __init__(self, instance_id, user):
self.id = instance_id
self.user = user
self.created = utils.utcnow()
def save(self):
LOG.debug(_("Saving %s: %s") % (self.__class__.__name__, self.__dict__))
return db.db_api.save(self)
@classmethod
def load(cls, context, instance_id):
history = db.db_api.find_by(cls, id=instance_id)
return history
@classmethod
def create(cls, context, instance_id, user):
history = cls.load(context, instance_id)
if history is not None:
return history
history = RootHistory(instance_id, user)
history.save()
return history
class ServiceStatuses(object):
RUNNING = ServiceStatus(0x01, 'running', 'ACTIVE')
BLOCKED = ServiceStatus(0x02, 'blocked', 'BLOCKED')

View File

@ -198,7 +198,9 @@ class InstanceController(BaseController):
LOG.error(e)
return wsgi.Result(str(e), 404)
# TODO(cp16net): need to set the return code correctly
return wsgi.Result(views.InstanceDetailView(server,
# Adding the root history, if it exists.
history = models.RootHistory.load(context=context, instance_id=id)
return wsgi.Result(views.InstanceDetailView(server, roothistory=history,
add_addresses=self.add_addresses).data(), 200)
def delete(self, req, tenant_id, id):

View File

@ -44,11 +44,18 @@ class InstanceView(object):
class InstanceDetailView(InstanceView):
def __init__(self, instance, add_addresses=False, roothistory=None):
super(InstanceDetailView, self).__init__(instance, add_addresses)
self.roothistory = roothistory
def data(self):
result = super(InstanceDetailView, self).data()
result['instance']['created'] = self.instance.created
result['instance']['flavor'] = self.instance.flavor
result['instance']['updated'] = self.instance.updated
if self.roothistory:
result['instance']['root_enabled_at'] = self.roothistory.created
result['instance']['root_enabled_by'] = self.roothistory.user
return result

View File

@ -54,7 +54,11 @@ class FakeGuest(object):
def enable_root(self):
self.root_was_enabled = True
return self._create_user({"_name":"root", "_password":"12345"})
return self._create_user({
"_name": "root",
"_password": "12345",
"_databases": [],
})
def is_root_enabled(self):
return self.root_was_enabled

View File

@ -341,8 +341,8 @@ if __name__ == '__main__':
hdlr.setFormatter(formatter)
logger.addHandler(hdlr)
logger.setLevel(logging.DEBUG)
# If any argument looks like a test name but doesn't have "reddwarf.tests" in
# front of it, automatically add that so we don't have to type as much
# If any argument looks like a test name but doesn't have "reddwarf.tests"
# in front of it, automatically add that so we don't have to type as much
show_elapsed = True
argv = []
for x in sys.argv: