# 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.

import errno
import os
import shutil
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',  'tmp', 'var', 'var/log', 'var/run')
    STARTUP = 'etc/chroot_startup.sh'
    STARTUP_DELAY_SECONDS = 5
    STARTUP_PID_FILE = 'var/run/vpn_startup.pid'
    STARTUP_SLEEPER_PID_FILE = 'var/run/vpn_sleeper.pid'
    COPIED_CONFIG_FILES = [
        'etc/ld.so.cache'
    ]
    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'
    }
    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._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 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, 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 /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)


    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.system('minijail0 -e -C %s %s' %
                     (self._temp_dir, ' '.join(self._jail_args + args)),
                     ignore_status=ignore_status)


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