Skip to content
This repository was archived by the owner on Sep 12, 2018. It is now read-only.

Commit d42cafd

Browse files
committed
tarfile: pax header and xattr support
tar archive have additional headers that store file data like security capabilities and ACLs. These values can be packed structures, not utf8 encoded. Python's ( < v3.3) tarfile does not support these xattr headers, and has encoding issues on the values stored. This change includes using a vendored version of python-2.7.6's tarfile.py, with changes to support this. Docker-DCO-1.1-Signed-off-by: Vincent Batts <[email protected]> (github: vbatts)
1 parent 68f97b3 commit d42cafd

File tree

3 files changed

+2633
-20
lines changed

3 files changed

+2633
-20
lines changed

docker_registry/images.py

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
import datetime
44
import functools
55
import logging
6-
import tarfile
6+
import xtarfile
77
import time
88

99
import flask
@@ -244,13 +244,13 @@ def put_image_layer(image_id):
244244
tarsum = checksums.TarSum(json_data)
245245
try:
246246
tmp.seek(0)
247-
tar = tarfile.open(mode='r|*', fileobj=tmp)
247+
tar = xtarfile.open(mode='r|*', fileobj=tmp)
248248
tarfilesinfo = layers.TarFilesInfo()
249249
for member in tar:
250250
tarsum.append(member, tar)
251251
tarfilesinfo.append(member)
252252
layers.set_image_files_cache(image_id, tarfilesinfo.json())
253-
except (IOError, tarfile.TarError) as e:
253+
except (IOError, xtarfile.TarError) as e:
254254
logger.debug('put_image_layer: Error when reading Tar stream '
255255
'tarsum. Disabling TarSum, TarFilesInfo. '
256256
'Error: {0}'.format(e))
@@ -433,7 +433,7 @@ def get_private_image_files(image_id, headers):
433433
return toolkit.response(data, headers=headers, raw=True)
434434
except exceptions.FileNotFoundError:
435435
return toolkit.api_error('Image not found', 404)
436-
except tarfile.TarError:
436+
except xtarfile.TarError:
437437
return toolkit.api_error('Layer format not supported', 400)
438438

439439

@@ -452,7 +452,7 @@ def get_image_files(image_id, headers):
452452
return toolkit.response(data, headers=headers, raw=True)
453453
except exceptions.FileNotFoundError:
454454
return toolkit.api_error('Image not found', 404)
455-
except tarfile.TarError:
455+
except xtarfile.TarError:
456456
return toolkit.api_error('Layer format not supported', 400)
457457

458458

@@ -479,5 +479,5 @@ def get_image_diff(image_id, headers):
479479
return toolkit.response(diff_json, headers=headers, raw=True)
480480
except exceptions.FileNotFoundError:
481481
return toolkit.api_error('Image not found', 404)
482-
except tarfile.TarError:
482+
except xtarfile.TarError:
483483
return toolkit.api_error('Layer format not supported', 400)

docker_registry/lib/layers.py

Lines changed: 17 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
# -*- coding: utf-8 -*-
22

33
import logging
4-
import tarfile
54
import tempfile
65

76
import backports.lzma as lzma
@@ -12,21 +11,25 @@
1211
from . import cache
1312
from . import rqueue
1413

14+
# this is our vendored 'tarfile' from python v2.7.6, with xattr support
15+
import xtarfile
16+
17+
1518
store = storage.load()
1619

1720
FILE_TYPES = {
18-
tarfile.REGTYPE: 'f',
19-
tarfile.AREGTYPE: 'f',
20-
tarfile.LNKTYPE: 'l',
21-
tarfile.SYMTYPE: 's',
22-
tarfile.CHRTYPE: 'c',
23-
tarfile.BLKTYPE: 'b',
24-
tarfile.DIRTYPE: 'd',
25-
tarfile.FIFOTYPE: 'i',
26-
tarfile.CONTTYPE: 't',
27-
tarfile.GNUTYPE_LONGNAME: 'L',
28-
tarfile.GNUTYPE_LONGLINK: 'K',
29-
tarfile.GNUTYPE_SPARSE: 'S',
21+
xtarfile.REGTYPE: 'f',
22+
xtarfile.AREGTYPE: 'f',
23+
xtarfile.LNKTYPE: 'l',
24+
xtarfile.SYMTYPE: 's',
25+
xtarfile.CHRTYPE: 'c',
26+
xtarfile.BLKTYPE: 'b',
27+
xtarfile.DIRTYPE: 'd',
28+
xtarfile.FIFOTYPE: 'i',
29+
xtarfile.CONTTYPE: 't',
30+
xtarfile.GNUTYPE_LONGNAME: 'L',
31+
xtarfile.GNUTYPE_LONGLINK: 'K',
32+
xtarfile.GNUTYPE_SPARSE: 'S',
3033
}
3134

3235
logger = logging.getLogger(__name__)
@@ -180,7 +183,7 @@ def get_image_files_from_fobj(layer_file):
180183
'''
181184
layer_file.seek(0)
182185
archive_file = Archive(layer_file)
183-
tar_file = tarfile.open(fileobj=archive_file)
186+
tar_file = xtarfile.open(fileobj=archive_file)
184187
files = read_tarfile(tar_file)
185188
return files
186189

0 commit comments

Comments
 (0)