github.com/containers/podman/v4@v4.9.4/pkg/specgen/generate/namespaces_linux.go (about)

     1  //go:build !remote
     2  // +build !remote
     3  
     4  package generate
     5  
     6  import (
     7  	"fmt"
     8  	"os"
     9  
    10  	"github.com/containers/podman/v4/libpod"
    11  	"github.com/containers/podman/v4/libpod/define"
    12  	"github.com/containers/podman/v4/pkg/specgen"
    13  	spec "github.com/opencontainers/runtime-spec/specs-go"
    14  	"github.com/opencontainers/runtime-tools/generate"
    15  	"github.com/sirupsen/logrus"
    16  )
    17  
    18  func specConfigureNamespaces(s *specgen.SpecGenerator, g *generate.Generator, rt *libpod.Runtime, pod *libpod.Pod) error {
    19  	// PID
    20  	switch s.PidNS.NSMode {
    21  	case specgen.Path:
    22  		if _, err := os.Stat(s.PidNS.Value); err != nil {
    23  			return fmt.Errorf("cannot find specified PID namespace path: %w", err)
    24  		}
    25  		if err := g.AddOrReplaceLinuxNamespace(string(spec.PIDNamespace), s.PidNS.Value); err != nil {
    26  			return err
    27  		}
    28  	case specgen.Host:
    29  		if err := g.RemoveLinuxNamespace(string(spec.PIDNamespace)); err != nil {
    30  			return err
    31  		}
    32  	case specgen.Private:
    33  		if err := g.AddOrReplaceLinuxNamespace(string(spec.PIDNamespace), ""); err != nil {
    34  			return err
    35  		}
    36  	}
    37  
    38  	// IPC
    39  	switch s.IpcNS.NSMode {
    40  	case specgen.Path:
    41  		if _, err := os.Stat(s.IpcNS.Value); err != nil {
    42  			return fmt.Errorf("cannot find specified IPC namespace path: %w", err)
    43  		}
    44  		if err := g.AddOrReplaceLinuxNamespace(string(spec.IPCNamespace), s.IpcNS.Value); err != nil {
    45  			return err
    46  		}
    47  	case specgen.Host:
    48  		if err := g.RemoveLinuxNamespace(string(spec.IPCNamespace)); err != nil {
    49  			return err
    50  		}
    51  	case specgen.Private:
    52  		if err := g.AddOrReplaceLinuxNamespace(string(spec.IPCNamespace), ""); err != nil {
    53  			return err
    54  		}
    55  	}
    56  
    57  	// UTS
    58  	switch s.UtsNS.NSMode {
    59  	case specgen.Path:
    60  		if _, err := os.Stat(s.UtsNS.Value); err != nil {
    61  			return fmt.Errorf("cannot find specified UTS namespace path: %w", err)
    62  		}
    63  		if err := g.AddOrReplaceLinuxNamespace(string(spec.UTSNamespace), s.UtsNS.Value); err != nil {
    64  			return err
    65  		}
    66  	case specgen.Host:
    67  		if err := g.RemoveLinuxNamespace(string(spec.UTSNamespace)); err != nil {
    68  			return err
    69  		}
    70  	case specgen.Private:
    71  		if err := g.AddOrReplaceLinuxNamespace(string(spec.UTSNamespace), ""); err != nil {
    72  			return err
    73  		}
    74  	}
    75  
    76  	hostname := s.Hostname
    77  	if hostname == "" {
    78  		switch {
    79  		case s.UtsNS.NSMode == specgen.FromPod:
    80  			hostname = pod.Hostname()
    81  		case s.UtsNS.NSMode == specgen.FromContainer:
    82  			utsCtr, err := rt.LookupContainer(s.UtsNS.Value)
    83  			if err != nil {
    84  				return fmt.Errorf("looking up container to share uts namespace with: %w", err)
    85  			}
    86  			hostname = utsCtr.Hostname()
    87  		case (s.NetNS.NSMode == specgen.Host && hostname == "") || s.UtsNS.NSMode == specgen.Host:
    88  			tmpHostname, err := os.Hostname()
    89  			if err != nil {
    90  				return fmt.Errorf("unable to retrieve hostname of the host: %w", err)
    91  			}
    92  			hostname = tmpHostname
    93  		default:
    94  			logrus.Debug("No hostname set; container's hostname will default to runtime default")
    95  		}
    96  	}
    97  
    98  	g.RemoveHostname()
    99  	if s.Hostname != "" || s.UtsNS.NSMode != specgen.Host {
   100  		// Set the hostname in the OCI configuration only if specified by
   101  		// the user or if we are creating a new UTS namespace.
   102  		// TODO: Should we be doing this for pod or container shared
   103  		// namespaces?
   104  		g.SetHostname(hostname)
   105  	}
   106  	if _, ok := s.Env["HOSTNAME"]; !ok && s.Hostname != "" {
   107  		g.AddProcessEnv("HOSTNAME", hostname)
   108  	}
   109  
   110  	// User
   111  	if _, err := specgen.SetupUserNS(s.IDMappings, s.UserNS, g); err != nil {
   112  		return err
   113  	}
   114  
   115  	// Cgroup
   116  	switch s.CgroupNS.NSMode {
   117  	case specgen.Path:
   118  		if _, err := os.Stat(s.CgroupNS.Value); err != nil {
   119  			return fmt.Errorf("cannot find specified cgroup namespace path: %w", err)
   120  		}
   121  		if err := g.AddOrReplaceLinuxNamespace(string(spec.CgroupNamespace), s.CgroupNS.Value); err != nil {
   122  			return err
   123  		}
   124  	case specgen.Host:
   125  		if err := g.RemoveLinuxNamespace(string(spec.CgroupNamespace)); err != nil {
   126  			return err
   127  		}
   128  	case specgen.Private:
   129  		if err := g.AddOrReplaceLinuxNamespace(string(spec.CgroupNamespace), ""); err != nil {
   130  			return err
   131  		}
   132  	}
   133  
   134  	// Net
   135  	switch s.NetNS.NSMode {
   136  	case specgen.Path:
   137  		if _, err := os.Stat(s.NetNS.Value); err != nil {
   138  			return fmt.Errorf("cannot find specified network namespace path: %w", err)
   139  		}
   140  		if err := g.AddOrReplaceLinuxNamespace(string(spec.NetworkNamespace), s.NetNS.Value); err != nil {
   141  			return err
   142  		}
   143  	case specgen.Host:
   144  		if err := g.RemoveLinuxNamespace(string(spec.NetworkNamespace)); err != nil {
   145  			return err
   146  		}
   147  	case specgen.Private, specgen.NoNetwork:
   148  		if err := g.AddOrReplaceLinuxNamespace(string(spec.NetworkNamespace), ""); err != nil {
   149  			return err
   150  		}
   151  	}
   152  
   153  	if g.Config.Annotations == nil {
   154  		g.Config.Annotations = make(map[string]string)
   155  	}
   156  	if s.PublishExposedPorts {
   157  		g.Config.Annotations[define.InspectAnnotationPublishAll] = define.InspectResponseTrue
   158  	}
   159  
   160  	return nil
   161  }