Skip to content

Commit

Permalink
Move build utils to appropriate file
Browse files Browse the repository at this point in the history
Signed-off-by: Joffrey F <joffrey@docker.com>
  • Loading branch information
shin- committed Mar 27, 2018
1 parent 081b78f commit 3fdc012
Show file tree
Hide file tree
Showing 3 changed files with 93 additions and 93 deletions.
6 changes: 3 additions & 3 deletions docker/utils/__init__.py
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
# 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 .utils import (
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,
create_host_config, parse_bytes, parse_env_file, version_lt,
version_gte, decode_json_header, split_command, create_ipam_config,
create_ipam_pool, parse_devices, normalize_links, convert_service_networks,
format_environment, create_archive, format_extra_hosts
format_environment, format_extra_hosts
)

91 changes: 90 additions & 1 deletion docker/utils/build.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,11 @@
import io
import os
import re
import six
import tarfile
import tempfile

from ..constants import IS_WINDOWS_PLATFORM
from .utils import create_archive
from fnmatch import fnmatch
from itertools import chain

Expand Down Expand Up @@ -127,3 +130,89 @@ def match(p):
yield f
elif matched:
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
89 changes: 0 additions & 89 deletions docker/utils/utils.py
Original file line number Diff line number Diff line change
@@ -1,17 +1,13 @@
import base64
import io
import os
import os.path
import json
import shlex
import tarfile
import tempfile
from distutils.version import StrictVersion
from datetime import datetime

import six

from .. import constants
from .. import errors
from .. import tls

Expand Down Expand Up @@ -46,98 +42,13 @@ 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):
data = base64.b64decode(header)
if six.PY3:
data = data.decode('utf-8')
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):
"""Compare docker versions
Expand Down

0 comments on commit 3fdc012

Please sign in to comment.