Skip to content

Commit b286acd

Browse files
dangraclaude
andcommitted
Add MachineRootfs type with SizeGB field
Add MachineRootfs struct with Persist and SizeGB fields, add Rootfs field to MachineConfig, and deprecate MachineGuest.PersistRootfs. Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
1 parent db3fb95 commit b286acd

File tree

2 files changed

+86
-7
lines changed

2 files changed

+86
-7
lines changed

machine_types.go

Lines changed: 15 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -414,6 +414,11 @@ func (mpr *MachinePersistRootfs) UnmarshalJSON(raw []byte) error {
414414
return nil
415415
}
416416

417+
type MachineRootfs struct {
418+
Persist MachinePersistRootfs `toml:"persist,omitempty" json:"persist,omitempty" enums:"never,always,restart"`
419+
SizeGB uint64 `toml:"size_gb,omitempty" json:"size_gb,omitempty"`
420+
}
421+
417422
// @description The Machine restart policy defines whether and how flyd restarts a Machine after its main process exits. See https://fly.io/docs/machines/guides-examples/machine-restart-policy/.
418423
type MachineRestart struct {
419424
// * no - Never try to restart a Machine automatically when its main process exits, whether that’s on purpose or on a crash.
@@ -439,13 +444,14 @@ type MachineMount struct {
439444
}
440445

441446
type MachineGuest struct {
442-
CPUKind string `toml:"cpu_kind,omitempty" json:"cpu_kind,omitempty"`
443-
CPUs int `toml:"cpus,omitempty" json:"cpus,omitempty"`
444-
MemoryMB int `toml:"memory_mb,omitempty" json:"memory_mb,omitempty"`
445-
GPUs int `toml:"gpus,omitempty" json:"gpus,omitempty"`
446-
GPUKind string `toml:"gpu_kind,omitempty" json:"gpu_kind,omitempty"`
447-
HostDedicationID string `toml:"host_dedication_id,omitempty" json:"host_dedication_id,omitempty"`
448-
PersistRootfs MachinePersistRootfs `toml:"persist_rootfs,omitempty" json:"persist_rootfs,omitempty" enums:"never,always,restart"`
447+
CPUKind string `toml:"cpu_kind,omitempty" json:"cpu_kind,omitempty"`
448+
CPUs int `toml:"cpus,omitempty" json:"cpus,omitempty"`
449+
MemoryMB int `toml:"memory_mb,omitempty" json:"memory_mb,omitempty"`
450+
GPUs int `toml:"gpus,omitempty" json:"gpus,omitempty"`
451+
GPUKind string `toml:"gpu_kind,omitempty" json:"gpu_kind,omitempty"`
452+
HostDedicationID string `toml:"host_dedication_id,omitempty" json:"host_dedication_id,omitempty"`
453+
// Deprecated: use MachineConfig.Rootfs instead
454+
PersistRootfs MachinePersistRootfs `toml:"persist_rootfs,omitempty" json:"persist_rootfs,omitempty" enums:"never,always,restart"`
449455

450456
KernelArgs []string `toml:"kernel_args,omitempty" json:"kernel_args,omitempty"`
451457
}
@@ -804,6 +810,8 @@ type MachineConfig struct {
804810
// with containers
805811
Volumes []*VolumeConfig `toml:"volumes,omitempty" json:"volumes,omitempty"`
806812

813+
Rootfs *MachineRootfs `toml:"rootfs,omitempty" json:"rootfs,omitempty"`
814+
807815
// Deprecated: use Guest instead
808816
VMSize string `toml:"size,omitempty" json:"size,omitempty"`
809817
// Deprecated: use Service.Autostart instead

machine_types_test.go

Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -303,6 +303,77 @@ func TestMachinePersistRootfsUnmarshalJSON(t *testing.T) {
303303
}
304304
}
305305

306+
func TestMachineRootfsJSON(t *testing.T) {
307+
t.Run("marshal", func(t *testing.T) {
308+
cases := []struct {
309+
name string
310+
input MachineConfig
311+
output string
312+
}{
313+
{
314+
name: "rootfs with persist and size",
315+
input: MachineConfig{Rootfs: &MachineRootfs{Persist: MachinePersistRootfsAlways, SizeGB: 10}},
316+
output: `{"init":{},"rootfs":{"persist":"always","size_gb":10}}`,
317+
},
318+
{
319+
name: "rootfs with persist only",
320+
input: MachineConfig{Rootfs: &MachineRootfs{Persist: MachinePersistRootfsRestart}},
321+
output: `{"init":{},"rootfs":{"persist":"restart"}}`,
322+
},
323+
{
324+
name: "nil rootfs omitted",
325+
input: MachineConfig{},
326+
output: `{"init":{}}`,
327+
},
328+
}
329+
for _, tc := range cases {
330+
b, err := json.Marshal(tc.input)
331+
if err != nil {
332+
t.Errorf("%s: unexpected error: %v", tc.name, err)
333+
} else if string(b) != tc.output {
334+
t.Errorf("%s: got %s, want %s", tc.name, string(b), tc.output)
335+
}
336+
}
337+
})
338+
339+
t.Run("unmarshal", func(t *testing.T) {
340+
cases := []struct {
341+
name string
342+
input string
343+
persist MachinePersistRootfs
344+
sizeGB uint64
345+
}{
346+
{"persist and size", `{"rootfs":{"persist":"always","size_gb":10}}`, MachinePersistRootfsAlways, 10},
347+
{"persist only", `{"rootfs":{"persist":"restart"}}`, MachinePersistRootfsRestart, 0},
348+
{"size only", `{"rootfs":{"size_gb":5}}`, MachinePersistRootfsNone, 5},
349+
{"no rootfs", `{}`, MachinePersistRootfsNone, 0},
350+
}
351+
for _, tc := range cases {
352+
var mc MachineConfig
353+
if err := json.Unmarshal([]byte(tc.input), &mc); err != nil {
354+
t.Errorf("%s: unexpected error: %v", tc.name, err)
355+
continue
356+
}
357+
if tc.persist == MachinePersistRootfsNone && tc.sizeGB == 0 {
358+
if mc.Rootfs != nil {
359+
t.Errorf("%s: expected nil rootfs, got %+v", tc.name, mc.Rootfs)
360+
}
361+
continue
362+
}
363+
if mc.Rootfs == nil {
364+
t.Errorf("%s: expected non-nil rootfs", tc.name)
365+
continue
366+
}
367+
if mc.Rootfs.Persist != tc.persist {
368+
t.Errorf("%s: persist got %v, want %v", tc.name, mc.Rootfs.Persist, tc.persist)
369+
}
370+
if mc.Rootfs.SizeGB != tc.sizeGB {
371+
t.Errorf("%s: size_gb got %d, want %d", tc.name, mc.Rootfs.SizeGB, tc.sizeGB)
372+
}
373+
}
374+
})
375+
}
376+
306377
func TestMachineAutostopUnmarshalJSON(t *testing.T) {
307378
type testcase struct {
308379
input string

0 commit comments

Comments
 (0)