@require_admin_context
def volume_detached(context, volume_id, attachment_id):
 remain_attachment = True
 session = get_session()
 with session.begin():
  try:
   attachment = _attachment_get(context, attachment_id, session=session)
  except exception.VolumeAttachmentNotFound:
   attachment_updates = None
   attachment = None
  if attachment:
   now = timeutils.utcnow()
   attachment_updates = {'attach_status': fields.VolumeAttachStatus.DETACHED, 'detach_time': now, 'deleted': True, 'deleted_at': now, 'updated_at': literal_column('updated_at')}
   attachment.update(attachment_updates)
   attachment.save(session=session)
   del attachment_updates['updated_at']
  attachment_list = None
  volume_ref = _volume_get(context, volume_id, session=session)
  volume_updates = {'updated_at': literal_column('updated_at')}
  if (not volume_ref.volume_attachment):
   attachment_list = volume_attachment_get_all_by_volume_id(context, volume_id, session=session)
   remain_attachment = False
  if (attachment_list and (len(attachment_list) > 0)):
   remain_attachment = True
  if (not remain_attachment):
   if (((not volume_ref.migration_status) and (not (volume_ref.status == 'uploading'))) or (volume_ref.migration_status in ('success', 'error'))):
    volume_updates['status'] = 'available'
   volume_updates['attach_status'] = fields.VolumeAttachStatus.DETACHED
  else:
   volume_updates['status'] = 'in-use'
   volume_updates['attach_status'] = fields.VolumeAttachStatus.ATTACHED
  volume_ref.update(volume_updates)
  volume_ref.save(session=session)
  del volume_updates['updated_at']
  return (volume_updates, attachment_updates)

@ require_admin_context def volume_detached ( context , volume_id , attachment_id ) : remain_attachment = True session = get_session ( ) with session . begin ( ) : try : attachment = _attachment_get ( context , attachment_id , session = session ) except exception . VolumeAttachmentNotFound : attachment_updates = None attachment = None if attachment : now = timeutils . utcnow ( ) attachment_updates = { 'attach_status' : fields . VolumeAttachStatus . DETACHED , 'detach_time' : now , 'deleted' : True , 'deleted_at' : now , 'updated_at' : literal_column ( 'updated_at' ) } attachment . update ( attachment_updates ) attachment . save ( session = session ) del attachment_updates [ 'updated_at' ] attachment_list = None volume_ref = _volume_get ( context , volume_id , session = session ) volume_updates = { 'updated_at' : literal_column ( 'updated_at' ) } if ( not volume_ref . volume_attachment ) : attachment_list = volume_attachment_get_all_by_volume_id ( context , volume_id , session = session ) remain_attachment = False if ( attachment_list and ( len ( attachment_list ) > 0 ) ) : remain_attachment = True if ( not remain_attachment ) : if ( ( ( not volume_ref . migration_status ) and ( not ( volume_ref . status == 'uploading' ) ) ) or ( volume_ref . migration_status in ( 'success' , 'error' ) ) ) : volume_updates [ 'status' ] = 'available' volume_updates [ 'attach_status' ] = fields . VolumeAttachStatus . DETACHED else : volume_updates [ 'status' ] = 'in-use' volume_updates [ 'attach_status' ] = fields . VolumeAttachStatus . ATTACHED volume_ref . update ( volume_updates ) volume_ref . save ( session = session ) del volume_updates [ 'updated_at' ] return ( volume_updates , attachment_updates )
ensure that a volume is set as detached .