@@ -72,6 +72,7 @@ type CLI struct {
7272 Policy PolicyCommand `cmd:"" help:"Policy commands"`
7373 Config ConfigCommand `cmd:"" help:"Runtime config commands"`
7474 Image ImageCommand `cmd:"" help:"Manage OCI image cache artifacts"`
75+ Create CreateCommand `cmd:"" help:"Create a sandbox"`
7576 Exec ExecCommand `cmd:"" help:"Execute a command in a cleanroom backend"`
7677 Console ConsoleCommand `cmd:"" help:"Attach an interactive console to a cleanroom execution"`
7778 Serve ServeCommand `cmd:"" help:"Run the cleanroom control-plane server"`
@@ -168,6 +169,22 @@ type ExecCommand struct {
168169 Command []string `arg:"" passthrough:"" required:"" help:"Command to execute"`
169170}
170171
172+ type SandboxCreateCommand struct {
173+ clientFlags
174+ Chdir string `short:"c" help:"Change to this directory before running commands"`
175+ Backend string `help:"Execution backend (defaults to runtime config or firecracker)"`
176+ LaunchSeconds int64 `help:"VM boot/guest-agent readiness timeout in seconds"`
177+ JSON bool `help:"Print sandbox as JSON"`
178+ }
179+
180+ type CreateCommand struct {
181+ clientFlags
182+ Chdir string `short:"c" help:"Change to this directory before running commands"`
183+ Backend string `help:"Execution backend (defaults to runtime config or firecracker)"`
184+ LaunchSeconds int64 `help:"VM boot/guest-agent readiness timeout in seconds"`
185+ JSON bool `help:"Print sandbox as JSON"`
186+ }
187+
171188type ConsoleCommand struct {
172189 clientFlags
173190 Chdir string `short:"c" help:"Change to this directory before running commands"`
@@ -202,6 +219,7 @@ type DoctorCommand struct {
202219}
203220
204221type SandboxCommand struct {
222+ Create SandboxCreateCommand `cmd:"" help:"Create a sandbox"`
205223 List SandboxListCommand `name:"ls" aliases:"list" cmd:"" help:"List active sandboxes"`
206224 Terminate SandboxTerminateCommand `name:"rm" aliases:"terminate" cmd:"" help:"Terminate a sandbox"`
207225}
@@ -656,6 +674,56 @@ func (c *SandboxTerminateCommand) Run(ctx *runtimeContext) error {
656674 return err
657675}
658676
677+ func runSandboxCreate (ctx * runtimeContext , connectFlags clientFlags , chdir , backend string , launchSeconds int64 , outputJSON bool ) error {
678+ client , err := connectFlags .connect ()
679+ if err != nil {
680+ return err
681+ }
682+
683+ cwd , err := resolveCWD (ctx .CWD , chdir )
684+ if err != nil {
685+ return err
686+ }
687+ compiled , _ , err := ctx .Loader .LoadAndCompile (cwd )
688+ if err != nil {
689+ return err
690+ }
691+
692+ resp , err := client .CreateSandbox (context .Background (), & cleanroomv1.CreateSandboxRequest {
693+ Backend : backend ,
694+ Options : & cleanroomv1.SandboxOptions {
695+ LaunchSeconds : launchSeconds ,
696+ },
697+ Policy : compiled .ToProto (),
698+ })
699+ if err != nil {
700+ return fmt .Errorf ("create sandbox: %w" , err )
701+ }
702+
703+ sandbox := resp .GetSandbox ()
704+ sandboxID := strings .TrimSpace (sandbox .GetSandboxId ())
705+ if sandboxID == "" {
706+ return errors .New ("create sandbox: response missing sandbox id" )
707+ }
708+
709+ if outputJSON {
710+ enc := json .NewEncoder (ctx .Stdout )
711+ enc .SetIndent ("" , " " )
712+ return enc .Encode (sandbox )
713+ }
714+
715+ _ , err = fmt .Fprintln (ctx .Stdout , sandboxID )
716+ return err
717+ }
718+
719+ func (c * SandboxCreateCommand ) Run (ctx * runtimeContext ) error {
720+ return runSandboxCreate (ctx , c .clientFlags , c .Chdir , c .Backend , c .LaunchSeconds , c .JSON )
721+ }
722+
723+ func (c * CreateCommand ) Run (ctx * runtimeContext ) error {
724+ return runSandboxCreate (ctx , c .clientFlags , c .Chdir , c .Backend , c .LaunchSeconds , c .JSON )
725+ }
726+
659727func (e * ExecCommand ) Run (ctx * runtimeContext ) error {
660728 logger , err := newLogger (e .LogLevel , "client" )
661729 if err != nil {
0 commit comments