from io import StringIO
from shutil import copy, rmtree
from pwd import getpwuid
-from datetime import datetime,timedelta
+from datetime import datetime, timedelta
FILTERED_ENV_NAMES = ['ftp_proxy', 'http_proxy', 'https_proxy']
"""Calculate a digest string unique to the text content"""
return hashlib.sha1(text).hexdigest()
+
def _file_checksum(filename):
return _text_checksum(open(filename, 'rb').read())
+
def _guess_docker_command():
""" Guess a working docker command or raise exception if not found"""
commands = [["docker"], ["sudo", "-n", "docker"]]
except OSError:
pass
commands_txt = "\n".join([" " + " ".join(x) for x in commands])
- raise Exception("Cannot find working docker command. Tried:\n%s" % \
+ raise Exception("Cannot find working docker command. Tried:\n%s" %
commands_txt)
+
def _copy_with_mkdir(src, root_dir, sub_path='.'):
"""Copy src into root_dir, creating sub_path as needed."""
dest_dir = os.path.normpath("%s/%s" % (root_dir, sub_path))
return libs
+
def _copy_binary_with_libs(src, bin_dest, dest_dir):
"""Maybe copy a binary and all its dependent libraries.
if libs:
for l in libs:
so_path = os.path.dirname(l)
- _copy_with_mkdir(l , dest_dir, so_path)
+ _copy_with_mkdir(l, dest_dir, so_path)
def _check_binfmt_misc(executable):
with open(binfmt_entry) as x: entry = x.read()
if re.search("flags:.*F.*\n", entry):
- print("binfmt_misc for %s uses persistent(F) mapping to host binary\n" %
+ print("binfmt_misc for %s uses persistent(F) mapping to host binary" %
(binary))
return None, True
img_name + ".docker")
return open(df, "r").read()
+
def _dockerfile_preprocess(df):
out = ""
for l in df.splitlines():
out += l + "\n"
return out
+
class Docker(object):
""" Running Docker commands """
def __init__(self):
def build_image(self, tag, docker_dir, dockerfile,
quiet=True, user=False, argv=None, extra_files_cksum=[]):
- if argv == None:
+ if argv is None:
argv = []
tmp_df = tempfile.NamedTemporaryFile(dir=docker_dir, suffix=".docker")
tmp_df.flush()
- self._do_check(["build", "-t", tag, "-f", tmp_df.name] + argv + \
+ self._do_check(["build", "-t", tag, "-f", tmp_df.name] + argv +
[docker_dir],
quiet=quiet)
def command(self, cmd, argv, quiet):
return self._do([cmd] + argv, quiet=quiet)
+
class SubCommand(object):
"""A SubCommand template base class"""
- name = None # Subcommand name
+ name = None # Subcommand name
+
def shared_args(self, parser):
parser.add_argument("--quiet", action="store_true",
help="Run quietly unless an error occurred")
def args(self, parser):
"""Setup argument parser"""
pass
+
def run(self, args, argv):
"""Run command.
args: parsed argument by argument parser.
"""
pass
+
class RunCommand(SubCommand):
"""Invoke docker run and take care of cleaning up"""
name = "run"
+
def args(self, parser):
parser.add_argument("--keep", action="store_true",
help="Don't remove image when command completes")
+
def run(self, args, argv):
return Docker().run(argv, args.keep, quiet=args.quiet)
+
class BuildCommand(SubCommand):
- """ Build docker image out of a dockerfile. Arguments: <tag> <dockerfile>"""
+ """ Build docker image out of a dockerfile. Arg: <tag> <dockerfile>"""
name = "build"
+
def args(self, parser):
parser.add_argument("--include-executable", "-e",
help="""Specify a binary that will be copied to the
cksum += [(filename, _file_checksum(filename))]
argv += ["--build-arg=" + k.lower() + "=" + v
- for k, v in os.environ.iteritems()
- if k.lower() in FILTERED_ENV_NAMES]
+ for k, v in os.environ.iteritems()
+ if k.lower() in FILTERED_ENV_NAMES]
dkr.build_image(tag, docker_dir, dockerfile,
quiet=args.quiet, user=args.user, argv=argv,
extra_files_cksum=cksum)
return 0
+
class UpdateCommand(SubCommand):
- """ Update a docker image with new executables. Arguments: <tag> <executable>"""
+ """ Update a docker image with new executables. Args: <tag> <executable>"""
name = "update"
+
def args(self, parser):
parser.add_argument("tag",
help="Image Tag")
return 0
+
class CleanCommand(SubCommand):
"""Clean up docker instances"""
name = "clean"
+
def run(self, args, argv):
Docker().clean()
return 0
+
class ImagesCommand(SubCommand):
"""Run "docker images" command"""
name = "images"
+
def run(self, args, argv):
return Docker().command("images", argv, args.quiet)
try:
dkr = Docker()
- except:
+ except subprocess.CalledProcessError:
print("Docker not set up")
return 1
def main():
parser = argparse.ArgumentParser(description="A Docker helper",
- usage="%s <subcommand> ..." % os.path.basename(sys.argv[0]))
+ usage="%s <subcommand> ..." %
+ os.path.basename(sys.argv[0]))
subparsers = parser.add_subparsers(title="subcommands", help=None)
for cls in SubCommand.__subclasses__():
cmd = cls()
args, argv = parser.parse_known_args()
return args.cmdobj.run(args, argv)
+
if __name__ == "__main__":
sys.exit(main())