Repository: containerd/containerd
File: internal/cri/server/sandbox_run.go (Go)

Code before:
			netnsMountDir = filepath.Join(c.config.StateDir, "netns")
		}

		if !userNsEnabled {
			sandbox.NetNS, err = netns.NewNetNS(netnsMountDir)
		} else {
			usernsOpts := config.GetLinux().GetSecurityContext().GetNamespaceOptions().GetUsernsOptions()
			sandbox.NetNS, err = c.setupNetnsWithinUserns(netnsMountDir, usernsOpts)
		}
		if err != nil {
			return nil, fmt.Errorf("failed to create network namespace for sandbox %q: %w", id, err)
		}
		// Update network namespace in the store, which is used to generate the container's spec
		sandbox.NetNSPath = sandbox.NetNS.GetPath()
		defer func() {
			// Remove the network namespace only if all the resource cleanup is done
			if retErr != nil && cleanupErr == nil {
				if cleanupErr = sandbox.NetNS.Remove(); cleanupErr != nil {
					log.G(ctx).WithError(cleanupErr).Errorf("Failed to remove network namespace %s for sandbox %q", sandbox.NetNSPath, id)
					return
				}
				sandbox.NetNSPath = ""
			}
		}()
		if err := sandboxInfo.AddExtension(podsandbox.MetadataKey, &sandbox.Metadata); err != nil {
			return nil, fmt.Errorf("unable to update extensions for sandbox %q: %w", id, err)
		}
		// Save sandbox metadata to store
		if sandboxInfo, err = c.client.SandboxStore().Update(ctx, sandboxInfo, "extensions"); err != nil {
			return nil, fmt.Errorf("unable to save sandbox %q to sandbox store: %w", id, err)
		}
		// Define this defer to teardownPodNetwork prior to the setupPodNetwork function call.
		// This is because in setupPodNetwork the resource is allocated even if it returns error, unlike other resource
		// creation functions.
		defer func() {
			// Remove the network namespace only if all the resource cleanup is done.
			if retErr != nil && cleanupErr == nil {
				deferCtx, deferCancel := util.DeferContext()
				defer deferCancel()
				// Teardown network if an error is returned.
				if cleanupErr = c.teardownPodNetwork(deferCtx, sandbox); cleanupErr != nil {
					log.G(ctx).WithError(cleanupErr).Errorf("Failed to destroy network for sandbox %q", id)

					// ignoring failed to destroy networks when we failed to setup networks
					if sandbox.CNIResult == nil {
						cleanupErr = nil
					}
				}

			}
		}()

Review comment (suggestion):
(Same question for the `AddExtension()` call below) Why do we need to call `AddExtension()` here again if `Metadata` doesn't look to be changing?

https://github.com/containerd/containerd/blob/1a43cb6a1035441f9aca8f5666a9b3ef9e70ab20/internal/cri/store/sandbox/sandbox.go#L34-L35

Code after:
			netnsMountDir = filepath.Join(c.config.StateDir, "netns")
		}

		if !userNsEnabled {
			sandbox.NetNS, err = netns.NewNetNS(netnsMountDir)
		} else {
			usernsOpts := config.GetLinux().GetSecurityContext().GetNamespaceOptions().GetUsernsOptions()
			sandbox.NetNS, err = c.setupNetnsWithinUserns(netnsMountDir, usernsOpts)
		}
		if err != nil {
			return nil, fmt.Errorf("failed to create network namespace for sandbox %q: %w", id, err)
		}
		// Update network namespace in the store, which is used to generate the container's spec
		sandbox.NetNSPath = sandbox.NetNS.GetPath()
		defer func() {
			// Remove the network namespace only if all the resource cleanup is done
			if retErr != nil && cleanupErr == nil {
				if cleanupErr = sandbox.NetNS.Remove(); cleanupErr != nil {
					log.G(ctx).WithError(cleanupErr).Errorf("Failed to remove network namespace %s for sandbox %q", sandbox.NetNSPath, id)
					return
				}
				sandbox.NetNSPath = ""
			}
		}()

		if err := sandboxInfo.AddExtension(podsandbox.MetadataKey, &sandbox.Metadata); err != nil {
			return nil, fmt.Errorf("unable to update extensions for sandbox %q: %w", id, err)
		}
		// Save sandbox metadata to store
		if sandboxInfo, err = c.client.SandboxStore().Update(ctx, sandboxInfo, "extensions"); err != nil {
			return nil, fmt.Errorf("unable to save sandbox %q to sandbox store: %w", id, err)
		}
		// Define this defer to teardownPodNetwork prior to the setupPodNetwork function call.
		// This is because in setupPodNetwork the resource is allocated even if it returns error, unlike other resource
		// creation functions.
		defer func() {
			// Remove the network namespace only if all the resource cleanup is done.
			if retErr != nil && cleanupErr == nil {
				deferCtx, deferCancel := util.DeferContext()
				defer deferCancel()
				// Teardown network if an error is returned.
				if cleanupErr = c.teardownPodNetwork(deferCtx, sandbox); cleanupErr != nil {
					log.G(ctx).WithError(cleanupErr).Errorf("Failed to destroy network for sandbox %q", id)

					// ignoring failed to destroy networks when we failed to setup networks
					if sandbox.CNIResult == nil {
						cleanupErr = nil
					}
				}

			}