Upload the contribution of vstf as bottleneck network framework.
[bottlenecks.git] / vstf / vstf / agent / agent.py
1 #!/usr/bin/env python
2 # coding=utf-8
3 import logging
4 import argparse
5 import signal
6
7 from oslo.config import cfg
8
9 from vstf.rpc_frame_work import rpc_consumer
10 from vstf.common.log import setup_logging
11 from vstf.common import daemon
12 from vstf.common.cfgparser import CfgParser
13
14 LOG = logging.getLogger(__name__)
15
16 server_opts = [
17     cfg.StrOpt('user', default='guest', help="the rabbit's user, default guest"),
18     cfg.StrOpt('passwd', default='guest', help="the rabbit's passwd, default guest"),
19     cfg.StrOpt('host', default='localhost', help="tell the process wich interface to listen"),
20     cfg.StrOpt('port', default=5672, help=""),
21     cfg.StrOpt('id', default='agent', help="")
22
23 ]
24
25 stc_opts = [
26     cfg.StrOpt('package', default='', help="the STC python path")
27 ]
28
29
30 class Client(daemon.Daemon):
31     """This is a consumer of vstf-agent which will create two channel to the
32     rabbitmq-server, one for direct call, one for fan call.
33     
34     agent start with a config file which record rabbitmq's ip, port and user passwd
35     also each agent has its own id.
36     
37     """
38
39     def __init__(self, agent, config_file):
40         """Record the config file, init the daemon.
41         
42         :param str config_file: the config of a VSTF agent.
43         
44         """
45         super(Client, self).__init__('/tmp/esp_rpc_client.pid')
46         self.config_file = config_file
47         self.agent = agent
48         self.config = None
49         self.proxy = None
50         self.run_flag = True
51
52     def init_config(self):
53         """Use olso.config to analyse the config file
54         
55         """
56         parser = CfgParser(self.config_file)
57         parser.register_my_opts(server_opts, "rabbit")
58         parser.register_my_opts(stc_opts, "spirent")
59         self.config = parser.parse()
60
61     def loop_thread(self):
62         LOG.info("Try to create direct proxy...")
63         self.proxy = rpc_consumer.VstfConsumer(self.agent,
64                                                 self.config.rabbit.user,
65                                                 self.config.rabbit.passwd,
66                                                 self.config.rabbit.host,
67                                                 self.config.rabbit.port,
68                                                 self.config.rabbit.id)
69         self.proxy.run()
70
71     def run(self):
72         """Run the rabbitmq consumers as a daemon.
73         
74         """
75         signal.signal(signal.SIGTERM, self.process_exit)
76         self.loop_thread()
77         LOG.info("agent start ok!")
78
79     def process_exit(self, signum, frame):
80         """This function try to stop the agent after running agent stop.
81         When we call vstf-agent stop which will send a signal SIGTERM to agent
82         When the agent catch the SIGTERM signal will call this function.
83         
84         """
85         LOG.info("daemon catch the signalterm, start to stop the process.")
86         self.run_flag = False
87         if self.proxy:
88             self.proxy.stop()
89
90     def start_agent(self):
91         self.init_config()
92         self.start()
93
94     def stop_agent(self):
95         """Notice that: this function just kill the agent by pid file, it has
96         none vars of the agent.
97         
98         """
99         LOG.info("call daemon stop.")
100         # kill the main thread
101         self.stop()
102
103
104 def main():
105     setup_logging(level=logging.INFO, log_file="/var/log/vstf/vstf-agent.log")
106     parser = argparse.ArgumentParser(description='agent option')
107     parser.add_argument('action', choices=('start', 'stop', "restart"),
108                         default="start", help="start or stop agent")
109     parser.add_argument('--agent_type', action='store',
110                         default="soft",
111                         choices=["soft", "spirent"],
112                         help="the agent type, as now, just soft and spirent")
113     parser.add_argument('--config_file', action='store',
114                         default="/etc/vstf/amqp/amqp.ini",
115                         help="some env_build params recorded in the config file")
116
117     args = parser.parse_args()
118
119     client = Client(args.agent_type, args.config_file)
120     if "start" == args.action:
121         client.start_agent()
122     elif "stop" == args.action:
123         client.stop_agent()
124     elif "restart" == args.action:
125         client.stop_agent()
126         client.start_agent()
127     else:
128         raise Exception("only support actions: start/stop/restart")
129
130
131 if __name__ == '__main__':
132     main()