沙箱中的客户端 SSH agent,供一个 SSH 会话使用 (WebSocket)
客户端转发其 agent (ssh -A) 时,SSH 网关请求的就是这个:客户机在一个只有 user(和 root)能进入的专用目录中创建套接字 /run/sbx/ssh-agent.<id>/agent,第一条消息 (AgentListening) 告知其位置:会话中的命令通过 SSH_AUTH_SOCK 获得它。之后,二进制消息承载程序对它发起的连接,每条消息由一个类型字节、连接编号(四个字节,小端序)和数据组成:服务端发出 n(有程序连接)、o(程序发送的数据)、x(程序关闭了连接);客户端发出 d(agent 的响应)和 x(agent 关闭了连接)。AgentReset 表示所有连接都已断开:沙箱进入了休眠。创建套接字时会唤醒沙箱,但套接字不会让沙箱保持运行:沙箱休眠期间 WebSocket 保持不变,沙箱再次运行时套接字还是原来那个。关闭 WebSocket 即结束套接字;如果当时沙箱在休眠,套接字会在沙箱再次运行一分钟后自行消失。用同一个 id 再次调用会从第一次调用手中接管套接字。只能用带 forward 权限范围的会话令牌打开:节点的 SSH 网关为每个会话获得这样的令牌 (POST /internal/ssh/authorize),控制平面也会为位于其前面的网关的会话获得:项目无法拥有这种令牌(POST …/tokens 只把 forward 授予运营方)。
消息格式见事件流和终端。
不接受项目的密钥;需要带 forward 的沙箱令牌。
https://api.glac.ai/v1/sandboxes/{id}/agent授权
路径参数
查询参数
请求头参数
Returns
101
此后连接即为 WebSocket。
400
请求不符合本调用的要求。unknown_parameter:查询中有本调用不接受的参数;websocket_expected:请求不是 WebSocket 升级请求;invalid_field:缺少 id 或 user,或者它们无效;no_such_user:沙箱中没有该用户。
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
agent_failed:客户机无法创建套接字;错误信息中附有原因(一个沙箱最多转发 16 个 agent)。
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 指明。