Upload the contribution of vstf as bottleneck network framework.
[bottlenecks.git] / vstf / vstf / agent / env / basic / vm9pfs.py
1 """
2 Created on 2015-8-27
3
4 @author: y00228926
5 """
6 import os
7 import logging
8 import textwrap
9 from vstf.common.utils import my_sleep
10 from vstf.agent.env.fsmonitor import constant
11
12 LOG = logging.getLogger(__name__)
13
14
15 class VMConfigBy9pfs(object):
16     """
17     host side implemetation of a self-defined communication protocol using libvirt 9pfs to give commands to the Virtual Machine.
18
19     """
20
21     def __init__(self, vm_9p_path):
22         """
23         :param vm_9p_path: The host path of libvirt 9pfs for a vm.
24         :return:
25         """
26         self.vm_9p_path = vm_9p_path
27
28     def clean(self):
29         self._unlink(self._path(constant.VM_CMD_RETURN_CODE_FILE))
30         self._unlink(self._path(constant.VM_CMD_DONE_FLAG_FILE))
31
32     def _path(self, relative_path):
33         return os.path.join(self.vm_9p_path, relative_path)
34
35     def _unlink(self, file_path):
36         os.unlink(file_path)
37         LOG.info("os.unlink(%s)", file_path)
38
39     def _read(self, filename):
40         filepath = self._path(filename)
41         with open(filepath, 'r') as f:
42             ret = f.read()
43             LOG.info("read(%s) -> %s", filepath, ret)
44         return ret
45
46     def _write(self, filename, cmd):
47         filepath = self._path(filename)
48         with open(filepath, 'w') as f:
49             f.write("%s" % cmd)
50             LOG.info("write(%s) <- %s", filepath, cmd)
51
52     def _wait_flag_file_to_exist(self, filename, timeout):
53         filepath = self._path(filename)
54         while timeout > 0:
55             if os.path.exists(filepath):
56                 LOG.info("wait and find file:%s", filepath)
57                 return True
58             my_sleep(1)
59             timeout -= 1
60             LOG.info("waiting file to exist:%s", filepath)
61         return False
62
63     def _get_cmd_return_code(self):
64         ret = self._read(constant.VM_CMD_RETURN_CODE_FILE)
65         return ret == constant.VM_CMD_EXCUTE_SUCCES_FLAG_CONTENT
66
67     def _wait_command_done(self):
68         done = self._wait_flag_file_to_exist(constant.VM_CMD_DONE_FLAG_FILE, constant.VM_COMMON_CMD_EXCUTE_TIME_OUT)
69         if done:
70             return self._get_cmd_return_code()
71         else:
72             return 'timeout'
73
74     def _set_cmd(self, cmd):
75         self._write(constant.VM_CMD_CONTENT_FILE, cmd)
76         self._write(constant.VM_CMD_SET_FLAG_FILE, '')
77         ret = self._wait_command_done()
78         if ret:
79             self.clean()
80             return ret
81         else:
82             raise Exception("9pfs command failure: timeout.")
83
84     def wait_up(self):
85         return self._wait_flag_file_to_exist(constant.VM_UP_Flag_FILE, constant.VM_UP_TIME_OUT)
86
87     def config_ip(self, mac, ip):
88         cmd = 'config_ip %s %s' % (mac, ip)
89         return self._set_cmd(cmd)
90
91     def config_gw(self, ip):
92         cmd = 'config_gw %s' % ip
93         return self._set_cmd(cmd)
94
95     def set_pktloop_dpdk(self, macs):
96         """
97         To connect two network devices together in the vm and loop the packets received to another.
98         Use dpdk testpmd to loop the packets. See FSMonitor.
99
100         :param macs: the mac address list of network cards of the vm.
101         :return: True for success, Exception for Failure.
102         """
103         mac_str = ' '.join(macs)
104         cmd = 'set_pktloop_dpdk ' + mac_str
105         return self._set_cmd(cmd)
106
107     def recover_nic_binding(self, macs):
108         """
109         in contrast to set_pktloop_dpdk, disconnect the looping.
110         :param macs:  the mac address list of network cards of the vm.
111         :return: True for success, Exception for Failure.
112         """
113         mac_str = ' '.join(macs)
114         cmd = 'recover_nic_binding ' + mac_str
115         return self._set_cmd(cmd)
116
117     def config_amqp(self, identity, server, port=5672, user="guest", passwd="guest"):
118         data = {
119             'server': server,
120             'port': port,
121             'id': identity,
122             'user': user,
123             'passwd': passwd
124         }
125         header = "[rabbit]"
126         content = '''
127         user=%(user)s
128         passwd=%(passwd)s
129         host=%(server)s
130         port=%(port)s
131         id=%(id)s''' % data
132         file_name = "amqp.ini"
133         dedented_text = textwrap.dedent(content)
134         self._write(file_name, header+dedented_text)
135         cmd = 'config_amqp %s' % file_name
136         return self._set_cmd(cmd)
137
138     def stop_vstf(self):
139         cmd = "stop_vstf"
140         return self._set_cmd(cmd)
141
142     def __repr__(self):
143         return self.__class__.__name__ + ':' + self.vm_9p_path
144
145
146 if __name__ == '__main__':
147     fs = VMConfigBy9pfs('/tmp/tmp4T6p7L')
148     print os.listdir(os.curdir)
149     print fs.config_ip('56:6f:44:a5:3f:a4', '192.168.188.200/23')
150     print fs.config_gw('192.168.188.1')
151     print fs.set_pktloop_dpdk(['56:6f:44:a5:3f:a2', '56:6f:44:a5:3f:a3'])
152     print fs.recover_nic_binding(['56:6f:44:a5:3f:a2', '56:6f:44:a5:3f:a3'])
153     print fs.config_amqp('192.168.188.200', '192.168.188.10')
154     print os.listdir(os.curdir)