mirror of
https://github.com/containerd/containerd.git
synced 2026-11-06 05:17:02 +00:00
Wire UpdatePodSandboxResources to Sandbox API
Integrates CRI container resource updates with core Sandbox API plugin. Delegates payload to out-of-tree controllers via UpdateSandbox API. Gracefully tolerates ErrNotImplemented to preserve backwards compatibility for legacy sandboxers. Assisted-by: Antigravity Signed-off-by: Chris Henzie <chrishenzie@gmail.com>
This commit is contained in:
5 files changed
+92
No files matched your search
@@ -110,6 +110,14 @@ func (c *criSandboxService) ShutdownSandbox(ctx context.Context, sandboxer strin
|
||||
return ctrl.Shutdown(ctx, sandboxID)
|
||||
}
|
||||
|
||||
func (c *criSandboxService) UpdateSandbox(ctx context.Context, sandboxer string, sandboxID string, sandbox sandbox.Sandbox, fields ...string) error {
|
||||
ctrl, err := c.SandboxController(sandboxer)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return ctrl.Update(ctx, sandboxID, sandbox, fields...)
|
||||
}
|
||||
|
||||
func (c *criSandboxService) StopSandbox(ctx context.Context, sandboxer, sandboxID string, opts ...sandbox.StopOpt) error {
|
||||
ctrl, err := c.SandboxController(sandboxer)
|
||||
if err != nil {
|
||||
|
||||
@@ -25,6 +25,7 @@ import (
|
||||
"github.com/containerd/containerd/v2/internal/cri/server/podsandbox"
|
||||
sstore "github.com/containerd/containerd/v2/internal/cri/store/sandbox"
|
||||
"github.com/containerd/containerd/v2/pkg/tracing"
|
||||
"github.com/containerd/errdefs"
|
||||
"github.com/containerd/log"
|
||||
)
|
||||
|
||||
@@ -75,6 +76,14 @@ func (c *criService) UpdatePodSandboxResources(ctx context.Context, r *runtime.U
|
||||
return nil, fmt.Errorf("failed to update sandbox %s in core store: %w", sandbox.ID, err)
|
||||
}
|
||||
|
||||
if err := c.sandboxService.UpdateSandbox(ctx, sandboxInfo.Sandboxer, sandboxInfo.ID, sandboxInfo, "extensions"); err != nil {
|
||||
// Tolerate these errors for older sandbox controllers that may not support this yet.
|
||||
if !errdefs.IsNotImplemented(err) {
|
||||
return nil, fmt.Errorf("failed to update sandbox controller: %w", err)
|
||||
}
|
||||
log.G(ctx).Tracef("sandbox controller %q does not implement Update endpoint", sandboxInfo.Sandboxer)
|
||||
}
|
||||
|
||||
err = c.nri.PostUpdatePodSandboxResources(ctx, &sandbox)
|
||||
if err != nil {
|
||||
log.G(ctx).WithError(err).Errorf("NRI post-update notification failed")
|
||||
|
||||
@@ -53,6 +53,17 @@ func (f *fakeSandboxStore) Update(_ context.Context, sb sandbox.Sandbox, _ ...st
|
||||
return sb, nil
|
||||
}
|
||||
|
||||
type recordSandboxService struct {
|
||||
fakeSandboxService
|
||||
calledID string
|
||||
returnErr error
|
||||
}
|
||||
|
||||
func (s *recordSandboxService) UpdateSandbox(_ context.Context, _ string, sandboxID string, _ sandbox.Sandbox, _ ...string) error {
|
||||
s.calledID = sandboxID
|
||||
return s.returnErr
|
||||
}
|
||||
|
||||
func TestUpdatePodSandboxResources(t *testing.T) {
|
||||
mySandbox := sstore.Metadata{
|
||||
ID: "test-sandbox-id",
|
||||
@@ -150,4 +161,63 @@ func TestUpdatePodSandboxResources(t *testing.T) {
|
||||
assert.Equal(t, int64(100), updatedRes.Overhead.MemoryLimitInBytes)
|
||||
assert.Equal(t, int64(200), updatedRes.Resources.CpuQuota)
|
||||
})
|
||||
|
||||
t.Run("success fallback when sandbox controller does not implement update", func(t *testing.T) {
|
||||
recordService := &recordSandboxService{returnErr: errdefs.ErrNotImplemented}
|
||||
c := newTestCRIService(func(service *criService) {
|
||||
service.sandboxService = recordService
|
||||
client, _ := containerd.New("", containerd.WithServices(containerd.WithSandboxStore(&fakeSandboxStore{})))
|
||||
service.client = client
|
||||
})
|
||||
s := sstore.NewSandbox(mySandbox, sstore.Status{})
|
||||
c.sandboxStore.Add(s)
|
||||
|
||||
req := &runtime.UpdatePodSandboxResourcesRequest{
|
||||
PodSandboxId: "test-sandbox-id",
|
||||
}
|
||||
|
||||
_, err := c.UpdatePodSandboxResources(context.Background(), req)
|
||||
require.NoError(t, err)
|
||||
|
||||
assert.Equal(t, "test-sandbox-id", recordService.calledID)
|
||||
})
|
||||
|
||||
t.Run("success when sandbox controller implements update", func(t *testing.T) {
|
||||
recordService := &recordSandboxService{returnErr: nil}
|
||||
c := newTestCRIService(func(service *criService) {
|
||||
service.sandboxService = recordService
|
||||
client, _ := containerd.New("", containerd.WithServices(containerd.WithSandboxStore(&fakeSandboxStore{})))
|
||||
service.client = client
|
||||
})
|
||||
s := sstore.NewSandbox(mySandbox, sstore.Status{})
|
||||
c.sandboxStore.Add(s)
|
||||
|
||||
req := &runtime.UpdatePodSandboxResourcesRequest{
|
||||
PodSandboxId: "test-sandbox-id",
|
||||
}
|
||||
|
||||
_, err := c.UpdatePodSandboxResources(context.Background(), req)
|
||||
require.NoError(t, err)
|
||||
|
||||
assert.Equal(t, "test-sandbox-id", recordService.calledID)
|
||||
})
|
||||
|
||||
t.Run("fails when sandbox controller update fails", func(t *testing.T) {
|
||||
recordService := &recordSandboxService{returnErr: errdefs.ErrInvalidArgument}
|
||||
c := newTestCRIService(func(service *criService) {
|
||||
service.sandboxService = recordService
|
||||
client, _ := containerd.New("", containerd.WithServices(containerd.WithSandboxStore(&fakeSandboxStore{})))
|
||||
service.client = client
|
||||
})
|
||||
s := sstore.NewSandbox(mySandbox, sstore.Status{})
|
||||
c.sandboxStore.Add(s)
|
||||
|
||||
req := &runtime.UpdatePodSandboxResourcesRequest{
|
||||
PodSandboxId: "test-sandbox-id",
|
||||
}
|
||||
|
||||
_, err := c.UpdatePodSandboxResources(context.Background(), req)
|
||||
require.Error(t, err)
|
||||
assert.Contains(t, err.Error(), errdefs.ErrInvalidArgument.Error())
|
||||
})
|
||||
}
|
||||
@@ -78,6 +78,7 @@ type sandboxService interface {
|
||||
CreateSandbox(ctx context.Context, info sandbox.Sandbox, opts ...sandbox.CreateOpt) error
|
||||
StartSandbox(ctx context.Context, sandboxer string, sandboxID string) (sandbox.ControllerInstance, error)
|
||||
WaitSandbox(ctx context.Context, sandboxer string, sandboxID string) (<-chan containerd.ExitStatus, error)
|
||||
UpdateSandbox(ctx context.Context, sandboxer string, sandboxID string, sandbox sandbox.Sandbox, fields ...string) error
|
||||
StopSandbox(ctx context.Context, sandboxer, sandboxID string, opts ...sandbox.StopOpt) error
|
||||
ShutdownSandbox(ctx context.Context, sandboxer string, sandboxID string) error
|
||||
SandboxStatus(ctx context.Context, sandboxer string, sandboxID string, verbose bool) (sandbox.ControllerStatus, error)
|
||||
|
||||
@@ -47,6 +47,10 @@ func (f *fakeSandboxService) StartSandbox(ctx context.Context, sandboxer string,
|
||||
return sandbox.ControllerInstance{}, errdefs.ErrNotImplemented
|
||||
}
|
||||
|
||||
func (f *fakeSandboxService) UpdateSandbox(ctx context.Context, sandboxer string, sandboxID string, sandbox sandbox.Sandbox, fields ...string) error {
|
||||
return errdefs.ErrNotImplemented
|
||||
}
|
||||
|
||||
func (f *fakeSandboxService) StopSandbox(ctx context.Context, sandboxer, sandboxID string, opts ...sandbox.StopOpt) error {
|
||||
return errdefs.ErrNotImplemented
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user