# Lint as: python2, python3
# Copyright (c) 2013 The Chromium OS Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.

from __future__ import absolute_import
from __future__ import division
from __future__ import print_function

import errno
import os
import shutil
import six
import time

from autotest_lib.client.bin import utils

class NetworkChroot(object):
    """Implements a chroot environment that runs in a separate network
    namespace from the caller.  This is useful for network tests that
    involve creating a server on the other end of a virtual ethernet
    pair.  This object is initialized with an interface name to pass
    to the chroot, as well as the IP address to assign to this
    interface, since in passing the interface into the chroot, any
    pre-configured address is removed.

    The startup of the chroot is an orchestrated process where a
    small startup script is run to perform the following tasks:
      - Write out pid file which will be a handle to the
        network namespace that that |interface| should be passed to.
      - Wait for the network namespace to be passed in, by performing
        a "sleep" and writing the pid of this process as well.  Our
        parent will kill this process to resume the startup process.
      - We can now configure the network interface with an address.
      - At this point, we can now start any user-requested server
        processes.
    """
    BIND_ROOT_DIRECTORIES = ('bin', 'dev', 'dev/pts', 'lib', 'lib32', 'lib64',
                             'proc', 'sbin', 'sys', 'usr', 'usr/local')
    # Subset of BIND_ROOT_DIRECTORIES that should be mounted writable.
    BIND_ROOT_WRITABLE_DIRECTORIES = frozenset(('dev/pts',))
    # Directories we'll bind mount when we want to bridge DBus namespaces.
    # Includes directories containing the system bus socket and machine ID.
    DBUS_BRIDGE_DIRECTORIES = ('run/dbus/', 'var/lib/dbus/')

    ROOT_DIRECTORIES = ('etc', 'etc/ssl', 'tmp', 'var', 'var/log', 'run',
                        'run/lock')
    ROOT_SYMLINKS = (
        ('var/run', '/run'),
        ('var/lock', '/run/lock'),
    )
    STARTUP = 'etc/chroot_startup.sh'
    STARTUP_DELAY_SECONDS = 5
    STARTUP_PID_FILE = 'run/vpn_startup.pid'
    STARTUP_SLEEPER_PID_FILE = 'run/vpn_sleeper.pid'
    COPIED_CONFIG_FILES = [
        'etc/ld.so.cache',
        'etc/ssl/openssl.cnf.compat'
    ]
    CONFIG_FILE_TEMPLATES = {
        STARTUP:
            '#!/bin/sh\n'
            'exec > /var/log/startup.log 2>&1\n'
            'set -x\n'
            'echo $$ > /%(startup-pidfile)s\n'
            'sleep %(startup-delay-seconds)d &\n'
            'echo $! > /%(sleeper-pidfile)s &\n'
            'wait\n'
            'ip addr add %(local-ip-and-prefix)s dev %(local-interface-name)s\n'
            'ip link set %(local-interface-name)s up\n'
            # For running strongSwan VPN with flag --with-piddir=/run/ipsec. We
            # want to use /run/ipsec for strongSwan runtime data dir instead of
            # /run, and the cmdline flag applies to both client and server.
            'mkdir -p /run/ipsec\n'
    }
    CONFIG_FILE_VALUES = {
        'sleeper-pidfile': STARTUP_SLEEPER_PID_FILE,
        'startup-delay-seconds': STARTUP_DELAY_SECONDS,
        'startup-pidfile': STARTUP_PID_FILE
    }

    def __init__(self, interface, address, prefix):
        self._interface = interface

        # Copy these values from the class-static since specific instances
        # of this class are allowed to modify their contents.
        self._bind_root_directories = list(self.BIND_ROOT_DIRECTORIES)
        self._root_directories = list(self.ROOT_DIRECTORIES)
        self._copied_config_files = list(self.COPIED_CONFIG_FILES)
        self._config_file_templates = self.CONFIG_FILE_TEMPLATES.copy()
        self._config_file_values = self.CONFIG_FILE_VALUES.copy()
        self._env = dict(os.environ)

        self._config_file_values.update({
            'local-interface-name': interface,
            'local-ip': address,
            'local-ip-and-prefix': '%s/%d' % (address, prefix)
        })


    def startup(self):
        """Create the chroot and start user processes."""
        self.make_chroot()
        self.write_configs()
        self.run(['/bin/bash', os.path.join('/', self.STARTUP), '&'])
        self.move_interface_to_chroot_namespace()
        self.kill_pid_file(self.STARTUP_SLEEPER_PID_FILE)


    def shutdown(self):
        """Remove the chroot filesystem in which the VPN server was running"""
        # TODO(pstew): Some processes take a while to exit, which will cause
        # the cleanup below to fail to complete successfully...
        time.sleep(10)
        utils.system_output('rm -rf --one-file-system %s' % self._temp_dir,
                            ignore_status=True)


    def add_config_templates(self, template_dict):
        """Add a filename-content dict to the set of templates for the chroot

        @param template_dict dict containing filename-content pairs for
            templates to be applied to the chroot.  The keys to this dict
            should not contain a leading '/'.

        """
        self._config_file_templates.update(template_dict)


    def add_config_values(self, value_dict):
        """Add a name-value dict to the set of values for the config template

        @param value_dict dict containing key-value pairs of values that will
            be applied to the config file templates.

        """
        self._config_file_values.update(value_dict)


    def add_copied_config_files(self, files):
        """Add |files| to the set to be copied to the chroot.

        @param files iterable object containing a list of files to
            be copied into the chroot.  These elements should not contain a
            leading '/'.

        """
        self._copied_config_files += files


    def add_root_directories(self, directories):
        """Add |directories| to the set created within the chroot.

        @param directories list/tuple containing a list of directories to
            be created in the chroot.  These elements should not contain a
            leading '/'.

        """
        self._root_directories += directories


    def add_startup_command(self, command):
        """Add a command to the script run when the chroot starts up.

        @param command string containing the command line to run.

        """
        self._config_file_templates[self.STARTUP] += '%s\n' % command


    def add_environment(self, env_dict):
        """Add variables to the chroot environment.

        @param env_dict dict dictionary containing environment variables
        """
        self._env.update(env_dict)


    def get_log_contents(self):
        """Return the logfiles from the chroot."""
        return utils.system_output("head -10000 %s" %
                                   self.chroot_path("var/log/*"))


    def bridge_dbus_namespaces(self):
        """Make the system DBus daemon visible inside the chroot."""
        # Need the system socket and the machine-id.
        self._bind_root_directories += self.DBUS_BRIDGE_DIRECTORIES


    def chroot_path(self, path):
        """Returns the the path within the chroot for |path|.

        @param path string filename within the choot.  This should not
            contain a leading '/'.

        """
        return os.path.join(self._temp_dir, path.lstrip('/'))


    def get_pid_file(self, pid_file, missing_ok=False):
        """Returns the integer contents of |pid_file| in the chroot.

        @param pid_file string containing the filename within the choot
            to read and convert to an integer.  This should not contain a
            leading '/'.
        @param missing_ok bool indicating whether exceptions due to failure
            to open the pid file should be caught.  If true a missing pid
            file will cause this method to return 0.  If false, a missing
            pid file will cause an exception.

        """
        chroot_pid_file = self.chroot_path(pid_file)
        try:
            with open(chroot_pid_file) as f:
                return int(f.read())
        except IOError as e:
            if not missing_ok or e.errno != errno.ENOENT:
                raise e

            return 0


    def kill_pid_file(self, pid_file, missing_ok=False):
        """Kills the process belonging to |pid_file| in the chroot.

        @param pid_file string filename within the chroot to gain the process ID
            which this method will kill.
        @param missing_ok bool indicating whether a missing pid file is okay,
            and should be ignored.

        """
        pid = self.get_pid_file(pid_file, missing_ok=missing_ok)
        if missing_ok and pid == 0:
            return
        utils.system('kill %d' % pid, ignore_status=True)


    def make_chroot(self):
        """Make a chroot filesystem."""
        self._temp_dir = utils.system_output(
                'mktemp -d /usr/local/tmp/chroot.XXXXXXXXX')
        utils.system('chmod go+rX %s' % self._temp_dir)
        for rootdir in self._root_directories:
            os.mkdir(self.chroot_path(rootdir))

        self._jail_args = []
        for rootdir in self._bind_root_directories:
            src_path = os.path.join('/', rootdir)
            dst_path = self.chroot_path(rootdir)
            if not os.path.exists(src_path):
                continue
            elif os.path.islink(src_path):
                link_path = os.readlink(src_path)
                os.symlink(link_path, dst_path)
            else:
                os.makedirs(dst_path)  # Recursively create directories.
                mount_arg = '%s,%s' % (src_path, src_path)
                if rootdir in self.BIND_ROOT_WRITABLE_DIRECTORIES:
                    mount_arg += ',1'
                self._jail_args += [ '-b', mount_arg ]

        for config_file in self._copied_config_files:
            src_path = os.path.join('/', config_file)
            dst_path = self.chroot_path(config_file)
            if os.path.exists(src_path):
                shutil.copyfile(src_path, dst_path)

        for src_path, target_path in self.ROOT_SYMLINKS:
            link_path = self.chroot_path(src_path)
            os.symlink(target_path, link_path)


    def move_interface_to_chroot_namespace(self):
        """Move network interface to the network namespace of the server."""
        utils.system('ip link set %s netns %d' %
                     (self._interface,
                      self.get_pid_file(self.STARTUP_PID_FILE)))


    def run(self, args, ignore_status=False):
        """Run a command in a chroot, within a separate network namespace.

        @param args list containing the command line arguments to run.
        @param ignore_status bool set to true if a failure should be ignored.

        """
        utils.run('minijail0 -e -C %s %s' %
                  (self._temp_dir, ' '.join(self._jail_args + args)),
                  timeout=None,
                  ignore_status=ignore_status,
                  stdout_tee=utils.TEE_TO_LOGS,
                  stderr_tee=utils.TEE_TO_LOGS,
                  env=self._env)


    def write_configs(self):
        """Write out config files"""
        for config_file, template in six.iteritems(self._config_file_templates):
            with open(self.chroot_path(config_file), 'w') as f:
                f.write(template % self._config_file_values)
