#!/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
import getpass
from tarfile import TarFile, TarInfo
from io import StringIO, BytesIO
from shutil import copy, rmtree
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='.', name=None):
    """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, name if name else os.path.basename(src))

    try:
        copy(src, dest_file)
    except FileNotFoundError:
        print("Couldn't copy %s to %s" % (src, dest_file))
        pass


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(search.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)
            name = os.path.basename(l)
            real_l = os.path.realpath(l)
            _copy_with_mkdir(real_l, dest_dir, so_path, name)


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_verify_flat(df):
    "Verify we do not include other qemu/ layers"
    for l in df.splitlines():
        if len(l.strip()) == 0 or l.startswith("#"):
            continue
        from_pref = "FROM qemu/"
        if l.startswith(from_pref):
            print("We no longer support multiple QEMU layers.")
            print("Dockerfiles should be flat, ideally created by lcitool")
            return False
    return True


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 and
            "GITLAB_CI" 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 = []

        if not _dockerfile_verify_flat(dockerfile):
            return -1

        checksum = _text_checksum(dockerfile)

        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 = getpass.getuser()
            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\n" % (checksum))
        for f, c in extra_files_cksum:
            tmp_df.write("LABEL com.qemu.%s-checksum=%s\n" % (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)

    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", "--rm", "--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("--skip-binfmt",
                            action="store_true",
                            help="""Skip binfmt entry check (used for testing)""")
        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.skip_binfmt:
                qpath = args.include_executable
            elif 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 FetchCommand(SubCommand):
    """ Fetch a docker image from the registry. Args: <tag> <registry>"""
    name = "fetch"

    def args(self, parser):
        parser.add_argument("tag",
                            help="Local tag for image")
        parser.add_argument("registry",
                            help="Docker registry")

    def run(self, args, argv):
        dkr = Docker()
        dkr.command(cmd="pull", quiet=args.quiet,
                    argv=["%s/%s" % (args.registry, args.tag)])
        dkr.command(cmd="tag", quiet=args.quiet,
                    argv=["%s/%s" % (args.registry, args.tag), args.tag])


class UpdateCommand(SubCommand):
    """ Update a docker image. Args: <tag> <actions>"""
    name = "update"

    def args(self, parser):
        parser.add_argument("tag",
                            help="Image Tag")
        parser.add_argument("--executable",
                            help="Executable to copy")
        parser.add_argument("--add-current-user", "-u", dest="user",
                            action="store_true",
                            help="Add the current user to image's passwd")

    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')

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

        if args.executable:
            # 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:
                    so_path = os.path.dirname(l)
                    name = os.path.basename(l)
                    real_l = os.path.realpath(l)
                    try:
                        tmp_tar.add(real_l, arcname="%s/%s" % (so_path, name))
                    except FileNotFoundError:
                        print("Couldn't add %s/%s to archive" % (so_path, name))
                        pass

            df.write(u"ADD . /\n")

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

        df_bytes = BytesIO(bytes(df.getvalue(), "UTF-8"))

        df_tar = TarInfo(name="Dockerfile")
        df_tar.size = df_bytes.getbuffer().nbytes
        tmp_tar.addfile(df_tar, fileobj=df_bytes)

        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 = ["-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)


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())
