# Copyright 2015 The Chromium Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.

"""
This module helps to deploy config files and shared folders from host to
container. It reads the settings from a setting file (ssp_deploy_config), and
deploy the config files based on the settings. The setting file has a json
string of a list of deployment settings. For example:
[{
    "source": "/etc/resolv.conf",
    "target": "/etc/resolv.conf",
    "append": true,
    "permission": 400
 },
 {
    "source": "ssh",
    "target": "/root/.ssh",
    "append": false,
    "permission": 400
 },
 {
    "source": "/usr/local/autotest/results/shared",
    "target": "/usr/local/autotest/results/shared",
    "mount": true,
    "readonly": false,
    "force_create": true
 }
]

Definition of each attribute for config files are as follows:
source: config file in host to be copied to container.
target: config file's location inside container.
append: true to append the content of config file to existing file inside
        container. If it's set to false, the existing file inside container will
        be overwritten.
permission: Permission to set to the config file inside container.

Example:
{
    "source": "/etc/resolv.conf",
    "target": "/etc/resolv.conf",
    "append": true,
    "permission": 400
}
The above example will:
1. Append the content of /etc/resolv.conf in host machine to file
   /etc/resolv.conf inside container.
2. Copy all files in ssh to /root/.ssh in container.
3. Change all these files' permission to 400

Definition of each attribute for sharing folders are as follows:
source: a folder in host to be mounted in container.
target: the folder's location inside container.
mount: true to mount the source folder onto the target inside container.
       A setting with false value of mount is invalid.
readonly: true if the mounted folder inside container should be readonly.
force_create: true to create the source folder if it doesn't exist.

Example:
 {
    "source": "/usr/local/autotest/results/shared",
    "target": "/usr/local/autotest/results/shared",
    "mount": true,
    "readonly": false,
    "force_create": true
 }
The above example will mount folder "/usr/local/autotest/results/shared" in the
host to path "/usr/local/autotest/results/shared" inside the container. The
folder can be written to inside container. If the source folder doesn't exist,
it will be created as `force_create` is set to true.

The setting file (ssp_deploy_config) lives in AUTOTEST_DIR folder.
For relative file path specified in ssp_deploy_config, AUTOTEST_DIR/containers
is the parent folder.
The setting file can be overridden by a shadow config, ssp_deploy_shadow_config.
For lab servers, puppet should be used to deploy ssp_deploy_shadow_config to
AUTOTEST_DIR and the configure files to AUTOTEST_DIR/containers.

The default setting file (ssp_deploy_config) contains
For SSP to work with none-lab servers, e.g., moblab and developer's workstation,
the module still supports copy over files like ssh config and autotest
shadow_config to container when AUTOTEST_DIR/containers/ssp_deploy_config is not
presented.

"""

import collections
import getpass
import json
import os
import socket

import common
from autotest_lib.client.common_lib import global_config
from autotest_lib.client.common_lib import utils
from autotest_lib.site_utils.lxc import constants
from autotest_lib.site_utils.lxc import utils as lxc_utils


config = global_config.global_config

# Path to ssp_deploy_config and ssp_deploy_shadow_config.
SSP_DEPLOY_CONFIG_FILE = os.path.join(common.autotest_dir,
                                      'ssp_deploy_config.json')
SSP_DEPLOY_SHADOW_CONFIG_FILE = os.path.join(common.autotest_dir,
                                             'ssp_deploy_shadow_config.json')
# A temp folder used to store files to be appended to the files inside
# container.
_APPEND_FOLDER = '/usr/local/ssp_append'

DeployConfig = collections.namedtuple(
        'DeployConfig', ['source', 'target', 'append', 'permission'])
MountConfig = collections.namedtuple(
        'MountConfig', ['source', 'target', 'mount', 'readonly',
                        'force_create'])


class SSPDeployError(Exception):
    """Exception raised if any error occurs when setting up test container."""


class DeployConfigManager(object):
    """An object to deploy config to container.

    The manager retrieves deploy configs from ssp_deploy_config or
    ssp_deploy_shadow_config, and sets up the container accordingly.
    For example:
    1. Copy given config files to specified location inside container.
    2. Append the content of given config files to specific files inside
       container.
    3. Make sure the config files have proper permission inside container.

    """

    @staticmethod
    def validate_path(deploy_config):
        """Validate the source and target in deploy_config dict.

        @param deploy_config: A dictionary of deploy config to be validated.

        @raise SSPDeployError: If any path in deploy config is invalid.
        """
        target = deploy_config['target']
        source = deploy_config['source']
        if not os.path.isabs(target):
            raise SSPDeployError('Target path must be absolute path: %s' %
                                 target)
        if not os.path.isabs(source):
            if source.startswith('~'):
                # This is to handle the case that the script is run with sudo.
                inject_user_path = ('~%s%s' % (utils.get_real_user(),
                                               source[1:]))
                source = os.path.expanduser(inject_user_path)
            else:
                source = os.path.join(common.autotest_dir, source)
            # Update the source setting in deploy config with the updated path.
            deploy_config['source'] = source


    @staticmethod
    def validate(deploy_config):
        """Validate the deploy config.

        Deploy configs need to be validated and pre-processed, e.g.,
        1. Target must be an absolute path.
        2. Source must be updated to be an absolute path.

        @param deploy_config: A dictionary of deploy config to be validated.

        @return: A DeployConfig object that contains the deploy config.

        @raise SSPDeployError: If the deploy config is invalid.

        """
        DeployConfigManager.validate_path(deploy_config)
        return DeployConfig(**deploy_config)


    @staticmethod
    def validate_mount(deploy_config):
        """Validate the deploy config for mounting a directory.

        Deploy configs need to be validated and pre-processed, e.g.,
        1. Target must be an absolute path.
        2. Source must be updated to be an absolute path.
        3. Mount must be true.

        @param deploy_config: A dictionary of deploy config to be validated.

        @return: A DeployConfig object that contains the deploy config.

        @raise SSPDeployError: If the deploy config is invalid.

        """
        DeployConfigManager.validate_path(deploy_config)
        c = MountConfig(**deploy_config)
        if not c.mount:
            raise SSPDeployError('`mount` must be true.')
        if not c.force_create and not os.path.exists(c.source):
            raise SSPDeployError('`source` does not exist.')
        return c


    def __init__(self, container, config_file=None):
        """Initialize the deploy config manager.

        @param container: The container needs to deploy config.
        @param config_file: An optional config file.  For testing.
        """
        self.container = container
        # If shadow config is used, the deployment procedure will skip some
        # special handling of config file, e.g.,
        # 1. Set enable_master_ssh to False in autotest shadow config.
        # 2. Set ssh logleve to ERROR for all hosts.
        if config_file is None:
            self.is_shadow_config = os.path.exists(
                    SSP_DEPLOY_SHADOW_CONFIG_FILE)
            config_file = (
                    SSP_DEPLOY_SHADOW_CONFIG_FILE if self.is_shadow_config
                    else SSP_DEPLOY_CONFIG_FILE)
        else:
            self.is_shadow_config = False

        with open(config_file) as f:
            deploy_configs = json.load(f)
        self.deploy_configs = [self.validate(c) for c in deploy_configs
                               if 'append' in c]
        self.mount_configs = [self.validate_mount(c) for c in deploy_configs
                              if 'mount' in c]
        tmp_append = os.path.join(self.container.rootfs,
                                  _APPEND_FOLDER.lstrip(os.path.sep))
        commands = []
        if lxc_utils.path_exists(tmp_append):
            commands = ['rm -rf "%s"' % tmp_append]
        commands.append('mkdir -p "%s"' % tmp_append)
        lxc_utils.sudo_commands(commands)


    def _deploy_config_pre_start(self, deploy_config):
        """Deploy a config before container is started.

        Most configs can be deployed before the container is up. For configs
        require a reboot to take effective, they must be deployed in this
        function.

        @param deploy_config: Config to be deployed.
        """
        if not lxc_utils.path_exists(deploy_config.source):
            return
        # Path to the target file relative to host.
        if deploy_config.append:
            target = os.path.join(_APPEND_FOLDER,
                                  os.path.basename(deploy_config.target))
        else:
            target = deploy_config.target

        self.container.copy(deploy_config.source, target)


    def _deploy_config_post_start(self, deploy_config):
        """Deploy a config after container is started.

        For configs to be appended after the existing config files in container,
        they must be copied to a temp location before container is up (deployed
        in function _deploy_config_pre_start). After the container is up, calls
        can be made to append the content of such configs to existing config
        files.

        @param deploy_config: Config to be deployed.

        """
        if deploy_config.append:
            source = os.path.join(_APPEND_FOLDER,
                                  os.path.basename(deploy_config.target))
            self.container.attach_run('cat \'%s\' >> \'%s\'' %
                                      (source, deploy_config.target))
        self.container.attach_run(
                'chmod -R %s \'%s\'' %
                (deploy_config.permission, deploy_config.target))


    def _modify_shadow_config(self):
        """Update the shadow config used in container with correct values.

        This only applies when no shadow SSP deploy config is applied. For
        default SSP deploy config, autotest shadow_config.ini is from autotest
        directory, which requires following modification to be able to work in
        container. If one chooses to use a shadow SSP deploy config file, the
        autotest shadow_config.ini must be from a source with following
        modification:
        1. Disable master ssh connection in shadow config, as it is not working
           properly in container yet, and produces noise in the log.
        2. Update AUTOTEST_WEB/host and SERVER/hostname to be the IP of the host
           if any is set to localhost or 127.0.0.1. Otherwise, set it to be the
           FQDN of the config value.
        3. Update SSP/user, which is used as the user makes RPC inside the
           container. This allows the RPC to pass ACL check as if the call is
           made in the host.

        """
        shadow_config = os.path.join(constants.CONTAINER_AUTOTEST_DIR,
                                     'shadow_config.ini')

        # Inject "AUTOSERV/enable_master_ssh: False" in shadow config as
        # container does not support master ssh connection yet.
        self.container.attach_run(
                'echo $\'\n[AUTOSERV]\nenable_master_ssh: False\n\' >> %s' %
                shadow_config)

        host_ip = lxc_utils.get_host_ip()
        local_names = ['localhost', '127.0.0.1']

        db_host = config.get_config_value('AUTOTEST_WEB', 'host')
        if db_host.lower() in local_names:
            new_host = host_ip
        else:
            new_host = socket.getfqdn(db_host)
        self.container.attach_run('echo $\'\n[AUTOTEST_WEB]\nhost: %s\n\' >> %s'
                                  % (new_host, shadow_config))

        afe_host = config.get_config_value('SERVER', 'hostname')
        if afe_host.lower() in local_names:
            new_host = host_ip
        else:
            new_host = socket.getfqdn(afe_host)
        self.container.attach_run('echo $\'\n[SERVER]\nhostname: %s\n\' >> %s' %
                                  (new_host, shadow_config))

        # Update configurations in SSP section:
        # user: The user running current process.
        # is_moblab: True if the autotest server is a Moblab instance.
        # host_container_ip: IP address of the lxcbr0 interface. Process running
        #     inside container can make RPC through this IP.
        self.container.attach_run(
                'echo $\'\n[SSP]\nuser: %s\nis_moblab: %s\n'
                'host_container_ip: %s\n\' >> %s' %
                (getpass.getuser(), bool(utils.is_moblab()),
                 lxc_utils.get_host_ip(), shadow_config))


    def _modify_ssh_config(self):
        """Modify ssh config for it to work inside container.

        This is only called when default ssp_deploy_config is used. If shadow
        deploy config is manually set up, this function will not be called.
        Therefore, the source of ssh config must be properly updated to be able
        to work inside container.

        """
        # Remove domain specific flags.
        ssh_config = '/root/.ssh/config'
        self.container.attach_run('sed -i \'s/UseProxyIf=false//g\' \'%s\'' %
                                  ssh_config)
        # TODO(dshi): crbug.com/451622 ssh connection loglevel is set to
        # ERROR in container before master ssh connection works. This is
        # to avoid logs being flooded with warning `Permanently added
        # '[hostname]' (RSA) to the list of known hosts.` (crbug.com/478364)
        # The sed command injects following at the beginning of .ssh/config
        # used in config. With such change, ssh command will not post
        # warnings.
        # Host *
        #   LogLevel Error
        self.container.attach_run(
                'sed -i \'1s/^/Host *\\n  LogLevel ERROR\\n\\n/\' \'%s\'' %
                ssh_config)

        # Inject ssh config for moblab to ssh to dut from container.
        if utils.is_moblab():
            # ssh to moblab itself using moblab user.
            self.container.attach_run(
                    'echo $\'\nHost 192.168.231.1\n  User moblab\n  '
                    'IdentityFile %%d/.ssh/testing_rsa\' >> %s' %
                    '/root/.ssh/config')
            # ssh to duts using root user.
            self.container.attach_run(
                    'echo $\'\nHost *\n  User root\n  '
                    'IdentityFile %%d/.ssh/testing_rsa\' >> %s' %
                    '/root/.ssh/config')


    def deploy_pre_start(self):
        """Deploy configs before the container is started.
        """
        for deploy_config in self.deploy_configs:
            self._deploy_config_pre_start(deploy_config)
        for mount_config in self.mount_configs:
            if (mount_config.force_create and
                not os.path.exists(mount_config.source)):
                utils.run('mkdir -p %s' % mount_config.source)
            self.container.mount_dir(mount_config.source,
                                     mount_config.target,
                                     mount_config.readonly)


    def deploy_post_start(self):
        """Deploy configs after the container is started.
        """
        for deploy_config in self.deploy_configs:
            self._deploy_config_post_start(deploy_config)
        # Autotest shadow config requires special handling to update hostname
        # of `localhost` with host IP. Shards always use `localhost` as value
        # of SERVER\hostname and AUTOTEST_WEB\host.
        self._modify_shadow_config()
        # Only apply special treatment for files deployed by the default
        # ssp_deploy_config
        if not self.is_shadow_config:
            self._modify_ssh_config()
