mirror of https://github.com/docker/docker-py.git
Move build utils to appropriate file
Signed-off-by: Joffrey F <joffrey@docker.com>
This commit is contained in:
parent
77c3e57dcf
commit
fce99c329f
|
@ -1,13 +1,13 @@
|
||||||
# flake8: noqa
|
# flake8: noqa
|
||||||
from .build import tar, exclude_paths
|
from .build import create_archive, exclude_paths, mkbuildcontext, tar
|
||||||
from .decorators import check_resource, minimum_version, update_headers
|
from .decorators import check_resource, minimum_version, update_headers
|
||||||
from .utils import (
|
from .utils import (
|
||||||
compare_version, convert_port_bindings, convert_volume_binds,
|
compare_version, convert_port_bindings, convert_volume_binds,
|
||||||
mkbuildcontext, parse_repository_tag, parse_host,
|
parse_repository_tag, parse_host,
|
||||||
kwargs_from_env, convert_filters, datetime_to_timestamp,
|
kwargs_from_env, convert_filters, datetime_to_timestamp,
|
||||||
create_host_config, parse_bytes, parse_env_file, version_lt,
|
create_host_config, parse_bytes, parse_env_file, version_lt,
|
||||||
version_gte, decode_json_header, split_command, create_ipam_config,
|
version_gte, decode_json_header, split_command, create_ipam_config,
|
||||||
create_ipam_pool, parse_devices, normalize_links, convert_service_networks,
|
create_ipam_pool, parse_devices, normalize_links, convert_service_networks,
|
||||||
format_environment, create_archive, format_extra_hosts
|
format_environment, format_extra_hosts
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
|
@ -1,8 +1,11 @@
|
||||||
|
import io
|
||||||
import os
|
import os
|
||||||
import re
|
import re
|
||||||
|
import six
|
||||||
|
import tarfile
|
||||||
|
import tempfile
|
||||||
|
|
||||||
from ..constants import IS_WINDOWS_PLATFORM
|
from ..constants import IS_WINDOWS_PLATFORM
|
||||||
from .utils import create_archive
|
|
||||||
from fnmatch import fnmatch
|
from fnmatch import fnmatch
|
||||||
from itertools import chain
|
from itertools import chain
|
||||||
|
|
||||||
|
@ -127,3 +130,89 @@ def walk(root, patterns, default=True):
|
||||||
yield f
|
yield f
|
||||||
elif matched:
|
elif matched:
|
||||||
yield f
|
yield f
|
||||||
|
|
||||||
|
|
||||||
|
def build_file_list(root):
|
||||||
|
files = []
|
||||||
|
for dirname, dirnames, fnames in os.walk(root):
|
||||||
|
for filename in fnames + dirnames:
|
||||||
|
longpath = os.path.join(dirname, filename)
|
||||||
|
files.append(
|
||||||
|
longpath.replace(root, '', 1).lstrip('/')
|
||||||
|
)
|
||||||
|
|
||||||
|
return files
|
||||||
|
|
||||||
|
|
||||||
|
def create_archive(root, files=None, fileobj=None, gzip=False,
|
||||||
|
extra_files=None):
|
||||||
|
extra_files = extra_files or []
|
||||||
|
if not fileobj:
|
||||||
|
fileobj = tempfile.NamedTemporaryFile()
|
||||||
|
t = tarfile.open(mode='w:gz' if gzip else 'w', fileobj=fileobj)
|
||||||
|
if files is None:
|
||||||
|
files = build_file_list(root)
|
||||||
|
for path in files:
|
||||||
|
if path in [e[0] for e in extra_files]:
|
||||||
|
# Extra files override context files with the same name
|
||||||
|
continue
|
||||||
|
full_path = os.path.join(root, path)
|
||||||
|
|
||||||
|
i = t.gettarinfo(full_path, arcname=path)
|
||||||
|
if i is None:
|
||||||
|
# This happens when we encounter a socket file. We can safely
|
||||||
|
# ignore it and proceed.
|
||||||
|
continue
|
||||||
|
|
||||||
|
# Workaround https://bugs.python.org/issue32713
|
||||||
|
if i.mtime < 0 or i.mtime > 8**11 - 1:
|
||||||
|
i.mtime = int(i.mtime)
|
||||||
|
|
||||||
|
if IS_WINDOWS_PLATFORM:
|
||||||
|
# Windows doesn't keep track of the execute bit, so we make files
|
||||||
|
# and directories executable by default.
|
||||||
|
i.mode = i.mode & 0o755 | 0o111
|
||||||
|
|
||||||
|
if i.isfile():
|
||||||
|
try:
|
||||||
|
with open(full_path, 'rb') as f:
|
||||||
|
t.addfile(i, f)
|
||||||
|
except IOError:
|
||||||
|
raise IOError(
|
||||||
|
'Can not read file in context: {}'.format(full_path)
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
# Directories, FIFOs, symlinks... don't need to be read.
|
||||||
|
t.addfile(i, None)
|
||||||
|
|
||||||
|
for name, contents in extra_files:
|
||||||
|
info = tarfile.TarInfo(name)
|
||||||
|
info.size = len(contents)
|
||||||
|
t.addfile(info, io.BytesIO(contents.encode('utf-8')))
|
||||||
|
|
||||||
|
t.close()
|
||||||
|
fileobj.seek(0)
|
||||||
|
return fileobj
|
||||||
|
|
||||||
|
|
||||||
|
def mkbuildcontext(dockerfile):
|
||||||
|
f = tempfile.NamedTemporaryFile()
|
||||||
|
t = tarfile.open(mode='w', fileobj=f)
|
||||||
|
if isinstance(dockerfile, io.StringIO):
|
||||||
|
dfinfo = tarfile.TarInfo('Dockerfile')
|
||||||
|
if six.PY3:
|
||||||
|
raise TypeError('Please use io.BytesIO to create in-memory '
|
||||||
|
'Dockerfiles with Python 3')
|
||||||
|
else:
|
||||||
|
dfinfo.size = len(dockerfile.getvalue())
|
||||||
|
dockerfile.seek(0)
|
||||||
|
elif isinstance(dockerfile, io.BytesIO):
|
||||||
|
dfinfo = tarfile.TarInfo('Dockerfile')
|
||||||
|
dfinfo.size = len(dockerfile.getvalue())
|
||||||
|
dockerfile.seek(0)
|
||||||
|
else:
|
||||||
|
dfinfo = t.gettarinfo(fileobj=dockerfile, arcname='Dockerfile')
|
||||||
|
t.addfile(dfinfo, dockerfile)
|
||||||
|
t.close()
|
||||||
|
f.seek(0)
|
||||||
|
return f
|
||||||
|
|
|
@ -1,17 +1,13 @@
|
||||||
import base64
|
import base64
|
||||||
import io
|
|
||||||
import os
|
import os
|
||||||
import os.path
|
import os.path
|
||||||
import json
|
import json
|
||||||
import shlex
|
import shlex
|
||||||
import tarfile
|
|
||||||
import tempfile
|
|
||||||
from distutils.version import StrictVersion
|
from distutils.version import StrictVersion
|
||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
|
|
||||||
import six
|
import six
|
||||||
|
|
||||||
from .. import constants
|
|
||||||
from .. import errors
|
from .. import errors
|
||||||
from .. import tls
|
from .. import tls
|
||||||
|
|
||||||
|
@ -46,29 +42,6 @@ def create_ipam_config(*args, **kwargs):
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
def mkbuildcontext(dockerfile):
|
|
||||||
f = tempfile.NamedTemporaryFile()
|
|
||||||
t = tarfile.open(mode='w', fileobj=f)
|
|
||||||
if isinstance(dockerfile, io.StringIO):
|
|
||||||
dfinfo = tarfile.TarInfo('Dockerfile')
|
|
||||||
if six.PY3:
|
|
||||||
raise TypeError('Please use io.BytesIO to create in-memory '
|
|
||||||
'Dockerfiles with Python 3')
|
|
||||||
else:
|
|
||||||
dfinfo.size = len(dockerfile.getvalue())
|
|
||||||
dockerfile.seek(0)
|
|
||||||
elif isinstance(dockerfile, io.BytesIO):
|
|
||||||
dfinfo = tarfile.TarInfo('Dockerfile')
|
|
||||||
dfinfo.size = len(dockerfile.getvalue())
|
|
||||||
dockerfile.seek(0)
|
|
||||||
else:
|
|
||||||
dfinfo = t.gettarinfo(fileobj=dockerfile, arcname='Dockerfile')
|
|
||||||
t.addfile(dfinfo, dockerfile)
|
|
||||||
t.close()
|
|
||||||
f.seek(0)
|
|
||||||
return f
|
|
||||||
|
|
||||||
|
|
||||||
def decode_json_header(header):
|
def decode_json_header(header):
|
||||||
data = base64.b64decode(header)
|
data = base64.b64decode(header)
|
||||||
if six.PY3:
|
if six.PY3:
|
||||||
|
@ -76,68 +49,6 @@ def decode_json_header(header):
|
||||||
return json.loads(data)
|
return json.loads(data)
|
||||||
|
|
||||||
|
|
||||||
def build_file_list(root):
|
|
||||||
files = []
|
|
||||||
for dirname, dirnames, fnames in os.walk(root):
|
|
||||||
for filename in fnames + dirnames:
|
|
||||||
longpath = os.path.join(dirname, filename)
|
|
||||||
files.append(
|
|
||||||
longpath.replace(root, '', 1).lstrip('/')
|
|
||||||
)
|
|
||||||
|
|
||||||
return files
|
|
||||||
|
|
||||||
|
|
||||||
def create_archive(root, files=None, fileobj=None, gzip=False,
|
|
||||||
extra_files=None):
|
|
||||||
if not fileobj:
|
|
||||||
fileobj = tempfile.NamedTemporaryFile()
|
|
||||||
t = tarfile.open(mode='w:gz' if gzip else 'w', fileobj=fileobj)
|
|
||||||
if files is None:
|
|
||||||
files = build_file_list(root)
|
|
||||||
for path in files:
|
|
||||||
if path in [e[0] for e in extra_files]:
|
|
||||||
# Extra files override context files with the same name
|
|
||||||
continue
|
|
||||||
full_path = os.path.join(root, path)
|
|
||||||
|
|
||||||
i = t.gettarinfo(full_path, arcname=path)
|
|
||||||
if i is None:
|
|
||||||
# This happens when we encounter a socket file. We can safely
|
|
||||||
# ignore it and proceed.
|
|
||||||
continue
|
|
||||||
|
|
||||||
# Workaround https://bugs.python.org/issue32713
|
|
||||||
if i.mtime < 0 or i.mtime > 8**11 - 1:
|
|
||||||
i.mtime = int(i.mtime)
|
|
||||||
|
|
||||||
if constants.IS_WINDOWS_PLATFORM:
|
|
||||||
# Windows doesn't keep track of the execute bit, so we make files
|
|
||||||
# and directories executable by default.
|
|
||||||
i.mode = i.mode & 0o755 | 0o111
|
|
||||||
|
|
||||||
if i.isfile():
|
|
||||||
try:
|
|
||||||
with open(full_path, 'rb') as f:
|
|
||||||
t.addfile(i, f)
|
|
||||||
except IOError:
|
|
||||||
raise IOError(
|
|
||||||
'Can not read file in context: {}'.format(full_path)
|
|
||||||
)
|
|
||||||
else:
|
|
||||||
# Directories, FIFOs, symlinks... don't need to be read.
|
|
||||||
t.addfile(i, None)
|
|
||||||
|
|
||||||
for name, contents in extra_files:
|
|
||||||
info = tarfile.TarInfo(name)
|
|
||||||
info.size = len(contents)
|
|
||||||
t.addfile(info, io.BytesIO(contents.encode('utf-8')))
|
|
||||||
|
|
||||||
t.close()
|
|
||||||
fileobj.seek(0)
|
|
||||||
return fileobj
|
|
||||||
|
|
||||||
|
|
||||||
def compare_version(v1, v2):
|
def compare_version(v1, v2):
|
||||||
"""Compare docker versions
|
"""Compare docker versions
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue