Skip to content

Commit 12cfb4e

Browse files
feat: Better stop behavior
1 parent 8ce4014 commit 12cfb4e

4 files changed

Lines changed: 49 additions & 11 deletions

File tree

.stats.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
11
configured_endpoints: 37
2-
openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/kernel%2Fhypeman-517b6ad15b7de0b84f157cdace2d86d68a3514807731c22dc69bac5668fc7b73.yml
3-
openapi_spec_hash: 8e42a75b55ee207d38d47988a1a6cd90
2+
openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/kernel%2Fhypeman-fa1e2bdf81a0cf5ecd0c01200b07d0bc08861f834b539c751aa0fec0496fdf2c.yml
3+
openapi_spec_hash: c70af233ec40cdc23b9a2886b508905e
44
config_hash: d452c139da1e46a44a68b91e8a40de72

api.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ Methods:
4242
- <code title="get /instances/{id}/logs">client.Instances.<a href="https://pkg.go.dev/github.com/kernel/hypeman-go#InstanceService.Logs">Logs</a>(ctx <a href="https://pkg.go.dev/context">context</a>.<a href="https://pkg.go.dev/context#Context">Context</a>, id <a href="https://pkg.go.dev/builtin#string">string</a>, query <a href="https://pkg.go.dev/github.com/kernel/hypeman-go">hypeman</a>.<a href="https://pkg.go.dev/github.com/kernel/hypeman-go#InstanceLogsParams">InstanceLogsParams</a>) (\*<a href="https://pkg.go.dev/builtin#string">string</a>, <a href="https://pkg.go.dev/builtin#error">error</a>)</code>
4343
- <code title="post /instances/{id}/restore">client.Instances.<a href="https://pkg.go.dev/github.com/kernel/hypeman-go#InstanceService.Restore">Restore</a>(ctx <a href="https://pkg.go.dev/context">context</a>.<a href="https://pkg.go.dev/context#Context">Context</a>, id <a href="https://pkg.go.dev/builtin#string">string</a>) (\*<a href="https://pkg.go.dev/github.com/kernel/hypeman-go">hypeman</a>.<a href="https://pkg.go.dev/github.com/kernel/hypeman-go#Instance">Instance</a>, <a href="https://pkg.go.dev/builtin#error">error</a>)</code>
4444
- <code title="post /instances/{id}/standby">client.Instances.<a href="https://pkg.go.dev/github.com/kernel/hypeman-go#InstanceService.Standby">Standby</a>(ctx <a href="https://pkg.go.dev/context">context</a>.<a href="https://pkg.go.dev/context#Context">Context</a>, id <a href="https://pkg.go.dev/builtin#string">string</a>) (\*<a href="https://pkg.go.dev/github.com/kernel/hypeman-go">hypeman</a>.<a href="https://pkg.go.dev/github.com/kernel/hypeman-go#Instance">Instance</a>, <a href="https://pkg.go.dev/builtin#error">error</a>)</code>
45-
- <code title="post /instances/{id}/start">client.Instances.<a href="https://pkg.go.dev/github.com/kernel/hypeman-go#InstanceService.Start">Start</a>(ctx <a href="https://pkg.go.dev/context">context</a>.<a href="https://pkg.go.dev/context#Context">Context</a>, id <a href="https://pkg.go.dev/builtin#string">string</a>) (\*<a href="https://pkg.go.dev/github.com/kernel/hypeman-go">hypeman</a>.<a href="https://pkg.go.dev/github.com/kernel/hypeman-go#Instance">Instance</a>, <a href="https://pkg.go.dev/builtin#error">error</a>)</code>
45+
- <code title="post /instances/{id}/start">client.Instances.<a href="https://pkg.go.dev/github.com/kernel/hypeman-go#InstanceService.Start">Start</a>(ctx <a href="https://pkg.go.dev/context">context</a>.<a href="https://pkg.go.dev/context#Context">Context</a>, id <a href="https://pkg.go.dev/builtin#string">string</a>, body <a href="https://pkg.go.dev/github.com/kernel/hypeman-go">hypeman</a>.<a href="https://pkg.go.dev/github.com/kernel/hypeman-go#InstanceStartParams">InstanceStartParams</a>) (\*<a href="https://pkg.go.dev/github.com/kernel/hypeman-go">hypeman</a>.<a href="https://pkg.go.dev/github.com/kernel/hypeman-go#Instance">Instance</a>, <a href="https://pkg.go.dev/builtin#error">error</a>)</code>
4646
- <code title="get /instances/{id}/stat">client.Instances.<a href="https://pkg.go.dev/github.com/kernel/hypeman-go#InstanceService.Stat">Stat</a>(ctx <a href="https://pkg.go.dev/context">context</a>.<a href="https://pkg.go.dev/context#Context">Context</a>, id <a href="https://pkg.go.dev/builtin#string">string</a>, query <a href="https://pkg.go.dev/github.com/kernel/hypeman-go">hypeman</a>.<a href="https://pkg.go.dev/github.com/kernel/hypeman-go#InstanceStatParams">InstanceStatParams</a>) (\*<a href="https://pkg.go.dev/github.com/kernel/hypeman-go">hypeman</a>.<a href="https://pkg.go.dev/github.com/kernel/hypeman-go#PathInfo">PathInfo</a>, <a href="https://pkg.go.dev/builtin#error">error</a>)</code>
4747
- <code title="post /instances/{id}/stop">client.Instances.<a href="https://pkg.go.dev/github.com/kernel/hypeman-go#InstanceService.Stop">Stop</a>(ctx <a href="https://pkg.go.dev/context">context</a>.<a href="https://pkg.go.dev/context#Context">Context</a>, id <a href="https://pkg.go.dev/builtin#string">string</a>) (\*<a href="https://pkg.go.dev/github.com/kernel/hypeman-go">hypeman</a>.<a href="https://pkg.go.dev/github.com/kernel/hypeman-go#Instance">Instance</a>, <a href="https://pkg.go.dev/builtin#error">error</a>)</code>
4848

instance.go

Lines changed: 31 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -133,14 +133,14 @@ func (r *InstanceService) Standby(ctx context.Context, id string, opts ...option
133133
}
134134

135135
// Start a stopped instance
136-
func (r *InstanceService) Start(ctx context.Context, id string, opts ...option.RequestOption) (res *Instance, err error) {
136+
func (r *InstanceService) Start(ctx context.Context, id string, body InstanceStartParams, opts ...option.RequestOption) (res *Instance, err error) {
137137
opts = slices.Concat(r.Options, opts)
138138
if id == "" {
139139
err = errors.New("missing required id parameter")
140140
return
141141
}
142142
path := fmt.Sprintf("instances/%s/start", id)
143-
err = requestconfig.ExecuteNewRequest(ctx, http.MethodPost, path, nil, &res, opts...)
143+
err = requestconfig.ExecuteNewRequest(ctx, http.MethodPost, path, body, &res, opts...)
144144
return
145145
}
146146

@@ -195,6 +195,11 @@ type Instance struct {
195195
DiskIoBps string `json:"disk_io_bps"`
196196
// Environment variables
197197
Env map[string]string `json:"env"`
198+
// App exit code (null if VM hasn't exited)
199+
ExitCode int64 `json:"exit_code,nullable"`
200+
// Human-readable description of exit (e.g., "command not found", "killed by signal
201+
// 9 (SIGKILL) - OOM")
202+
ExitMessage string `json:"exit_message"`
198203
// GPU information attached to the instance
199204
GPU InstanceGPU `json:"gpu"`
200205
// Whether a snapshot exists for this instance
@@ -232,6 +237,8 @@ type Instance struct {
232237
State respjson.Field
233238
DiskIoBps respjson.Field
234239
Env respjson.Field
240+
ExitCode respjson.Field
241+
ExitMessage respjson.Field
235242
GPU respjson.Field
236243
HasSnapshot respjson.Field
237244
HotplugSize respjson.Field
@@ -468,8 +475,14 @@ type InstanceNewParams struct {
468475
SkipKernelHeaders param.Opt[bool] `json:"skip_kernel_headers,omitzero"`
469476
// Number of virtual CPUs
470477
Vcpus param.Opt[int64] `json:"vcpus,omitzero"`
478+
// Override image CMD (like docker run <image> <command>). Omit to use image
479+
// default.
480+
Cmd []string `json:"cmd,omitzero"`
471481
// Device IDs or names to attach for GPU/PCI passthrough
472482
Devices []string `json:"devices,omitzero"`
483+
// Override image entrypoint (like docker run --entrypoint). Omit to use image
484+
// default.
485+
Entrypoint []string `json:"entrypoint,omitzero"`
473486
// Environment variables
474487
Env map[string]string `json:"env,omitzero"`
475488
// GPU configuration for the instance
@@ -577,6 +590,22 @@ const (
577590
InstanceLogsParamsSourceHypeman InstanceLogsParamsSource = "hypeman"
578591
)
579592

593+
type InstanceStartParams struct {
594+
// Override image CMD for this run. Omit to keep previous value.
595+
Cmd []string `json:"cmd,omitzero"`
596+
// Override image entrypoint for this run. Omit to keep previous value.
597+
Entrypoint []string `json:"entrypoint,omitzero"`
598+
paramObj
599+
}
600+
601+
func (r InstanceStartParams) MarshalJSON() (data []byte, err error) {
602+
type shadow InstanceStartParams
603+
return param.MarshalObject(r, (*shadow)(&r))
604+
}
605+
func (r *InstanceStartParams) UnmarshalJSON(data []byte) error {
606+
return apijson.UnmarshalRoot(data, r)
607+
}
608+
580609
type InstanceStatParams struct {
581610
// Path to stat in the guest filesystem
582611
Path string `query:"path,required" json:"-"`

instance_test.go

Lines changed: 15 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -27,10 +27,12 @@ func TestInstanceNewWithOptionalParams(t *testing.T) {
2727
option.WithAPIKey("My API Key"),
2828
)
2929
_, err := client.Instances.New(context.TODO(), hypeman.InstanceNewParams{
30-
Image: "docker.io/library/alpine:latest",
31-
Name: "my-workload-1",
32-
Devices: []string{"l4-gpu"},
33-
DiskIoBps: hypeman.String("100MB/s"),
30+
Image: "docker.io/library/alpine:latest",
31+
Name: "my-workload-1",
32+
Cmd: []string{"echo", "hello"},
33+
Devices: []string{"l4-gpu"},
34+
DiskIoBps: hypeman.String("100MB/s"),
35+
Entrypoint: []string{"/bin/sh", "-c"},
3436
Env: map[string]string{
3537
"PORT": "3000",
3638
"NODE_ENV": "production",
@@ -186,7 +188,7 @@ func TestInstanceStandby(t *testing.T) {
186188
}
187189
}
188190

189-
func TestInstanceStart(t *testing.T) {
191+
func TestInstanceStartWithOptionalParams(t *testing.T) {
190192
t.Skip("Prism tests are disabled")
191193
baseURL := "http://localhost:4010"
192194
if envURL, ok := os.LookupEnv("TEST_API_BASE_URL"); ok {
@@ -199,7 +201,14 @@ func TestInstanceStart(t *testing.T) {
199201
option.WithBaseURL(baseURL),
200202
option.WithAPIKey("My API Key"),
201203
)
202-
_, err := client.Instances.Start(context.TODO(), "id")
204+
_, err := client.Instances.Start(
205+
context.TODO(),
206+
"id",
207+
hypeman.InstanceStartParams{
208+
Cmd: []string{"string"},
209+
Entrypoint: []string{"string"},
210+
},
211+
)
203212
if err != nil {
204213
var apierr *hypeman.Error
205214
if errors.As(err, &apierr) {

0 commit comments

Comments
 (0)