vnf-update: update attributes

Change-Id: Id5b11643bf28e977c52caccadd5d574132d72c24
This commit is contained in:
Isaku Yamahata 2015-05-13 18:54:18 -07:00
parent 87b8d0fb4a
commit af4cf6c6e5
6 changed files with 65 additions and 18 deletions

View File

@ -605,13 +605,24 @@ class ServiceResourcePluginDb(servicevm.ServiceVMPluginBase,
context, device_id, _ACTIVE_UPDATE, constants.PENDING_UPDATE) context, device_id, _ACTIVE_UPDATE, constants.PENDING_UPDATE)
return self._make_device_dict(device_db) return self._make_device_dict(device_db)
def _update_device_post(self, context, device_id, new_status): def _update_device_post(self, context, device_id, new_status,
new_device_dict=None):
with context.session.begin(subtransactions=True): with context.session.begin(subtransactions=True):
(self._model_query(context, Device). (self._model_query(context, Device).
filter(Device.id == device_id). filter(Device.id == device_id).
filter(Device.status == constants.PENDING_UPDATE). filter(Device.status == constants.PENDING_UPDATE).
update({'status': new_status})) update({'status': new_status}))
dev_attrs = new_device_dict.get('attributes', {})
(context.session.query(DeviceAttribute).
filter(DeviceAttribute.device_id == device_id).
filter(~DeviceAttribute.key.in_(dev_attrs.keys())).
delete(synchronize_session='fetch'))
for (key, value) in dev_attrs.items():
self._device_attribute_update_or_create(context, device_id,
key, value)
def _delete_device_pre(self, context, device_id): def _delete_device_pre(self, context, device_id):
with context.session.begin(subtransactions=True): with context.session.begin(subtransactions=True):
# TODO(yamahata): race. keep others from inserting new binding # TODO(yamahata): race. keep others from inserting new binding

View File

@ -22,6 +22,7 @@
# TODO(yamahata): once unittests are impletemted, move this there # TODO(yamahata): once unittests are impletemted, move this there
import uuid import uuid
from tacker.common import log
from tacker.openstack.common import log as logging from tacker.openstack.common import log as logging
from tacker.vm.drivers import abstract_driver from tacker.vm.drivers import abstract_driver
@ -46,28 +47,30 @@ class DeviceNoop(abstract_driver.DeviceAbstractDriver):
def get_description(self): def get_description(self):
return 'Nuetron Device Noop driver' return 'Nuetron Device Noop driver'
@log.log
def create(self, **kwargs): def create(self, **kwargs):
LOG.debug(_('create %s'), kwargs)
instance_id = str(uuid.uuid4()) instance_id = str(uuid.uuid4())
self._instances.add(instance_id) self._instances.add(instance_id)
return instance_id return instance_id
@log.log
def create_wait(self, plugin, context, device_dict, device_id): def create_wait(self, plugin, context, device_dict, device_id):
LOG.debug(_('create_wait %s'), device_id) pass
def update(self, plugin, context, device_id, **kwargs): @log.log
LOG.debug(_('update device_id %(devcie_id)s kwargs %(kwargs)s'), def update(self, plugin, context, device_id, device_dict, device):
{'device_id': device_id, 'kwargs': kwargs})
if device_id not in self._instances: if device_id not in self._instances:
LOG.debug(_('not found')) LOG.debug(_('not found'))
raise ValueError('No instance %s' % device_id) raise ValueError('No instance %s' % device_id)
@log.log
def update_wait(self, plugin, context, device_id): def update_wait(self, plugin, context, device_id):
LOG.debug(_('update_wait %s'), device_id) pass
@log.log
def delete(self, plugin, context, device_id): def delete(self, plugin, context, device_id):
LOG.debug(_('delete %s'), device_id)
self._instances.remove(device_id) self._instances.remove(device_id)
@log.log
def delete_wait(self, plugin, context, device_id): def delete_wait(self, plugin, context, device_id):
LOG.debug(_('delete_wait %s'), device_id) pass

View File

@ -58,7 +58,9 @@ class DeviceAbstractDriver(extensions.PluginInterface):
"""wait for device creation to complete.""" """wait for device creation to complete."""
@abc.abstractmethod @abc.abstractmethod
def update(self, plugin, context, device): def update(self, plugin, context, device_id, device_dict, device):
# device_dict: old device_dict to be updated
# device: update with device dict
pass pass
@abc.abstractmethod @abc.abstractmethod

View File

@ -266,10 +266,39 @@ class DeviceHeat(abstract_driver.DeviceAbstractDriver):
# work around. mgmt suports Only single vm for now. # work around. mgmt suports Only single vm for now.
device_dict['mgmt_url'] = mgmt_ips[0] device_dict['mgmt_url'] = mgmt_ips[0]
def update(self, plugin, context, device): @log.log
# do nothing but checking if the stack exists at the moment def update(self, plugin, context, device_id, device_dict, device):
# checking if the stack exists at the moment
heatclient_ = HeatClient(context) heatclient_ = HeatClient(context)
heatclient_.get(device['id']) heatclient_.get(device_id)
# update config attribute
config_yaml = device_dict.get('attributes', {}).get('config', '')
update_yaml = device['device'].get('attributes', {}).get('config', '')
LOG.debug('yaml orig %(orig)s update %(update)s',
{'orig': config_yaml, 'update': update_yaml})
config_dict = yaml.load(config_yaml) or {}
update_dict = yaml.load(update_yaml)
if not update_dict:
return
@log.log
def deep_update(orig_dict, new_dict):
for key, value in new_dict.items():
if isinstance(value, dict):
if key in orig_dict and isinstance(orig_dict[key], dict):
deep_update(orig_dict[key], value)
continue
orig_dict[key] = value
LOG.debug('dict orig %(orig)s update %(update)s',
{'orig': config_dict, 'update': update_dict})
deep_update(config_dict, update_dict)
LOG.debug('dict new %(new)s update %(update)s',
{'new': config_dict, 'update': update_dict})
new_yaml = yaml.dump(config_dict)
device_dict.setdefault('attributes', {})['config'] = new_yaml
def update_wait(self, plugin, context, device_id): def update_wait(self, plugin, context, device_id):
# do nothing but checking if the stack exists at the moment # do nothing but checking if the stack exists at the moment

View File

@ -240,9 +240,8 @@ class DeviceNova(abstract_driver.DeviceAbstractDriver):
if status == 'ERROR': if status == 'ERROR':
raise RuntimeError(_("creation of server %s faild") % device_id) raise RuntimeError(_("creation of server %s faild") % device_id)
def update(self, plugin, context, device): def update(self, plugin, context, device_id, device_dict, device):
# do nothing but checking if the instance exists at the moment # do nothing but checking if the instance exists at the moment
device_id = device['id']
nova = self._nova_client() nova = self._nova_client()
nova.servers.get(device_id) nova.servers.get(device_id)

View File

@ -339,7 +339,9 @@ class ServiceVMPlugin(vm_db.ServiceResourcePluginDb, ServiceVMMgmtMixin):
new_status = constants.ERROR new_status = constants.ERROR
device_dict['status'] = new_status device_dict['status'] = new_status
self.mgmt_update_post(context, device_dict) self.mgmt_update_post(context, device_dict)
self._update_device_post(context, device_dict['id'], new_status)
self._update_device_post(context, device_dict['id'],
new_status, device_dict)
def update_device(self, context, device_id, device): def update_device(self, context, device_id, device):
device_dict = self._update_device_pre(context, device_id) device_dict = self._update_device_pre(context, device_id)
@ -348,8 +350,9 @@ class ServiceVMPlugin(vm_db.ServiceResourcePluginDb, ServiceVMMgmtMixin):
try: try:
self.mgmt_update_pre(context, device_dict) self.mgmt_update_pre(context, device_dict)
self._device_manager.invoke(driver_name, 'update', plugin=self, self._device_manager.invoke(
context=context, device_id=instance_id) driver_name, 'update', plugin=self, context=context,
device_id=instance_id, device_dict=device_dict, device=device)
except Exception: except Exception:
with excutils.save_and_reraise_exception(): with excutils.save_and_reraise_exception():
device_dict['status'] = constants.ERROR device_dict['status'] = constants.ERROR