Skip to content

Commit 4386083

Browse files
feat: Add instance restart policy
1 parent 3f708bf commit 4386083

4 files changed

Lines changed: 162 additions & 4 deletions

File tree

.stats.yml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
11
configured_endpoints: 52
2-
openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/kernel/hypeman-71aee51a5e8c3b045e5f554b096af26c16d76deafb3279fdfceba4349acf1f58.yml
3-
openapi_spec_hash: 5a00e48eb3e384355faf2eb57bd3b6f4
4-
config_hash: 7da023612dfc50a6be53b67f4dc233f2
2+
openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/kernel/hypeman-f9fed11ca56bb499302232ce70b65d8fa6c0f88c5274dbf16670283303449c63.yml
3+
openapi_spec_hash: 24530949a7f53ab57694443c45088190
4+
config_hash: 99e93e381d8384de5a44c6eeed4bd4b1

api.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ Params Types:
3838
- <a href="https://pkg.go.dev/github.com/kernel/hypeman-go">hypeman</a>.<a href="https://pkg.go.dev/github.com/kernel/hypeman-go#HealthCheckExecParam">HealthCheckExecParam</a>
3939
- <a href="https://pkg.go.dev/github.com/kernel/hypeman-go">hypeman</a>.<a href="https://pkg.go.dev/github.com/kernel/hypeman-go#HealthCheckHTTPParam">HealthCheckHTTPParam</a>
4040
- <a href="https://pkg.go.dev/github.com/kernel/hypeman-go">hypeman</a>.<a href="https://pkg.go.dev/github.com/kernel/hypeman-go#HealthCheckTcpParam">HealthCheckTcpParam</a>
41+
- <a href="https://pkg.go.dev/github.com/kernel/hypeman-go">hypeman</a>.<a href="https://pkg.go.dev/github.com/kernel/hypeman-go#RestartPolicyParam">RestartPolicyParam</a>
4142
- <a href="https://pkg.go.dev/github.com/kernel/hypeman-go">hypeman</a>.<a href="https://pkg.go.dev/github.com/kernel/hypeman-go#SetSnapshotScheduleRequestParam">SetSnapshotScheduleRequestParam</a>
4243
- <a href="https://pkg.go.dev/github.com/kernel/hypeman-go">hypeman</a>.<a href="https://pkg.go.dev/github.com/kernel/hypeman-go#SnapshotPolicyParam">SnapshotPolicyParam</a>
4344
- <a href="https://pkg.go.dev/github.com/kernel/hypeman-go">hypeman</a>.<a href="https://pkg.go.dev/github.com/kernel/hypeman-go#SnapshotScheduleRetentionParam">SnapshotScheduleRetentionParam</a>
@@ -56,6 +57,8 @@ Response Types:
5657
- <a href="https://pkg.go.dev/github.com/kernel/hypeman-go">hypeman</a>.<a href="https://pkg.go.dev/github.com/kernel/hypeman-go#InstanceHealthStatus">InstanceHealthStatus</a>
5758
- <a href="https://pkg.go.dev/github.com/kernel/hypeman-go">hypeman</a>.<a href="https://pkg.go.dev/github.com/kernel/hypeman-go#InstanceStats">InstanceStats</a>
5859
- <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>
60+
- <a href="https://pkg.go.dev/github.com/kernel/hypeman-go">hypeman</a>.<a href="https://pkg.go.dev/github.com/kernel/hypeman-go#RestartPolicy">RestartPolicy</a>
61+
- <a href="https://pkg.go.dev/github.com/kernel/hypeman-go">hypeman</a>.<a href="https://pkg.go.dev/github.com/kernel/hypeman-go#RestartStatus">RestartStatus</a>
5962
- <a href="https://pkg.go.dev/github.com/kernel/hypeman-go">hypeman</a>.<a href="https://pkg.go.dev/github.com/kernel/hypeman-go#SnapshotPolicy">SnapshotPolicy</a>
6063
- <a href="https://pkg.go.dev/github.com/kernel/hypeman-go">hypeman</a>.<a href="https://pkg.go.dev/github.com/kernel/hypeman-go#SnapshotSchedule">SnapshotSchedule</a>
6164
- <a href="https://pkg.go.dev/github.com/kernel/hypeman-go">hypeman</a>.<a href="https://pkg.go.dev/github.com/kernel/hypeman-go#SnapshotScheduleRetention">SnapshotScheduleRetention</a>

instance.go

Lines changed: 143 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -690,6 +690,10 @@ type Instance struct {
690690
// initializing, shutdown). Consumers (e.g. billing) sum the phases they consider
691691
// billable.
692692
PhaseDurationsMs map[string]int64 `json:"phase_durations_ms"`
693+
// Whole-instance restart supervision policy.
694+
RestartPolicy RestartPolicy `json:"restart_policy"`
695+
// Runtime status for restart policy decisions.
696+
RestartStatus RestartStatus `json:"restart_status"`
693697
// Base memory size (human-readable)
694698
Size string `json:"size"`
695699
SnapshotPolicy SnapshotPolicy `json:"snapshot_policy"`
@@ -728,6 +732,8 @@ type Instance struct {
728732
Network respjson.Field
729733
OverlaySize respjson.Field
730734
PhaseDurationsMs respjson.Field
735+
RestartPolicy respjson.Field
736+
RestartStatus respjson.Field
731737
Size respjson.Field
732738
SnapshotPolicy respjson.Field
733739
StartedAt respjson.Field
@@ -967,6 +973,139 @@ func (r *PathInfo) UnmarshalJSON(data []byte) error {
967973
return apijson.UnmarshalRoot(data, r)
968974
}
969975

976+
// Whole-instance restart supervision policy.
977+
type RestartPolicy struct {
978+
// Delay before each restart attempt, expressed as a Go duration like "5s" or "1m".
979+
Backoff string `json:"backoff"`
980+
// Consecutive automatic restart attempts before blocking retries. 0 means
981+
// unlimited.
982+
MaxAttempts int64 `json:"max_attempts"`
983+
// Restart behavior when the guest program exits:
984+
//
985+
// - never: do not automatically restart
986+
// - always: restart after any guest exit
987+
// - on_failure: restart only for nonzero, signaled, OOM, or unknown exits
988+
//
989+
// Any of "never", "always", "on_failure".
990+
Policy RestartPolicyPolicy `json:"policy"`
991+
// Running this long resets the consecutive restart attempt count.
992+
StableAfter string `json:"stable_after"`
993+
// JSON contains metadata for fields, check presence with [respjson.Field.Valid].
994+
JSON struct {
995+
Backoff respjson.Field
996+
MaxAttempts respjson.Field
997+
Policy respjson.Field
998+
StableAfter respjson.Field
999+
ExtraFields map[string]respjson.Field
1000+
raw string
1001+
} `json:"-"`
1002+
}
1003+
1004+
// Returns the unmodified JSON received from the API
1005+
func (r RestartPolicy) RawJSON() string { return r.JSON.raw }
1006+
func (r *RestartPolicy) UnmarshalJSON(data []byte) error {
1007+
return apijson.UnmarshalRoot(data, r)
1008+
}
1009+
1010+
// ToParam converts this RestartPolicy to a RestartPolicyParam.
1011+
//
1012+
// Warning: the fields of the param type will not be present. ToParam should only
1013+
// be used at the last possible moment before sending a request. Test for this with
1014+
// RestartPolicyParam.Overrides()
1015+
func (r RestartPolicy) ToParam() RestartPolicyParam {
1016+
return param.Override[RestartPolicyParam](json.RawMessage(r.RawJSON()))
1017+
}
1018+
1019+
// Restart behavior when the guest program exits:
1020+
//
1021+
// - never: do not automatically restart
1022+
// - always: restart after any guest exit
1023+
// - on_failure: restart only for nonzero, signaled, OOM, or unknown exits
1024+
type RestartPolicyPolicy string
1025+
1026+
const (
1027+
RestartPolicyPolicyNever RestartPolicyPolicy = "never"
1028+
RestartPolicyPolicyAlways RestartPolicyPolicy = "always"
1029+
RestartPolicyPolicyOnFailure RestartPolicyPolicy = "on_failure"
1030+
)
1031+
1032+
// Whole-instance restart supervision policy.
1033+
type RestartPolicyParam struct {
1034+
// Delay before each restart attempt, expressed as a Go duration like "5s" or "1m".
1035+
Backoff param.Opt[string] `json:"backoff,omitzero"`
1036+
// Consecutive automatic restart attempts before blocking retries. 0 means
1037+
// unlimited.
1038+
MaxAttempts param.Opt[int64] `json:"max_attempts,omitzero"`
1039+
// Running this long resets the consecutive restart attempt count.
1040+
StableAfter param.Opt[string] `json:"stable_after,omitzero"`
1041+
// Restart behavior when the guest program exits:
1042+
//
1043+
// - never: do not automatically restart
1044+
// - always: restart after any guest exit
1045+
// - on_failure: restart only for nonzero, signaled, OOM, or unknown exits
1046+
//
1047+
// Any of "never", "always", "on_failure".
1048+
Policy RestartPolicyPolicy `json:"policy,omitzero"`
1049+
paramObj
1050+
}
1051+
1052+
func (r RestartPolicyParam) MarshalJSON() (data []byte, err error) {
1053+
type shadow RestartPolicyParam
1054+
return param.MarshalObject(r, (*shadow)(&r))
1055+
}
1056+
func (r *RestartPolicyParam) UnmarshalJSON(data []byte) error {
1057+
return apijson.UnmarshalRoot(data, r)
1058+
}
1059+
1060+
// Runtime status for restart policy decisions.
1061+
type RestartStatus struct {
1062+
// Consecutive automatic restart attempts in the current failure window.
1063+
Attempts int64 `json:"attempts"`
1064+
// Reason automatic restarts are currently blocked.
1065+
//
1066+
// Any of "manual_stop", "max_attempts_exceeded".
1067+
BlockedReason RestartStatusBlockedReason `json:"blocked_reason" api:"nullable"`
1068+
// Last time Hypeman attempted an automatic restart.
1069+
LastAttemptAt time.Time `json:"last_attempt_at" api:"nullable" format:"date-time"`
1070+
// Most recent non-exit failure signal that entered restart policy.
1071+
//
1072+
// Any of "health_check_failed".
1073+
LastReason RestartStatusLastReason `json:"last_reason" api:"nullable"`
1074+
// Next scheduled automatic restart attempt after backoff.
1075+
NextAttemptAt time.Time `json:"next_attempt_at" api:"nullable" format:"date-time"`
1076+
// JSON contains metadata for fields, check presence with [respjson.Field.Valid].
1077+
JSON struct {
1078+
Attempts respjson.Field
1079+
BlockedReason respjson.Field
1080+
LastAttemptAt respjson.Field
1081+
LastReason respjson.Field
1082+
NextAttemptAt respjson.Field
1083+
ExtraFields map[string]respjson.Field
1084+
raw string
1085+
} `json:"-"`
1086+
}
1087+
1088+
// Returns the unmodified JSON received from the API
1089+
func (r RestartStatus) RawJSON() string { return r.JSON.raw }
1090+
func (r *RestartStatus) UnmarshalJSON(data []byte) error {
1091+
return apijson.UnmarshalRoot(data, r)
1092+
}
1093+
1094+
// Reason automatic restarts are currently blocked.
1095+
type RestartStatusBlockedReason string
1096+
1097+
const (
1098+
RestartStatusBlockedReasonManualStop RestartStatusBlockedReason = "manual_stop"
1099+
RestartStatusBlockedReasonMaxAttemptsExceeded RestartStatusBlockedReason = "max_attempts_exceeded"
1100+
)
1101+
1102+
// Most recent non-exit failure signal that entered restart policy.
1103+
type RestartStatusLastReason string
1104+
1105+
const (
1106+
RestartStatusLastReasonHealthCheckFailed RestartStatusLastReason = "health_check_failed"
1107+
)
1108+
9701109
// The properties Interval, Retention are required.
9711110
type SetSnapshotScheduleRequestParam struct {
9721111
// Snapshot interval (Go duration format, minimum 1m).
@@ -1309,6 +1448,8 @@ type InstanceNewParams struct {
13091448
Hypervisor InstanceNewParamsHypervisor `json:"hypervisor,omitzero"`
13101449
// Network configuration for the instance
13111450
Network InstanceNewParamsNetwork `json:"network,omitzero"`
1451+
// Whole-instance restart supervision policy.
1452+
RestartPolicy RestartPolicyParam `json:"restart_policy,omitzero"`
13121453
// Snapshot policy for this instance. Controls compression settings applied when
13131454
// creating snapshots or entering standby, plus any default standby-only
13141455
// compression delay.
@@ -1505,6 +1646,8 @@ type InstanceUpdateParams struct {
15051646
// Workload health check policy. Health is reported separately from instance
15061647
// lifecycle state.
15071648
HealthCheck HealthCheckParam `json:"health_check,omitzero"`
1649+
// Whole-instance restart supervision policy.
1650+
RestartPolicy RestartPolicyParam `json:"restart_policy,omitzero"`
15081651
paramObj
15091652
}
15101653

instance_test.go

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -95,7 +95,13 @@ func TestInstanceNewWithOptionalParams(t *testing.T) {
9595
},
9696
Enabled: hypeman.Bool(true),
9797
},
98-
OverlaySize: hypeman.String("20GB"),
98+
OverlaySize: hypeman.String("20GB"),
99+
RestartPolicy: hypeman.RestartPolicyParam{
100+
Backoff: hypeman.String("5s"),
101+
MaxAttempts: hypeman.Int(10),
102+
Policy: hypeman.RestartPolicyPolicyOnFailure,
103+
StableAfter: hypeman.String("10m"),
104+
},
99105
Size: hypeman.String("2GB"),
100106
SkipGuestAgent: hypeman.Bool(false),
101107
SkipKernelHeaders: hypeman.Bool(true),
@@ -176,6 +182,12 @@ func TestInstanceUpdateWithOptionalParams(t *testing.T) {
176182
Timeout: hypeman.String("2s"),
177183
Type: hypeman.HealthCheckTypeNone,
178184
},
185+
RestartPolicy: hypeman.RestartPolicyParam{
186+
Backoff: hypeman.String("5s"),
187+
MaxAttempts: hypeman.Int(10),
188+
Policy: hypeman.RestartPolicyPolicyOnFailure,
189+
StableAfter: hypeman.String("10m"),
190+
},
179191
},
180192
)
181193
if err != nil {

0 commit comments

Comments
 (0)