#!/usr/bin/env python3
#
# Docker controlling module
#
# Copyright (c) 2016 Red Hat Inc.
#
# Authors:
#  Fam Zheng <famz@redhat.com>
#
# This work is licensed under the terms of the GNU GPL, version 2
# or (at your option) any later version. See the COPYING file in
# the top-level directory.

import os
import sys
import subprocess
import json
import hashlib
import atexit
import uuid
import argparse
import enum
import tempfile
import re
import signal
from tarfile import TarFile, TarInfo
from io import StringIO
from shutil import copy, rmtree
from pwd import getpwuid
from datetime import datetime, timedelta


FILTERED_ENV_NAMES = ['ftp_proxy', 'http_proxy', 'https_proxy']


DEVNULL = open(os.devnull, 'wb')

class EngineEnum(enum.IntEnum):
    AUTO = 1
    DOCKER = 2
    PODMAN = 3

    def __str__(self):
        return self.name.lower()

    def __repr__(self):
        return str(self)

    @staticmethod
    def argparse(s):
        try:
            return EngineEnum[s.upper()]
        except KeyError:
            return s


USE_ENGINE = EngineEnum.AUTO

def _bytes_checksum(bytes):
    """Calculate a digest string unique to the text content"""
    return hashlib.sha1(bytes).hexdigest()

def _text_checksum(text):
    """Calculate a digest string unique to the text content"""
    return _bytes_checksum(text.encode('utf-8'))

def _read_dockerfile(path):
    return open(path, 'rt', encoding='utf-8').read()

def _file_checksum(filename):
    return _bytes_checksum(open(filename, 'rb').read())


def _guess_engine_command():
    """ Guess a working engine command or raise exception if not found"""
    commands = []

    if USE_ENGINE in [EngineEnum.AUTO, EngineEnum.PODMAN]:
        commands += [["podman"]]
    if USE_ENGINE in [EngineEnum.AUTO, EngineEnum.DOCKER]:
        commands += [["docker"], ["sudo", "-n", "docker"]]
    for cmd in commands:
        try:
            # docker version will return the client details in stdout
            # but still report a status of 1 if it can't contact the daemon
            if subprocess.call(cmd + ["version"],
                               stdout=DEVNULL, stderr=DEVNULL) == 0:
                return cmd
        except OSError:
            pass
    commands_txt = "\n".join(["  " + " ".join(x) for x in commands])
    raise Exception("Cannot find working engine 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))
    try:
        os.makedirs(dest_dir)
    except OSError:
        # we can safely ignore already created directories
        pass

    dest_file = "%s/%s" % (dest_dir, os.path.basename(src))
    copy(src, dest_file)


def _get_so_libs(executable):
    """Return a list of libraries associated with an executable.

    The paths may be symbolic links which would need to be resolved to
    ensure the right data is copied."""

    libs = []
    ldd_re = re.compile(r"(?:\S+ => )?(\S*) \(:?0x[0-9a-f]+\)")
    try:
        ldd_output = subprocess.check_output(["ldd", executable]).decode('utf-8')
        for line in ldd_output.split("\n"):
            search = ldd_re.search(line)
            if search:
                try:
                    libs.append(s.group(1))
                except IndexError:
                    pass
    except subprocess.CalledProcessError:
        print("%s had no associated libraries (static build?)" % (executable))

    return libs


def _copy_binary_with_libs(src, bin_dest, dest_dir):
    """Maybe copy a binary and all its dependent libraries.

    If bin_dest isn't set we only copy the support libraries because
    we don't need qemu in the docker path to run (due to persistent
    mapping). Indeed users may get confused if we aren't running what
    is in the image.

    This does rely on the host file-system being fairly multi-arch
    aware so the file don't clash with the guests layout.
    """

    if bin_dest:
        _copy_with_mkdir(src, dest_dir, os.path.dirname(bin_dest))
    else:
        print("only copying support libraries for %s" % (src))

    libs = _get_so_libs(src)
    if libs:
        for l in libs:
            so_path = os.path.dirname(l)
            real_l = os.path.realpath(l)
            _copy_with_mkdir(real_l, dest_dir, so_path)


def _check_binfmt_misc(executable):
    """Check binfmt_misc has entry for executable in the right place.

    The details of setting up binfmt_misc are outside the scope of
    this script but we should at least fail early with a useful
    message if it won't work.

    Returns the configured binfmt path and a valid flag. For
    persistent configurations we will still want to copy and dependent
    libraries.
    """

    binary = os.path.basename(executable)
    binfmt_entry = "/proc/sys/fs/binfmt_misc/%s" % (binary)

    if not os.path.exists(binfmt_entry):
        print ("No binfmt_misc entry for %s" % (binary))
        return None, False

    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" %
              (binary))
        return None, True

    m = re.search("interpreter (\S+)\n", entry)
    interp = m.group(1)
    if interp and interp != executable:
        print("binfmt_misc for %s does not point to %s, using %s" %
              (binary, executable, interp))

    return interp, True


def _read_qemu_dockerfile(img_name):
    # special case for Debian linux-user images
    if img_name.startswith("debian") and img_name.endswith("user"):
        img_name = "debian-bootstrap"

    df = os.path.join(os.path.dirname(__file__), "dockerfiles",
                      img_name + ".docker")
    return _read_dockerfile(df)


def _dockerfile_preprocess(df):
    out = ""
    for l in df.splitlines():
        if len(l.strip()) == 0 or l.startswith("#"):
            continue
        from_pref = "FROM qemu/"
        if l.startswith(from_pref):
            # TODO: Alternatively we could replace this line with "FROM $ID"
            # where $ID is the image's hex id obtained with
            #    $ docker images $IMAGE --format="{{.Id}}"
            # but unfortunately that's not supported by RHEL 7.
            inlining = _read_qemu_dockerfile(l[len(from_pref):])
            out += _dockerfile_preprocess(inlining)
            continue
        out += l + "\n"
    return out


class Docker(object):
    """ Running Docker commands """
    def __init__(self):
        self._command = _guess_engine_command()

        if "docker" in self._command and "TRAVIS" not in os.environ:
            os.environ["DOCKER_BUILDKIT"] = "1"
            self._buildkit = True
        else:
            self._buildkit = False

        self._instance = None
        atexit.register(self._kill_instances)
        signal.signal(signal.SIGTERM, self._kill_instances)
        signal.signal(signal.SIGHUP, self._kill_instances)

    def _do(self, cmd, quiet=True, **kwargs):
        if quiet:
            kwargs["stdout"] = DEVNULL
        return subprocess.call(self._command + cmd, **kwargs)

    def _do_check(self, cmd, quiet=True, **kwargs):
        if quiet:
            kwargs["stdout"] = DEVNULL
        return subprocess.check_call(self._command + cmd, **kwargs)

    def _do_kill_instances(self, only_known, only_active=True):
        cmd = ["ps", "-q"]
        if not only_active:
            cmd.append("-a")

        filter = "--filter=label=com.qemu.instance.uuid"
        if only_known:
            if self._instance:
                filter += "=%s" % (self._instance)
            else:
                # no point trying to kill, we finished
                return

        print("filter=%s" % (filter))
        cmd.append(filter)
        for i in self._output(cmd).split():
            self._do(["rm", "-f", i])

    def clean(self):
        self._do_kill_instances(False, False)
        return 0

    def _kill_instances(self, *args, **kwargs):
        return self._do_kill_instances(True)

    def _output(self, cmd, **kwargs):
        try:
            return subprocess.check_output(self._command + cmd,
                                           stderr=subprocess.STDOUT,
                                           encoding='utf-8',
                                           **kwargs)
        except TypeError:
            # 'encoding' argument was added in 3.6+
            return subprocess.check_output(self._command + cmd,
                                           stderr=subprocess.STDOUT,
                                           **kwargs).decode('utf-8')


    def inspect_tag(self, tag):
        try:
            return self._output(["inspect", tag])
        except subprocess.CalledProcessError:
            return None

    def get_image_creation_time(self, info):
        return json.loads(info)[0]["Created"]

    def get_image_dockerfile_checksum(self, tag):
        resp = self.inspect_tag(tag)
        labels = json.loads(resp)[0]["Config"].get("Labels", {})
        return labels.get("com.qemu.dockerfile-checksum", "")

    def build_image(self, tag, docker_dir, dockerfile,
                    quiet=True, user=False, argv=None, registry=None,
                    extra_files_cksum=[]):
        if argv is None:
            argv = []

        # pre-calculate the docker checksum before any
        # substitutions we make for caching
        checksum = _text_checksum(_dockerfile_preprocess(dockerfile))

        if registry is not None:
            sources = re.findall("FROM qemu\/(.*)", dockerfile)
            # Fetch any cache layers we can, may fail
            for s in sources:
                pull_args = ["pull", "%s/qemu/%s" % (registry, s)]
                if self._do(pull_args, quiet=quiet) != 0:
                    registry = None
                    break
            # Make substitutions
            if registry is not None:
                dockerfile = dockerfile.replace("FROM qemu/",
                                                "FROM %s/qemu/" %
                                                (registry))

        tmp_df = tempfile.NamedTemporaryFile(mode="w+t",
                                             encoding='utf-8',
                                             dir=docker_dir, suffix=".docker")
        tmp_df.write(dockerfile)

        if user:
            uid = os.getuid()
            uname = getpwuid(uid).pw_name
            tmp_df.write("\n")
            tmp_df.write("RUN id %s 2>/dev/null || useradd -u %d -U %s" %
                         (uname, uid, uname))

        tmp_df.write("\n")
        tmp_df.write("LABEL com.qemu.dockerfile-checksum=%s" % (checksum))
        for f, c in extra_files_cksum:
            tmp_df.write("LABEL com.qemu.%s-checksum=%s" % (f, c))

        tmp_df.flush()

        build_args = ["build", "-t", tag, "-f", tmp_df.name]
        if self._buildkit:
            build_args += ["--build-arg", "BUILDKIT_INLINE_CACHE=1"]

        if registry is not None:
            pull_args = ["pull", "%s/%s" % (registry, tag)]
            self._do(pull_args, quiet=quiet)
            cache = "%s/%s" % (registry, tag)
            build_args += ["--cache-from", cache]
        build_args += argv
        build_args += [docker_dir]

        self._do_check(build_args,
                       quiet=quiet)

    def update_image(self, tag, tarball, quiet=True):
        "Update a tagged image using "

        self._do_check(["build", "-t", tag, "-"], quiet=quiet, stdin=tarball)

    def image_matches_dockerfile(self, tag, dockerfile):
        try:
            checksum = self.get_image_dockerfile_checksum(tag)
        except Exception:
            return False
        return checksum == _text_checksum(_dockerfile_preprocess(dockerfile))

    def run(self, cmd, keep, quiet, as_user=False):
        label = uuid.uuid4().hex
        if not keep:
            self._instance = label

        if as_user:
            uid = os.getuid()
            cmd = [ "-u", str(uid) ] + cmd
            # podman requires a bit more fiddling
            if self._command[0] == "podman":
                cmd.insert(0, '--userns=keep-id')

        ret = self._do_check(["run", "--label",
                             "com.qemu.instance.uuid=" + label] + cmd,
                             quiet=quiet)
        if not keep:
            self._instance = None
        return ret

    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

    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.
        argv: remaining arguments from sys.argv.
        """
        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")
        parser.add_argument("--run-as-current-user", action="store_true",
                            help="Run container using the current user's uid")

    def run(self, args, argv):
        return Docker().run(argv, args.keep, quiet=args.quiet,
                            as_user=args.run_as_current_user)


class BuildCommand(SubCommand):
    """ 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
                            container together with all its dependent
                            libraries""")
        parser.add_argument("--extra-files", nargs='*',
                            help="""Specify files that will be copied in the
                            Docker image, fulfilling the ADD directive from the
                            Dockerfile""")
        parser.add_argument("--add-current-user", "-u", dest="user",
                            action="store_true",
                            help="Add the current user to image's passwd")
        parser.add_argument("--registry", "-r",
                            help="cache from docker registry")
        parser.add_argument("-t", dest="tag",
                            help="Image Tag")
        parser.add_argument("-f", dest="dockerfile",
                            help="Dockerfile name")

    def run(self, args, argv):
        dockerfile = _read_dockerfile(args.dockerfile)
        tag = args.tag

        dkr = Docker()
        if "--no-cache" not in argv and \
           dkr.image_matches_dockerfile(tag, dockerfile):
            if not args.quiet:
                print("Image is up to date.")
        else:
            # Create a docker context directory for the build
            docker_dir = tempfile.mkdtemp(prefix="docker_build")

            # Validate binfmt_misc will work
            if args.include_executable:
                qpath, enabled = _check_binfmt_misc(args.include_executable)
                if not enabled:
                    return 1

            # Is there a .pre file to run in the build context?
            docker_pre = os.path.splitext(args.dockerfile)[0]+".pre"
            if os.path.exists(docker_pre):
                stdout = DEVNULL if args.quiet else None
                rc = subprocess.call(os.path.realpath(docker_pre),
                                     cwd=docker_dir, stdout=stdout)
                if rc == 3:
                    print("Skip")
                    return 0
                elif rc != 0:
                    print("%s exited with code %d" % (docker_pre, rc))
                    return 1

            # Copy any extra files into the Docker context. These can be
            # included by the use of the ADD directive in the Dockerfile.
            cksum = []
            if args.include_executable:
                # FIXME: there is no checksum of this executable and the linked
                # libraries, once the image built any change of this executable
                # or any library won't trigger another build.
                _copy_binary_with_libs(args.include_executable,
                                       qpath, docker_dir)

            for filename in args.extra_files or []:
                _copy_with_mkdir(filename, docker_dir)
                cksum += [(filename, _file_checksum(filename))]

            argv += ["--build-arg=" + k.lower() + "=" + v
                     for k, v in os.environ.items()
                     if k.lower() in FILTERED_ENV_NAMES]
            dkr.build_image(tag, docker_dir, dockerfile,
                            quiet=args.quiet, user=args.user,
                            argv=argv, registry=args.registry,
                            extra_files_cksum=cksum)

            rmtree(docker_dir)

        return 0


class UpdateCommand(SubCommand):
    """ Update a docker image with new executables. Args: <tag> <executable>"""
    name = "update"

    def args(self, parser):
        parser.add_argument("tag",
                            help="Image Tag")
        parser.add_argument("executable",
                            help="Executable to copy")

    def run(self, args, argv):
        # Create a temporary tarball with our whole build context and
        # dockerfile for the update
        tmp = tempfile.NamedTemporaryFile(suffix="dckr.tar.gz")
        tmp_tar = TarFile(fileobj=tmp, mode='w')

        # Add the executable to the tarball, using the current
        # configured binfmt_misc path. If we don't get a path then we
        # only need the support libraries copied
        ff, enabled = _check_binfmt_misc(args.executable)

        if not enabled:
            print("binfmt_misc not enabled, update disabled")
            return 1

        if ff:
            tmp_tar.add(args.executable, arcname=ff)

        # Add any associated libraries
        libs = _get_so_libs(args.executable)
        if libs:
            for l in libs:
                tmp_tar.add(os.path.realpath(l), arcname=l)

        # Create a Docker buildfile
        df = StringIO()
        df.write("FROM %s\n" % args.tag)
        df.write("ADD . /\n")
        df.seek(0)

        df_tar = TarInfo(name="Dockerfile")
        df_tar.size = len(df.buf)
        tmp_tar.addfile(df_tar, fileobj=df)

        tmp_tar.close()

        # reset the file pointers
        tmp.flush()
        tmp.seek(0)

        # Run the build with our tarball context
        dkr = Docker()
        dkr.update_image(args.tag, tmp, quiet=args.quiet)

        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)


class ProbeCommand(SubCommand):
    """Probe if we can run docker automatically"""
    name = "probe"

    def run(self, args, argv):
        try:
            docker = Docker()
            if docker._command[0] == "docker":
                print("docker")
            elif docker._command[0] == "sudo":
                print("sudo docker")
            elif docker._command[0] == "podman":
                print("podman")
        except Exception:
            print("no")

        return


class CcCommand(SubCommand):
    """Compile sources with cc in images"""
    name = "cc"

    def args(self, parser):
        parser.add_argument("--image", "-i", required=True,
                            help="The docker image in which to run cc")
        parser.add_argument("--cc", default="cc",
                            help="The compiler executable to call")
        parser.add_argument("--source-path", "-s", nargs="*", dest="paths",
                            help="""Extra paths to (ro) mount into container for
                            reading sources""")

    def run(self, args, argv):
        if argv and argv[0] == "--":
            argv = argv[1:]
        cwd = os.getcwd()
        cmd = ["--rm", "-w", cwd,
               "-v", "%s:%s:rw" % (cwd, cwd)]
        if args.paths:
            for p in args.paths:
                cmd += ["-v", "%s:%s:ro,z" % (p, p)]
        cmd += [args.image, args.cc]
        cmd += argv
        return Docker().run(cmd, False, quiet=args.quiet,
                            as_user=True)


class CheckCommand(SubCommand):
    """Check if we need to re-build a docker image out of a dockerfile.
    Arguments: <tag> <dockerfile>"""
    name = "check"

    def args(self, parser):
        parser.add_argument("tag",
                            help="Image Tag")
        parser.add_argument("dockerfile", default=None,
                            help="Dockerfile name", nargs='?')
        parser.add_argument("--checktype", choices=["checksum", "age"],
                            default="checksum", help="check type")
        parser.add_argument("--olderthan", default=60, type=int,
                            help="number of minutes")

    def run(self, args, argv):
        tag = args.tag

        try:
            dkr = Docker()
        except subprocess.CalledProcessError:
            print("Docker not set up")
            return 1

        info = dkr.inspect_tag(tag)
        if info is None:
            print("Image does not exist")
            return 1

        if args.checktype == "checksum":
            if not args.dockerfile:
                print("Need a dockerfile for tag:%s" % (tag))
                return 1

            dockerfile = _read_dockerfile(args.dockerfile)

            if dkr.image_matches_dockerfile(tag, dockerfile):
                if not args.quiet:
                    print("Image is up to date")
                return 0
            else:
                print("Image needs updating")
                return 1
        elif args.checktype == "age":
            timestr = dkr.get_image_creation_time(info).split(".")[0]
            created = datetime.strptime(timestr, "%Y-%m-%dT%H:%M:%S")
            past = datetime.now() - timedelta(minutes=args.olderthan)
            if created < past:
                print ("Image created @ %s more than %d minutes old" %
                       (timestr, args.olderthan))
                return 1
            else:
                if not args.quiet:
                    print ("Image less than %d minutes old" % (args.olderthan))
                return 0


def main():
    global USE_ENGINE

    parser = argparse.ArgumentParser(description="A Docker helper",
                                     usage="%s <subcommand> ..." %
                                     os.path.basename(sys.argv[0]))
    parser.add_argument("--engine", type=EngineEnum.argparse, choices=list(EngineEnum),
                        help="specify which container engine to use")
    subparsers = parser.add_subparsers(title="subcommands", help=None)
    for cls in SubCommand.__subclasses__():
        cmd = cls()
        subp = subparsers.add_parser(cmd.name, help=cmd.__doc__)
        cmd.shared_args(subp)
        cmd.args(subp)
        subp.set_defaults(cmdobj=cmd)
    args, argv = parser.parse_known_args()
    if args.engine:
        USE_ENGINE = args.engine
    return args.cmdobj.run(args, argv)


if __name__ == "__main__":
    sys.exit(main())
