From e20bf70001109ae2c8981835c9d030cd69bb0ada Mon Sep 17 00:00:00 2001 From: Shubhranshu153 Date: Mon, 28 Oct 2024 08:51:15 +0000 Subject: [PATCH] feat: Add Support for idmapping in finch-daemon Signed-off-by: Shubhranshu153 --- internal/service/container/create.go | 14 ++++++ internal/service/container/create_test.go | 56 +++++++++++++++++++++++ 2 files changed, 70 insertions(+) diff --git a/internal/service/container/create.go b/internal/service/container/create.go index 8ca6b399..49d61eca 100644 --- a/internal/service/container/create.go +++ b/internal/service/container/create.go @@ -6,6 +6,7 @@ package container import ( "context" "fmt" + "strings" "github.com/containerd/containerd" "github.com/containerd/containerd/cio" @@ -20,6 +21,17 @@ import ( "github.com/runfinch/finch-daemon/pkg/errdefs" ) +// ExtractUsernsFromLabels searches for a label with the prefix +// "runfinch.com/internal/userns=" and sets the Userns field. +func extractUsernsFromLabels(createOpt *types.ContainerCreateOptions) { + for _, label := range createOpt.Label { + if strings.HasPrefix(label, "runfinch.com/internal/userns=") { + createOpt.Userns = strings.TrimPrefix(label, "runfinch.com/internal/userns=") + return // Exit after the first match + } + } +} + func (s *service) Create(ctx context.Context, image string, cmd []string, createOpt types.ContainerCreateOptions, netOpt types.NetworkOptions) (cid string, err error) { // Set path to nerdctl binary required for OCI hooks and logging if createOpt.NerdctlCmd == "" { @@ -31,6 +43,8 @@ func (s *service) Create(ctx context.Context, image string, cmd []string, create createOpt.NerdctlArgs = []string{} } + extractUsernsFromLabels(&createOpt) + // translate network IDs to names because nerdctl currently does not recognize networks by their IDs during create. // TODO: remove this when the issue is fixed upstream. if err := s.translateNetworkIds(&netOpt); err != nil { diff --git a/internal/service/container/create_test.go b/internal/service/container/create_test.go index b8cd4957..cc0d1f02 100644 --- a/internal/service/container/create_test.go +++ b/internal/service/container/create_test.go @@ -287,3 +287,59 @@ var _ = Describe("Container Create API ", func() { }) }) }) + +var _ = Describe("Extracting Userns from Labels", func() { + var ( + createOpt *types.ContainerCreateOptions + ) + + BeforeEach(func() { + createOpt = &types.ContainerCreateOptions{} + }) + + Describe("when there are labels", func() { + Context("with a matching userns label", func() { + BeforeEach(func() { + createOpt.Label = []string{"runfinch.com/internal/userns=test-namespace", "other.label=value"} + }) + + It("should extract the userns correctly", func() { + extractUsernsFromLabels(createOpt) + Expect(createOpt.Userns).To(Equal("test-namespace")) + }) + }) + + Context("without a matching userns label", func() { + BeforeEach(func() { + createOpt.Label = []string{"other.label=value"} + }) + + It("should not set userns", func() { + extractUsernsFromLabels(createOpt) + Expect(createOpt.Userns).To(BeEmpty()) + }) + }) + + Context("with multiple matching userns labels", func() { + BeforeEach(func() { + createOpt.Label = []string{"runfinch.com/internal/userns=test-namespace", "runfinch.com/internal/userns=another-namespace"} + }) + + It("should extract only the first userns label", func() { + extractUsernsFromLabels(createOpt) + Expect(createOpt.Userns).To(Equal("test-namespace")) + }) + }) + + Context("when the label list is empty", func() { + BeforeEach(func() { + createOpt.Label = []string{} + }) + + It("should not set userns", func() { + extractUsernsFromLabels(createOpt) + Expect(createOpt.Userns).To(BeEmpty()) + }) + }) + }) +})