Skip to content

Commit b7d4c7f

Browse files
committed
feat: agent sandbox pv preview - go daemon
1 parent a15dbec commit b7d4c7f

26 files changed

Lines changed: 2628 additions & 10 deletions

sandbox/daemon/Dockerfile

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
# 生产用多阶段镜像: 构建 daemon 二进制, 以常驻(resident)模式运行。
2+
# 沙箱内 daemon 与常驻 daemon 共用同一二进制, 常驻模式由 CMD 的 `resident` 参数切入。
3+
4+
FROM golang:1.25.4-alpine3.22 AS builder
5+
6+
WORKDIR /workspace
7+
8+
# 构建依赖: git(make build 通过 git describe 注入版本)、make、bash
9+
RUN apk add --no-cache git make bash
10+
11+
# 先拉依赖, 利用层缓存
12+
COPY go.mod go.mod
13+
COPY go.sum go.sum
14+
RUN go mod download
15+
16+
COPY . .
17+
18+
# make build 会同时生成 swagger 文档并产出 build/daemon
19+
RUN make build
20+
21+
FROM alpine:3.22
22+
23+
WORKDIR /app
24+
25+
# 时区与根证书(archive 需 HTTPS PUT 到 bkrepo 临时 URL);
26+
# mailcap 提供 /etc/mime.types, 让标准库 mime.TypeByExtension 能识别更多扩展名。
27+
RUN apk add --no-cache ca-certificates tzdata mailcap
28+
29+
COPY --from=builder /workspace/build/daemon /app/daemon
30+
COPY --from=builder /workspace/build/daemon /usr/local/bin/daemon
31+
32+
# 常驻 daemon 默认监听 8000
33+
EXPOSE 8000
34+
35+
ENTRYPOINT ["/app/daemon"]
36+
CMD ["resident"]

sandbox/daemon/cmd/main.go

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -188,6 +188,13 @@ func main() {
188188
return
189189
}
190190

191+
// resident 子命令: 以常驻模式启动(挂 CFS 根, 面向 apiserver 提供 PV 文件操作)。
192+
// 与 version 同构, 靠 os.Args[1] 特判, 不影响现有沙箱 daemon 的 entrypoint 拉起逻辑。
193+
if len(os.Args) > 1 && os.Args[1] == "resident" {
194+
runResident()
195+
return
196+
}
197+
191198
errChan := make(chan error)
192199

193200
cfg, err := config.Load()
@@ -269,6 +276,41 @@ func main() {
269276
slog.Info("Shutdown complete")
270277
}
271278

279+
// runResident starts the daemon in resident mode.
280+
//
281+
// It shares the common bootstrap (config + logging + signal-driven graceful shutdown)
282+
// with the sandbox mode but does NOT manage an entrypoint child process: the resident
283+
// daemon is a standalone platform component that only serves PV file operations over HTTP.
284+
func runResident() {
285+
cfg, err := config.Load()
286+
if err != nil {
287+
slog.Error("Failed to load config", "error", err)
288+
panic(err)
289+
}
290+
291+
var logWriter io.Writer
292+
logFile, err := os.OpenFile(cfg.DaemonLogFilePath, os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0o644)
293+
if err != nil {
294+
slog.Error("Failed to open log file", "path", cfg.DaemonLogFilePath, "error", err)
295+
} else {
296+
defer logFile.Close() // nolint
297+
logWriter = logFile
298+
}
299+
initLogs(logWriter)
300+
301+
slog.Info("Starting resident daemon", "cfsRoot", cfg.CFSRoot)
302+
303+
ctx, stop := signal.NotifyContext(context.Background(), syscall.SIGINT, syscall.SIGTERM)
304+
defer stop()
305+
306+
if err := server.StartResident(ctx); err != nil {
307+
slog.Error("Resident server error", "error", err)
308+
os.Exit(1)
309+
}
310+
311+
slog.Info("Resident daemon shutdown complete")
312+
}
313+
272314
func initLogs(logWriter io.Writer) {
273315
logLevel := config.ParseLogLevel(config.G.LogLevel)
274316
handler := config.NewMultiWriterHandler(logLevel, os.Stdout, logWriter)

0 commit comments

Comments
 (0)