Files
MoShiro/web/admin/src/pages/JoinTokenCreated.tsx
T
justme 12be44645f
ci/woodpecker/push/main-amd64-build Pipeline was successful
feat: install nodes and the backend from a static compose file; remove dead code [CI]
Agent, Probe and Backend now start from one static compose.yaml plus a local
.env: the panel (or the release assets, for the very first Backend) provides
the file, the panel's command writes the public values into .env, checks the
file's SHA-256 and runs compose up. Updating is compose pull && compose up -d.
The image is chosen by the CI channel (:latest, or MOSHIRO_VERSION in .env),
not by the panel; the previous one-line script stays as a fallback.

- packaging/compose/{agent,probe,backend}/compose.yaml are the single source,
  embedded in the Backend and served at /install/compose/{file}; the root
  compose.yaml moved there. Releases also carry them and list them in the
  signed SHA256SUMS.
- The container entrypoint defaults the node name to the host name.
- Join token creation returns a compose block (.env, url, hash, per-platform
  commands); the admin dialog leads with it.
- Remove code with no references (HotLayer members, LiveHub.SubscriberCount,
  QueryService.ParseParams, ReleaseService.Forget, a few constants) and reduce
  the install-code lookup to the role it is for.
2026-10-08 20:24:23 +08:00

81 lines
4.5 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import type { CreatedJoinTokenDto } from '@shared/api/types'
import { fmtTime } from '@shared/format'
import { CommandTabs, CopyButton, Dialog, Field, guessPlatform, type CommandTab } from '@shared/ui'
/**
* 加入令牌创建之后的对话框:Agent 和 Probe 共用同一份。
* 首选 compose:把面板给的 .env 存下来,下载 compose.yaml,`compose up -d`,以后更新就是 `compose pull && compose up -d`。
* .env 里只有公开的值(面板地址、一次性码、信任根指纹和属主),没有任何私钥;脚本一行命令留作备用。
*/
export function JoinTokenCreated({ created, kind, onClose }: { created: CreatedJoinTokenDto; kind: 'Agent' | 'Probe'; onClose: () => void }) {
const compose = created.compose
const script = created.install_commands
const composeTabs: CommandTab[] = [
{ id: 'linux', label: 'Linux · Podman', command: compose.linux },
...(compose.macos ? [{ id: 'macos', label: 'macOS · Docker', command: compose.macos }] : []),
...(compose.windows ? [{ id: 'windows', label: 'Windows · Docker', command: compose.windows }] : []),
]
const initial = composeTabs.some((t) => t.id === guessPlatform()) ? guessPlatform() : 'linux'
return (
<Dialog
title="加入令牌已创建"
onClose={onClose}
actions={
<button type="button" className="btn primary" onClick={onClose}>
完成
</button>
}
>
<div className="stack">
<div className="notice warn">一次性码只显示这一次,请现在就复制。下面只有公开的值(面板地址、一次性码、信任根指纹和属主),没有任何私钥。</div>
<Field
label={`容器安装(推荐):在要加入的机器上运行(${kind})`}
hint="需要 podman compose 或 docker compose。命令建一个目录,把参数写进 .env(权限 600),下载 compose.yaml 并核对 SHA-256,一致才启动。节点名字默认取主机名,想自己定就改 .env 里的 MOSHIRO_NAME。"
>
<CommandTabs storageKey="moshiro.compose_tab" initial={initial} tabs={composeTabs} />
</Field>
<details>
<summary>分步做:.env 内容、compose 下载地址和哈希</summary>
<div className="stack" style={{ marginTop: 8 }}>
<Field label=".env(存成当前目录下的 .env)">
<div className="row" style={{ alignItems: 'flex-start', gap: 8 }}>
<pre className="code" style={{ flex: 1, whiteSpace: 'pre-wrap', wordBreak: 'break-all', margin: 0 }}>{compose.env}</pre>
<CopyButton text={compose.env} />
</div>
</Field>
<Field label="compose.yaml">
<div className="stack">
<div className="row" style={{ gap: 8 }}>
<span className="mono" style={{ wordBreak: 'break-all' }}>{compose.url}</span>
<CopyButton text={compose.url} />
</div>
<div className="muted mono" style={{ wordBreak: 'break-all' }}>SHA-256 {compose.sha256}</div>
</div>
</Field>
</div>
</details>
<p className="muted">
以后更新:<span className="mono">podman compose pull &amp;&amp; podman compose up -d</span>(Docker 把 podman 换成 docker);身份和配置在命名卷里,不会动。
想固定版本,在 .env 里写 <span className="mono">MOSHIRO_VERSION=版本号</span>。注册成功之后,可以把 .env 里的 <span className="mono">MOSHIRO_JOIN</span> 一行删掉。
{kind === 'Agent' ? (created.token.auto_approve ? ' 使用它注册的 Agent 会自动启用。' : ' 使用它注册的 Agent 需要你在列表里审批之后才会启用。') : ''}
可用 {created.token.max_uses} 次,{fmtTime(created.token.expires_at)} 过期。
</p>
<details>
<summary>备用:一行安装脚本(先核对脚本哈希再执行,需要 Docker 或 Podman)</summary>
<div style={{ marginTop: 8 }}>
<CommandTabs
storageKey="moshiro.install_tab"
initial={guessPlatform()}
tabs={[
{ id: 'linux', label: 'Linux · 脚本', command: script.linux },
{ id: 'macos', label: 'macOS · 脚本', command: script.macos },
{ id: 'windows', label: 'Windows · 脚本', command: script.windows },
]}
/>
</div>
</details>
</div>
</Dialog>
)
}