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 }