def prepare_certs_and_keys_on_host(session, host, certs_dir, key_name):
    """
    Prepare certificates and keys on the host

    :param session: RemoteSession object for host connection
    :param host: dictionary with the host information
    :param certs_dir: path pointing to directory with certificates
    :param key_name: string with a name used for a key and certificate
    :returns: tuple of paths for key and certificate
    """
    libvirt_pki_private_dir = '/etc/pki/libvirt/private'
    libvirt_pki_dir = '/etc/pki/libvirt'
    cmd = "mkdir -p {}".format(libvirt_pki_private_dir)
    status, output = session.cmd_status_output(cmd)
    logging.debug(
        "Making directory for certificates has failed due to: {}".format(
            output))
    src_key_path = os.path.join(certs_dir, key_name + 'key.pem')
    src_cert_path = os.path.join(certs_dir, key_name + 'cert.pem')
    dest_key_path = os.path.join(libvirt_pki_private_dir,
                                 key_name[:-1] + 'key.pem')
    dest_cert_path = os.path.join(libvirt_pki_dir, key_name[:-1] + 'cert.pem')
    # SCP server cert and server key to server
    remote.copy_files_to(host['ip'], 'scp', host['user'], host['pwd'], '22',
                         src_key_path, dest_key_path)
    remote.copy_files_to(host['ip'], 'scp', host['user'], host['pwd'], '22',
                         src_cert_path, dest_cert_path)
    return dest_key_path, dest_cert_path
Beispiel #2
0
 def _reset_file(self):
     """
     Copy backup from local to remote.
     """
     if self.client == "test":
         shutil.copy(self.backup_path, self.remote_path)
     else:
         remote.copy_files_to(self.address, self.client, self.username,
                              self.password, self.port, self.backup_path,
                              self.remote_path, self.limit,
                              self.log_filename, self.verbose, self.timeout)
Beispiel #3
0
 def push_file(self, local_path, timeout=600):
     """
     Copy file from local to remote.
     """
     logging.debug("Push local: '%s' to remote: '%s'." %
                   (local_path, self.remote_path))
     remote.copy_files_to(self.address,
                          self.cp_client,
                          self.username,
                          self.password,
                          self.cp_port,
                          local_path,
                          self.remote_path,
                          timeout=timeout)
def copy_ca_certs_to_hosts(certs_dir, *host_info):
    """
    Copy certificates to required destination path

    :param certs_dir: path pointing to directory with certificates
    :param host_info: multiple dictionaries with the host information
    :returns: path to destination CA certificate
    """
    ca_cert_path = os.path.join(certs_dir, 'cacert.pem')
    remote_ca_cert_path = '/etc/pki/CA/cacert.pem'
    try:
        for host in host_info:
            remote.copy_files_to(host['ip'], 'scp', host['user'], host['pwd'],
                                 '22', ca_cert_path, remote_ca_cert_path)
    except remote.SCPError as detail:
        raise exceptions.TestError(detail)
    return remote_ca_cert_path
Beispiel #5
0
def _copy_control(session, control_path, is_utility=False):
    remote_dir = REMOTE_PYTHON_PATH if is_utility else REMOTE_CONTROL_DIR
    # run on remote Linux hosts
    if session.client == "ssh":
        transfer_client = "scp"
        transfer_port = 22
        remote_control_path = os.path.join(remote_dir,
                                           os.path.basename(control_path))
    # run on remote Windows hosts
    elif session.client == "nc":
        transfer_client = "rss"
        transfer_port = 10023
        # ..todo:: use `remote_dir` here
        remote_control_path = "%TEMP%\\" + os.path.basename(control_path)
    else:
        raise NotImplementedError(
            "run_subcontrol not implemented for client %s" % session.client)
    remote.copy_files_to(session.host, transfer_client, session.username,
                         session.password, transfer_port, control_path,
                         remote_control_path)
    return remote_control_path
Beispiel #6
0
def share_remote_objects(session,
                         control_path,
                         host="localhost",
                         port=9090,
                         os_type="windows",
                         extra_params=None):
    """
    Create and share remote objects from a remote location over the network.

    :param session: remote session to the platform
    :type session: RemoteSession
    :param str control_path: path to the control on the host
    :param str host: ip address of the remote sharing server
    :param int port: port of the remote sharing server
    :param str os_type: OS type of the session, either "linux" or "windows"
    :param extra_params: extra parameters to pass to the remote object sharing
                         control file (sismilarly to subcontrol setting above),
                         with keys usually prepended with "ro_" prefix
    :type extra_params: {str, str}
    :returns: newly created middleware session for the remote object server
    :rtype: :py:class:`RemoteSession`
    :raises: :py:class:`RuntimeError` if the object server failed to start

    In comparison to :py:func:`share_local_object`, this function fires up a
    name server from a second spawned session (not remote util call) and uses
    static (template) control as a remote object server which has to be
    preprogrammed but thus also customized (e.g. sharing multiple objects).

    In comparison to :py:func:`share_local_objects`, this function is not
    an internal implementation sharing everything on the other side but only
    what is dicated by the remote object server module and thus its creator.

    .. note:: Created and works specifically for Windows and Linux.
    """
    LOG.info("Sharing the remote objects over the network")
    extra_params = {} if extra_params is None else extra_params

    # setup remote objects server
    LOG.info("Starting nameserver for the remote objects")
    cmd = "python -m Pyro4.naming -n %s -p %s" % (host, port)
    session.cmd("START " + cmd if os_type == "windows" else cmd + " &")

    LOG.info("Starting the server daemon for the remote objects")
    # ..todo:: later on we can dynamize this further depending on usage of this alternative function
    transfer_client = "rss" if os_type == "windows" else "scp"
    transfer_port = 10023 if os_type == "windows" else 22
    local_path = set_subcontrol_parameter(control_path, "ro_server_ip", host)
    # optional parameters (set only if present and/or available)
    for key in extra_params.keys():
        local_path = set_subcontrol_parameter(local_path, key,
                                              extra_params[key])
    remote_path = os.path.join(REMOTE_CONTROL_DIR,
                               os.path.basename(control_path))
    # NOTE: since we are creating the path in Linux but use it in Windows,
    # we replace some of the backslashes
    if os_type == "windows":
        remote_path = remote_path.replace("/", "\\")
    remote.copy_files_to(session.host,
                         transfer_client,
                         session.username,
                         session.password,
                         transfer_port,
                         local_path,
                         remote_path,
                         timeout=10)
    middleware_session = remote.wait_for_login(session.client, session.host,
                                               session.port, session.username,
                                               session.password,
                                               session.prompt, session.linesep)
    middleware_session.set_status_test_command(session.status_test_command)
    middleware_session.set_output_func(LOG.info)
    middleware_session.set_output_params(())
    middleware_session.sendline("python %s" % remote_path)

    # HACK: not the best way to do this but the stderr and stdout are mixed and we
    # cannot get the exit status so we rely on the mixed stdout/stderr output
    output, attempts = "", 30
    while "Remote objects shared over the network" not in output:
        output = middleware_session.get_output()
        LOG.debug(output)
        if attempts <= 0 or "Traceback (most recent call last):" in output:
            raise RuntimeError("The remote objects server failed to start")
        attempts -= 1
        time.sleep(1)

    Pyro4.config.NS_HOST = host
    logging.getLogger("Pyro4").setLevel(10)
    return middleware_session
Beispiel #7
0
    def sync_directories(self):
        """
        Synchronize the directories between the local and remote machines
        :returns: True if any files needed to be copied; False otherwise. Does
        not support symlinks.
        """
        def get_local_hashes(path):
            """
            Create a dict of the hashes of all files in path on the local
            machine.
            :param path: Path to search
            """
            def hash_file(file_name):
                """
                Calculate hex-encoded hash of a file
                :param file_name: File to hash
                """
                f = open(file_name, mode='r')
                h = hashlib.sha1()
                while True:
                    buf = f.read(4096)
                    if not buf:
                        break
                    h.update(buf)
                return h.hexdigest()

            def visit(arg, dir_name, file_names):
                """
                Callback function to calculate and store hashes
                :param arg: Tuple with base path and the hash that will contain
                            the results.
                :param dir_name: Current directory
                :param file_names: File names in the current directory
                """
                (base_path, result) = arg
                for file_name in file_names:
                    path = os.path.join(dir_name, file_name)
                    if os.path.isfile(path):
                        result[os.path.relpath(path,
                                               base_path)] = hash_file(path)

            result = {}
            os.path.walk(path, visit, (path, result))

            return result

        def get_remote_hashes(path, session, linesep):
            """
            Create a dict of the hashes of all files in path on the remote
            machine.
            :param path: Path to search
            :param session: Session object to use
            :param linesep: Line separation string for the remote system
            """

            cmd = 'test \! -d %s || find %s -type f | xargs sha1sum' % (path,
                                                                        path)
            status, output = session.cmd_status_output(cmd)
            if not status == 0:
                raise BuildError("Unable to get hashes of remote files: '%s'" %
                                 output)
            result = {}
            # Output is "<sum>  <filename><linesep><sum>  <filename>..."
            for line in output.split(linesep):
                if re.match("^[a-f0-9]{32,}  [^ ].*$", line):
                    (h, f) = line.split(None, 1)
                    result[os.path.relpath(f, path)] = h

            return result

        def list_recursive_dirnames(path):
            """
            List all directories that exist in path on the local machine
            :param path: Path to search
            """
            def visit(arg, dir_name, file_names):
                """
                Callback function list all directories
                :param arg: Tuple with base path and the list that will contain
                            the results.
                :param dir_name: Current directory
                :param file_names: File names in the current directory
                """
                (base_path, result) = arg
                for file_name in file_names:
                    path = os.path.join(dir_name, file_name)
                    if os.path.isdir(path):
                        result.append(os.path.relpath(path, base_path))

            result = []
            os.path.walk(path, visit, (path, result))

            return result

        remote_hashes = get_remote_hashes(self.full_build_path, self.session,
                                          self.linesep)
        local_hashes = get_local_hashes(self.source)

        to_transfer = []
        for rel_path in list(local_hashes.keys()):
            rhash = remote_hashes.get(rel_path)
            if rhash is None or not rhash == local_hashes[rel_path]:
                to_transfer.append(rel_path)

        need_build = False
        if to_transfer:
            logging.info("Need to copy files to %s on target" %
                         self.full_build_path)
            need_build = True

            # Create all directories
            dirs = list_recursive_dirnames(self.source)
            if dirs:
                dirs_text = " ".join(dirs)
                fmt_arg = (self.full_build_path, self.full_build_path,
                           dirs_text)
                cmd = 'mkdir -p %s && cd %s && mkdir -p %s' % fmt_arg
            else:
                cmd = 'mkdir -p %s' % self.full_build_path
            status, output = self.session.cmd_status_output(cmd)
            if not status == 0:
                raise BuildError("Unable to create remote directories: '%s'" %
                                 output)

            # Copy files
            for file_name in to_transfer:
                local_path = os.path.join(self.source, file_name)
                remote_path = os.path.join(self.full_build_path, file_name)
                remote.copy_files_to(self.address, self.file_transfer_client,
                                     self.username, self.password,
                                     self.file_transfer_port, local_path,
                                     remote_path)

        else:
            logging.info("Directory %s on target already up-to-date" %
                         self.full_build_path)

        return need_build