Repository: containerd/containerd
File: internal/cri/opts/spec_opts.go (Go)

Code before:
// Swap swaps two items in an array of mounts. Used in sorting
func (m orderedMounts) Swap(i, j int) {
	m[i], m[j] = m[j], m[i]
}

// parts returns the number of parts in the destination of a mount. Used in sorting.
func (m orderedMounts) parts(i int) int {
	return strings.Count(filepath.Clean(m[i].ContainerPath), string(os.PathSeparator))
}

// WithAnnotation sets the provided annotation
func WithAnnotation(k, v string) oci.SpecOpts {
	return func(ctx context.Context, client oci.Client, c *containers.Container, s *runtimespec.Spec) error {
		if s.Annotations == nil {
			s.Annotations = make(map[string]string)
		}
		s.Annotations[k] = v
		return nil
	}
}

// WithAffinityCPUs sets the CPU affinity values in runtime spec for windows.
func WithAffinityCPUs(affinityCPUs []*runtime.WindowsCpuGroupAffinity) oci.SpecOpts {
	return func(_ context.Context, _ oci.Client, c *containers.Container, s *runtimespec.Spec) error {
		// We would expect the Windows and Resources struct to be setup by now
		if affinityCPUs == nil || s.Windows == nil || s.Windows.Resources == nil {
			return nil
		}
		if s.Windows.Resources.CPU == nil {
			s.Windows.Resources.CPU = &runtimespec.WindowsCPUResources{}
		}
		if s.Windows.Resources.CPU.Affinity == nil {
			s.Windows.Resources.CPU.Affinity = make([]runtimespec.WindowsCPUGroupAffinity, len(affinityCPUs))
		}
		for i, affinity := range affinityCPUs {
			s.Windows.Resources.CPU.Affinity[i] = runtimespec.WindowsCPUGroupAffinity{
				Mask:  affinity.CpuMask,
				Group: affinity.CpuGroup,
			}
		}
		return nil
	}
}

// WithAdditionalGIDs adds any additional groups listed for a particular user in the
// /etc/groups file of the image's root filesystem to the OCI spec's additionalGids array.
func WithAdditionalGIDs(userstr string) oci.SpecOpts {
	return func(ctx context.Context, client oci.Client, c *containers.Container, s *runtimespec.Spec) (err error) {
		if s.Process == nil {
			s.Process = &runtimespec.Process{}
		}

Review comment (refactor):
Not 100% sure what we do in other cases, but curious if  there's situations where this function should be able to reset prior state.

At least it's probably good to describe the behavior in the GoDoc. I had something similar not too long ago, where an existing function would _replace_ what's there, so I had to add another function to allow _appending_. https://github.com/containerd/containerd/blob/a6dc9905cbb1833c459362ba72928bd348967158/client/client_opts.go#L72-L86


Alternatively, we could either have the option to require an empty slice to "reset" (and `nil` to be no-op), or a second argument to define "overwrite vs append" (although I'm not always a fan of booleans 😂)


Depending on some of the intended behavior, might also want to consider checking `len(affinityCPUs) == 0` instead of checking for `nil`.

Code after:
// Swap swaps two items in an array of mounts. Used in sorting
func (m orderedMounts) Swap(i, j int) {
	m[i], m[j] = m[j], m[i]
}

// parts returns the number of parts in the destination of a mount. Used in sorting.
func (m orderedMounts) parts(i int) int {
	return strings.Count(filepath.Clean(m[i].ContainerPath), string(os.PathSeparator))
}

// WithAnnotation sets the provided annotation
func WithAnnotation(k, v string) oci.SpecOpts {
	return func(ctx context.Context, client oci.Client, c *containers.Container, s *runtimespec.Spec) error {
		if s.Annotations == nil {
			s.Annotations = make(map[string]string)
		}
		s.Annotations[k] = v
		return nil
	}
}

// WithWindowsAffinityCPUs sets the CPU affinity values in runtime spec for windows.
func WithWindowsAffinityCPUs(config *runtime.WindowsContainerConfig) oci.SpecOpts {
	return func(_ context.Context, _ oci.Client, c *containers.Container, s *runtimespec.Spec) error {
		if s.Windows == nil || config.Resources == nil || config.Resources.AffinityCpus == nil {
			return nil
		}

		if s.Windows.Resources == nil {
			s.Windows.Resources = &runtimespec.WindowsResources{}
		}

		if s.Windows.Resources.CPU == nil {
			s.Windows.Resources.CPU = &runtimespec.WindowsCPUResources{}
		}

		affinities := make([]runtimespec.WindowsCPUGroupAffinity, 0, len(config.Resources.AffinityCpus))
		for _, affinity := range config.Resources.AffinityCpus {
			affinities = append(affinities, runtimespec.WindowsCPUGroupAffinity{
				Mask:  affinity.CpuMask,
				Group: affinity.CpuGroup,
			})
		}
		s.Windows.Resources.CPU.Affinity = affinities
		return nil
	}
}

// WithAdditionalGIDs adds any additional groups listed for a particular user in the
// /etc/groups file of the image's root filesystem to the OCI spec's additionalGids array.
func WithAdditionalGIDs(userstr string) oci.SpecOpts {