3535import gzip
3636import hashlib
3737import http .client
38+ import io
3839import os
3940import os .path
4041import signal
@@ -972,19 +973,39 @@ def __exit__(self, exc_type, exc_value, traceback):
972973 return False
973974
974975
976+ class AzureStreamReadAdapter (io .RawIOBase ):
977+ def __init__ (self , raw ):
978+ super ().__init__ ()
979+ self .raw = raw
980+ def readable (self ):
981+ return True
982+ def seekable (self ):
983+ return False
984+ def writable (self ):
985+ return False
986+ def read (self , size = - 1 ):
987+ return self .raw .read (size )
988+ def readall (self ):
989+ return self .raw .read ()
990+ def readinto (self , buf ):
991+ data = self .raw .read (len (buf ))
992+ buf [0 :len (data )] = data
993+ return len (data )
994+
975995class AzureArchive (BaseArchive ):
976996 def __init__ (self , spec ):
977997 super ().__init__ (spec )
978998 self .__container = spec ['container' ]
979999 self .__account = spec ['account' ]
980- self .__key = spec .get ('key' )
981- self .__sasToken = spec .get ('sasToken' )
1000+ self .__credential = spec .get ('key' , spec .get ('sasToken' ))
1001+
1002+ def __getClient (self ):
9821003 try :
983- from azure .storage .blob import BlockBlobService
1004+ from azure .storage .blob import ContainerClient
9841005 except ImportError :
9851006 raise BuildError ("azure-storage-blob Python3 library not installed!" )
986- self . __service = BlockBlobService ( account_name = self .__account ,
987- account_key = self .__key , sas_token = self .__sasToken , socket_timeout = 6000 )
1007+ return ContainerClient ( "https://{}.blob.core.windows.net" . format ( self .__account ) ,
1008+ self .__container , self .__credential )
9881009
9891010 @staticmethod
9901011 def __makeBlobName (buildId , suffix ):
@@ -997,70 +1018,79 @@ def _remoteName(self, buildId, suffix):
9971018 self .__container , self .__makeBlobName (buildId , suffix ))
9981019
9991020 def _openDownloadFile (self , buildId , suffix ):
1000- from azure . common import AzureException , AzureMissingResourceHttpError
1001- ( tmpFd , tmpName ) = mkstemp ()
1021+ client = self . __getClient ()
1022+ from azure . core . exceptions import AzureError , ResourceNotFoundError
10021023 try :
1003- os . close ( tmpFd )
1004- self . __service . get_blob_to_path ( self . __container ,
1005- self . __makeBlobName ( buildId , suffix ), tmpName )
1006- ret = tmpName
1007- tmpName = None
1008- return AzureDownloader ( ret )
1009- except AzureMissingResourceHttpError :
1024+ stream = client . download_blob ( self . __makeBlobName ( buildId , suffix ) )
1025+ stream = AzureStreamReadAdapter ( stream ) # Make io.RawIOBase compatible
1026+ stream = io . BufferedReader ( stream , 1048576 ) # 1MiB buffer. Azure read()s are synchronous.
1027+ ret = AzureDownloader ( client , stream )
1028+ client = None
1029+ return ret
1030+ except ResourceNotFoundError :
10101031 raise ArtifactNotFoundError ()
1011- except AzureException as e :
1032+ except AzureError as e :
10121033 raise ArtifactDownloadError (str (e ))
10131034 finally :
1014- if tmpName is not None : os . unlink ( tmpName )
1035+ if client is not None : client . close ( )
10151036
10161037 def _openUploadFile (self , buildId , suffix ):
1017- from azure . common import AzureException
1018-
1038+ containerClient = self . __getClient ()
1039+ from azure . core . exceptions import AzureError
10191040 blobName = self .__makeBlobName (buildId , suffix )
1041+ blobClient = None
10201042 try :
1021- if self .__service .exists (self .__container , blobName ):
1043+ blobClient = containerClient .get_blob_client (blobName )
1044+ if blobClient .exists ():
10221045 raise ArtifactExistsError ()
1023- except AzureException as e :
1046+ ret = AzureUploader (containerClient , blobClient )
1047+ containerClient = blobClient = None
1048+ return ret
1049+ except AzureError as e :
10241050 raise ArtifactUploadError (str (e ))
1025- ( tmpFd , tmpName ) = mkstemp ()
1026- os .close (tmpFd )
1027- return AzureUploader ( self . __service , self . __container , tmpName , blobName )
1051+ finally :
1052+ if blobClient is not None : blobClient .close ()
1053+ if containerClient is not None : containerClient . close ( )
10281054
10291055class AzureDownloader :
1030- def __init__ (self , name ):
1031- self .name = name
1056+ def __init__ (self , client , stream ):
1057+ self .__client = client
1058+ self .__stream = stream
10321059 def __enter__ (self ):
1033- return (self . name , None )
1060+ return (None , self . __stream )
10341061 def __exit__ (self , exc_type , exc_value , traceback ):
1035- os . unlink ( self .name )
1062+ self .__client . close ( )
10361063 return False
10371064
10381065class AzureUploader :
1039- def __init__ (self , service , container , name , remoteName ):
1040- self .__service = service
1041- self .__container = container
1042- self .__name = name
1043- self .__remoteName = remoteName
1066+ def __init__ (self , containerClient , blobClient ):
1067+ self .__containerClient = containerClient
1068+ self .__blobClient = blobClient
10441069
10451070 def __enter__ (self ):
1046- return (self .__name , None )
1071+ self .__tmp = TemporaryFile ()
1072+ return (None , self .__tmp )
10471073
10481074 def __exit__ (self , exc_type , exc_value , traceback ):
10491075 try :
10501076 if exc_type is None :
10511077 self .__upload ()
10521078 finally :
1053- os .unlink (self .__name )
1079+ self .__tmp .close ()
1080+ self .__blobClient .close ()
1081+ self .__containerClient .close ()
10541082 return False
10551083
10561084 def __upload (self ):
1057- from azure .common import AzureException , AzureConflictHttpError
1085+ from azure .core . exceptions import AzureError , ResourceExistsError
10581086 try :
1059- self .__service .create_blob_from_path (self .__container ,
1060- self .__remoteName , self .__name , if_none_match = "*" )
1061- except AzureConflictHttpError :
1087+ self .__tmp .seek (0 , os .SEEK_END )
1088+ length = self .__tmp .tell ()
1089+ self .__tmp .seek (0 )
1090+ self .__blobClient .upload_blob (self .__tmp , length = length , overwrite = False )
1091+ except ResourceExistsError :
10621092 raise ArtifactExistsError ()
1063- except AzureException as e :
1093+ except AzureError as e :
10641094 raise ArtifactUploadError (str (e ))
10651095
10661096
0 commit comments