@exagone313/dsh-podman 0.2.0-rc.3 → 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 +14 -2
- 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 +154 -42
- package/dist/card-route.test.js +85 -43
- package/dist/card-test-support.js +39 -66
- package/dist/client/ContainerCard.d.ts +1 -1
- package/dist/client/ContainerCard.js +92 -50
- package/dist/client/card-protocol.d.ts +6 -3
- package/dist/client/container-card-caches.js +11 -6
- package/dist/client/container-card-controller.d.ts +16 -18
- package/dist/client/container-card-controller.js +92 -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 +13141 -2036
- package/dist/client/locales.d.ts +6 -1
- package/dist/client/locales.js +106 -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.d.ts +1 -0
- package/dist/dsh-version.js +46 -0
- 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 +11 -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 +38 -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/version-compat.d.ts +4 -0
- package/dist/version-compat.js +29 -0
- package/dist/version-compat.test.d.ts +1 -0
- package/dist/version-compat.test.js +27 -0
- package/dist/volumes.test.js +1 -1
- package/dist/workspace-binding.d.ts +19 -10
- package/dist/workspace-binding.js +252 -78
- package/dist/workspace-binding.test.js +202 -27
- package/docs/architecture.md +71 -20
- package/docs/architecture.zh.md +62 -12
- 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 +184 -29
- package/docs/development.zh.md +165 -26
- package/docs/install-dsh-and-dsh-podman.md +24 -21
- package/docs/install-dsh-and-dsh-podman.zh.md +20 -21
- 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.md
CHANGED
|
@@ -20,8 +20,8 @@ This page is for **contributors** building the plugin from this repository.
|
|
|
20
20
|
|
|
21
21
|
## Building
|
|
22
22
|
|
|
23
|
-
Prerequisites: Go 1.27, Node ≥ 22, pnpm 12,
|
|
24
|
-
`@deepseek-ai/dsh-client-*` packages published on npm.
|
|
23
|
+
Prerequisites: Go 1.27, Node ≥ 22, pnpm 12, Deno ≥ 2.9 (formatting), and (for
|
|
24
|
+
the browser half) the `@deepseek-ai/dsh-client-*` packages published on npm.
|
|
25
25
|
|
|
26
26
|
```sh
|
|
27
27
|
pnpm install
|
|
@@ -36,20 +36,22 @@ The `Makefile` wraps the common workflows:
|
|
|
36
36
|
```sh
|
|
37
37
|
make build-go # build both Go binaries into bin/<os>-<arch>/
|
|
38
38
|
make build # build-go + pnpm-build
|
|
39
|
-
make vet # go vet with the build tags
|
|
39
|
+
make vet # gofmt -s check + go vet with the build tags
|
|
40
40
|
make test-go # go test with the build tags
|
|
41
41
|
make test # test-go + pnpm test (JS tests, which run against dist/)
|
|
42
|
-
make
|
|
43
|
-
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
|
|
44
46
|
```
|
|
45
47
|
|
|
46
|
-
`make image` depends on `
|
|
47
|
-
Go collector in `scripts/download-licenses`, which shells out to
|
|
48
|
+
`make image` depends on `third-party-licenses.pkg`: the `download-licenses`
|
|
49
|
+
target runs the Go collector in `scripts/download-licenses`, which shells out to
|
|
48
50
|
`go-licenses save` and gathers the project's MIT license plus every third-party
|
|
49
|
-
Go license and Apache `NOTICE` into `
|
|
50
|
-
(never committed) and is baked into the orchestrator and guest-agent
|
|
51
|
-
`/usr/share/licenses/dsh-podman/LICENSE`; because workspace containers
|
|
52
|
-
guest-agent image, it also rides along into every workspace container.
|
|
51
|
+
Go license and Apache `NOTICE` into `third-party-licenses.pkg`. That file is
|
|
52
|
+
gitignored (never committed) and is baked into the orchestrator and guest-agent
|
|
53
|
+
images at `/usr/share/licenses/dsh-podman/LICENSE`; because workspace containers
|
|
54
|
+
mount the guest-agent image, it also rides along into every workspace container.
|
|
53
55
|
|
|
54
56
|
`pnpm test` runs `node --test dist/*.test.js`, so it requires `pnpm build` to
|
|
55
57
|
have run first (the `test` target handles this).
|
|
@@ -66,6 +68,19 @@ The JS side loads the raw `.proto` files at runtime via `@grpc/proto-loader`
|
|
|
66
68
|
(copied to `dist/grpc/proto/` at build time); no TypeScript bindings are
|
|
67
69
|
generated. Optionally validate the schema with `buf lint` and `buf breaking`.
|
|
68
70
|
|
|
71
|
+
## Naming
|
|
72
|
+
|
|
73
|
+
Proto field names are `lower_snake_case` (Buf's `BASIC` lint enforces it), and
|
|
74
|
+
the JS side reads them through proto-loader's camelCase projection, so
|
|
75
|
+
`secret_env` becomes `secretEnv` and `image_id` becomes `imageId`. Never spell a
|
|
76
|
+
proto field in its snake_case form in TypeScript: proto-loader ignores an
|
|
77
|
+
unknown property, so the value would be silently dropped.
|
|
78
|
+
|
|
79
|
+
Tool parameters are camelCase, except the ones that deliberately mirror the
|
|
80
|
+
harness's built-in tools (`file_path`, `old_string`, `new_string`,
|
|
81
|
+
`replace_all`). Settings are camelCase; the persisted TOML state uses snake_case
|
|
82
|
+
tags.
|
|
83
|
+
|
|
69
84
|
## Install development builds
|
|
70
85
|
|
|
71
86
|
### Build
|
|
@@ -75,33 +90,165 @@ make # builds plugin and go binaries
|
|
|
75
90
|
make image # build images
|
|
76
91
|
```
|
|
77
92
|
|
|
78
|
-
###
|
|
93
|
+
### Run the local images (Quadlet)
|
|
94
|
+
|
|
95
|
+
The shipped units pull the release images. Point them at the images built by
|
|
96
|
+
`make image` to run a local build as the real services; comment the original
|
|
97
|
+
line out so switching back is a one-line edit.
|
|
98
|
+
|
|
99
|
+
In `~/.config/containers/systemd/dsh.container`:
|
|
100
|
+
|
|
101
|
+
```ini
|
|
102
|
+
#Image=ghcr.io/exagone313/dsh-podman/dsh:1
|
|
103
|
+
Image=localhost/dsh-podman-dsh:latest
|
|
104
|
+
Environment=DSH_PODMAN_PLUGIN_SOURCE=%h/project/dsh-podman
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
The unit already mounts `%h/project` read-only, so a repository checked out
|
|
108
|
+
under `~/project` needs no extra `Volume=`. `npm pack` leaves the archive the
|
|
109
|
+
entrypoint installs next to `package.json` (see
|
|
110
|
+
[Install a local plugin build](#install-a-local-plugin-build)).
|
|
111
|
+
|
|
112
|
+
In `~/.config/containers/systemd/dsh-podman-orchestrator.container`:
|
|
113
|
+
|
|
114
|
+
```ini
|
|
115
|
+
#Image=ghcr.io/exagone313/dsh-podman/orchestrator:1
|
|
116
|
+
Image=localhost/dsh-podman-orchestrator:latest
|
|
117
|
+
#Environment=DSH_PODMAN_GUEST_AGENT_IMAGE=ghcr.io/exagone313/dsh-podman/guest-agent
|
|
118
|
+
#Environment=DSH_PODMAN_GUEST_AGENT_IMAGE_USE_VERSION_TAG=true
|
|
119
|
+
Environment=DSH_PODMAN_GUEST_AGENT_IMAGE=localhost/dsh-podman-guest-agent:latest
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
The release reference is version-tagged, so every release gets a distinct image
|
|
123
|
+
reference. The local build reuses a single `:latest` tag instead; the
|
|
124
|
+
orchestrator then cannot tell that the agent was rebuilt, which is what
|
|
125
|
+
[Update workspace containers](#update-workspace-containers) is about.
|
|
126
|
+
|
|
127
|
+
Reload systemd after editing the units:
|
|
79
128
|
|
|
80
129
|
```bash
|
|
130
|
+
systemctl --user daemon-reload
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
### Deploy a change
|
|
134
|
+
|
|
135
|
+
```bash
|
|
136
|
+
make # Go binaries + the plugin bundle
|
|
137
|
+
make image # orchestrator, guest-agent and dsh images
|
|
138
|
+
npm pack # the plugin archive the dsh entrypoint installs
|
|
81
139
|
systemctl --user restart dsh dsh-podman-orchestrator
|
|
82
140
|
```
|
|
83
141
|
|
|
84
|
-
|
|
142
|
+
The dsh image installs the plugin at container start, so restarting dsh is what
|
|
143
|
+
reinstalls the freshly packed archive; restarting the orchestrator picks up the
|
|
144
|
+
new orchestrator and guest-agent images.
|
|
145
|
+
|
|
146
|
+
### Update workspace containers
|
|
147
|
+
|
|
148
|
+
The guest-agent image is mounted into each container when it is created, so a
|
|
149
|
+
running container keeps the agent it started with. The orchestrator recreates a
|
|
150
|
+
container by itself only when its guest-agent image reference differs from the
|
|
151
|
+
configured one — which happens with the version-tagged release reference, but
|
|
152
|
+
not with the local `:latest` tag. After rebuilding the guest agent, recreate the
|
|
153
|
+
containers yourself:
|
|
154
|
+
|
|
155
|
+
- from the Podman page (sidebar **Plugins** panel → **Installed** →
|
|
156
|
+
**dsh-podman**), per container: **Recreate** (same image) or **Recreate with
|
|
157
|
+
image**;
|
|
158
|
+
- with `container_recreate`, for a named container or the default one.
|
|
159
|
+
|
|
160
|
+
To rebuild a whole workspace instead, use **Remove pod** on its row (or
|
|
161
|
+
`RemoveWorkspace`): the pod and all its containers are removed, and the next
|
|
162
|
+
attach creates the pod and its default container again. Restarting the two
|
|
163
|
+
services never touches workspace containers, and neither action removes volumes,
|
|
164
|
+
secrets, or project data.
|
|
165
|
+
|
|
166
|
+
A container that still runs an agent from an older image makes dsh log
|
|
167
|
+
`rejected by server because of excess pings` for its guest socket. The message
|
|
168
|
+
is harmless (grpc-js backs off and reconnects) and disappears once the container
|
|
169
|
+
is recreated; the same message for `orchestrator.sock` means the orchestrator
|
|
170
|
+
service is still running the previous image.
|
|
171
|
+
|
|
172
|
+
### Development container toolchain
|
|
173
|
+
|
|
174
|
+
A workspace container's root filesystem is read-only and disposable, so the
|
|
175
|
+
toolchain a contributor builds with needs a workspace volume. No development
|
|
176
|
+
image is distributed: build a custom one — the
|
|
177
|
+
[setup prompt](development-prompt.md) builds `dsh-podman-tooling` from the
|
|
178
|
+
`archlinux` base with `go`, `nodejs-lts-jod`, `npm`, `deno`, `reuse` and
|
|
179
|
+
`python-chardet` — and create a workspace volume for the state an image cannot
|
|
180
|
+
keep: the Go and npm caches, `gopath` with the `go install`ed tools, and pnpm,
|
|
181
|
+
which `package.json` pins to a version the Arch repositories do not carry.
|
|
182
|
+
|
|
183
|
+
The prompt mounts that volume as `dsh-podman-toolchain` at `/opt/toolchain`
|
|
184
|
+
(read-write) and points the container's caches at it, so commands work without
|
|
185
|
+
sourcing anything:
|
|
186
|
+
|
|
187
|
+
| Container setting | Value |
|
|
188
|
+
| ----------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
189
|
+
| PATH additions | `/opt/toolchain/gopath/bin`, `/opt/toolchain/npm-global/bin`, `/opt/toolchain/pnpm-home` |
|
|
190
|
+
| Environment | `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` |
|
|
191
|
+
|
|
192
|
+
Set the commit identity once on the Podman page (sidebar **Plugins** panel →
|
|
193
|
+
**Installed** → **dsh-podman**) under
|
|
194
|
+
[Default environment](configuration.md#default-environment) → **Git identity**,
|
|
195
|
+
so containers get `GIT_AUTHOR_*`/`GIT_COMMITTER_*` without a `~/.gitconfig`.
|
|
196
|
+
|
|
197
|
+
The prompt applies all of this from inside dsh and can be pasted again to repair
|
|
198
|
+
a workspace. Podman stores managed volumes with `DSH_PODMAN_VOLUME_PREFIX`
|
|
199
|
+
prepended, so it lists the volume as `dsh-podman-dsh-podman-toolchain`.
|
|
200
|
+
|
|
201
|
+
### Install a local plugin build
|
|
202
|
+
|
|
203
|
+
The dsh image installs the plugin itself at container start, so a development
|
|
204
|
+
build is served by pointing that install at a bind-mounted package. The Quadlet
|
|
205
|
+
setup above is the first form below, with the repository directory itself
|
|
206
|
+
(`%h/project/dsh-podman`) already visible through the unit's read-only
|
|
207
|
+
`%h/project` mount. Build the plugin and pack it:
|
|
85
208
|
|
|
86
209
|
```bash
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
210
|
+
pnpm build
|
|
211
|
+
npm pack # writes exagone313-dsh-podman-<version>.tgz
|
|
212
|
+
```
|
|
213
|
+
|
|
214
|
+
Then add one of these to the dsh container unit and restart it:
|
|
215
|
+
|
|
216
|
+
```
|
|
217
|
+
# the repository directory, which must contain the packed archive
|
|
218
|
+
Volume=/path/to/repo:/mnt/dsh-podman:ro
|
|
219
|
+
Environment=DSH_PODMAN_PLUGIN_SOURCE=/mnt/dsh-podman
|
|
93
220
|
```
|
|
94
221
|
|
|
222
|
+
```
|
|
223
|
+
# or the archive itself
|
|
224
|
+
Volume=/path/to/exagone313-dsh-podman-x.y.z.tgz:/mnt/dsh-podman.tgz:ro
|
|
225
|
+
Environment=DSH_PODMAN_PLUGIN_SOURCE=/mnt/dsh-podman.tgz
|
|
226
|
+
```
|
|
227
|
+
|
|
228
|
+
The entrypoint installs that package on every start and never falls back to the
|
|
229
|
+
registry — a missing package is an error. Re-run `pnpm build && npm pack` and
|
|
230
|
+
restart dsh to pick up changes.
|
|
231
|
+
|
|
232
|
+
Without `DSH_PODMAN_PLUGIN_SOURCE`, the entrypoint installs
|
|
233
|
+
`@exagone313/dsh-podman@$DSH_PODMAN_PLUGIN_VERSION` (the version baked into the
|
|
234
|
+
image) exactly, upgrading or downgrading the profile's copy to match.
|
|
235
|
+
|
|
95
236
|
## Continuous integration
|
|
96
237
|
|
|
97
|
-
CI
|
|
238
|
+
CI runs on every **branch** push and pull request, split across
|
|
239
|
+
`.github/workflows/ci-common.yml` (REUSE lint and zizmor), `ci-code.yml` (Go,
|
|
240
|
+
JS, images, Trivy), `ci-docs.yml` (Deno fmt) and `ci-dsh-image.yml`. A **tag**
|
|
241
|
+
push runs only `release.yml`, which repeats the build, vet and tests itself:
|
|
98
242
|
|
|
99
243
|
- **actions-lint** — zizmor scans the workflows for insecure practices.
|
|
100
|
-
- **
|
|
101
|
-
|
|
102
|
-
|
|
244
|
+
- **reuse** — REUSE license compliance.
|
|
245
|
+
- **go** — build, `gofmt -s` check, vet, tests, and govulncheck (Go
|
|
246
|
+
vulnerabilities). Unfixed findings don't fail the job; fixable ones do.
|
|
247
|
+
- **js** — TypeScript formatting check, install, typecheck, build, tests, and
|
|
248
|
+
`pnpm audit`.
|
|
249
|
+
- **docs** — Markdown formatting check (`deno fmt` via `make fmt-check-md`).
|
|
103
250
|
- **images** — builds the orchestrator and guest-agent images (runs only after
|
|
104
|
-
the test jobs pass).
|
|
251
|
+
the test jobs pass); **dsh image** builds `Containerfile.dsh`.
|
|
105
252
|
- **trivy** — filesystem vulnerability scan (unfixed ignored) and container
|
|
106
253
|
misconfiguration scan (DS-0002 excluded via `.trivyignore.yaml`).
|
|
107
254
|
|
|
@@ -115,9 +262,12 @@ pre-releases like `1.0.0-rc.1` also work). The release workflow
|
|
|
115
262
|
|
|
116
263
|
1. Runs the tests, then builds both binaries for `linux/amd64` and
|
|
117
264
|
`linux/arm64`.
|
|
118
|
-
2. Pushes the **orchestrator** and **guest-agent** images to GHCR
|
|
119
|
-
(`ghcr.io/exagone313/dsh-podman/{orchestrator,guest-agent}`)
|
|
120
|
-
|
|
265
|
+
2. Pushes the **dsh**, **orchestrator** and **guest-agent** images to GHCR
|
|
266
|
+
(`ghcr.io/exagone313/dsh-podman/{dsh,orchestrator,guest-agent}`). Every
|
|
267
|
+
release is tagged with its version; a **stable** release — `1.0.0` or above
|
|
268
|
+
with no pre-release suffix — is also tagged with its major version (`1`) and
|
|
269
|
+
`latest`. A `0.x` release and any hyphenated tag are pre-releases: they get
|
|
270
|
+
the version tag only.
|
|
121
271
|
3. Publishes the plugin to **npm** (`@exagone313/dsh-podman`) with provenance;
|
|
122
272
|
pre-releases are published under the `next` dist-tag.
|
|
123
273
|
4. Creates a **GitHub release** with auto-generated notes and attaches the
|
|
@@ -127,8 +277,8 @@ The tag must match `package.json`'s version — the workflow fails otherwise —
|
|
|
127
277
|
bump both with the version script:
|
|
128
278
|
|
|
129
279
|
```sh
|
|
130
|
-
pnpm bump-version
|
|
131
|
-
git push origin master
|
|
280
|
+
pnpm bump-version x.y.z # add --dry-run to validate only
|
|
281
|
+
git push origin master x.y.z
|
|
132
282
|
```
|
|
133
283
|
|
|
134
284
|
`scripts/bump-version.mjs` checks that the version is a semver release or
|
|
@@ -139,4 +289,9 @@ built plugin and binaries report, since `scripts/generate-version.mjs` derives
|
|
|
139
289
|
the embedded version from `git describe --tags`. Pre-releases (`1.0.0-rc.1`) are
|
|
140
290
|
bumped the same way.
|
|
141
291
|
|
|
292
|
+
A release can also be triggered, or a failed one re-run, from the Actions tab
|
|
293
|
+
with `workflow_dispatch`, which takes the version as input. Already-published
|
|
294
|
+
steps are skipped (npm skips a version it already has, and an existing GitHub
|
|
295
|
+
release is left alone), so a retry never republishes.
|
|
296
|
+
|
|
142
297
|
The `NPM_TOKEN` secret must be configured on the repository for the npm step.
|
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,32 +88,151 @@ 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:
|
|
123
|
+
|
|
124
|
+
```bash
|
|
125
|
+
systemctl --user daemon-reload
|
|
126
|
+
```
|
|
127
|
+
|
|
128
|
+
### 部署改动
|
|
77
129
|
|
|
78
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
|
|
|
82
|
-
|
|
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
|
+
|
|
188
|
+
### 安装本地插件构建
|
|
189
|
+
|
|
190
|
+
dsh 镜像会在容器启动时自行安装插件,因此本地开发构建通过将安装源指向 bind mount
|
|
191
|
+
的包来使用。上面的 Quadlet 配置就是下面第一种形式,仓库目录本身
|
|
192
|
+
(`%h/project/dsh-podman`)已经通过单元的只读 `%h/project`
|
|
193
|
+
挂载可见。先构建并打包插件:
|
|
83
194
|
|
|
84
195
|
```bash
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
podman cp ./exagone313-dsh-podman-"${v}".tgz dsh:/tmp/
|
|
88
|
-
podman exec -it dsh dsh plugin --profile web remove @exagone313/dsh-podman # necessary, to force reinstall if the same version
|
|
89
|
-
podman exec -it dsh dsh plugin --profile web add /tmp/exagone313-dsh-podman-"${v}".tgz --allow-build=protobufjs
|
|
90
|
-
systemctl --user restart dsh
|
|
196
|
+
pnpm build
|
|
197
|
+
npm pack # 生成 exagone313-dsh-podman-<version>.tgz
|
|
91
198
|
```
|
|
92
199
|
|
|
200
|
+
然后在 dsh 容器单元中加入以下之一并重启:
|
|
201
|
+
|
|
202
|
+
```
|
|
203
|
+
# 仓库目录,其中必须包含已打包的归档
|
|
204
|
+
Volume=/path/to/repo:/mnt/dsh-podman:ro
|
|
205
|
+
Environment=DSH_PODMAN_PLUGIN_SOURCE=/mnt/dsh-podman
|
|
206
|
+
```
|
|
207
|
+
|
|
208
|
+
```
|
|
209
|
+
# 或者归档本身
|
|
210
|
+
Volume=/path/to/exagone313-dsh-podman-x.y.z.tgz:/mnt/dsh-podman.tgz:ro
|
|
211
|
+
Environment=DSH_PODMAN_PLUGIN_SOURCE=/mnt/dsh-podman.tgz
|
|
212
|
+
```
|
|
213
|
+
|
|
214
|
+
入口脚本会在每次启动时安装该包,且绝不会回退到注册表——找不到包即为错误。重新运行
|
|
215
|
+
`pnpm build && npm pack` 并重启 dsh 即可生效。
|
|
216
|
+
|
|
217
|
+
未设置 `DSH_PODMAN_PLUGIN_SOURCE` 时,入口脚本会精确安装
|
|
218
|
+
`@exagone313/dsh-podman@$DSH_PODMAN_PLUGIN_VERSION`(镜像构建时写入的版本),并相应升级或降级配置中的副本。
|
|
219
|
+
|
|
93
220
|
## 持续集成
|
|
94
221
|
|
|
95
|
-
CI
|
|
222
|
+
CI 在每次**分支**推送和拉取请求时运行,分散在
|
|
223
|
+
`.github/workflows/ci-common.yml`(REUSE lint 与
|
|
224
|
+
zizmor)、`ci-code.yml`(Go、JS、镜像、Trivy)、`ci-docs.yml`(Deno fmt)和
|
|
225
|
+
`ci-dsh-image.yml` 中。推送**标签**时只运行 `release.yml`,它自身会重复构建、vet
|
|
226
|
+
和测试:
|
|
96
227
|
|
|
97
228
|
- **actions-lint** — zizmor 扫描工作流是否存在不安全实践。
|
|
98
|
-
- **
|
|
229
|
+
- **reuse** — REUSE 许可证合规检查。
|
|
230
|
+
- **go** — 构建、`gofmt -s` 检查、vet、测试和 govulncheck(Go 漏洞)。未修复的
|
|
99
231
|
发现不会导致任务失败;可修复的会导致失败。
|
|
100
|
-
- **js** —
|
|
101
|
-
- **
|
|
232
|
+
- **js** — TypeScript 格式检查、安装、类型检查、构建、测试和 `pnpm audit`。
|
|
233
|
+
- **docs** — Markdown 格式检查(通过 `make fmt-check-md` 运行 `deno fmt`)。
|
|
234
|
+
- **images** — 构建 orchestrator 和 guest-agent
|
|
235
|
+
镜像(仅在测试任务通过后运行);**dsh image** 构建 `Containerfile.dsh`。
|
|
102
236
|
- **trivy** — 文件系统漏洞扫描(未修复的被忽略)和容器 错误配置扫描(DS-0002
|
|
103
237
|
通过 `.trivyignore.yaml` 排除)。
|
|
104
238
|
|
|
@@ -110,9 +244,10 @@ CI(`.github/workflows/ci.yml`)在每次分支推送和拉取请求时运行
|
|
|
110
244
|
这样的预发布同样有效)触发。发布工作流 (`.github/workflows/release.yml`):
|
|
111
245
|
|
|
112
246
|
1. 运行测试,然后为 `linux/amd64` 和 `linux/arm64` 构建两个二进制文件。
|
|
113
|
-
2. 将 **orchestrator** 和 **guest-agent** 镜像推送到 GHCR
|
|
114
|
-
(`ghcr.io/exagone313/dsh-podman/{orchestrator,guest-agent}
|
|
115
|
-
|
|
247
|
+
2. 将 **dsh**、**orchestrator** 和 **guest-agent** 镜像推送到 GHCR
|
|
248
|
+
(`ghcr.io/exagone313/dsh-podman/{dsh,orchestrator,guest-agent}`)。每个发布都打上其版本标签;**稳定**发布——`1.0.0`
|
|
249
|
+
及以上且不带预发布后缀——还会打上其主版本号(`1`)和 `latest`。`0.x`
|
|
250
|
+
发布以及任何带连字符的标签都属于预发布:只打版本标签。
|
|
116
251
|
3. 将插件发布到 **npm**(`@exagone313/dsh-podman`),附带来源证明; 预发布在
|
|
117
252
|
`next` dist-tag 下发布。
|
|
118
253
|
4. 创建带有自动生成说明的 **GitHub release**,并附上 二进制文件和 npm tarball。
|
|
@@ -121,8 +256,8 @@ CI(`.github/workflows/ci.yml`)在每次分支推送和拉取请求时运行
|
|
|
121
256
|
中的版本一致——否则工作流会失败——因此请用版本脚本同时更新两者:
|
|
122
257
|
|
|
123
258
|
```sh
|
|
124
|
-
pnpm bump-version
|
|
125
|
-
git push origin master
|
|
259
|
+
pnpm bump-version x.y.z # 加上 --dry-run 则仅校验
|
|
260
|
+
git push origin master x.y.z
|
|
126
261
|
```
|
|
127
262
|
|
|
128
263
|
`scripts/bump-version.mjs` 会检查版本是否为递增的 Semver
|
|
@@ -132,4 +267,8 @@ git push origin master 0.1.1
|
|
|
132
267
|
`scripts/generate-version.mjs` 从 `git describe --tags`
|
|
133
268
|
推导嵌入的版本。预发布版(`1.0.0-rc.1`)也用同样的方式递增。
|
|
134
269
|
|
|
270
|
+
也可以在 Actions 页面通过 `workflow_dispatch`
|
|
271
|
+
触发发布,或重新运行失败的发布,版本作为输入传入。已完成的步骤会被跳过(npm
|
|
272
|
+
会跳过已存在的版本,已有的 GitHub release 不会被改动),因此重试不会重复发布。
|
|
273
|
+
|
|
135
274
|
npm 步骤要求仓库配置 `NPM_TOKEN` 密钥。
|
|
@@ -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
|
|
@@ -95,12 +98,13 @@ could be added in the future.
|
|
|
95
98
|
|
|
96
99
|
## Installation
|
|
97
100
|
|
|
98
|
-
### dsh setup
|
|
99
|
-
|
|
100
101
|
This installation uses
|
|
101
102
|
[Podman Quadlet](https://docs.podman.io/en/latest/markdown/podman-systemd.unit.5.html),
|
|
102
103
|
which adds Podman integration into systemd.
|
|
103
104
|
|
|
105
|
+
Note that the dsh-podman plugin will be installed at dsh container startup,
|
|
106
|
+
which requires online access.
|
|
107
|
+
|
|
104
108
|
1. Create the Quadlet directory for your user:
|
|
105
109
|
```bash
|
|
106
110
|
mkdir -p ~/.config/containers/systemd
|
|
@@ -108,6 +112,9 @@ which adds Podman integration into systemd.
|
|
|
108
112
|
2. Copy the files [dsh.container](../quadlet/dsh.container) and
|
|
109
113
|
[dsh-podman-orchestrator.container](../quadlet/dsh-podman-orchestrator.container)
|
|
110
114
|
to `~/.config/containers/systemd/`.
|
|
115
|
+
```bash
|
|
116
|
+
cp quadlet/* ~/.config/containers/systemd/
|
|
117
|
+
```
|
|
111
118
|
- Adapt the files to your desired project directory if you wish to change it.
|
|
112
119
|
3. Reload systemd session configuration:
|
|
113
120
|
```bash
|
|
@@ -137,29 +144,25 @@ which adds Podman integration into systemd.
|
|
|
137
144
|
9. Once your web browser has saved this token, you'll be able to access dsh with
|
|
138
145
|
the URL [http://127.0.0.1:3080/](http://127.0.0.1:3080/).
|
|
139
146
|
|
|
140
|
-
### dsh-podman plugin installation
|
|
141
|
-
|
|
142
|
-
1. Run this command to install the dsh-podman plugin:
|
|
143
|
-
```bash
|
|
144
|
-
podman exec dsh dsh plugin --profile web add @exagone313/dsh-podman --allow-build=protobufjs
|
|
145
|
-
```
|
|
146
|
-
2. Restart dsh to complete the installation:
|
|
147
|
-
```bash
|
|
148
|
-
systemctl --user restart dsh
|
|
149
|
-
```
|
|
150
|
-
|
|
151
147
|
## Verification
|
|
152
148
|
|
|
153
|
-
- Open **
|
|
154
|
-
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.
|
|
155
152
|
- In a dsh session, run a shell command. It should execute inside a Podman
|
|
156
153
|
container for the current workspace (the plugin auto-creates the workspace's
|
|
157
154
|
default container on first use).
|
|
158
155
|
|
|
159
|
-
##
|
|
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**
|
|
160
164
|
|
|
161
|
-
|
|
165
|
+
## Updating dsh & dsh-podman
|
|
162
166
|
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
```
|
|
167
|
+
Read the [update documentation](./update.md) to know how to manually update or
|
|
168
|
+
set up auto-updates.
|