2
2
import logging
3
3
import os
4
4
import pickle
5
+ import shutil
5
6
import tarfile
6
7
import uuid
7
8
from datetime import timedelta
@@ -382,7 +383,8 @@ def _create_storage_medium(self):
382
383
383
384
if storage_type == TAPE :
384
385
slot = TapeSlot .objects .filter (status = 20 , storage_medium__isnull = True ,
385
- medium_id__startswith = self .target ).exclude (medium_id__exact = '' ).first ()
386
+ medium_id__startswith = self .target
387
+ ).exclude (medium_id__exact = '' ).natural_sort ().first ()
386
388
if slot is None :
387
389
raise ValueError ("No tape available for allocation" )
388
390
medium = StorageMedium .objects .create (medium_id = slot .medium_id , storage_target = self , status = 20 ,
@@ -669,12 +671,13 @@ def deactivate(self) -> None:
669
671
def mark_as_full (self ):
670
672
logger = logging .getLogger ('essarch.storage.models' )
671
673
logger .debug ('Marking storage medium as full: "{}"' .format (str (self .pk )))
674
+ logger .info ('Storage medium is full, start to verify: "{}"' .format (self .medium_id ))
672
675
objs = self .storage .annotate (
673
676
content_location_value_int = Cast ('content_location_value' , models .IntegerField ())
674
677
).order_by ('content_location_value_int' )
675
678
676
679
if objs .count () > 3 :
677
- objs = [objs .first (), objs [objs .count () / 2 ], objs .last ()]
680
+ objs = [objs .first (), objs [int ( objs .count () / 2 ) ], objs .last ()]
678
681
679
682
try :
680
683
for obj in objs :
@@ -684,11 +687,15 @@ def mark_as_full(self):
684
687
logger .exception ('Failed to verify storage medium: "{}"' .format (str (self .pk )))
685
688
raise
686
689
else :
690
+ verifydir = Path .objects .get (entity = 'verify' ).value
691
+ tmppath = os .path .join (verifydir , self .storage_target .target )
692
+ shutil .rmtree (tmppath )
687
693
self .status = 30
688
694
storage_backend = self .storage_target .get_storage_backend ()
689
695
storage_backend .post_mark_as_full (self )
690
696
finally :
691
697
self .save (update_fields = ['status' ])
698
+ logger .info ('Storage medium is full, content verified success: "{}"' .format (self .medium_id ))
692
699
693
700
class Meta :
694
701
permissions = (
@@ -985,7 +992,7 @@ def verify(self):
985
992
drive .last_change = timezone .now ()
986
993
drive .save (update_fields = ['last_change' ])
987
994
988
- filename = os .path .join (tmppath , self .ip .object_identifier_value + '.tar' ),
995
+ filename = os .path .join (tmppath , self .ip .object_identifier_value + '.tar' )
989
996
algorithm = self .ip .get_message_digest_algorithm_display ()
990
997
options = {'expected' : self .ip .message_digest , 'algorithm' : algorithm }
991
998
@@ -1084,6 +1091,11 @@ def __str__(self):
1084
1091
return self .device
1085
1092
1086
1093
1094
+ class TapeSlotQueryset (models .QuerySet ):
1095
+ def natural_sort (self ):
1096
+ return natural_sort (self , 'medium_id' )
1097
+
1098
+
1087
1099
class TapeSlot (models .Model ):
1088
1100
STATUS_CHOICES = (
1089
1101
(0 , 'Inactive' ),
@@ -1103,6 +1115,8 @@ class TapeSlot(models.Model):
1103
1115
robot = models .ForeignKey ('Robot' , models .PROTECT , related_name = 'tape_slots' )
1104
1116
status = models .IntegerField (choices = STATUS_CHOICES , default = 20 )
1105
1117
1118
+ objects = TapeSlotQueryset .as_manager ()
1119
+
1106
1120
@classmethod
1107
1121
@transaction .atomic
1108
1122
@retry (retry = retry_if_exception_type (RequestException ), reraise = True , stop = stop_after_attempt (5 ),
0 commit comments