swift源代码解读(一)

来源:互联网 发布:imo即时通讯软件 编辑:程序博客网 时间:2024/06/06 00:09

首先获得swift的源代码,使用git clone https://github.opnestack/swift.git来获得源代码,然后看看其中的启动过程swift-init文件源代码如下

#!/usr/bin/env python# Copyright (c) 2010-2012 OpenStack Foundation## Licensed under the Apache License, Version 2.0 (the "License");# you may not use this file except in compliance with the License.# You may obtain a copy of the License at##    http://www.apache.org/licenses/LICENSE-2.0## Unless required by applicable law or agreed to in writing, software# distributed under the License is distributed on an "AS IS" BASIS,# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or# implied.# See the License for the specific language governing permissions and# limitations under the License.import sysfrom optparse import OptionParserfrom swift.common.manager import Manager, UnknownCommandError, \    KILL_WAIT, RUN_DIRAGE = """%prog <server>[.config] [<server>[.config] ...] <command> [options]Commands:""" + '\n'.join(["%16s: %s" % x for x in Manager.list_commands()])def main():    parser = OptionParser(USAGE)#填入提示纤细,将在parser.print()进行输出#进行参数的解析,如果是-v  则进行存储    parser.add_option('-v', '--verbose', action="store_true",                      default=False, help="display verbose output")  #将-w 后的参数放在parser.wait对象当中    parser.add_option('-w', '--no-wait', action="store_false", dest="wait",                      default=True, help="won't wait for server to start "                      "before returning")    #解析 -o后的参数,    parser.add_option('-o', '--once', action="store_true",                      default=False, help="only run one pass of daemon")    # this is a negative option, default is options.daemon = True#解析 -n后的参数,放在daemon成员对象当中    parser.add_option('-n', '--no-daemon', action="store_false", dest="daemon",                      default=True, help="start server interactively")#解析-g 后的参数    parser.add_option('-g', '--graceful', action="store_true",                      default=False, help="send SIGHUP to supporting servers")#解析-c后的参数,并将该成员对象放在parser.number成员对象当中    parser.add_option('-c', '--config-num', metavar="N", type="int",                      dest="number", default=0,                      help="send command to the Nth server only")#解析 -k 后的参数,    parser.add_option('-k', '--kill-wait', metavar="N", type="int",                      dest="kill_wait", default=KILL_WAIT,                      help="wait N seconds for processes to die (default 15)")#解析 -r后的参数,放在run_dir成员对象中    parser.add_option('-r', '--run-dir', type="str",                      dest="run_dir", default=RUN_DIR,                      help="alternative directory to store running pid files "                      "default: %s" % RUN_DIR)    #进行输入参数解析    options, args = parser.parse_args()    if len(args) < 2:        parser.print_help()        print 'ERROR: specify server(s) and command'        return 1    command = args[-1]#python将数组看成是一个环,-1就是0的前一个,也就是最后一个    servers = args[:-1]#args去掉最后一个之后的数组    # this is just a silly swap for me cause I always try to "start main"    commands = dict(Manager.list_commands()).keys()    #例如,如果输入是swift-init main start 则command是start    servers 则是['swift-init','main']       if command not in commands and servers[0] in commands:        servers.append(command)        command = servers.pop(0)
我们一步一步的看,假如输入的用户命令是swift-init   main start

那么。我们可以得到

command=start#也即输入的最后一个参数start

而servers=args[:-1]则是args去掉最后一个也即

servers=swift-init main

然后继续分析代码

 commands = dict(Manager.list_commands()).keys()
Manager.list_commands函数在swift/swift/common/manager.py文件当中定义的,
 #在@classname函数中的不使用self而是cls,静态函数使用@staticmethod声明的,可以不带有参数    def list_commands(cls):        #返回一系列可以作为命令的函数的字符串,三个双引号,表示三个双引号之间的内容都是一个        """Get all publicly accessible commands         :returns: a list of string tuples (cmd, help), the method names who are                  decorated as commands        """        get_method = lambda cmd: getattr(cls, cmd)#lambda匿名函数,定义了一个变量get_method,参数是cmd,直接调用getattr                return sorted([(x.replace('_', '-'), get_method(x).__doc__.strip())                       #遍历Manager对象的成员,如果成员又属性'publicly_accessible'                       #则返回该成员,如果没有,则返回False,对于符合条件的成员则获得一个键值对,一个是名称如"start"一个是描述                       for x in dir(cls) if                       getattr(get_method(x), 'publicly_accessible', False)])#

需要注意的是list_commands是一个@clasmethod也即类函数,可以直接使用类来访问.

接下来继续分析代码,一下这段代码的含义是用户输入的最后一个参数不在commands当中,但是第一个却在commands当中,那么我们进行替换,第一个参数设置成command,而最后一个则是服务,避免错误的命令,例如 swift-init main start 是可行的,但是start  swift-init main也是对的!!!

if command not in commands and servers[0] in commands:        servers.append(command)        command = servers.pop(0)
继续代码
 manager = Manager(servers, run_dir=options.run_dir)#如上面的输入有效参数是:main,依次加载主要服务

这段代码主要作用是加载服务,如果用户输入的是swift-init  main start ,那么command则是start   servers 则是swift-init main,现在看下Manager的构造函数

 def __init__(self, servers, run_dir=RUN_DIR):        self.server_names = set()#Manager的server_names初始化为一个集合,我们可以认为servers里面是swift-init main,也即有效参数是main        for server in servers:            if server == 'all':                self.server_names.update(ALL_SERVERS)            elif server == 'main':                self.server_names.update(MAIN_SERVERS)  #server_names更新成为  MAIN_SERVERS = ['proxy-server', 'account-server', 'container-server', 'object-server']            elif server == 'rest':                self.server_names.update(REST_SERVERS)            elif '*' in server:                # convert glob to regex                self.server_names.update([                    s for s in ALL_SERVERS if                    re.match(server.replace('*', '.*'), s)])            else:                self.server_names.add(server)        self.servers = set()#Manager的servers成员初始化成为一个集合        for name in self.server_names:            self.servers.add(Server(name, run_dir))#依次添加服务

至此,我们的准备工作完成接下来就是运行命令了...

0 0