diff --git a/.github/actions/build-sandbox-template/action.yml b/.github/actions/build-sandbox-template/action.yml index c4aee77de9..48c3f96958 100644 --- a/.github/actions/build-sandbox-template/action.yml +++ b/.github/actions/build-sandbox-template/action.yml @@ -8,7 +8,7 @@ runs: env: TEMPLATE_ID: "2j6ly824owf4awgai1xo" KERNEL_VERSION: "vmlinux-6.1.158" - FIRECRACKER_VERSION: "v1.12.1_a41d3fb" + FIRECRACKER_VERSION: "v1.14.1_aa14c57" run: | # Generate an unique build ID for the template for this run export BUILD_ID=$(uuidgen) diff --git a/packages/api/internal/sandbox/sandbox_features.go b/packages/api/internal/sandbox/sandbox_features.go index e8eb0e7d0d..cf3fb933a8 100644 --- a/packages/api/internal/sandbox/sandbox_features.go +++ b/packages/api/internal/sandbox/sandbox_features.go @@ -39,7 +39,15 @@ func (v *VersionInfo) Version() semver.Version { } func (v *VersionInfo) HasHugePages() bool { - if v.lastReleaseVersion.Major() >= 1 && v.lastReleaseVersion.Minor() >= 7 { + if v.lastReleaseVersion.Major() == 1 && v.lastReleaseVersion.Minor() >= 7 { + return true + } + + return false +} + +func (v *VersionInfo) HasFreePageReporting() bool { + if v.lastReleaseVersion.Major() == 1 && v.lastReleaseVersion.Minor() >= 14 { return true } diff --git a/packages/api/internal/template-manager/create_template.go b/packages/api/internal/template-manager/create_template.go index 9e5ac7224e..373313982a 100644 --- a/packages/api/internal/template-manager/create_template.go +++ b/packages/api/internal/template-manager/create_template.go @@ -109,6 +109,8 @@ func (tm *TemplateManager) CreateTemplate( return fmt.Errorf("failed to convert image registry: %w", err) } + freePageReporting := features.HasFreePageReporting() + template := &templatemanagergrpc.TemplateConfig{ TeamID: teamID.String(), TemplateID: templateID, @@ -119,6 +121,7 @@ func (tm *TemplateManager) CreateTemplate( KernelVersion: kernelVersion, FirecrackerVersion: firecrackerVersion, HugePages: features.HasHugePages(), + FreePageReporting: &freePageReporting, StartCommand: startCmd, ReadyCommand: readyCmd, Force: force, diff --git a/packages/orchestrator/README.md b/packages/orchestrator/README.md index 498d21be3d..a0e2d9ab81 100644 --- a/packages/orchestrator/README.md +++ b/packages/orchestrator/README.md @@ -36,7 +36,7 @@ Flags: - `-template ` - Template ID (default: `local-template`) - `-storage ` - Local path or `gs://bucket` (enables local mode with auto-download of kernel/FC) - `-kernel ` - Kernel version (default: `vmlinux-6.1.102`) -- `-firecracker ` - Firecracker version (default: `v1.12.1_a41d3fb`) +- `-firecracker ` - Firecracker version (default: `v1.14.1_aa14c57`) - `-vcpu ` - vCPUs (default: `1`) - `-memory ` - Memory in MB (default: `512`) - `-disk ` - Disk in MB (default: `1000`) diff --git a/packages/orchestrator/cmd/create-build/main.go b/packages/orchestrator/cmd/create-build/main.go index 9b95714c54..b6d2c30929 100644 --- a/packages/orchestrator/cmd/create-build/main.go +++ b/packages/orchestrator/cmd/create-build/main.go @@ -59,6 +59,7 @@ func main() { memory := flag.Int("memory", 1024, "memory MB") disk := flag.Int("disk", 1024, "disk MB") hugePages := flag.Bool("hugepages", true, "use 2MB huge pages for memory (false = 4KB pages)") + freePageReporting := flag.Bool("free-page-reporting", false, "enable free page reporting via balloon device (requires Firecracker v1.14+)") startCmd := flag.String("start-cmd", "", "start command") setupCmd := flag.String("setup-cmd", "", "setup command to run during build (e.g., install deps)") readyCmd := flag.String("ready-cmd", "", "ready check command") @@ -96,7 +97,16 @@ func main() { log.Fatalf("network config: %v", err) } - err = doBuild(ctx, *templateID, *toBuild, *fromBuild, *kernel, *fc, *vcpu, *memory, *disk, *hugePages, *startCmd, *setupCmd, *readyCmd, localMode, *verbose, *timeout, builderConfig, networkConfig) + // Detect if --free-page-reporting was explicitly set; if not, pass nil so + // doBuild can default based on the Firecracker version. + var fprOverride *bool + flag.Visit(func(f *flag.Flag) { + if f.Name == "free-page-reporting" { + fprOverride = freePageReporting + } + }) + + err = doBuild(ctx, *templateID, *toBuild, *fromBuild, *kernel, *fc, *vcpu, *memory, *disk, *hugePages, fprOverride, *startCmd, *setupCmd, *readyCmd, localMode, *verbose, *timeout, builderConfig, networkConfig) if err != nil { log.Fatal(err) } @@ -174,9 +184,10 @@ func setupEnv(ctx context.Context, storagePath, kernel, fc string, localMode boo func doBuild( parentCtx context.Context, - templateID, buildID, fromBuild, kernel, fc string, + templateID, buildID, fromBuild, kernel, fcVersion string, vcpu, memory, disk int, hugePages bool, + freePageReporting *bool, startCmd, setupCmd, readyCmd string, localMode, verbose bool, timeout int, @@ -316,6 +327,18 @@ func doBuild( }) } + // Default FPR to enabled when the FC version supports it (v1.14+); explicit flag overrides. + var fprEnabled bool + if freePageReporting != nil { + fprEnabled = *freePageReporting + } else { + versionOnly, _, _ := strings.Cut(fcVersion, "_") + supported, err := utils.IsGTEVersion(versionOnly, "v1.14.0") + if err == nil { + fprEnabled = supported + } + } + tmpl := config.TemplateConfig{ Version: templates.TemplateV2LatestVersion, TemplateID: templateID, @@ -324,10 +347,11 @@ func doBuild( MemoryMB: int64(memory), DiskSizeMB: int64(disk), HugePages: hugePages, + FreePageReporting: fprEnabled, StartCmd: startCmd, ReadyCmd: readyCmd, KernelVersion: kernel, - FirecrackerVersion: fc, + FirecrackerVersion: fcVersion, Steps: steps, } diff --git a/packages/orchestrator/internal/portmap/recover.go b/packages/orchestrator/internal/portmap/recover.go index dcdadc0e45..a688f1bd00 100644 --- a/packages/orchestrator/internal/portmap/recover.go +++ b/packages/orchestrator/internal/portmap/recover.go @@ -58,7 +58,7 @@ func (h *recovery) PMAPPROC_CALLIT(args rfc1057.Call_args) rfc1057.Call_result { } func (h *recovery) tryRecovery(name string) { - if r := recover(); r != nil { //nolint:revive // recover is called from a deferred named function, which is valid Go + if r := recover(); r != nil { //nolint:revive // recover works fine — always called via defer logger.L().Error(h.ctx, fmt.Sprintf("panic in %q portmap handler", name), zap.Any("panic", r)) } } diff --git a/packages/orchestrator/internal/sandbox/block/tracker.go b/packages/orchestrator/internal/sandbox/block/tracker.go deleted file mode 100644 index 7cd21a562b..0000000000 --- a/packages/orchestrator/internal/sandbox/block/tracker.go +++ /dev/null @@ -1,80 +0,0 @@ -package block - -import ( - "iter" - "sync" - - "github.com/bits-and-blooms/bitset" - - "github.com/e2b-dev/infra/packages/shared/pkg/storage/header" - "github.com/e2b-dev/infra/packages/shared/pkg/utils" -) - -type Tracker struct { - b *bitset.BitSet - mu sync.RWMutex - - blockSize int64 -} - -func NewTracker(blockSize int64) *Tracker { - return &Tracker{ - // The bitset resizes automatically based on the maximum set bit. - b: bitset.New(0), - blockSize: blockSize, - } -} - -func (t *Tracker) Has(off int64) bool { - t.mu.RLock() - defer t.mu.RUnlock() - - return t.b.Test(uint(header.BlockIdx(off, t.blockSize))) -} - -func (t *Tracker) Add(off int64) { - t.mu.Lock() - defer t.mu.Unlock() - - t.b.Set(uint(header.BlockIdx(off, t.blockSize))) -} - -func (t *Tracker) Reset() { - t.mu.Lock() - defer t.mu.Unlock() - - t.b.ClearAll() -} - -// BitSet returns the bitset. -// This is not safe to use concurrently. -func (t *Tracker) BitSet() *bitset.BitSet { - return t.b -} - -func (t *Tracker) BlockSize() int64 { - return t.blockSize -} - -func (t *Tracker) Clone() *Tracker { - t.mu.RLock() - defer t.mu.RUnlock() - - return &Tracker{ - b: t.b.Clone(), - blockSize: t.BlockSize(), - } -} - -func (t *Tracker) Offsets() iter.Seq[int64] { - t.mu.RLock() - defer t.mu.RUnlock() - - return bitsetOffsets(t.b.Clone(), t.BlockSize()) -} - -func bitsetOffsets(b *bitset.BitSet, blockSize int64) iter.Seq[int64] { - return utils.TransformTo(b.EachSet(), func(idx uint) int64 { - return header.BlockOffset(int64(idx), blockSize) - }) -} diff --git a/packages/orchestrator/internal/sandbox/block/tracker_test.go b/packages/orchestrator/internal/sandbox/block/tracker_test.go deleted file mode 100644 index f872baad93..0000000000 --- a/packages/orchestrator/internal/sandbox/block/tracker_test.go +++ /dev/null @@ -1,173 +0,0 @@ -package block - -import ( - "maps" - "math/rand" - "slices" - "testing" - - "github.com/stretchr/testify/assert" -) - -func TestTracker_AddAndHas(t *testing.T) { - t.Parallel() - const pageSize = 4096 - tr := NewTracker(pageSize) - - offset := int64(pageSize * 4) - - // Initially should not be marked - assert.False(t, tr.Has(offset), "Expected offset %d not to be marked initially", offset) - - // After adding, should be marked - tr.Add(offset) - assert.True(t, tr.Has(offset), "Expected offset %d to be marked after Add", offset) - - // Other offsets should not be marked - otherOffsets := []int64{ - 0, pageSize, 2 * pageSize, 3 * pageSize, 5 * pageSize, 10 * pageSize, - } - for _, other := range otherOffsets { - if other == offset { - continue - } - assert.False(t, tr.Has(other), "Did not expect offset %d to be marked (only %d should be marked)", other, offset) - } -} - -func TestTracker_Reset(t *testing.T) { - t.Parallel() - const pageSize = 4096 - tr := NewTracker(pageSize) - - offset := int64(pageSize * 4) - - // Add offset and verify it's marked - tr.Add(offset) - assert.True(t, tr.Has(offset), "Expected offset %d to be marked after Add", offset) - - // After reset, should not be marked - tr.Reset() - assert.False(t, tr.Has(offset), "Expected offset %d to be cleared after Reset", offset) - - // Offsets that were never set should also remain unset - otherOffsets := []int64{0, pageSize, 2 * pageSize, pageSize * 10} - for _, other := range otherOffsets { - assert.False(t, tr.Has(other), "Expected offset %d to not be marked after Reset", other) - } -} - -func TestTracker_MultipleOffsets(t *testing.T) { - t.Parallel() - const pageSize = 4096 - tr := NewTracker(pageSize) - - offsets := []int64{0, pageSize, 2 * pageSize, 10 * pageSize} - - // Add multiple offsets - for _, o := range offsets { - tr.Add(o) - } - - // Verify all offsets are marked - for _, o := range offsets { - assert.True(t, tr.Has(o), "Expected offset %d to be marked", o) - } - - // Check offsets in between added offsets are not set - // (Offsets that aren't inside any marked block should not be marked) - nonSetOffsets := []int64{ - 3 * pageSize, - 4 * pageSize, - 5 * pageSize, - 6 * pageSize, - 7 * pageSize, - 8 * pageSize, - 9 * pageSize, - 11 * pageSize, - } - for _, off := range nonSetOffsets { - assert.False(t, tr.Has(off), "Expected offset %d to not be marked (only explicit blocks added)", off) - } -} - -func TestTracker_ResetClearsAll(t *testing.T) { - t.Parallel() - const pageSize = 4096 - tr := NewTracker(pageSize) - - offsets := []int64{0, pageSize, 2 * pageSize, 10 * pageSize} - - // Add multiple offsets - for _, o := range offsets { - tr.Add(o) - } - - // Reset should clear all - tr.Reset() - - // Verify all offsets are cleared - for _, o := range offsets { - assert.False(t, tr.Has(o), "Expected offset %d to be cleared after Reset", o) - } - // Check unrelated offsets also not marked - moreOffsets := []int64{3 * pageSize, 7 * pageSize, 100, 4095} - for _, o := range moreOffsets { - assert.False(t, tr.Has(o), "Expected offset %d to not be marked after Reset", o) - } -} - -func TestTracker_MisalignedOffset(t *testing.T) { - t.Parallel() - const pageSize = 4096 - tr := NewTracker(pageSize) - - // Test with misaligned offset - misalignedOffset := int64(123) - tr.Add(misalignedOffset) - - // Should be set for the block containing the offset—that is, block 0 (0..4095) - assert.True(t, tr.Has(misalignedOffset), "Expected misaligned offset %d to be marked (should mark its containing block)", misalignedOffset) - - // Now check that any offset in the same block is also considered marked - anotherOffsetInSameBlock := int64(1000) - assert.True(t, tr.Has(anotherOffsetInSameBlock), "Expected offset %d to be marked as in same block as %d", anotherOffsetInSameBlock, misalignedOffset) - - // But not for a different block - offsetInNextBlock := int64(pageSize) - assert.False(t, tr.Has(offsetInNextBlock), "Did not expect offset %d to be marked", offsetInNextBlock) - - // And not far outside any set block - offsetFar := int64(2 * pageSize) - assert.False(t, tr.Has(offsetFar), "Did not expect offset %d to be marked", offsetFar) -} - -func TestTracker_Offsets(t *testing.T) { - t.Parallel() - const pageSize = 4096 - tr := NewTracker(pageSize) - - numOffsets := 300 - - offsetsMap := map[int64]struct{}{} - - for range numOffsets { - select { - case <-t.Context().Done(): - t.FailNow() - default: - } - - base := int64(rand.Intn(121)) // 0..120 - offset := base * pageSize - - offsetsMap[offset] = struct{}{} - tr.Add(offset) - } - - expectedOffsets := slices.Collect(maps.Keys(offsetsMap)) - actualOffsets := slices.Collect(tr.Offsets()) - - assert.Len(t, actualOffsets, len(expectedOffsets)) - assert.ElementsMatch(t, expectedOffsets, actualOffsets) -} diff --git a/packages/orchestrator/internal/sandbox/fc/client.go b/packages/orchestrator/internal/sandbox/fc/client.go index 9aec93d236..4ebd3e3212 100644 --- a/packages/orchestrator/internal/sandbox/fc/client.go +++ b/packages/orchestrator/internal/sandbox/fc/client.go @@ -389,6 +389,30 @@ func (c *apiClient) startVM(ctx context.Context) error { return nil } +func (c *apiClient) enableFreePageReporting(ctx context.Context) error { + ctx, span := tracer.Start(ctx, "enable-free-page-reporting") + defer span.End() + + amountMib := int64(0) + deflateOnOom := false + + balloonConfig := operations.PutBalloonParams{ + Context: ctx, + Body: &models.Balloon{ + AmountMib: &amountMib, + DeflateOnOom: &deflateOnOom, + FreePageReporting: true, + }, + } + + _, err := c.client.Operations.PutBalloon(&balloonConfig) + if err != nil { + return fmt.Errorf("error setting up balloon device: %w", err) + } + + return nil +} + func (c *apiClient) memoryMapping(ctx context.Context) (*memory.Mapping, error) { params := operations.GetMemoryMappingsParams{ Context: ctx, diff --git a/packages/orchestrator/internal/sandbox/fc/process.go b/packages/orchestrator/internal/sandbox/fc/process.go index 11a04b6495..bd1d6c24f8 100644 --- a/packages/orchestrator/internal/sandbox/fc/process.go +++ b/packages/orchestrator/internal/sandbox/fc/process.go @@ -299,6 +299,7 @@ func (p *Process) Create( vCPUCount int64, memoryMB int64, hugePages bool, + freePageReporting bool, options ProcessOptions, txRateLimit TxRateLimiterConfig, cgroupFD int, @@ -437,6 +438,16 @@ func (p *Process) Create( } telemetry.ReportEvent(ctx, "set fc entropy config") + if freePageReporting { + err = p.client.enableFreePageReporting(ctx) + if err != nil { + fcStopErr := p.Stop(ctx) + + return errors.Join(fmt.Errorf("error enabling free page reporting: %w", err), fcStopErr) + } + telemetry.ReportEvent(ctx, "enabled free page reporting") + } + err = p.client.startVM(ctx) if err != nil { fcStopErr := p.Stop(ctx) diff --git a/packages/orchestrator/internal/sandbox/sandbox.go b/packages/orchestrator/internal/sandbox/sandbox.go index cad07ac37c..8bddd4845b 100644 --- a/packages/orchestrator/internal/sandbox/sandbox.go +++ b/packages/orchestrator/internal/sandbox/sandbox.go @@ -71,6 +71,9 @@ type Config struct { TotalDiskSizeMB int64 HugePages bool + // Enable free page reporting + FreePageReporting bool + Network *orchestrator.SandboxNetworkConfig Envd EnvdMetadata @@ -363,6 +366,7 @@ func (f *Factory) CreateSandbox( config.Vcpu, config.RamMB, config.HugePages, + config.FreePageReporting, processOptions, fc.TxRateLimiterConfig{ Ops: fc.TokenBucketConfig(throttleConfig.Ops), diff --git a/packages/orchestrator/internal/sandbox/uffd/memory/mapping.go b/packages/orchestrator/internal/sandbox/uffd/memory/mapping.go index a9fdc85f36..2872d86276 100644 --- a/packages/orchestrator/internal/sandbox/uffd/memory/mapping.go +++ b/packages/orchestrator/internal/sandbox/uffd/memory/mapping.go @@ -50,15 +50,15 @@ func NewMappingFromFc(regions []*models.GuestMemoryRegionMapping) (*Mapping, err return NewMapping(r), nil } -// GetOffset returns the relative offset and the pagesize of the mapped range for a given address. -func (m *Mapping) GetOffset(hostVirtAddr uintptr) (int64, uintptr, error) { +// GetOffset returns the relative offset of the mapped range for a given address. +func (m *Mapping) GetOffset(hostVirtAddr uintptr) (int64, error) { for _, r := range m.Regions { if hostVirtAddr >= r.BaseHostVirtAddr && hostVirtAddr < r.endHostVirtAddr() { - return r.shiftedOffset(hostVirtAddr), r.PageSize, nil + return r.shiftedOffset(hostVirtAddr), nil } } - return 0, 0, AddressNotFoundError{hostVirtAddr: hostVirtAddr} + return 0, AddressNotFoundError{hostVirtAddr: hostVirtAddr} } // GetHostVirtRanges returns the host virtual addresses and sizes (ranges) that cover exactly the given [offset, offset+length) range in the host virtual address space. @@ -95,12 +95,12 @@ func (m *Mapping) getHostVirtRegion(off int64) (*Region, error) { return nil, OffsetNotFoundError{offset: off} } -// GetHostVirtAddr returns the host virtual address and page size for the given offset. -func (m *Mapping) GetHostVirtAddr(off int64) (uintptr, uintptr, error) { +// GetHostVirtAddr returns the host virtual address the given offset. +func (m *Mapping) GetHostVirtAddr(off int64) (uintptr, error) { region, err := m.getHostVirtRegion(off) if err != nil { - return 0, 0, err + return 0, err } - return region.shiftedHostVirtAddr(off), region.PageSize, nil + return region.shiftedHostVirtAddr(off), nil } diff --git a/packages/orchestrator/internal/sandbox/uffd/memory/mapping_offset_test.go b/packages/orchestrator/internal/sandbox/uffd/memory/mapping_offset_test.go index 4be1c1e6e0..c2841885d8 100644 --- a/packages/orchestrator/internal/sandbox/uffd/memory/mapping_offset_test.go +++ b/packages/orchestrator/internal/sandbox/uffd/memory/mapping_offset_test.go @@ -103,13 +103,12 @@ func TestMapping_GetOffset(t *testing.T) { t.Run(tt.name, func(t *testing.T) { t.Parallel() - offset, pagesize, err := mapping.GetOffset(tt.hostVirtAddr) + offset, err := mapping.GetOffset(tt.hostVirtAddr) if tt.expectError != nil { require.ErrorIs(t, err, tt.expectError) } else { require.NoError(t, err) assert.Equal(t, tt.expectedOffset, offset) - assert.Equal(t, tt.expectedPagesize, pagesize) } }) } @@ -121,7 +120,7 @@ func TestMapping_EmptyRegions(t *testing.T) { mapping := NewMapping([]Region{}) // Test GetOffset with empty regions - _, _, err := mapping.GetOffset(0x1000) + _, err := mapping.GetOffset(0x1000) require.ErrorIs(t, err, AddressNotFoundError{hostVirtAddr: 0x1000}) } @@ -140,23 +139,21 @@ func TestMapping_BoundaryConditions(t *testing.T) { mapping := NewMapping(regions) // Test exact start boundary - offset, pagesize, err := mapping.GetOffset(0x1000) + offset, err := mapping.GetOffset(0x1000) require.NoError(t, err) assert.Equal(t, int64(0x5000), offset) // 0x5000 + (0x1000 - 0x1000) - assert.Equal(t, uintptr(header.PageSize), pagesize) // Test just before end boundary (exclusive) - offset, pagesize, err = mapping.GetOffset(0x2FFF) // 0x1000 + 0x2000 - 1 + offset, err = mapping.GetOffset(0x2FFF) // 0x1000 + 0x2000 - 1 require.NoError(t, err) assert.Equal(t, int64(0x5000+(0x2FFF-0x1000)), offset) // 0x6FFF - assert.Equal(t, uintptr(header.PageSize), pagesize) // Test exact end boundary (should fail - exclusive) - _, _, err = mapping.GetOffset(0x3000) // 0x1000 + 0x2000 + _, err = mapping.GetOffset(0x3000) // 0x1000 + 0x2000 require.ErrorIs(t, err, AddressNotFoundError{hostVirtAddr: 0x3000}) // Test below start boundary (should fail) - _, _, err = mapping.GetOffset(0x0FFF) // 0x1000 - 0x1000 + _, err = mapping.GetOffset(0x0FFF) // 0x1000 - 0x1000 require.ErrorIs(t, err, AddressNotFoundError{hostVirtAddr: 0x0FFF}) } @@ -174,10 +171,9 @@ func TestMapping_SingleLargeRegion(t *testing.T) { } mapping := NewMapping(regions) - offset, pagesize, err := mapping.GetOffset(0xABCDEF) + offset, err := mapping.GetOffset(0xABCDEF) require.NoError(t, err) assert.Equal(t, int64(0x100+0xABCDEF), offset) - assert.Equal(t, uintptr(header.PageSize), pagesize) } func TestMapping_ZeroSizeRegion(t *testing.T) { @@ -194,7 +190,7 @@ func TestMapping_ZeroSizeRegion(t *testing.T) { mapping := NewMapping(regions) - _, _, err := mapping.GetOffset(0x2000) + _, err := mapping.GetOffset(0x2000) require.ErrorIs(t, err, AddressNotFoundError{hostVirtAddr: 0x2000}) } @@ -218,19 +214,17 @@ func TestMapping_MultipleRegionsSparse(t *testing.T) { mapping := NewMapping(regions) // Should succeed for start of first region - offset, pagesize, err := mapping.GetOffset(0x100) + offset, err := mapping.GetOffset(0x100) require.NoError(t, err) assert.Equal(t, int64(0x1000), offset) - assert.Equal(t, uintptr(header.PageSize), pagesize) // Should succeed for start of second region - offset, pagesize, err = mapping.GetOffset(0x10000) + offset, err = mapping.GetOffset(0x10000) require.NoError(t, err) assert.Equal(t, int64(0x2000), offset) - assert.Equal(t, uintptr(header.PageSize), pagesize) // In gap - _, _, err = mapping.GetOffset(0x5000) + _, err = mapping.GetOffset(0x5000) require.ErrorIs(t, err, AddressNotFoundError{hostVirtAddr: 0x5000}) } @@ -250,18 +244,16 @@ func TestMapping_HugepagePagesize(t *testing.T) { mapping := NewMapping(regions) // Test valid address in region using hugepages - offset, pagesize, err := mapping.GetOffset(0x401000) + offset, err := mapping.GetOffset(0x401000) require.NoError(t, err) assert.Equal(t, int64(0x800000+(0x401000-0x400000)), offset) - assert.Equal(t, uintptr(hugepageSize), pagesize) // Test start of region - offset, pagesize, err = mapping.GetOffset(0x400000) + offset, err = mapping.GetOffset(0x400000) require.NoError(t, err) assert.Equal(t, int64(0x800000), offset) - assert.Equal(t, uintptr(hugepageSize), pagesize) // Test end of region (exclusive, should fail) - _, _, err = mapping.GetOffset(0x400000 + uintptr(hugepageSize)) + _, err = mapping.GetOffset(0x400000 + uintptr(hugepageSize)) require.ErrorIs(t, err, AddressNotFoundError{hostVirtAddr: 0x400000 + uintptr(hugepageSize)}) } diff --git a/packages/orchestrator/internal/sandbox/uffd/userfaultfd/cross_process_helpers_test.go b/packages/orchestrator/internal/sandbox/uffd/userfaultfd/cross_process_helpers_test.go index 382a20fdb2..1941e9b290 100644 --- a/packages/orchestrator/internal/sandbox/uffd/userfaultfd/cross_process_helpers_test.go +++ b/packages/orchestrator/internal/sandbox/uffd/userfaultfd/cross_process_helpers_test.go @@ -16,6 +16,7 @@ import ( "os" "os/exec" "os/signal" + "slices" "strconv" "strings" "syscall" @@ -307,8 +308,19 @@ func crossProcessServe() error { case <-ctx.Done(): return case <-offsetsSignal: - for offset := range uffd.faulted().Offsets() { - writeErr := binary.Write(offsetsFile, binary.LittleEndian, uint64(offset)) + faultedOffsets, faultedErr := uffd.faulted() + if faultedErr != nil { + msg := fmt.Errorf("error getting faulted offsets: %w", faultedErr) + + fmt.Fprint(os.Stderr, msg.Error()) + + cancel(msg) + + return + } + + for _, offset := range faultedOffsets { + writeErr := binary.Write(offsetsFile, binary.LittleEndian, offset) if writeErr != nil { msg := fmt.Errorf("error writing offsets to file: %w", writeErr) @@ -383,3 +395,31 @@ func crossProcessServe() error { return nil } } + +func (u *Userfaultfd) faulted() ([]uint64, error) { + // This will be at worst cancelled when the uffd is closed. + u.settleRequests.Lock() + u.settleRequests.Unlock() //nolint:staticcheck // SA2001: intentional — we just need to settle the read locks. + + return u.pageTracker.faultedOffsets(u.ma) +} + +func (pt *pageTracker) faultedOffsets(ma *memory.Mapping) ([]uint64, error) { + pt.mu.RLock() + defer pt.mu.RUnlock() + + offsets := make([]uint64, 0, len(pt.m)) + for addr := range pt.m { + offset, err := ma.GetOffset(addr) + if err != nil { + return nil, fmt.Errorf("address %#x not in mapping: %w", addr, err) + } + offsets = append(offsets, uint64(offset)) + } + + if len(offsets) > 1 { + slices.Sort(offsets) + } + + return offsets, nil +} diff --git a/packages/orchestrator/internal/sandbox/uffd/userfaultfd/deferred.go b/packages/orchestrator/internal/sandbox/uffd/userfaultfd/deferred.go new file mode 100644 index 0000000000..6089ad7660 --- /dev/null +++ b/packages/orchestrator/internal/sandbox/uffd/userfaultfd/deferred.go @@ -0,0 +1,26 @@ +package userfaultfd + +import "sync" + +// deferredFaults collects pagefaults that couldn't be handled (EAGAIN) +// and need to be retried on the next poll iteration. Safe for concurrent push. +type deferredFaults struct { + mu sync.Mutex + pf []*UffdPagefault +} + +func (d *deferredFaults) push(pf *UffdPagefault) { + d.mu.Lock() + d.pf = append(d.pf, pf) + d.mu.Unlock() +} + +// drain returns all accumulated pagefaults and resets the internal list. +func (d *deferredFaults) drain() []*UffdPagefault { + d.mu.Lock() + out := d.pf + d.pf = nil + d.mu.Unlock() + + return out +} diff --git a/packages/orchestrator/internal/sandbox/uffd/userfaultfd/fd.go b/packages/orchestrator/internal/sandbox/uffd/userfaultfd/fd.go index 60c773c540..958a199f47 100644 --- a/packages/orchestrator/internal/sandbox/uffd/userfaultfd/fd.go +++ b/packages/orchestrator/internal/sandbox/uffd/userfaultfd/fd.go @@ -21,6 +21,10 @@ struct uffd_pagefault { #define UFFD_FEATURE_WP_ASYNC (1 << 15) #endif +struct uffd_remove { + __u64 start; + __u64 end; +}; */ import "C" @@ -33,20 +37,30 @@ import ( const ( NR_userfaultfd = C.__NR_userfaultfd - UFFD_API = C.UFFD_API + UFFD_API = C.UFFD_API + UFFD_EVENT_PAGEFAULT = C.UFFD_EVENT_PAGEFAULT + UFFD_EVENT_REMOVE = C.UFFD_EVENT_REMOVE UFFDIO_REGISTER_MODE_MISSING = C.UFFDIO_REGISTER_MODE_MISSING UFFDIO_REGISTER_MODE_WP = C.UFFDIO_REGISTER_MODE_WP UFFDIO_COPY_MODE_WP = C.UFFDIO_COPY_MODE_WP - UFFDIO_API = C.UFFDIO_API - UFFDIO_REGISTER = C.UFFDIO_REGISTER - UFFDIO_UNREGISTER = C.UFFDIO_UNREGISTER - UFFDIO_COPY = C.UFFDIO_COPY + UFFDIO_WRITEPROTECT_MODE_WP = C.UFFDIO_WRITEPROTECT_MODE_WP + + UFFDIO_ZEROPAGE_MODE_DONTWAKE = C.UFFDIO_ZEROPAGE_MODE_DONTWAKE + + UFFDIO_API = C.UFFDIO_API + UFFDIO_REGISTER = C.UFFDIO_REGISTER + UFFDIO_COPY = C.UFFDIO_COPY + UFFDIO_ZEROPAGE = C.UFFDIO_ZEROPAGE + UFFDIO_WRITEPROTECT = C.UFFDIO_WRITEPROTECT + UFFDIO_WAKE = C.UFFDIO_WAKE UFFD_PAGEFAULT_FLAG_WRITE = C.UFFD_PAGEFAULT_FLAG_WRITE + UFFD_PAGEFAULT_FLAG_MINOR = C.UFFD_PAGEFAULT_FLAG_MINOR + UFFD_PAGEFAULT_FLAG_WP = C.UFFD_PAGEFAULT_FLAG_WP UFFD_FEATURE_MISSING_HUGETLBFS = C.UFFD_FEATURE_MISSING_HUGETLBFS UFFD_FEATURE_WP_ASYNC = C.UFFD_FEATURE_WP_ASYNC @@ -59,11 +73,13 @@ type ( UffdMsg = C.struct_uffd_msg UffdPagefault = C.struct_uffd_pagefault + UffdRemove = C.struct_uffd_remove UffdioAPI = C.struct_uffdio_api UffdioRegister = C.struct_uffdio_register UffdioRange = C.struct_uffdio_range UffdioCopy = C.struct_uffdio_copy + UffdioZero = C.struct_uffdio_zeropage UffdioWriteProtect = C.struct_uffdio_writeprotect ) @@ -98,6 +114,21 @@ func newUffdioCopy(b []byte, address CULong, pagesize CULong, mode CULong, bytes } } +func newUffdioZero(address, pagesize, mode CULong) UffdioZero { + return UffdioZero{ + _range: newUffdioRange(address, pagesize), + mode: mode, + zeropage: 0, + } +} + +func newUffdioWriteProtect(address, pagesize, mode CULong) UffdioWriteProtect { + return UffdioWriteProtect{ + _range: newUffdioRange(address, pagesize), + mode: mode, + } +} + func getMsgEvent(msg *UffdMsg) CUChar { return msg.event } @@ -130,6 +161,41 @@ func (f Fd) copy(addr, pagesize uintptr, data []byte, mode CULong) error { return nil } +func (f Fd) zero(addr, pagesize uintptr, mode CULong) error { + zero := newUffdioZero(CULong(addr)&^CULong(pagesize-1), CULong(pagesize), mode) + + if _, _, errno := syscall.Syscall(syscall.SYS_IOCTL, uintptr(f), UFFDIO_ZEROPAGE, uintptr(unsafe.Pointer(&zero))); errno != 0 { + return errno + } + + // Check if the bytes actually zeroed out by the kernel match the page size + if zero.zeropage != CLong(pagesize) { + return fmt.Errorf("UFFDIO_ZEROPAGE copied %d bytes, expected %d", zero.zeropage, pagesize) + } + + return nil +} + +func (f Fd) writeProtect(addr, pagesize uintptr, mode CULong) error { + writeProtect := newUffdioWriteProtect(CULong(addr), CULong(pagesize), mode) + + if _, _, errno := syscall.Syscall(syscall.SYS_IOCTL, uintptr(f), UFFDIO_WRITEPROTECT, uintptr(unsafe.Pointer(&writeProtect))); errno != 0 { + return errno + } + + return nil +} + +func (f Fd) wake(addr, pagesize uintptr) error { + uffdRange := newUffdioRange(CULong(addr), CULong(pagesize)) + + if _, _, errno := syscall.Syscall(syscall.SYS_IOCTL, uintptr(f), UFFDIO_WAKE, uintptr(unsafe.Pointer(&uffdRange))); errno != 0 { + return errno + } + + return nil +} + func (f Fd) close() error { return syscall.Close(int(f)) } diff --git a/packages/orchestrator/internal/sandbox/uffd/userfaultfd/invoke.go b/packages/orchestrator/internal/sandbox/uffd/userfaultfd/invoke.go new file mode 100644 index 0000000000..71205ca263 --- /dev/null +++ b/packages/orchestrator/internal/sandbox/uffd/userfaultfd/invoke.go @@ -0,0 +1,10 @@ +package userfaultfd + +// safeInvoke calls fn and returns its result, or nil if fn is nil. +func safeInvoke(fn func() error) error { + if fn == nil { + return nil + } + + return fn() +} diff --git a/packages/orchestrator/internal/sandbox/uffd/userfaultfd/page_tracker.go b/packages/orchestrator/internal/sandbox/uffd/userfaultfd/page_tracker.go new file mode 100644 index 0000000000..b3ba62176f --- /dev/null +++ b/packages/orchestrator/internal/sandbox/uffd/userfaultfd/page_tracker.go @@ -0,0 +1,46 @@ +package userfaultfd + +import "sync" + +type pageState uint8 + +const ( + unfaulted pageState = iota + faulted + removed +) + +type pageTracker struct { + pageSize uintptr + + m map[uintptr]pageState + mu sync.RWMutex +} + +func newPageTracker(pageSize uintptr) pageTracker { + return pageTracker{ + pageSize: pageSize, + m: make(map[uintptr]pageState), + } +} + +func (pt *pageTracker) get(addr uintptr) pageState { + pt.mu.RLock() + defer pt.mu.RUnlock() + + state, ok := pt.m[addr] + if !ok { + return unfaulted + } + + return state +} + +func (pt *pageTracker) setState(start, end uintptr, state pageState) { + pt.mu.Lock() + defer pt.mu.Unlock() + + for addr := start; addr < end; addr += pt.pageSize { + pt.m[addr] = state + } +} diff --git a/packages/orchestrator/internal/sandbox/uffd/userfaultfd/prefault.go b/packages/orchestrator/internal/sandbox/uffd/userfaultfd/prefault.go new file mode 100644 index 0000000000..ee3096b7ee --- /dev/null +++ b/packages/orchestrator/internal/sandbox/uffd/userfaultfd/prefault.go @@ -0,0 +1,69 @@ +package userfaultfd + +import ( + "context" + "fmt" + + "github.com/e2b-dev/infra/packages/orchestrator/internal/sandbox/block" +) + +// Prefault proactively copies a page to guest memory at the given offset. +// This is used to speed up sandbox starts by prefetching pages that are known to be needed. +// Returns nil on success, or if the page is already mapped (EEXIST is handled gracefully). +func (u *Userfaultfd) Prefault(ctx context.Context, offset int64, data []byte) error { + ctx, span := tracer.Start(ctx, "prefault page") + defer span.End() + + addr, err := u.ma.GetHostVirtAddr(offset) + if err != nil { + return fmt.Errorf("failed to get host virtual address: %w", err) + } + + if len(data) != int(u.pageSize) { + return fmt.Errorf("data length (%d) does not match pagesize (%d)", len(data), u.pageSize) + } + + // We're treating prefault handling as if it was caused by a read access. + // This way, we will fault the page with UFFD_COPY_MODE_WP which will preserve + // the WP bit for the page. This works even in the case of a race with a + // concurrent on-demand write access. + // + // If the on-demand fault handler beats us, we will get an EEXIST here. + // If we beat the on-demand handler, it will get the EEXIST. + // + // In both cases, the WP bit will be cleared because it is handled asynchronously + // by the kernel. + handled, err := u.faultPage( + ctx, + addr, + offset, + block.Read, + directDataSource{data, int64(u.pageSize)}, + nil, + ) + if err != nil { + span.RecordError(fmt.Errorf("could not prefault page")) + + return fmt.Errorf("failed to fault page: %w", err) + } + + if !handled { + span.AddEvent("prefault: page already faulted or write returned EAGAIN") + } + + return nil +} + +// directDataSource wraps a byte slice to implement block.Slicer for prefaulting. +type directDataSource struct { + data []byte + pagesize int64 +} + +func (d directDataSource) Slice(_ context.Context, _, _ int64) ([]byte, error) { + return d.data, nil +} + +func (d directDataSource) BlockSize() int64 { + return d.pagesize +} diff --git a/packages/orchestrator/internal/sandbox/uffd/userfaultfd/userfaultfd.go b/packages/orchestrator/internal/sandbox/uffd/userfaultfd/userfaultfd.go index 4db0fe5127..dcb159d4ca 100644 --- a/packages/orchestrator/internal/sandbox/uffd/userfaultfd/userfaultfd.go +++ b/packages/orchestrator/internal/sandbox/uffd/userfaultfd/userfaultfd.go @@ -19,6 +19,7 @@ import ( "github.com/e2b-dev/infra/packages/orchestrator/internal/sandbox/uffd/fdexit" "github.com/e2b-dev/infra/packages/orchestrator/internal/sandbox/uffd/memory" "github.com/e2b-dev/infra/packages/shared/pkg/logger" + "github.com/e2b-dev/infra/packages/shared/pkg/storage/header" ) var tracer = otel.Tracer("github.com/e2b-dev/infra/packages/orchestrator/internal/sandbox/uffd/userfaultfd") @@ -35,15 +36,13 @@ func hasEvent(revents, event int16) bool { type Userfaultfd struct { fd Fd - src block.Slicer - ma *memory.Mapping - - // We don't skip the already mapped pages, because if the memory is swappable the page *might* under some conditions be mapped out. - // For hugepages this should not be a problem, but might theoretically happen to normal pages with swap - missingRequests *block.Tracker - // We use the settleRequests to guard the missingRequests so we can access a consistent state of the missingRequests after the requests are finished. - settleRequests sync.RWMutex + src block.Slicer + ma *memory.Mapping + pageSize uintptr + pageTracker pageTracker + // We use the settleRequests to guard the prefetchTracker so we can access a consistent state of the prefetchTracker after the requests are finished. + settleRequests sync.RWMutex prefetchTracker *block.PrefetchTracker wg errgroup.Group @@ -64,7 +63,8 @@ func NewUserfaultfdFromFd(fd uintptr, src block.Slicer, m *memory.Mapping, logge u := &Userfaultfd{ fd: Fd(fd), src: src, - missingRequests: block.NewTracker(blockSize), + pageSize: uintptr(blockSize), + pageTracker: newPageTracker(uintptr(blockSize)), prefetchTracker: block.NewPrefetchTracker(blockSize), ma: m, logger: logger, @@ -78,8 +78,59 @@ func NewUserfaultfdFromFd(fd uintptr, src block.Slicer, m *memory.Mapping, logge return u, nil } -func (u *Userfaultfd) Close() error { - return u.fd.close() +// readEvents reads all available UFFD events from the file descriptor, +// returning removes and pagefaults separately. +func (u *Userfaultfd) readEvents(ctx context.Context) ([]*UffdRemove, []*UffdPagefault, error) { + // We are reusing the same buffer for all events, but that's fine, + // because getMsgArg, will make a copy of the actual event from `buf` + // and it's a pointer to this copy that we are returning to caller. + buf := make([]byte, unsafe.Sizeof(UffdMsg{})) + + var removes []*UffdRemove + var pagefaults []*UffdPagefault + + for { + n, err := syscall.Read(int(u.fd), buf) + if errors.Is(err, syscall.EINTR) { + u.logger.Debug(ctx, "uffd: interrupted read. Reading again") + + continue + } + + if errors.Is(err, syscall.EAGAIN) { + // EAGAIN means that we have drained all the available events for the file descriptor. + // We are done. + break + } + + if err != nil { + return nil, nil, fmt.Errorf("failed reading uffd: %w", err) + } + + // `Read` returned with 0 bytes actually read. No more events to read + // and the writing end has been closed. This should never happen, unless + // something (us or Firecracker) closes the file descriptor + // TODO: Ignore it for now, but maybe we should return an error(?) + if n == 0 { + break + } + + msg := (*UffdMsg)(unsafe.Pointer(&buf[0])) + + event := getMsgEvent(msg) + arg := getMsgArg(msg) + + switch event { + case UFFD_EVENT_PAGEFAULT: + pagefaults = append(pagefaults, (*UffdPagefault)(unsafe.Pointer(&arg[0]))) + case UFFD_EVENT_REMOVE: + removes = append(removes, (*UffdRemove)(unsafe.Pointer(&arg[0]))) + default: + return nil, nil, ErrUnexpectedEventType + } + } + + return removes, pagefaults, nil } func (u *Userfaultfd) Serve( @@ -109,7 +160,8 @@ func (u *Userfaultfd) Serve( unix.POLLNVAL: "POLLNVAL", } -outerLoop: + var deferred deferredFaults + for { if _, err := unix.Poll( pollFds, @@ -175,211 +227,210 @@ outerLoop: continue } - buf := make([]byte, unsafe.Sizeof(UffdMsg{})) - - for { - _, err := syscall.Read(int(u.fd), buf) - if err == syscall.EINTR { - u.logger.Debug(ctx, "uffd: interrupted read, reading again") - - continue - } - - if err == nil { - // There is no error so we can proceed. - - eagainCounter.Log(ctx) - noDataCounter.Log(ctx) - - break - } - - if err == syscall.EAGAIN { - eagainCounter.Increase("EAGAIN") - - // Continue polling the fd. - continue outerLoop - } - + removes, pagefaults, err := u.readEvents(ctx) + if err != nil { u.logger.Error(ctx, "uffd: read error", zap.Error(err)) return fmt.Errorf("failed to read: %w", err) } - msg := *(*UffdMsg)(unsafe.Pointer(&buf[0])) - - if msgEvent := getMsgEvent(&msg); msgEvent != UFFD_EVENT_PAGEFAULT { - u.logger.Error(ctx, "UFFD serve unexpected event type", zap.Any("event_type", msgEvent)) - - return ErrUnexpectedEventType - } - - arg := getMsgArg(&msg) - pagefault := (*(*UffdPagefault)(unsafe.Pointer(&arg[0]))) - flags := pagefault.flags - - addr := getPagefaultAddress(&pagefault) + // Collect deferred pagefaults from previous iteration's goroutines. + pagefaults = append(deferred.drain(), pagefaults...) - offset, pagesize, err := u.ma.GetOffset(addr) - if err != nil { - u.logger.Error(ctx, "UFFD serve get mapping error", zap.Error(err)) - - return fmt.Errorf("failed to map: %w", err) - } - - // Handle write to missing page (WRITE flag) - // If the event has WRITE flag, it was a write to a missing page. - // For the write to be executed, we first need to copy the page from the source to the guest memory. - if flags&UFFD_PAGEFAULT_FLAG_WRITE != 0 { - u.wg.Go(func() error { - return u.faultPage(ctx, addr, offset, pagesize, u.src, fdExit.SignalExit, block.Write) - }) + // No events were found which is weird since, if we are here, + // poll() returned with an event indicating that UFFD had something + // for us to read. Log an error and continue + if len(removes) == 0 && len(pagefaults) == 0 { + eagainCounter.Increase("EAGAIN") continue } - // Handle read to missing page ("MISSING" flag) - // If the event has no flags, it was a read to a missing page and we need to copy the page from the source to the guest memory. - if flags == 0 { - u.wg.Go(func() error { - return u.faultPage(ctx, addr, offset, pagesize, u.src, fdExit.SignalExit, block.Read) - }) + // We successfully read all available UFFD events. + noDataCounter.Log(ctx) + eagainCounter.Log(ctx) - continue + // First handle the UFFD_EVENT_REMOVE events + for _, rm := range removes { + u.pageTracker.setState(uintptr(rm.start), uintptr(rm.end), removed) } - // MINOR and WP flags are not expected as we don't register the uffd with these flags. - return fmt.Errorf("unexpected event type: %d, closing uffd", flags) - } -} + for _, pf := range pagefaults { + // We don't handle minor page faults. + if pf.flags&UFFD_PAGEFAULT_FLAG_MINOR != 0 { + return fmt.Errorf("unexpected MINOR pagefault event, closing UFFD") + } -func (u *Userfaultfd) faulted() *block.Tracker { - // This will be at worst cancelled when the uffd is closed. - u.settleRequests.Lock() - // The locking here would work even without using defer (just lock-then-unlock the mutex), but at this point let's make it lock to the clone, - // so it is consistent even if there is a another uffd call after. - defer u.settleRequests.Unlock() + // We don't handle write-protection page faults, we're using asynchronous write protection. + if pf.flags&UFFD_PAGEFAULT_FLAG_WP != 0 { + return fmt.Errorf("unexpected WP pagefault event, closing UFFD") + } - return u.missingRequests.Clone() -} + addr := getPagefaultAddress(pf) + offset, err := u.ma.GetOffset(addr) + if err != nil { + u.logger.Error(ctx, "UFFD serve got mapping error", zap.Error(err)) -func (u *Userfaultfd) PrefetchData() block.PrefetchData { - // This will be at worst cancelled when the uffd is closed. - u.settleRequests.Lock() - // The locking here would work even without using defer (just lock-then-unlock the mutex), but at this point let's make it lock to the clone, - // so it is consistent even if there is a another uffd call after. - defer u.settleRequests.Unlock() + return fmt.Errorf("failed to map: %w", err) + } - return u.prefetchTracker.PrefetchData() -} + var source block.Slicer -// Prefault proactively copies a page to guest memory at the given offset. -// This is used to speed up sandbox starts by prefetching pages that are known to be needed. -// Returns nil on success, or if the page is already mapped (EEXIST is handled gracefully). -func (u *Userfaultfd) Prefault(ctx context.Context, offset int64, data []byte) error { - ctx, span := tracer.Start(ctx, "prefault page") - defer span.End() - - // Get host virtual address and page size for this offset - addr, pagesize, err := u.ma.GetHostVirtAddr(offset) - if err != nil { - return fmt.Errorf("failed to get host virtual address: %w", err) - } + switch state := u.pageTracker.get(addr); state { + case faulted: + // Skip faulting the page. This has already been faulted, either during pre-faulting + // or because we handled another page fault on the same address in the current + // iteration. It can only be removed via a a UFFD_EVENT_REMOVE, which will mark the + // page as `unfaulted`. + continue + case removed: + // Fault the page as empty. + case unfaulted: + source = u.src + default: + return fmt.Errorf("unexpected pageState: %#v", state) + } - if len(data) != int(pagesize) { - return fmt.Errorf("data length (%d) is less than pagesize (%d)", len(data), pagesize) + u.wg.Go(func() error { + // The RLock must be called inside the goroutine to ensure RUnlock runs via defer, + // even if the errgroup is cancelled or the goroutine returns early. + // This check protects us against race condition between marking the request for prefetching and accessing the prefetchTracker. + u.settleRequests.RLock() + defer u.settleRequests.RUnlock() + + var accessType block.AccessType + + if pf.flags&UFFD_PAGEFAULT_FLAG_WRITE == 0 { + accessType = block.Read + } else { + accessType = block.Write + } + + handled, err := u.faultPage( + ctx, + addr, + offset, + accessType, + source, + fdExit.SignalExit, + ) + if err != nil { + return err + } + + if handled { + u.pageTracker.setState(addr, addr+u.pageSize, faulted) + u.prefetchTracker.Add(offset, accessType) + } else { + deferred.push(pf) + } + + return nil + }) + } } - - return u.faultPage(ctx, addr, offset, pagesize, directDataSource{data, int64(pagesize)}, nil, block.Prefetch) -} - -// directDataSource wraps a byte slice to implement block.Slicer for prefaulting. -type directDataSource struct { - data []byte - pagesize int64 -} - -func (d directDataSource) Slice(_ context.Context, _, _ int64) ([]byte, error) { - return d.data, nil -} - -func (d directDataSource) BlockSize() int64 { - return d.pagesize } func (u *Userfaultfd) faultPage( ctx context.Context, addr uintptr, offset int64, - pagesize uintptr, + accessType block.AccessType, source block.Slicer, onFailure func() error, - accessType block.AccessType, -) error { +) (bool, error) { span := trace.SpanFromContext(ctx) - // The RLock must be called inside the goroutine to ensure RUnlock runs via defer, - // even if the errgroup is cancelled or the goroutine returns early. - // This check protects us against race condition between marking the request as missing and accessing the missingRequests tracker. - // The Firecracker pause should return only after the requested memory is faulted in, so we don't need to guard the pagefault from the moment it is created. - u.settleRequests.RLock() - defer u.settleRequests.RUnlock() - defer func() { if r := recover(); r != nil { - u.logger.Error(ctx, "UFFD serve panic", zap.Any("pagesize", pagesize), zap.Any("panic", r)) + u.logger.Error(ctx, "UFFD serve panic", zap.Any("pagesize", u.pageSize), zap.Any("panic", r)) } }() - b, dataErr := source.Slice(ctx, offset, int64(pagesize)) - if dataErr != nil { - var signalErr error - if onFailure != nil { - signalErr = onFailure() - } - - joinedErr := errors.Join(dataErr, signalErr) + var writeErr error + var mode CULong - span.RecordError(joinedErr) - u.logger.Error(ctx, "UFFD serve data fetch error", zap.Error(joinedErr)) - - return fmt.Errorf("failed to read from source: %w", joinedErr) + // Performing copy() on UFFD clears the WP bit unless we explicitly tell + // it not to. We do that for faults caused by a read access. Write accesses + // would anyways clear the write-protection bit. + if accessType == block.Read { + mode = UFFDIO_COPY_MODE_WP } - var copyMode CULong + // Write to guest memory. nil data means zero-fill + switch { + case source == nil && u.pageSize == header.PageSize: + // Firecracker uses anonymous mappings for 4K pages. Anonymous mappings can only + // be write protected once pages are populated. We need to enable write-protection + // *after* we serve the page fault. + // + // To avoid the race condition, first serve the page without waking the thread + writeErr = u.fd.zero(addr, u.pageSize, UFFDIO_ZEROPAGE_MODE_DONTWAKE) + if writeErr != nil { + break + } + // Then, write-protect the page + writeErr = u.fd.writeProtect(addr, u.pageSize, UFFDIO_WRITEPROTECT_MODE_WP) + if writeErr != nil { + break + } + // And, finally, wake up the faulting thread + writeErr = u.fd.wake(addr, u.pageSize) + case source == nil && u.pageSize == header.HugepageSize: + writeErr = u.fd.copy(addr, u.pageSize, header.EmptyHugePage, mode) + default: + b, dataErr := source.Slice(ctx, offset, int64(u.pageSize)) + if dataErr != nil { + joinedErr := errors.Join(dataErr, safeInvoke(onFailure)) + + span.RecordError(joinedErr) + u.logger.Error(ctx, "UFFD serve data fetch error", zap.Error(joinedErr)) + + return false, fmt.Errorf("failed to read from source: %w", joinedErr) + } - // Performing copy() on UFFD clears the WP bit unless we explicitly tell - // it not to. We do that for faults caused by a read access. Write accesses - // would anyways cause clear the write-protection bit. - if accessType != block.Write { - copyMode |= UFFDIO_COPY_MODE_WP + writeErr = u.fd.copy(addr, u.pageSize, b, mode) } - copyErr := u.fd.copy(addr, pagesize, b, copyMode) - if errors.Is(copyErr, unix.EEXIST) { - // Page is already mapped + // Page is already mapped. + // Probably because we have already pre-faulted it. Otherwise, we should not + // try to handle a page fault for the same address twice, since we are now + // tracking the state of pages. + if errors.Is(writeErr, unix.EEXIST) { span.SetAttributes(attribute.Bool("uffd.already_mapped", true)) - return nil + return true, nil } - if copyErr != nil { - var signalErr error - if onFailure != nil { - signalErr = onFailure() - } + if errors.Is(writeErr, unix.EAGAIN) { + // This happens when a remove event arrives in the UFFD file descriptor while + // we are trying to copy()/zero() a page. We need to read all the events from + // file descriptor and try again. + u.logger.Debug(ctx, "UFFD page write EAGAIN, deferring", zap.Uintptr("addr", addr)) + + return false, nil + } - joinedErr := errors.Join(copyErr, signalErr) + if writeErr != nil { + joinedErr := errors.Join(writeErr, safeInvoke(onFailure)) span.RecordError(joinedErr) u.logger.Error(ctx, "UFFD serve uffdio copy error", zap.Error(joinedErr)) - return fmt.Errorf("failed uffdio copy: %w", joinedErr) + return false, fmt.Errorf("failed uffdio copy %w", joinedErr) } - // Add the offset to the missing requests tracker with metadata. - u.missingRequests.Add(offset) - u.prefetchTracker.Add(offset, accessType) + return true, nil +} - return nil +func (u *Userfaultfd) PrefetchData() block.PrefetchData { + // This will be at worst cancelled when the uffd is closed. + u.settleRequests.Lock() + u.settleRequests.Unlock() //nolint:staticcheck // SA2001: intentional — we just need to settle the read locks. + + return u.prefetchTracker.PrefetchData() +} + +func (u *Userfaultfd) Close() error { + return u.fd.close() } diff --git a/packages/orchestrator/internal/template/build/config/config.go b/packages/orchestrator/internal/template/build/config/config.go index fc73a097bf..8a31beb7e8 100644 --- a/packages/orchestrator/internal/template/build/config/config.go +++ b/packages/orchestrator/internal/template/build/config/config.go @@ -41,6 +41,9 @@ type TemplateConfig struct { // HugePages sets whether the VM use huge pages. HugePages bool + // FreePageReporting enables the corresponding feature in Firecracker + FreePageReporting bool + // Command to run to check if the template is ready. ReadyCmd string diff --git a/packages/orchestrator/internal/template/build/phases/base/builder.go b/packages/orchestrator/internal/template/build/phases/base/builder.go index d2442126a5..a2fb5fc7c7 100644 --- a/packages/orchestrator/internal/template/build/phases/base/builder.go +++ b/packages/orchestrator/internal/template/build/phases/base/builder.go @@ -200,9 +200,10 @@ func (bb *BaseBuilder) buildLayerFromOCI( userLogger.Info(ctx, "Provisioning sandbox template") baseSbxConfig := sandbox.Config{ - Vcpu: bb.Config.VCpuCount, - RamMB: bb.Config.MemoryMB, - HugePages: bb.Config.HugePages, + Vcpu: bb.Config.VCpuCount, + RamMB: bb.Config.MemoryMB, + HugePages: bb.Config.HugePages, + FreePageReporting: bb.Config.FreePageReporting, // Allow sandbox internet access during provisioning Network: &orchestrator.SandboxNetworkConfig{}, diff --git a/packages/orchestrator/internal/template/build/phases/finalize/builder.go b/packages/orchestrator/internal/template/build/phases/finalize/builder.go index 1b84dd2a8f..abbda2db76 100644 --- a/packages/orchestrator/internal/template/build/phases/finalize/builder.go +++ b/packages/orchestrator/internal/template/build/phases/finalize/builder.go @@ -149,9 +149,10 @@ func (ppb *PostProcessingBuilder) Build( // Configure sandbox for final layer sbxConfig := sandbox.Config{ - Vcpu: ppb.Config.VCpuCount, - RamMB: ppb.Config.MemoryMB, - HugePages: ppb.Config.HugePages, + Vcpu: ppb.Config.VCpuCount, + RamMB: ppb.Config.MemoryMB, + HugePages: ppb.Config.HugePages, + FreePageReporting: ppb.Config.FreePageReporting, Envd: sandbox.EnvdMetadata{ Version: ppb.EnvdVersion, diff --git a/packages/orchestrator/internal/template/build/phases/steps/builder.go b/packages/orchestrator/internal/template/build/phases/steps/builder.go index f11a4e6369..c77c1b52cf 100644 --- a/packages/orchestrator/internal/template/build/phases/steps/builder.go +++ b/packages/orchestrator/internal/template/build/phases/steps/builder.go @@ -159,9 +159,10 @@ func (sb *StepBuilder) Build( step := sb.step sbxConfig := sandbox.Config{ - Vcpu: sb.Config.VCpuCount, - RamMB: sb.Config.MemoryMB, - HugePages: sb.Config.HugePages, + Vcpu: sb.Config.VCpuCount, + RamMB: sb.Config.MemoryMB, + HugePages: sb.Config.HugePages, + FreePageReporting: sb.Config.FreePageReporting, Envd: sandbox.EnvdMetadata{ Version: sb.EnvdVersion, diff --git a/packages/orchestrator/internal/template/server/create_template.go b/packages/orchestrator/internal/template/server/create_template.go index f5ee87aafb..118ed67dfd 100644 --- a/packages/orchestrator/internal/template/server/create_template.go +++ b/packages/orchestrator/internal/template/server/create_template.go @@ -70,6 +70,7 @@ func (s *ServerStore) TemplateCreate(ctx context.Context, templateRequest *templ ReadyCmd: cfg.GetReadyCommand(), DiskSizeMB: int64(cfg.GetDiskSizeMB()), HugePages: cfg.GetHugePages(), + FreePageReporting: cfg.GetFreePageReporting(), FromImage: cfg.GetFromImage(), FromTemplate: cfg.GetFromTemplate(), RegistryAuthProvider: authProvider, diff --git a/packages/orchestrator/template-manager.proto b/packages/orchestrator/template-manager.proto index 4ef795fb59..95dd17131e 100644 --- a/packages/orchestrator/template-manager.proto +++ b/packages/orchestrator/template-manager.proto @@ -84,6 +84,7 @@ message TemplateConfig { optional FromImageRegistry fromImageRegistry = 15; string teamID = 16; + optional bool freePageReporting = 17; } message TemplateCreateRequest { diff --git a/packages/shared/pkg/fc/client/operations/create_snapshot_parameters.go b/packages/shared/pkg/fc/client/operations/create_snapshot_parameters.go index d5a2d163d9..945ad30987 100644 --- a/packages/shared/pkg/fc/client/operations/create_snapshot_parameters.go +++ b/packages/shared/pkg/fc/client/operations/create_snapshot_parameters.go @@ -62,7 +62,7 @@ type CreateSnapshotParams struct { /* Body. - The configuration used for creating a snaphot. + The configuration used for creating a snapshot. */ Body *models.SnapshotCreateParams diff --git a/packages/shared/pkg/fc/client/operations/describe_balloon_hinting_parameters.go b/packages/shared/pkg/fc/client/operations/describe_balloon_hinting_parameters.go new file mode 100644 index 0000000000..2a954ceae1 --- /dev/null +++ b/packages/shared/pkg/fc/client/operations/describe_balloon_hinting_parameters.go @@ -0,0 +1,125 @@ +// Code generated by go-swagger; DO NOT EDIT. + +package operations + +import ( + "context" + "net/http" + "time" + + "github.com/go-openapi/errors" + "github.com/go-openapi/runtime" + cr "github.com/go-openapi/runtime/client" + "github.com/go-openapi/strfmt" +) + +// NewDescribeBalloonHintingParams creates a new DescribeBalloonHintingParams object, +// with the default timeout for this client. +// +// Default values are not hydrated, since defaults are normally applied by the API server side. +// +// To enforce default values in parameter, use SetDefaults or WithDefaults. +func NewDescribeBalloonHintingParams() *DescribeBalloonHintingParams { + return &DescribeBalloonHintingParams{ + timeout: cr.DefaultTimeout, + } +} + +// NewDescribeBalloonHintingParamsWithTimeout creates a new DescribeBalloonHintingParams object +// with the ability to set a timeout on a request. +func NewDescribeBalloonHintingParamsWithTimeout(timeout time.Duration) *DescribeBalloonHintingParams { + return &DescribeBalloonHintingParams{ + timeout: timeout, + } +} + +// NewDescribeBalloonHintingParamsWithContext creates a new DescribeBalloonHintingParams object +// with the ability to set a context for a request. +func NewDescribeBalloonHintingParamsWithContext(ctx context.Context) *DescribeBalloonHintingParams { + return &DescribeBalloonHintingParams{ + Context: ctx, + } +} + +// NewDescribeBalloonHintingParamsWithHTTPClient creates a new DescribeBalloonHintingParams object +// with the ability to set a custom HTTPClient for a request. +func NewDescribeBalloonHintingParamsWithHTTPClient(client *http.Client) *DescribeBalloonHintingParams { + return &DescribeBalloonHintingParams{ + HTTPClient: client, + } +} + +/* +DescribeBalloonHintingParams contains all the parameters to send to the API endpoint + + for the describe balloon hinting operation. + + Typically these are written to a http.Request. +*/ +type DescribeBalloonHintingParams struct { + timeout time.Duration + Context context.Context + HTTPClient *http.Client +} + +// WithDefaults hydrates default values in the describe balloon hinting params (not the query body). +// +// All values with no default are reset to their zero value. +func (o *DescribeBalloonHintingParams) WithDefaults() *DescribeBalloonHintingParams { + o.SetDefaults() + return o +} + +// SetDefaults hydrates default values in the describe balloon hinting params (not the query body). +// +// All values with no default are reset to their zero value. +func (o *DescribeBalloonHintingParams) SetDefaults() { + // no default values defined for this parameter +} + +// WithTimeout adds the timeout to the describe balloon hinting params +func (o *DescribeBalloonHintingParams) WithTimeout(timeout time.Duration) *DescribeBalloonHintingParams { + o.SetTimeout(timeout) + return o +} + +// SetTimeout adds the timeout to the describe balloon hinting params +func (o *DescribeBalloonHintingParams) SetTimeout(timeout time.Duration) { + o.timeout = timeout +} + +// WithContext adds the context to the describe balloon hinting params +func (o *DescribeBalloonHintingParams) WithContext(ctx context.Context) *DescribeBalloonHintingParams { + o.SetContext(ctx) + return o +} + +// SetContext adds the context to the describe balloon hinting params +func (o *DescribeBalloonHintingParams) SetContext(ctx context.Context) { + o.Context = ctx +} + +// WithHTTPClient adds the HTTPClient to the describe balloon hinting params +func (o *DescribeBalloonHintingParams) WithHTTPClient(client *http.Client) *DescribeBalloonHintingParams { + o.SetHTTPClient(client) + return o +} + +// SetHTTPClient adds the HTTPClient to the describe balloon hinting params +func (o *DescribeBalloonHintingParams) SetHTTPClient(client *http.Client) { + o.HTTPClient = client +} + +// WriteToRequest writes these params to a swagger request +func (o *DescribeBalloonHintingParams) WriteToRequest(r runtime.ClientRequest, reg strfmt.Registry) error { + + if err := r.SetTimeout(o.timeout); err != nil { + return err + } + var res []error + + if len(res) > 0 { + return errors.CompositeValidationError(res...) + } + return nil +} diff --git a/packages/shared/pkg/fc/client/operations/describe_balloon_hinting_responses.go b/packages/shared/pkg/fc/client/operations/describe_balloon_hinting_responses.go new file mode 100644 index 0000000000..c5be936f3b --- /dev/null +++ b/packages/shared/pkg/fc/client/operations/describe_balloon_hinting_responses.go @@ -0,0 +1,261 @@ +// Code generated by go-swagger; DO NOT EDIT. + +package operations + +import ( + "encoding/json" + stderrors "errors" + "fmt" + "io" + + "github.com/go-openapi/runtime" + "github.com/go-openapi/strfmt" + + "github.com/e2b-dev/infra/packages/shared/pkg/fc/models" +) + +// DescribeBalloonHintingReader is a Reader for the DescribeBalloonHinting structure. +type DescribeBalloonHintingReader struct { + formats strfmt.Registry +} + +// ReadResponse reads a server response into the received o. +func (o *DescribeBalloonHintingReader) ReadResponse(response runtime.ClientResponse, consumer runtime.Consumer) (any, error) { + switch response.Code() { + case 200: + result := NewDescribeBalloonHintingOK() + if err := result.readResponse(response, consumer, o.formats); err != nil { + return nil, err + } + return result, nil + case 400: + result := NewDescribeBalloonHintingBadRequest() + if err := result.readResponse(response, consumer, o.formats); err != nil { + return nil, err + } + return nil, result + default: + result := NewDescribeBalloonHintingDefault(response.Code()) + if err := result.readResponse(response, consumer, o.formats); err != nil { + return nil, err + } + if response.Code()/100 == 2 { + return result, nil + } + return nil, result + } +} + +// NewDescribeBalloonHintingOK creates a DescribeBalloonHintingOK with default headers values +func NewDescribeBalloonHintingOK() *DescribeBalloonHintingOK { + return &DescribeBalloonHintingOK{} +} + +/* +DescribeBalloonHintingOK describes a response with status code 200, with default header values. + +The balloon free page hinting statistics +*/ +type DescribeBalloonHintingOK struct { + Payload *models.BalloonHintingStatus +} + +// IsSuccess returns true when this describe balloon hinting o k response has a 2xx status code +func (o *DescribeBalloonHintingOK) IsSuccess() bool { + return true +} + +// IsRedirect returns true when this describe balloon hinting o k response has a 3xx status code +func (o *DescribeBalloonHintingOK) IsRedirect() bool { + return false +} + +// IsClientError returns true when this describe balloon hinting o k response has a 4xx status code +func (o *DescribeBalloonHintingOK) IsClientError() bool { + return false +} + +// IsServerError returns true when this describe balloon hinting o k response has a 5xx status code +func (o *DescribeBalloonHintingOK) IsServerError() bool { + return false +} + +// IsCode returns true when this describe balloon hinting o k response a status code equal to that given +func (o *DescribeBalloonHintingOK) IsCode(code int) bool { + return code == 200 +} + +// Code gets the status code for the describe balloon hinting o k response +func (o *DescribeBalloonHintingOK) Code() int { + return 200 +} + +func (o *DescribeBalloonHintingOK) Error() string { + payload, _ := json.Marshal(o.Payload) + return fmt.Sprintf("[GET /balloon/hinting/status][%d] describeBalloonHintingOK %s", 200, payload) +} + +func (o *DescribeBalloonHintingOK) String() string { + payload, _ := json.Marshal(o.Payload) + return fmt.Sprintf("[GET /balloon/hinting/status][%d] describeBalloonHintingOK %s", 200, payload) +} + +func (o *DescribeBalloonHintingOK) GetPayload() *models.BalloonHintingStatus { + return o.Payload +} + +func (o *DescribeBalloonHintingOK) readResponse(response runtime.ClientResponse, consumer runtime.Consumer, formats strfmt.Registry) error { + + o.Payload = new(models.BalloonHintingStatus) + + // response payload + if err := consumer.Consume(response.Body(), o.Payload); err != nil && !stderrors.Is(err, io.EOF) { + return err + } + + return nil +} + +// NewDescribeBalloonHintingBadRequest creates a DescribeBalloonHintingBadRequest with default headers values +func NewDescribeBalloonHintingBadRequest() *DescribeBalloonHintingBadRequest { + return &DescribeBalloonHintingBadRequest{} +} + +/* +DescribeBalloonHintingBadRequest describes a response with status code 400, with default header values. + +The balloon free hinting was not enabled when the device was configured. +*/ +type DescribeBalloonHintingBadRequest struct { + Payload *models.Error +} + +// IsSuccess returns true when this describe balloon hinting bad request response has a 2xx status code +func (o *DescribeBalloonHintingBadRequest) IsSuccess() bool { + return false +} + +// IsRedirect returns true when this describe balloon hinting bad request response has a 3xx status code +func (o *DescribeBalloonHintingBadRequest) IsRedirect() bool { + return false +} + +// IsClientError returns true when this describe balloon hinting bad request response has a 4xx status code +func (o *DescribeBalloonHintingBadRequest) IsClientError() bool { + return true +} + +// IsServerError returns true when this describe balloon hinting bad request response has a 5xx status code +func (o *DescribeBalloonHintingBadRequest) IsServerError() bool { + return false +} + +// IsCode returns true when this describe balloon hinting bad request response a status code equal to that given +func (o *DescribeBalloonHintingBadRequest) IsCode(code int) bool { + return code == 400 +} + +// Code gets the status code for the describe balloon hinting bad request response +func (o *DescribeBalloonHintingBadRequest) Code() int { + return 400 +} + +func (o *DescribeBalloonHintingBadRequest) Error() string { + payload, _ := json.Marshal(o.Payload) + return fmt.Sprintf("[GET /balloon/hinting/status][%d] describeBalloonHintingBadRequest %s", 400, payload) +} + +func (o *DescribeBalloonHintingBadRequest) String() string { + payload, _ := json.Marshal(o.Payload) + return fmt.Sprintf("[GET /balloon/hinting/status][%d] describeBalloonHintingBadRequest %s", 400, payload) +} + +func (o *DescribeBalloonHintingBadRequest) GetPayload() *models.Error { + return o.Payload +} + +func (o *DescribeBalloonHintingBadRequest) readResponse(response runtime.ClientResponse, consumer runtime.Consumer, formats strfmt.Registry) error { + + o.Payload = new(models.Error) + + // response payload + if err := consumer.Consume(response.Body(), o.Payload); err != nil && !stderrors.Is(err, io.EOF) { + return err + } + + return nil +} + +// NewDescribeBalloonHintingDefault creates a DescribeBalloonHintingDefault with default headers values +func NewDescribeBalloonHintingDefault(code int) *DescribeBalloonHintingDefault { + return &DescribeBalloonHintingDefault{ + _statusCode: code, + } +} + +/* +DescribeBalloonHintingDefault describes a response with status code -1, with default header values. + +Internal Server Error +*/ +type DescribeBalloonHintingDefault struct { + _statusCode int + + Payload *models.Error +} + +// IsSuccess returns true when this describe balloon hinting default response has a 2xx status code +func (o *DescribeBalloonHintingDefault) IsSuccess() bool { + return o._statusCode/100 == 2 +} + +// IsRedirect returns true when this describe balloon hinting default response has a 3xx status code +func (o *DescribeBalloonHintingDefault) IsRedirect() bool { + return o._statusCode/100 == 3 +} + +// IsClientError returns true when this describe balloon hinting default response has a 4xx status code +func (o *DescribeBalloonHintingDefault) IsClientError() bool { + return o._statusCode/100 == 4 +} + +// IsServerError returns true when this describe balloon hinting default response has a 5xx status code +func (o *DescribeBalloonHintingDefault) IsServerError() bool { + return o._statusCode/100 == 5 +} + +// IsCode returns true when this describe balloon hinting default response a status code equal to that given +func (o *DescribeBalloonHintingDefault) IsCode(code int) bool { + return o._statusCode == code +} + +// Code gets the status code for the describe balloon hinting default response +func (o *DescribeBalloonHintingDefault) Code() int { + return o._statusCode +} + +func (o *DescribeBalloonHintingDefault) Error() string { + payload, _ := json.Marshal(o.Payload) + return fmt.Sprintf("[GET /balloon/hinting/status][%d] describeBalloonHinting default %s", o._statusCode, payload) +} + +func (o *DescribeBalloonHintingDefault) String() string { + payload, _ := json.Marshal(o.Payload) + return fmt.Sprintf("[GET /balloon/hinting/status][%d] describeBalloonHinting default %s", o._statusCode, payload) +} + +func (o *DescribeBalloonHintingDefault) GetPayload() *models.Error { + return o.Payload +} + +func (o *DescribeBalloonHintingDefault) readResponse(response runtime.ClientResponse, consumer runtime.Consumer, formats strfmt.Registry) error { + + o.Payload = new(models.Error) + + // response payload + if err := consumer.Consume(response.Body(), o.Payload); err != nil && !stderrors.Is(err, io.EOF) { + return err + } + + return nil +} diff --git a/packages/shared/pkg/fc/client/operations/get_memory_dirty_parameters.go b/packages/shared/pkg/fc/client/operations/get_memory_dirty_parameters.go deleted file mode 100644 index 2838328ece..0000000000 --- a/packages/shared/pkg/fc/client/operations/get_memory_dirty_parameters.go +++ /dev/null @@ -1,125 +0,0 @@ -// Code generated by go-swagger; DO NOT EDIT. - -package operations - -import ( - "context" - "net/http" - "time" - - "github.com/go-openapi/errors" - "github.com/go-openapi/runtime" - cr "github.com/go-openapi/runtime/client" - "github.com/go-openapi/strfmt" -) - -// NewGetMemoryDirtyParams creates a new GetMemoryDirtyParams object, -// with the default timeout for this client. -// -// Default values are not hydrated, since defaults are normally applied by the API server side. -// -// To enforce default values in parameter, use SetDefaults or WithDefaults. -func NewGetMemoryDirtyParams() *GetMemoryDirtyParams { - return &GetMemoryDirtyParams{ - timeout: cr.DefaultTimeout, - } -} - -// NewGetMemoryDirtyParamsWithTimeout creates a new GetMemoryDirtyParams object -// with the ability to set a timeout on a request. -func NewGetMemoryDirtyParamsWithTimeout(timeout time.Duration) *GetMemoryDirtyParams { - return &GetMemoryDirtyParams{ - timeout: timeout, - } -} - -// NewGetMemoryDirtyParamsWithContext creates a new GetMemoryDirtyParams object -// with the ability to set a context for a request. -func NewGetMemoryDirtyParamsWithContext(ctx context.Context) *GetMemoryDirtyParams { - return &GetMemoryDirtyParams{ - Context: ctx, - } -} - -// NewGetMemoryDirtyParamsWithHTTPClient creates a new GetMemoryDirtyParams object -// with the ability to set a custom HTTPClient for a request. -func NewGetMemoryDirtyParamsWithHTTPClient(client *http.Client) *GetMemoryDirtyParams { - return &GetMemoryDirtyParams{ - HTTPClient: client, - } -} - -/* -GetMemoryDirtyParams contains all the parameters to send to the API endpoint - - for the get memory dirty operation. - - Typically these are written to a http.Request. -*/ -type GetMemoryDirtyParams struct { - timeout time.Duration - Context context.Context - HTTPClient *http.Client -} - -// WithDefaults hydrates default values in the get memory dirty params (not the query body). -// -// All values with no default are reset to their zero value. -func (o *GetMemoryDirtyParams) WithDefaults() *GetMemoryDirtyParams { - o.SetDefaults() - return o -} - -// SetDefaults hydrates default values in the get memory dirty params (not the query body). -// -// All values with no default are reset to their zero value. -func (o *GetMemoryDirtyParams) SetDefaults() { - // no default values defined for this parameter -} - -// WithTimeout adds the timeout to the get memory dirty params -func (o *GetMemoryDirtyParams) WithTimeout(timeout time.Duration) *GetMemoryDirtyParams { - o.SetTimeout(timeout) - return o -} - -// SetTimeout adds the timeout to the get memory dirty params -func (o *GetMemoryDirtyParams) SetTimeout(timeout time.Duration) { - o.timeout = timeout -} - -// WithContext adds the context to the get memory dirty params -func (o *GetMemoryDirtyParams) WithContext(ctx context.Context) *GetMemoryDirtyParams { - o.SetContext(ctx) - return o -} - -// SetContext adds the context to the get memory dirty params -func (o *GetMemoryDirtyParams) SetContext(ctx context.Context) { - o.Context = ctx -} - -// WithHTTPClient adds the HTTPClient to the get memory dirty params -func (o *GetMemoryDirtyParams) WithHTTPClient(client *http.Client) *GetMemoryDirtyParams { - o.SetHTTPClient(client) - return o -} - -// SetHTTPClient adds the HTTPClient to the get memory dirty params -func (o *GetMemoryDirtyParams) SetHTTPClient(client *http.Client) { - o.HTTPClient = client -} - -// WriteToRequest writes these params to a swagger request -func (o *GetMemoryDirtyParams) WriteToRequest(r runtime.ClientRequest, reg strfmt.Registry) error { - - if err := r.SetTimeout(o.timeout); err != nil { - return err - } - var res []error - - if len(res) > 0 { - return errors.CompositeValidationError(res...) - } - return nil -} diff --git a/packages/shared/pkg/fc/client/operations/get_memory_dirty_responses.go b/packages/shared/pkg/fc/client/operations/get_memory_dirty_responses.go deleted file mode 100644 index c3df69bfb4..0000000000 --- a/packages/shared/pkg/fc/client/operations/get_memory_dirty_responses.go +++ /dev/null @@ -1,261 +0,0 @@ -// Code generated by go-swagger; DO NOT EDIT. - -package operations - -import ( - "encoding/json" - stderrors "errors" - "fmt" - "io" - - "github.com/go-openapi/runtime" - "github.com/go-openapi/strfmt" - - "github.com/e2b-dev/infra/packages/shared/pkg/fc/models" -) - -// GetMemoryDirtyReader is a Reader for the GetMemoryDirty structure. -type GetMemoryDirtyReader struct { - formats strfmt.Registry -} - -// ReadResponse reads a server response into the received o. -func (o *GetMemoryDirtyReader) ReadResponse(response runtime.ClientResponse, consumer runtime.Consumer) (any, error) { - switch response.Code() { - case 200: - result := NewGetMemoryDirtyOK() - if err := result.readResponse(response, consumer, o.formats); err != nil { - return nil, err - } - return result, nil - case 400: - result := NewGetMemoryDirtyBadRequest() - if err := result.readResponse(response, consumer, o.formats); err != nil { - return nil, err - } - return nil, result - default: - result := NewGetMemoryDirtyDefault(response.Code()) - if err := result.readResponse(response, consumer, o.formats); err != nil { - return nil, err - } - if response.Code()/100 == 2 { - return result, nil - } - return nil, result - } -} - -// NewGetMemoryDirtyOK creates a GetMemoryDirtyOK with default headers values -func NewGetMemoryDirtyOK() *GetMemoryDirtyOK { - return &GetMemoryDirtyOK{} -} - -/* -GetMemoryDirtyOK describes a response with status code 200, with default header values. - -OK -*/ -type GetMemoryDirtyOK struct { - Payload *models.MemoryDirty -} - -// IsSuccess returns true when this get memory dirty o k response has a 2xx status code -func (o *GetMemoryDirtyOK) IsSuccess() bool { - return true -} - -// IsRedirect returns true when this get memory dirty o k response has a 3xx status code -func (o *GetMemoryDirtyOK) IsRedirect() bool { - return false -} - -// IsClientError returns true when this get memory dirty o k response has a 4xx status code -func (o *GetMemoryDirtyOK) IsClientError() bool { - return false -} - -// IsServerError returns true when this get memory dirty o k response has a 5xx status code -func (o *GetMemoryDirtyOK) IsServerError() bool { - return false -} - -// IsCode returns true when this get memory dirty o k response a status code equal to that given -func (o *GetMemoryDirtyOK) IsCode(code int) bool { - return code == 200 -} - -// Code gets the status code for the get memory dirty o k response -func (o *GetMemoryDirtyOK) Code() int { - return 200 -} - -func (o *GetMemoryDirtyOK) Error() string { - payload, _ := json.Marshal(o.Payload) - return fmt.Sprintf("[GET /memory/dirty][%d] getMemoryDirtyOK %s", 200, payload) -} - -func (o *GetMemoryDirtyOK) String() string { - payload, _ := json.Marshal(o.Payload) - return fmt.Sprintf("[GET /memory/dirty][%d] getMemoryDirtyOK %s", 200, payload) -} - -func (o *GetMemoryDirtyOK) GetPayload() *models.MemoryDirty { - return o.Payload -} - -func (o *GetMemoryDirtyOK) readResponse(response runtime.ClientResponse, consumer runtime.Consumer, formats strfmt.Registry) error { - - o.Payload = new(models.MemoryDirty) - - // response payload - if err := consumer.Consume(response.Body(), o.Payload); err != nil && !stderrors.Is(err, io.EOF) { - return err - } - - return nil -} - -// NewGetMemoryDirtyBadRequest creates a GetMemoryDirtyBadRequest with default headers values -func NewGetMemoryDirtyBadRequest() *GetMemoryDirtyBadRequest { - return &GetMemoryDirtyBadRequest{} -} - -/* -GetMemoryDirtyBadRequest describes a response with status code 400, with default header values. - -The microVM is not paused. -*/ -type GetMemoryDirtyBadRequest struct { - Payload *models.Error -} - -// IsSuccess returns true when this get memory dirty bad request response has a 2xx status code -func (o *GetMemoryDirtyBadRequest) IsSuccess() bool { - return false -} - -// IsRedirect returns true when this get memory dirty bad request response has a 3xx status code -func (o *GetMemoryDirtyBadRequest) IsRedirect() bool { - return false -} - -// IsClientError returns true when this get memory dirty bad request response has a 4xx status code -func (o *GetMemoryDirtyBadRequest) IsClientError() bool { - return true -} - -// IsServerError returns true when this get memory dirty bad request response has a 5xx status code -func (o *GetMemoryDirtyBadRequest) IsServerError() bool { - return false -} - -// IsCode returns true when this get memory dirty bad request response a status code equal to that given -func (o *GetMemoryDirtyBadRequest) IsCode(code int) bool { - return code == 400 -} - -// Code gets the status code for the get memory dirty bad request response -func (o *GetMemoryDirtyBadRequest) Code() int { - return 400 -} - -func (o *GetMemoryDirtyBadRequest) Error() string { - payload, _ := json.Marshal(o.Payload) - return fmt.Sprintf("[GET /memory/dirty][%d] getMemoryDirtyBadRequest %s", 400, payload) -} - -func (o *GetMemoryDirtyBadRequest) String() string { - payload, _ := json.Marshal(o.Payload) - return fmt.Sprintf("[GET /memory/dirty][%d] getMemoryDirtyBadRequest %s", 400, payload) -} - -func (o *GetMemoryDirtyBadRequest) GetPayload() *models.Error { - return o.Payload -} - -func (o *GetMemoryDirtyBadRequest) readResponse(response runtime.ClientResponse, consumer runtime.Consumer, formats strfmt.Registry) error { - - o.Payload = new(models.Error) - - // response payload - if err := consumer.Consume(response.Body(), o.Payload); err != nil && !stderrors.Is(err, io.EOF) { - return err - } - - return nil -} - -// NewGetMemoryDirtyDefault creates a GetMemoryDirtyDefault with default headers values -func NewGetMemoryDirtyDefault(code int) *GetMemoryDirtyDefault { - return &GetMemoryDirtyDefault{ - _statusCode: code, - } -} - -/* -GetMemoryDirtyDefault describes a response with status code -1, with default header values. - -Internal server error -*/ -type GetMemoryDirtyDefault struct { - _statusCode int - - Payload *models.Error -} - -// IsSuccess returns true when this get memory dirty default response has a 2xx status code -func (o *GetMemoryDirtyDefault) IsSuccess() bool { - return o._statusCode/100 == 2 -} - -// IsRedirect returns true when this get memory dirty default response has a 3xx status code -func (o *GetMemoryDirtyDefault) IsRedirect() bool { - return o._statusCode/100 == 3 -} - -// IsClientError returns true when this get memory dirty default response has a 4xx status code -func (o *GetMemoryDirtyDefault) IsClientError() bool { - return o._statusCode/100 == 4 -} - -// IsServerError returns true when this get memory dirty default response has a 5xx status code -func (o *GetMemoryDirtyDefault) IsServerError() bool { - return o._statusCode/100 == 5 -} - -// IsCode returns true when this get memory dirty default response a status code equal to that given -func (o *GetMemoryDirtyDefault) IsCode(code int) bool { - return o._statusCode == code -} - -// Code gets the status code for the get memory dirty default response -func (o *GetMemoryDirtyDefault) Code() int { - return o._statusCode -} - -func (o *GetMemoryDirtyDefault) Error() string { - payload, _ := json.Marshal(o.Payload) - return fmt.Sprintf("[GET /memory/dirty][%d] getMemoryDirty default %s", o._statusCode, payload) -} - -func (o *GetMemoryDirtyDefault) String() string { - payload, _ := json.Marshal(o.Payload) - return fmt.Sprintf("[GET /memory/dirty][%d] getMemoryDirty default %s", o._statusCode, payload) -} - -func (o *GetMemoryDirtyDefault) GetPayload() *models.Error { - return o.Payload -} - -func (o *GetMemoryDirtyDefault) readResponse(response runtime.ClientResponse, consumer runtime.Consumer, formats strfmt.Registry) error { - - o.Payload = new(models.Error) - - // response payload - if err := consumer.Consume(response.Body(), o.Payload); err != nil && !stderrors.Is(err, io.EOF) { - return err - } - - return nil -} diff --git a/packages/shared/pkg/fc/client/operations/get_memory_hotplug_parameters.go b/packages/shared/pkg/fc/client/operations/get_memory_hotplug_parameters.go new file mode 100644 index 0000000000..225d750e0f --- /dev/null +++ b/packages/shared/pkg/fc/client/operations/get_memory_hotplug_parameters.go @@ -0,0 +1,125 @@ +// Code generated by go-swagger; DO NOT EDIT. + +package operations + +import ( + "context" + "net/http" + "time" + + "github.com/go-openapi/errors" + "github.com/go-openapi/runtime" + cr "github.com/go-openapi/runtime/client" + "github.com/go-openapi/strfmt" +) + +// NewGetMemoryHotplugParams creates a new GetMemoryHotplugParams object, +// with the default timeout for this client. +// +// Default values are not hydrated, since defaults are normally applied by the API server side. +// +// To enforce default values in parameter, use SetDefaults or WithDefaults. +func NewGetMemoryHotplugParams() *GetMemoryHotplugParams { + return &GetMemoryHotplugParams{ + timeout: cr.DefaultTimeout, + } +} + +// NewGetMemoryHotplugParamsWithTimeout creates a new GetMemoryHotplugParams object +// with the ability to set a timeout on a request. +func NewGetMemoryHotplugParamsWithTimeout(timeout time.Duration) *GetMemoryHotplugParams { + return &GetMemoryHotplugParams{ + timeout: timeout, + } +} + +// NewGetMemoryHotplugParamsWithContext creates a new GetMemoryHotplugParams object +// with the ability to set a context for a request. +func NewGetMemoryHotplugParamsWithContext(ctx context.Context) *GetMemoryHotplugParams { + return &GetMemoryHotplugParams{ + Context: ctx, + } +} + +// NewGetMemoryHotplugParamsWithHTTPClient creates a new GetMemoryHotplugParams object +// with the ability to set a custom HTTPClient for a request. +func NewGetMemoryHotplugParamsWithHTTPClient(client *http.Client) *GetMemoryHotplugParams { + return &GetMemoryHotplugParams{ + HTTPClient: client, + } +} + +/* +GetMemoryHotplugParams contains all the parameters to send to the API endpoint + + for the get memory hotplug operation. + + Typically these are written to a http.Request. +*/ +type GetMemoryHotplugParams struct { + timeout time.Duration + Context context.Context + HTTPClient *http.Client +} + +// WithDefaults hydrates default values in the get memory hotplug params (not the query body). +// +// All values with no default are reset to their zero value. +func (o *GetMemoryHotplugParams) WithDefaults() *GetMemoryHotplugParams { + o.SetDefaults() + return o +} + +// SetDefaults hydrates default values in the get memory hotplug params (not the query body). +// +// All values with no default are reset to their zero value. +func (o *GetMemoryHotplugParams) SetDefaults() { + // no default values defined for this parameter +} + +// WithTimeout adds the timeout to the get memory hotplug params +func (o *GetMemoryHotplugParams) WithTimeout(timeout time.Duration) *GetMemoryHotplugParams { + o.SetTimeout(timeout) + return o +} + +// SetTimeout adds the timeout to the get memory hotplug params +func (o *GetMemoryHotplugParams) SetTimeout(timeout time.Duration) { + o.timeout = timeout +} + +// WithContext adds the context to the get memory hotplug params +func (o *GetMemoryHotplugParams) WithContext(ctx context.Context) *GetMemoryHotplugParams { + o.SetContext(ctx) + return o +} + +// SetContext adds the context to the get memory hotplug params +func (o *GetMemoryHotplugParams) SetContext(ctx context.Context) { + o.Context = ctx +} + +// WithHTTPClient adds the HTTPClient to the get memory hotplug params +func (o *GetMemoryHotplugParams) WithHTTPClient(client *http.Client) *GetMemoryHotplugParams { + o.SetHTTPClient(client) + return o +} + +// SetHTTPClient adds the HTTPClient to the get memory hotplug params +func (o *GetMemoryHotplugParams) SetHTTPClient(client *http.Client) { + o.HTTPClient = client +} + +// WriteToRequest writes these params to a swagger request +func (o *GetMemoryHotplugParams) WriteToRequest(r runtime.ClientRequest, reg strfmt.Registry) error { + + if err := r.SetTimeout(o.timeout); err != nil { + return err + } + var res []error + + if len(res) > 0 { + return errors.CompositeValidationError(res...) + } + return nil +} diff --git a/packages/shared/pkg/fc/client/operations/get_memory_hotplug_responses.go b/packages/shared/pkg/fc/client/operations/get_memory_hotplug_responses.go new file mode 100644 index 0000000000..69799f3747 --- /dev/null +++ b/packages/shared/pkg/fc/client/operations/get_memory_hotplug_responses.go @@ -0,0 +1,185 @@ +// Code generated by go-swagger; DO NOT EDIT. + +package operations + +import ( + "encoding/json" + stderrors "errors" + "fmt" + "io" + + "github.com/go-openapi/runtime" + "github.com/go-openapi/strfmt" + + "github.com/e2b-dev/infra/packages/shared/pkg/fc/models" +) + +// GetMemoryHotplugReader is a Reader for the GetMemoryHotplug structure. +type GetMemoryHotplugReader struct { + formats strfmt.Registry +} + +// ReadResponse reads a server response into the received o. +func (o *GetMemoryHotplugReader) ReadResponse(response runtime.ClientResponse, consumer runtime.Consumer) (any, error) { + switch response.Code() { + case 200: + result := NewGetMemoryHotplugOK() + if err := result.readResponse(response, consumer, o.formats); err != nil { + return nil, err + } + return result, nil + default: + result := NewGetMemoryHotplugDefault(response.Code()) + if err := result.readResponse(response, consumer, o.formats); err != nil { + return nil, err + } + if response.Code()/100 == 2 { + return result, nil + } + return nil, result + } +} + +// NewGetMemoryHotplugOK creates a GetMemoryHotplugOK with default headers values +func NewGetMemoryHotplugOK() *GetMemoryHotplugOK { + return &GetMemoryHotplugOK{} +} + +/* +GetMemoryHotplugOK describes a response with status code 200, with default header values. + +OK +*/ +type GetMemoryHotplugOK struct { + Payload *models.MemoryHotplugStatus +} + +// IsSuccess returns true when this get memory hotplug o k response has a 2xx status code +func (o *GetMemoryHotplugOK) IsSuccess() bool { + return true +} + +// IsRedirect returns true when this get memory hotplug o k response has a 3xx status code +func (o *GetMemoryHotplugOK) IsRedirect() bool { + return false +} + +// IsClientError returns true when this get memory hotplug o k response has a 4xx status code +func (o *GetMemoryHotplugOK) IsClientError() bool { + return false +} + +// IsServerError returns true when this get memory hotplug o k response has a 5xx status code +func (o *GetMemoryHotplugOK) IsServerError() bool { + return false +} + +// IsCode returns true when this get memory hotplug o k response a status code equal to that given +func (o *GetMemoryHotplugOK) IsCode(code int) bool { + return code == 200 +} + +// Code gets the status code for the get memory hotplug o k response +func (o *GetMemoryHotplugOK) Code() int { + return 200 +} + +func (o *GetMemoryHotplugOK) Error() string { + payload, _ := json.Marshal(o.Payload) + return fmt.Sprintf("[GET /hotplug/memory][%d] getMemoryHotplugOK %s", 200, payload) +} + +func (o *GetMemoryHotplugOK) String() string { + payload, _ := json.Marshal(o.Payload) + return fmt.Sprintf("[GET /hotplug/memory][%d] getMemoryHotplugOK %s", 200, payload) +} + +func (o *GetMemoryHotplugOK) GetPayload() *models.MemoryHotplugStatus { + return o.Payload +} + +func (o *GetMemoryHotplugOK) readResponse(response runtime.ClientResponse, consumer runtime.Consumer, formats strfmt.Registry) error { + + o.Payload = new(models.MemoryHotplugStatus) + + // response payload + if err := consumer.Consume(response.Body(), o.Payload); err != nil && !stderrors.Is(err, io.EOF) { + return err + } + + return nil +} + +// NewGetMemoryHotplugDefault creates a GetMemoryHotplugDefault with default headers values +func NewGetMemoryHotplugDefault(code int) *GetMemoryHotplugDefault { + return &GetMemoryHotplugDefault{ + _statusCode: code, + } +} + +/* +GetMemoryHotplugDefault describes a response with status code -1, with default header values. + +Internal server error +*/ +type GetMemoryHotplugDefault struct { + _statusCode int + + Payload *models.Error +} + +// IsSuccess returns true when this get memory hotplug default response has a 2xx status code +func (o *GetMemoryHotplugDefault) IsSuccess() bool { + return o._statusCode/100 == 2 +} + +// IsRedirect returns true when this get memory hotplug default response has a 3xx status code +func (o *GetMemoryHotplugDefault) IsRedirect() bool { + return o._statusCode/100 == 3 +} + +// IsClientError returns true when this get memory hotplug default response has a 4xx status code +func (o *GetMemoryHotplugDefault) IsClientError() bool { + return o._statusCode/100 == 4 +} + +// IsServerError returns true when this get memory hotplug default response has a 5xx status code +func (o *GetMemoryHotplugDefault) IsServerError() bool { + return o._statusCode/100 == 5 +} + +// IsCode returns true when this get memory hotplug default response a status code equal to that given +func (o *GetMemoryHotplugDefault) IsCode(code int) bool { + return o._statusCode == code +} + +// Code gets the status code for the get memory hotplug default response +func (o *GetMemoryHotplugDefault) Code() int { + return o._statusCode +} + +func (o *GetMemoryHotplugDefault) Error() string { + payload, _ := json.Marshal(o.Payload) + return fmt.Sprintf("[GET /hotplug/memory][%d] getMemoryHotplug default %s", o._statusCode, payload) +} + +func (o *GetMemoryHotplugDefault) String() string { + payload, _ := json.Marshal(o.Payload) + return fmt.Sprintf("[GET /hotplug/memory][%d] getMemoryHotplug default %s", o._statusCode, payload) +} + +func (o *GetMemoryHotplugDefault) GetPayload() *models.Error { + return o.Payload +} + +func (o *GetMemoryHotplugDefault) readResponse(response runtime.ClientResponse, consumer runtime.Consumer, formats strfmt.Registry) error { + + o.Payload = new(models.Error) + + // response payload + if err := consumer.Consume(response.Body(), o.Payload); err != nil && !stderrors.Is(err, io.EOF) { + return err + } + + return nil +} diff --git a/packages/shared/pkg/fc/client/operations/load_snapshot_parameters.go b/packages/shared/pkg/fc/client/operations/load_snapshot_parameters.go index 5067fee113..df1f826f67 100644 --- a/packages/shared/pkg/fc/client/operations/load_snapshot_parameters.go +++ b/packages/shared/pkg/fc/client/operations/load_snapshot_parameters.go @@ -62,7 +62,7 @@ type LoadSnapshotParams struct { /* Body. - The configuration used for loading a snaphot. + The configuration used for loading a snapshot. */ Body *models.SnapshotLoadParams diff --git a/packages/shared/pkg/fc/client/operations/operations_client.go b/packages/shared/pkg/fc/client/operations/operations_client.go index ead938ce2e..d29a2e37f1 100644 --- a/packages/shared/pkg/fc/client/operations/operations_client.go +++ b/packages/shared/pkg/fc/client/operations/operations_client.go @@ -57,6 +57,8 @@ type ClientService interface { DescribeBalloonConfig(params *DescribeBalloonConfigParams, opts ...ClientOption) (*DescribeBalloonConfigOK, error) + DescribeBalloonHinting(params *DescribeBalloonHintingParams, opts ...ClientOption) (*DescribeBalloonHintingOK, error) + DescribeBalloonStats(params *DescribeBalloonStatsParams, opts ...ClientOption) (*DescribeBalloonStatsOK, error) DescribeInstance(params *DescribeInstanceParams, opts ...ClientOption) (*DescribeInstanceOK, error) @@ -71,6 +73,8 @@ type ClientService interface { GetMemory(params *GetMemoryParams, opts ...ClientOption) (*GetMemoryOK, error) + GetMemoryHotplug(params *GetMemoryHotplugParams, opts ...ClientOption) (*GetMemoryHotplugOK, error) + GetMemoryMappings(params *GetMemoryMappingsParams, opts ...ClientOption) (*GetMemoryMappingsOK, error) GetMmds(params *GetMmdsParams, opts ...ClientOption) (*GetMmdsOK, error) @@ -87,6 +91,8 @@ type ClientService interface { PatchMachineConfiguration(params *PatchMachineConfigurationParams, opts ...ClientOption) (*PatchMachineConfigurationNoContent, error) + PatchMemoryHotplug(params *PatchMemoryHotplugParams, opts ...ClientOption) (*PatchMemoryHotplugNoContent, error) + PatchMmds(params *PatchMmdsParams, opts ...ClientOption) (*PatchMmdsNoContent, error) PatchVM(params *PatchVMParams, opts ...ClientOption) (*PatchVMNoContent, error) @@ -103,18 +109,28 @@ type ClientService interface { PutGuestNetworkInterfaceByID(params *PutGuestNetworkInterfaceByIDParams, opts ...ClientOption) (*PutGuestNetworkInterfaceByIDNoContent, error) + PutGuestPmemByID(params *PutGuestPmemByIDParams, opts ...ClientOption) (*PutGuestPmemByIDNoContent, error) + PutGuestVsock(params *PutGuestVsockParams, opts ...ClientOption) (*PutGuestVsockNoContent, error) PutLogger(params *PutLoggerParams, opts ...ClientOption) (*PutLoggerNoContent, error) PutMachineConfiguration(params *PutMachineConfigurationParams, opts ...ClientOption) (*PutMachineConfigurationNoContent, error) + PutMemoryHotplug(params *PutMemoryHotplugParams, opts ...ClientOption) (*PutMemoryHotplugNoContent, error) + PutMetrics(params *PutMetricsParams, opts ...ClientOption) (*PutMetricsNoContent, error) PutMmds(params *PutMmdsParams, opts ...ClientOption) (*PutMmdsNoContent, error) PutMmdsConfig(params *PutMmdsConfigParams, opts ...ClientOption) (*PutMmdsConfigNoContent, error) + PutSerialDevice(params *PutSerialDeviceParams, opts ...ClientOption) (*PutSerialDeviceNoContent, error) + + StartBalloonHinting(params *StartBalloonHintingParams, opts ...ClientOption) (*StartBalloonHintingOK, error) + + StopBalloonHinting(params *StopBalloonHintingParams, opts ...ClientOption) (*StopBalloonHintingOK, error) + SetTransport(transport runtime.ClientTransport) } @@ -246,6 +262,48 @@ func (a *Client) DescribeBalloonConfig(params *DescribeBalloonConfigParams, opts return nil, runtime.NewAPIError("unexpected success response: content available as default response in error", unexpectedSuccess, unexpectedSuccess.Code()) } +/* +DescribeBalloonHinting returns the balloon hinting statistics only if enabled pre boot +*/ +func (a *Client) DescribeBalloonHinting(params *DescribeBalloonHintingParams, opts ...ClientOption) (*DescribeBalloonHintingOK, error) { + // NOTE: parameters are not validated before sending + if params == nil { + params = NewDescribeBalloonHintingParams() + } + op := &runtime.ClientOperation{ + ID: "describeBalloonHinting", + Method: "GET", + PathPattern: "/balloon/hinting/status", + ProducesMediaTypes: []string{"application/json"}, + ConsumesMediaTypes: []string{"application/json"}, + Schemes: []string{"http"}, + Params: params, + Reader: &DescribeBalloonHintingReader{formats: a.formats}, + Context: params.Context, + Client: params.HTTPClient, + } + for _, opt := range opts { + opt(op) + } + result, err := a.transport.Submit(op) + if err != nil { + return nil, err + } + + // only one success response has to be checked + success, ok := result.(*DescribeBalloonHintingOK) + if ok { + return success, nil + } + + // unexpected success response. + // + // a default response is provided: fill this and return an error + unexpectedSuccess := result.(*DescribeBalloonHintingDefault) + + return nil, runtime.NewAPIError("unexpected success response: content available as default response in error", unexpectedSuccess, unexpectedSuccess.Code()) +} + /* DescribeBalloonStats returns the latest balloon device statistics only if enabled pre boot */ @@ -548,6 +606,50 @@ func (a *Client) GetMemory(params *GetMemoryParams, opts ...ClientOption) (*GetM return nil, runtime.NewAPIError("unexpected success response: content available as default response in error", unexpectedSuccess, unexpectedSuccess.Code()) } +/* +GetMemoryHotplug retrieves the status of the hotpluggable memory + +Reuturn the status of the hotpluggable memory. This can be used to follow the progress of the guest after a PATCH API. +*/ +func (a *Client) GetMemoryHotplug(params *GetMemoryHotplugParams, opts ...ClientOption) (*GetMemoryHotplugOK, error) { + // NOTE: parameters are not validated before sending + if params == nil { + params = NewGetMemoryHotplugParams() + } + op := &runtime.ClientOperation{ + ID: "getMemoryHotplug", + Method: "GET", + PathPattern: "/hotplug/memory", + ProducesMediaTypes: []string{"application/json"}, + ConsumesMediaTypes: []string{"application/json"}, + Schemes: []string{"http"}, + Params: params, + Reader: &GetMemoryHotplugReader{formats: a.formats}, + Context: params.Context, + Client: params.HTTPClient, + } + for _, opt := range opts { + opt(op) + } + result, err := a.transport.Submit(op) + if err != nil { + return nil, err + } + + // only one success response has to be checked + success, ok := result.(*GetMemoryHotplugOK) + if ok { + return success, nil + } + + // unexpected success response. + // + // a default response is provided: fill this and return an error + unexpectedSuccess := result.(*GetMemoryHotplugDefault) + + return nil, runtime.NewAPIError("unexpected success response: content available as default response in error", unexpectedSuccess, unexpectedSuccess.Code()) +} + /* GetMemoryMappings gets the memory mappings with skippable pages bitmap */ @@ -896,6 +998,50 @@ func (a *Client) PatchMachineConfiguration(params *PatchMachineConfigurationPara return nil, runtime.NewAPIError("unexpected success response: content available as default response in error", unexpectedSuccess, unexpectedSuccess.Code()) } +/* +PatchMemoryHotplug updates the size of the hotpluggable memory region + +Updates the size of the hotpluggable memory region. The guest will plug and unplug memory to hit the requested memory. +*/ +func (a *Client) PatchMemoryHotplug(params *PatchMemoryHotplugParams, opts ...ClientOption) (*PatchMemoryHotplugNoContent, error) { + // NOTE: parameters are not validated before sending + if params == nil { + params = NewPatchMemoryHotplugParams() + } + op := &runtime.ClientOperation{ + ID: "patchMemoryHotplug", + Method: "PATCH", + PathPattern: "/hotplug/memory", + ProducesMediaTypes: []string{"application/json"}, + ConsumesMediaTypes: []string{"application/json"}, + Schemes: []string{"http"}, + Params: params, + Reader: &PatchMemoryHotplugReader{formats: a.formats}, + Context: params.Context, + Client: params.HTTPClient, + } + for _, opt := range opts { + opt(op) + } + result, err := a.transport.Submit(op) + if err != nil { + return nil, err + } + + // only one success response has to be checked + success, ok := result.(*PatchMemoryHotplugNoContent) + if ok { + return success, nil + } + + // unexpected success response. + // + // a default response is provided: fill this and return an error + unexpectedSuccess := result.(*PatchMemoryHotplugDefault) + + return nil, runtime.NewAPIError("unexpected success response: content available as default response in error", unexpectedSuccess, unexpectedSuccess.Code()) +} + /* PatchMmds updates the m m d s data store */ @@ -1246,6 +1392,50 @@ func (a *Client) PutGuestNetworkInterfaceByID(params *PutGuestNetworkInterfaceBy return nil, runtime.NewAPIError("unexpected success response: content available as default response in error", unexpectedSuccess, unexpectedSuccess.Code()) } +/* +PutGuestPmemByID creates or updates a pmem device pre boot only + +Creates new pmem device with ID specified by id parameter. If a pmem device with the specified ID already exists, updates its state based on new input. Will fail if update is not possible. +*/ +func (a *Client) PutGuestPmemByID(params *PutGuestPmemByIDParams, opts ...ClientOption) (*PutGuestPmemByIDNoContent, error) { + // NOTE: parameters are not validated before sending + if params == nil { + params = NewPutGuestPmemByIDParams() + } + op := &runtime.ClientOperation{ + ID: "putGuestPmemByID", + Method: "PUT", + PathPattern: "/pmem/{id}", + ProducesMediaTypes: []string{"application/json"}, + ConsumesMediaTypes: []string{"application/json"}, + Schemes: []string{"http"}, + Params: params, + Reader: &PutGuestPmemByIDReader{formats: a.formats}, + Context: params.Context, + Client: params.HTTPClient, + } + for _, opt := range opts { + opt(op) + } + result, err := a.transport.Submit(op) + if err != nil { + return nil, err + } + + // only one success response has to be checked + success, ok := result.(*PutGuestPmemByIDNoContent) + if ok { + return success, nil + } + + // unexpected success response. + // + // a default response is provided: fill this and return an error + unexpectedSuccess := result.(*PutGuestPmemByIDDefault) + + return nil, runtime.NewAPIError("unexpected success response: content available as default response in error", unexpectedSuccess, unexpectedSuccess.Code()) +} + /* PutGuestVsock creates updates a vsock device pre boot only @@ -1376,6 +1566,50 @@ func (a *Client) PutMachineConfiguration(params *PutMachineConfigurationParams, return nil, runtime.NewAPIError("unexpected success response: content available as default response in error", unexpectedSuccess, unexpectedSuccess.Code()) } +/* +PutMemoryHotplug configures the hotpluggable memory + +Configure the hotpluggable memory, which is a virtio-mem device, with an associated memory area that can be hot(un)plugged in the guest on demand using the PATCH API. +*/ +func (a *Client) PutMemoryHotplug(params *PutMemoryHotplugParams, opts ...ClientOption) (*PutMemoryHotplugNoContent, error) { + // NOTE: parameters are not validated before sending + if params == nil { + params = NewPutMemoryHotplugParams() + } + op := &runtime.ClientOperation{ + ID: "putMemoryHotplug", + Method: "PUT", + PathPattern: "/hotplug/memory", + ProducesMediaTypes: []string{"application/json"}, + ConsumesMediaTypes: []string{"application/json"}, + Schemes: []string{"http"}, + Params: params, + Reader: &PutMemoryHotplugReader{formats: a.formats}, + Context: params.Context, + Client: params.HTTPClient, + } + for _, opt := range opts { + opt(op) + } + result, err := a.transport.Submit(op) + if err != nil { + return nil, err + } + + // only one success response has to be checked + success, ok := result.(*PutMemoryHotplugNoContent) + if ok { + return success, nil + } + + // unexpected success response. + // + // a default response is provided: fill this and return an error + unexpectedSuccess := result.(*PutMemoryHotplugDefault) + + return nil, runtime.NewAPIError("unexpected success response: content available as default response in error", unexpectedSuccess, unexpectedSuccess.Code()) +} + /* PutMetrics initializes the metrics system by specifying a named pipe or a file for the metrics output */ @@ -1504,6 +1738,134 @@ func (a *Client) PutMmdsConfig(params *PutMmdsConfigParams, opts ...ClientOption return nil, runtime.NewAPIError("unexpected success response: content available as default response in error", unexpectedSuccess, unexpectedSuccess.Code()) } +/* +PutSerialDevice configures the serial console + +Configure the serial console, which the guest can write its kernel logs to. Has no effect if the serial console is not also enabled on the guest kernel command line +*/ +func (a *Client) PutSerialDevice(params *PutSerialDeviceParams, opts ...ClientOption) (*PutSerialDeviceNoContent, error) { + // NOTE: parameters are not validated before sending + if params == nil { + params = NewPutSerialDeviceParams() + } + op := &runtime.ClientOperation{ + ID: "putSerialDevice", + Method: "PUT", + PathPattern: "/serial", + ProducesMediaTypes: []string{"application/json"}, + ConsumesMediaTypes: []string{"application/json"}, + Schemes: []string{"http"}, + Params: params, + Reader: &PutSerialDeviceReader{formats: a.formats}, + Context: params.Context, + Client: params.HTTPClient, + } + for _, opt := range opts { + opt(op) + } + result, err := a.transport.Submit(op) + if err != nil { + return nil, err + } + + // only one success response has to be checked + success, ok := result.(*PutSerialDeviceNoContent) + if ok { + return success, nil + } + + // unexpected success response. + // + // a default response is provided: fill this and return an error + unexpectedSuccess := result.(*PutSerialDeviceDefault) + + return nil, runtime.NewAPIError("unexpected success response: content available as default response in error", unexpectedSuccess, unexpectedSuccess.Code()) +} + +/* +StartBalloonHinting starts a free page hinting run only if enabled pre boot +*/ +func (a *Client) StartBalloonHinting(params *StartBalloonHintingParams, opts ...ClientOption) (*StartBalloonHintingOK, error) { + // NOTE: parameters are not validated before sending + if params == nil { + params = NewStartBalloonHintingParams() + } + op := &runtime.ClientOperation{ + ID: "startBalloonHinting", + Method: "PATCH", + PathPattern: "/balloon/hinting/start", + ProducesMediaTypes: []string{"application/json"}, + ConsumesMediaTypes: []string{"application/json"}, + Schemes: []string{"http"}, + Params: params, + Reader: &StartBalloonHintingReader{formats: a.formats}, + Context: params.Context, + Client: params.HTTPClient, + } + for _, opt := range opts { + opt(op) + } + result, err := a.transport.Submit(op) + if err != nil { + return nil, err + } + + // only one success response has to be checked + success, ok := result.(*StartBalloonHintingOK) + if ok { + return success, nil + } + + // unexpected success response. + // + // a default response is provided: fill this and return an error + unexpectedSuccess := result.(*StartBalloonHintingDefault) + + return nil, runtime.NewAPIError("unexpected success response: content available as default response in error", unexpectedSuccess, unexpectedSuccess.Code()) +} + +/* +StopBalloonHinting stops a free page hinting run only if enabled pre boot +*/ +func (a *Client) StopBalloonHinting(params *StopBalloonHintingParams, opts ...ClientOption) (*StopBalloonHintingOK, error) { + // NOTE: parameters are not validated before sending + if params == nil { + params = NewStopBalloonHintingParams() + } + op := &runtime.ClientOperation{ + ID: "stopBalloonHinting", + Method: "PATCH", + PathPattern: "/balloon/hinting/stop", + ProducesMediaTypes: []string{"application/json"}, + ConsumesMediaTypes: []string{"application/json"}, + Schemes: []string{"http"}, + Params: params, + Reader: &StopBalloonHintingReader{formats: a.formats}, + Context: params.Context, + Client: params.HTTPClient, + } + for _, opt := range opts { + opt(op) + } + result, err := a.transport.Submit(op) + if err != nil { + return nil, err + } + + // only one success response has to be checked + success, ok := result.(*StopBalloonHintingOK) + if ok { + return success, nil + } + + // unexpected success response. + // + // a default response is provided: fill this and return an error + unexpectedSuccess := result.(*StopBalloonHintingDefault) + + return nil, runtime.NewAPIError("unexpected success response: content available as default response in error", unexpectedSuccess, unexpectedSuccess.Code()) +} + // SetTransport changes the transport on the client func (a *Client) SetTransport(transport runtime.ClientTransport) { a.transport = transport diff --git a/packages/shared/pkg/fc/client/operations/patch_memory_hotplug_parameters.go b/packages/shared/pkg/fc/client/operations/patch_memory_hotplug_parameters.go new file mode 100644 index 0000000000..ef741faebb --- /dev/null +++ b/packages/shared/pkg/fc/client/operations/patch_memory_hotplug_parameters.go @@ -0,0 +1,150 @@ +// Code generated by go-swagger; DO NOT EDIT. + +package operations + +import ( + "context" + "net/http" + "time" + + "github.com/go-openapi/errors" + "github.com/go-openapi/runtime" + cr "github.com/go-openapi/runtime/client" + "github.com/go-openapi/strfmt" + + "github.com/e2b-dev/infra/packages/shared/pkg/fc/models" +) + +// NewPatchMemoryHotplugParams creates a new PatchMemoryHotplugParams object, +// with the default timeout for this client. +// +// Default values are not hydrated, since defaults are normally applied by the API server side. +// +// To enforce default values in parameter, use SetDefaults or WithDefaults. +func NewPatchMemoryHotplugParams() *PatchMemoryHotplugParams { + return &PatchMemoryHotplugParams{ + timeout: cr.DefaultTimeout, + } +} + +// NewPatchMemoryHotplugParamsWithTimeout creates a new PatchMemoryHotplugParams object +// with the ability to set a timeout on a request. +func NewPatchMemoryHotplugParamsWithTimeout(timeout time.Duration) *PatchMemoryHotplugParams { + return &PatchMemoryHotplugParams{ + timeout: timeout, + } +} + +// NewPatchMemoryHotplugParamsWithContext creates a new PatchMemoryHotplugParams object +// with the ability to set a context for a request. +func NewPatchMemoryHotplugParamsWithContext(ctx context.Context) *PatchMemoryHotplugParams { + return &PatchMemoryHotplugParams{ + Context: ctx, + } +} + +// NewPatchMemoryHotplugParamsWithHTTPClient creates a new PatchMemoryHotplugParams object +// with the ability to set a custom HTTPClient for a request. +func NewPatchMemoryHotplugParamsWithHTTPClient(client *http.Client) *PatchMemoryHotplugParams { + return &PatchMemoryHotplugParams{ + HTTPClient: client, + } +} + +/* +PatchMemoryHotplugParams contains all the parameters to send to the API endpoint + + for the patch memory hotplug operation. + + Typically these are written to a http.Request. +*/ +type PatchMemoryHotplugParams struct { + + /* Body. + + Hotpluggable memory size update + */ + Body *models.MemoryHotplugSizeUpdate + + timeout time.Duration + Context context.Context + HTTPClient *http.Client +} + +// WithDefaults hydrates default values in the patch memory hotplug params (not the query body). +// +// All values with no default are reset to their zero value. +func (o *PatchMemoryHotplugParams) WithDefaults() *PatchMemoryHotplugParams { + o.SetDefaults() + return o +} + +// SetDefaults hydrates default values in the patch memory hotplug params (not the query body). +// +// All values with no default are reset to their zero value. +func (o *PatchMemoryHotplugParams) SetDefaults() { + // no default values defined for this parameter +} + +// WithTimeout adds the timeout to the patch memory hotplug params +func (o *PatchMemoryHotplugParams) WithTimeout(timeout time.Duration) *PatchMemoryHotplugParams { + o.SetTimeout(timeout) + return o +} + +// SetTimeout adds the timeout to the patch memory hotplug params +func (o *PatchMemoryHotplugParams) SetTimeout(timeout time.Duration) { + o.timeout = timeout +} + +// WithContext adds the context to the patch memory hotplug params +func (o *PatchMemoryHotplugParams) WithContext(ctx context.Context) *PatchMemoryHotplugParams { + o.SetContext(ctx) + return o +} + +// SetContext adds the context to the patch memory hotplug params +func (o *PatchMemoryHotplugParams) SetContext(ctx context.Context) { + o.Context = ctx +} + +// WithHTTPClient adds the HTTPClient to the patch memory hotplug params +func (o *PatchMemoryHotplugParams) WithHTTPClient(client *http.Client) *PatchMemoryHotplugParams { + o.SetHTTPClient(client) + return o +} + +// SetHTTPClient adds the HTTPClient to the patch memory hotplug params +func (o *PatchMemoryHotplugParams) SetHTTPClient(client *http.Client) { + o.HTTPClient = client +} + +// WithBody adds the body to the patch memory hotplug params +func (o *PatchMemoryHotplugParams) WithBody(body *models.MemoryHotplugSizeUpdate) *PatchMemoryHotplugParams { + o.SetBody(body) + return o +} + +// SetBody adds the body to the patch memory hotplug params +func (o *PatchMemoryHotplugParams) SetBody(body *models.MemoryHotplugSizeUpdate) { + o.Body = body +} + +// WriteToRequest writes these params to a swagger request +func (o *PatchMemoryHotplugParams) WriteToRequest(r runtime.ClientRequest, reg strfmt.Registry) error { + + if err := r.SetTimeout(o.timeout); err != nil { + return err + } + var res []error + if o.Body != nil { + if err := r.SetBodyParam(o.Body); err != nil { + return err + } + } + + if len(res) > 0 { + return errors.CompositeValidationError(res...) + } + return nil +} diff --git a/packages/shared/pkg/fc/client/operations/patch_memory_hotplug_responses.go b/packages/shared/pkg/fc/client/operations/patch_memory_hotplug_responses.go new file mode 100644 index 0000000000..2f4f3808a0 --- /dev/null +++ b/packages/shared/pkg/fc/client/operations/patch_memory_hotplug_responses.go @@ -0,0 +1,171 @@ +// Code generated by go-swagger; DO NOT EDIT. + +package operations + +import ( + "encoding/json" + stderrors "errors" + "fmt" + "io" + + "github.com/go-openapi/runtime" + "github.com/go-openapi/strfmt" + + "github.com/e2b-dev/infra/packages/shared/pkg/fc/models" +) + +// PatchMemoryHotplugReader is a Reader for the PatchMemoryHotplug structure. +type PatchMemoryHotplugReader struct { + formats strfmt.Registry +} + +// ReadResponse reads a server response into the received o. +func (o *PatchMemoryHotplugReader) ReadResponse(response runtime.ClientResponse, consumer runtime.Consumer) (any, error) { + switch response.Code() { + case 204: + result := NewPatchMemoryHotplugNoContent() + if err := result.readResponse(response, consumer, o.formats); err != nil { + return nil, err + } + return result, nil + default: + result := NewPatchMemoryHotplugDefault(response.Code()) + if err := result.readResponse(response, consumer, o.formats); err != nil { + return nil, err + } + if response.Code()/100 == 2 { + return result, nil + } + return nil, result + } +} + +// NewPatchMemoryHotplugNoContent creates a PatchMemoryHotplugNoContent with default headers values +func NewPatchMemoryHotplugNoContent() *PatchMemoryHotplugNoContent { + return &PatchMemoryHotplugNoContent{} +} + +/* +PatchMemoryHotplugNoContent describes a response with status code 204, with default header values. + +Hotpluggable memory configured +*/ +type PatchMemoryHotplugNoContent struct { +} + +// IsSuccess returns true when this patch memory hotplug no content response has a 2xx status code +func (o *PatchMemoryHotplugNoContent) IsSuccess() bool { + return true +} + +// IsRedirect returns true when this patch memory hotplug no content response has a 3xx status code +func (o *PatchMemoryHotplugNoContent) IsRedirect() bool { + return false +} + +// IsClientError returns true when this patch memory hotplug no content response has a 4xx status code +func (o *PatchMemoryHotplugNoContent) IsClientError() bool { + return false +} + +// IsServerError returns true when this patch memory hotplug no content response has a 5xx status code +func (o *PatchMemoryHotplugNoContent) IsServerError() bool { + return false +} + +// IsCode returns true when this patch memory hotplug no content response a status code equal to that given +func (o *PatchMemoryHotplugNoContent) IsCode(code int) bool { + return code == 204 +} + +// Code gets the status code for the patch memory hotplug no content response +func (o *PatchMemoryHotplugNoContent) Code() int { + return 204 +} + +func (o *PatchMemoryHotplugNoContent) Error() string { + return fmt.Sprintf("[PATCH /hotplug/memory][%d] patchMemoryHotplugNoContent", 204) +} + +func (o *PatchMemoryHotplugNoContent) String() string { + return fmt.Sprintf("[PATCH /hotplug/memory][%d] patchMemoryHotplugNoContent", 204) +} + +func (o *PatchMemoryHotplugNoContent) readResponse(response runtime.ClientResponse, consumer runtime.Consumer, formats strfmt.Registry) error { + + return nil +} + +// NewPatchMemoryHotplugDefault creates a PatchMemoryHotplugDefault with default headers values +func NewPatchMemoryHotplugDefault(code int) *PatchMemoryHotplugDefault { + return &PatchMemoryHotplugDefault{ + _statusCode: code, + } +} + +/* +PatchMemoryHotplugDefault describes a response with status code -1, with default header values. + +Internal server error +*/ +type PatchMemoryHotplugDefault struct { + _statusCode int + + Payload *models.Error +} + +// IsSuccess returns true when this patch memory hotplug default response has a 2xx status code +func (o *PatchMemoryHotplugDefault) IsSuccess() bool { + return o._statusCode/100 == 2 +} + +// IsRedirect returns true when this patch memory hotplug default response has a 3xx status code +func (o *PatchMemoryHotplugDefault) IsRedirect() bool { + return o._statusCode/100 == 3 +} + +// IsClientError returns true when this patch memory hotplug default response has a 4xx status code +func (o *PatchMemoryHotplugDefault) IsClientError() bool { + return o._statusCode/100 == 4 +} + +// IsServerError returns true when this patch memory hotplug default response has a 5xx status code +func (o *PatchMemoryHotplugDefault) IsServerError() bool { + return o._statusCode/100 == 5 +} + +// IsCode returns true when this patch memory hotplug default response a status code equal to that given +func (o *PatchMemoryHotplugDefault) IsCode(code int) bool { + return o._statusCode == code +} + +// Code gets the status code for the patch memory hotplug default response +func (o *PatchMemoryHotplugDefault) Code() int { + return o._statusCode +} + +func (o *PatchMemoryHotplugDefault) Error() string { + payload, _ := json.Marshal(o.Payload) + return fmt.Sprintf("[PATCH /hotplug/memory][%d] patchMemoryHotplug default %s", o._statusCode, payload) +} + +func (o *PatchMemoryHotplugDefault) String() string { + payload, _ := json.Marshal(o.Payload) + return fmt.Sprintf("[PATCH /hotplug/memory][%d] patchMemoryHotplug default %s", o._statusCode, payload) +} + +func (o *PatchMemoryHotplugDefault) GetPayload() *models.Error { + return o.Payload +} + +func (o *PatchMemoryHotplugDefault) readResponse(response runtime.ClientResponse, consumer runtime.Consumer, formats strfmt.Registry) error { + + o.Payload = new(models.Error) + + // response payload + if err := consumer.Consume(response.Body(), o.Payload); err != nil && !stderrors.Is(err, io.EOF) { + return err + } + + return nil +} diff --git a/packages/shared/pkg/fc/client/operations/put_guest_pmem_by_id_parameters.go b/packages/shared/pkg/fc/client/operations/put_guest_pmem_by_id_parameters.go new file mode 100644 index 0000000000..77c2d0911c --- /dev/null +++ b/packages/shared/pkg/fc/client/operations/put_guest_pmem_by_id_parameters.go @@ -0,0 +1,172 @@ +// Code generated by go-swagger; DO NOT EDIT. + +package operations + +import ( + "context" + "net/http" + "time" + + "github.com/go-openapi/errors" + "github.com/go-openapi/runtime" + cr "github.com/go-openapi/runtime/client" + "github.com/go-openapi/strfmt" + + "github.com/e2b-dev/infra/packages/shared/pkg/fc/models" +) + +// NewPutGuestPmemByIDParams creates a new PutGuestPmemByIDParams object, +// with the default timeout for this client. +// +// Default values are not hydrated, since defaults are normally applied by the API server side. +// +// To enforce default values in parameter, use SetDefaults or WithDefaults. +func NewPutGuestPmemByIDParams() *PutGuestPmemByIDParams { + return &PutGuestPmemByIDParams{ + timeout: cr.DefaultTimeout, + } +} + +// NewPutGuestPmemByIDParamsWithTimeout creates a new PutGuestPmemByIDParams object +// with the ability to set a timeout on a request. +func NewPutGuestPmemByIDParamsWithTimeout(timeout time.Duration) *PutGuestPmemByIDParams { + return &PutGuestPmemByIDParams{ + timeout: timeout, + } +} + +// NewPutGuestPmemByIDParamsWithContext creates a new PutGuestPmemByIDParams object +// with the ability to set a context for a request. +func NewPutGuestPmemByIDParamsWithContext(ctx context.Context) *PutGuestPmemByIDParams { + return &PutGuestPmemByIDParams{ + Context: ctx, + } +} + +// NewPutGuestPmemByIDParamsWithHTTPClient creates a new PutGuestPmemByIDParams object +// with the ability to set a custom HTTPClient for a request. +func NewPutGuestPmemByIDParamsWithHTTPClient(client *http.Client) *PutGuestPmemByIDParams { + return &PutGuestPmemByIDParams{ + HTTPClient: client, + } +} + +/* +PutGuestPmemByIDParams contains all the parameters to send to the API endpoint + + for the put guest pmem by ID operation. + + Typically these are written to a http.Request. +*/ +type PutGuestPmemByIDParams struct { + + /* Body. + + Guest pmem device properties + */ + Body *models.Pmem + + /* ID. + + The id of the guest pmem device + */ + ID string + + timeout time.Duration + Context context.Context + HTTPClient *http.Client +} + +// WithDefaults hydrates default values in the put guest pmem by ID params (not the query body). +// +// All values with no default are reset to their zero value. +func (o *PutGuestPmemByIDParams) WithDefaults() *PutGuestPmemByIDParams { + o.SetDefaults() + return o +} + +// SetDefaults hydrates default values in the put guest pmem by ID params (not the query body). +// +// All values with no default are reset to their zero value. +func (o *PutGuestPmemByIDParams) SetDefaults() { + // no default values defined for this parameter +} + +// WithTimeout adds the timeout to the put guest pmem by ID params +func (o *PutGuestPmemByIDParams) WithTimeout(timeout time.Duration) *PutGuestPmemByIDParams { + o.SetTimeout(timeout) + return o +} + +// SetTimeout adds the timeout to the put guest pmem by ID params +func (o *PutGuestPmemByIDParams) SetTimeout(timeout time.Duration) { + o.timeout = timeout +} + +// WithContext adds the context to the put guest pmem by ID params +func (o *PutGuestPmemByIDParams) WithContext(ctx context.Context) *PutGuestPmemByIDParams { + o.SetContext(ctx) + return o +} + +// SetContext adds the context to the put guest pmem by ID params +func (o *PutGuestPmemByIDParams) SetContext(ctx context.Context) { + o.Context = ctx +} + +// WithHTTPClient adds the HTTPClient to the put guest pmem by ID params +func (o *PutGuestPmemByIDParams) WithHTTPClient(client *http.Client) *PutGuestPmemByIDParams { + o.SetHTTPClient(client) + return o +} + +// SetHTTPClient adds the HTTPClient to the put guest pmem by ID params +func (o *PutGuestPmemByIDParams) SetHTTPClient(client *http.Client) { + o.HTTPClient = client +} + +// WithBody adds the body to the put guest pmem by ID params +func (o *PutGuestPmemByIDParams) WithBody(body *models.Pmem) *PutGuestPmemByIDParams { + o.SetBody(body) + return o +} + +// SetBody adds the body to the put guest pmem by ID params +func (o *PutGuestPmemByIDParams) SetBody(body *models.Pmem) { + o.Body = body +} + +// WithID adds the id to the put guest pmem by ID params +func (o *PutGuestPmemByIDParams) WithID(id string) *PutGuestPmemByIDParams { + o.SetID(id) + return o +} + +// SetID adds the id to the put guest pmem by ID params +func (o *PutGuestPmemByIDParams) SetID(id string) { + o.ID = id +} + +// WriteToRequest writes these params to a swagger request +func (o *PutGuestPmemByIDParams) WriteToRequest(r runtime.ClientRequest, reg strfmt.Registry) error { + + if err := r.SetTimeout(o.timeout); err != nil { + return err + } + var res []error + if o.Body != nil { + if err := r.SetBodyParam(o.Body); err != nil { + return err + } + } + + // path param id + if err := r.SetPathParam("id", o.ID); err != nil { + return err + } + + if len(res) > 0 { + return errors.CompositeValidationError(res...) + } + return nil +} diff --git a/packages/shared/pkg/fc/client/operations/put_guest_pmem_by_id_responses.go b/packages/shared/pkg/fc/client/operations/put_guest_pmem_by_id_responses.go new file mode 100644 index 0000000000..106440e244 --- /dev/null +++ b/packages/shared/pkg/fc/client/operations/put_guest_pmem_by_id_responses.go @@ -0,0 +1,247 @@ +// Code generated by go-swagger; DO NOT EDIT. + +package operations + +import ( + "encoding/json" + stderrors "errors" + "fmt" + "io" + + "github.com/go-openapi/runtime" + "github.com/go-openapi/strfmt" + + "github.com/e2b-dev/infra/packages/shared/pkg/fc/models" +) + +// PutGuestPmemByIDReader is a Reader for the PutGuestPmemByID structure. +type PutGuestPmemByIDReader struct { + formats strfmt.Registry +} + +// ReadResponse reads a server response into the received o. +func (o *PutGuestPmemByIDReader) ReadResponse(response runtime.ClientResponse, consumer runtime.Consumer) (any, error) { + switch response.Code() { + case 204: + result := NewPutGuestPmemByIDNoContent() + if err := result.readResponse(response, consumer, o.formats); err != nil { + return nil, err + } + return result, nil + case 400: + result := NewPutGuestPmemByIDBadRequest() + if err := result.readResponse(response, consumer, o.formats); err != nil { + return nil, err + } + return nil, result + default: + result := NewPutGuestPmemByIDDefault(response.Code()) + if err := result.readResponse(response, consumer, o.formats); err != nil { + return nil, err + } + if response.Code()/100 == 2 { + return result, nil + } + return nil, result + } +} + +// NewPutGuestPmemByIDNoContent creates a PutGuestPmemByIDNoContent with default headers values +func NewPutGuestPmemByIDNoContent() *PutGuestPmemByIDNoContent { + return &PutGuestPmemByIDNoContent{} +} + +/* +PutGuestPmemByIDNoContent describes a response with status code 204, with default header values. + +Pmem device is created/updated +*/ +type PutGuestPmemByIDNoContent struct { +} + +// IsSuccess returns true when this put guest pmem by Id no content response has a 2xx status code +func (o *PutGuestPmemByIDNoContent) IsSuccess() bool { + return true +} + +// IsRedirect returns true when this put guest pmem by Id no content response has a 3xx status code +func (o *PutGuestPmemByIDNoContent) IsRedirect() bool { + return false +} + +// IsClientError returns true when this put guest pmem by Id no content response has a 4xx status code +func (o *PutGuestPmemByIDNoContent) IsClientError() bool { + return false +} + +// IsServerError returns true when this put guest pmem by Id no content response has a 5xx status code +func (o *PutGuestPmemByIDNoContent) IsServerError() bool { + return false +} + +// IsCode returns true when this put guest pmem by Id no content response a status code equal to that given +func (o *PutGuestPmemByIDNoContent) IsCode(code int) bool { + return code == 204 +} + +// Code gets the status code for the put guest pmem by Id no content response +func (o *PutGuestPmemByIDNoContent) Code() int { + return 204 +} + +func (o *PutGuestPmemByIDNoContent) Error() string { + return fmt.Sprintf("[PUT /pmem/{id}][%d] putGuestPmemByIdNoContent", 204) +} + +func (o *PutGuestPmemByIDNoContent) String() string { + return fmt.Sprintf("[PUT /pmem/{id}][%d] putGuestPmemByIdNoContent", 204) +} + +func (o *PutGuestPmemByIDNoContent) readResponse(response runtime.ClientResponse, consumer runtime.Consumer, formats strfmt.Registry) error { + + return nil +} + +// NewPutGuestPmemByIDBadRequest creates a PutGuestPmemByIDBadRequest with default headers values +func NewPutGuestPmemByIDBadRequest() *PutGuestPmemByIDBadRequest { + return &PutGuestPmemByIDBadRequest{} +} + +/* +PutGuestPmemByIDBadRequest describes a response with status code 400, with default header values. + +Pmem device cannot be created/updated due to bad input +*/ +type PutGuestPmemByIDBadRequest struct { + Payload *models.Error +} + +// IsSuccess returns true when this put guest pmem by Id bad request response has a 2xx status code +func (o *PutGuestPmemByIDBadRequest) IsSuccess() bool { + return false +} + +// IsRedirect returns true when this put guest pmem by Id bad request response has a 3xx status code +func (o *PutGuestPmemByIDBadRequest) IsRedirect() bool { + return false +} + +// IsClientError returns true when this put guest pmem by Id bad request response has a 4xx status code +func (o *PutGuestPmemByIDBadRequest) IsClientError() bool { + return true +} + +// IsServerError returns true when this put guest pmem by Id bad request response has a 5xx status code +func (o *PutGuestPmemByIDBadRequest) IsServerError() bool { + return false +} + +// IsCode returns true when this put guest pmem by Id bad request response a status code equal to that given +func (o *PutGuestPmemByIDBadRequest) IsCode(code int) bool { + return code == 400 +} + +// Code gets the status code for the put guest pmem by Id bad request response +func (o *PutGuestPmemByIDBadRequest) Code() int { + return 400 +} + +func (o *PutGuestPmemByIDBadRequest) Error() string { + payload, _ := json.Marshal(o.Payload) + return fmt.Sprintf("[PUT /pmem/{id}][%d] putGuestPmemByIdBadRequest %s", 400, payload) +} + +func (o *PutGuestPmemByIDBadRequest) String() string { + payload, _ := json.Marshal(o.Payload) + return fmt.Sprintf("[PUT /pmem/{id}][%d] putGuestPmemByIdBadRequest %s", 400, payload) +} + +func (o *PutGuestPmemByIDBadRequest) GetPayload() *models.Error { + return o.Payload +} + +func (o *PutGuestPmemByIDBadRequest) readResponse(response runtime.ClientResponse, consumer runtime.Consumer, formats strfmt.Registry) error { + + o.Payload = new(models.Error) + + // response payload + if err := consumer.Consume(response.Body(), o.Payload); err != nil && !stderrors.Is(err, io.EOF) { + return err + } + + return nil +} + +// NewPutGuestPmemByIDDefault creates a PutGuestPmemByIDDefault with default headers values +func NewPutGuestPmemByIDDefault(code int) *PutGuestPmemByIDDefault { + return &PutGuestPmemByIDDefault{ + _statusCode: code, + } +} + +/* +PutGuestPmemByIDDefault describes a response with status code -1, with default header values. + +Internal server error. +*/ +type PutGuestPmemByIDDefault struct { + _statusCode int + + Payload *models.Error +} + +// IsSuccess returns true when this put guest pmem by ID default response has a 2xx status code +func (o *PutGuestPmemByIDDefault) IsSuccess() bool { + return o._statusCode/100 == 2 +} + +// IsRedirect returns true when this put guest pmem by ID default response has a 3xx status code +func (o *PutGuestPmemByIDDefault) IsRedirect() bool { + return o._statusCode/100 == 3 +} + +// IsClientError returns true when this put guest pmem by ID default response has a 4xx status code +func (o *PutGuestPmemByIDDefault) IsClientError() bool { + return o._statusCode/100 == 4 +} + +// IsServerError returns true when this put guest pmem by ID default response has a 5xx status code +func (o *PutGuestPmemByIDDefault) IsServerError() bool { + return o._statusCode/100 == 5 +} + +// IsCode returns true when this put guest pmem by ID default response a status code equal to that given +func (o *PutGuestPmemByIDDefault) IsCode(code int) bool { + return o._statusCode == code +} + +// Code gets the status code for the put guest pmem by ID default response +func (o *PutGuestPmemByIDDefault) Code() int { + return o._statusCode +} + +func (o *PutGuestPmemByIDDefault) Error() string { + payload, _ := json.Marshal(o.Payload) + return fmt.Sprintf("[PUT /pmem/{id}][%d] putGuestPmemByID default %s", o._statusCode, payload) +} + +func (o *PutGuestPmemByIDDefault) String() string { + payload, _ := json.Marshal(o.Payload) + return fmt.Sprintf("[PUT /pmem/{id}][%d] putGuestPmemByID default %s", o._statusCode, payload) +} + +func (o *PutGuestPmemByIDDefault) GetPayload() *models.Error { + return o.Payload +} + +func (o *PutGuestPmemByIDDefault) readResponse(response runtime.ClientResponse, consumer runtime.Consumer, formats strfmt.Registry) error { + + o.Payload = new(models.Error) + + // response payload + if err := consumer.Consume(response.Body(), o.Payload); err != nil && !stderrors.Is(err, io.EOF) { + return err + } + + return nil +} diff --git a/packages/shared/pkg/fc/client/operations/put_memory_hotplug_parameters.go b/packages/shared/pkg/fc/client/operations/put_memory_hotplug_parameters.go new file mode 100644 index 0000000000..5a1e21323b --- /dev/null +++ b/packages/shared/pkg/fc/client/operations/put_memory_hotplug_parameters.go @@ -0,0 +1,150 @@ +// Code generated by go-swagger; DO NOT EDIT. + +package operations + +import ( + "context" + "net/http" + "time" + + "github.com/go-openapi/errors" + "github.com/go-openapi/runtime" + cr "github.com/go-openapi/runtime/client" + "github.com/go-openapi/strfmt" + + "github.com/e2b-dev/infra/packages/shared/pkg/fc/models" +) + +// NewPutMemoryHotplugParams creates a new PutMemoryHotplugParams object, +// with the default timeout for this client. +// +// Default values are not hydrated, since defaults are normally applied by the API server side. +// +// To enforce default values in parameter, use SetDefaults or WithDefaults. +func NewPutMemoryHotplugParams() *PutMemoryHotplugParams { + return &PutMemoryHotplugParams{ + timeout: cr.DefaultTimeout, + } +} + +// NewPutMemoryHotplugParamsWithTimeout creates a new PutMemoryHotplugParams object +// with the ability to set a timeout on a request. +func NewPutMemoryHotplugParamsWithTimeout(timeout time.Duration) *PutMemoryHotplugParams { + return &PutMemoryHotplugParams{ + timeout: timeout, + } +} + +// NewPutMemoryHotplugParamsWithContext creates a new PutMemoryHotplugParams object +// with the ability to set a context for a request. +func NewPutMemoryHotplugParamsWithContext(ctx context.Context) *PutMemoryHotplugParams { + return &PutMemoryHotplugParams{ + Context: ctx, + } +} + +// NewPutMemoryHotplugParamsWithHTTPClient creates a new PutMemoryHotplugParams object +// with the ability to set a custom HTTPClient for a request. +func NewPutMemoryHotplugParamsWithHTTPClient(client *http.Client) *PutMemoryHotplugParams { + return &PutMemoryHotplugParams{ + HTTPClient: client, + } +} + +/* +PutMemoryHotplugParams contains all the parameters to send to the API endpoint + + for the put memory hotplug operation. + + Typically these are written to a http.Request. +*/ +type PutMemoryHotplugParams struct { + + /* Body. + + Hotpluggable memory configuration + */ + Body *models.MemoryHotplugConfig + + timeout time.Duration + Context context.Context + HTTPClient *http.Client +} + +// WithDefaults hydrates default values in the put memory hotplug params (not the query body). +// +// All values with no default are reset to their zero value. +func (o *PutMemoryHotplugParams) WithDefaults() *PutMemoryHotplugParams { + o.SetDefaults() + return o +} + +// SetDefaults hydrates default values in the put memory hotplug params (not the query body). +// +// All values with no default are reset to their zero value. +func (o *PutMemoryHotplugParams) SetDefaults() { + // no default values defined for this parameter +} + +// WithTimeout adds the timeout to the put memory hotplug params +func (o *PutMemoryHotplugParams) WithTimeout(timeout time.Duration) *PutMemoryHotplugParams { + o.SetTimeout(timeout) + return o +} + +// SetTimeout adds the timeout to the put memory hotplug params +func (o *PutMemoryHotplugParams) SetTimeout(timeout time.Duration) { + o.timeout = timeout +} + +// WithContext adds the context to the put memory hotplug params +func (o *PutMemoryHotplugParams) WithContext(ctx context.Context) *PutMemoryHotplugParams { + o.SetContext(ctx) + return o +} + +// SetContext adds the context to the put memory hotplug params +func (o *PutMemoryHotplugParams) SetContext(ctx context.Context) { + o.Context = ctx +} + +// WithHTTPClient adds the HTTPClient to the put memory hotplug params +func (o *PutMemoryHotplugParams) WithHTTPClient(client *http.Client) *PutMemoryHotplugParams { + o.SetHTTPClient(client) + return o +} + +// SetHTTPClient adds the HTTPClient to the put memory hotplug params +func (o *PutMemoryHotplugParams) SetHTTPClient(client *http.Client) { + o.HTTPClient = client +} + +// WithBody adds the body to the put memory hotplug params +func (o *PutMemoryHotplugParams) WithBody(body *models.MemoryHotplugConfig) *PutMemoryHotplugParams { + o.SetBody(body) + return o +} + +// SetBody adds the body to the put memory hotplug params +func (o *PutMemoryHotplugParams) SetBody(body *models.MemoryHotplugConfig) { + o.Body = body +} + +// WriteToRequest writes these params to a swagger request +func (o *PutMemoryHotplugParams) WriteToRequest(r runtime.ClientRequest, reg strfmt.Registry) error { + + if err := r.SetTimeout(o.timeout); err != nil { + return err + } + var res []error + if o.Body != nil { + if err := r.SetBodyParam(o.Body); err != nil { + return err + } + } + + if len(res) > 0 { + return errors.CompositeValidationError(res...) + } + return nil +} diff --git a/packages/shared/pkg/fc/client/operations/put_memory_hotplug_responses.go b/packages/shared/pkg/fc/client/operations/put_memory_hotplug_responses.go new file mode 100644 index 0000000000..7bb3ea5061 --- /dev/null +++ b/packages/shared/pkg/fc/client/operations/put_memory_hotplug_responses.go @@ -0,0 +1,171 @@ +// Code generated by go-swagger; DO NOT EDIT. + +package operations + +import ( + "encoding/json" + stderrors "errors" + "fmt" + "io" + + "github.com/go-openapi/runtime" + "github.com/go-openapi/strfmt" + + "github.com/e2b-dev/infra/packages/shared/pkg/fc/models" +) + +// PutMemoryHotplugReader is a Reader for the PutMemoryHotplug structure. +type PutMemoryHotplugReader struct { + formats strfmt.Registry +} + +// ReadResponse reads a server response into the received o. +func (o *PutMemoryHotplugReader) ReadResponse(response runtime.ClientResponse, consumer runtime.Consumer) (any, error) { + switch response.Code() { + case 204: + result := NewPutMemoryHotplugNoContent() + if err := result.readResponse(response, consumer, o.formats); err != nil { + return nil, err + } + return result, nil + default: + result := NewPutMemoryHotplugDefault(response.Code()) + if err := result.readResponse(response, consumer, o.formats); err != nil { + return nil, err + } + if response.Code()/100 == 2 { + return result, nil + } + return nil, result + } +} + +// NewPutMemoryHotplugNoContent creates a PutMemoryHotplugNoContent with default headers values +func NewPutMemoryHotplugNoContent() *PutMemoryHotplugNoContent { + return &PutMemoryHotplugNoContent{} +} + +/* +PutMemoryHotplugNoContent describes a response with status code 204, with default header values. + +Hotpluggable memory configured +*/ +type PutMemoryHotplugNoContent struct { +} + +// IsSuccess returns true when this put memory hotplug no content response has a 2xx status code +func (o *PutMemoryHotplugNoContent) IsSuccess() bool { + return true +} + +// IsRedirect returns true when this put memory hotplug no content response has a 3xx status code +func (o *PutMemoryHotplugNoContent) IsRedirect() bool { + return false +} + +// IsClientError returns true when this put memory hotplug no content response has a 4xx status code +func (o *PutMemoryHotplugNoContent) IsClientError() bool { + return false +} + +// IsServerError returns true when this put memory hotplug no content response has a 5xx status code +func (o *PutMemoryHotplugNoContent) IsServerError() bool { + return false +} + +// IsCode returns true when this put memory hotplug no content response a status code equal to that given +func (o *PutMemoryHotplugNoContent) IsCode(code int) bool { + return code == 204 +} + +// Code gets the status code for the put memory hotplug no content response +func (o *PutMemoryHotplugNoContent) Code() int { + return 204 +} + +func (o *PutMemoryHotplugNoContent) Error() string { + return fmt.Sprintf("[PUT /hotplug/memory][%d] putMemoryHotplugNoContent", 204) +} + +func (o *PutMemoryHotplugNoContent) String() string { + return fmt.Sprintf("[PUT /hotplug/memory][%d] putMemoryHotplugNoContent", 204) +} + +func (o *PutMemoryHotplugNoContent) readResponse(response runtime.ClientResponse, consumer runtime.Consumer, formats strfmt.Registry) error { + + return nil +} + +// NewPutMemoryHotplugDefault creates a PutMemoryHotplugDefault with default headers values +func NewPutMemoryHotplugDefault(code int) *PutMemoryHotplugDefault { + return &PutMemoryHotplugDefault{ + _statusCode: code, + } +} + +/* +PutMemoryHotplugDefault describes a response with status code -1, with default header values. + +Internal server error +*/ +type PutMemoryHotplugDefault struct { + _statusCode int + + Payload *models.Error +} + +// IsSuccess returns true when this put memory hotplug default response has a 2xx status code +func (o *PutMemoryHotplugDefault) IsSuccess() bool { + return o._statusCode/100 == 2 +} + +// IsRedirect returns true when this put memory hotplug default response has a 3xx status code +func (o *PutMemoryHotplugDefault) IsRedirect() bool { + return o._statusCode/100 == 3 +} + +// IsClientError returns true when this put memory hotplug default response has a 4xx status code +func (o *PutMemoryHotplugDefault) IsClientError() bool { + return o._statusCode/100 == 4 +} + +// IsServerError returns true when this put memory hotplug default response has a 5xx status code +func (o *PutMemoryHotplugDefault) IsServerError() bool { + return o._statusCode/100 == 5 +} + +// IsCode returns true when this put memory hotplug default response a status code equal to that given +func (o *PutMemoryHotplugDefault) IsCode(code int) bool { + return o._statusCode == code +} + +// Code gets the status code for the put memory hotplug default response +func (o *PutMemoryHotplugDefault) Code() int { + return o._statusCode +} + +func (o *PutMemoryHotplugDefault) Error() string { + payload, _ := json.Marshal(o.Payload) + return fmt.Sprintf("[PUT /hotplug/memory][%d] putMemoryHotplug default %s", o._statusCode, payload) +} + +func (o *PutMemoryHotplugDefault) String() string { + payload, _ := json.Marshal(o.Payload) + return fmt.Sprintf("[PUT /hotplug/memory][%d] putMemoryHotplug default %s", o._statusCode, payload) +} + +func (o *PutMemoryHotplugDefault) GetPayload() *models.Error { + return o.Payload +} + +func (o *PutMemoryHotplugDefault) readResponse(response runtime.ClientResponse, consumer runtime.Consumer, formats strfmt.Registry) error { + + o.Payload = new(models.Error) + + // response payload + if err := consumer.Consume(response.Body(), o.Payload); err != nil && !stderrors.Is(err, io.EOF) { + return err + } + + return nil +} diff --git a/packages/shared/pkg/fc/client/operations/put_serial_device_parameters.go b/packages/shared/pkg/fc/client/operations/put_serial_device_parameters.go new file mode 100644 index 0000000000..dbbd288e92 --- /dev/null +++ b/packages/shared/pkg/fc/client/operations/put_serial_device_parameters.go @@ -0,0 +1,150 @@ +// Code generated by go-swagger; DO NOT EDIT. + +package operations + +import ( + "context" + "net/http" + "time" + + "github.com/go-openapi/errors" + "github.com/go-openapi/runtime" + cr "github.com/go-openapi/runtime/client" + "github.com/go-openapi/strfmt" + + "github.com/e2b-dev/infra/packages/shared/pkg/fc/models" +) + +// NewPutSerialDeviceParams creates a new PutSerialDeviceParams object, +// with the default timeout for this client. +// +// Default values are not hydrated, since defaults are normally applied by the API server side. +// +// To enforce default values in parameter, use SetDefaults or WithDefaults. +func NewPutSerialDeviceParams() *PutSerialDeviceParams { + return &PutSerialDeviceParams{ + timeout: cr.DefaultTimeout, + } +} + +// NewPutSerialDeviceParamsWithTimeout creates a new PutSerialDeviceParams object +// with the ability to set a timeout on a request. +func NewPutSerialDeviceParamsWithTimeout(timeout time.Duration) *PutSerialDeviceParams { + return &PutSerialDeviceParams{ + timeout: timeout, + } +} + +// NewPutSerialDeviceParamsWithContext creates a new PutSerialDeviceParams object +// with the ability to set a context for a request. +func NewPutSerialDeviceParamsWithContext(ctx context.Context) *PutSerialDeviceParams { + return &PutSerialDeviceParams{ + Context: ctx, + } +} + +// NewPutSerialDeviceParamsWithHTTPClient creates a new PutSerialDeviceParams object +// with the ability to set a custom HTTPClient for a request. +func NewPutSerialDeviceParamsWithHTTPClient(client *http.Client) *PutSerialDeviceParams { + return &PutSerialDeviceParams{ + HTTPClient: client, + } +} + +/* +PutSerialDeviceParams contains all the parameters to send to the API endpoint + + for the put serial device operation. + + Typically these are written to a http.Request. +*/ +type PutSerialDeviceParams struct { + + /* Body. + + Serial console properties + */ + Body *models.SerialDevice + + timeout time.Duration + Context context.Context + HTTPClient *http.Client +} + +// WithDefaults hydrates default values in the put serial device params (not the query body). +// +// All values with no default are reset to their zero value. +func (o *PutSerialDeviceParams) WithDefaults() *PutSerialDeviceParams { + o.SetDefaults() + return o +} + +// SetDefaults hydrates default values in the put serial device params (not the query body). +// +// All values with no default are reset to their zero value. +func (o *PutSerialDeviceParams) SetDefaults() { + // no default values defined for this parameter +} + +// WithTimeout adds the timeout to the put serial device params +func (o *PutSerialDeviceParams) WithTimeout(timeout time.Duration) *PutSerialDeviceParams { + o.SetTimeout(timeout) + return o +} + +// SetTimeout adds the timeout to the put serial device params +func (o *PutSerialDeviceParams) SetTimeout(timeout time.Duration) { + o.timeout = timeout +} + +// WithContext adds the context to the put serial device params +func (o *PutSerialDeviceParams) WithContext(ctx context.Context) *PutSerialDeviceParams { + o.SetContext(ctx) + return o +} + +// SetContext adds the context to the put serial device params +func (o *PutSerialDeviceParams) SetContext(ctx context.Context) { + o.Context = ctx +} + +// WithHTTPClient adds the HTTPClient to the put serial device params +func (o *PutSerialDeviceParams) WithHTTPClient(client *http.Client) *PutSerialDeviceParams { + o.SetHTTPClient(client) + return o +} + +// SetHTTPClient adds the HTTPClient to the put serial device params +func (o *PutSerialDeviceParams) SetHTTPClient(client *http.Client) { + o.HTTPClient = client +} + +// WithBody adds the body to the put serial device params +func (o *PutSerialDeviceParams) WithBody(body *models.SerialDevice) *PutSerialDeviceParams { + o.SetBody(body) + return o +} + +// SetBody adds the body to the put serial device params +func (o *PutSerialDeviceParams) SetBody(body *models.SerialDevice) { + o.Body = body +} + +// WriteToRequest writes these params to a swagger request +func (o *PutSerialDeviceParams) WriteToRequest(r runtime.ClientRequest, reg strfmt.Registry) error { + + if err := r.SetTimeout(o.timeout); err != nil { + return err + } + var res []error + if o.Body != nil { + if err := r.SetBodyParam(o.Body); err != nil { + return err + } + } + + if len(res) > 0 { + return errors.CompositeValidationError(res...) + } + return nil +} diff --git a/packages/shared/pkg/fc/client/operations/put_serial_device_responses.go b/packages/shared/pkg/fc/client/operations/put_serial_device_responses.go new file mode 100644 index 0000000000..ac09a76f57 --- /dev/null +++ b/packages/shared/pkg/fc/client/operations/put_serial_device_responses.go @@ -0,0 +1,171 @@ +// Code generated by go-swagger; DO NOT EDIT. + +package operations + +import ( + "encoding/json" + stderrors "errors" + "fmt" + "io" + + "github.com/go-openapi/runtime" + "github.com/go-openapi/strfmt" + + "github.com/e2b-dev/infra/packages/shared/pkg/fc/models" +) + +// PutSerialDeviceReader is a Reader for the PutSerialDevice structure. +type PutSerialDeviceReader struct { + formats strfmt.Registry +} + +// ReadResponse reads a server response into the received o. +func (o *PutSerialDeviceReader) ReadResponse(response runtime.ClientResponse, consumer runtime.Consumer) (any, error) { + switch response.Code() { + case 204: + result := NewPutSerialDeviceNoContent() + if err := result.readResponse(response, consumer, o.formats); err != nil { + return nil, err + } + return result, nil + default: + result := NewPutSerialDeviceDefault(response.Code()) + if err := result.readResponse(response, consumer, o.formats); err != nil { + return nil, err + } + if response.Code()/100 == 2 { + return result, nil + } + return nil, result + } +} + +// NewPutSerialDeviceNoContent creates a PutSerialDeviceNoContent with default headers values +func NewPutSerialDeviceNoContent() *PutSerialDeviceNoContent { + return &PutSerialDeviceNoContent{} +} + +/* +PutSerialDeviceNoContent describes a response with status code 204, with default header values. + +Serial device configured +*/ +type PutSerialDeviceNoContent struct { +} + +// IsSuccess returns true when this put serial device no content response has a 2xx status code +func (o *PutSerialDeviceNoContent) IsSuccess() bool { + return true +} + +// IsRedirect returns true when this put serial device no content response has a 3xx status code +func (o *PutSerialDeviceNoContent) IsRedirect() bool { + return false +} + +// IsClientError returns true when this put serial device no content response has a 4xx status code +func (o *PutSerialDeviceNoContent) IsClientError() bool { + return false +} + +// IsServerError returns true when this put serial device no content response has a 5xx status code +func (o *PutSerialDeviceNoContent) IsServerError() bool { + return false +} + +// IsCode returns true when this put serial device no content response a status code equal to that given +func (o *PutSerialDeviceNoContent) IsCode(code int) bool { + return code == 204 +} + +// Code gets the status code for the put serial device no content response +func (o *PutSerialDeviceNoContent) Code() int { + return 204 +} + +func (o *PutSerialDeviceNoContent) Error() string { + return fmt.Sprintf("[PUT /serial][%d] putSerialDeviceNoContent", 204) +} + +func (o *PutSerialDeviceNoContent) String() string { + return fmt.Sprintf("[PUT /serial][%d] putSerialDeviceNoContent", 204) +} + +func (o *PutSerialDeviceNoContent) readResponse(response runtime.ClientResponse, consumer runtime.Consumer, formats strfmt.Registry) error { + + return nil +} + +// NewPutSerialDeviceDefault creates a PutSerialDeviceDefault with default headers values +func NewPutSerialDeviceDefault(code int) *PutSerialDeviceDefault { + return &PutSerialDeviceDefault{ + _statusCode: code, + } +} + +/* +PutSerialDeviceDefault describes a response with status code -1, with default header values. + +Internal server error +*/ +type PutSerialDeviceDefault struct { + _statusCode int + + Payload *models.Error +} + +// IsSuccess returns true when this put serial device default response has a 2xx status code +func (o *PutSerialDeviceDefault) IsSuccess() bool { + return o._statusCode/100 == 2 +} + +// IsRedirect returns true when this put serial device default response has a 3xx status code +func (o *PutSerialDeviceDefault) IsRedirect() bool { + return o._statusCode/100 == 3 +} + +// IsClientError returns true when this put serial device default response has a 4xx status code +func (o *PutSerialDeviceDefault) IsClientError() bool { + return o._statusCode/100 == 4 +} + +// IsServerError returns true when this put serial device default response has a 5xx status code +func (o *PutSerialDeviceDefault) IsServerError() bool { + return o._statusCode/100 == 5 +} + +// IsCode returns true when this put serial device default response a status code equal to that given +func (o *PutSerialDeviceDefault) IsCode(code int) bool { + return o._statusCode == code +} + +// Code gets the status code for the put serial device default response +func (o *PutSerialDeviceDefault) Code() int { + return o._statusCode +} + +func (o *PutSerialDeviceDefault) Error() string { + payload, _ := json.Marshal(o.Payload) + return fmt.Sprintf("[PUT /serial][%d] putSerialDevice default %s", o._statusCode, payload) +} + +func (o *PutSerialDeviceDefault) String() string { + payload, _ := json.Marshal(o.Payload) + return fmt.Sprintf("[PUT /serial][%d] putSerialDevice default %s", o._statusCode, payload) +} + +func (o *PutSerialDeviceDefault) GetPayload() *models.Error { + return o.Payload +} + +func (o *PutSerialDeviceDefault) readResponse(response runtime.ClientResponse, consumer runtime.Consumer, formats strfmt.Registry) error { + + o.Payload = new(models.Error) + + // response payload + if err := consumer.Consume(response.Body(), o.Payload); err != nil && !stderrors.Is(err, io.EOF) { + return err + } + + return nil +} diff --git a/packages/shared/pkg/fc/client/operations/start_balloon_hinting_parameters.go b/packages/shared/pkg/fc/client/operations/start_balloon_hinting_parameters.go new file mode 100644 index 0000000000..e11fe84d31 --- /dev/null +++ b/packages/shared/pkg/fc/client/operations/start_balloon_hinting_parameters.go @@ -0,0 +1,150 @@ +// Code generated by go-swagger; DO NOT EDIT. + +package operations + +import ( + "context" + "net/http" + "time" + + "github.com/go-openapi/errors" + "github.com/go-openapi/runtime" + cr "github.com/go-openapi/runtime/client" + "github.com/go-openapi/strfmt" + + "github.com/e2b-dev/infra/packages/shared/pkg/fc/models" +) + +// NewStartBalloonHintingParams creates a new StartBalloonHintingParams object, +// with the default timeout for this client. +// +// Default values are not hydrated, since defaults are normally applied by the API server side. +// +// To enforce default values in parameter, use SetDefaults or WithDefaults. +func NewStartBalloonHintingParams() *StartBalloonHintingParams { + return &StartBalloonHintingParams{ + timeout: cr.DefaultTimeout, + } +} + +// NewStartBalloonHintingParamsWithTimeout creates a new StartBalloonHintingParams object +// with the ability to set a timeout on a request. +func NewStartBalloonHintingParamsWithTimeout(timeout time.Duration) *StartBalloonHintingParams { + return &StartBalloonHintingParams{ + timeout: timeout, + } +} + +// NewStartBalloonHintingParamsWithContext creates a new StartBalloonHintingParams object +// with the ability to set a context for a request. +func NewStartBalloonHintingParamsWithContext(ctx context.Context) *StartBalloonHintingParams { + return &StartBalloonHintingParams{ + Context: ctx, + } +} + +// NewStartBalloonHintingParamsWithHTTPClient creates a new StartBalloonHintingParams object +// with the ability to set a custom HTTPClient for a request. +func NewStartBalloonHintingParamsWithHTTPClient(client *http.Client) *StartBalloonHintingParams { + return &StartBalloonHintingParams{ + HTTPClient: client, + } +} + +/* +StartBalloonHintingParams contains all the parameters to send to the API endpoint + + for the start balloon hinting operation. + + Typically these are written to a http.Request. +*/ +type StartBalloonHintingParams struct { + + /* Body. + + When the device completes the hinting whether we should automatically ack this. + */ + Body *models.BalloonStartCmd + + timeout time.Duration + Context context.Context + HTTPClient *http.Client +} + +// WithDefaults hydrates default values in the start balloon hinting params (not the query body). +// +// All values with no default are reset to their zero value. +func (o *StartBalloonHintingParams) WithDefaults() *StartBalloonHintingParams { + o.SetDefaults() + return o +} + +// SetDefaults hydrates default values in the start balloon hinting params (not the query body). +// +// All values with no default are reset to their zero value. +func (o *StartBalloonHintingParams) SetDefaults() { + // no default values defined for this parameter +} + +// WithTimeout adds the timeout to the start balloon hinting params +func (o *StartBalloonHintingParams) WithTimeout(timeout time.Duration) *StartBalloonHintingParams { + o.SetTimeout(timeout) + return o +} + +// SetTimeout adds the timeout to the start balloon hinting params +func (o *StartBalloonHintingParams) SetTimeout(timeout time.Duration) { + o.timeout = timeout +} + +// WithContext adds the context to the start balloon hinting params +func (o *StartBalloonHintingParams) WithContext(ctx context.Context) *StartBalloonHintingParams { + o.SetContext(ctx) + return o +} + +// SetContext adds the context to the start balloon hinting params +func (o *StartBalloonHintingParams) SetContext(ctx context.Context) { + o.Context = ctx +} + +// WithHTTPClient adds the HTTPClient to the start balloon hinting params +func (o *StartBalloonHintingParams) WithHTTPClient(client *http.Client) *StartBalloonHintingParams { + o.SetHTTPClient(client) + return o +} + +// SetHTTPClient adds the HTTPClient to the start balloon hinting params +func (o *StartBalloonHintingParams) SetHTTPClient(client *http.Client) { + o.HTTPClient = client +} + +// WithBody adds the body to the start balloon hinting params +func (o *StartBalloonHintingParams) WithBody(body *models.BalloonStartCmd) *StartBalloonHintingParams { + o.SetBody(body) + return o +} + +// SetBody adds the body to the start balloon hinting params +func (o *StartBalloonHintingParams) SetBody(body *models.BalloonStartCmd) { + o.Body = body +} + +// WriteToRequest writes these params to a swagger request +func (o *StartBalloonHintingParams) WriteToRequest(r runtime.ClientRequest, reg strfmt.Registry) error { + + if err := r.SetTimeout(o.timeout); err != nil { + return err + } + var res []error + if o.Body != nil { + if err := r.SetBodyParam(o.Body); err != nil { + return err + } + } + + if len(res) > 0 { + return errors.CompositeValidationError(res...) + } + return nil +} diff --git a/packages/shared/pkg/fc/client/operations/start_balloon_hinting_responses.go b/packages/shared/pkg/fc/client/operations/start_balloon_hinting_responses.go new file mode 100644 index 0000000000..ab0c595034 --- /dev/null +++ b/packages/shared/pkg/fc/client/operations/start_balloon_hinting_responses.go @@ -0,0 +1,247 @@ +// Code generated by go-swagger; DO NOT EDIT. + +package operations + +import ( + "encoding/json" + stderrors "errors" + "fmt" + "io" + + "github.com/go-openapi/runtime" + "github.com/go-openapi/strfmt" + + "github.com/e2b-dev/infra/packages/shared/pkg/fc/models" +) + +// StartBalloonHintingReader is a Reader for the StartBalloonHinting structure. +type StartBalloonHintingReader struct { + formats strfmt.Registry +} + +// ReadResponse reads a server response into the received o. +func (o *StartBalloonHintingReader) ReadResponse(response runtime.ClientResponse, consumer runtime.Consumer) (any, error) { + switch response.Code() { + case 200: + result := NewStartBalloonHintingOK() + if err := result.readResponse(response, consumer, o.formats); err != nil { + return nil, err + } + return result, nil + case 400: + result := NewStartBalloonHintingBadRequest() + if err := result.readResponse(response, consumer, o.formats); err != nil { + return nil, err + } + return nil, result + default: + result := NewStartBalloonHintingDefault(response.Code()) + if err := result.readResponse(response, consumer, o.formats); err != nil { + return nil, err + } + if response.Code()/100 == 2 { + return result, nil + } + return nil, result + } +} + +// NewStartBalloonHintingOK creates a StartBalloonHintingOK with default headers values +func NewStartBalloonHintingOK() *StartBalloonHintingOK { + return &StartBalloonHintingOK{} +} + +/* +StartBalloonHintingOK describes a response with status code 200, with default header values. + +Free page hinting run started. +*/ +type StartBalloonHintingOK struct { +} + +// IsSuccess returns true when this start balloon hinting o k response has a 2xx status code +func (o *StartBalloonHintingOK) IsSuccess() bool { + return true +} + +// IsRedirect returns true when this start balloon hinting o k response has a 3xx status code +func (o *StartBalloonHintingOK) IsRedirect() bool { + return false +} + +// IsClientError returns true when this start balloon hinting o k response has a 4xx status code +func (o *StartBalloonHintingOK) IsClientError() bool { + return false +} + +// IsServerError returns true when this start balloon hinting o k response has a 5xx status code +func (o *StartBalloonHintingOK) IsServerError() bool { + return false +} + +// IsCode returns true when this start balloon hinting o k response a status code equal to that given +func (o *StartBalloonHintingOK) IsCode(code int) bool { + return code == 200 +} + +// Code gets the status code for the start balloon hinting o k response +func (o *StartBalloonHintingOK) Code() int { + return 200 +} + +func (o *StartBalloonHintingOK) Error() string { + return fmt.Sprintf("[PATCH /balloon/hinting/start][%d] startBalloonHintingOK", 200) +} + +func (o *StartBalloonHintingOK) String() string { + return fmt.Sprintf("[PATCH /balloon/hinting/start][%d] startBalloonHintingOK", 200) +} + +func (o *StartBalloonHintingOK) readResponse(response runtime.ClientResponse, consumer runtime.Consumer, formats strfmt.Registry) error { + + return nil +} + +// NewStartBalloonHintingBadRequest creates a StartBalloonHintingBadRequest with default headers values +func NewStartBalloonHintingBadRequest() *StartBalloonHintingBadRequest { + return &StartBalloonHintingBadRequest{} +} + +/* +StartBalloonHintingBadRequest describes a response with status code 400, with default header values. + +The balloon free hinting was not enabled when the device was configured. +*/ +type StartBalloonHintingBadRequest struct { + Payload *models.Error +} + +// IsSuccess returns true when this start balloon hinting bad request response has a 2xx status code +func (o *StartBalloonHintingBadRequest) IsSuccess() bool { + return false +} + +// IsRedirect returns true when this start balloon hinting bad request response has a 3xx status code +func (o *StartBalloonHintingBadRequest) IsRedirect() bool { + return false +} + +// IsClientError returns true when this start balloon hinting bad request response has a 4xx status code +func (o *StartBalloonHintingBadRequest) IsClientError() bool { + return true +} + +// IsServerError returns true when this start balloon hinting bad request response has a 5xx status code +func (o *StartBalloonHintingBadRequest) IsServerError() bool { + return false +} + +// IsCode returns true when this start balloon hinting bad request response a status code equal to that given +func (o *StartBalloonHintingBadRequest) IsCode(code int) bool { + return code == 400 +} + +// Code gets the status code for the start balloon hinting bad request response +func (o *StartBalloonHintingBadRequest) Code() int { + return 400 +} + +func (o *StartBalloonHintingBadRequest) Error() string { + payload, _ := json.Marshal(o.Payload) + return fmt.Sprintf("[PATCH /balloon/hinting/start][%d] startBalloonHintingBadRequest %s", 400, payload) +} + +func (o *StartBalloonHintingBadRequest) String() string { + payload, _ := json.Marshal(o.Payload) + return fmt.Sprintf("[PATCH /balloon/hinting/start][%d] startBalloonHintingBadRequest %s", 400, payload) +} + +func (o *StartBalloonHintingBadRequest) GetPayload() *models.Error { + return o.Payload +} + +func (o *StartBalloonHintingBadRequest) readResponse(response runtime.ClientResponse, consumer runtime.Consumer, formats strfmt.Registry) error { + + o.Payload = new(models.Error) + + // response payload + if err := consumer.Consume(response.Body(), o.Payload); err != nil && !stderrors.Is(err, io.EOF) { + return err + } + + return nil +} + +// NewStartBalloonHintingDefault creates a StartBalloonHintingDefault with default headers values +func NewStartBalloonHintingDefault(code int) *StartBalloonHintingDefault { + return &StartBalloonHintingDefault{ + _statusCode: code, + } +} + +/* +StartBalloonHintingDefault describes a response with status code -1, with default header values. + +Internal Server Error +*/ +type StartBalloonHintingDefault struct { + _statusCode int + + Payload *models.Error +} + +// IsSuccess returns true when this start balloon hinting default response has a 2xx status code +func (o *StartBalloonHintingDefault) IsSuccess() bool { + return o._statusCode/100 == 2 +} + +// IsRedirect returns true when this start balloon hinting default response has a 3xx status code +func (o *StartBalloonHintingDefault) IsRedirect() bool { + return o._statusCode/100 == 3 +} + +// IsClientError returns true when this start balloon hinting default response has a 4xx status code +func (o *StartBalloonHintingDefault) IsClientError() bool { + return o._statusCode/100 == 4 +} + +// IsServerError returns true when this start balloon hinting default response has a 5xx status code +func (o *StartBalloonHintingDefault) IsServerError() bool { + return o._statusCode/100 == 5 +} + +// IsCode returns true when this start balloon hinting default response a status code equal to that given +func (o *StartBalloonHintingDefault) IsCode(code int) bool { + return o._statusCode == code +} + +// Code gets the status code for the start balloon hinting default response +func (o *StartBalloonHintingDefault) Code() int { + return o._statusCode +} + +func (o *StartBalloonHintingDefault) Error() string { + payload, _ := json.Marshal(o.Payload) + return fmt.Sprintf("[PATCH /balloon/hinting/start][%d] startBalloonHinting default %s", o._statusCode, payload) +} + +func (o *StartBalloonHintingDefault) String() string { + payload, _ := json.Marshal(o.Payload) + return fmt.Sprintf("[PATCH /balloon/hinting/start][%d] startBalloonHinting default %s", o._statusCode, payload) +} + +func (o *StartBalloonHintingDefault) GetPayload() *models.Error { + return o.Payload +} + +func (o *StartBalloonHintingDefault) readResponse(response runtime.ClientResponse, consumer runtime.Consumer, formats strfmt.Registry) error { + + o.Payload = new(models.Error) + + // response payload + if err := consumer.Consume(response.Body(), o.Payload); err != nil && !stderrors.Is(err, io.EOF) { + return err + } + + return nil +} diff --git a/packages/shared/pkg/fc/client/operations/stop_balloon_hinting_parameters.go b/packages/shared/pkg/fc/client/operations/stop_balloon_hinting_parameters.go new file mode 100644 index 0000000000..8cb0986560 --- /dev/null +++ b/packages/shared/pkg/fc/client/operations/stop_balloon_hinting_parameters.go @@ -0,0 +1,125 @@ +// Code generated by go-swagger; DO NOT EDIT. + +package operations + +import ( + "context" + "net/http" + "time" + + "github.com/go-openapi/errors" + "github.com/go-openapi/runtime" + cr "github.com/go-openapi/runtime/client" + "github.com/go-openapi/strfmt" +) + +// NewStopBalloonHintingParams creates a new StopBalloonHintingParams object, +// with the default timeout for this client. +// +// Default values are not hydrated, since defaults are normally applied by the API server side. +// +// To enforce default values in parameter, use SetDefaults or WithDefaults. +func NewStopBalloonHintingParams() *StopBalloonHintingParams { + return &StopBalloonHintingParams{ + timeout: cr.DefaultTimeout, + } +} + +// NewStopBalloonHintingParamsWithTimeout creates a new StopBalloonHintingParams object +// with the ability to set a timeout on a request. +func NewStopBalloonHintingParamsWithTimeout(timeout time.Duration) *StopBalloonHintingParams { + return &StopBalloonHintingParams{ + timeout: timeout, + } +} + +// NewStopBalloonHintingParamsWithContext creates a new StopBalloonHintingParams object +// with the ability to set a context for a request. +func NewStopBalloonHintingParamsWithContext(ctx context.Context) *StopBalloonHintingParams { + return &StopBalloonHintingParams{ + Context: ctx, + } +} + +// NewStopBalloonHintingParamsWithHTTPClient creates a new StopBalloonHintingParams object +// with the ability to set a custom HTTPClient for a request. +func NewStopBalloonHintingParamsWithHTTPClient(client *http.Client) *StopBalloonHintingParams { + return &StopBalloonHintingParams{ + HTTPClient: client, + } +} + +/* +StopBalloonHintingParams contains all the parameters to send to the API endpoint + + for the stop balloon hinting operation. + + Typically these are written to a http.Request. +*/ +type StopBalloonHintingParams struct { + timeout time.Duration + Context context.Context + HTTPClient *http.Client +} + +// WithDefaults hydrates default values in the stop balloon hinting params (not the query body). +// +// All values with no default are reset to their zero value. +func (o *StopBalloonHintingParams) WithDefaults() *StopBalloonHintingParams { + o.SetDefaults() + return o +} + +// SetDefaults hydrates default values in the stop balloon hinting params (not the query body). +// +// All values with no default are reset to their zero value. +func (o *StopBalloonHintingParams) SetDefaults() { + // no default values defined for this parameter +} + +// WithTimeout adds the timeout to the stop balloon hinting params +func (o *StopBalloonHintingParams) WithTimeout(timeout time.Duration) *StopBalloonHintingParams { + o.SetTimeout(timeout) + return o +} + +// SetTimeout adds the timeout to the stop balloon hinting params +func (o *StopBalloonHintingParams) SetTimeout(timeout time.Duration) { + o.timeout = timeout +} + +// WithContext adds the context to the stop balloon hinting params +func (o *StopBalloonHintingParams) WithContext(ctx context.Context) *StopBalloonHintingParams { + o.SetContext(ctx) + return o +} + +// SetContext adds the context to the stop balloon hinting params +func (o *StopBalloonHintingParams) SetContext(ctx context.Context) { + o.Context = ctx +} + +// WithHTTPClient adds the HTTPClient to the stop balloon hinting params +func (o *StopBalloonHintingParams) WithHTTPClient(client *http.Client) *StopBalloonHintingParams { + o.SetHTTPClient(client) + return o +} + +// SetHTTPClient adds the HTTPClient to the stop balloon hinting params +func (o *StopBalloonHintingParams) SetHTTPClient(client *http.Client) { + o.HTTPClient = client +} + +// WriteToRequest writes these params to a swagger request +func (o *StopBalloonHintingParams) WriteToRequest(r runtime.ClientRequest, reg strfmt.Registry) error { + + if err := r.SetTimeout(o.timeout); err != nil { + return err + } + var res []error + + if len(res) > 0 { + return errors.CompositeValidationError(res...) + } + return nil +} diff --git a/packages/shared/pkg/fc/client/operations/stop_balloon_hinting_responses.go b/packages/shared/pkg/fc/client/operations/stop_balloon_hinting_responses.go new file mode 100644 index 0000000000..d08561d4fd --- /dev/null +++ b/packages/shared/pkg/fc/client/operations/stop_balloon_hinting_responses.go @@ -0,0 +1,247 @@ +// Code generated by go-swagger; DO NOT EDIT. + +package operations + +import ( + "encoding/json" + stderrors "errors" + "fmt" + "io" + + "github.com/go-openapi/runtime" + "github.com/go-openapi/strfmt" + + "github.com/e2b-dev/infra/packages/shared/pkg/fc/models" +) + +// StopBalloonHintingReader is a Reader for the StopBalloonHinting structure. +type StopBalloonHintingReader struct { + formats strfmt.Registry +} + +// ReadResponse reads a server response into the received o. +func (o *StopBalloonHintingReader) ReadResponse(response runtime.ClientResponse, consumer runtime.Consumer) (any, error) { + switch response.Code() { + case 200: + result := NewStopBalloonHintingOK() + if err := result.readResponse(response, consumer, o.formats); err != nil { + return nil, err + } + return result, nil + case 400: + result := NewStopBalloonHintingBadRequest() + if err := result.readResponse(response, consumer, o.formats); err != nil { + return nil, err + } + return nil, result + default: + result := NewStopBalloonHintingDefault(response.Code()) + if err := result.readResponse(response, consumer, o.formats); err != nil { + return nil, err + } + if response.Code()/100 == 2 { + return result, nil + } + return nil, result + } +} + +// NewStopBalloonHintingOK creates a StopBalloonHintingOK with default headers values +func NewStopBalloonHintingOK() *StopBalloonHintingOK { + return &StopBalloonHintingOK{} +} + +/* +StopBalloonHintingOK describes a response with status code 200, with default header values. + +Free page hinting run stopped. +*/ +type StopBalloonHintingOK struct { +} + +// IsSuccess returns true when this stop balloon hinting o k response has a 2xx status code +func (o *StopBalloonHintingOK) IsSuccess() bool { + return true +} + +// IsRedirect returns true when this stop balloon hinting o k response has a 3xx status code +func (o *StopBalloonHintingOK) IsRedirect() bool { + return false +} + +// IsClientError returns true when this stop balloon hinting o k response has a 4xx status code +func (o *StopBalloonHintingOK) IsClientError() bool { + return false +} + +// IsServerError returns true when this stop balloon hinting o k response has a 5xx status code +func (o *StopBalloonHintingOK) IsServerError() bool { + return false +} + +// IsCode returns true when this stop balloon hinting o k response a status code equal to that given +func (o *StopBalloonHintingOK) IsCode(code int) bool { + return code == 200 +} + +// Code gets the status code for the stop balloon hinting o k response +func (o *StopBalloonHintingOK) Code() int { + return 200 +} + +func (o *StopBalloonHintingOK) Error() string { + return fmt.Sprintf("[PATCH /balloon/hinting/stop][%d] stopBalloonHintingOK", 200) +} + +func (o *StopBalloonHintingOK) String() string { + return fmt.Sprintf("[PATCH /balloon/hinting/stop][%d] stopBalloonHintingOK", 200) +} + +func (o *StopBalloonHintingOK) readResponse(response runtime.ClientResponse, consumer runtime.Consumer, formats strfmt.Registry) error { + + return nil +} + +// NewStopBalloonHintingBadRequest creates a StopBalloonHintingBadRequest with default headers values +func NewStopBalloonHintingBadRequest() *StopBalloonHintingBadRequest { + return &StopBalloonHintingBadRequest{} +} + +/* +StopBalloonHintingBadRequest describes a response with status code 400, with default header values. + +The balloon free hinting was not enabled when the device was configured. +*/ +type StopBalloonHintingBadRequest struct { + Payload *models.Error +} + +// IsSuccess returns true when this stop balloon hinting bad request response has a 2xx status code +func (o *StopBalloonHintingBadRequest) IsSuccess() bool { + return false +} + +// IsRedirect returns true when this stop balloon hinting bad request response has a 3xx status code +func (o *StopBalloonHintingBadRequest) IsRedirect() bool { + return false +} + +// IsClientError returns true when this stop balloon hinting bad request response has a 4xx status code +func (o *StopBalloonHintingBadRequest) IsClientError() bool { + return true +} + +// IsServerError returns true when this stop balloon hinting bad request response has a 5xx status code +func (o *StopBalloonHintingBadRequest) IsServerError() bool { + return false +} + +// IsCode returns true when this stop balloon hinting bad request response a status code equal to that given +func (o *StopBalloonHintingBadRequest) IsCode(code int) bool { + return code == 400 +} + +// Code gets the status code for the stop balloon hinting bad request response +func (o *StopBalloonHintingBadRequest) Code() int { + return 400 +} + +func (o *StopBalloonHintingBadRequest) Error() string { + payload, _ := json.Marshal(o.Payload) + return fmt.Sprintf("[PATCH /balloon/hinting/stop][%d] stopBalloonHintingBadRequest %s", 400, payload) +} + +func (o *StopBalloonHintingBadRequest) String() string { + payload, _ := json.Marshal(o.Payload) + return fmt.Sprintf("[PATCH /balloon/hinting/stop][%d] stopBalloonHintingBadRequest %s", 400, payload) +} + +func (o *StopBalloonHintingBadRequest) GetPayload() *models.Error { + return o.Payload +} + +func (o *StopBalloonHintingBadRequest) readResponse(response runtime.ClientResponse, consumer runtime.Consumer, formats strfmt.Registry) error { + + o.Payload = new(models.Error) + + // response payload + if err := consumer.Consume(response.Body(), o.Payload); err != nil && !stderrors.Is(err, io.EOF) { + return err + } + + return nil +} + +// NewStopBalloonHintingDefault creates a StopBalloonHintingDefault with default headers values +func NewStopBalloonHintingDefault(code int) *StopBalloonHintingDefault { + return &StopBalloonHintingDefault{ + _statusCode: code, + } +} + +/* +StopBalloonHintingDefault describes a response with status code -1, with default header values. + +Internal Server Error +*/ +type StopBalloonHintingDefault struct { + _statusCode int + + Payload *models.Error +} + +// IsSuccess returns true when this stop balloon hinting default response has a 2xx status code +func (o *StopBalloonHintingDefault) IsSuccess() bool { + return o._statusCode/100 == 2 +} + +// IsRedirect returns true when this stop balloon hinting default response has a 3xx status code +func (o *StopBalloonHintingDefault) IsRedirect() bool { + return o._statusCode/100 == 3 +} + +// IsClientError returns true when this stop balloon hinting default response has a 4xx status code +func (o *StopBalloonHintingDefault) IsClientError() bool { + return o._statusCode/100 == 4 +} + +// IsServerError returns true when this stop balloon hinting default response has a 5xx status code +func (o *StopBalloonHintingDefault) IsServerError() bool { + return o._statusCode/100 == 5 +} + +// IsCode returns true when this stop balloon hinting default response a status code equal to that given +func (o *StopBalloonHintingDefault) IsCode(code int) bool { + return o._statusCode == code +} + +// Code gets the status code for the stop balloon hinting default response +func (o *StopBalloonHintingDefault) Code() int { + return o._statusCode +} + +func (o *StopBalloonHintingDefault) Error() string { + payload, _ := json.Marshal(o.Payload) + return fmt.Sprintf("[PATCH /balloon/hinting/stop][%d] stopBalloonHinting default %s", o._statusCode, payload) +} + +func (o *StopBalloonHintingDefault) String() string { + payload, _ := json.Marshal(o.Payload) + return fmt.Sprintf("[PATCH /balloon/hinting/stop][%d] stopBalloonHinting default %s", o._statusCode, payload) +} + +func (o *StopBalloonHintingDefault) GetPayload() *models.Error { + return o.Payload +} + +func (o *StopBalloonHintingDefault) readResponse(response runtime.ClientResponse, consumer runtime.Consumer, formats strfmt.Registry) error { + + o.Payload = new(models.Error) + + // response payload + if err := consumer.Consume(response.Body(), o.Payload); err != nil && !stderrors.Is(err, io.EOF) { + return err + } + + return nil +} diff --git a/packages/shared/pkg/fc/firecracker.yml b/packages/shared/pkg/fc/firecracker.yml index 61ed7a61fd..af1cfb806c 100644 --- a/packages/shared/pkg/fc/firecracker.yml +++ b/packages/shared/pkg/fc/firecracker.yml @@ -5,7 +5,7 @@ info: The API is accessible through HTTP calls on specific URLs carrying JSON modeled data. The transport medium is a Unix Domain Socket. - version: 1.12.1 + version: 1.14.1 termsOfService: "" contact: email: "firecracker-maintainers@amazon.com" @@ -169,6 +169,63 @@ paths: schema: $ref: "#/definitions/Error" + /balloon/hinting/start: + patch: + summary: Starts a free page hinting run only if enabled pre-boot. + operationId: startBalloonHinting + parameters: + - name: body + in: body + description: When the device completes the hinting whether we should automatically ack this. + required: false + schema: + $ref: "#/definitions/BalloonStartCmd" + responses: + 200: + description: Free page hinting run started. + 400: + description: The balloon free hinting was not enabled when the device was configured. + schema: + $ref: "#/definitions/Error" + default: + description: Internal Server Error + schema: + $ref: "#/definitions/Error" + + /balloon/hinting/status: + get: + summary: Returns the balloon hinting statistics, only if enabled pre-boot. + operationId: describeBalloonHinting + responses: + 200: + description: The balloon free page hinting statistics + schema: + $ref: "#/definitions/BalloonHintingStatus" + 400: + description: The balloon free hinting was not enabled when the device was configured. + schema: + $ref: "#/definitions/Error" + default: + description: Internal Server Error + schema: + $ref: "#/definitions/Error" + + /balloon/hinting/stop: + patch: + summary: Stops a free page hinting run only if enabled pre-boot. + operationId: stopBalloonHinting + responses: + 200: + description: Free page hinting run stopped. + 400: + description: The balloon free hinting was not enabled when the device was configured. + schema: + $ref: "#/definitions/Error" + default: + description: Internal Server Error + schema: + $ref: "#/definitions/Error" + /boot-source: put: summary: Creates or updates the boot source. Pre-boot only. @@ -282,6 +339,38 @@ paths: schema: $ref: "#/definitions/Error" + /pmem/{id}: + put: + summary: Creates or updates a pmem device. Pre-boot only. + description: + Creates new pmem device with ID specified by id parameter. + If a pmem device with the specified ID already exists, updates its state based on new input. + Will fail if update is not possible. + operationId: putGuestPmemByID + parameters: + - name: id + in: path + description: The id of the guest pmem device + required: true + type: string + - name: body + in: body + description: Guest pmem device properties + required: true + schema: + $ref: "#/definitions/Pmem" + responses: + 204: + description: Pmem device is created/updated + 400: + description: Pmem device cannot be created/updated due to bad input + schema: + $ref: "#/definitions/Error" + default: + description: Internal server error. + schema: + $ref: "#/definitions/Error" + /logger: put: summary: Initializes the logger by specifying a named pipe or a file for the logs output. @@ -450,6 +539,7 @@ paths: description: The MMDS data store JSON. schema: type: object + additionalProperties: true 404: description: The MMDS data store content can not be found. schema: @@ -506,6 +596,84 @@ paths: schema: $ref: "#/definitions/Error" + /serial: + put: + summary: Configures the serial console + operationId: putSerialDevice + description: + Configure the serial console, which the guest can write its kernel logs to. Has no effect if + the serial console is not also enabled on the guest kernel command line + parameters: + - name: body + in: body + description: Serial console properties + required: true + schema: + $ref: "#/definitions/SerialDevice" + responses: + 204: + description: Serial device configured + default: + description: Internal server error + schema: + $ref: "#/definitions/Error" + + /hotplug/memory: + put: + summary: Configures the hotpluggable memory + operationId: putMemoryHotplug + description: + Configure the hotpluggable memory, which is a virtio-mem device, with an associated memory area + that can be hot(un)plugged in the guest on demand using the PATCH API. + parameters: + - name: body + in: body + description: Hotpluggable memory configuration + required: true + schema: + $ref: "#/definitions/MemoryHotplugConfig" + responses: + 204: + description: Hotpluggable memory configured + default: + description: Internal server error + schema: + $ref: "#/definitions/Error" + patch: + summary: Updates the size of the hotpluggable memory region + operationId: patchMemoryHotplug + description: + Updates the size of the hotpluggable memory region. The guest will plug and unplug memory to + hit the requested memory. + parameters: + - name: body + in: body + description: Hotpluggable memory size update + required: true + schema: + $ref: "#/definitions/MemoryHotplugSizeUpdate" + responses: + 204: + description: Hotpluggable memory configured + default: + description: Internal server error + schema: + $ref: "#/definitions/Error" + get: + summary: Retrieves the status of the hotpluggable memory + operationId: getMemoryHotplug + description: + Reuturn the status of the hotpluggable memory. This can be used to follow the progress of the guest + after a PATCH API. + responses: + 200: + description: OK + schema: + $ref: "#/definitions/MemoryHotplugStatus" + default: + description: Internal server error + schema: + $ref: "#/definitions/Error" /network-interfaces/{iface_id}: put: @@ -575,7 +743,7 @@ paths: parameters: - name: body in: body - description: The configuration used for creating a snaphot. + description: The configuration used for creating a snapshot. required: true schema: $ref: "#/definitions/SnapshotCreateParams" @@ -602,7 +770,7 @@ paths: parameters: - name: body in: body - description: The configuration used for loading a snaphot. + description: The configuration used for loading a snapshot. required: true schema: $ref: "#/definitions/SnapshotLoadParams" @@ -767,6 +935,12 @@ definitions: stats_polling_interval_s: type: integer description: Interval in seconds between refreshing statistics. A non-zero value will enable the statistics. Defaults to 0. + free_page_hinting: + type: boolean + description: Whether the free page hinting feature is enabled. + free_page_reporting: + type: boolean + description: Whether the free page reporting feature is enabled. BalloonUpdate: type: object @@ -841,6 +1015,53 @@ definitions: description: The number of failed hugetlb page allocations in the guest. type: integer format: int64 + oom_kill: + description: OOM killer invocations, indicating critical memory pressure. + type: integer + format: int64 + alloc_stall: + description: Counter of Allocation enter a slow path to gain more memory page. The reclaim/scan metrics can reveal what is actually happening. + type: integer + format: int64 + async_scan: + description: Amount of memory scanned asynchronously. + type: integer + format: int64 + direct_scan: + description: Amount of memory scanned directly. + type: integer + format: int64 + async_reclaim: + description: Amount of memory reclaimed asynchronously. + type: integer + format: int64 + direct_reclaim: + description: Amount of memory reclaimed directly. + type: integer + format: int64 + + BalloonStartCmd: + type: object + description: + Command used to start a free page hinting run. + properties: + acknowledge_on_stop: + description: If Firecracker should automatically acknowledge when the guest submits a done cmd. + type: boolean + + BalloonHintingStatus: + type: object + description: + Describes the free page hinting status. + required: + - host_cmd + properties: + host_cmd: + description: The last command issued by the host. + type: integer + guest_cmd: + description: The last command provided by the guest. + type: integer BalloonStatsUpdate: type: object @@ -893,21 +1114,119 @@ definitions: The CPU configuration template defines a set of bit maps as modifiers of flags accessed by register to be disabled/enabled for the microvm. properties: + kvm_capabilities: + type: array + description: A collection of KVM capabilities to be added or removed (both x86_64 and aarch64) + items: + type: string + description: KVM capability as a numeric string. Prefix with '!' to remove capability. Example "121" (add) or "!121" (remove) cpuid_modifiers: - type: object - description: A collection of CPUIDs to be modified. (x86_64) + type: array + description: A collection of CPUID leaf modifiers (x86_64 only) + items: + $ref: "#/definitions/CpuidLeafModifier" msr_modifiers: - type: object - description: A collection of model specific registers to be modified. (x86_64) + type: array + description: A collection of model specific register modifiers (x86_64 only) + items: + $ref: "#/definitions/MsrModifier" reg_modifiers: - type: object - description: A collection of registers to be modified. (aarch64) + type: array + description: A collection of register modifiers (aarch64 only) + items: + $ref: "#/definitions/ArmRegisterModifier" vcpu_features: - type: object - description: A collection of vcpu features to be modified. (aarch64) - kvm_capabilities: - type: object - description: A collection of kvm capabilities to be modified. (aarch64) + type: array + description: A collection of vCPU features to be modified (aarch64 only) + items: + $ref: "#/definitions/VcpuFeatures" + + CpuidLeafModifier: + type: object + description: Modifier for a CPUID leaf and subleaf (x86_64) + required: + - leaf + - subleaf + - flags + - modifiers + properties: + leaf: + type: string + description: CPUID leaf index as hex, binary, or decimal string (e.g., "0x0", "0b0", "0")) + subleaf: + type: string + description: CPUID subleaf index as hex, binary, or decimal string (e.g., "0x0", "0b0", "0") + flags: + type: integer + format: int32 + description: KVM feature flags for this leaf-subleaf + modifiers: + type: array + description: Register modifiers for this CPUID leaf + items: + $ref: "#/definitions/CpuidRegisterModifier" + + CpuidRegisterModifier: + type: object + description: Modifier for a specific CPUID register within a leaf (x86_64) + required: + - register + - bitmap + properties: + register: + type: string + description: Target CPUID register name + enum: + - eax + - ebx + - ecx + - edx + bitmap: + type: string + description: 32-bit bitmap string defining which bits to modify. Format is "0b" followed by 32 characters where '0' = clear bit, '1' = set bit, 'x' = don't modify. Example "0b00000000000000000000000000000001" or "0bxxxxxxxxxxxxxxxxxxxxxxxxxxxx0001" + + MsrModifier: + type: object + description: Modifier for a model specific register (x86_64) + required: + - addr + - bitmap + properties: + addr: + type: string + description: 32-bit MSR address as hex, binary, or decimal string (e.g., "0x10a", "0b100001010", "266") + bitmap: + type: string + description: 64-bit bitmap string defining which bits to modify. Format is "0b" followed by 64 characters where '0' = clear bit, '1' = set bit, 'x' = don't modify. Underscores can be used for readability. Example "0b0000000000000000000000000000000000000000000000000000000000000001" + + ArmRegisterModifier: + type: object + description: Modifier for an ARM register (aarch64) + required: + - addr + - bitmap + properties: + addr: + type: string + description: 64-bit register address as hex, binary, or decimal string (e.g., "0x0", "0b0", "0") + bitmap: + type: string + description: 128-bit bitmap string defining which bits to modify. Format is "0b" followed by up to 128 characters where '0' = clear bit, '1' = set bit, 'x' = don't modify. Underscores can be used for readability. Example "0b0000000000000000000000000000000000000000000000000000000000000001" + + VcpuFeatures: + type: object + description: vCPU feature modifier (aarch64) + required: + - index + - bitmap + properties: + index: + type: integer + format: int32 + description: Index in the kvm_vcpu_init.features array + bitmap: + type: string + description: 32-bit bitmap string defining which bits to modify. Format is "0b" followed by 32 characters where '0' = clear bit, '1' = set bit, 'x' = don't modify. Example "0b00000000000000000000000001100000" Drive: type: object @@ -936,7 +1255,7 @@ definitions: is_read_only: type: boolean description: - Is block read only. + Is block read only. This field is required for virtio-block config and should be omitted for vhost-user-block configuration. path_on_host: type: string @@ -961,6 +1280,30 @@ definitions: Path to the socket of vhost-user-block backend. This field is required for vhost-user-block config should be omitted for virtio-block configuration. + Pmem: + type: object + required: + - id + - path_on_host + properties: + id: + type: string + description: + Identificator for this device. + path_on_host: + type: string + description: + Host level path for the virtio-pmem device to use as a backing file. + root_device: + type: boolean + description: + Flag to make this device be the root device for VM boot. + Setting this flag will fail if there is another device configured to be a root device already. + read_only: + type: boolean + description: + Flag to map backing file in read-only mode. + Error: type: object properties: @@ -989,6 +1332,8 @@ definitions: $ref: "#/definitions/MachineConfiguration" metrics: $ref: "#/definitions/Metrics" + memory-hotplug: + $ref: "#/definitions/MemoryHotplugConfig" mmds-config: $ref: "#/definitions/MmdsConfig" network-interfaces: @@ -996,6 +1341,11 @@ definitions: description: Configurations for all net devices. items: $ref: "#/definitions/NetworkInterface" + pmem: + type: array + description: Configurations for all pmem devices. + items: + $ref: "#/definitions/Pmem" vsock: $ref: "#/definitions/Vsock" entropy: @@ -1239,11 +1589,18 @@ definitions: format: "169.254.([1-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-4]).([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])" default: "169.254.169.254" description: A valid IPv4 link-local address. + imds_compat: + type: boolean + description: + MMDS operates compatibly with EC2 IMDS (i.e. responds "text/plain" + content regardless of Accept header in requests). + default: false MmdsContentsObject: type: object description: Describes the contents of MMDS in JSON format. + additionalProperties: true NetworkInterface: type: object @@ -1316,7 +1673,10 @@ definitions: properties: mem_file_path: type: string - description: Path to the file that will contain the guest memory. + description: + Path to the file that will contain the guest memory. It is optional. + In case that a user doesn't provide a path, they are responsible to + ensure they store the microVM's memory state via external means. snapshot_path: type: string description: Path to the file that will contain the microVM state. @@ -1358,7 +1718,11 @@ definitions: enable_diff_snapshots: type: boolean description: - Enable support for incremental (diff) snapshots by tracking dirty guest pages. + (Deprecated) Enable dirty page tracking to improve space efficiency of diff snapshots + track_dirty_pages: + type: boolean + description: + Enable dirty page tracking to improve space efficiency of diff snapshots mem_file_path: type: string description: @@ -1438,6 +1802,66 @@ definitions: rate_limiter: $ref: "#/definitions/RateLimiter" + SerialDevice: + type: object + description: + The configuration of the serial device + properties: + serial_out_path: + type: string + description: Path to a file or named pipe on the host to which serial output should be written. + + MemoryHotplugConfig: + type: object + description: + The configuration of the hotpluggable memory device (virtio-mem) + properties: + total_size_mib: + type: integer + description: Total size of the hotpluggable memory in MiB. + slot_size_mib: + type: integer + default: 128 + minimum: 128 + description: Slot size for the hotpluggable memory in MiB. This will determine the granularity of + hot-plug memory from the host. Refer to the device documentation on how to tune this value. + block_size_mib: + type: integer + default: 2 + minimum: 2 + description: (Logical) Block size for the hotpluggable memory in MiB. This will determine the logical + granularity of hot-plug memory for the guest. Refer to the device documentation on how to tune this value. + + MemoryHotplugSizeUpdate: + type: object + description: + An update to the size of the hotpluggable memory region. + properties: + requested_size_mib: + type: integer + description: New target region size. + + MemoryHotplugStatus: + type: object + description: + The status of the hotpluggable memory device (virtio-mem) + properties: + total_size_mib: + type: integer + description: Total size of the hotpluggable memory in MiB. + slot_size_mib: + type: integer + description: Slot size for the hotpluggable memory in MiB. + block_size_mib: + type: integer + description: (Logical) Block size for the hotpluggable memory in MiB. + plugged_size_mib: + type: integer + description: Plugged size for the hotpluggable memory in MiB. + requested_size_mib: + type: integer + description: Requested size for the hotpluggable memory in MiB. + FirecrackerVersion: type: object description: diff --git a/packages/shared/pkg/fc/models/arm_register_modifier.go b/packages/shared/pkg/fc/models/arm_register_modifier.go new file mode 100644 index 0000000000..1c6c79119f --- /dev/null +++ b/packages/shared/pkg/fc/models/arm_register_modifier.go @@ -0,0 +1,85 @@ +// Code generated by go-swagger; DO NOT EDIT. + +package models + +import ( + "context" + + "github.com/go-openapi/errors" + "github.com/go-openapi/strfmt" + "github.com/go-openapi/swag" + "github.com/go-openapi/validate" +) + +// ArmRegisterModifier Modifier for an ARM register (aarch64) +// +// swagger:model ArmRegisterModifier +type ArmRegisterModifier struct { + + // 64-bit register address as hex, binary, or decimal string (e.g., "0x0", "0b0", "0") + // Required: true + Addr *string `json:"addr"` + + // 128-bit bitmap string defining which bits to modify. Format is "0b" followed by up to 128 characters where '0' = clear bit, '1' = set bit, 'x' = don't modify. Underscores can be used for readability. Example "0b0000000000000000000000000000000000000000000000000000000000000001" + // Required: true + Bitmap *string `json:"bitmap"` +} + +// Validate validates this arm register modifier +func (m *ArmRegisterModifier) Validate(formats strfmt.Registry) error { + var res []error + + if err := m.validateAddr(formats); err != nil { + res = append(res, err) + } + + if err := m.validateBitmap(formats); err != nil { + res = append(res, err) + } + + if len(res) > 0 { + return errors.CompositeValidationError(res...) + } + return nil +} + +func (m *ArmRegisterModifier) validateAddr(formats strfmt.Registry) error { + + if err := validate.Required("addr", "body", m.Addr); err != nil { + return err + } + + return nil +} + +func (m *ArmRegisterModifier) validateBitmap(formats strfmt.Registry) error { + + if err := validate.Required("bitmap", "body", m.Bitmap); err != nil { + return err + } + + return nil +} + +// ContextValidate validates this arm register modifier based on context it is used +func (m *ArmRegisterModifier) ContextValidate(ctx context.Context, formats strfmt.Registry) error { + return nil +} + +// MarshalBinary interface implementation +func (m *ArmRegisterModifier) MarshalBinary() ([]byte, error) { + if m == nil { + return nil, nil + } + return swag.WriteJSON(m) +} + +// UnmarshalBinary interface implementation +func (m *ArmRegisterModifier) UnmarshalBinary(b []byte) error { + var res ArmRegisterModifier + if err := swag.ReadJSON(b, &res); err != nil { + return err + } + *m = res + return nil +} diff --git a/packages/shared/pkg/fc/models/balloon.go b/packages/shared/pkg/fc/models/balloon.go index ce73d06a8b..b209c8f1cd 100644 --- a/packages/shared/pkg/fc/models/balloon.go +++ b/packages/shared/pkg/fc/models/balloon.go @@ -24,6 +24,12 @@ type Balloon struct { // Required: true DeflateOnOom *bool `json:"deflate_on_oom"` + // Whether the free page hinting feature is enabled. + FreePageHinting bool `json:"free_page_hinting,omitempty"` + + // Whether the free page reporting feature is enabled. + FreePageReporting bool `json:"free_page_reporting,omitempty"` + // Interval in seconds between refreshing statistics. A non-zero value will enable the statistics. Defaults to 0. StatsPollingIntervals int64 `json:"stats_polling_interval_s,omitempty"` } diff --git a/packages/shared/pkg/fc/models/balloon_hinting_status.go b/packages/shared/pkg/fc/models/balloon_hinting_status.go new file mode 100644 index 0000000000..4b7c0b456e --- /dev/null +++ b/packages/shared/pkg/fc/models/balloon_hinting_status.go @@ -0,0 +1,71 @@ +// Code generated by go-swagger; DO NOT EDIT. + +package models + +import ( + "context" + + "github.com/go-openapi/errors" + "github.com/go-openapi/strfmt" + "github.com/go-openapi/swag" + "github.com/go-openapi/validate" +) + +// BalloonHintingStatus Describes the free page hinting status. +// +// swagger:model BalloonHintingStatus +type BalloonHintingStatus struct { + + // The last command provided by the guest. + GuestCmd int64 `json:"guest_cmd,omitempty"` + + // The last command issued by the host. + // Required: true + HostCmd *int64 `json:"host_cmd"` +} + +// Validate validates this balloon hinting status +func (m *BalloonHintingStatus) Validate(formats strfmt.Registry) error { + var res []error + + if err := m.validateHostCmd(formats); err != nil { + res = append(res, err) + } + + if len(res) > 0 { + return errors.CompositeValidationError(res...) + } + return nil +} + +func (m *BalloonHintingStatus) validateHostCmd(formats strfmt.Registry) error { + + if err := validate.Required("host_cmd", "body", m.HostCmd); err != nil { + return err + } + + return nil +} + +// ContextValidate validates this balloon hinting status based on context it is used +func (m *BalloonHintingStatus) ContextValidate(ctx context.Context, formats strfmt.Registry) error { + return nil +} + +// MarshalBinary interface implementation +func (m *BalloonHintingStatus) MarshalBinary() ([]byte, error) { + if m == nil { + return nil, nil + } + return swag.WriteJSON(m) +} + +// UnmarshalBinary interface implementation +func (m *BalloonHintingStatus) UnmarshalBinary(b []byte) error { + var res BalloonHintingStatus + if err := swag.ReadJSON(b, &res); err != nil { + return err + } + *m = res + return nil +} diff --git a/packages/shared/pkg/fc/models/balloon_start_cmd.go b/packages/shared/pkg/fc/models/balloon_start_cmd.go new file mode 100644 index 0000000000..d0b38243cc --- /dev/null +++ b/packages/shared/pkg/fc/models/balloon_start_cmd.go @@ -0,0 +1,47 @@ +// Code generated by go-swagger; DO NOT EDIT. + +package models + +import ( + "context" + + "github.com/go-openapi/strfmt" + "github.com/go-openapi/swag" +) + +// BalloonStartCmd Command used to start a free page hinting run. +// +// swagger:model BalloonStartCmd +type BalloonStartCmd struct { + + // If Firecracker should automatically acknowledge when the guest submits a done cmd. + AcknowledgeOnStop bool `json:"acknowledge_on_stop,omitempty"` +} + +// Validate validates this balloon start cmd +func (m *BalloonStartCmd) Validate(formats strfmt.Registry) error { + return nil +} + +// ContextValidate validates this balloon start cmd based on context it is used +func (m *BalloonStartCmd) ContextValidate(ctx context.Context, formats strfmt.Registry) error { + return nil +} + +// MarshalBinary interface implementation +func (m *BalloonStartCmd) MarshalBinary() ([]byte, error) { + if m == nil { + return nil, nil + } + return swag.WriteJSON(m) +} + +// UnmarshalBinary interface implementation +func (m *BalloonStartCmd) UnmarshalBinary(b []byte) error { + var res BalloonStartCmd + if err := swag.ReadJSON(b, &res); err != nil { + return err + } + *m = res + return nil +} diff --git a/packages/shared/pkg/fc/models/balloon_stats.go b/packages/shared/pkg/fc/models/balloon_stats.go index e32e9d8e58..a80c80867a 100644 --- a/packages/shared/pkg/fc/models/balloon_stats.go +++ b/packages/shared/pkg/fc/models/balloon_stats.go @@ -24,9 +24,24 @@ type BalloonStats struct { // Required: true ActualPages *int64 `json:"actual_pages"` + // Counter of Allocation enter a slow path to gain more memory page. The reclaim/scan metrics can reveal what is actually happening. + AllocStall int64 `json:"alloc_stall,omitempty"` + + // Amount of memory reclaimed asynchronously. + AsyncReclaim int64 `json:"async_reclaim,omitempty"` + + // Amount of memory scanned asynchronously. + AsyncScan int64 `json:"async_scan,omitempty"` + // An estimate of how much memory is available (in bytes) for starting new applications, without pushing the system to swap. AvailableMemory int64 `json:"available_memory,omitempty"` + // Amount of memory reclaimed directly. + DirectReclaim int64 `json:"direct_reclaim,omitempty"` + + // Amount of memory scanned directly. + DirectScan int64 `json:"direct_scan,omitempty"` + // The amount of memory, in bytes, that can be quickly reclaimed without additional I/O. Typically these pages are used for caching files from disk. DiskCaches int64 `json:"disk_caches,omitempty"` @@ -45,6 +60,9 @@ type BalloonStats struct { // The number of minor page faults that have occurred. MinorFaults int64 `json:"minor_faults,omitempty"` + // OOM killer invocations, indicating critical memory pressure. + OomKill int64 `json:"oom_kill,omitempty"` + // The amount of memory that has been swapped in (in bytes). SwapIn int64 `json:"swap_in,omitempty"` diff --git a/packages/shared/pkg/fc/models/cpu_config.go b/packages/shared/pkg/fc/models/cpu_config.go index c3c9927f90..7b5f5d03b6 100644 --- a/packages/shared/pkg/fc/models/cpu_config.go +++ b/packages/shared/pkg/fc/models/cpu_config.go @@ -4,7 +4,10 @@ package models import ( "context" + stderrors "errors" + "strconv" + "github.com/go-openapi/errors" "github.com/go-openapi/strfmt" "github.com/go-openapi/swag" ) @@ -14,29 +17,307 @@ import ( // swagger:model CpuConfig type CPUConfig struct { - // A collection of CPUIDs to be modified. (x86_64) - CpuidModifiers any `json:"cpuid_modifiers,omitempty"` + // A collection of CPUID leaf modifiers (x86_64 only) + CpuidModifiers []*CpuidLeafModifier `json:"cpuid_modifiers"` - // A collection of kvm capabilities to be modified. (aarch64) - KvmCapabilities any `json:"kvm_capabilities,omitempty"` + // A collection of KVM capabilities to be added or removed (both x86_64 and aarch64) + KvmCapabilities []string `json:"kvm_capabilities"` - // A collection of model specific registers to be modified. (x86_64) - MsrModifiers any `json:"msr_modifiers,omitempty"` + // A collection of model specific register modifiers (x86_64 only) + MsrModifiers []*MsrModifier `json:"msr_modifiers"` - // A collection of registers to be modified. (aarch64) - RegModifiers any `json:"reg_modifiers,omitempty"` + // A collection of register modifiers (aarch64 only) + RegModifiers []*ArmRegisterModifier `json:"reg_modifiers"` - // A collection of vcpu features to be modified. (aarch64) - VcpuFeatures any `json:"vcpu_features,omitempty"` + // A collection of vCPU features to be modified (aarch64 only) + VcpuFeatures []*VcpuFeatures `json:"vcpu_features"` } // Validate validates this Cpu config func (m *CPUConfig) Validate(formats strfmt.Registry) error { + var res []error + + if err := m.validateCpuidModifiers(formats); err != nil { + res = append(res, err) + } + + if err := m.validateMsrModifiers(formats); err != nil { + res = append(res, err) + } + + if err := m.validateRegModifiers(formats); err != nil { + res = append(res, err) + } + + if err := m.validateVcpuFeatures(formats); err != nil { + res = append(res, err) + } + + if len(res) > 0 { + return errors.CompositeValidationError(res...) + } + return nil +} + +func (m *CPUConfig) validateCpuidModifiers(formats strfmt.Registry) error { + if swag.IsZero(m.CpuidModifiers) { // not required + return nil + } + + for i := 0; i < len(m.CpuidModifiers); i++ { + if swag.IsZero(m.CpuidModifiers[i]) { // not required + continue + } + + if m.CpuidModifiers[i] != nil { + if err := m.CpuidModifiers[i].Validate(formats); err != nil { + ve := new(errors.Validation) + if stderrors.As(err, &ve) { + return ve.ValidateName("cpuid_modifiers" + "." + strconv.Itoa(i)) + } + ce := new(errors.CompositeError) + if stderrors.As(err, &ce) { + return ce.ValidateName("cpuid_modifiers" + "." + strconv.Itoa(i)) + } + + return err + } + } + + } + + return nil +} + +func (m *CPUConfig) validateMsrModifiers(formats strfmt.Registry) error { + if swag.IsZero(m.MsrModifiers) { // not required + return nil + } + + for i := 0; i < len(m.MsrModifiers); i++ { + if swag.IsZero(m.MsrModifiers[i]) { // not required + continue + } + + if m.MsrModifiers[i] != nil { + if err := m.MsrModifiers[i].Validate(formats); err != nil { + ve := new(errors.Validation) + if stderrors.As(err, &ve) { + return ve.ValidateName("msr_modifiers" + "." + strconv.Itoa(i)) + } + ce := new(errors.CompositeError) + if stderrors.As(err, &ce) { + return ce.ValidateName("msr_modifiers" + "." + strconv.Itoa(i)) + } + + return err + } + } + + } + + return nil +} + +func (m *CPUConfig) validateRegModifiers(formats strfmt.Registry) error { + if swag.IsZero(m.RegModifiers) { // not required + return nil + } + + for i := 0; i < len(m.RegModifiers); i++ { + if swag.IsZero(m.RegModifiers[i]) { // not required + continue + } + + if m.RegModifiers[i] != nil { + if err := m.RegModifiers[i].Validate(formats); err != nil { + ve := new(errors.Validation) + if stderrors.As(err, &ve) { + return ve.ValidateName("reg_modifiers" + "." + strconv.Itoa(i)) + } + ce := new(errors.CompositeError) + if stderrors.As(err, &ce) { + return ce.ValidateName("reg_modifiers" + "." + strconv.Itoa(i)) + } + + return err + } + } + + } + return nil } -// ContextValidate validates this Cpu config based on context it is used +func (m *CPUConfig) validateVcpuFeatures(formats strfmt.Registry) error { + if swag.IsZero(m.VcpuFeatures) { // not required + return nil + } + + for i := 0; i < len(m.VcpuFeatures); i++ { + if swag.IsZero(m.VcpuFeatures[i]) { // not required + continue + } + + if m.VcpuFeatures[i] != nil { + if err := m.VcpuFeatures[i].Validate(formats); err != nil { + ve := new(errors.Validation) + if stderrors.As(err, &ve) { + return ve.ValidateName("vcpu_features" + "." + strconv.Itoa(i)) + } + ce := new(errors.CompositeError) + if stderrors.As(err, &ce) { + return ce.ValidateName("vcpu_features" + "." + strconv.Itoa(i)) + } + + return err + } + } + + } + + return nil +} + +// ContextValidate validate this Cpu config based on the context it is used func (m *CPUConfig) ContextValidate(ctx context.Context, formats strfmt.Registry) error { + var res []error + + if err := m.contextValidateCpuidModifiers(ctx, formats); err != nil { + res = append(res, err) + } + + if err := m.contextValidateMsrModifiers(ctx, formats); err != nil { + res = append(res, err) + } + + if err := m.contextValidateRegModifiers(ctx, formats); err != nil { + res = append(res, err) + } + + if err := m.contextValidateVcpuFeatures(ctx, formats); err != nil { + res = append(res, err) + } + + if len(res) > 0 { + return errors.CompositeValidationError(res...) + } + return nil +} + +func (m *CPUConfig) contextValidateCpuidModifiers(ctx context.Context, formats strfmt.Registry) error { + + for i := 0; i < len(m.CpuidModifiers); i++ { + + if m.CpuidModifiers[i] != nil { + + if swag.IsZero(m.CpuidModifiers[i]) { // not required + return nil + } + + if err := m.CpuidModifiers[i].ContextValidate(ctx, formats); err != nil { + ve := new(errors.Validation) + if stderrors.As(err, &ve) { + return ve.ValidateName("cpuid_modifiers" + "." + strconv.Itoa(i)) + } + ce := new(errors.CompositeError) + if stderrors.As(err, &ce) { + return ce.ValidateName("cpuid_modifiers" + "." + strconv.Itoa(i)) + } + + return err + } + } + + } + + return nil +} + +func (m *CPUConfig) contextValidateMsrModifiers(ctx context.Context, formats strfmt.Registry) error { + + for i := 0; i < len(m.MsrModifiers); i++ { + + if m.MsrModifiers[i] != nil { + + if swag.IsZero(m.MsrModifiers[i]) { // not required + return nil + } + + if err := m.MsrModifiers[i].ContextValidate(ctx, formats); err != nil { + ve := new(errors.Validation) + if stderrors.As(err, &ve) { + return ve.ValidateName("msr_modifiers" + "." + strconv.Itoa(i)) + } + ce := new(errors.CompositeError) + if stderrors.As(err, &ce) { + return ce.ValidateName("msr_modifiers" + "." + strconv.Itoa(i)) + } + + return err + } + } + + } + + return nil +} + +func (m *CPUConfig) contextValidateRegModifiers(ctx context.Context, formats strfmt.Registry) error { + + for i := 0; i < len(m.RegModifiers); i++ { + + if m.RegModifiers[i] != nil { + + if swag.IsZero(m.RegModifiers[i]) { // not required + return nil + } + + if err := m.RegModifiers[i].ContextValidate(ctx, formats); err != nil { + ve := new(errors.Validation) + if stderrors.As(err, &ve) { + return ve.ValidateName("reg_modifiers" + "." + strconv.Itoa(i)) + } + ce := new(errors.CompositeError) + if stderrors.As(err, &ce) { + return ce.ValidateName("reg_modifiers" + "." + strconv.Itoa(i)) + } + + return err + } + } + + } + + return nil +} + +func (m *CPUConfig) contextValidateVcpuFeatures(ctx context.Context, formats strfmt.Registry) error { + + for i := 0; i < len(m.VcpuFeatures); i++ { + + if m.VcpuFeatures[i] != nil { + + if swag.IsZero(m.VcpuFeatures[i]) { // not required + return nil + } + + if err := m.VcpuFeatures[i].ContextValidate(ctx, formats); err != nil { + ve := new(errors.Validation) + if stderrors.As(err, &ve) { + return ve.ValidateName("vcpu_features" + "." + strconv.Itoa(i)) + } + ce := new(errors.CompositeError) + if stderrors.As(err, &ce) { + return ce.ValidateName("vcpu_features" + "." + strconv.Itoa(i)) + } + + return err + } + } + + } + return nil } diff --git a/packages/shared/pkg/fc/models/cpuid_leaf_modifier.go b/packages/shared/pkg/fc/models/cpuid_leaf_modifier.go new file mode 100644 index 0000000000..9ace041fef --- /dev/null +++ b/packages/shared/pkg/fc/models/cpuid_leaf_modifier.go @@ -0,0 +1,181 @@ +// Code generated by go-swagger; DO NOT EDIT. + +package models + +import ( + "context" + stderrors "errors" + "strconv" + + "github.com/go-openapi/errors" + "github.com/go-openapi/strfmt" + "github.com/go-openapi/swag" + "github.com/go-openapi/validate" +) + +// CpuidLeafModifier Modifier for a CPUID leaf and subleaf (x86_64) +// +// swagger:model CpuidLeafModifier +type CpuidLeafModifier struct { + + // KVM feature flags for this leaf-subleaf + // Required: true + Flags *int32 `json:"flags"` + + // CPUID leaf index as hex, binary, or decimal string (e.g., "0x0", "0b0", "0")) + // Required: true + Leaf *string `json:"leaf"` + + // Register modifiers for this CPUID leaf + // Required: true + Modifiers []*CpuidRegisterModifier `json:"modifiers"` + + // CPUID subleaf index as hex, binary, or decimal string (e.g., "0x0", "0b0", "0") + // Required: true + Subleaf *string `json:"subleaf"` +} + +// Validate validates this cpuid leaf modifier +func (m *CpuidLeafModifier) Validate(formats strfmt.Registry) error { + var res []error + + if err := m.validateFlags(formats); err != nil { + res = append(res, err) + } + + if err := m.validateLeaf(formats); err != nil { + res = append(res, err) + } + + if err := m.validateModifiers(formats); err != nil { + res = append(res, err) + } + + if err := m.validateSubleaf(formats); err != nil { + res = append(res, err) + } + + if len(res) > 0 { + return errors.CompositeValidationError(res...) + } + return nil +} + +func (m *CpuidLeafModifier) validateFlags(formats strfmt.Registry) error { + + if err := validate.Required("flags", "body", m.Flags); err != nil { + return err + } + + return nil +} + +func (m *CpuidLeafModifier) validateLeaf(formats strfmt.Registry) error { + + if err := validate.Required("leaf", "body", m.Leaf); err != nil { + return err + } + + return nil +} + +func (m *CpuidLeafModifier) validateModifiers(formats strfmt.Registry) error { + + if err := validate.Required("modifiers", "body", m.Modifiers); err != nil { + return err + } + + for i := 0; i < len(m.Modifiers); i++ { + if swag.IsZero(m.Modifiers[i]) { // not required + continue + } + + if m.Modifiers[i] != nil { + if err := m.Modifiers[i].Validate(formats); err != nil { + ve := new(errors.Validation) + if stderrors.As(err, &ve) { + return ve.ValidateName("modifiers" + "." + strconv.Itoa(i)) + } + ce := new(errors.CompositeError) + if stderrors.As(err, &ce) { + return ce.ValidateName("modifiers" + "." + strconv.Itoa(i)) + } + + return err + } + } + + } + + return nil +} + +func (m *CpuidLeafModifier) validateSubleaf(formats strfmt.Registry) error { + + if err := validate.Required("subleaf", "body", m.Subleaf); err != nil { + return err + } + + return nil +} + +// ContextValidate validate this cpuid leaf modifier based on the context it is used +func (m *CpuidLeafModifier) ContextValidate(ctx context.Context, formats strfmt.Registry) error { + var res []error + + if err := m.contextValidateModifiers(ctx, formats); err != nil { + res = append(res, err) + } + + if len(res) > 0 { + return errors.CompositeValidationError(res...) + } + return nil +} + +func (m *CpuidLeafModifier) contextValidateModifiers(ctx context.Context, formats strfmt.Registry) error { + + for i := 0; i < len(m.Modifiers); i++ { + + if m.Modifiers[i] != nil { + + if swag.IsZero(m.Modifiers[i]) { // not required + return nil + } + + if err := m.Modifiers[i].ContextValidate(ctx, formats); err != nil { + ve := new(errors.Validation) + if stderrors.As(err, &ve) { + return ve.ValidateName("modifiers" + "." + strconv.Itoa(i)) + } + ce := new(errors.CompositeError) + if stderrors.As(err, &ce) { + return ce.ValidateName("modifiers" + "." + strconv.Itoa(i)) + } + + return err + } + } + + } + + return nil +} + +// MarshalBinary interface implementation +func (m *CpuidLeafModifier) MarshalBinary() ([]byte, error) { + if m == nil { + return nil, nil + } + return swag.WriteJSON(m) +} + +// UnmarshalBinary interface implementation +func (m *CpuidLeafModifier) UnmarshalBinary(b []byte) error { + var res CpuidLeafModifier + if err := swag.ReadJSON(b, &res); err != nil { + return err + } + *m = res + return nil +} diff --git a/packages/shared/pkg/fc/models/cpuid_register_modifier.go b/packages/shared/pkg/fc/models/cpuid_register_modifier.go new file mode 100644 index 0000000000..9c77a5b28a --- /dev/null +++ b/packages/shared/pkg/fc/models/cpuid_register_modifier.go @@ -0,0 +1,127 @@ +// Code generated by go-swagger; DO NOT EDIT. + +package models + +import ( + "context" + "encoding/json" + + "github.com/go-openapi/errors" + "github.com/go-openapi/strfmt" + "github.com/go-openapi/swag" + "github.com/go-openapi/validate" +) + +// CpuidRegisterModifier Modifier for a specific CPUID register within a leaf (x86_64) +// +// swagger:model CpuidRegisterModifier +type CpuidRegisterModifier struct { + + // 32-bit bitmap string defining which bits to modify. Format is "0b" followed by 32 characters where '0' = clear bit, '1' = set bit, 'x' = don't modify. Example "0b00000000000000000000000000000001" or "0bxxxxxxxxxxxxxxxxxxxxxxxxxxxx0001" + // Required: true + Bitmap *string `json:"bitmap"` + + // Target CPUID register name + // Required: true + // Enum: ["eax","ebx","ecx","edx"] + Register *string `json:"register"` +} + +// Validate validates this cpuid register modifier +func (m *CpuidRegisterModifier) Validate(formats strfmt.Registry) error { + var res []error + + if err := m.validateBitmap(formats); err != nil { + res = append(res, err) + } + + if err := m.validateRegister(formats); err != nil { + res = append(res, err) + } + + if len(res) > 0 { + return errors.CompositeValidationError(res...) + } + return nil +} + +func (m *CpuidRegisterModifier) validateBitmap(formats strfmt.Registry) error { + + if err := validate.Required("bitmap", "body", m.Bitmap); err != nil { + return err + } + + return nil +} + +var cpuidRegisterModifierTypeRegisterPropEnum []any + +func init() { + var res []string + if err := json.Unmarshal([]byte(`["eax","ebx","ecx","edx"]`), &res); err != nil { + panic(err) + } + for _, v := range res { + cpuidRegisterModifierTypeRegisterPropEnum = append(cpuidRegisterModifierTypeRegisterPropEnum, v) + } +} + +const ( + + // CpuidRegisterModifierRegisterEax captures enum value "eax" + CpuidRegisterModifierRegisterEax string = "eax" + + // CpuidRegisterModifierRegisterEbx captures enum value "ebx" + CpuidRegisterModifierRegisterEbx string = "ebx" + + // CpuidRegisterModifierRegisterEcx captures enum value "ecx" + CpuidRegisterModifierRegisterEcx string = "ecx" + + // CpuidRegisterModifierRegisterEdx captures enum value "edx" + CpuidRegisterModifierRegisterEdx string = "edx" +) + +// prop value enum +func (m *CpuidRegisterModifier) validateRegisterEnum(path, location string, value string) error { + if err := validate.EnumCase(path, location, value, cpuidRegisterModifierTypeRegisterPropEnum, true); err != nil { + return err + } + return nil +} + +func (m *CpuidRegisterModifier) validateRegister(formats strfmt.Registry) error { + + if err := validate.Required("register", "body", m.Register); err != nil { + return err + } + + // value enum + if err := m.validateRegisterEnum("register", "body", *m.Register); err != nil { + return err + } + + return nil +} + +// ContextValidate validates this cpuid register modifier based on context it is used +func (m *CpuidRegisterModifier) ContextValidate(ctx context.Context, formats strfmt.Registry) error { + return nil +} + +// MarshalBinary interface implementation +func (m *CpuidRegisterModifier) MarshalBinary() ([]byte, error) { + if m == nil { + return nil, nil + } + return swag.WriteJSON(m) +} + +// UnmarshalBinary interface implementation +func (m *CpuidRegisterModifier) UnmarshalBinary(b []byte) error { + var res CpuidRegisterModifier + if err := swag.ReadJSON(b, &res); err != nil { + return err + } + *m = res + return nil +} diff --git a/packages/shared/pkg/fc/models/full_vm_configuration.go b/packages/shared/pkg/fc/models/full_vm_configuration.go index 89131f61ed..b53f74760e 100644 --- a/packages/shared/pkg/fc/models/full_vm_configuration.go +++ b/packages/shared/pkg/fc/models/full_vm_configuration.go @@ -38,6 +38,9 @@ type FullVMConfiguration struct { // machine config MachineConfig *MachineConfiguration `json:"machine-config,omitempty"` + // memory hotplug + MemoryHotplug *MemoryHotplugConfig `json:"memory-hotplug,omitempty"` + // metrics Metrics *Metrics `json:"metrics,omitempty"` @@ -47,6 +50,9 @@ type FullVMConfiguration struct { // Configurations for all net devices. NetworkInterfaces []*NetworkInterface `json:"network-interfaces"` + // Configurations for all pmem devices. + Pmem []*Pmem `json:"pmem"` + // vsock Vsock *Vsock `json:"vsock,omitempty"` } @@ -83,6 +89,10 @@ func (m *FullVMConfiguration) Validate(formats strfmt.Registry) error { res = append(res, err) } + if err := m.validateMemoryHotplug(formats); err != nil { + res = append(res, err) + } + if err := m.validateMetrics(formats); err != nil { res = append(res, err) } @@ -95,6 +105,10 @@ func (m *FullVMConfiguration) Validate(formats strfmt.Registry) error { res = append(res, err) } + if err := m.validatePmem(formats); err != nil { + res = append(res, err) + } + if err := m.validateVsock(formats); err != nil { res = append(res, err) } @@ -273,6 +287,29 @@ func (m *FullVMConfiguration) validateMachineConfig(formats strfmt.Registry) err return nil } +func (m *FullVMConfiguration) validateMemoryHotplug(formats strfmt.Registry) error { + if swag.IsZero(m.MemoryHotplug) { // not required + return nil + } + + if m.MemoryHotplug != nil { + if err := m.MemoryHotplug.Validate(formats); err != nil { + ve := new(errors.Validation) + if stderrors.As(err, &ve) { + return ve.ValidateName("memory-hotplug") + } + ce := new(errors.CompositeError) + if stderrors.As(err, &ce) { + return ce.ValidateName("memory-hotplug") + } + + return err + } + } + + return nil +} + func (m *FullVMConfiguration) validateMetrics(formats strfmt.Registry) error { if swag.IsZero(m.Metrics) { // not required return nil @@ -349,6 +386,36 @@ func (m *FullVMConfiguration) validateNetworkInterfaces(formats strfmt.Registry) return nil } +func (m *FullVMConfiguration) validatePmem(formats strfmt.Registry) error { + if swag.IsZero(m.Pmem) { // not required + return nil + } + + for i := 0; i < len(m.Pmem); i++ { + if swag.IsZero(m.Pmem[i]) { // not required + continue + } + + if m.Pmem[i] != nil { + if err := m.Pmem[i].Validate(formats); err != nil { + ve := new(errors.Validation) + if stderrors.As(err, &ve) { + return ve.ValidateName("pmem" + "." + strconv.Itoa(i)) + } + ce := new(errors.CompositeError) + if stderrors.As(err, &ce) { + return ce.ValidateName("pmem" + "." + strconv.Itoa(i)) + } + + return err + } + } + + } + + return nil +} + func (m *FullVMConfiguration) validateVsock(formats strfmt.Registry) error { if swag.IsZero(m.Vsock) { // not required return nil @@ -404,6 +471,10 @@ func (m *FullVMConfiguration) ContextValidate(ctx context.Context, formats strfm res = append(res, err) } + if err := m.contextValidateMemoryHotplug(ctx, formats); err != nil { + res = append(res, err) + } + if err := m.contextValidateMetrics(ctx, formats); err != nil { res = append(res, err) } @@ -416,6 +487,10 @@ func (m *FullVMConfiguration) ContextValidate(ctx context.Context, formats strfm res = append(res, err) } + if err := m.contextValidatePmem(ctx, formats); err != nil { + res = append(res, err) + } + if err := m.contextValidateVsock(ctx, formats); err != nil { res = append(res, err) } @@ -605,6 +680,31 @@ func (m *FullVMConfiguration) contextValidateMachineConfig(ctx context.Context, return nil } +func (m *FullVMConfiguration) contextValidateMemoryHotplug(ctx context.Context, formats strfmt.Registry) error { + + if m.MemoryHotplug != nil { + + if swag.IsZero(m.MemoryHotplug) { // not required + return nil + } + + if err := m.MemoryHotplug.ContextValidate(ctx, formats); err != nil { + ve := new(errors.Validation) + if stderrors.As(err, &ve) { + return ve.ValidateName("memory-hotplug") + } + ce := new(errors.CompositeError) + if stderrors.As(err, &ce) { + return ce.ValidateName("memory-hotplug") + } + + return err + } + } + + return nil +} + func (m *FullVMConfiguration) contextValidateMetrics(ctx context.Context, formats strfmt.Registry) error { if m.Metrics != nil { @@ -684,6 +784,35 @@ func (m *FullVMConfiguration) contextValidateNetworkInterfaces(ctx context.Conte return nil } +func (m *FullVMConfiguration) contextValidatePmem(ctx context.Context, formats strfmt.Registry) error { + + for i := 0; i < len(m.Pmem); i++ { + + if m.Pmem[i] != nil { + + if swag.IsZero(m.Pmem[i]) { // not required + return nil + } + + if err := m.Pmem[i].ContextValidate(ctx, formats); err != nil { + ve := new(errors.Validation) + if stderrors.As(err, &ve) { + return ve.ValidateName("pmem" + "." + strconv.Itoa(i)) + } + ce := new(errors.CompositeError) + if stderrors.As(err, &ce) { + return ce.ValidateName("pmem" + "." + strconv.Itoa(i)) + } + + return err + } + } + + } + + return nil +} + func (m *FullVMConfiguration) contextValidateVsock(ctx context.Context, formats strfmt.Registry) error { if m.Vsock != nil { diff --git a/packages/shared/pkg/fc/models/memory_hotplug_config.go b/packages/shared/pkg/fc/models/memory_hotplug_config.go new file mode 100644 index 0000000000..adbbcd1605 --- /dev/null +++ b/packages/shared/pkg/fc/models/memory_hotplug_config.go @@ -0,0 +1,94 @@ +// Code generated by go-swagger; DO NOT EDIT. + +package models + +import ( + "context" + + "github.com/go-openapi/errors" + "github.com/go-openapi/strfmt" + "github.com/go-openapi/swag" + "github.com/go-openapi/validate" +) + +// MemoryHotplugConfig The configuration of the hotpluggable memory device (virtio-mem) +// +// swagger:model MemoryHotplugConfig +type MemoryHotplugConfig struct { + + // (Logical) Block size for the hotpluggable memory in MiB. This will determine the logical granularity of hot-plug memory for the guest. Refer to the device documentation on how to tune this value. + // Minimum: 2 + BlockSizeMib int64 `json:"block_size_mib,omitempty"` + + // Slot size for the hotpluggable memory in MiB. This will determine the granularity of hot-plug memory from the host. Refer to the device documentation on how to tune this value. + // Minimum: 128 + SlotSizeMib int64 `json:"slot_size_mib,omitempty"` + + // Total size of the hotpluggable memory in MiB. + TotalSizeMib int64 `json:"total_size_mib,omitempty"` +} + +// Validate validates this memory hotplug config +func (m *MemoryHotplugConfig) Validate(formats strfmt.Registry) error { + var res []error + + if err := m.validateBlockSizeMib(formats); err != nil { + res = append(res, err) + } + + if err := m.validateSlotSizeMib(formats); err != nil { + res = append(res, err) + } + + if len(res) > 0 { + return errors.CompositeValidationError(res...) + } + return nil +} + +func (m *MemoryHotplugConfig) validateBlockSizeMib(formats strfmt.Registry) error { + if swag.IsZero(m.BlockSizeMib) { // not required + return nil + } + + if err := validate.MinimumInt("block_size_mib", "body", m.BlockSizeMib, 2, false); err != nil { + return err + } + + return nil +} + +func (m *MemoryHotplugConfig) validateSlotSizeMib(formats strfmt.Registry) error { + if swag.IsZero(m.SlotSizeMib) { // not required + return nil + } + + if err := validate.MinimumInt("slot_size_mib", "body", m.SlotSizeMib, 128, false); err != nil { + return err + } + + return nil +} + +// ContextValidate validates this memory hotplug config based on context it is used +func (m *MemoryHotplugConfig) ContextValidate(ctx context.Context, formats strfmt.Registry) error { + return nil +} + +// MarshalBinary interface implementation +func (m *MemoryHotplugConfig) MarshalBinary() ([]byte, error) { + if m == nil { + return nil, nil + } + return swag.WriteJSON(m) +} + +// UnmarshalBinary interface implementation +func (m *MemoryHotplugConfig) UnmarshalBinary(b []byte) error { + var res MemoryHotplugConfig + if err := swag.ReadJSON(b, &res); err != nil { + return err + } + *m = res + return nil +} diff --git a/packages/shared/pkg/fc/models/memory_hotplug_size_update.go b/packages/shared/pkg/fc/models/memory_hotplug_size_update.go new file mode 100644 index 0000000000..c071f79dd0 --- /dev/null +++ b/packages/shared/pkg/fc/models/memory_hotplug_size_update.go @@ -0,0 +1,47 @@ +// Code generated by go-swagger; DO NOT EDIT. + +package models + +import ( + "context" + + "github.com/go-openapi/strfmt" + "github.com/go-openapi/swag" +) + +// MemoryHotplugSizeUpdate An update to the size of the hotpluggable memory region. +// +// swagger:model MemoryHotplugSizeUpdate +type MemoryHotplugSizeUpdate struct { + + // New target region size. + RequestedSizeMib int64 `json:"requested_size_mib,omitempty"` +} + +// Validate validates this memory hotplug size update +func (m *MemoryHotplugSizeUpdate) Validate(formats strfmt.Registry) error { + return nil +} + +// ContextValidate validates this memory hotplug size update based on context it is used +func (m *MemoryHotplugSizeUpdate) ContextValidate(ctx context.Context, formats strfmt.Registry) error { + return nil +} + +// MarshalBinary interface implementation +func (m *MemoryHotplugSizeUpdate) MarshalBinary() ([]byte, error) { + if m == nil { + return nil, nil + } + return swag.WriteJSON(m) +} + +// UnmarshalBinary interface implementation +func (m *MemoryHotplugSizeUpdate) UnmarshalBinary(b []byte) error { + var res MemoryHotplugSizeUpdate + if err := swag.ReadJSON(b, &res); err != nil { + return err + } + *m = res + return nil +} diff --git a/packages/shared/pkg/fc/models/memory_hotplug_status.go b/packages/shared/pkg/fc/models/memory_hotplug_status.go new file mode 100644 index 0000000000..795817bf1e --- /dev/null +++ b/packages/shared/pkg/fc/models/memory_hotplug_status.go @@ -0,0 +1,59 @@ +// Code generated by go-swagger; DO NOT EDIT. + +package models + +import ( + "context" + + "github.com/go-openapi/strfmt" + "github.com/go-openapi/swag" +) + +// MemoryHotplugStatus The status of the hotpluggable memory device (virtio-mem) +// +// swagger:model MemoryHotplugStatus +type MemoryHotplugStatus struct { + + // (Logical) Block size for the hotpluggable memory in MiB. + BlockSizeMib int64 `json:"block_size_mib,omitempty"` + + // Plugged size for the hotpluggable memory in MiB. + PluggedSizeMib int64 `json:"plugged_size_mib,omitempty"` + + // Requested size for the hotpluggable memory in MiB. + RequestedSizeMib int64 `json:"requested_size_mib,omitempty"` + + // Slot size for the hotpluggable memory in MiB. + SlotSizeMib int64 `json:"slot_size_mib,omitempty"` + + // Total size of the hotpluggable memory in MiB. + TotalSizeMib int64 `json:"total_size_mib,omitempty"` +} + +// Validate validates this memory hotplug status +func (m *MemoryHotplugStatus) Validate(formats strfmt.Registry) error { + return nil +} + +// ContextValidate validates this memory hotplug status based on context it is used +func (m *MemoryHotplugStatus) ContextValidate(ctx context.Context, formats strfmt.Registry) error { + return nil +} + +// MarshalBinary interface implementation +func (m *MemoryHotplugStatus) MarshalBinary() ([]byte, error) { + if m == nil { + return nil, nil + } + return swag.WriteJSON(m) +} + +// UnmarshalBinary interface implementation +func (m *MemoryHotplugStatus) UnmarshalBinary(b []byte) error { + var res MemoryHotplugStatus + if err := swag.ReadJSON(b, &res); err != nil { + return err + } + *m = res + return nil +} diff --git a/packages/shared/pkg/fc/models/mmds_config.go b/packages/shared/pkg/fc/models/mmds_config.go index 718e73be09..b42fdc644f 100644 --- a/packages/shared/pkg/fc/models/mmds_config.go +++ b/packages/shared/pkg/fc/models/mmds_config.go @@ -17,6 +17,9 @@ import ( // swagger:model MmdsConfig type MmdsConfig struct { + // MMDS operates compatibly with EC2 IMDS (i.e. responds "text/plain" content regardless of Accept header in requests). + ImdsCompat *bool `json:"imds_compat,omitempty"` + // A valid IPv4 link-local address. IPv4Address *string `json:"ipv4_address,omitempty"` diff --git a/packages/shared/pkg/fc/models/msr_modifier.go b/packages/shared/pkg/fc/models/msr_modifier.go new file mode 100644 index 0000000000..120964ea9e --- /dev/null +++ b/packages/shared/pkg/fc/models/msr_modifier.go @@ -0,0 +1,85 @@ +// Code generated by go-swagger; DO NOT EDIT. + +package models + +import ( + "context" + + "github.com/go-openapi/errors" + "github.com/go-openapi/strfmt" + "github.com/go-openapi/swag" + "github.com/go-openapi/validate" +) + +// MsrModifier Modifier for a model specific register (x86_64) +// +// swagger:model MsrModifier +type MsrModifier struct { + + // 32-bit MSR address as hex, binary, or decimal string (e.g., "0x10a", "0b100001010", "266") + // Required: true + Addr *string `json:"addr"` + + // 64-bit bitmap string defining which bits to modify. Format is "0b" followed by 64 characters where '0' = clear bit, '1' = set bit, 'x' = don't modify. Underscores can be used for readability. Example "0b0000000000000000000000000000000000000000000000000000000000000001" + // Required: true + Bitmap *string `json:"bitmap"` +} + +// Validate validates this msr modifier +func (m *MsrModifier) Validate(formats strfmt.Registry) error { + var res []error + + if err := m.validateAddr(formats); err != nil { + res = append(res, err) + } + + if err := m.validateBitmap(formats); err != nil { + res = append(res, err) + } + + if len(res) > 0 { + return errors.CompositeValidationError(res...) + } + return nil +} + +func (m *MsrModifier) validateAddr(formats strfmt.Registry) error { + + if err := validate.Required("addr", "body", m.Addr); err != nil { + return err + } + + return nil +} + +func (m *MsrModifier) validateBitmap(formats strfmt.Registry) error { + + if err := validate.Required("bitmap", "body", m.Bitmap); err != nil { + return err + } + + return nil +} + +// ContextValidate validates this msr modifier based on context it is used +func (m *MsrModifier) ContextValidate(ctx context.Context, formats strfmt.Registry) error { + return nil +} + +// MarshalBinary interface implementation +func (m *MsrModifier) MarshalBinary() ([]byte, error) { + if m == nil { + return nil, nil + } + return swag.WriteJSON(m) +} + +// UnmarshalBinary interface implementation +func (m *MsrModifier) UnmarshalBinary(b []byte) error { + var res MsrModifier + if err := swag.ReadJSON(b, &res); err != nil { + return err + } + *m = res + return nil +} diff --git a/packages/shared/pkg/fc/models/pmem.go b/packages/shared/pkg/fc/models/pmem.go new file mode 100644 index 0000000000..aad5d79d21 --- /dev/null +++ b/packages/shared/pkg/fc/models/pmem.go @@ -0,0 +1,91 @@ +// Code generated by go-swagger; DO NOT EDIT. + +package models + +import ( + "context" + + "github.com/go-openapi/errors" + "github.com/go-openapi/strfmt" + "github.com/go-openapi/swag" + "github.com/go-openapi/validate" +) + +// Pmem pmem +// +// swagger:model Pmem +type Pmem struct { + + // Identificator for this device. + // Required: true + ID *string `json:"id"` + + // Host level path for the virtio-pmem device to use as a backing file. + // Required: true + PathOnHost *string `json:"path_on_host"` + + // Flag to map backing file in read-only mode. + ReadOnly bool `json:"read_only,omitempty"` + + // Flag to make this device be the root device for VM boot. Setting this flag will fail if there is another device configured to be a root device already. + RootDevice bool `json:"root_device,omitempty"` +} + +// Validate validates this pmem +func (m *Pmem) Validate(formats strfmt.Registry) error { + var res []error + + if err := m.validateID(formats); err != nil { + res = append(res, err) + } + + if err := m.validatePathOnHost(formats); err != nil { + res = append(res, err) + } + + if len(res) > 0 { + return errors.CompositeValidationError(res...) + } + return nil +} + +func (m *Pmem) validateID(formats strfmt.Registry) error { + + if err := validate.Required("id", "body", m.ID); err != nil { + return err + } + + return nil +} + +func (m *Pmem) validatePathOnHost(formats strfmt.Registry) error { + + if err := validate.Required("path_on_host", "body", m.PathOnHost); err != nil { + return err + } + + return nil +} + +// ContextValidate validates this pmem based on context it is used +func (m *Pmem) ContextValidate(ctx context.Context, formats strfmt.Registry) error { + return nil +} + +// MarshalBinary interface implementation +func (m *Pmem) MarshalBinary() ([]byte, error) { + if m == nil { + return nil, nil + } + return swag.WriteJSON(m) +} + +// UnmarshalBinary interface implementation +func (m *Pmem) UnmarshalBinary(b []byte) error { + var res Pmem + if err := swag.ReadJSON(b, &res); err != nil { + return err + } + *m = res + return nil +} diff --git a/packages/shared/pkg/fc/models/serial_device.go b/packages/shared/pkg/fc/models/serial_device.go new file mode 100644 index 0000000000..dde495fc1f --- /dev/null +++ b/packages/shared/pkg/fc/models/serial_device.go @@ -0,0 +1,47 @@ +// Code generated by go-swagger; DO NOT EDIT. + +package models + +import ( + "context" + + "github.com/go-openapi/strfmt" + "github.com/go-openapi/swag" +) + +// SerialDevice The configuration of the serial device +// +// swagger:model SerialDevice +type SerialDevice struct { + + // Path to a file or named pipe on the host to which serial output should be written. + SerialOutPath string `json:"serial_out_path,omitempty"` +} + +// Validate validates this serial device +func (m *SerialDevice) Validate(formats strfmt.Registry) error { + return nil +} + +// ContextValidate validates this serial device based on context it is used +func (m *SerialDevice) ContextValidate(ctx context.Context, formats strfmt.Registry) error { + return nil +} + +// MarshalBinary interface implementation +func (m *SerialDevice) MarshalBinary() ([]byte, error) { + if m == nil { + return nil, nil + } + return swag.WriteJSON(m) +} + +// UnmarshalBinary interface implementation +func (m *SerialDevice) UnmarshalBinary(b []byte) error { + var res SerialDevice + if err := swag.ReadJSON(b, &res); err != nil { + return err + } + *m = res + return nil +} diff --git a/packages/shared/pkg/fc/models/snapshot_create_params.go b/packages/shared/pkg/fc/models/snapshot_create_params.go index b839c19252..45e435d01b 100644 --- a/packages/shared/pkg/fc/models/snapshot_create_params.go +++ b/packages/shared/pkg/fc/models/snapshot_create_params.go @@ -17,7 +17,7 @@ import ( // swagger:model SnapshotCreateParams type SnapshotCreateParams struct { - // Path to the file that will contain the guest memory. + // Path to the file that will contain the guest memory. It is optional. In case that a user doesn't provide a path, they are responsible to ensure they store the microVM's memory state via external means. MemFilePath string `json:"mem_file_path,omitempty"` // Path to the file that will contain the microVM state. diff --git a/packages/shared/pkg/fc/models/snapshot_load_params.go b/packages/shared/pkg/fc/models/snapshot_load_params.go index 1c313b00e3..a1ae7d90b9 100644 --- a/packages/shared/pkg/fc/models/snapshot_load_params.go +++ b/packages/shared/pkg/fc/models/snapshot_load_params.go @@ -18,7 +18,7 @@ import ( // swagger:model SnapshotLoadParams type SnapshotLoadParams struct { - // Enable support for incremental (diff) snapshots by tracking dirty guest pages. + // (Deprecated) Enable dirty page tracking to improve space efficiency of diff snapshots EnableDiffSnapshots bool `json:"enable_diff_snapshots,omitempty"` // Configuration for the backend that handles memory load. If this field is specified, `mem_file_path` is forbidden. Either `mem_backend` or `mem_file_path` must be present at a time. @@ -36,6 +36,9 @@ type SnapshotLoadParams struct { // Path to the file that contains the microVM state to be loaded. // Required: true SnapshotPath *string `json:"snapshot_path"` + + // Enable dirty page tracking to improve space efficiency of diff snapshots + TrackDirtyPages bool `json:"track_dirty_pages,omitempty"` } // Validate validates this snapshot load params diff --git a/packages/shared/pkg/fc/models/vcpu_features.go b/packages/shared/pkg/fc/models/vcpu_features.go new file mode 100644 index 0000000000..dd9f71f81b --- /dev/null +++ b/packages/shared/pkg/fc/models/vcpu_features.go @@ -0,0 +1,85 @@ +// Code generated by go-swagger; DO NOT EDIT. + +package models + +import ( + "context" + + "github.com/go-openapi/errors" + "github.com/go-openapi/strfmt" + "github.com/go-openapi/swag" + "github.com/go-openapi/validate" +) + +// VcpuFeatures vCPU feature modifier (aarch64) +// +// swagger:model VcpuFeatures +type VcpuFeatures struct { + + // 32-bit bitmap string defining which bits to modify. Format is "0b" followed by 32 characters where '0' = clear bit, '1' = set bit, 'x' = don't modify. Example "0b00000000000000000000000001100000" + // Required: true + Bitmap *string `json:"bitmap"` + + // Index in the kvm_vcpu_init.features array + // Required: true + Index *int32 `json:"index"` +} + +// Validate validates this vcpu features +func (m *VcpuFeatures) Validate(formats strfmt.Registry) error { + var res []error + + if err := m.validateBitmap(formats); err != nil { + res = append(res, err) + } + + if err := m.validateIndex(formats); err != nil { + res = append(res, err) + } + + if len(res) > 0 { + return errors.CompositeValidationError(res...) + } + return nil +} + +func (m *VcpuFeatures) validateBitmap(formats strfmt.Registry) error { + + if err := validate.Required("bitmap", "body", m.Bitmap); err != nil { + return err + } + + return nil +} + +func (m *VcpuFeatures) validateIndex(formats strfmt.Registry) error { + + if err := validate.Required("index", "body", m.Index); err != nil { + return err + } + + return nil +} + +// ContextValidate validates this vcpu features based on context it is used +func (m *VcpuFeatures) ContextValidate(ctx context.Context, formats strfmt.Registry) error { + return nil +} + +// MarshalBinary interface implementation +func (m *VcpuFeatures) MarshalBinary() ([]byte, error) { + if m == nil { + return nil, nil + } + return swag.WriteJSON(m) +} + +// UnmarshalBinary interface implementation +func (m *VcpuFeatures) UnmarshalBinary(b []byte) error { + var res VcpuFeatures + if err := swag.ReadJSON(b, &res); err != nil { + return err + } + *m = res + return nil +} diff --git a/packages/shared/pkg/feature-flags/flags.go b/packages/shared/pkg/feature-flags/flags.go index 7e65aa8a0a..646f8e3d9c 100644 --- a/packages/shared/pkg/feature-flags/flags.go +++ b/packages/shared/pkg/feature-flags/flags.go @@ -208,12 +208,14 @@ const ( const ( DefaultFirecackerV1_10Version = "v1.10.1_30cbb07" DefaultFirecackerV1_12Version = "v1.12.1_a41d3fb" - DefaultFirecrackerVersion = DefaultFirecackerV1_12Version + DefaultFirecackerV1_14Version = "v1.14.1_aa14c57" + DefaultFirecrackerVersion = DefaultFirecackerV1_14Version ) var FirecrackerVersionMap = map[string]string{ "v1.10": DefaultFirecackerV1_10Version, "v1.12": DefaultFirecackerV1_12Version, + "v1.14": DefaultFirecackerV1_14Version, } // BuildIoEngine Sync is used by default as there seems to be a bad interaction between Async and a lot of io operations. diff --git a/packages/shared/pkg/grpc/template-manager/template-manager.pb.go b/packages/shared/pkg/grpc/template-manager/template-manager.pb.go index ebc032f7dc..3c3fe06023 100644 --- a/packages/shared/pkg/grpc/template-manager/template-manager.pb.go +++ b/packages/shared/pkg/grpc/template-manager/template-manager.pb.go @@ -699,6 +699,7 @@ type TemplateConfig struct { Source isTemplateConfig_Source `protobuf_oneof:"source"` FromImageRegistry *FromImageRegistry `protobuf:"bytes,15,opt,name=fromImageRegistry,proto3,oneof" json:"fromImageRegistry,omitempty"` TeamID string `protobuf:"bytes,16,opt,name=teamID,proto3" json:"teamID,omitempty"` + FreePageReporting *bool `protobuf:"varint,17,opt,name=freePageReporting,proto3,oneof" json:"freePageReporting,omitempty"` } func (x *TemplateConfig) Reset() { @@ -852,6 +853,13 @@ func (x *TemplateConfig) GetTeamID() string { return "" } +func (x *TemplateConfig) GetFreePageReporting() bool { + if x != nil && x.FreePageReporting != nil { + return *x.FreePageReporting + } + return false +} + type isTemplateConfig_Source interface { isTemplateConfig_Source() } @@ -1404,7 +1412,7 @@ var file_template_manager_proto_rawDesc = []byte{ 0x03, 0x67, 0x63, 0x70, 0x12, 0x2c, 0x0a, 0x07, 0x67, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x6c, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x10, 0x2e, 0x47, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x6c, 0x52, 0x65, 0x67, 0x69, 0x73, 0x74, 0x72, 0x79, 0x48, 0x00, 0x52, 0x07, 0x67, 0x65, 0x6e, 0x65, 0x72, - 0x61, 0x6c, 0x42, 0x06, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x22, 0x84, 0x05, 0x0a, 0x0e, 0x54, + 0x61, 0x6c, 0x42, 0x06, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x22, 0xcd, 0x05, 0x0a, 0x0e, 0x54, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x1e, 0x0a, 0x0a, 0x74, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, 0x49, 0x44, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x74, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, 0x49, 0x44, 0x12, 0x18, 0x0a, @@ -1442,129 +1450,134 @@ var file_template_manager_proto_rawDesc = []byte{ 0x65, 0x67, 0x69, 0x73, 0x74, 0x72, 0x79, 0x48, 0x02, 0x52, 0x11, 0x66, 0x72, 0x6f, 0x6d, 0x49, 0x6d, 0x61, 0x67, 0x65, 0x52, 0x65, 0x67, 0x69, 0x73, 0x74, 0x72, 0x79, 0x88, 0x01, 0x01, 0x12, 0x16, 0x0a, 0x06, 0x74, 0x65, 0x61, 0x6d, 0x49, 0x44, 0x18, 0x10, 0x20, 0x01, 0x28, 0x09, 0x52, - 0x06, 0x74, 0x65, 0x61, 0x6d, 0x49, 0x44, 0x42, 0x08, 0x0a, 0x06, 0x73, 0x6f, 0x75, 0x72, 0x63, - 0x65, 0x42, 0x08, 0x0a, 0x06, 0x5f, 0x66, 0x6f, 0x72, 0x63, 0x65, 0x42, 0x14, 0x0a, 0x12, 0x5f, - 0x66, 0x72, 0x6f, 0x6d, 0x49, 0x6d, 0x61, 0x67, 0x65, 0x52, 0x65, 0x67, 0x69, 0x73, 0x74, 0x72, - 0x79, 0x22, 0xa3, 0x01, 0x0a, 0x15, 0x54, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, 0x43, 0x72, - 0x65, 0x61, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x2b, 0x0a, 0x08, 0x74, - 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0f, 0x2e, - 0x54, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x08, - 0x74, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, 0x12, 0x23, 0x0a, 0x0a, 0x63, 0x61, 0x63, 0x68, - 0x65, 0x53, 0x63, 0x6f, 0x70, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x48, 0x00, 0x52, 0x0a, - 0x63, 0x61, 0x63, 0x68, 0x65, 0x53, 0x63, 0x6f, 0x70, 0x65, 0x88, 0x01, 0x01, 0x12, 0x1d, 0x0a, - 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x48, 0x01, - 0x52, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x88, 0x01, 0x01, 0x42, 0x0d, 0x0a, 0x0b, - 0x5f, 0x63, 0x61, 0x63, 0x68, 0x65, 0x53, 0x63, 0x6f, 0x70, 0x65, 0x42, 0x0a, 0x0a, 0x08, 0x5f, - 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x22, 0x8b, 0x03, 0x0a, 0x15, 0x54, 0x65, 0x6d, 0x70, - 0x6c, 0x61, 0x74, 0x65, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, - 0x74, 0x12, 0x1e, 0x0a, 0x0a, 0x74, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, 0x49, 0x44, 0x18, - 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x74, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, 0x49, - 0x44, 0x12, 0x18, 0x0a, 0x07, 0x62, 0x75, 0x69, 0x6c, 0x64, 0x49, 0x44, 0x18, 0x02, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x07, 0x62, 0x75, 0x69, 0x6c, 0x64, 0x49, 0x44, 0x12, 0x1b, 0x0a, 0x06, 0x6f, - 0x66, 0x66, 0x73, 0x65, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x05, 0x48, 0x00, 0x52, 0x06, 0x6f, - 0x66, 0x66, 0x73, 0x65, 0x74, 0x88, 0x01, 0x01, 0x12, 0x24, 0x0a, 0x05, 0x6c, 0x65, 0x76, 0x65, - 0x6c, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x09, 0x2e, 0x4c, 0x6f, 0x67, 0x4c, 0x65, 0x76, - 0x65, 0x6c, 0x48, 0x01, 0x52, 0x05, 0x6c, 0x65, 0x76, 0x65, 0x6c, 0x88, 0x01, 0x01, 0x12, 0x19, - 0x0a, 0x05, 0x6c, 0x69, 0x6d, 0x69, 0x74, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0d, 0x48, 0x02, 0x52, - 0x05, 0x6c, 0x69, 0x6d, 0x69, 0x74, 0x88, 0x01, 0x01, 0x12, 0x35, 0x0a, 0x05, 0x73, 0x74, 0x61, - 0x72, 0x74, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, - 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, - 0x74, 0x61, 0x6d, 0x70, 0x48, 0x03, 0x52, 0x05, 0x73, 0x74, 0x61, 0x72, 0x74, 0x88, 0x01, 0x01, - 0x12, 0x31, 0x0a, 0x03, 0x65, 0x6e, 0x64, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, - 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, - 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x48, 0x04, 0x52, 0x03, 0x65, 0x6e, 0x64, - 0x88, 0x01, 0x01, 0x12, 0x31, 0x0a, 0x09, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, - 0x18, 0x08, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x0e, 0x2e, 0x4c, 0x6f, 0x67, 0x73, 0x44, 0x69, 0x72, - 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x48, 0x05, 0x52, 0x09, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, - 0x69, 0x6f, 0x6e, 0x88, 0x01, 0x01, 0x42, 0x09, 0x0a, 0x07, 0x5f, 0x6f, 0x66, 0x66, 0x73, 0x65, - 0x74, 0x42, 0x08, 0x0a, 0x06, 0x5f, 0x6c, 0x65, 0x76, 0x65, 0x6c, 0x42, 0x08, 0x0a, 0x06, 0x5f, - 0x6c, 0x69, 0x6d, 0x69, 0x74, 0x42, 0x08, 0x0a, 0x06, 0x5f, 0x73, 0x74, 0x61, 0x72, 0x74, 0x42, - 0x06, 0x0a, 0x04, 0x5f, 0x65, 0x6e, 0x64, 0x42, 0x0c, 0x0a, 0x0a, 0x5f, 0x64, 0x69, 0x72, 0x65, - 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x22, 0x56, 0x0a, 0x1a, 0x54, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, - 0x65, 0x42, 0x75, 0x69, 0x6c, 0x64, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, - 0x65, 0x73, 0x74, 0x12, 0x18, 0x0a, 0x07, 0x62, 0x75, 0x69, 0x6c, 0x64, 0x49, 0x44, 0x18, 0x01, - 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x62, 0x75, 0x69, 0x6c, 0x64, 0x49, 0x44, 0x12, 0x1e, 0x0a, - 0x0a, 0x74, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, 0x49, 0x44, 0x18, 0x02, 0x20, 0x01, 0x28, - 0x09, 0x52, 0x0a, 0x74, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, 0x49, 0x44, 0x22, 0x65, 0x0a, - 0x15, 0x54, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, 0x42, 0x75, 0x69, 0x6c, 0x64, 0x4d, 0x65, - 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x12, 0x24, 0x0a, 0x0d, 0x72, 0x6f, 0x6f, 0x74, 0x66, 0x73, - 0x53, 0x69, 0x7a, 0x65, 0x4b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0d, 0x72, - 0x6f, 0x6f, 0x74, 0x66, 0x73, 0x53, 0x69, 0x7a, 0x65, 0x4b, 0x65, 0x79, 0x12, 0x26, 0x0a, 0x0e, - 0x65, 0x6e, 0x76, 0x64, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x4b, 0x65, 0x79, 0x18, 0x02, - 0x20, 0x01, 0x28, 0x09, 0x52, 0x0e, 0x65, 0x6e, 0x76, 0x64, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, - 0x6e, 0x4b, 0x65, 0x79, 0x22, 0x83, 0x02, 0x0a, 0x15, 0x54, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, - 0x65, 0x42, 0x75, 0x69, 0x6c, 0x64, 0x4c, 0x6f, 0x67, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x38, - 0x0a, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x06, 0x74, 0x65, 0x61, 0x6d, 0x49, 0x44, 0x12, 0x31, 0x0a, 0x11, 0x66, 0x72, 0x65, 0x65, 0x50, + 0x61, 0x67, 0x65, 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x69, 0x6e, 0x67, 0x18, 0x11, 0x20, 0x01, + 0x28, 0x08, 0x48, 0x03, 0x52, 0x11, 0x66, 0x72, 0x65, 0x65, 0x50, 0x61, 0x67, 0x65, 0x52, 0x65, + 0x70, 0x6f, 0x72, 0x74, 0x69, 0x6e, 0x67, 0x88, 0x01, 0x01, 0x42, 0x08, 0x0a, 0x06, 0x73, 0x6f, + 0x75, 0x72, 0x63, 0x65, 0x42, 0x08, 0x0a, 0x06, 0x5f, 0x66, 0x6f, 0x72, 0x63, 0x65, 0x42, 0x14, + 0x0a, 0x12, 0x5f, 0x66, 0x72, 0x6f, 0x6d, 0x49, 0x6d, 0x61, 0x67, 0x65, 0x52, 0x65, 0x67, 0x69, + 0x73, 0x74, 0x72, 0x79, 0x42, 0x14, 0x0a, 0x12, 0x5f, 0x66, 0x72, 0x65, 0x65, 0x50, 0x61, 0x67, + 0x65, 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x69, 0x6e, 0x67, 0x22, 0xa3, 0x01, 0x0a, 0x15, 0x54, + 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x52, 0x65, 0x71, + 0x75, 0x65, 0x73, 0x74, 0x12, 0x2b, 0x0a, 0x08, 0x74, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, + 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0f, 0x2e, 0x54, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, + 0x65, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x08, 0x74, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, + 0x65, 0x12, 0x23, 0x0a, 0x0a, 0x63, 0x61, 0x63, 0x68, 0x65, 0x53, 0x63, 0x6f, 0x70, 0x65, 0x18, + 0x02, 0x20, 0x01, 0x28, 0x09, 0x48, 0x00, 0x52, 0x0a, 0x63, 0x61, 0x63, 0x68, 0x65, 0x53, 0x63, + 0x6f, 0x70, 0x65, 0x88, 0x01, 0x01, 0x12, 0x1d, 0x0a, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, + 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x48, 0x01, 0x52, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, + 0x6f, 0x6e, 0x88, 0x01, 0x01, 0x42, 0x0d, 0x0a, 0x0b, 0x5f, 0x63, 0x61, 0x63, 0x68, 0x65, 0x53, + 0x63, 0x6f, 0x70, 0x65, 0x42, 0x0a, 0x0a, 0x08, 0x5f, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, + 0x22, 0x8b, 0x03, 0x0a, 0x15, 0x54, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, 0x53, 0x74, 0x61, + 0x74, 0x75, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1e, 0x0a, 0x0a, 0x74, 0x65, + 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, 0x49, 0x44, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, + 0x74, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, 0x49, 0x44, 0x12, 0x18, 0x0a, 0x07, 0x62, 0x75, + 0x69, 0x6c, 0x64, 0x49, 0x44, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x62, 0x75, 0x69, + 0x6c, 0x64, 0x49, 0x44, 0x12, 0x1b, 0x0a, 0x06, 0x6f, 0x66, 0x66, 0x73, 0x65, 0x74, 0x18, 0x03, + 0x20, 0x01, 0x28, 0x05, 0x48, 0x00, 0x52, 0x06, 0x6f, 0x66, 0x66, 0x73, 0x65, 0x74, 0x88, 0x01, + 0x01, 0x12, 0x24, 0x0a, 0x05, 0x6c, 0x65, 0x76, 0x65, 0x6c, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0e, + 0x32, 0x09, 0x2e, 0x4c, 0x6f, 0x67, 0x4c, 0x65, 0x76, 0x65, 0x6c, 0x48, 0x01, 0x52, 0x05, 0x6c, + 0x65, 0x76, 0x65, 0x6c, 0x88, 0x01, 0x01, 0x12, 0x19, 0x0a, 0x05, 0x6c, 0x69, 0x6d, 0x69, 0x74, + 0x18, 0x05, 0x20, 0x01, 0x28, 0x0d, 0x48, 0x02, 0x52, 0x05, 0x6c, 0x69, 0x6d, 0x69, 0x74, 0x88, + 0x01, 0x01, 0x12, 0x35, 0x0a, 0x05, 0x73, 0x74, 0x61, 0x72, 0x74, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, - 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x09, 0x74, - 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x12, 0x18, 0x0a, 0x07, 0x6d, 0x65, 0x73, 0x73, - 0x61, 0x67, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, - 0x67, 0x65, 0x12, 0x1f, 0x0a, 0x05, 0x6c, 0x65, 0x76, 0x65, 0x6c, 0x18, 0x03, 0x20, 0x01, 0x28, - 0x0e, 0x32, 0x09, 0x2e, 0x4c, 0x6f, 0x67, 0x4c, 0x65, 0x76, 0x65, 0x6c, 0x52, 0x05, 0x6c, 0x65, - 0x76, 0x65, 0x6c, 0x12, 0x3a, 0x0a, 0x06, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x73, 0x18, 0x04, 0x20, - 0x03, 0x28, 0x0b, 0x32, 0x22, 0x2e, 0x54, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, 0x42, 0x75, - 0x69, 0x6c, 0x64, 0x4c, 0x6f, 0x67, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x2e, 0x46, 0x69, 0x65, 0x6c, - 0x64, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x06, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x73, 0x1a, - 0x39, 0x0a, 0x0b, 0x46, 0x69, 0x65, 0x6c, 0x64, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, - 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, - 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, - 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0x57, 0x0a, 0x19, 0x54, 0x65, - 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, 0x42, 0x75, 0x69, 0x6c, 0x64, 0x53, 0x74, 0x61, 0x74, 0x75, - 0x73, 0x52, 0x65, 0x61, 0x73, 0x6f, 0x6e, 0x12, 0x18, 0x0a, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, - 0x67, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, - 0x65, 0x12, 0x17, 0x0a, 0x04, 0x73, 0x74, 0x65, 0x70, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x48, - 0x00, 0x52, 0x04, 0x73, 0x74, 0x65, 0x70, 0x88, 0x01, 0x01, 0x42, 0x07, 0x0a, 0x05, 0x5f, 0x73, - 0x74, 0x65, 0x70, 0x22, 0x86, 0x02, 0x0a, 0x1b, 0x54, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, - 0x42, 0x75, 0x69, 0x6c, 0x64, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, - 0x6e, 0x73, 0x65, 0x12, 0x2b, 0x0a, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x01, 0x20, - 0x01, 0x28, 0x0e, 0x32, 0x13, 0x2e, 0x54, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, 0x42, 0x75, - 0x69, 0x6c, 0x64, 0x53, 0x74, 0x61, 0x74, 0x65, 0x52, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, - 0x12, 0x32, 0x0a, 0x08, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x18, 0x02, 0x20, 0x01, - 0x28, 0x0b, 0x32, 0x16, 0x2e, 0x54, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, 0x42, 0x75, 0x69, - 0x6c, 0x64, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x52, 0x08, 0x6d, 0x65, 0x74, 0x61, - 0x64, 0x61, 0x74, 0x61, 0x12, 0x36, 0x0a, 0x0a, 0x6c, 0x6f, 0x67, 0x45, 0x6e, 0x74, 0x72, 0x69, - 0x65, 0x73, 0x18, 0x05, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x16, 0x2e, 0x54, 0x65, 0x6d, 0x70, 0x6c, - 0x61, 0x74, 0x65, 0x42, 0x75, 0x69, 0x6c, 0x64, 0x4c, 0x6f, 0x67, 0x45, 0x6e, 0x74, 0x72, 0x79, - 0x52, 0x0a, 0x6c, 0x6f, 0x67, 0x45, 0x6e, 0x74, 0x72, 0x69, 0x65, 0x73, 0x12, 0x37, 0x0a, 0x06, - 0x72, 0x65, 0x61, 0x73, 0x6f, 0x6e, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x54, + 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x48, 0x03, 0x52, + 0x05, 0x73, 0x74, 0x61, 0x72, 0x74, 0x88, 0x01, 0x01, 0x12, 0x31, 0x0a, 0x03, 0x65, 0x6e, 0x64, + 0x18, 0x07, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, + 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, + 0x6d, 0x70, 0x48, 0x04, 0x52, 0x03, 0x65, 0x6e, 0x64, 0x88, 0x01, 0x01, 0x12, 0x31, 0x0a, 0x09, + 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x08, 0x20, 0x01, 0x28, 0x0e, 0x32, + 0x0e, 0x2e, 0x4c, 0x6f, 0x67, 0x73, 0x44, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x48, + 0x05, 0x52, 0x09, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x88, 0x01, 0x01, 0x42, + 0x09, 0x0a, 0x07, 0x5f, 0x6f, 0x66, 0x66, 0x73, 0x65, 0x74, 0x42, 0x08, 0x0a, 0x06, 0x5f, 0x6c, + 0x65, 0x76, 0x65, 0x6c, 0x42, 0x08, 0x0a, 0x06, 0x5f, 0x6c, 0x69, 0x6d, 0x69, 0x74, 0x42, 0x08, + 0x0a, 0x06, 0x5f, 0x73, 0x74, 0x61, 0x72, 0x74, 0x42, 0x06, 0x0a, 0x04, 0x5f, 0x65, 0x6e, 0x64, + 0x42, 0x0c, 0x0a, 0x0a, 0x5f, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x22, 0x56, + 0x0a, 0x1a, 0x54, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, 0x42, 0x75, 0x69, 0x6c, 0x64, 0x44, + 0x65, 0x6c, 0x65, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x18, 0x0a, 0x07, + 0x62, 0x75, 0x69, 0x6c, 0x64, 0x49, 0x44, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x62, + 0x75, 0x69, 0x6c, 0x64, 0x49, 0x44, 0x12, 0x1e, 0x0a, 0x0a, 0x74, 0x65, 0x6d, 0x70, 0x6c, 0x61, + 0x74, 0x65, 0x49, 0x44, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x74, 0x65, 0x6d, 0x70, + 0x6c, 0x61, 0x74, 0x65, 0x49, 0x44, 0x22, 0x65, 0x0a, 0x15, 0x54, 0x65, 0x6d, 0x70, 0x6c, 0x61, + 0x74, 0x65, 0x42, 0x75, 0x69, 0x6c, 0x64, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x12, + 0x24, 0x0a, 0x0d, 0x72, 0x6f, 0x6f, 0x74, 0x66, 0x73, 0x53, 0x69, 0x7a, 0x65, 0x4b, 0x65, 0x79, + 0x18, 0x01, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0d, 0x72, 0x6f, 0x6f, 0x74, 0x66, 0x73, 0x53, 0x69, + 0x7a, 0x65, 0x4b, 0x65, 0x79, 0x12, 0x26, 0x0a, 0x0e, 0x65, 0x6e, 0x76, 0x64, 0x56, 0x65, 0x72, + 0x73, 0x69, 0x6f, 0x6e, 0x4b, 0x65, 0x79, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0e, 0x65, + 0x6e, 0x76, 0x64, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x4b, 0x65, 0x79, 0x22, 0x83, 0x02, + 0x0a, 0x15, 0x54, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, 0x42, 0x75, 0x69, 0x6c, 0x64, 0x4c, + 0x6f, 0x67, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x38, 0x0a, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, + 0x74, 0x61, 0x6d, 0x70, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, + 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, + 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, + 0x70, 0x12, 0x18, 0x0a, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x18, 0x02, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x12, 0x1f, 0x0a, 0x05, 0x6c, + 0x65, 0x76, 0x65, 0x6c, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x09, 0x2e, 0x4c, 0x6f, 0x67, + 0x4c, 0x65, 0x76, 0x65, 0x6c, 0x52, 0x05, 0x6c, 0x65, 0x76, 0x65, 0x6c, 0x12, 0x3a, 0x0a, 0x06, + 0x66, 0x69, 0x65, 0x6c, 0x64, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x22, 0x2e, 0x54, + 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, 0x42, 0x75, 0x69, 0x6c, 0x64, 0x4c, 0x6f, 0x67, 0x45, + 0x6e, 0x74, 0x72, 0x79, 0x2e, 0x46, 0x69, 0x65, 0x6c, 0x64, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, + 0x52, 0x06, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x73, 0x1a, 0x39, 0x0a, 0x0b, 0x46, 0x69, 0x65, 0x6c, + 0x64, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, + 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, + 0x02, 0x38, 0x01, 0x22, 0x57, 0x0a, 0x19, 0x54, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, 0x42, + 0x75, 0x69, 0x6c, 0x64, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x61, 0x73, 0x6f, 0x6e, + 0x12, 0x18, 0x0a, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x12, 0x17, 0x0a, 0x04, 0x73, 0x74, + 0x65, 0x70, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x48, 0x00, 0x52, 0x04, 0x73, 0x74, 0x65, 0x70, + 0x88, 0x01, 0x01, 0x42, 0x07, 0x0a, 0x05, 0x5f, 0x73, 0x74, 0x65, 0x70, 0x22, 0x86, 0x02, 0x0a, + 0x1b, 0x54, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, 0x42, 0x75, 0x69, 0x6c, 0x64, 0x53, 0x74, + 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x2b, 0x0a, 0x06, + 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x13, 0x2e, 0x54, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, 0x42, 0x75, 0x69, 0x6c, 0x64, 0x53, 0x74, 0x61, 0x74, - 0x75, 0x73, 0x52, 0x65, 0x61, 0x73, 0x6f, 0x6e, 0x48, 0x00, 0x52, 0x06, 0x72, 0x65, 0x61, 0x73, - 0x6f, 0x6e, 0x88, 0x01, 0x01, 0x42, 0x09, 0x0a, 0x07, 0x5f, 0x72, 0x65, 0x61, 0x73, 0x6f, 0x6e, - 0x4a, 0x04, 0x08, 0x03, 0x10, 0x04, 0x4a, 0x04, 0x08, 0x04, 0x10, 0x05, 0x2a, 0x34, 0x0a, 0x08, - 0x4c, 0x6f, 0x67, 0x4c, 0x65, 0x76, 0x65, 0x6c, 0x12, 0x09, 0x0a, 0x05, 0x44, 0x65, 0x62, 0x75, - 0x67, 0x10, 0x00, 0x12, 0x08, 0x0a, 0x04, 0x49, 0x6e, 0x66, 0x6f, 0x10, 0x01, 0x12, 0x08, 0x0a, - 0x04, 0x57, 0x61, 0x72, 0x6e, 0x10, 0x02, 0x12, 0x09, 0x0a, 0x05, 0x45, 0x72, 0x72, 0x6f, 0x72, - 0x10, 0x03, 0x2a, 0x2a, 0x0a, 0x0d, 0x4c, 0x6f, 0x67, 0x73, 0x44, 0x69, 0x72, 0x65, 0x63, 0x74, - 0x69, 0x6f, 0x6e, 0x12, 0x0b, 0x0a, 0x07, 0x46, 0x6f, 0x72, 0x77, 0x61, 0x72, 0x64, 0x10, 0x00, - 0x12, 0x0c, 0x0a, 0x08, 0x42, 0x61, 0x63, 0x6b, 0x77, 0x61, 0x72, 0x64, 0x10, 0x01, 0x2a, 0x3d, - 0x0a, 0x12, 0x54, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, 0x42, 0x75, 0x69, 0x6c, 0x64, 0x53, - 0x74, 0x61, 0x74, 0x65, 0x12, 0x0c, 0x0a, 0x08, 0x42, 0x75, 0x69, 0x6c, 0x64, 0x69, 0x6e, 0x67, - 0x10, 0x00, 0x12, 0x0a, 0x0a, 0x06, 0x46, 0x61, 0x69, 0x6c, 0x65, 0x64, 0x10, 0x01, 0x12, 0x0d, - 0x0a, 0x09, 0x43, 0x6f, 0x6d, 0x70, 0x6c, 0x65, 0x74, 0x65, 0x64, 0x10, 0x02, 0x32, 0xbe, 0x02, - 0x0a, 0x0f, 0x54, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, - 0x65, 0x12, 0x40, 0x0a, 0x0e, 0x54, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, 0x43, 0x72, 0x65, - 0x61, 0x74, 0x65, 0x12, 0x16, 0x2e, 0x54, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, 0x43, 0x72, - 0x65, 0x61, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x16, 0x2e, 0x67, 0x6f, - 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, - 0x70, 0x74, 0x79, 0x12, 0x4b, 0x0a, 0x13, 0x54, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, 0x42, - 0x75, 0x69, 0x6c, 0x64, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x16, 0x2e, 0x54, 0x65, 0x6d, - 0x70, 0x6c, 0x61, 0x74, 0x65, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, - 0x73, 0x74, 0x1a, 0x1c, 0x2e, 0x54, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, 0x42, 0x75, 0x69, - 0x6c, 0x64, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, - 0x12, 0x4a, 0x0a, 0x13, 0x54, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, 0x42, 0x75, 0x69, 0x6c, - 0x64, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x12, 0x1b, 0x2e, 0x54, 0x65, 0x6d, 0x70, 0x6c, 0x61, - 0x74, 0x65, 0x42, 0x75, 0x69, 0x6c, 0x64, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x52, 0x65, 0x71, + 0x65, 0x52, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x32, 0x0a, 0x08, 0x6d, 0x65, 0x74, + 0x61, 0x64, 0x61, 0x74, 0x61, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x16, 0x2e, 0x54, 0x65, + 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, 0x42, 0x75, 0x69, 0x6c, 0x64, 0x4d, 0x65, 0x74, 0x61, 0x64, + 0x61, 0x74, 0x61, 0x52, 0x08, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x12, 0x36, 0x0a, + 0x0a, 0x6c, 0x6f, 0x67, 0x45, 0x6e, 0x74, 0x72, 0x69, 0x65, 0x73, 0x18, 0x05, 0x20, 0x03, 0x28, + 0x0b, 0x32, 0x16, 0x2e, 0x54, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, 0x42, 0x75, 0x69, 0x6c, + 0x64, 0x4c, 0x6f, 0x67, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x0a, 0x6c, 0x6f, 0x67, 0x45, 0x6e, + 0x74, 0x72, 0x69, 0x65, 0x73, 0x12, 0x37, 0x0a, 0x06, 0x72, 0x65, 0x61, 0x73, 0x6f, 0x6e, 0x18, + 0x06, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x54, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, + 0x42, 0x75, 0x69, 0x6c, 0x64, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x61, 0x73, 0x6f, + 0x6e, 0x48, 0x00, 0x52, 0x06, 0x72, 0x65, 0x61, 0x73, 0x6f, 0x6e, 0x88, 0x01, 0x01, 0x42, 0x09, + 0x0a, 0x07, 0x5f, 0x72, 0x65, 0x61, 0x73, 0x6f, 0x6e, 0x4a, 0x04, 0x08, 0x03, 0x10, 0x04, 0x4a, + 0x04, 0x08, 0x04, 0x10, 0x05, 0x2a, 0x34, 0x0a, 0x08, 0x4c, 0x6f, 0x67, 0x4c, 0x65, 0x76, 0x65, + 0x6c, 0x12, 0x09, 0x0a, 0x05, 0x44, 0x65, 0x62, 0x75, 0x67, 0x10, 0x00, 0x12, 0x08, 0x0a, 0x04, + 0x49, 0x6e, 0x66, 0x6f, 0x10, 0x01, 0x12, 0x08, 0x0a, 0x04, 0x57, 0x61, 0x72, 0x6e, 0x10, 0x02, + 0x12, 0x09, 0x0a, 0x05, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x10, 0x03, 0x2a, 0x2a, 0x0a, 0x0d, 0x4c, + 0x6f, 0x67, 0x73, 0x44, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x0b, 0x0a, 0x07, + 0x46, 0x6f, 0x72, 0x77, 0x61, 0x72, 0x64, 0x10, 0x00, 0x12, 0x0c, 0x0a, 0x08, 0x42, 0x61, 0x63, + 0x6b, 0x77, 0x61, 0x72, 0x64, 0x10, 0x01, 0x2a, 0x3d, 0x0a, 0x12, 0x54, 0x65, 0x6d, 0x70, 0x6c, + 0x61, 0x74, 0x65, 0x42, 0x75, 0x69, 0x6c, 0x64, 0x53, 0x74, 0x61, 0x74, 0x65, 0x12, 0x0c, 0x0a, + 0x08, 0x42, 0x75, 0x69, 0x6c, 0x64, 0x69, 0x6e, 0x67, 0x10, 0x00, 0x12, 0x0a, 0x0a, 0x06, 0x46, + 0x61, 0x69, 0x6c, 0x65, 0x64, 0x10, 0x01, 0x12, 0x0d, 0x0a, 0x09, 0x43, 0x6f, 0x6d, 0x70, 0x6c, + 0x65, 0x74, 0x65, 0x64, 0x10, 0x02, 0x32, 0xbe, 0x02, 0x0a, 0x0f, 0x54, 0x65, 0x6d, 0x70, 0x6c, + 0x61, 0x74, 0x65, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x40, 0x0a, 0x0e, 0x54, 0x65, + 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x12, 0x16, 0x2e, 0x54, + 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, - 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x12, 0x50, 0x0a, 0x13, - 0x49, 0x6e, 0x69, 0x74, 0x4c, 0x61, 0x79, 0x65, 0x72, 0x46, 0x69, 0x6c, 0x65, 0x55, 0x70, 0x6c, - 0x6f, 0x61, 0x64, 0x12, 0x1b, 0x2e, 0x49, 0x6e, 0x69, 0x74, 0x4c, 0x61, 0x79, 0x65, 0x72, 0x46, - 0x69, 0x6c, 0x65, 0x55, 0x70, 0x6c, 0x6f, 0x61, 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, - 0x1a, 0x1c, 0x2e, 0x49, 0x6e, 0x69, 0x74, 0x4c, 0x61, 0x79, 0x65, 0x72, 0x46, 0x69, 0x6c, 0x65, - 0x55, 0x70, 0x6c, 0x6f, 0x61, 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x42, 0x33, - 0x5a, 0x31, 0x68, 0x74, 0x74, 0x70, 0x73, 0x3a, 0x2f, 0x2f, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, - 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x65, 0x32, 0x62, 0x2d, 0x64, 0x65, 0x76, 0x2f, 0x69, 0x6e, 0x66, - 0x72, 0x61, 0x2f, 0x74, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, 0x2d, 0x6d, 0x61, 0x6e, 0x61, - 0x67, 0x65, 0x72, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x12, 0x4b, 0x0a, 0x13, + 0x54, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, 0x42, 0x75, 0x69, 0x6c, 0x64, 0x53, 0x74, 0x61, + 0x74, 0x75, 0x73, 0x12, 0x16, 0x2e, 0x54, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, 0x53, 0x74, + 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1c, 0x2e, 0x54, 0x65, + 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, 0x42, 0x75, 0x69, 0x6c, 0x64, 0x53, 0x74, 0x61, 0x74, 0x75, + 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x4a, 0x0a, 0x13, 0x54, 0x65, 0x6d, + 0x70, 0x6c, 0x61, 0x74, 0x65, 0x42, 0x75, 0x69, 0x6c, 0x64, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, + 0x12, 0x1b, 0x2e, 0x54, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, 0x42, 0x75, 0x69, 0x6c, 0x64, + 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x16, 0x2e, + 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, + 0x45, 0x6d, 0x70, 0x74, 0x79, 0x12, 0x50, 0x0a, 0x13, 0x49, 0x6e, 0x69, 0x74, 0x4c, 0x61, 0x79, + 0x65, 0x72, 0x46, 0x69, 0x6c, 0x65, 0x55, 0x70, 0x6c, 0x6f, 0x61, 0x64, 0x12, 0x1b, 0x2e, 0x49, + 0x6e, 0x69, 0x74, 0x4c, 0x61, 0x79, 0x65, 0x72, 0x46, 0x69, 0x6c, 0x65, 0x55, 0x70, 0x6c, 0x6f, + 0x61, 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1c, 0x2e, 0x49, 0x6e, 0x69, 0x74, + 0x4c, 0x61, 0x79, 0x65, 0x72, 0x46, 0x69, 0x6c, 0x65, 0x55, 0x70, 0x6c, 0x6f, 0x61, 0x64, 0x52, + 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x42, 0x33, 0x5a, 0x31, 0x68, 0x74, 0x74, 0x70, 0x73, + 0x3a, 0x2f, 0x2f, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x65, 0x32, + 0x62, 0x2d, 0x64, 0x65, 0x76, 0x2f, 0x69, 0x6e, 0x66, 0x72, 0x61, 0x2f, 0x74, 0x65, 0x6d, 0x70, + 0x6c, 0x61, 0x74, 0x65, 0x2d, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x72, 0x62, 0x06, 0x70, 0x72, + 0x6f, 0x74, 0x6f, 0x33, } var ( diff --git a/tests/integration/seed.go b/tests/integration/seed.go index d3fa713909..48d287c13f 100644 --- a/tests/integration/seed.go +++ b/tests/integration/seed.go @@ -207,7 +207,7 @@ INSERT INTO env_builds ( cluster_node_id, version, created_at, updated_at ) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, CURRENT_TIMESTAMP) `, build.id, "FROM e2bdev/base:latest", dbtypes.BuildStatusUploaded, - 2, 512, 512, 1982, "vmlinux-6.1.102", "v1.12.1_a41d3fb", "0.2.4", + 2, 512, 512, 1982, "vmlinux-6.1.102", "v1.14.1_aa14c57", "0.2.4", "integration-test-node", templates.TemplateV1Version, build.createdAt) } else { err = db.TestsRawSQL(ctx, ` @@ -217,7 +217,7 @@ INSERT INTO env_builds ( cluster_node_id, version, updated_at ) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, CURRENT_TIMESTAMP) `, build.id, "FROM e2bdev/base:latest", dbtypes.BuildStatusUploaded, - 2, 512, 512, 1982, "vmlinux-6.1.102", "v1.12.1_a41d3fb", "0.2.4", + 2, 512, 512, 1982, "vmlinux-6.1.102", "v1.14.1_aa14c57", "0.2.4", "integration-test-node", templates.TemplateV1Version) } if err != nil {