summaryrefslogtreecommitdiffstats
path: root/vstf/vstf/agent/env/basic/vm9pfs.py
blob: f3a2c2ce0f97a3be45c1939179e259faaed9c066 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
"""
Created on 2015-8-27

@author: y00228926
"""
import os
import logging
import textwrap
from vstf.common.utils import my_sleep
from vstf.agent.env.fsmonitor import constant

LOG = logging.getLogger(__name__)


class VMConfigBy9pfs(object):
    """
    host side implemetation of a self-defined communication protocol using libvirt 9pfs to give commands to the Virtual Machine.

    """

    def __init__(self, vm_9p_path):
        """
        :param vm_9p_path: The host path of libvirt 9pfs for a vm.
        :return:
        """
        self.vm_9p_path = vm_9p_path

    def clean(self):
        self._unlink(self._path(constant.VM_CMD_RETURN_CODE_FILE))
        self._unlink(self._path(constant.VM_CMD_DONE_FLAG_FILE))

    def _path(self, relative_path):
        return os.path.join(self.vm_9p_path, relative_path)

    def _unlink(self, file_path):
        os.unlink(file_path)
        LOG.info("os.unlink(%s)", file_path)

    def _read(self, filename):
        filepath = self._path(filename)
        with open(filepath, 'r') as f:
            ret = f.read()
            LOG.info("read(%s) -> %s", filepath, ret)
        return ret

    def _write(self, filename, cmd):
        filepath = self._path(filename)
        with open(filepath, 'w') as f:
            f.write("%s" % cmd)
            LOG.info("write(%s) <- %s", filepath, cmd)

    def _wait_flag_file_to_exist(self, filename, timeout):
        filepath = self._path(filename)
        while timeout > 0:
            if os.path.exists(filepath):
                LOG.info("wait and find file:%s", filepath)
                return True
            my_sleep(1)
            timeout -= 1
            LOG.info("waiting file to exist:%s", filepath)
        return False

    def _get_cmd_return_code(self):
        ret = self._read(constant.VM_CMD_RETURN_CODE_FILE)
        return ret == constant.VM_CMD_EXCUTE_SUCCES_FLAG_CONTENT

    def _wait_command_done(self):
        done = self._wait_flag_file_to_exist(constant.VM_CMD_DONE_FLAG_FILE, constant.VM_COMMON_CMD_EXCUTE_TIME_OUT)
        if done:
            return self._get_cmd_return_code()
        else:
            return 'timeout'

    def _set_cmd(self, cmd):
        self._write(constant.VM_CMD_CONTENT_FILE, cmd)
        self._write(constant.VM_CMD_SET_FLAG_FILE, '')
        ret = self._wait_command_done()
        if ret:
            self.clean()
            return ret
        else:
            raise Exception("9pfs command failure: timeout.")

    def wait_up(self):
        return self._wait_flag_file_to_exist(constant.VM_UP_Flag_FILE, constant.VM_UP_TIME_OUT)

    def config_ip(self, mac, ip):
        cmd = 'config_ip %s %s' % (mac, ip)
        return self._set_cmd(cmd)

    def config_gw(self, ip):
        cmd = 'config_gw %s' % ip
        return self._set_cmd(cmd)

    def set_pktloop_dpdk(self, macs):
        """
        To connect two network devices together in the vm and loop the packets received to another.
        Use dpdk testpmd to loop the packets. See FSMonitor.

        :param macs: the mac address list of network cards of the vm.
        :return: True for success, Exception for Failure.
        """
        mac_str = ' '.join(macs)
        cmd = 'set_pktloop_dpdk ' + mac_str
        return self._set_cmd(cmd)

    def recover_nic_binding(self, macs):
        """
        in contrast to set_pktloop_dpdk, disconnect the looping.
        :param macs:  the mac address list of network cards of the vm.
        :return: True for success, Exception for Failure.
        """
        mac_str = ' '.join(macs)
        cmd = 'recover_nic_binding ' + mac_str
        return self._set_cmd(cmd)

    def config_amqp(self, identity, server, port=5672, user="guest", passwd="guest"):
        data = {
            'server': server,
            'port': port,
            'id': identity,
            'user': user,
            'passwd': passwd
        }
        header = "[rabbit]"
        content = '''
        user=%(user)s
        passwd=%(passwd)s
        host=%(server)s
        port=%(port)s
        id=%(id)s''' % data
        file_name = "amqp.ini"
        dedented_text = textwrap.dedent(content)
        self._write(file_name, header+dedented_text)
        cmd = 'config_amqp %s' % file_name
        return self._set_cmd(cmd)

    def stop_vstf(self):
        cmd = "stop_vstf"
        return self._set_cmd(cmd)

    def __repr__(self):
        return self.__class__.__name__ + ':' + self.vm_9p_path


if __name__ == '__main__':
    fs = VMConfigBy9pfs('/tmp/tmp4T6p7L')
    print os.listdir(os.curdir)
    print fs.config_ip('56:6f:44:a5:3f:a4', '192.168.188.200/23')
    print fs.config_gw('192.168.188.1')
    print fs.set_pktloop_dpdk(['56:6f:44:a5:3f:a2', '56:6f:44:a5:3f:a3'])
    print fs.recover_nic_binding(['56:6f:44:a5:3f:a2', '56:6f:44:a5:3f:a3'])
    print fs.config_amqp('192.168.188.200', '192.168.188.10')
    print os.listdir(os.curdir)