

@base.remotable
def save(self, expected_vm_state=None, expected_task_state=None, admin_state_reset=False):
    'Save updates to this instance\n\n        Column-wise updates will be made based on the result of\n        self.what_changed(). If expected_task_state is provided,\n        it will be checked against the in-database copy of the\n        instance before updates are made.\n\n        :param:context: Security context\n        :param:expected_task_state: Optional tuple of valid task states\n        for the instance to be in\n        :param:expected_vm_state: Optional tuple of valid vm states\n        for the instance to be in\n        :param admin_state_reset: True if admin API is forcing setting\n        of task_state/vm_state\n\n        '
    self._sync_cells = (not self._cell_name_blocks_sync())
    context = self._context
    cell_type = cells_opts.get_cell_type()
    if (cell_type is not None):
        stale_instance = self.obj_clone()
    cells_update_from_api = ((cell_type == 'api') and self.cell_name and self._sync_cells)
    if cells_update_from_api:

        def _handle_cell_update_from_api():
            cells_api = cells_rpcapi.CellsAPI()
            cells_api.instance_update_from_api(context, stale_instance, expected_vm_state, expected_task_state, admin_state_reset)
    updates = {
        
    }
    changes = self.obj_what_changed()
    for field in self.fields:
        if (self.obj_attr_is_set(field) and isinstance(expected_vm_state.fields[field], fields.ObjectField)):
            try:
                getattr(self, ('_save_%s' % field))(context)
            except AttributeError:
                LOG.exception(_LE('No save handler for %s'), field, instance=self)
            except db_exc.DBReferenceError as exp:
                if (exp.key != 'instance_uuid'):
                    raise
                raise exception.InstanceNotFound(instance_id=self.uuid)
        elif (field in changes):
            if ((field == 'cell_name') and (self[field] is not None) and self[field].startswith(cells_utils.BLOCK_SYNC_FLAG)):
                updates[field] = self[field].replace(cells_utils.BLOCK_SYNC_FLAG, '', 1)
            else:
                updates[field] = self[field]
    if (not updates):
        if cells_update_from_api:
            _handle_cell_update_from_api()
        return
    if ('cleaned' in updates):
        if updates['cleaned']:
            updates['cleaned'] = 1
        else:
            updates['cleaned'] = 0
    if (expected_task_state is not None):
        updates['expected_task_state'] = expected_task_state
    if (expected_vm_state is not None):
        updates['expected_vm_state'] = expected_vm_state
    expected_attrs = [attr for attr in _INSTANCE_OPTIONAL_JOINED_FIELDS if self.obj_attr_is_set(attr)]
    if ('pci_devices' in expected_attrs):
        expected_attrs.remove('pci_devices')
    if ('system_metadata' not in expected_attrs):
        expected_attrs.append('system_metadata')
        expected_attrs.append('flavor')
    (old_ref, inst_ref) = db.instance_update_and_get_original(context, self.uuid, updates, columns_to_join=_expected_cols(expected_attrs))
    self._from_db_object(context, self, inst_ref, expected_attrs=expected_attrs)
    if cells_update_from_api:
        _handle_cell_update_from_api()
    elif (cell_type == 'compute'):
        if self._sync_cells:
            cells_api = cells_rpcapi.CellsAPI()
            cells_api.instance_update_at_top(context, stale_instance)

    def _notify():
        new_ref = self.obj_clone()
        notifications.send_update(context, old_ref, new_ref)
    if (not self._sync_cells):
        _notify = (lambda : None)
    _notify()
    self.obj_reset_changes()

dataset/ETHPy150Open BU-NU-CLOUD-SP16/Trusted-Platform-Module-nova/nova/objects/instance.py Instance.save/VarMisuse@166/481 `self`->`expected_vm_state`