@exagone313/dsh-podman 0.2.0-rc.4 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +12 -0
- package/README.zh.md +14 -2
- package/cordis.patch.yml +58 -0
- package/dist/approval-reasons.d.ts +3 -4
- package/dist/approval-reasons.js +40 -49
- package/dist/approval-reasons.test.js +43 -15
- package/dist/approval.js +27 -10
- package/dist/approval.test.js +165 -34
- package/dist/card-route.d.ts +3 -2
- package/dist/card-route.js +103 -35
- package/dist/card-route.test.js +60 -43
- package/dist/card-test-support.js +39 -66
- package/dist/client/ContainerCard.d.ts +1 -1
- package/dist/client/ContainerCard.js +76 -70
- package/dist/client/card-protocol.d.ts +3 -3
- package/dist/client/container-card-caches.js +11 -6
- package/dist/client/container-card-controller.d.ts +13 -18
- package/dist/client/container-card-controller.js +86 -40
- package/dist/client/container-card-create-modal.d.ts +2 -2
- package/dist/client/container-card-create-modal.js +13 -5
- package/dist/client/container-card-default-env.d.ts +10 -0
- package/dist/client/container-card-default-env.js +69 -0
- package/dist/client/container-card-directory.d.ts +2 -2
- package/dist/client/container-card-directory.js +12 -4
- package/dist/client/container-card-editors.d.ts +3 -3
- package/dist/client/container-card-editors.js +104 -32
- package/dist/client/container-card-images.d.ts +4 -4
- package/dist/client/container-card-images.js +19 -6
- package/dist/client/container-card-paths.d.ts +3 -3
- package/dist/client/container-card-paths.js +18 -11
- package/dist/client/container-card-row.d.ts +10 -6
- package/dist/client/container-card-row.js +82 -13
- package/dist/client/container-card-secrets.d.ts +3 -3
- package/dist/client/container-card-secrets.js +8 -6
- package/dist/client/container-card-shared.d.ts +4 -17
- package/dist/client/container-card-shared.js +9 -25
- package/dist/client/container-card-styles.d.ts +2 -8
- package/dist/client/container-card-styles.js +14 -52
- package/dist/client/container-card-volumes.d.ts +2 -2
- package/dist/client/container-card-volumes.js +9 -5
- package/dist/client/container-card-workspace.d.ts +8 -6
- package/dist/client/container-card-workspace.js +9 -3
- package/dist/client/directory-picker.js +2 -1
- package/dist/client/index.js +13109 -2117
- package/dist/client/locales.d.ts +6 -1
- package/dist/client/locales.js +88 -38
- package/dist/client/podman-terminal-guide.d.ts +11 -0
- package/dist/client/podman-terminal-guide.js +208 -0
- package/dist/client/podman-terminal-title.d.ts +7 -0
- package/dist/client/podman-terminal-title.js +30 -0
- package/dist/client/podman-terminal.d.ts +26 -0
- package/dist/client/podman-terminal.js +412 -0
- package/dist/client/read-only-approval.d.ts +2 -2
- package/dist/client/read-only-approval.js +13 -3
- package/dist/client/slot-contract.d.ts +0 -11
- package/dist/client/terminal-preference.d.ts +26 -0
- package/dist/client/terminal-preference.js +67 -0
- package/dist/client/terminal-protocol.d.ts +85 -0
- package/dist/client/terminal-protocol.js +14 -0
- package/dist/client/terminal-tab.d.ts +60 -0
- package/dist/client/terminal-tab.js +35 -0
- package/dist/client/terminal-targets.d.ts +33 -0
- package/dist/client/terminal-targets.js +65 -0
- package/dist/client/terminal-titles.d.ts +23 -0
- package/dist/client/terminal-titles.js +52 -0
- package/dist/client/terminal-transport.d.ts +63 -0
- package/dist/client/terminal-transport.js +207 -0
- package/dist/client/tool-views.js +215 -49
- package/dist/container-env.d.ts +11 -0
- package/dist/container-env.js +96 -0
- package/dist/container-env.test.d.ts +1 -0
- package/dist/container-env.test.js +93 -0
- package/dist/containers.test.js +196 -18
- package/dist/daemons.test.js +18 -4
- package/dist/dsh-version.js +2 -1
- package/dist/env-rows.d.ts +14 -0
- package/dist/env-rows.js +52 -0
- package/dist/env-rows.test.d.ts +1 -0
- package/dist/env-rows.test.js +43 -0
- package/dist/fs-provider.d.ts +1 -0
- package/dist/fs-provider.js +26 -12
- package/dist/fs-provider.test.js +51 -10
- package/dist/generated/version.d.ts +2 -2
- package/dist/generated/version.js +2 -2
- package/dist/grpc/proto/dshctl/v1/control.proto +8 -1
- package/dist/grpc/proto/dshguest/v1/guest.proto +5 -0
- package/dist/grpc/runtime-client.d.ts +3 -1
- package/dist/grpc/runtime-client.js +90 -17
- package/dist/guest-rpc.d.ts +15 -19
- package/dist/guest-rpc.js +289 -70
- package/dist/guest-rpc.test.d.ts +1 -0
- package/dist/guest-rpc.test.js +241 -0
- package/dist/guest-terminal.d.ts +30 -0
- package/dist/guest-terminal.js +196 -0
- package/dist/images.test.js +10 -3
- package/dist/index.d.ts +11 -16
- package/dist/index.js +42 -36
- package/dist/locales.test.d.ts +1 -0
- package/dist/locales.test.js +34 -0
- package/dist/misc.test.js +38 -10
- package/dist/mount-enums.js +2 -1
- package/dist/mount-input.d.ts +2 -0
- package/dist/mount-input.js +38 -22
- package/dist/mounts.test.js +81 -11
- package/dist/naming.test.d.ts +1 -0
- package/dist/naming.test.js +28 -0
- package/dist/output-reader.js +36 -4
- package/dist/package-deps.test.d.ts +1 -0
- package/dist/package-deps.test.js +49 -0
- package/dist/paths.test.js +4 -2
- package/dist/plugin-meta.test.d.ts +1 -0
- package/dist/plugin-meta.test.js +29 -0
- package/dist/project-path.js +33 -7
- package/dist/project-path.test.js +14 -0
- package/dist/prompts.d.ts +0 -4
- package/dist/prompts.js +15 -84
- package/dist/read-only-shell.js +3 -1
- package/dist/read-only-shell.test.js +80 -25
- package/dist/runtime-client.test.d.ts +1 -0
- package/dist/runtime-client.test.js +53 -0
- package/dist/secrets.test.js +21 -6
- package/dist/settings-commands.test.js +61 -14
- package/dist/settings-create.test.js +32 -10
- package/dist/settings-default-env.test.d.ts +1 -0
- package/dist/settings-default-env.test.js +175 -0
- package/dist/settings-mounts.test.js +46 -7
- package/dist/settings-schema.d.ts +6 -11
- package/dist/settings-schema.js +4 -8
- package/dist/settings-schema.test.d.ts +1 -0
- package/dist/settings-schema.test.js +35 -0
- package/dist/settings-workspaces.test.js +36 -63
- package/dist/spill-store.d.ts +1 -0
- package/dist/spill-store.js +17 -4
- package/dist/spill-store.test.js +31 -8
- package/dist/subprocess.d.ts +4 -0
- package/dist/subprocess.js +148 -162
- package/dist/subprocess.test.js +118 -8
- package/dist/terminal-preference.test.d.ts +1 -0
- package/dist/terminal-preference.test.js +62 -0
- package/dist/terminal-route.d.ts +10 -0
- package/dist/terminal-route.js +270 -0
- package/dist/terminal-route.test.d.ts +1 -0
- package/dist/terminal-route.test.js +265 -0
- package/dist/terminal-sessions.d.ts +69 -0
- package/dist/terminal-sessions.js +252 -0
- package/dist/terminal-shells.d.ts +22 -0
- package/dist/terminal-shells.js +99 -0
- package/dist/terminal-tab.test.d.ts +1 -0
- package/dist/terminal-tab.test.js +58 -0
- package/dist/terminal-targets.test.d.ts +1 -0
- package/dist/terminal-targets.test.js +43 -0
- package/dist/terminal-titles.test.d.ts +1 -0
- package/dist/terminal-titles.test.js +36 -0
- package/dist/test-support.d.ts +35 -5
- package/dist/test-support.js +91 -29
- package/dist/tool-defs.js +19 -4
- package/dist/tool-handlers.js +80 -28
- package/dist/tool-params.js +19 -5
- package/dist/volumes.test.js +1 -1
- package/dist/workspace-binding.d.ts +18 -9
- package/dist/workspace-binding.js +244 -77
- package/dist/workspace-binding.test.js +189 -25
- package/docs/architecture.md +62 -21
- package/docs/architecture.zh.md +57 -13
- package/docs/configuration.md +61 -20
- package/docs/configuration.zh.md +53 -19
- package/docs/development-prompt.md +72 -0
- package/docs/development-prompt.zh.md +69 -0
- package/docs/development.md +141 -21
- package/docs/development.zh.md +125 -17
- package/docs/install-dsh-and-dsh-podman.md +21 -8
- package/docs/install-dsh-and-dsh-podman.zh.md +18 -8
- package/docs/uninstall.md +83 -0
- package/docs/uninstall.zh.md +79 -0
- package/docs/update.md +120 -0
- package/docs/update.zh.md +114 -0
- package/docs/usage.md +108 -61
- package/docs/usage.zh.md +76 -38
- package/locale/en.json +6 -0
- package/locale/zh.json +6 -0
- package/package.json +58 -25
- package/quadlet/dsh-podman-orchestrator.container +46 -0
- package/quadlet/dsh.container +35 -0
- package/LICENSE.pkg +0 -17103
- package/dist/preferences.d.ts +0 -6
- package/dist/preferences.js +0 -27
package/docs/development.zh.md
CHANGED
|
@@ -19,7 +19,8 @@ SPDX-License-Identifier: MIT
|
|
|
19
19
|
|
|
20
20
|
## 构建
|
|
21
21
|
|
|
22
|
-
前置要求:Go 1.27、Node ≥ 22、pnpm 12
|
|
22
|
+
前置要求:Go 1.27、Node ≥ 22、pnpm 12、Deno ≥
|
|
23
|
+
2.9(用于格式化),以及(浏览器端所需的)发布在 npm 上的
|
|
23
24
|
`@deepseek-ai/dsh-client-*` 包。
|
|
24
25
|
|
|
25
26
|
```sh
|
|
@@ -35,19 +36,22 @@ Go 构建标签会跳过 btrfs 和 devicemapper 存储驱动,它们需要宿
|
|
|
35
36
|
```sh
|
|
36
37
|
make build-go # build both Go binaries into bin/<os>-<arch>/
|
|
37
38
|
make build # build-go + pnpm-build
|
|
38
|
-
make vet # go vet with the build tags
|
|
39
|
+
make vet # gofmt -s check + go vet with the build tags
|
|
39
40
|
make test-go # go test with the build tags
|
|
40
41
|
make test # test-go + pnpm test (JS tests, which run against dist/)
|
|
41
|
-
make
|
|
42
|
-
make
|
|
42
|
+
make fmt # gofmt -s + deno fmt (TypeScript and Markdown)
|
|
43
|
+
make fmt-check # verify the formatting without rewriting anything
|
|
44
|
+
make download-licenses # generate third-party-licenses.pkg from the project and third-party Go licenses
|
|
45
|
+
make image # build the orchestrator, guest-agent and dsh container images
|
|
43
46
|
```
|
|
44
47
|
|
|
45
|
-
`make image` 依赖 `
|
|
48
|
+
`make image` 依赖 `third-party-licenses.pkg`:`download-licenses` 目标会运行
|
|
46
49
|
`scripts/download-licenses` 中的 Go 收集器,它调用 `go-licenses save` 并将项目的
|
|
47
|
-
MIT 许可证以及所有第三方 Go 许可证和 Apache `NOTICE` 汇总到
|
|
48
|
-
中。该文件被 gitignore (从不提交),并被烘焙进
|
|
49
|
-
|
|
50
|
-
guest-agent
|
|
50
|
+
MIT 许可证以及所有第三方 Go 许可证和 Apache `NOTICE` 汇总到
|
|
51
|
+
`third-party-licenses.pkg` 中。该文件被 gitignore (从不提交),并被烘焙进
|
|
52
|
+
orchestrator 和 guest-agent 镜像,位于
|
|
53
|
+
`/usr/share/licenses/dsh-podman/LICENSE`;由于工作区容器会挂载 guest-agent
|
|
54
|
+
镜像,因此它也会随之进入每个工作区容器。
|
|
51
55
|
|
|
52
56
|
`pnpm test` 运行 `node --test dist/*.test.js`,因此它要求先运行 `pnpm build`
|
|
53
57
|
(`test` 目标会处理这一点)。
|
|
@@ -64,6 +68,17 @@ JS 端在运行时通过 `@grpc/proto-loader` 加载原始 `.proto` 文件(构
|
|
|
64
68
|
`dist/grpc/proto/`);不生成 TypeScript 绑定。也可以使用 `buf lint` 和
|
|
65
69
|
`buf breaking` 校验 schema。
|
|
66
70
|
|
|
71
|
+
## 命名
|
|
72
|
+
|
|
73
|
+
`.proto` 字段名为 `lower_snake_case`(Buf 的 `BASIC` lint 会强制检查),JS
|
|
74
|
+
端通过 proto-loader 的 camelCase 投影读取,因此 `secret_env` 变为
|
|
75
|
+
`secretEnv`、`image_id` 变为 `imageId`。切勿在 TypeScript 中使用下划线形式的
|
|
76
|
+
proto 字段名:proto-loader 会忽略未知属性,该值会被静默丢弃。
|
|
77
|
+
|
|
78
|
+
工具参数使用 camelCase,只有刻意与 harness
|
|
79
|
+
内置工具保持一致的名字除外(`file_path`、`old_string`、`new_string`、`replace_all`)。设置项使用
|
|
80
|
+
camelCase;持久化的 TOML 状态使用下划线标签。
|
|
81
|
+
|
|
67
82
|
## 安装开发构建
|
|
68
83
|
|
|
69
84
|
### 构建
|
|
@@ -73,16 +88,109 @@ make # builds plugin and go binaries
|
|
|
73
88
|
make image # build images
|
|
74
89
|
```
|
|
75
90
|
|
|
76
|
-
###
|
|
91
|
+
### 运行本地镜像(Quadlet)
|
|
92
|
+
|
|
93
|
+
随附的单元会拉取发布镜像。把它们指向 `make image`
|
|
94
|
+
构建的镜像,就能把本地构建当作正式服务来运行;把原来的行注释掉,切回时只需改一行。
|
|
95
|
+
|
|
96
|
+
在 `~/.config/containers/systemd/dsh.container` 中:
|
|
97
|
+
|
|
98
|
+
```ini
|
|
99
|
+
#Image=ghcr.io/exagone313/dsh-podman/dsh:1
|
|
100
|
+
Image=localhost/dsh-podman-dsh:latest
|
|
101
|
+
Environment=DSH_PODMAN_PLUGIN_SOURCE=%h/project/dsh-podman
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
该单元已经把 `%h/project` 以只读方式挂载,因此检出在 `~/project`
|
|
105
|
+
下的仓库无需额外的 `Volume=`。`npm pack` 会把入口脚本要安装的归档放在
|
|
106
|
+
`package.json` 旁边(见[安装本地插件构建](#安装本地插件构建))。
|
|
107
|
+
|
|
108
|
+
在 `~/.config/containers/systemd/dsh-podman-orchestrator.container` 中:
|
|
109
|
+
|
|
110
|
+
```ini
|
|
111
|
+
#Image=ghcr.io/exagone313/dsh-podman/orchestrator:1
|
|
112
|
+
Image=localhost/dsh-podman-orchestrator:latest
|
|
113
|
+
#Environment=DSH_PODMAN_GUEST_AGENT_IMAGE=ghcr.io/exagone313/dsh-podman/guest-agent
|
|
114
|
+
#Environment=DSH_PODMAN_GUEST_AGENT_IMAGE_USE_VERSION_TAG=true
|
|
115
|
+
Environment=DSH_PODMAN_GUEST_AGENT_IMAGE=localhost/dsh-podman-guest-agent:latest
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
发布引用带有版本标签,因此每个发布版本都有各自不同的镜像引用。本地构建则复用同一个
|
|
119
|
+
`:latest` 标签;orchestrator 因此无法察觉 guest agent
|
|
120
|
+
已被重建,详见[更新工作区容器](#更新工作区容器)。
|
|
121
|
+
|
|
122
|
+
编辑单元后重新加载 systemd:
|
|
77
123
|
|
|
78
124
|
```bash
|
|
125
|
+
systemctl --user daemon-reload
|
|
126
|
+
```
|
|
127
|
+
|
|
128
|
+
### 部署改动
|
|
129
|
+
|
|
130
|
+
```bash
|
|
131
|
+
make # Go binaries + the plugin bundle
|
|
132
|
+
make image # orchestrator, guest-agent and dsh images
|
|
133
|
+
npm pack # the plugin archive the dsh entrypoint installs
|
|
79
134
|
systemctl --user restart dsh dsh-podman-orchestrator
|
|
80
135
|
```
|
|
81
136
|
|
|
137
|
+
dsh 镜像会在容器启动时安装插件,因此重启 dsh 才会重新安装刚打包的归档;重启
|
|
138
|
+
orchestrator 则会采用新的 orchestrator 与 guest-agent 镜像。
|
|
139
|
+
|
|
140
|
+
### 更新工作区容器
|
|
141
|
+
|
|
142
|
+
guest-agent 镜像会在容器创建时挂载进去,因此正在运行的容器仍使用它启动时的那份
|
|
143
|
+
agent。只有当容器的 guest-agent 镜像引用与当前配置不一致时,orchestrator
|
|
144
|
+
才会自行重建该容器——带版本标签的发布引用会如此,本地 `:latest` 标签则不会。重建
|
|
145
|
+
guest agent 之后,请自行重建容器:
|
|
146
|
+
|
|
147
|
+
- 在 Podman 页面(侧边栏 **插件** 面板 → **已安装** →
|
|
148
|
+
**dsh-podman**)中按容器操作:**Recreate**(沿用当前镜像)或 **Recreate with
|
|
149
|
+
image**;
|
|
150
|
+
- 或使用 `container_recreate`,作用于命名容器或默认容器。
|
|
151
|
+
|
|
152
|
+
若要重建整个工作区,可在其行上使用 **Remove pod**(或 `RemoveWorkspace`):pod
|
|
153
|
+
及其所有容器都会被移除,下次接入时会重新创建 pod
|
|
154
|
+
与默认容器。重启这两个服务绝不会触及工作区容器,上述两种操作也都不会删除卷、机密或项目数据。
|
|
155
|
+
|
|
156
|
+
仍在运行旧镜像中 guest agent 的容器会让 dsh 为其 guest 套接字记录
|
|
157
|
+
`rejected by server because of excess pings`。该消息无害(grpc-js
|
|
158
|
+
会退避并重连),重建该容器后即消失;若同样的消息出现在 `orchestrator.sock`
|
|
159
|
+
上,则说明 orchestrator 服务仍在运行上一个镜像。
|
|
160
|
+
|
|
161
|
+
### 开发容器工具链
|
|
162
|
+
|
|
163
|
+
工作区容器的根文件系统是只读且一次性的,因此贡献者构建所用的工具链需要工作区的一个卷。项目并不分发开发镜像:请自行构建一个自定义镜像——[设置提示词](development-prompt.zh.md)
|
|
164
|
+
会以 `archlinux` 为父镜像构建 `dsh-podman-tooling`,包含
|
|
165
|
+
`go`、`nodejs-lts-jod`、`npm`、`deno`、`reuse` 和
|
|
166
|
+
`python-chardet`——并为镜像无法保存的状态创建工作区卷:Go 与 npm 缓存、含
|
|
167
|
+
`go install` 工具的 `gopath`, 以及 `package.json` 固定版本、Arch 仓库没有的
|
|
168
|
+
pnpm。
|
|
169
|
+
|
|
170
|
+
提示词会把该卷以 `dsh-podman-toolchain` 挂载到
|
|
171
|
+
`/opt/toolchain`(读写),并让容器的缓存都指向它,因此无需 source
|
|
172
|
+
任何脚本即可使用:
|
|
173
|
+
|
|
174
|
+
| 容器设置 | 值 |
|
|
175
|
+
| ----------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
176
|
+
| PATH 追加项 | `/opt/toolchain/gopath/bin`、`/opt/toolchain/npm-global/bin`、`/opt/toolchain/pnpm-home` |
|
|
177
|
+
| 环境变量 | `GOCACHE=/opt/toolchain/gocache`、`GOMODCACHE=/opt/toolchain/gomodcache`、`GOPATH=/opt/toolchain/gopath`、`npm_config_cache=/opt/toolchain/npm-cache`、`npm_config_prefix=/opt/toolchain/npm-global`、`PNPM_HOME=/opt/toolchain/pnpm-home`、`DENO_DIR=/opt/toolchain/deno-dir`、`GOENV=/opt/toolchain/home/.config/go/env` |
|
|
178
|
+
|
|
179
|
+
在 Podman 页面(侧边栏 **插件** 面板 → **已安装** →
|
|
180
|
+
**dsh-podman**)的[默认环境变量](configuration.zh.md#默认环境变量) → **Git
|
|
181
|
+
身份** 中设置一次提交身份,容器便无需 `~/.gitconfig` 即可获得
|
|
182
|
+
`GIT_AUTHOR_*`/`GIT_COMMITTER_*`。
|
|
183
|
+
|
|
184
|
+
提示词会在 dsh 内完成上述全部配置,并且可以反复粘贴以修复工作区。Podman
|
|
185
|
+
存储受管卷时会加上 `DSH_PODMAN_VOLUME_PREFIX` 前缀,因此该卷显示为
|
|
186
|
+
`dsh-podman-dsh-podman-toolchain`。
|
|
187
|
+
|
|
82
188
|
### 安装本地插件构建
|
|
83
189
|
|
|
84
190
|
dsh 镜像会在容器启动时自行安装插件,因此本地开发构建通过将安装源指向 bind mount
|
|
85
|
-
|
|
191
|
+
的包来使用。上面的 Quadlet 配置就是下面第一种形式,仓库目录本身
|
|
192
|
+
(`%h/project/dsh-podman`)已经通过单元的只读 `%h/project`
|
|
193
|
+
挂载可见。先构建并打包插件:
|
|
86
194
|
|
|
87
195
|
```bash
|
|
88
196
|
pnpm build
|
|
@@ -99,7 +207,7 @@ Environment=DSH_PODMAN_PLUGIN_SOURCE=/mnt/dsh-podman
|
|
|
99
207
|
|
|
100
208
|
```
|
|
101
209
|
# 或者归档本身
|
|
102
|
-
Volume=/path/to/exagone313-dsh-podman-
|
|
210
|
+
Volume=/path/to/exagone313-dsh-podman-x.y.z.tgz:/mnt/dsh-podman.tgz:ro
|
|
103
211
|
Environment=DSH_PODMAN_PLUGIN_SOURCE=/mnt/dsh-podman.tgz
|
|
104
212
|
```
|
|
105
213
|
|
|
@@ -119,10 +227,10 @@ zizmor)、`ci-code.yml`(Go、JS、镜像、Trivy)、`ci-docs.yml`(Deno f
|
|
|
119
227
|
|
|
120
228
|
- **actions-lint** — zizmor 扫描工作流是否存在不安全实践。
|
|
121
229
|
- **reuse** — REUSE 许可证合规检查。
|
|
122
|
-
- **go** —
|
|
230
|
+
- **go** — 构建、`gofmt -s` 检查、vet、测试和 govulncheck(Go 漏洞)。未修复的
|
|
123
231
|
发现不会导致任务失败;可修复的会导致失败。
|
|
124
|
-
- **js** —
|
|
125
|
-
- **docs** —
|
|
232
|
+
- **js** — TypeScript 格式检查、安装、类型检查、构建、测试和 `pnpm audit`。
|
|
233
|
+
- **docs** — Markdown 格式检查(通过 `make fmt-check-md` 运行 `deno fmt`)。
|
|
126
234
|
- **images** — 构建 orchestrator 和 guest-agent
|
|
127
235
|
镜像(仅在测试任务通过后运行);**dsh image** 构建 `Containerfile.dsh`。
|
|
128
236
|
- **trivy** — 文件系统漏洞扫描(未修复的被忽略)和容器 错误配置扫描(DS-0002
|
|
@@ -148,8 +256,8 @@ zizmor)、`ci-code.yml`(Go、JS、镜像、Trivy)、`ci-docs.yml`(Deno f
|
|
|
148
256
|
中的版本一致——否则工作流会失败——因此请用版本脚本同时更新两者:
|
|
149
257
|
|
|
150
258
|
```sh
|
|
151
|
-
pnpm bump-version
|
|
152
|
-
git push origin master
|
|
259
|
+
pnpm bump-version x.y.z # 加上 --dry-run 则仅校验
|
|
260
|
+
git push origin master x.y.z
|
|
153
261
|
```
|
|
154
262
|
|
|
155
263
|
`scripts/bump-version.mjs` 会检查版本是否为递增的 Semver
|
|
@@ -10,11 +10,14 @@ SPDX-License-Identifier: MIT
|
|
|
10
10
|
|
|
11
11
|
The goal of this guide is to install:
|
|
12
12
|
|
|
13
|
-
- [DeepSeek Harness](https://deepseek.com/harness), referred to later as _dsh_
|
|
13
|
+
- [DeepSeek Harness](https://deepseek.com/harness), referred to later as _dsh_,
|
|
14
|
+
in its own Podman container
|
|
14
15
|
- the dsh-podman plugin in dsh, which replaces host filesystem and shell access
|
|
15
16
|
- the dsh-podman orchestrator, a separate Podman container that integrates with
|
|
16
17
|
Podman
|
|
17
18
|
|
|
19
|
+
Note that if there is existing installation data at `~/.dsh`, it will be reused.
|
|
20
|
+
|
|
18
21
|
Having the dsh plugin and the orchestrator running as separate containers is an
|
|
19
22
|
important part of the security design of dsh-podman: dsh itself doesn't have
|
|
20
23
|
direct access to Podman, only the orchestrator does, with limitations. dsh
|
|
@@ -109,6 +112,9 @@ which requires online access.
|
|
|
109
112
|
2. Copy the files [dsh.container](../quadlet/dsh.container) and
|
|
110
113
|
[dsh-podman-orchestrator.container](../quadlet/dsh-podman-orchestrator.container)
|
|
111
114
|
to `~/.config/containers/systemd/`.
|
|
115
|
+
```bash
|
|
116
|
+
cp quadlet/* ~/.config/containers/systemd/
|
|
117
|
+
```
|
|
112
118
|
- Adapt the files to your desired project directory if you wish to change it.
|
|
113
119
|
3. Reload systemd session configuration:
|
|
114
120
|
```bash
|
|
@@ -140,16 +146,23 @@ which requires online access.
|
|
|
140
146
|
|
|
141
147
|
## Verification
|
|
142
148
|
|
|
143
|
-
- Open **
|
|
144
|
-
and, for a workspace, offer to create its
|
|
149
|
+
- Open the sidebar's **Plugins** panel → **Installed** → **dsh-podman**: the
|
|
150
|
+
page should list the base images and, for a workspace, offer to create its
|
|
151
|
+
default container.
|
|
145
152
|
- In a dsh session, run a shell command. It should execute inside a Podman
|
|
146
153
|
container for the current workspace (the plugin auto-creates the workspace's
|
|
147
154
|
default container on first use).
|
|
148
155
|
|
|
149
|
-
##
|
|
156
|
+
## Set Git identity (recommended)
|
|
157
|
+
|
|
158
|
+
- Open settings from the sidebar's **Plugins** panel → **Installed** →
|
|
159
|
+
**dsh-podman**
|
|
160
|
+
- Scroll down to **Default environment**
|
|
161
|
+
- Click on **Git identity**
|
|
162
|
+
- Enter the name and email to use for Git and click on **Apply**
|
|
163
|
+
- Click on **Apply default environment variables** and then **Confirm**
|
|
150
164
|
|
|
151
|
-
|
|
165
|
+
## Updating dsh & dsh-podman
|
|
152
166
|
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
```
|
|
167
|
+
Read the [update documentation](./update.md) to know how to manually update or
|
|
168
|
+
set up auto-updates.
|
|
@@ -10,10 +10,13 @@ SPDX-License-Identifier: MIT
|
|
|
10
10
|
|
|
11
11
|
本指南的目标是安装:
|
|
12
12
|
|
|
13
|
-
- [DeepSeek Harness](https://deepseek.com/harness),下文简称 _dsh_
|
|
13
|
+
- [DeepSeek Harness](https://deepseek.com/harness),下文简称 _dsh_,在它自己的
|
|
14
|
+
Podman 容器中运行
|
|
14
15
|
- dsh 中的 dsh-podman 插件,它取代了宿主的文件系统和 shell 访问
|
|
15
16
|
- dsh-podman 编排器,一个与 Podman 集成的独立 Podman 容器
|
|
16
17
|
|
|
18
|
+
请注意,如果 `~/.dsh` 中已有安装数据,它将被复用。
|
|
19
|
+
|
|
17
20
|
将 dsh 插件和编排器作为独立的容器运行,是 dsh-podman 安全设计的重要一环: dsh
|
|
18
21
|
本身不能直接访问 Podman,只有编排器可以,并且受到限制。dsh
|
|
19
22
|
不应能通过这条路径提权,因为提供给 dsh 的权限能力是受限的:
|
|
@@ -90,6 +93,9 @@ SPDX-License-Identifier: MIT
|
|
|
90
93
|
2. 将文件 [dsh.container](../quadlet/dsh.container) 和
|
|
91
94
|
[dsh-podman-orchestrator.container](../quadlet/dsh-podman-orchestrator.container)
|
|
92
95
|
复制到 `~/.config/containers/systemd/`。
|
|
96
|
+
```bash
|
|
97
|
+
cp quadlet/* ~/.config/containers/systemd/
|
|
98
|
+
```
|
|
93
99
|
- 如果你希望更改项目目录,可相应调整这些文件。
|
|
94
100
|
3. 重新加载 systemd 会话配置:
|
|
95
101
|
```bash
|
|
@@ -120,15 +126,19 @@ SPDX-License-Identifier: MIT
|
|
|
120
126
|
|
|
121
127
|
## 验证
|
|
122
128
|
|
|
123
|
-
-
|
|
124
|
-
dsh-podman
|
|
129
|
+
- 打开侧边栏的 **插件** 面板 → **已安装** →
|
|
130
|
+
**dsh-podman**:页面应列出基础镜像,并针对工作区提供创建其默认容器的选项。
|
|
125
131
|
- 在 dsh 会话中运行一条 shell 命令。它应在当前工作区的 Podman
|
|
126
132
|
容器内执行(插件会在首次使用时自动创建工作区的默认容器)。
|
|
127
133
|
|
|
128
|
-
##
|
|
134
|
+
## 配置 Git 身份(推荐)
|
|
135
|
+
|
|
136
|
+
- 打开侧边栏的 **插件** 面板 → **已安装** → **dsh-podman**
|
|
137
|
+
- 向下滚动到 **默认环境**
|
|
138
|
+
- 点击 **Git 身份**
|
|
139
|
+
- 输入用于 Git 的名称和邮箱,然后点击 **应用**
|
|
140
|
+
- 点击 **应用默认环境变量**,然后点击 **确认**
|
|
129
141
|
|
|
130
|
-
|
|
142
|
+
## 更新 dsh 与 dsh-podman
|
|
131
143
|
|
|
132
|
-
|
|
133
|
-
systemctl --user enable --now podman-auto-update.timer
|
|
134
|
-
```
|
|
144
|
+
请阅读[更新文档](./update.zh.md),了解如何手动更新或设置自动更新。
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
<!--
|
|
2
|
+
SPDX-FileCopyrightText: 2026 Elouan Martinet <exa@elou.world>
|
|
3
|
+
|
|
4
|
+
SPDX-License-Identifier: MIT
|
|
5
|
+
-->
|
|
6
|
+
|
|
7
|
+
# Uninstall
|
|
8
|
+
|
|
9
|
+
This page undoes the [installation guide](install-dsh-and-dsh-podman.md): it
|
|
10
|
+
assumes dsh runs from the dsh-podman image with the orchestrator, both started
|
|
11
|
+
from Quadlet units.
|
|
12
|
+
|
|
13
|
+
The dsh image installs the dsh-podman plugin at container start, and the
|
|
14
|
+
plugin's bundle layer is what disables dsh's own `subprocess`, `fs-sandbox`,
|
|
15
|
+
`spill-local` and built-in Terminal UI (`ui-sidebar-terminal`) plugins.
|
|
16
|
+
Uninstalling therefore also means running dsh without dsh-podman: its built-in
|
|
17
|
+
shell and filesystem tools are active again, and they run **on the host** as the
|
|
18
|
+
dsh user, with no container isolation.
|
|
19
|
+
|
|
20
|
+
## Stop the containers and remove the Quadlet units
|
|
21
|
+
|
|
22
|
+
```bash
|
|
23
|
+
systemctl --user stop dsh dsh-podman-orchestrator
|
|
24
|
+
rm ~/.config/containers/systemd/dsh.container
|
|
25
|
+
rm ~/.config/containers/systemd/dsh-podman-orchestrator.container
|
|
26
|
+
systemctl --user daemon-reload
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
## Then choose one of the two following options
|
|
30
|
+
|
|
31
|
+
These are alternatives, not steps: pick the one that matches what you want to
|
|
32
|
+
keep.
|
|
33
|
+
|
|
34
|
+
### Remove dsh entirely
|
|
35
|
+
|
|
36
|
+
```bash
|
|
37
|
+
podman unshare rm -rf ~/.dsh
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
`~/.dsh` is the whole harness home: the profiles (including the installed
|
|
41
|
+
plugin), the settings, and the orchestrator's state and package caches. The
|
|
42
|
+
orchestrator runs as root, so parts of that directory belong to the container's
|
|
43
|
+
root and only `podman unshare` can remove them, from the user namespace.
|
|
44
|
+
|
|
45
|
+
### Keep dsh without dsh-podman
|
|
46
|
+
|
|
47
|
+
Run dsh directly instead of from the image — as the harness documents, with
|
|
48
|
+
`npx @deepseek-ai/dsh web` — after removing the plugin from the profile, so dsh
|
|
49
|
+
stops loading it and its built-in plugins are active again:
|
|
50
|
+
|
|
51
|
+
```bash
|
|
52
|
+
npx @deepseek-ai/dsh plugin --profile web remove @exagone313/dsh-podman
|
|
53
|
+
npx @deepseek-ai/dsh web
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
Then archive the sessions that used the podman tools, from the session's menu
|
|
57
|
+
(**Archive session**): those tools no longer exist without dsh-podman, so
|
|
58
|
+
resuming such a session would leave the model calling tools that are gone.
|
|
59
|
+
|
|
60
|
+
The orchestrator's leftover state and package caches can be removed too. They
|
|
61
|
+
belong to the container's root, so remove them from the user namespace:
|
|
62
|
+
|
|
63
|
+
```bash
|
|
64
|
+
podman unshare rm -rf ~/.dsh/dsh-podman
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
## Remove the Podman resources (optional)
|
|
68
|
+
|
|
69
|
+
The orchestrator creates one pod per dsh workspace, plus named volumes and
|
|
70
|
+
secrets, and builds images. Removing them only reclaims disk space; project
|
|
71
|
+
directories are bind mounts and are never touched.
|
|
72
|
+
|
|
73
|
+
```bash
|
|
74
|
+
# Workspace pods and their containers, one per dsh workspace
|
|
75
|
+
podman pod ls --format '{{.Name}}' | grep '^dsh-podman-' | xargs -r podman pod rm -f
|
|
76
|
+
|
|
77
|
+
# Named volumes and secrets the orchestrator created
|
|
78
|
+
podman volume ls --format '{{.Name}}' | grep '^dsh-podman-' | xargs -r podman volume rm
|
|
79
|
+
podman secret ls --format '{{.Name}}' | grep '^dsh-podman-' | xargs -r podman secret rm
|
|
80
|
+
|
|
81
|
+
# Built workspace images, the base images, and the dsh-podman images themselves
|
|
82
|
+
podman images --format '{{.Repository}}:{{.Tag}}' | grep 'dsh-podman/' | xargs -r podman rmi
|
|
83
|
+
```
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
<!--
|
|
2
|
+
SPDX-FileCopyrightText: 2026 Elouan Martinet <exa@elou.world>
|
|
3
|
+
|
|
4
|
+
SPDX-License-Identifier: MIT
|
|
5
|
+
-->
|
|
6
|
+
|
|
7
|
+
# 卸载
|
|
8
|
+
|
|
9
|
+
本页用于撤销[安装指南](install-dsh-and-dsh-podman.zh.md)中的操作:其中假设 dsh
|
|
10
|
+
运行在 dsh-podman 镜像中,并与编排器一同由 Quadlet 单元启动。
|
|
11
|
+
|
|
12
|
+
dsh 镜像会在容器启动时安装 dsh-podman 插件,而该插件的 bundle 层正是禁用 dsh
|
|
13
|
+
自带的 `subprocess`、`fs-sandbox`、`spill-local`
|
|
14
|
+
与内置终端界面(`ui-sidebar-terminal`) 插件的原因。因此,卸载也意味着不再使用
|
|
15
|
+
dsh-podman 运行 dsh:其内置的 shell 与文件系统工具会重新启用,并以 dsh
|
|
16
|
+
用户的身份**在主机上**运行,不再有容器隔离。
|
|
17
|
+
|
|
18
|
+
## 停止容器并移除 Quadlet 单元
|
|
19
|
+
|
|
20
|
+
```bash
|
|
21
|
+
systemctl --user stop dsh dsh-podman-orchestrator
|
|
22
|
+
rm ~/.config/containers/systemd/dsh.container
|
|
23
|
+
rm ~/.config/containers/systemd/dsh-podman-orchestrator.container
|
|
24
|
+
systemctl --user daemon-reload
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
## 然后在以下两个选项中选择一个
|
|
28
|
+
|
|
29
|
+
这两个选项是并列的,而不是先后步骤:请根据你想保留的内容选择其一。
|
|
30
|
+
|
|
31
|
+
### 完全删除 dsh
|
|
32
|
+
|
|
33
|
+
```bash
|
|
34
|
+
podman unshare rm -rf ~/.dsh
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
`~/.dsh` 是整个 harness 主目录:包含各个
|
|
38
|
+
profile(其中有已安装的插件)、设置,以及编排器的状态与软件包缓存。编排器以 root
|
|
39
|
+
运行,因此该目录中部分文件属于容器内的 root,只能在用户命名空间(user
|
|
40
|
+
namespace)中用 `podman unshare` 删除。
|
|
41
|
+
|
|
42
|
+
### 保留 dsh 但不使用 dsh-podman
|
|
43
|
+
|
|
44
|
+
改为直接运行 dsh,而不是从镜像运行——如 harness 文档所述,使用
|
|
45
|
+
`npx @deepseek-ai/dsh web`——在此之前先从 profile 中移除插件,这样 dsh
|
|
46
|
+
便不再加载它,其内置插件也会重新启用:
|
|
47
|
+
|
|
48
|
+
```bash
|
|
49
|
+
npx @deepseek-ai/dsh plugin --profile web remove @exagone313/dsh-podman
|
|
50
|
+
npx @deepseek-ai/dsh web
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
然后归档曾使用 podman 工具的会话,从会话菜单中选择**归档会话**(Archive
|
|
54
|
+
session):没有 dsh-podman
|
|
55
|
+
之后这些工具已不存在,继续恢复此类会话会让模型调用已消失的工具。
|
|
56
|
+
|
|
57
|
+
编排器残留的状态与软件包缓存也可以删除。它们属于容器内的
|
|
58
|
+
root,因此请在用户命名空间中删除:
|
|
59
|
+
|
|
60
|
+
```bash
|
|
61
|
+
podman unshare rm -rf ~/.dsh/dsh-podman
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
## 删除 Podman 资源(可选)
|
|
65
|
+
|
|
66
|
+
编排器会为每个 dsh 工作区创建一个
|
|
67
|
+
pod,并创建命名卷与机密,还会构建镜像。删除它们只是回收磁盘空间;项目目录是绑定挂载,绝不会被改动。
|
|
68
|
+
|
|
69
|
+
```bash
|
|
70
|
+
# 工作区 pod 及其容器,每个 dsh 工作区一个
|
|
71
|
+
podman pod ls --format '{{.Name}}' | grep '^dsh-podman-' | xargs -r podman pod rm -f
|
|
72
|
+
|
|
73
|
+
# 编排器创建的命名卷与机密
|
|
74
|
+
podman volume ls --format '{{.Name}}' | grep '^dsh-podman-' | xargs -r podman volume rm
|
|
75
|
+
podman secret ls --format '{{.Name}}' | grep '^dsh-podman-' | xargs -r podman secret rm
|
|
76
|
+
|
|
77
|
+
# 构建的工作区镜像、基础镜像,以及 dsh-podman 自身的镜像
|
|
78
|
+
podman images --format '{{.Repository}}:{{.Tag}}' | grep 'dsh-podman/' | xargs -r podman rmi
|
|
79
|
+
```
|
package/docs/update.md
ADDED
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
<!--
|
|
2
|
+
SPDX-FileCopyrightText: 2026 Elouan Martinet <exa@elou.world>
|
|
3
|
+
|
|
4
|
+
SPDX-License-Identifier: MIT
|
|
5
|
+
-->
|
|
6
|
+
|
|
7
|
+
# Update
|
|
8
|
+
|
|
9
|
+
You should run updates only when no agents are running.
|
|
10
|
+
|
|
11
|
+
Existing guest containers will be recreated afterwards, so running processes and
|
|
12
|
+
daemons will be killed.
|
|
13
|
+
|
|
14
|
+
Note that the corresponding dsh-podman plugin will be installed from npm at
|
|
15
|
+
startup.
|
|
16
|
+
|
|
17
|
+
When enabling auto-updates, it is possible to skip updates while an agent is
|
|
18
|
+
running. Read further to set this up.
|
|
19
|
+
|
|
20
|
+
## Update manually
|
|
21
|
+
|
|
22
|
+
Pull the new images:
|
|
23
|
+
|
|
24
|
+
```bash
|
|
25
|
+
podman pull ghcr.io/exagone313/dsh-podman/dsh:1 ghcr.io/exagone313/dsh-podman/orchestrator:1
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
Restart dsh and dsh-podman-orchestrator:
|
|
29
|
+
|
|
30
|
+
```bash
|
|
31
|
+
systemctl --user restart dsh dsh-podman-orchestrator
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
## Upgrade to a new major version
|
|
35
|
+
|
|
36
|
+
Currently, dsh-podman major version is 1. To upgrade to major version 2 and
|
|
37
|
+
above, check the
|
|
38
|
+
[release notes](https://github.com/Exagone313/dsh-podman/releases).
|
|
39
|
+
|
|
40
|
+
## Enable auto-updates
|
|
41
|
+
|
|
42
|
+
The quadlet configuration for dsh and dsh-podman-orchestrator enables
|
|
43
|
+
auto-update of images (`AutoUpdate=registry`). The `podman-auto-update` systemd
|
|
44
|
+
timer needs to be enabled for this to work:
|
|
45
|
+
|
|
46
|
+
```bash
|
|
47
|
+
systemctl --user enable --now podman-auto-update.timer
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
Also, make sure user lingering is enabled for your user (as root):
|
|
51
|
+
|
|
52
|
+
```bash
|
|
53
|
+
loginctl enable-linger your-username
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
Each time the timer runs, the Podman auto-update tool tries to pull newer
|
|
57
|
+
versions of the images. If new versions are pulled, the corresponding containers
|
|
58
|
+
will be recreated.
|
|
59
|
+
|
|
60
|
+
By default, this timer runs once per day, around midnight.
|
|
61
|
+
|
|
62
|
+
## Change when auto-updates happen
|
|
63
|
+
|
|
64
|
+
You can override the time when the timer runs.
|
|
65
|
+
|
|
66
|
+
Create the directory that contains user overrides for the `podman-auto-update`
|
|
67
|
+
systemd timer:
|
|
68
|
+
|
|
69
|
+
```bash
|
|
70
|
+
mkdir -p ~/.config/systemd/user/podman-auto-update.timer.d
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
Copy the drop-in
|
|
74
|
+
[`podman-auto-update.timer.conf`](../systemd-dropins/podman-auto-update.timer.conf)
|
|
75
|
+
into the directory and edit its content according to your needs.
|
|
76
|
+
|
|
77
|
+
```bash
|
|
78
|
+
cp systemd-dropins/podman-auto-update.timer.conf ~/.config/systemd/user/podman-auto-update.timer.d/
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
Reload systemd configuration and restart the timer:
|
|
82
|
+
|
|
83
|
+
```bash
|
|
84
|
+
systemctl --user daemon-reload
|
|
85
|
+
systemctl --user restart podman-auto-update.timer
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
You can verify when the timer will run next with:
|
|
89
|
+
|
|
90
|
+
```bash
|
|
91
|
+
systemctl --user list-timers
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
The same drop-in file can be edited to run updates multiple times a day.
|
|
95
|
+
|
|
96
|
+
## Skip updates while an agent is running
|
|
97
|
+
|
|
98
|
+
An update restarts the dsh container, which interrupts any agent turn in flight.
|
|
99
|
+
It is possible to skip updates when an agent is running.
|
|
100
|
+
|
|
101
|
+
Create the directory that contains user overrides for the `podman-auto-update`
|
|
102
|
+
systemd service (it is not the same directory as the timer):
|
|
103
|
+
|
|
104
|
+
```bash
|
|
105
|
+
mkdir -p ~/.config/systemd/user/podman-auto-update.service.d
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
Copy the drop-in
|
|
109
|
+
[`podman-auto-update-skip-when-busy.conf`](../systemd-dropins/podman-auto-update-skip-when-busy.conf)
|
|
110
|
+
into the directory.
|
|
111
|
+
|
|
112
|
+
```bash
|
|
113
|
+
cp systemd-dropins/podman-auto-update-skip-when-busy.conf ~/.config/systemd/user/podman-auto-update.service.d/
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
Reload systemd configuration:
|
|
117
|
+
|
|
118
|
+
```bash
|
|
119
|
+
systemctl --user daemon-reload
|
|
120
|
+
```
|