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

Commit 2f12b06

Browse files
committed
Merge pull request #381 from vbatts/vbatts-xattr_support
tarfile: pax header and xattr support
2 parents 68f97b3 + 09e9e20 commit 2f12b06

File tree

11 files changed

+222
-2
lines changed

11 files changed

+222
-2
lines changed

docker_registry/images.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@
33
import datetime
44
import functools
55
import logging
6-
import tarfile
76
import time
87

98
import flask
@@ -20,6 +19,9 @@
2019
from .lib import checksums
2120
from .lib import layers
2221
from .lib import mirroring
22+
# this is our monkey patched snippet from python v2.7.6 'tarfile'
23+
# with xattr support
24+
from .lib.xtarfile import tarfile
2325

2426

2527
store = storage.load()

docker_registry/lib/layers.py

Lines changed: 4 additions & 1 deletion
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
@@ -11,6 +10,10 @@
1110
from .. import storage
1211
from . import cache
1312
from . import rqueue
13+
# this is our monkey patched snippet from python v2.7.6 'tarfile'
14+
# with xattr support
15+
from .xtarfile import tarfile
16+
1417

1518
store = storage.load()
1619

docker_registry/lib/xtarfile.py

Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
'''
2+
This is __proc_pax from ./Lib/tarfile.py from v2.7.6
3+
catching raw (non-utf8) bytes to support some xattr headers in tar archives
4+
5+
This is for the use-case of reading the tar archive, not for the use case of
6+
interacting with inodes on the filesystem that have xattr's.
7+
-- vbatts
8+
'''
9+
10+
import re
11+
import tarfile
12+
13+
14+
def _proc_pax(self, filetar):
15+
"""Process an extended or global header as described in
16+
POSIX.1-2001.
17+
"""
18+
# Read the header information.
19+
buf = filetar.fileobj.read(self._block(self.size))
20+
21+
# A pax header stores supplemental information for either
22+
# the following file (extended) or all following files
23+
# (global).
24+
if self.type == tarfile.XGLTYPE:
25+
pax_headers = filetar.pax_headers
26+
else:
27+
pax_headers = filetar.pax_headers.copy()
28+
29+
# Parse pax header information. A record looks like that:
30+
# "%d %s=%s\n" % (length, keyword, value). length is the size
31+
# of the complete record including the length field itself and
32+
# the newline. keyword and value are both UTF-8 encoded strings.
33+
regex = re.compile(r"(\d+) ([^=]+)=", re.U)
34+
pos = 0
35+
while True:
36+
match = regex.match(buf, pos)
37+
if not match:
38+
break
39+
40+
length, keyword = match.groups()
41+
length = int(length)
42+
value = buf[match.end(2) + 1:match.start(1) + length - 1]
43+
44+
try:
45+
keyword = keyword.decode("utf8")
46+
except Exception:
47+
# just leave the raw bytes
48+
pass
49+
50+
try:
51+
value = value.decode("utf8")
52+
except Exception:
53+
# just leave the raw bytes
54+
pass
55+
56+
pax_headers[keyword] = value
57+
pos += length
58+
59+
# Fetch the next header.
60+
try:
61+
next = self.fromtarfile(filetar)
62+
except tarfile.HeaderError:
63+
raise tarfile.SubsequentHeaderError("missing or bad subsequent header")
64+
65+
if self.type in (tarfile.XHDTYPE, tarfile.SOLARIS_XHDTYPE):
66+
# Patch the TarInfo object with the extended header info.
67+
next._apply_pax_info(pax_headers, filetar.encoding, filetar.errors)
68+
next.offset = self.offset
69+
70+
if "size" in pax_headers:
71+
# If the extended header replaces the size field,
72+
# we need to recalculate the offset where the next
73+
# header starts.
74+
offset = next.offset_data
75+
if next.isreg() or next.type not in tarfile.SUPPORTED_TYPES:
76+
offset += next._block(next.size)
77+
filetar.offset = offset
78+
79+
return next
80+
81+
tarfile.TarInfo._proc_pax = _proc_pax

tests/base.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,15 @@
33
import docker_registry.run as run
44

55
import hashlib
6+
import os
67
import random
78
import string
89
import unittest
910

1011
from docker_registry.core import compat
1112

13+
data_dir = os.path.join(os.path.dirname(__file__), "data")
14+
1215

1316
class TestCase(unittest.TestCase):
1417

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
{"id":"46af0962ab5afeb5ce6740d4d91652e69206fc991fd5328c1a94d364ad00e457","parent":"def3f9165934325dfd027c86530b2ea49bb57a0963eb1336b3a0415ff6fd56de","created":"2014-04-07T02:45:52.610504484Z","container":"e0f07f8d72cae171a3dcc35859960e7e956e0628bce6fedc4122bf55b2c287c7","container_config":{"Hostname":"88807319f25e","Domainname":"","User":"","Memory":0,"MemorySwap":0,"CpuShares":0,"AttachStdin":false,"AttachStdout":false,"AttachStderr":false,"PortSpecs":null,"ExposedPorts":null,"Tty":false,"OpenStdin":false,"StdinOnce":false,"Env":["HOME=/","PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"],"Cmd":["/bin/sh","-c","sed -ri 's/^(%wheel.*)(ALL)$/\\1NOPASSWD: \\2/' /etc/sudoers"],"Image":"def3f9165934325dfd027c86530b2ea49bb57a0963eb1336b3a0415ff6fd56de","Volumes":null,"WorkingDir":"","Entrypoint":null,"NetworkDisabled":false,"OnBuild":[]},"docker_version":"0.9.1-dev","config":{"Hostname":"88807319f25e","Domainname":"","User":"","Memory":0,"MemorySwap":0,"CpuShares":0,"AttachStdin":false,"AttachStdout":false,"AttachStderr":false,"PortSpecs":null,"ExposedPorts":null,"Tty":false,"OpenStdin":false,"StdinOnce":false,"Env":["HOME=/","PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"],"Cmd":null,"Image":"def3f9165934325dfd027c86530b2ea49bb57a0963eb1336b3a0415ff6fd56de","Volumes":null,"WorkingDir":"","Entrypoint":null,"NetworkDisabled":false,"OnBuild":[]},"architecture":"amd64","os":"linux","Size":3425}
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
{"id":"511136ea3c5a64f264b78b5433614aec563103b4d4702f3ba7d4d2698e22c158","comment":"Imported from -","created":"2013-06-13T14:03:50.821769-07:00","container_config":{"Hostname":"","Domainname":"","User":"","Memory":0,"MemorySwap":0,"CpuShares":0,"AttachStdin":false,"AttachStdout":false,"AttachStderr":false,"PortSpecs":null,"ExposedPorts":null,"Tty":false,"OpenStdin":false,"StdinOnce":false,"Env":null,"Cmd":null,"Image":"","Volumes":null,"WorkingDir":"","Entrypoint":null,"NetworkDisabled":false,"OnBuild":null},"docker_version":"0.4.0","architecture":"x86_64","Size":0}

tests/data/xattr/json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
{"id":"4439c3c7f847954100b42b267e7e5529cac1d6934db082f65795c5ca2e594d93","parent":"73b164f4437db87e96e90083c73a6592f549646ae2ec00ed33c6b9b49a5c4470","created":"2014-05-16T17:19:44.091534414Z","container":"5f92fb06cc58f357f0cde41394e2bbbb664e663974b2ac1693ab07b7a306749b","container_config":{"Hostname":"9565c6517a0e","Domainname":"","User":"","Memory":0,"MemorySwap":0,"CpuShares":0,"Cpuset":"","AttachStdin":false,"AttachStdout":false,"AttachStderr":false,"PortSpecs":null,"ExposedPorts":null,"Tty":false,"OpenStdin":false,"StdinOnce":false,"Env":["HOME=/","PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"],"Cmd":["/bin/sh","-c","setcap 'cap_setgid,cap_setuid+ep' ./file \u0026\u0026 getcap ./file"],"Image":"73b164f4437db87e96e90083c73a6592f549646ae2ec00ed33c6b9b49a5c4470","Volumes":null,"WorkingDir":"","Entrypoint":null,"NetworkDisabled":false,"OnBuild":[]},"docker_version":"0.11.1-dev","config":{"Hostname":"9565c6517a0e","Domainname":"","User":"","Memory":0,"MemorySwap":0,"CpuShares":0,"Cpuset":"","AttachStdin":false,"AttachStdout":false,"AttachStderr":false,"PortSpecs":null,"ExposedPorts":null,"Tty":false,"OpenStdin":false,"StdinOnce":false,"Env":["HOME=/","PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"],"Cmd":null,"Image":"73b164f4437db87e96e90083c73a6592f549646ae2ec00ed33c6b9b49a5c4470","Volumes":null,"WorkingDir":"","Entrypoint":null,"NetworkDisabled":false,"OnBuild":[]},"architecture":"amd64","os":"linux","Size":0}

tests/data/xattr/layer.tar

2.5 KB
Binary file not shown.

0 commit comments

Comments
 (0)