fix docs
This commit is contained in:
parent
d506ec98d5
commit
c4d17b9024
@ -15,31 +15,41 @@
|
|||||||
`iot` 通过 TLS 长连接向 `efka` 下发容器命令:
|
`iot` 通过 TLS 长连接向 `efka` 下发容器命令:
|
||||||
|
|
||||||
```erlang
|
```erlang
|
||||||
{command, Ref, {container, CommandMap}}
|
{<<"command">>, Ref, {<<"container">>, CommandMap}}
|
||||||
```
|
```
|
||||||
|
|
||||||
`efka` 执行后回复:
|
`efka` 执行后回复:
|
||||||
|
|
||||||
```erlang
|
```erlang
|
||||||
{command_response, Ref, {container, Reply}}
|
{<<"command_response">>, Ref, {<<"container">>, Reply}}
|
||||||
```
|
```
|
||||||
|
|
||||||
`Reply` 取值:
|
`Reply` 取值:
|
||||||
|
|
||||||
```erlang
|
```erlang
|
||||||
ok
|
<<"ok">>
|
||||||
{ok, Result}
|
{<<"ok">>, Result}
|
||||||
{error, Reason}
|
{<<"error">>, Reason}
|
||||||
```
|
```
|
||||||
|
|
||||||
只有 `efka_client` 处于 `activated` 状态时,容器命令才会正常执行;处于 `restricted` 或其他状态时会返回错误。
|
`Ref` 是 `crypto:strong_rand_bytes(16)` 生成的 16 字节 binary。网络帧只使用 `binary_to_term(PacketBin, [safe])` 可解码的 safe term;协议 label、业务 label、map key 和 action 都使用 binary。
|
||||||
|
|
||||||
|
只有 `efka_client` 处于 `activated` 状态时,容器命令才会正常执行;处于非 activated 状态时会返回错误。
|
||||||
|
|
||||||
## 2. 容器命令 map
|
## 2. 容器命令 map
|
||||||
|
|
||||||
|
`efka_client` 收到网络协议里的 binary-key `CommandMap` 后,直接按 binary key 和 binary action 做函数参数匹配,不再做整包 atom-key 转换。
|
||||||
|
|
||||||
|
- command 顶层、`target`、deploy `params`、`create` 中间结构都使用 binary key。
|
||||||
|
- `<<"action">>` 的取值使用 binary:`<<"list">>`、`<<"deploy">>`、`<<"start">>`、`<<"stop">>`、`<<"kill">>`、`<<"remove">>`、`<<"config">>`。
|
||||||
|
- `<<"__undefined__">>` 只在 Docker 参数构造读取可选字段时按需当成 `undefined` 处理。
|
||||||
|
|
||||||
|
下面各小节描述的是 `efka` 直接接收和处理的 map 格式。
|
||||||
|
|
||||||
### list
|
### list
|
||||||
|
|
||||||
```erlang
|
```erlang
|
||||||
#{action => list}
|
#{<<"action">> => <<"list">>}
|
||||||
```
|
```
|
||||||
|
|
||||||
执行:
|
执行:
|
||||||
@ -58,9 +68,9 @@ GET /containers/json?all=true
|
|||||||
|
|
||||||
```erlang
|
```erlang
|
||||||
#{
|
#{
|
||||||
action => deploy,
|
<<"action">> => <<"deploy">>,
|
||||||
task_id => TaskId,
|
<<"task_id">> => TaskId,
|
||||||
params => Params
|
<<"params">> => Params
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
@ -76,8 +86,8 @@ docker_deploy_manager:deploy(TaskId, Params)
|
|||||||
|
|
||||||
```erlang
|
```erlang
|
||||||
#{
|
#{
|
||||||
action => start,
|
<<"action">> => <<"start">>,
|
||||||
target => Target
|
<<"target">> => Target
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
@ -97,9 +107,9 @@ POST /containers/{name_or_id}/start
|
|||||||
|
|
||||||
```erlang
|
```erlang
|
||||||
#{
|
#{
|
||||||
action => stop,
|
<<"action">> => <<"stop">>,
|
||||||
target => Target,
|
<<"target">> => Target,
|
||||||
timeout_seconds => TimeoutSeconds
|
<<"timeout_seconds">> => TimeoutSeconds
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
@ -119,9 +129,9 @@ POST /containers/{name_or_id}/stop?t={TimeoutSeconds}
|
|||||||
|
|
||||||
```erlang
|
```erlang
|
||||||
#{
|
#{
|
||||||
action => kill,
|
<<"action">> => <<"kill">>,
|
||||||
target => Target,
|
<<"target">> => Target,
|
||||||
signal => Signal
|
<<"signal">> => Signal
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
@ -135,10 +145,10 @@ docker_commands:kill_container(ContainerNameOrId, Signal)
|
|||||||
|
|
||||||
```erlang
|
```erlang
|
||||||
#{
|
#{
|
||||||
action => remove,
|
<<"action">> => <<"remove">>,
|
||||||
target => Target,
|
<<"target">> => Target,
|
||||||
force => Force,
|
<<"force">> => Force,
|
||||||
remove_volumes => RemoveVolumes
|
<<"remove_volumes">> => RemoveVolumes
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
@ -152,9 +162,9 @@ docker_commands:remove_container(ContainerNameOrId, Force, RemoveVolumes)
|
|||||||
|
|
||||||
```erlang
|
```erlang
|
||||||
#{
|
#{
|
||||||
action => config,
|
<<"action">> => <<"config">>,
|
||||||
target => Target,
|
<<"target">> => Target,
|
||||||
config => Config
|
<<"config">> => Config
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
@ -172,8 +182,8 @@ docker_helper:update_container_config(ContainerNameOrId, iolist_to_binary(Config
|
|||||||
|
|
||||||
```erlang
|
```erlang
|
||||||
#{
|
#{
|
||||||
name => ContainerName,
|
<<"name">> => ContainerName,
|
||||||
id => ContainerId
|
<<"id">> => ContainerId
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
@ -189,8 +199,8 @@ docker_helper:update_container_config(ContainerNameOrId, iolist_to_binary(Config
|
|||||||
|
|
||||||
```erlang
|
```erlang
|
||||||
#{
|
#{
|
||||||
container_name => ContainerName,
|
<<"container_name">> => ContainerName,
|
||||||
create => Create
|
<<"create">> => Create
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
@ -215,9 +225,9 @@ efka.root_dir/container_name/
|
|||||||
|
|
||||||
```erlang
|
```erlang
|
||||||
#{
|
#{
|
||||||
config => ContainerConfig,
|
<<"config">> => ContainerConfig,
|
||||||
host_config => HostConfig,
|
<<"host_config">> => HostConfig,
|
||||||
networking_config => NetworkingConfig
|
<<"networking_config">> => NetworkingConfig
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
@ -340,8 +350,8 @@ Body = iolist_to_binary(json:encode(Options))
|
|||||||
|
|
||||||
```erlang
|
```erlang
|
||||||
[
|
[
|
||||||
#{container_port => 80, protocol => <<"tcp">>},
|
#{<<"container_port">> => 80, <<"protocol">> => <<"tcp">>},
|
||||||
#{container_port => 53, protocol => <<"udp">>}
|
#{<<"container_port">> => 53, <<"protocol">> => <<"udp">>}
|
||||||
]
|
]
|
||||||
```
|
```
|
||||||
|
|
||||||
@ -369,10 +379,10 @@ Body = iolist_to_binary(json:encode(Options))
|
|||||||
|
|
||||||
```erlang
|
```erlang
|
||||||
#{
|
#{
|
||||||
test => [<<"CMD-SHELL">>, <<"curl -f http://localhost || exit 1">>],
|
<<"test">> => [<<"CMD-SHELL">>, <<"curl -f http://localhost || exit 1">>],
|
||||||
interval_ns => 30000000000,
|
<<"interval_ns">> => 30000000000,
|
||||||
timeout_ns => 10000000000,
|
<<"timeout_ns">> => 10000000000,
|
||||||
retries => 3
|
<<"retries">> => 3
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
@ -440,7 +450,7 @@ efka 自动补丁后输出:
|
|||||||
输入:
|
输入:
|
||||||
|
|
||||||
```erlang
|
```erlang
|
||||||
#{name => <<"always">>, maximum_retry_count => 0}
|
#{<<"name">> => <<"always">>, <<"maximum_retry_count">> => 0}
|
||||||
```
|
```
|
||||||
|
|
||||||
输出:
|
输出:
|
||||||
@ -458,7 +468,7 @@ efka 自动补丁后输出:
|
|||||||
输入:
|
输入:
|
||||||
|
|
||||||
```erlang
|
```erlang
|
||||||
#{name => <<"on-failure">>, maximum_retry_count => 3}
|
#{<<"name">> => <<"on-failure">>, <<"maximum_retry_count">> => 3}
|
||||||
```
|
```
|
||||||
|
|
||||||
输出:
|
输出:
|
||||||
@ -481,9 +491,9 @@ efka 自动补丁后输出:
|
|||||||
```erlang
|
```erlang
|
||||||
[
|
[
|
||||||
#{
|
#{
|
||||||
path_on_host => <<"/dev/ttyUSB0">>,
|
<<"path_on_host">> => <<"/dev/ttyUSB0">>,
|
||||||
path_in_container => <<"/dev/ttyUSB0">>,
|
<<"path_in_container">> => <<"/dev/ttyUSB0">>,
|
||||||
cgroup_permissions => <<"rwm">>
|
<<"cgroup_permissions">> => <<"rwm">>
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
```
|
```
|
||||||
@ -512,10 +522,10 @@ efka 自动补丁后输出:
|
|||||||
|
|
||||||
```erlang
|
```erlang
|
||||||
#{
|
#{
|
||||||
memory => 536870912,
|
<<"memory">> => 536870912,
|
||||||
memory_reservation => 268435456,
|
<<"memory_reservation">> => 268435456,
|
||||||
nano_cpus => 1500000000,
|
<<"nano_cpus">> => 1500000000,
|
||||||
cpu_shares => 512
|
<<"cpu_shares">> => 512
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
@ -540,7 +550,7 @@ efka 自动补丁后输出:
|
|||||||
|
|
||||||
```erlang
|
```erlang
|
||||||
[
|
[
|
||||||
#{name => <<"nofile">>, soft => 1024, hard => 2048}
|
#{<<"name">> => <<"nofile">>, <<"soft">> => 1024, <<"hard">> => 2048}
|
||||||
]
|
]
|
||||||
```
|
```
|
||||||
|
|
||||||
@ -628,9 +638,9 @@ efka 自动补丁后输出:
|
|||||||
|
|
||||||
```erlang
|
```erlang
|
||||||
#{
|
#{
|
||||||
endpoints => [
|
<<"endpoints">> => [
|
||||||
#{name => <<"bridge">>},
|
#{<<"name">> => <<"bridge">>},
|
||||||
#{name => <<"mynet">>}
|
#{<<"name">> => <<"mynet">>}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
@ -661,26 +671,26 @@ efka 自动补丁后输出:
|
|||||||
收到的 deploy command:
|
收到的 deploy command:
|
||||||
|
|
||||||
```erlang
|
```erlang
|
||||||
{command, Ref, {container, #{
|
{<<"command">>, Ref, {<<"container">>, #{
|
||||||
action => deploy,
|
<<"action">> => <<"deploy">>,
|
||||||
task_id => 1001,
|
<<"task_id">> => 1001,
|
||||||
params => #{
|
<<"params">> => #{
|
||||||
container_name => <<"my_nginx">>,
|
<<"container_name">> => <<"my_nginx">>,
|
||||||
create => #{
|
<<"create">> => #{
|
||||||
config => #{
|
<<"config">> => #{
|
||||||
image => <<"docker.io/library/nginx:latest">>,
|
<<"image">> => <<"docker.io/library/nginx:latest">>,
|
||||||
cmd => [<<"nginx">>, <<"-g">>, <<"daemon off;">>],
|
<<"cmd">> => [<<"nginx">>, <<"-g">>, <<"daemon off;">>],
|
||||||
env => [<<"ENV=prod">>],
|
<<"env">> => [<<"ENV=prod">>],
|
||||||
volumes => [<<"/data">>],
|
<<"volumes">> => [<<"/data">>],
|
||||||
exposed_ports => [#{container_port => 80, protocol => <<"tcp">>}]
|
<<"exposed_ports">> => [#{<<"container_port">> => 80, <<"protocol">> => <<"tcp">>}]
|
||||||
},
|
},
|
||||||
host_config => #{
|
<<"host_config">> => #{
|
||||||
binds => [<<"/host/data:/data">>],
|
<<"binds">> => [<<"/host/data:/data">>],
|
||||||
restart_policy => #{name => <<"always">>, maximum_retry_count => 0},
|
<<"restart_policy">> => #{<<"name">> => <<"always">>, <<"maximum_retry_count">> => 0},
|
||||||
memory => 536870912
|
<<"memory">> => 536870912
|
||||||
},
|
},
|
||||||
networking_config => #{
|
<<"networking_config">> => #{
|
||||||
endpoints => [#{name => <<"bridge">>}]
|
<<"endpoints">> => [#{<<"name">> => <<"bridge">>}]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -2,95 +2,99 @@
|
|||||||
|
|
||||||
本文档描述 `efka` 与 `iot` 之间的 TLS 长连接协议。当前协议由 Erlang term 直接序列化,发送端使用 `term_to_binary/1`,接收端使用 `binary_to_term(PacketBin, [safe])`。
|
本文档描述 `efka` 与 `iot` 之间的 TLS 长连接协议。当前协议由 Erlang term 直接序列化,发送端使用 `term_to_binary/1`,接收端使用 `binary_to_term(PacketBin, [safe])`。
|
||||||
|
|
||||||
|
协议帧只使用 safe external term:顶层 label、业务 label、map key 使用 binary;`Ref` 使用 `crypto:strong_rand_bytes(16)` 生成,是 16 字节 binary。网络协议里不发送 Erlang `reference()`,也不依赖动态创建 atom。
|
||||||
|
|
||||||
## 传输层
|
## 传输层
|
||||||
|
|
||||||
- `efka` 作为 TLS client 连接 `iot`。
|
- `efka` 作为 TLS client 连接 `iot`。
|
||||||
- `iot` 作为 TLS server 接收多个 `efka` 连接,一个连接对应一个 `ssl_channel` 进程。
|
- `iot` 作为 TLS server 接收多个 `efka` 连接,一个连接对应一个 `ssl_channel` 进程。
|
||||||
- socket 使用 `{packet, 4}`,每个 Erlang term binary 作为一个完整包发送。
|
- socket 使用 `{packet, 4}`,每个 Erlang term binary 作为一个完整包发送。
|
||||||
- `Ref` 使用 `make_ref()` 生成,只在当前连接的 inflight 表内匹配。
|
- `Ref` 使用 `crypto:strong_rand_bytes(16)` 生成,只在当前连接的 inflight 表内匹配。
|
||||||
|
|
||||||
## 顶层帧
|
## 顶层帧
|
||||||
|
|
||||||
协议顶层 tuple 用来表达交互语义:
|
协议顶层 tuple 用来表达交互语义:
|
||||||
|
|
||||||
```erlang
|
```erlang
|
||||||
{request, Ref, Body}
|
{<<"request">>, Ref, Body}
|
||||||
{response, Ref, Reply}
|
{<<"response">>, Ref, Reply}
|
||||||
{command, Ref, {Domain, Payload}}
|
{<<"command">>, Ref, {Domain, Payload}}
|
||||||
{command_response, Ref, {Domain, Reply}}
|
{<<"command_response">>, Ref, {Domain, Reply}}
|
||||||
{message, Body}
|
{<<"message">>, Body}
|
||||||
```
|
```
|
||||||
|
|
||||||
语义说明:
|
语义说明:
|
||||||
|
|
||||||
| 帧 | 方向 | 语义 |
|
| 帧 | 方向 | 语义 |
|
||||||
| --- | --- | --- |
|
| --- | --- | --- |
|
||||||
| `{request, Ref, Body}` | efka -> iot | efka 发起请求,需要 iot 回复 |
|
| `{<<"request">>, Ref, Body}` | efka -> iot | efka 发起请求,需要 iot 回复 |
|
||||||
| `{response, Ref, Reply}` | iot -> efka | iot 对 efka request 的回复 |
|
| `{<<"response">>, Ref, Reply}` | iot -> efka | iot 对 efka request 的回复 |
|
||||||
| `{command, Ref, {Domain, Payload}}` | iot -> efka | iot 下发命令,需要 efka 回复 |
|
| `{<<"command">>, Ref, {Domain, Payload}}` | iot -> efka | iot 下发命令,需要 efka 回复 |
|
||||||
| `{command_response, Ref, {Domain, Reply}}` | efka -> iot | efka 对 iot command 的回复 |
|
| `{<<"command_response">>, Ref, {Domain, Reply}}` | efka -> iot | efka 对 iot command 的回复 |
|
||||||
| `{message, Body}` | 双向 | 异步消息,不要求回复 |
|
| `{<<"message">>, Body}` | 双向 | 异步消息,不要求回复 |
|
||||||
|
|
||||||
`command` 和 `command_response` 的 `Domain` 表示业务域,目前支持:
|
`command` 和 `command_response` 的 `Domain` 表示业务域,目前支持:
|
||||||
|
|
||||||
- `container`
|
- `<<"container">>`
|
||||||
|
|
||||||
## 鉴权请求
|
## 鉴权请求
|
||||||
|
|
||||||
初始连接由 `efka` 发起鉴权 request。每条 TLS 连接只允许一次鉴权;`iot` 侧鉴权成功后会在 `ssl_channel` 标记该连接已鉴权,如果同一连接再次发送 `auth_request`,`iot` 会直接关闭连接。
|
初始连接由 `efka` 发起鉴权 request。每条 TLS 连接只允许一次鉴权;`iot` 侧鉴权成功后会在 `ssl_channel` 标记该连接已鉴权,如果同一连接再次发送 `auth_request`,`iot` 会直接关闭连接。
|
||||||
|
|
||||||
```erlang
|
```erlang
|
||||||
{request, Ref, {auth_request, #{
|
{<<"request">>, Ref, {<<"auth_request">>, #{
|
||||||
uuid => UUID,
|
<<"uuid">> => UUID,
|
||||||
token => Token,
|
<<"token">> => Token,
|
||||||
timestamp => Timestamp
|
<<"timestamp">> => Timestamp
|
||||||
}}}
|
}}}
|
||||||
```
|
```
|
||||||
|
|
||||||
`iot` 回复:
|
`iot` 回复:
|
||||||
|
|
||||||
```erlang
|
```erlang
|
||||||
{response, Ref, {auth_response, ok}}
|
{<<"response">>, Ref, {<<"auth_response">>, <<"ok">>}}
|
||||||
{response, Ref, {auth_response, {error, {failed, Reason}}}}
|
{<<"response">>, Ref, {<<"auth_response">>, {<<"error">>, {<<"failed">>, Reason}}}}
|
||||||
```
|
```
|
||||||
|
|
||||||
处理语义:
|
处理语义:
|
||||||
|
|
||||||
- `ok`:`efka` 进入 `activated` 状态。
|
- `<<"ok">>`:`efka` 进入 `activated` 状态。
|
||||||
- `{error, {failed, Reason}}`:鉴权失败,`iot` 返回失败响应后关闭连接;`efka` 进入重连流程。
|
- `{<<"error">>, {<<"failed">>, Reason}}`:鉴权失败,`iot` 返回失败响应后关闭连接;`efka` 进入重连流程。
|
||||||
|
|
||||||
## 授权控制
|
## 授权控制
|
||||||
|
|
||||||
`/host/activate` 只修改 `iot` 本地和持久化的 host 授权状态,不再向 `efka` 下发 auth command。`efka` 可以继续保持连接并发送数据,是否处理这些数据由 `iot_host` 当前状态决定。
|
`/host/activate` 只修改 `iot` 本地和持久化的 host 授权状态,不再向 `efka` 下发 auth command。`efka` 可以继续保持连接并发送数据,是否处理这些数据由 `iot_host` 当前状态决定。
|
||||||
|
|
||||||
因此当前协议没有 `{command, Ref, {auth, ...}}` 和 `{command_response, Ref, {auth, ...}}`。授权关闭时,`iot_host` 保持 channel 在线,但不处理上报数据;授权重新打开后,已在线的 channel 可以继续使用。
|
因此当前协议没有 `{<<"command">>, Ref, {<<"auth">>, ...}}` 和 `{<<"command_response">>, Ref, {<<"auth">>, ...}}`。授权关闭时,`iot_host` 保持 channel 在线,但不处理上报数据;授权重新打开后,已在线的 channel 可以继续使用。
|
||||||
|
|
||||||
## 容器管理命令
|
## 容器管理命令
|
||||||
|
|
||||||
`iot` 对 `efka` 的容器管理使用 command 语义:
|
`iot` 对 `efka` 的容器管理使用 command 语义:
|
||||||
|
|
||||||
```erlang
|
```erlang
|
||||||
{command, Ref, {container, CommandMap}}
|
{<<"command">>, Ref, {<<"container">>, CommandMap}}
|
||||||
```
|
```
|
||||||
|
|
||||||
`efka` 回复:
|
`efka` 回复:
|
||||||
|
|
||||||
```erlang
|
```erlang
|
||||||
{command_response, Ref, {container, Reply}}
|
{<<"command_response">>, Ref, {<<"container">>, Reply}}
|
||||||
```
|
```
|
||||||
|
|
||||||
`Reply` 取值:
|
`Reply` 取值:
|
||||||
|
|
||||||
```erlang
|
```erlang
|
||||||
ok
|
<<"ok">>
|
||||||
{ok, Result}
|
{<<"ok">>, Result}
|
||||||
{error, Reason}
|
{<<"error">>, Reason}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
`CommandMap` 使用 binary key 和 binary action;`efka` 接收后直接按 binary key/action 匹配,Docker 参数链路继续使用 binary-key map,不再转换成 atom-key map。
|
||||||
|
|
||||||
### list
|
### list
|
||||||
|
|
||||||
```erlang
|
```erlang
|
||||||
#{action => list}
|
#{<<"action">> => <<"list">>}
|
||||||
```
|
```
|
||||||
|
|
||||||
返回当前 `efka` 主机上的容器列表。
|
返回当前 `efka` 主机上的容器列表。
|
||||||
@ -99,9 +103,9 @@ ok
|
|||||||
|
|
||||||
```erlang
|
```erlang
|
||||||
#{
|
#{
|
||||||
action => deploy,
|
<<"action">> => <<"deploy">>,
|
||||||
task_id => TaskId,
|
<<"task_id">> => TaskId,
|
||||||
params => Params
|
<<"params">> => Params
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
@ -111,8 +115,8 @@ ok
|
|||||||
|
|
||||||
```erlang
|
```erlang
|
||||||
#{
|
#{
|
||||||
action => start,
|
<<"action">> => <<"start">>,
|
||||||
target => Target
|
<<"target">> => Target
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
@ -120,9 +124,9 @@ ok
|
|||||||
|
|
||||||
```erlang
|
```erlang
|
||||||
#{
|
#{
|
||||||
action => stop,
|
<<"action">> => <<"stop">>,
|
||||||
target => Target,
|
<<"target">> => Target,
|
||||||
timeout_seconds => TimeoutSeconds
|
<<"timeout_seconds">> => TimeoutSeconds
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
@ -130,9 +134,9 @@ ok
|
|||||||
|
|
||||||
```erlang
|
```erlang
|
||||||
#{
|
#{
|
||||||
action => kill,
|
<<"action">> => <<"kill">>,
|
||||||
target => Target,
|
<<"target">> => Target,
|
||||||
signal => Signal
|
<<"signal">> => Signal
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
@ -140,10 +144,10 @@ ok
|
|||||||
|
|
||||||
```erlang
|
```erlang
|
||||||
#{
|
#{
|
||||||
action => remove,
|
<<"action">> => <<"remove">>,
|
||||||
target => Target,
|
<<"target">> => Target,
|
||||||
force => Force,
|
<<"force">> => Force,
|
||||||
remove_volumes => RemoveVolumes
|
<<"remove_volumes">> => RemoveVolumes
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
@ -151,9 +155,9 @@ ok
|
|||||||
|
|
||||||
```erlang
|
```erlang
|
||||||
#{
|
#{
|
||||||
action => config,
|
<<"action">> => <<"config">>,
|
||||||
target => Target,
|
<<"target">> => Target,
|
||||||
config => Config
|
<<"config">> => Config
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
@ -165,8 +169,8 @@ ok
|
|||||||
|
|
||||||
```erlang
|
```erlang
|
||||||
#{
|
#{
|
||||||
name => ContainerName,
|
<<"name">> => ContainerName,
|
||||||
id => ContainerId
|
<<"id">> => ContainerId
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
@ -179,9 +183,9 @@ ok
|
|||||||
### efka -> iot: data
|
### efka -> iot: data
|
||||||
|
|
||||||
```erlang
|
```erlang
|
||||||
{message, {data, #{
|
{<<"message">>, {<<"data">>, #{
|
||||||
route_key => RouteKey,
|
<<"route_key">> => RouteKey,
|
||||||
metric => Metric
|
<<"metric">> => Metric
|
||||||
}}}
|
}}}
|
||||||
```
|
```
|
||||||
|
|
||||||
@ -190,20 +194,20 @@ ok
|
|||||||
### efka -> iot: task_event
|
### efka -> iot: task_event
|
||||||
|
|
||||||
```erlang
|
```erlang
|
||||||
{message, {task_event, #{
|
{<<"message">>, {<<"task_event">>, #{
|
||||||
task_id => TaskId,
|
<<"task_id">> => TaskId,
|
||||||
type => Type,
|
<<"type">> => Type,
|
||||||
stream => Stream
|
<<"stream">> => Stream
|
||||||
}}}
|
}}}
|
||||||
```
|
```
|
||||||
|
|
||||||
任务事件流关闭时:
|
任务事件流关闭时:
|
||||||
|
|
||||||
```erlang
|
```erlang
|
||||||
{message, {task_event, #{
|
{<<"message">>, {<<"task_event">>, #{
|
||||||
task_id => TaskId,
|
<<"task_id">> => TaskId,
|
||||||
type => <<"close">>,
|
<<"type">> => <<"close">>,
|
||||||
stream => Reason
|
<<"stream">> => Reason
|
||||||
}}}
|
}}}
|
||||||
```
|
```
|
||||||
|
|
||||||
@ -218,10 +222,10 @@ GET /event_stream?uuid=<host_uuid>&task_id=<task_id>
|
|||||||
### iot -> efka: pub
|
### iot -> efka: pub
|
||||||
|
|
||||||
```erlang
|
```erlang
|
||||||
{message, {pub, #{
|
{<<"message">>, {<<"pub">>, #{
|
||||||
topic => Topic,
|
<<"topic">> => Topic,
|
||||||
qos => Qos,
|
<<"qos">> => Qos,
|
||||||
content => Content
|
<<"content">> => Content
|
||||||
}}}
|
}}}
|
||||||
```
|
```
|
||||||
|
|
||||||
@ -248,5 +252,6 @@ GET /event_stream?uuid=<host_uuid>&task_id=<task_id>
|
|||||||
- 旧容器回复:`{response, Ref, {container_response, ...}}`
|
- 旧容器回复:`{response, Ref, {container_response, ...}}`
|
||||||
- 旧授权控制:`{message, {auth_control, Command}}`
|
- 旧授权控制:`{message, {auth_control, Command}}`
|
||||||
- 已移除的 auth command:`{command, Ref, {auth, activate | deactivate}}`
|
- 已移除的 auth command:`{command, Ref, {auth, activate | deactivate}}`
|
||||||
|
- 旧 Ref:Erlang `reference()`,例如 `make_ref()` 生成的值。
|
||||||
|
|
||||||
如果需要滚动升级,应先增加临时兼容分支或引入协议版本协商。
|
如果需要滚动升级,应先增加临时兼容分支或引入协议版本协商。
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user