示例#1
0
    def get_nodes_tasks(node_id):
        """
        :param node_id: an integer number of node id
        :return: a set of deployment tasks for corresponding node
        """
        tasks = set()
        ssh = SSHManager()

        result = ssh.execute_on_remote(ssh.admin_ip, "ls /var/log/astute")
        filenames = [filename.strip() for filename in result['stdout']]

        for filename in filenames:
            ssh.download_from_remote(
                ssh.admin_ip,
                destination="/var/log/astute/{0}".format(filename),
                target="/tmp/{0}".format(filename))

        data = fileinput.FileInput(
            files=["/tmp/{0}".format(filename) for filename in filenames],
            openhook=fileinput.hook_compressed)
        for line in data:
            if "Task time summary" in line \
                    and "node {}".format(node_id) in line:
                # FIXME: define an exact search of task
                task_name = line.split("Task time summary: ")[1].split()[0]
                check = any([excluded_task in task_name
                             for excluded_task in TASKS_BLACKLIST])
                if check:
                    continue
                tasks.add(task_name)
        return tasks
示例#2
0
文件: utils.py 项目: avgoor/fuel-qa
    def store_astute_yaml_for_one_node(nailgun_node):
        ssh_manager = SSHManager()
        if 'roles' not in nailgun_node:
            return None
        errmsg = 'Downloading "{0}.yaml" from the {1} failed'
        msg = 'File "{0}.yaml" was downloaded from the {1}'
        nodename = nailgun_node['name']
        ip = nailgun_node['ip']
        for role in nailgun_node['roles']:
            filename = '{0}/{1}-{2}-{3}.yaml'.format(settings.LOGS_DIR,
                                                     func_name,
                                                     nodename,
                                                     role)

            if not ssh_manager.isfile_on_remote(ip,
                                                '/etc/{0}.yaml'.format(role)):
                role = 'primary-' + role
            if ssh_manager.download_from_remote(ip,
                                                '/etc/{0}.yaml'.format(role),
                                                filename):
                logger.info(msg.format(role, nodename))
            else:
                logger.error(errmsg.format(role, nodename))
        if settings.DOWNLOAD_FACTS:
            fact_filename = re.sub(r'-\w*\.', '-facts.', filename)
            generate_facts(ip)
            if ssh_manager.download_from_remote(ip,
                                                '/tmp/facts.yaml',
                                                fact_filename):
                logger.info(msg.format('facts', nodename))
            else:
                logger.error(errmsg.format('facts', nodename))
示例#3
0
    def get_nodes_tasks(node_id):
        """
        :param node_id: an integer number of node id
        :return: a set of deployment tasks for corresponding node
        """
        tasks = set()
        ssh = SSHManager()

        result = ssh.execute_on_remote(ssh.admin_ip, "ls /var/log/astute")
        filenames = [filename.strip() for filename in result['stdout']]

        for filename in filenames:
            ssh.download_from_remote(
                ssh.admin_ip,
                destination="/var/log/astute/{0}".format(filename),
                target="/tmp/{0}".format(filename))

        data = fileinput.FileInput(
            files=["/tmp/{0}".format(filename) for filename in filenames],
            openhook=fileinput.hook_compressed)
        for line in data:
            if "Task time summary" in line \
                    and "node {}".format(node_id) in line:
                # FIXME: define an exact search of task
                task_name = line.split("Task time summary: ")[1].split()[0]
                check = any([excluded_task in task_name
                             for excluded_task in TASKS_BLACKLIST])
                if check:
                    continue
                tasks.add(task_name)
        return tasks
示例#4
0
文件: utils.py 项目: jvalinas/fuel-qa
    def store_astute_yaml_for_one_node(nailgun_node):
        ssh_manager = SSHManager()
        if 'roles' not in nailgun_node:
            return None
        errmsg = 'Downloading "{0}.yaml" from the {1} failed'
        msg = 'File "{0}.yaml" was downloaded from the {1}'
        nodename = nailgun_node['name']
        ip = nailgun_node['ip']
        for role in nailgun_node['roles']:
            filename = '{0}/{1}-{2}-{3}.yaml'.format(settings.LOGS_DIR,
                                                     func_name, nodename, role)

            if not ssh_manager.isfile_on_remote(ip,
                                                '/etc/{0}.yaml'.format(role)):
                role = 'primary-' + role
            if ssh_manager.download_from_remote(ip,
                                                '/etc/{0}.yaml'.format(role),
                                                filename):
                logger.info(msg.format(role, nodename))
            else:
                logger.error(errmsg.format(role, nodename))
        if settings.DOWNLOAD_FACTS:
            fact_filename = re.sub(r'-\w*\.', '-facts.', filename)
            generate_facts(ip)
            if ssh_manager.download_from_remote(ip, '/tmp/facts.yaml',
                                                fact_filename):
                logger.info(msg.format('facts', nodename))
            else:
                logger.error(errmsg.format('facts', nodename))
示例#5
0
class BaseActions(object):
    """BaseActions."""  # TODO documentation

    def __init__(self):
        self.ssh_manager = SSHManager()
        self.admin_ip = self.ssh_manager.admin_ip
        self.container = None

    def __repr__(self):
        klass, obj_id = type(self), hex(id(self))
        container = getattr(self, 'container', None)
        return "[{klass}({obj_id}), container:{container}]".format(
            klass=klass, obj_id=obj_id, container=container)

    def execute_in_container(self,
                             command,
                             container=None,
                             exit_code=None,
                             stdin=None):
        if not container:
            container = self.container
        cmd = 'dockerctl shell {0} {1}'.format(container, command)
        if stdin is not None:
            cmd = 'echo "{0}" | {1}'.format(stdin, cmd)

        result = self.ssh_manager.execute(ip=self.admin_ip, cmd=cmd)
        if exit_code is not None:
            assert_equal(exit_code, result['exit_code'],
                         ('Command {cmd} returned exit code "{e}", but '
                          'expected "{c}". Output: {out}; {err} ').format(
                              cmd=cmd,
                              e=result['exit_code'],
                              c=exit_code,
                              out=result['stdout'],
                              err=result['stderr']))
        return ''.join(result['stdout']).strip()

    def copy_between_node_and_container(self, copy_from, copy_to):
        """ Copy files from/to container.
        :param copy_from: path to copy file from
        :param copy_to: path to copy file to
        For ex.:

            - to copy from container to master node use:
                 copy_from = container:path_from
                 copy_to = path_to
            - to copy from master node to container use:
                 copy_from = path_from
                 copy_to = container:path_to

        :return:
            Standard output from console
        """
        cmd = 'dockerctl copy {0} {1}'.format(copy_from, copy_to)
        result = self.ssh_manager.execute(ip=self.admin_ip, cmd=cmd)
        assert_equal(0, result['exit_code'],
                     ('Command copy returned exit code "{e}", but '
                      'expected "0". Output: {out}; {err} ').format(
                          cmd=cmd,
                          e=result['exit_code'],
                          out=result['stdout'],
                          err=result['stderr']))
        return ''.join(result['stdout']).strip()

    @property
    def is_container_ready(self):
        result = self.ssh_manager.execute(
            ip=self.admin_ip,
            cmd="timeout 5 dockerctl check {0}".format(self.container))
        return result['exit_code'] == 0

    def wait_for_ready_container(self, timeout=300):
        wait(lambda: self.is_container_ready, timeout=timeout)

    def put_value_to_local_yaml(self, old_file, new_file, element, value):
        """Changes content in old_file at element is given to the new value
        and creates new file with changed content
        :param old_file: a path to the file content from to be changed
        :param new_file: a path to the new file to ve created with new content
        :param element: tuple with path to element to be changed
        for example: ['root_elem', 'first_elem', 'target_elem']
        if there are a few elements with equal names use integer
        to identify which element should be used
        :return: nothing
        """

        with open(old_file, 'r') as f_old:
            yaml_dict = yaml.load(f_old)

        origin_yaml = yaml_dict
        for k in element[:-1]:
            yaml_dict = yaml_dict[k]
        yaml_dict[element[-1]] = value

        with open(new_file, 'w') as f_new:
            yaml.dump(origin_yaml,
                      f_new,
                      default_flow_style=False,
                      default_style='"')

    def get_value_from_local_yaml(self, yaml_file, element):
        """Get a value of the element from the local yaml file

           :param str yaml_file: a path to the yaml file
           :param list element:
               list with path to element to be read
               for example: ['root_elem', 'first_elem', 'target_elem']
               if there are a few elements with equal names use integer
               to identify which element should be used
           :return obj: value
        """
        with open(yaml_file, 'r') as f_old:
            yaml_dict = yaml.load(f_old)

        for i, k in enumerate(element):
            try:
                yaml_dict = yaml_dict[k]
            except IndexError:
                raise IndexError(
                    "Element {0} not found in the file {1}".format(
                        element[:i + 1], f_old))
            except KeyError:
                raise KeyError("Element {0} not found in the file {1}".format(
                    element[:i + 1], f_old))
        return yaml_dict

    def change_yaml_file_in_container(self,
                                      path_to_file,
                                      element,
                                      value,
                                      container=None):
        """Changes values in the yaml file stored at container
        There is no need to copy file manually
        :param path_to_file: absolutely path to the file
        :param element: list with path to the element be changed
        :param value: new value for element
        :param container: Container with file. By default it is nailgun
        :return: Nothing
        """
        if not container:
            container = self.container

        old_file = '/tmp/temp_file_{0}.old.yaml'.format(str(os.getpid()))
        new_file = '/tmp/temp_file_{0}.new.yaml'.format(str(os.getpid()))

        self.copy_between_node_and_container(
            '{0}:{1}'.format(container, path_to_file), old_file)
        self.ssh_manager.download_from_remote(ip=self.admin_ip,
                                              destination=old_file,
                                              target=old_file)
        self.put_value_to_local_yaml(old_file, new_file, element, value)
        self.ssh_manager.upload_to_remote(ip=self.admin_ip,
                                          source=new_file,
                                          target=new_file)
        self.copy_between_node_and_container(
            new_file, '{0}:{1}'.format(container, path_to_file))
        os.remove(old_file)
        os.remove(new_file)

    def get_value_from_yaml(self, path_to_file, element):
        """Get a value from the yaml file stored in container
           or on master node if self.container is None

        :param str path_to_file: absolutely path to the file
        :param list element: list with path to the element be changed
        :return obj: value
        """

        if self.container:
            admin_tmp_file = '/tmp/temp_file_{0}.yaml'.format(str(os.getpid()))
            self.copy_between_node_and_container(
                '{0}:{1}'.format(self.container, path_to_file), admin_tmp_file)
        else:
            admin_tmp_file = path_to_file

        host_tmp_file = '/tmp/temp_file_{0}.yaml'.format(str(os.getpid()))
        self.ssh_manager.download_from_remote(ip=self.admin_ip,
                                              destination=admin_tmp_file,
                                              target=host_tmp_file)
        value = self.get_value_from_local_yaml(host_tmp_file, element)
        os.remove(host_tmp_file)
        return value

    def put_value_to_yaml(self, path_to_file, element, value):
        """Put a value to the yaml file stored in container
           or on master node if self.container is None

        :param str path_to_file: absolutely path to the file
        :param list element: list with path to the element be changed
        :param value: new value for element
        :return: None
        """

        if self.container:
            admin_tmp_file = '/tmp/temp_file_{0}.yaml'.format(str(os.getpid()))
            self.copy_between_node_and_container(
                '{0}:{1}'.format(self.container, path_to_file), admin_tmp_file)
        else:
            admin_tmp_file = path_to_file

        host_tmp_file = '/tmp/temp_file_{0}.yaml'.format(str(os.getpid()))
        self.ssh_manager.download_from_remote(ip=self.admin_ip,
                                              destination=admin_tmp_file,
                                              target=host_tmp_file)
        self.put_value_to_local_yaml(host_tmp_file, host_tmp_file, element,
                                     value)
        self.ssh_manager.upload_to_remote(ip=self.admin_ip,
                                          source=host_tmp_file,
                                          target=admin_tmp_file)
        if self.container:
            self.copy_between_node_and_container(
                admin_tmp_file, '{0}:{1}'.format(self.container, path_to_file))
        os.remove(host_tmp_file)
示例#6
0
class BaseActions(object):
    """BaseActions."""  # TODO documentation

    def __init__(self):
        self.ssh_manager = SSHManager()
        self.admin_ip = self.ssh_manager.admin_ip

    def __repr__(self):
        klass, obj_id = type(self), hex(id(self))
        return "[{klass}({obj_id})]".format(
            klass=klass,
            obj_id=obj_id)

    # TODO(kozhukalov): This method seems not needed and
    # can easily be replaced by using execute_on_remote
    # available in SSHManager (up to the type of return value)
    def execute(self, cmd, exit_code=None, stdin=None):
        if stdin is not None:
            cmd = 'echo "{0}" | {1}'.format(stdin, cmd)

        result = self.ssh_manager.execute(
            ip=self.admin_ip,
            cmd=cmd
        )
        if exit_code is not None:
            assert_equal(exit_code,
                         result['exit_code'],
                         ('Command {cmd} returned exit code "{e}", but '
                          'expected "{c}". Output: {out}; {err} ').format(
                             cmd=cmd,
                             e=result['exit_code'],
                             c=exit_code,
                             out=result['stdout'],
                             err=result['stderr']
                         ))
        return ''.join(result['stdout']).strip()

    def restart_service(self, service):
        result = self.ssh_manager(
            ip=self.admin_ip,
            cmd="systemctl restart {0}".format(service))
        return result['exit_code'] == 0

    def put_value_to_local_yaml(self, old_file, new_file, element, value):
        """Changes content in old_file at element is given to the new value
        and creates new file with changed content
        :param old_file: a path to the file content from to be changed
        :param new_file: a path to the new file to ve created with new content
        :param element: tuple with path to element to be changed
        for example: ['root_elem', 'first_elem', 'target_elem']
        if there are a few elements with equal names use integer
        to identify which element should be used
        :return: nothing
        """

        with open(old_file, 'r') as f_old:
            yaml_dict = yaml.load(f_old)

        origin_yaml = yaml_dict
        for k in element[:-1]:
            yaml_dict = yaml_dict[k]
        yaml_dict[element[-1]] = value

        with open(new_file, 'w') as f_new:
            yaml.dump(origin_yaml, f_new, default_flow_style=False,
                      default_style='"')

    def get_value_from_local_yaml(self, yaml_file, element):
        """Get a value of the element from the local yaml file

           :param str yaml_file: a path to the yaml file
           :param list element:
               list with path to element to be read
               for example: ['root_elem', 'first_elem', 'target_elem']
               if there are a few elements with equal names use integer
               to identify which element should be used
           :return obj: value
        """
        with open(yaml_file, 'r') as f_old:
            yaml_dict = yaml.load(f_old)

        for i, k in enumerate(element):
            try:
                yaml_dict = yaml_dict[k]
            except IndexError:
                raise IndexError("Element {0} not found in the file {1}"
                                 .format(element[: i + 1], f_old))
            except KeyError:
                raise KeyError("Element {0} not found in the file {1}"
                               .format(element[: i + 1], f_old))
        return yaml_dict

    def change_remote_yaml(self, path_to_file, element, value):
        """Changes values in the yaml file stored
        There is no need to copy file manually
        :param path_to_file: absolute path to the file
        :param element: list with path to the element be changed
        :param value: new value for element
        :return: Nothing
        """
        old_file = '/tmp/temp_file_{0}.old.yaml'.format(str(os.getpid()))
        new_file = '/tmp/temp_file_{0}.new.yaml'.format(str(os.getpid()))

        self.ssh_manager.download_from_remote(
            ip=self.admin_ip,
            destination=path_to_file,
            target=old_file
        )
        self.put_value_to_local_yaml(old_file, new_file, element, value)
        self.ssh_manager.upload_to_remote(
            ip=self.admin_ip,
            source=new_file,
            target=path_to_file
        )
        os.remove(old_file)
        os.remove(new_file)

    def get_value_from_remote_yaml(self, path_to_file, element):
        """Get a value from the yaml file stored
           on the master node

        :param str path_to_file: absolute path to the file
        :param list element: list with path to the element
        :return obj: value
        """

        host_tmp_file = '/tmp/temp_file_{0}.yaml'.format(str(os.getpid()))
        self.ssh_manager.download_from_remote(
            ip=self.admin_ip,
            destination=path_to_file,
            target=host_tmp_file
        )
        value = self.get_value_from_local_yaml(host_tmp_file, element)
        os.remove(host_tmp_file)
        return value

    def put_value_to_remote_yaml(self, path_to_file, element, value):
        """Put a value to the yaml file stored
           on the master node

        :param str path_to_file: absolute path to the file
        :param list element: list with path to the element be changed
        :param value: new value for element
        :return: None
        """

        host_tmp_file = '/tmp/temp_file_{0}.yaml'.format(str(os.getpid()))
        self.ssh_manager.download_from_remote(
            ip=self.admin_ip,
            destination=path_to_file,
            target=host_tmp_file
        )
        self.put_value_to_local_yaml(host_tmp_file, host_tmp_file,
                                     element, value)
        self.ssh_manager.upload_to_remote(
            ip=self.admin_ip,
            source=host_tmp_file,
            target=path_to_file
        )
        os.remove(host_tmp_file)
示例#7
0
class BaseActions(object):
    """BaseActions."""  # TODO documentation

    def __init__(self):
        self.ssh_manager = SSHManager()
        self.admin_ip = self.ssh_manager.admin_ip

    def __repr__(self):
        klass, obj_id = type(self), hex(id(self))
        return "[{klass}({obj_id})]".format(klass=klass, obj_id=obj_id)

    def restart_service(self, service):
        result = self.ssh_manager.execute(
            ip=self.admin_ip, cmd="systemctl restart {0}".format(service))
        return result['exit_code'] == 0

    @staticmethod
    def put_value_to_local_yaml(old_file, new_file, element, value):
        """Changes content in old_file at element is given to the new value
        and creates new file with changed content
        :param old_file: a path to the file content from to be changed
        :param new_file: a path to the new file to ve created with new content
        :param element: tuple with path to element to be changed
        for example: ['root_elem', 'first_elem', 'target_elem']
        if there are a few elements with equal names use integer
        to identify which element should be used
        :return: nothing
        """

        with open(old_file, 'r') as f_old:
            yaml_dict = yaml.load(f_old)

        origin_yaml = yaml_dict
        for k in element[:-1]:
            yaml_dict = yaml_dict[k]
        yaml_dict[element[-1]] = value

        with open(new_file, 'w') as f_new:
            yaml.dump(origin_yaml,
                      f_new,
                      default_flow_style=False,
                      default_style='"')

    @staticmethod
    def get_value_from_local_yaml(yaml_file, element):
        """Get a value of the element from the local yaml file

           :param str yaml_file: a path to the yaml file
           :param list element:
               list with path to element to be read
               for example: ['root_elem', 'first_elem', 'target_elem']
               if there are a few elements with equal names use integer
               to identify which element should be used
           :return obj: value
        """
        with open(yaml_file, 'r') as f_old:
            yaml_dict = yaml.load(f_old)

        for i, k in enumerate(element):
            try:
                yaml_dict = yaml_dict[k]
            except IndexError:
                raise IndexError(
                    "Element {0} not found in the file {1}".format(
                        element[:i + 1], f_old))
            except KeyError:
                raise KeyError("Element {0} not found in the file {1}".format(
                    element[:i + 1], f_old))
        return yaml_dict

    def change_remote_yaml(self, path_to_file, element, value):
        """Changes values in the yaml file stored
        There is no need to copy file manually
        :param path_to_file: absolute path to the file
        :param element: list with path to the element be changed
        :param value: new value for element
        :return: Nothing
        """
        old_file = '/tmp/temp_file_{0}.old.yaml'.format(str(os.getpid()))
        new_file = '/tmp/temp_file_{0}.new.yaml'.format(str(os.getpid()))

        self.ssh_manager.download_from_remote(ip=self.admin_ip,
                                              destination=path_to_file,
                                              target=old_file)
        self.put_value_to_local_yaml(old_file, new_file, element, value)
        self.ssh_manager.upload_to_remote(ip=self.admin_ip,
                                          source=new_file,
                                          target=path_to_file)
        os.remove(old_file)
        os.remove(new_file)

    def get_value_from_remote_yaml(self, path_to_file, element):
        """Get a value from the yaml file stored
           on the master node

        :param str path_to_file: absolute path to the file
        :param list element: list with path to the element
        :return obj: value
        """

        host_tmp_file = '/tmp/temp_file_{0}.yaml'.format(str(os.getpid()))
        self.ssh_manager.download_from_remote(ip=self.admin_ip,
                                              destination=path_to_file,
                                              target=host_tmp_file)
        value = self.get_value_from_local_yaml(host_tmp_file, element)
        os.remove(host_tmp_file)
        return value

    def put_value_to_remote_yaml(self, path_to_file, element, value):
        """Put a value to the yaml file stored
           on the master node

        :param str path_to_file: absolute path to the file
        :param list element: list with path to the element be changed
        :param value: new value for element
        :return: None
        """

        host_tmp_file = '/tmp/temp_file_{0}.yaml'.format(str(os.getpid()))
        self.ssh_manager.download_from_remote(ip=self.admin_ip,
                                              destination=path_to_file,
                                              target=host_tmp_file)
        self.put_value_to_local_yaml(host_tmp_file, host_tmp_file, element,
                                     value)
        self.ssh_manager.upload_to_remote(ip=self.admin_ip,
                                          source=host_tmp_file,
                                          target=path_to_file)
        os.remove(host_tmp_file)
示例#8
0
class BaseActions(object):
    """BaseActions."""  # TODO documentation

    def __init__(self):
        self.ssh_manager = SSHManager()
        self.admin_ip = self.ssh_manager.admin_ip
        self.container = None

    def __repr__(self):
        klass, obj_id = type(self), hex(id(self))
        container = getattr(self, 'container', None)
        return "[{klass}({obj_id}), container:{container}]".format(
            klass=klass,
            obj_id=obj_id,
            container=container)

    def execute_in_container(self, command, container=None, exit_code=None,
                             stdin=None):
        if not container:
            container = self.container
        cmd = 'dockerctl shell {0} {1}'.format(container, command)
        if stdin is not None:
            cmd = 'echo "{0}" | {1}'.format(stdin, cmd)

        result = self.ssh_manager.execute(
            ip=self.admin_ip,
            cmd=cmd
        )
        if exit_code is not None:
            assert_equal(exit_code,
                         result['exit_code'],
                         ('Command {cmd} returned exit code "{e}", but '
                          'expected "{c}". Output: {out}; {err} ').format(
                             cmd=cmd,
                             e=result['exit_code'],
                             c=exit_code,
                             out=result['stdout'],
                             err=result['stderr']
                         ))
        return ''.join(result['stdout']).strip()

    def copy_between_node_and_container(self, copy_from, copy_to):
        """ Copy files from/to container.
        :param copy_from: path to copy file from
        :param copy_to: path to copy file to
        For ex.:

            - to copy from container to master node use:
                 copy_from = container:path_from
                 copy_to = path_to
            - to copy from master node to container use:
                 copy_from = path_from
                 copy_to = container:path_to

        :return:
            Standard output from console
        """
        cmd = 'dockerctl copy {0} {1}'.format(copy_from, copy_to)
        result = self.ssh_manager.execute(
            ip=self.admin_ip,
            cmd=cmd
        )
        assert_equal(0, result['exit_code'],
                     ('Command copy returned exit code "{e}", but '
                      'expected "0". Output: {out}; {err} ').format(
                         cmd=cmd,
                         e=result['exit_code'],
                         out=result['stdout'],
                         err=result['stderr']))
        return ''.join(result['stdout']).strip()

    @property
    def is_container_ready(self):
        result = self.ssh_manager.execute(
            ip=self.admin_ip,
            cmd="timeout 5 dockerctl check {0}".format(self.container)
        )
        return result['exit_code'] == 0

    def wait_for_ready_container(self, timeout=300):
        wait(lambda: self.is_container_ready, timeout=timeout)

    def put_value_to_local_yaml(self, old_file, new_file, element, value):
        """Changes content in old_file at element is given to the new value
        and creates new file with changed content
        :param old_file: a path to the file content from to be changed
        :param new_file: a path to the new file to ve created with new content
        :param element: tuple with path to element to be changed
        for example: ['root_elem', 'first_elem', 'target_elem']
        if there are a few elements with equal names use integer
        to identify which element should be used
        :return: nothing
        """

        with open(old_file, 'r') as f_old:
            yaml_dict = yaml.load(f_old)

        origin_yaml = yaml_dict
        for k in element[:-1]:
            yaml_dict = yaml_dict[k]
        yaml_dict[element[-1]] = value

        with open(new_file, 'w') as f_new:
            yaml.dump(origin_yaml, f_new, default_flow_style=False,
                      default_style='"')

    def get_value_from_local_yaml(self, yaml_file, element):
        """Get a value of the element from the local yaml file

           :param str yaml_file: a path to the yaml file
           :param list element:
               list with path to element to be read
               for example: ['root_elem', 'first_elem', 'target_elem']
               if there are a few elements with equal names use integer
               to identify which element should be used
           :return obj: value
        """
        with open(yaml_file, 'r') as f_old:
            yaml_dict = yaml.load(f_old)

        for i, k in enumerate(element):
            try:
                yaml_dict = yaml_dict[k]
            except IndexError:
                raise IndexError("Element {0} not found in the file {1}"
                                 .format(element[: i + 1], f_old))
            except KeyError:
                raise KeyError("Element {0} not found in the file {1}"
                               .format(element[: i + 1], f_old))
        return yaml_dict

    def change_yaml_file_in_container(
            self, path_to_file, element, value, container=None):
        """Changes values in the yaml file stored at container
        There is no need to copy file manually
        :param path_to_file: absolutely path to the file
        :param element: list with path to the element be changed
        :param value: new value for element
        :param container: Container with file. By default it is nailgun
        :return: Nothing
        """
        if not container:
            container = self.container

        old_file = '/tmp/temp_file_{0}.old.yaml'.format(str(os.getpid()))
        new_file = '/tmp/temp_file_{0}.new.yaml'.format(str(os.getpid()))

        self.copy_between_node_and_container(
            '{0}:{1}'.format(container, path_to_file), old_file)
        self.ssh_manager.download_from_remote(
            ip=self.admin_ip,
            destination=old_file,
            target=old_file
        )
        self.put_value_to_local_yaml(old_file, new_file, element, value)
        self.ssh_manager.upload_to_remote(
            ip=self.admin_ip,
            source=new_file,
            target=new_file
        )
        self.copy_between_node_and_container(
            new_file, '{0}:{1}'.format(container, path_to_file))
        os.remove(old_file)
        os.remove(new_file)

    def get_value_from_yaml(self, path_to_file, element):
        """Get a value from the yaml file stored in container
           or on master node if self.container is None

        :param str path_to_file: absolutely path to the file
        :param list element: list with path to the element be changed
        :return obj: value
        """

        if self.container:
            admin_tmp_file = '/tmp/temp_file_{0}.yaml'.format(str(os.getpid()))
            self.copy_between_node_and_container(
                '{0}:{1}'.format(self.container, path_to_file), admin_tmp_file)
        else:
            admin_tmp_file = path_to_file

        host_tmp_file = '/tmp/temp_file_{0}.yaml'.format(str(os.getpid()))
        self.ssh_manager.download_from_remote(
            ip=self.admin_ip,
            destination=admin_tmp_file,
            target=host_tmp_file
        )
        value = self.get_value_from_local_yaml(host_tmp_file, element)
        os.remove(host_tmp_file)
        return value

    def put_value_to_yaml(self, path_to_file, element, value):
        """Put a value to the yaml file stored in container
           or on master node if self.container is None

        :param str path_to_file: absolutely path to the file
        :param list element: list with path to the element be changed
        :param value: new value for element
        :return: None
        """

        if self.container:
            admin_tmp_file = '/tmp/temp_file_{0}.yaml'.format(str(os.getpid()))
            self.copy_between_node_and_container(
                '{0}:{1}'.format(self.container, path_to_file), admin_tmp_file)
        else:
            admin_tmp_file = path_to_file

        host_tmp_file = '/tmp/temp_file_{0}.yaml'.format(str(os.getpid()))
        self.ssh_manager.download_from_remote(
            ip=self.admin_ip,
            destination=admin_tmp_file,
            target=host_tmp_file
        )
        self.put_value_to_local_yaml(host_tmp_file, host_tmp_file,
                                     element, value)
        self.ssh_manager.upload_to_remote(
            ip=self.admin_ip,
            source=host_tmp_file,
            target=admin_tmp_file
        )
        if self.container:
            self.copy_between_node_and_container(
                admin_tmp_file, '{0}:{1}'.format(self.container, path_to_file))
        os.remove(host_tmp_file)
示例#9
0
class BaseActions(object):
    """BaseActions."""  # TODO documentation

    def __init__(self):
        self.ssh_manager = SSHManager()
        self.admin_ip = self.ssh_manager.admin_ip

    def __repr__(self):
        klass, obj_id = type(self), hex(id(self))
        return "[{klass}({obj_id})]".format(
            klass=klass,
            obj_id=obj_id)

    def restart_service(self, service):
        result = self.ssh_manager.execute(
            ip=self.admin_ip,
            cmd="systemctl restart {0}".format(service))
        return result['exit_code'] == 0

    @staticmethod
    def put_value_to_local_yaml(old_file, new_file, element, value):
        """Changes content in old_file at element is given to the new value
        and creates new file with changed content
        :param old_file: a path to the file content from to be changed
        :param new_file: a path to the new file to ve created with new content
        :param element: tuple with path to element to be changed
        for example: ['root_elem', 'first_elem', 'target_elem']
        if there are a few elements with equal names use integer
        to identify which element should be used
        :return: nothing
        """

        with open(old_file, 'r') as f_old:
            yaml_dict = yaml.load(f_old)

        origin_yaml = yaml_dict
        for k in element[:-1]:
            yaml_dict = yaml_dict[k]
        yaml_dict[element[-1]] = value

        with open(new_file, 'w') as f_new:
            yaml.dump(origin_yaml, f_new, default_flow_style=False,
                      default_style='"')

    @staticmethod
    def get_value_from_local_yaml(yaml_file, element):
        """Get a value of the element from the local yaml file

           :param str yaml_file: a path to the yaml file
           :param list element:
               list with path to element to be read
               for example: ['root_elem', 'first_elem', 'target_elem']
               if there are a few elements with equal names use integer
               to identify which element should be used
           :return obj: value
        """
        with open(yaml_file, 'r') as f_old:
            yaml_dict = yaml.load(f_old)

        for i, k in enumerate(element):
            try:
                yaml_dict = yaml_dict[k]
            except IndexError:
                raise IndexError("Element {0} not found in the file {1}"
                                 .format(element[: i + 1], f_old))
            except KeyError:
                raise KeyError("Element {0} not found in the file {1}"
                               .format(element[: i + 1], f_old))
        return yaml_dict

    def change_remote_yaml(self, path_to_file, element, value):
        """Changes values in the yaml file stored
        There is no need to copy file manually
        :param path_to_file: absolute path to the file
        :param element: list with path to the element be changed
        :param value: new value for element
        :return: Nothing
        """
        old_file = '/tmp/temp_file_{0}.old.yaml'.format(str(os.getpid()))
        new_file = '/tmp/temp_file_{0}.new.yaml'.format(str(os.getpid()))

        self.ssh_manager.download_from_remote(
            ip=self.admin_ip,
            destination=path_to_file,
            target=old_file
        )
        self.put_value_to_local_yaml(old_file, new_file, element, value)
        self.ssh_manager.upload_to_remote(
            ip=self.admin_ip,
            source=new_file,
            target=path_to_file
        )
        os.remove(old_file)
        os.remove(new_file)

    def get_value_from_remote_yaml(self, path_to_file, element):
        """Get a value from the yaml file stored
           on the master node

        :param str path_to_file: absolute path to the file
        :param list element: list with path to the element
        :return obj: value
        """

        host_tmp_file = '/tmp/temp_file_{0}.yaml'.format(str(os.getpid()))
        self.ssh_manager.download_from_remote(
            ip=self.admin_ip,
            destination=path_to_file,
            target=host_tmp_file
        )
        value = self.get_value_from_local_yaml(host_tmp_file, element)
        os.remove(host_tmp_file)
        return value

    def put_value_to_remote_yaml(self, path_to_file, element, value):
        """Put a value to the yaml file stored
           on the master node

        :param str path_to_file: absolute path to the file
        :param list element: list with path to the element be changed
        :param value: new value for element
        :return: None
        """

        host_tmp_file = '/tmp/temp_file_{0}.yaml'.format(str(os.getpid()))
        self.ssh_manager.download_from_remote(
            ip=self.admin_ip,
            destination=path_to_file,
            target=host_tmp_file
        )
        self.put_value_to_local_yaml(host_tmp_file, host_tmp_file,
                                     element, value)
        self.ssh_manager.upload_to_remote(
            ip=self.admin_ip,
            source=host_tmp_file,
            target=path_to_file
        )
        os.remove(host_tmp_file)
示例#10
0
class BaseActions(object):
    """BaseActions."""  # TODO documentation

    def __init__(self):
        self.ssh_manager = SSHManager()
        self.admin_ip = self.ssh_manager.admin_ip

    def __repr__(self):
        klass, obj_id = type(self), hex(id(self))
        return "[{klass}({obj_id})]".format(klass=klass, obj_id=obj_id)

    # TODO(kozhukalov): This method seems not needed and
    # can easily be replaced by using execute_on_remote
    # available in SSHManager (up to the type of return value)
    def execute(self, cmd, exit_code=None, stdin=None):
        if stdin is not None:
            cmd = 'echo "{0}" | {1}'.format(stdin, cmd)

        result = self.ssh_manager.execute(ip=self.admin_ip, cmd=cmd)
        if exit_code is not None:
            assert_equal(exit_code, result['exit_code'],
                         ('Command {cmd} returned exit code "{e}", but '
                          'expected "{c}". Output: {out}; {err} ').format(
                              cmd=cmd,
                              e=result['exit_code'],
                              c=exit_code,
                              out=result['stdout'],
                              err=result['stderr']))
        return ''.join(result['stdout']).strip()

    def restart_service(self, service):
        result = self.ssh_manager(ip=self.admin_ip,
                                  cmd="systemctl restart {0}".format(service))
        return result['exit_code'] == 0

    def put_value_to_local_yaml(self, old_file, new_file, element, value):
        """Changes content in old_file at element is given to the new value
        and creates new file with changed content
        :param old_file: a path to the file content from to be changed
        :param new_file: a path to the new file to ve created with new content
        :param element: tuple with path to element to be changed
        for example: ['root_elem', 'first_elem', 'target_elem']
        if there are a few elements with equal names use integer
        to identify which element should be used
        :return: nothing
        """

        with open(old_file, 'r') as f_old:
            yaml_dict = yaml.load(f_old)

        origin_yaml = yaml_dict
        for k in element[:-1]:
            yaml_dict = yaml_dict[k]
        yaml_dict[element[-1]] = value

        with open(new_file, 'w') as f_new:
            yaml.dump(origin_yaml,
                      f_new,
                      default_flow_style=False,
                      default_style='"')

    def get_value_from_local_yaml(self, yaml_file, element):
        """Get a value of the element from the local yaml file

           :param str yaml_file: a path to the yaml file
           :param list element:
               list with path to element to be read
               for example: ['root_elem', 'first_elem', 'target_elem']
               if there are a few elements with equal names use integer
               to identify which element should be used
           :return obj: value
        """
        with open(yaml_file, 'r') as f_old:
            yaml_dict = yaml.load(f_old)

        for i, k in enumerate(element):
            try:
                yaml_dict = yaml_dict[k]
            except IndexError:
                raise IndexError(
                    "Element {0} not found in the file {1}".format(
                        element[:i + 1], f_old))
            except KeyError:
                raise KeyError("Element {0} not found in the file {1}".format(
                    element[:i + 1], f_old))
        return yaml_dict

    def change_remote_yaml(self, path_to_file, element, value):
        """Changes values in the yaml file stored
        There is no need to copy file manually
        :param path_to_file: absolute path to the file
        :param element: list with path to the element be changed
        :param value: new value for element
        :return: Nothing
        """
        old_file = '/tmp/temp_file_{0}.old.yaml'.format(str(os.getpid()))
        new_file = '/tmp/temp_file_{0}.new.yaml'.format(str(os.getpid()))

        self.ssh_manager.download_from_remote(ip=self.admin_ip,
                                              destination=path_to_file,
                                              target=old_file)
        self.put_value_to_local_yaml(old_file, new_file, element, value)
        self.ssh_manager.upload_to_remote(ip=self.admin_ip,
                                          source=new_file,
                                          target=path_to_file)
        os.remove(old_file)
        os.remove(new_file)

    def get_value_from_remote_yaml(self, path_to_file, element):
        """Get a value from the yaml file stored
           on the master node

        :param str path_to_file: absolute path to the file
        :param list element: list with path to the element
        :return obj: value
        """

        host_tmp_file = '/tmp/temp_file_{0}.yaml'.format(str(os.getpid()))
        self.ssh_manager.download_from_remote(ip=self.admin_ip,
                                              destination=path_to_file,
                                              target=host_tmp_file)
        value = self.get_value_from_local_yaml(host_tmp_file, element)
        os.remove(host_tmp_file)
        return value

    def put_value_to_remote_yaml(self, path_to_file, element, value):
        """Put a value to the yaml file stored
           on the master node

        :param str path_to_file: absolute path to the file
        :param list element: list with path to the element be changed
        :param value: new value for element
        :return: None
        """

        host_tmp_file = '/tmp/temp_file_{0}.yaml'.format(str(os.getpid()))
        self.ssh_manager.download_from_remote(ip=self.admin_ip,
                                              destination=path_to_file,
                                              target=host_tmp_file)
        self.put_value_to_local_yaml(host_tmp_file, host_tmp_file, element,
                                     value)
        self.ssh_manager.upload_to_remote(ip=self.admin_ip,
                                          source=host_tmp_file,
                                          target=path_to_file)
        os.remove(host_tmp_file)