forked from wrenn/wrenn
Add USER, COPY, ENV persistence to template build system
Implement three new recipe commands for the admin template builder: - USER <name>: creates the user (adduser + passwordless sudo), switches execution context so subsequent RUN/START commands run as that user via su wrapping. Last USER becomes the template's default_user. - COPY <src> <dst>: copies files from an uploaded build archive (tar/tar.gz/zip) into the sandbox. Source paths validated against traversal. Ownership set to the current USER. - ENV persistence: accumulated env vars stored in templates.default_env (JSONB) and injected via PostInit when sandboxes are created from the template, mirroring Docker's image metadata approach. Supporting changes: - Pre-build creates wrenn-user as default (via USER command) - WORKDIR now creates the directory if it doesn't exist (mkdir -p) - Per-step progress updates (ProgressFunc callback) for live UI - Multipart form support on POST /v1/admin/builds for archive upload - Proto: default_user/default_env fields on Create/ResumeSandboxRequest - Host agent: SetDefaults calls PostInitWithDefaults on envd - Control plane: reads template defaults, passes on sandbox create/resume - Frontend: file upload widget, recipe copy button, keyword colors for USER/COPY, fixed Svelte whitespace stripping in step display - Admin panel defaults to /admin/templates instead of /admin/hosts - Migration adds default_user and default_env to templates and template_builds tables
This commit is contained in:
@ -111,16 +111,37 @@ func TestParseStep(t *testing.T) {
|
||||
input: "WORKDIR",
|
||||
wantErr: true,
|
||||
},
|
||||
// USER and COPY stubs
|
||||
// USER
|
||||
{
|
||||
name: "USER stub",
|
||||
name: "USER basic",
|
||||
input: "USER www-data",
|
||||
want: Step{Kind: KindUSER, Raw: "USER www-data"},
|
||||
want: Step{Kind: KindUSER, Raw: "USER www-data", Key: "www-data"},
|
||||
},
|
||||
{
|
||||
name: "COPY stub",
|
||||
name: "USER empty",
|
||||
input: "USER",
|
||||
wantErr: true,
|
||||
},
|
||||
{
|
||||
name: "USER invalid chars",
|
||||
input: "USER bad user",
|
||||
wantErr: true,
|
||||
},
|
||||
// COPY
|
||||
{
|
||||
name: "COPY basic",
|
||||
input: "COPY config.yaml /etc/app/config.yaml",
|
||||
want: Step{Kind: KindCOPY, Raw: "COPY config.yaml /etc/app/config.yaml"},
|
||||
want: Step{Kind: KindCOPY, Raw: "COPY config.yaml /etc/app/config.yaml", Src: "config.yaml", Dst: "/etc/app/config.yaml"},
|
||||
},
|
||||
{
|
||||
name: "COPY missing dst",
|
||||
input: "COPY config.yaml",
|
||||
wantErr: true,
|
||||
},
|
||||
{
|
||||
name: "COPY empty",
|
||||
input: "COPY",
|
||||
wantErr: true,
|
||||
},
|
||||
// Unknown keyword
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user