分享

OpenStack Swift源码分析(1)----swift服务启动源码分析之一

tntzbzc 发表于 2014-11-20 15:34:49 [显示全部楼层] 回帖奖励 阅读模式 关闭右栏 1 22307
本帖最后由 pig2 于 2014-11-21 15:07 编辑
问题导读
1.swift-init main start命令的作用是什么?
2.哪个类是管理各个server执行操作的类?








   
    从头开始,部署完成swift以后,就可以执行命令swift-init main start来执行swift的初始化工作。这里实际上执行的是/bin/swift-init中的main方法,下面我们开始看代码:
  1. if __name__ == "__main__":
  2.     sys.exit(main())   
复制代码



进一步调用方法main:


  1. def main():  
  2.     parser = OptionParser(USAGE)  
  3.     parser.add_option('-v', '--verbose', action="store_true",  
  4.                       default=False, help="display verbose output")  
  5.     parser.add_option('-w', '--no-wait', action="store_false", dest="wait",  
  6.                       default=True, help="won't wait for server to start "  
  7.                       "before returning")  
  8.     parser.add_option('-o', '--once', action="store_true",  
  9.                       default=False, help="only run one pass of daemon")  
  10.     # this is a negative option, default is options.daemon = True  
  11.     parser.add_option('-n', '--no-daemon', action="store_false", dest="daemon",  
  12.                       default=True, help="start server interactively")  
  13.     parser.add_option('-g', '--graceful', action="store_true",  
  14.                       default=False, help="send SIGHUP to supporting servers")  
  15.     parser.add_option('-c', '--config-num', metavar="N", type="int",  
  16.                       dest="number", default=0,  
  17.                       help="send command to the Nth server only")  
  18.     parser.add_option('-k', '--kill-wait', metavar="N", type="int",  
  19.                       dest="kill_wait", default=KILL_WAIT,  
  20.                       help="wait N seconds for processes to die (default 15)")  
  21.     parser.add_option('-r', '--run-dir', type="str",  
  22.                       dest="run_dir", default=RUN_DIR,  
  23.                       help="alternative directory to store running pid files "  
  24.                       "default: %s" % RUN_DIR)  
  25.   
  26.     options, args = parser.parse_args()  
  27.   
  28.     if len(args) < 2:  
  29.         parser.print_help()  
  30.         print 'ERROR: specify server(s) and command'  
  31.         return 1  
  32.   
  33.     # 在这里对命令和参数进行了分割,从而决定接下来的执行任务:  
  34.     # command此处为start;  
  35.     # servers此处为['swift-init','main'];  
  36.     command = args[-1]  
  37.     servers = args[:-1]  
  38.   
  39.     # this is just a silly swap for me cause I always try to "start main"  
  40.     commands = dict(Manager.list_commands()).keys()  
  41.     if command not in commands and servers[0] in commands:  
  42.         servers.append(command)  
  43.         command = servers.pop(0)  
  44.   
  45.     # 实例化类Manager;  
  46.     # Manager是直接管理各个servers的类;  
  47.     # 初始化各个服务;  
  48.     manager = Manager(servers, run_dir=options.run_dir)  
  49.     try:  
  50.         status = manager.run_command(command, **options.__dict__)  
  51.     except UnknownCommandError:  
  52.         parser.print_help()  
  53.         print 'ERROR: unknown command, %s' % command  
  54.         status = 1  
  55.   
  56.     return 1 if status else 0  
复制代码





看其中的一段代码:
  1. # list_commands:获取所有可公开访问的命令;
  2.     commands = dict(Manager.list_commands()).keys()
  3.     if command not in commands and servers[0] in commands:
  4.         servers.append(command)
  5.         command = servers.pop(0)
复制代码

   

经过调试输出:
  1.   commands = ['status', 'start', 'force-reload', 'stop', 'no-wait', 'no-daemon', 'reload', 'shutdown', 'restart', 'once']
  2. # 实例化类Manager;
  3. # Manager是直接管理各个servers的类;
  4. # 初始化各个服务;
  5. manager = Manager(servers, run_dir=options.run_dir)   
复制代码

  
其中Manager是管理各个server执行操作的类,这条语句实现了对类Manager的初始化并获取实力对象;
    具体来看:


  1. class Manager():
  2.     """
  3.     管理各个server执行操作的类;
  4.     param servers:服务名称列表;
  5.     """
  6.     def __init__(self, servers, run_dir=RUN_DIR):
  7.         server_names = set()
  8.         for server in servers:
  9.             if server == 'all':
  10.                 server_names.update(ALL_SERVERS)
  11.             # MAIN_SERVERS = ['proxy-server', 'account-server', 'container-server', 'object-server']
  12.             elif server == 'main':
  13.                 server_names.update(MAIN_SERVERS)
  14.             elif server == 'rest':
  15.                 server_names.update(REST_SERVERS)
  16.             elif '*' in server:
  17.                 # convert glob to regex
  18.                 server_names.update([s for s in ALL_SERVERS if re.match(server.replace('*', '.*'), s)])
  19.             else:
  20.                 server_names.add(server)
  21.         self.servers = set()
  22.         # 如果servers中包含‘main’:
  23.         # server_names = ['proxy-server', 'account-server', 'container-server', 'object-server'];
  24.         # run_dir = /var/run/swift;
  25.         # Server:依次初始化四个服务;
  26.         for name in server_names:
  27.             self.servers.add(Server(name, run_dir))   
复制代码




我们前面测试得到servers = ['swift-init', 'main'],可见server_names = ['proxy-server', 'account-server', 'container-server', 'object-server'],这是swift四个服务的名称;
    所以这个初始化方法根据传入servers的参数值,确定了server_names的值;
    再回到/bin/swift-init中的main方法:
  1.     try:
  2.         status = manager.run_command(command, **options.__dict__)
  3.     except UnknownCommandError:
  4.         parser.print_help()
  5.         print 'ERROR: unknown command, %s' % command
  6.         status = 1   
复制代码




其中:
    command = start
    options = {'run_dir': '/var/run/swift', 'daemon': True, 'verbose': False, 'number': 0, 'kill_wait': 15, 'graceful': False, 'wait': True, 'once': False}
    进一步看方法run_command:
  1. def run_command(self, cmd, **kwargs):
  2.     """
  3.     找到命令名称并运行它;
  4.     """
  5.     f = self.get_command(cmd)
  6.     return f(**kwargs)   
复制代码




再看方法get_command:

   
  1. def get_command(self, cmd):
  2.         """
  3.         查找并返回cmd指定的方法名称;
  4.         """
  5.         cmd = cmd.lower().replace('-', '_')
  6.         try:
  7.             f = getattr(self, cmd)
  8.         except AttributeError:
  9.             raise UnknownCommandError(cmd)
  10.         if not hasattr(f, 'publicly_accessible'):
  11.             raise UnknownCommandError(cmd)
  12.         return f   
复制代码



可以知道通过这两个方法的结合,可以定位到cmd指定的方法,并进一步运行它;
    这里具体调用并执行的是def start(self, **kwargs):
  1. def start(self, **kwargs):
  2.         """
  3.         启动一个服务;
  4.         """
  5.         setup_env()
  6.         status = 0
  7.         for server in self.servers:
  8.             server.launch(**kwargs)
  9.         if not kwargs.get('daemon', True):
  10.             for server in self.servers:
  11.                 try:
  12.                     status += server.interact(**kwargs)
  13.                 except KeyboardInterrupt:
  14.                     print _('\nuser quit')
  15.                     self.stop(**kwargs)
  16.                     break
  17.         elif kwargs.get('wait', True):
  18.             for server in self.servers:
  19.                 status += server.wait(**kwargs)
  20.         return status
复制代码




   这个方法中将会依次启动servers指定的服务,即servers = ['proxy-server', 'account-server', 'container-server', 'object-server'];
    具体实现将会在下一篇博文中进行解析。
    博文中不免有不正确的地方,欢迎朋友们不吝批评指正,谢谢大家了!

相关内容:
OpenStack Swift源码分析(1)----swift服务启动源码分析之一

OpenStack Swift源码分析(2)----swift服务启动源码分析之二

OpenStack Swift源码分析(3)----swift服务启动源码分析之三





已有(1)人评论

跳转到指定楼层
yangdy 发表于 2015-11-20 16:28:51
Usage: swift-init <server>[.config] [<server>[.config] ...] <command> [options]这个是什么意思?可以swift-init proxy等等 start来启动吗?除了这个还有什么方式
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

关闭

推荐上一条 /2 下一条