1、VNC

在计算领域,虚拟网络计算(VNC)是一种图形桌面共享系统,它使用RFB协议远程控制另一台计算机。它将键盘和鼠标事件从一台计算机传输到另一台计算机,并通过网络将图形屏幕更新传递回另一个方向。在像OpenStack这样的IaaS系统中,VNC是最终用户通过GUI访问VMs的一个非常方便的工具。Nova提供两种VNC代理:noVNC和Nova xvpvncproxy。

2、整体流程

1)·使用nova get-vnc-console去获取VNC URL,nova-api接受到消息后向虚拟机所在的计算节点发送get_vnc_console rpc请求;

2)计算节点收到请求后生成一个token,并调用libvirt驱动的get_vnc_console函数;

3)libvirt连接libvirt服务端获取虚拟机的vnc port等信息;

4)nova-api向nova-consoleauth发送authorize_console请求,token作为键值将计算节点返回的信息进行缓存;

5)返回URL;

6)浏览器访问URL;

7)noVNC监听6080 HTTP 端口,接受此URL请求,然后向Nova-consoleauth发送check_token消息;

8)在浏览器中出现虚拟机桌面。

3、代码解析

    /nova/api/openstack/compute/remote_consoles.pydef get_vnc_console(self, req, id, body):"""Get text console output."""context = req.environ['nova.context']context.can(rc_policies.BASE_POLICY_NAME)# If type is not supplied or unknown, get_vnc_console below will cope#获取vnc类型,在命令行中增加的novnc参数console_type = body['os-getVNCConsole'].get('type')#获取虚拟机,调用计算节点上的函数,获取urlinstance = common.get_instance(self.compute_api, context, id)try:output = self.compute_api.get_vnc_console(context,instance,console_type)except exception.ConsoleTypeUnavailable as e:raise webob.exc.HTTPBadRequest(explanation=e.format_message())except (exception.InstanceUnknownCell,exception.InstanceNotFound) as e:raise webob.exc.HTTPNotFound(explanation=e.format_message())except exception.InstanceNotReady as e:raise webob.exc.HTTPConflict(explanation=e.format_message())except NotImplementedError:common.raise_feature_not_supported()return {'console': {'type': console_type, 'url': output['url']}}
    /nova/compute/api.pydef get_vnc_console(self, context, instance, console_type):"""Get a url to an instance Console."""#向计算节点发送rpc请求,请求消息发送至mq,获取connect_infoconnect_info = self.compute_rpcapi.get_vnc_console(context,instance=instance, console_type=console_type)#向nova-consoleauth发送请求,缓存connect_infoself.consoleauth_rpcapi.authorize_console(context,connect_info['token'], console_type,connect_info['host'], connect_info['port'],connect_info['internal_access_path'], instance.uuid,access_url=connect_info['access_url'])return {'url': connect_info['access_url']}
    /nova/compute/manager.pydef get_vnc_console(self, context, console_type, instance):"""Return connection information for a vnc console."""context = context.elevated()LOG.debug("Getting vnc console", instance=instance)#随机生成一个tokentoken = uuidutils.generate_uuid()if not CONF.vnc.enabled:raise exception.ConsoleTypeUnavailable(console_type=console_type)#对返回信息进行格式化if console_type == 'novnc':# For essex, novncproxy_base_url must include the full path# including the html file (like http://myhost/vnc_auto.html)access_url = '%s?token=%s' % (CONF.vnc.novncproxy_base_url, token)elif console_type == 'xvpvnc':access_url = '%s?token=%s' % (CONF.vnc.xvpvncproxy_base_url, token)else:raise exception.ConsoleTypeInvalid(console_type=console_type)try:# Retrieve connect info from driver, and then decorate with our# access info token#调用驱动函数获取真正的连接信息console = self.driver.get_vnc_console(context, instance)connect_info = console.get_connection_info(token, access_url)except exception.InstanceNotFound:if instance.vm_state != vm_states.BUILDING:raiseraise exception.InstanceNotReady(instance_id=instance.uuid)return connect_info
    /nova/consoleauth/manager.pydef authorize_console(self, context, token, console_type, host, port,internal_access_path, instance_uuid,access_url=None):#以token作为键值token_dict = {'token': token,'instance_uuid': instance_uuid,'console_type': console_type,'host': host,'port': port,'internal_access_path': internal_access_path,'access_url': access_url,'last_activity_at': time.time()}data = jsonutils.dumps(token_dict)#将token放在缓存中self.mc.set(token.encode('UTF-8'), data)tokens = self._get_tokens_for_instance(instance_uuid)# Remove the expired tokens from cache.token_values = self.mc.get_multi([tok.encode('UTF-8') for tok in tokens])tokens = [name for name, value in zip(tokens, token_values)if value is not None]tokens.append(token)self.mc_instance.set(instance_uuid.encode('UTF-8'),jsonutils.dumps(tokens))LOG.info(_LI("Received Token: %(token)s, %(token_dict)s"),{'token': token, 'token_dict': token_dict})
    /nova/console/websocketproxy.pydef new_websocket_client(self):"""Called after a new WebSocket connection has been established."""# Reopen the eventlet hub to make sure we don't share an epoll# fd with parent and/or siblings, which would be badfrom eventlet import hubshubs.use_hub()# The nova expected behavior is to have token# passed to the method GET of the requestparse = urlparse.urlparse(self.path)if parse.scheme not in ('http', 'https'):# From a bug in urlparse in Python < 2.7.4 we cannot support# special schemes (cf: http://bugs.python.org/issue9374)if sys.version_info < (2, 7, 4):raise exception.NovaException(_("We do not support scheme '%s' under Python < 2.7.4, ""please use http or https") % parse.scheme)query = parse.query#请求信息中获取tokentoken = urlparse.parse_qs(query).get("token", [""]).pop()if not token:# NoVNC uses it's own convention that forward token# from the request to a cookie header, we should check# also for this behaviorhcookie = self.headers.getheader('cookie')if hcookie:cookie = Cookie.SimpleCookie()for hcookie_part in hcookie.split(';'):hcookie_part = hcookie_part.lstrip()try:cookie.load(hcookie_part)except Cookie.CookieError:# NOTE(stgleb): Do not print out cookie content# for security reasons.LOG.warning(_LW('Found malformed cookie'))else:if 'token' in cookie:token = cookie['token'].valuectxt = context.get_admin_context()rpcapi = consoleauth_rpcapi.ConsoleAuthAPI()#对token信息进行校验connect_info = rpcapi.check_token(ctxt, token=token)if not connect_info:raise exception.InvalidToken(token=token)# Verify Originexpected_origin_hostname = self.headers.getheader('Host')if ':' in expected_origin_hostname:e = expected_origin_hostnameif '[' in e and ']' in e:expected_origin_hostname = e.split(']')[0][1:]else:expected_origin_hostname = e.split(':')[0]expected_origin_hostnames = CONF.console.allowed_originsexpected_origin_hostnames.append(expected_origin_hostname)origin_url = self.headers.getheader('Origin')# missing origin header indicates non-browser client which is OKif origin_url is not None:origin = urlparse.urlparse(origin_url)origin_hostname = origin.hostnameorigin_scheme = origin.schemeif origin_hostname == '' or origin_scheme == '':detail = _("Origin header not valid.")raise exception.ValidationError(detail=detail)if origin_hostname not in expected_origin_hostnames:detail = _("Origin header does not match this host.")raise exception.ValidationError(detail=detail)if not self.verify_origin_proto(connect_info, origin_scheme):detail = _("Origin header protocol does not match this host.")raise exception.ValidationError(detail=detail)self.msg(_('connect info: %s'), str(connect_info))host = connect_info['host']port = int(connect_info['port'])# Connect to the targetself.msg(_("connecting to: %(host)s:%(port)s") % {'host': host,'port': port})tsock = self.socket(host, port, connect=True)# Handshake as necessaryif connect_info.get('internal_access_path'):tsock.send("CONNECT %s HTTP/1.1\r\n\r\n" %connect_info['internal_access_path'])while True:data = tsock.recv(4096, socket.MSG_PEEK)if data.find("\r\n\r\n") != -1:if data.split("\r\n")[0].find("200") == -1:raise exception.InvalidConnectionInfo()tsock.recv(len(data))break# Start proxyingtry:self.do_proxy(tsock)except Exception:if tsock:tsock.shutdown(socket.SHUT_RDWR)tsock.close()self.vmsg(_("%(host)s:%(port)s: ""Websocket client or target closed") %{'host': host, 'port': port})raise

OpenStack--novnc获取登陆相关推荐

  1. ABAP 获取登陆者的IP地址和主机名

    DATA:   opcode_usr_attr(1) TYPE x VALUE 5,      terminal          TYPE usr41-terminal. * 获取终端名  OPCO ...

  2. 从微信服务器获取用户信息,微信小程序Ⅴ [获取登陆用户信息,重点openID(详解)]...

    ♩ 背景 其实这篇文章几个月前就写完了,可是这段时间,微信小程序官方文档有了更新,同事在我本身的实际操做过程当中,发现以前写的过于繁杂,因此如今进行简化梳理,欢迎指摘. 语言框架:ThinkPHP3. ...

  3. loadrunner之获取登陆接口中的token值及 LoadRunner数据更新与更新方式

    Loadrunner获取登陆接口中的token值   登录后,服务器会生成token并返回给客户端,之后客户端与服务器交互的操作中,服务器程序会对比这个token,正确则允许操作,否则拒绝客户端请求. ...

  4. openstack数据库获取一个虚机的floating_ip, fix_ip, project_name, user_name, hostname, host

     转载请注明 http://www.cnblogs.com/juandx/p/5418204.html openstack有3个库,nova,neutron,keystone,我现在需要做的是跨库联表 ...

  5. php curl获取登陆cookie,PHP curl 模拟登陆 获取cookie

    PHP curl 模拟登陆 获取cookie求助 菜鸟学习使用PHP curl模拟登陆,等陆weiphon论坛时用以下代码成功,登陆www.xiaomi.com就死活成功不了,求助啊.窃以为是cook ...

  6. 权限维持——获取登陆账号及安装后门程序

    当攻击者获取服务器权限后,通常会采用一些后门技术来维持自己当前得到的权限,服务器一旦被植入后门,那么攻击者下次进入就方便多了. 由于攻击可能被发现,会清除一些shell,导致目标丢失,所以需要留下后门 ...

  7. 爬虫-利用Cookiejar类对象获取登陆后的cookie信息-人人网旧版的模拟登陆演练

    http.cookiejar模块 演练-动态获取cookie然后访问个人中心 目标:构建相关的对象 流程: 创建cookiejar对象 创建cookie处理器对象 创建打开器对象 构建请求头(包含了u ...

  8. python 爬虫 cookies设置,获取登陆后界面。

    前言 Cookie Cookie 是指某些网站服务器为了辨别用户身份和进行Session跟踪,而储存在用户浏览器上的文本文件,Cookie可以保持登录信息到用户下次与服务器的会话. Cookie原理 ...

  9. Java实现扫码微信登陆(获取登陆成功的用户信息 + 包含使用vue怎么显示登陆二维码)

    实现于springboot中 依据b站视频写出的: 点击此处进行观看 然后记录于此处. 首先微信登陆的流程为: (可以去微信开发者平台看) 第一步:请求CODE 若提示"该链接无法访问&qu ...

最新文章

  1. 曝光丨探访哈工大机器人的秘密基地(图)
  2. 前端面试instanceof_一起回归一下每日一题这些经典面试题
  3. 阿里云图数据库GDB V3引擎发布,加速开启“图智”未来
  4. SpringBoot整合Redis 主从复制_01
  5. php基础语法知识笔记(一)
  6. 集成ueditor后显示html问题处理
  7. Linux技术进阶示意图
  8. 如何在 macOS Monterey 中更改光标颜色
  9. PIP(Python包管理工具)-Mac环境下安装
  10. 方波、三角波、正弦波信号发生器
  11. Windows下CURL编译 支持HTTPS
  12. Spring Data Rest学习篇----@Projection
  13. 微信公众号关注回复,关键字回复全流程开发
  14. 基于解决sci和ei等国外论文检索难等问题的辅助软件分析
  15. 物联网智慧物流平台开发
  16. 如何利用Simulink来设计一个AEB的算法,并通过SCANeR仿真来测试?
  17. 函数式编程之根-拉姆达运算/演算(λ-calculus)
  18. 粒子寻优算法PSO学习笔记
  19. python爬虫系列--lxml(etree/parse/xpath)的使用
  20. 计算机联锁控制系统技术是,铁路信号计算机联锁控制系统容错技术探析

热门文章

  1. Raft算法(zookeeper核心算法)
  2. 树状数组(单点修改,区间修改等)
  3. 2022年全球市场天然除臭剂和香水总体规模、主要生产商、主要地区、产品和应用细分研究报告
  4. 【JS】获取当前日期与时间
  5. python怎么用turtle画同心圆_在Python中用turtle函数画同心圆
  6. 绝对路径和相对路径详解
  7. markdown 表格不能换行吗
  8. Vue进阶(七十五):相对路径和绝对路径
  9. 带你优雅地使用Ubuntu——新电脑安装Ubuntu问题解决、常用软件安装、桌面美化一条龙
  10. 微信朋友圈广告投放价格