Verificando a integridade do tarfile em Python
Estou trabalhando na conversão do meu script de backup do shell para o Python. Um dos recursos do meu antigo script era verificar o integridade do tarfile criado: gzip -t.
Isso parece ser um pouco complicado em Python.
Parece que a única maneira de fazer isso é lendo cada um dos objetos TarInfo compactados dentro do tarfile.
Existe uma maneira de verificar um arquivo tar para integridade, sem extrair para o disco ou mantê-lo na memória (na sua totalidade)?
Pessoas boas em #python em freenode sugeriram que eu deveria ler cada pedaço de TarInfo pedaço por pedaço, descartando cada pedaço de leitura.
Devo admitir que não tenho ideia de como fazer isso, visto que acabei de iniciar o Python.
Imagine que eu tenha um tarfile de 30GB que contém arquivos de 1kb a 10GB ...
Esta é a solução que comecei a escrever:
try:
tardude = tarfile.open("zero.tar.gz")
except:
print "There was an error opening tarfile. The file might be corrupt or missing."
for member_info in tardude.getmembers():
try:
check = tardude.extractfile(member_info.name)
except:
print "File: %r is corrupt." % member_info.name
tardude.close()
Este código está longe de terminar. Eu não ousaria rodar isso em um enorme arquivo tar de 30GB, porque em um ponto, check seria um objeto de 10 + GB (se eu tiver arquivos tão grandes dentro do arquivo tar)
Bônus: Eu tentei corromper manualmente zero.tar.gz (editor hexadecimal - edite alguns bytes no midfile). O primeiro, exceto não pega IOError ... Aqui está a saída:
Traceback (most recent call last):
File "./test.py", line 31, in <module>
for member_info in tardude.getmembers():
File "/usr/lib/python2.7/tarfile.py", line 1805, in getmembers
self._load() # all members, we first have to
File "/usr/lib/python2.7/tarfile.py", line 2380, in _load
tarinfo = self.next()
File "/usr/lib/python2.7/tarfile.py", line 2315, in next
self.fileobj.seek(self.offset)
File "/usr/lib/python2.7/gzip.py", line 429, in seek
self.read(1024)
File "/usr/lib/python2.7/gzip.py", line 256, in read
self._read(readsize)
File "/usr/lib/python2.7/gzip.py", line 320, in _read
self._read_eof()
File "/usr/lib/python2.7/gzip.py", line 342, in _read_eof
hex(self.crc)))
IOError: CRC check failed 0xe5384b87 != 0xdfe91e1L