沙箱发起的连接,用于 SSH 网关的端口转发 (WebSocket)
客户机从沙箱内部向 host:port 发起的一条 TCP 连接,以及一个 WebSocket,其二进制消息双向承载这条连接的字节:客户端的端口转发每请求一条连接,SSH 网关就这样建立一条(ssh -L <port>:<the sandbox's forward socket>,即进入沙箱的 SOCKS 代理)。由于连接由客户机发起,沙箱绑定在 127.0.0.1 上的服务也能访问;连往互联网的连接以沙箱自己的身份出去,计入它的出站流量;沙箱的出站规则像对待它发起的任何连接一样裁决这条连接:规则拒绝的会被拒绝,沙箱访问不到的地方也访问不到(节点、宿主机的其他地址、其他沙箱、私有地址段都不行)。拒绝发生在协议升级之前:返回 connect_failed,附带客户机给出的原因。客户端的文本消息 ForwardEof 表示它不再发送数据:客户机半关闭这条连接,对端之后发来的数据仍会传回。对端关闭连接时,或者在 GET /internal/node 的 ssh_forwards.idle_seconds 时间内双向都没有数据时,服务端以 1000 关闭。一个沙箱同时最多开 ssh_forwards.per_sandbox 条这样的连接。会唤醒沙箱,并在连接打开期间让它保持运行。只能用带 forward 权限范围的会话令牌打开:节点的 SSH 网关为每个会话获得这样的令牌 (POST /internal/ssh/authorize),控制平面也会为位于其前面的网关的会话获得:项目无法拥有这种令牌(POST …/tokens 只把 forward 授予运营方)。
消息格式见事件流和终端。
不接受项目的密钥;需要带 forward 的沙箱令牌。
https://api.glac.ai/v1/sandboxes/{id}/connect授权
路径参数
查询参数
请求头参数
Returns
101
此后连接即为 WebSocket。
400
请求不符合本调用的要求。unknown_parameter:查询中有本调用不接受的参数;websocket_expected:请求不是 WebSocket 升级请求;invalid_field:缺少 host 或 port,或超出范围。
401
missing_api_key, invalid_api_key, expired_api_key, invalid_token.
403
凭据无权执行此操作。needs_forward:凭据不是沙箱令牌(而是项目的密钥或运营方的密钥);token_scope:沙箱令牌不带 forward,只有 SSH 网关会话的令牌才带。spend_limit_reached:沙箱因达到支出上限而被冻结;它会连同数据一起休眠,直到上限提高。
404
请求中指定的对象不存在。sandbox_not_found:沙箱不存在。
409
某个对象的状态不允许此操作。sandbox_failed:沙箱处于 failed 状态;sandbox_too_old:沙箱创建于节点支持此功能之前。
502
connect_failed:客户机无法建立连接;错误信息中附有原因(does not resolve,或 [errno N]:111 表示没有程序在监听或沙箱的规则拒绝了连接,113 或 101 表示无路可达,110 表示 10 秒内没有响应)。
503
too_many_forwards:沙箱已打开 ssh_forwards.per_sandbox 条这样的连接;等其中一条结束后才能再开。可重试。
default
其他任何失败,格式相同。internal (500):节点出错;错误信息不会多说,节点日志中以请求的 id 记录了原因。unavailable(503,可重试):no_capacity,节点的网络槽位都已占用;memory_full,调用需要启动的虚拟机(创建、唤醒、从磁盘启动、恢复、回滚、构建)在宿主机内存中放不下(还要算上已承诺给其上运行的虚拟机的内存),也没有暂停或空闲的虚拟机可以让其休眠来腾出空间(节点的 memory);drive_full,调用需要构建模板,而节点的数据盘没有空间(节点的 drive);unavailable,节点正在关闭、沙箱 10 分钟后仍处于 starting、沙箱没有响应,或者沙箱正在迁到本节点(带 Retry-After: 1);fenced,节点的租约隔离了该沙箱 (Node.lease)。moved (409):沙箱已迁到另一个节点,由 to 指明。