Personal opinion, there may be errors. Just start learning Nova and learn from the API first.
1, D:\ code \python-novaclient\python-novaclient\novaclient\v1_1\shell.py, the top how to call is not very clear, start here first.
DEF do_list (cs, args): "" List active servers. "" " imageID = none Flavorid = none #查找镜像 if args.image: &nbs P imageID = _find_image (cs, args.image) .id #查找套餐类型 If args.flavor: &NBS P Flavorid = _find_flavor (cs, Args.flavor) .id search_opts</span> = { &N Bsp ' all_tenants ': args.all_tenants, ' reservation_id ': args.reservation_id, ' IP ': args.ip, ' IP6 ': args.ip6, & nbsp ' name ': args.name, ' image ': imageid, &NB Sp ' flavor ': flavorid, ' status ': args.status, &NBS P ' tenant_id ': args.tenant, #租赁人id &NBSP ' host ': args.host, ' instance_name ': Args.instance_nam e} #过滤条件 filters = {' Flavor ': lambda f:f[' id '], ' security_groups ': utils._format_security_groups} #存放过滤后的结果 formatters = {} <span style= "font-family:arial, Helvetica, Sans-serif;" > #formatters Dictionary keywords </span> field_titles = [] If args.fields: &NBSP ; For field in Args.fields.split (', '): #让field formatting into some sort of string Field_title, formatter = Utils._make_field_formatter (field, , &N Bsp filters)   Field_titles.append (field_title) Formatters[field_title] = formatter Id_col = ' id ' #同一目录下 The list method inside the servers.py, the next function explains here. List of #这里的返回值是server servers = cs.servers.list (search_opts=search_opts) </span></ strong> convert = [(' Os-ext-srv-attr:host ', ' host '), &NBSP ;(' os-ext-sts:task_state ', ' task_state '), (' Os-ext-srv-attr: Instance_name ', ' instance_name '), (' hostId ', ' host_id ')] & nbsp _translate_keys (servers, convert) #这个columns should be the meaning of the column, and printing about it. If field_titles: columns = [Id_col] + field_titles else:   ; columns = [Id_col, ' Name ', ' Status ', ' Networks '] formatters[' Networks '] = Utils._format_servers_list_networks #这里负责具体输出nova The output of the list command. utils.print_list (servers, columns, &NBS P;formatters, Sortby_index=1)
2. D:\ code \python-novaclient\python-novaclient\novaclient\v1_1\servers.py----The list method in the Servermanager class.
def list (self, detailed=true, Search_opts=none): "" " # Detailed is responsible for returning detailed server information, reservation_id only returns the corresponding ID. Get a list of servers. Optional detailed returns details server inf o. Optional reservation_id only returns instances with that Reservat ion_id. : rtype:list of:class: ' Server ' ' " &NBS P The contents of the #search_opt are shown in the green font of the previous function, which is a dictionary. If search_opts is none: search_opts = {} Qparams = {} #这里吧search_opt dictionary content copy to qparams for OPT, Val in Search_opts.iteritems (): If val: Qparams[opt] = val &NBSP;&NBsp; #这里把我们的选项进行url编码 because you want to send an HTTP request query_string = "?%s"% Urllib.urle Ncode (qparams) if qparams else "" detail = "" if detailed: &NB Sp detail = "/detail" #这里继续调用_list方法, the function below continues the analysis. The first parameter of this function is the URL, the second parameter is response_key return self._list ("/servers%s%s"% (detail, query_string), "Servers")
3. D:\ Code \python-novaclient\python-novaclient\novaclient\base.py-----_list Method
def _list (self, URL, Response_key, Obj_class=none, Body=none): #根据body是否为空调用post Or get method, both functions call a function, except that the arguments are not the same---_cs_request If body: _RESP, BODY = self.api.client.post (URL, body=body) else: &NBS P _RESP, BODY = self.api.client.get (URL) If Obj_class is none: Obj_class = self.resource_class #参考上边的传参, you can find this The content of Response_key should be "servers" #到这里我们获取了数据. data = body[response_key] # NOTE (JA): Keystone returns values as Li St as {' values ': [...]} # Unlike other services which just return the list... #上边的注释讲的很清楚, if data is a dictionary, the content of the specific server is insideThe corresponding key= ' values ' field value, the result is a list If isinstance (data, dict): &NB Sp try: data = data[' values '] Except keyerror: pass #这里没有仔细看了, the last word is return return results. The WITH statement, like the try finally, can handle the context cleanup of the exception condition. with Self.completion_cache (' human_id ', Obj_class, mode= "W"): &NBSP ; with Self.completion_cache (' uuid ', Obj_class, mode= "W"): RET urn [Obj_class (self, res, loaded=true) For RES in data if RES]
4. D:\ Code \python-novaclient\python-novaclient\novaclient\client.py----Post
Def post (self, URL, **kwargs): return self._cs_request (URL, ' post ', **kwargs) 5, d:\ code \ python-novaclient\python-novaclient\novaclient\client.py----_cs_request # The client sends the request sequence to the server. def _cs_request (self, URL, method, **kwargs): if not self.management_url: & nbsp self.authenticate () # Perform the request once. If we get a 401 back then it # might is because the auth token expired, so try to # re-authenticate and try again. If it still fails, bail. try: #headers If this key is not set to NULL, then Attribute ' X-auth-token ' assignment to headers dictionary Kwargs.setdefault (' headers ', {}) [' X-auth-token '] = self.auth_token If self.projectid: &N Bsp kwargs['Headers ' [' x-auth-project-id '] = self.projectid #这里进一步发送消息. RESP, BODY = self._time_request (self.management_url + URL, method, , &NB Sp **kwargs) return resp, body except EXCEP tions. Unauthorized as e: try: SE Lf.authenticate () kwargs[' headers ' [' x-auth-token '] = self.auth_ token RESP, BODY = self._time_request (Self.management_url + URL,&NB Sp , &NB Sp &NBSp method, **kwargs) return resp, body &NBS P except exceptions. unauthorized: raise E
6, D:\ code \python-novaclient\python-novaclient\novaclient\client.py----_time_request
def _time_request (self, URL, method, **kwargs): start_time = Time.time () resp, body = self.request (URL, method, * *kwargs) Self.times.append (("%s%s"% (method, url), start_time, Time.time ())) return resp, body
7. D:\ Code \python-novaclient\python-novaclient\novaclient\client.py----Request
def request (self, URL, method, **kwargs): kwargs.setdefault (' headers ', Kwargs.get (' headers ', {})) kwargs[' headers ' [' user-agent '] = self. user_agent kwargs[' headers ' [' Accept '] = ' Application/json ' if ' bod Y ' in kwargs: kwargs[' headers ' [' content-type '] = ' Application/json '   ; kwargs[' data '] = json.dumps (kwargs[' body ') del Kwarg s[' body '] If Self.timeout is not none: KWARGS.SETDEFAU LT (' timeout ', self.timeout) # Print request section self.http_log_req (URL, method ,), Kwargs) #这里发送http请求并得到相应的response. RESP =self.http.request ( method, url, verify=self.verify_cert, &NB Sp **kwargs) #打印相应部分 &NB Sp SELF.HTTP_LOG_RESP (RESP) #检查响应的内容. If resp.text: # TODO (dtroyer): Verify the note below In a requests context # NOTE (Alaski): Because Force_exceptions_to_status_code=tru e # HTTPLIB2 Returns a connection refused event as a response. & nbsp # to determine if it's a bad request or refused connection we need # to check the body. &NBSP;HTTPLIB2 tests check for ' Connection refused ' # or ' actively refused ' in th e body, so that's what we ' ll do. &NBsp if Resp.status_code = = 400: if (' Connection refused ' In Resp.text or ' actively refused ' in Resp.text): &nbs P raise exceptions. Connectionrefused (resp.text) try: BODY = json.loads (resp.text) except valueerror: &NBSP ; pass BODY = none &N Bsp else: BODY = none if Resp.status_code >= 400: raise Exceptions.from_response (resp, body, url, method) RET Urn resp, body
There are some content themselves do not understand, and then add, do_list the most outside by who call has not been written in, post and get the difference is not clear, first written here. Below the actual combat plus print tracking to see the specific process.
Copyright NOTICE: This article for Bo Master original article, without Bo Master permission not reproduced.
Nova Client source Code Analysis---Nova List command