github.com/hanks177/podman/v4@v4.1.3-0.20220613032544-16d90015bc83/pkg/specgen/generate/pod_create.go (about) 1 package generate 2 3 import ( 4 "context" 5 "net" 6 7 "github.com/hanks177/podman/v4/libpod" 8 "github.com/hanks177/podman/v4/libpod/define" 9 "github.com/hanks177/podman/v4/pkg/domain/entities" 10 "github.com/hanks177/podman/v4/pkg/specgen" 11 "github.com/pkg/errors" 12 "github.com/sirupsen/logrus" 13 ) 14 15 func MakePod(p *entities.PodSpec, rt *libpod.Runtime) (*libpod.Pod, error) { 16 if err := p.PodSpecGen.Validate(); err != nil { 17 return nil, err 18 } 19 20 if !p.PodSpecGen.NoInfra { 21 imageName, err := PullOrBuildInfraImage(rt, p.PodSpecGen.InfraImage) 22 if err != nil { 23 return nil, err 24 } 25 p.PodSpecGen.InfraImage = imageName 26 p.PodSpecGen.InfraContainerSpec.RawImageName = imageName 27 } 28 29 if !p.PodSpecGen.NoInfra && p.PodSpecGen.InfraContainerSpec != nil { 30 var err error 31 p.PodSpecGen.InfraContainerSpec, err = MapSpec(&p.PodSpecGen) 32 if err != nil { 33 return nil, err 34 } 35 } 36 37 options, err := createPodOptions(&p.PodSpecGen) 38 if err != nil { 39 return nil, err 40 } 41 pod, err := rt.NewPod(context.Background(), p.PodSpecGen, options...) 42 if err != nil { 43 return nil, err 44 } 45 if !p.PodSpecGen.NoInfra && p.PodSpecGen.InfraContainerSpec != nil { 46 if p.PodSpecGen.InfraContainerSpec.Name == "" { 47 p.PodSpecGen.InfraContainerSpec.Name = pod.ID()[:12] + "-infra" 48 } 49 _, err = CompleteSpec(context.Background(), rt, p.PodSpecGen.InfraContainerSpec) 50 if err != nil { 51 return nil, err 52 } 53 p.PodSpecGen.InfraContainerSpec.User = "" // infraSpec user will get incorrectly assigned via the container creation process, overwrite here 54 rtSpec, spec, opts, err := MakeContainer(context.Background(), rt, p.PodSpecGen.InfraContainerSpec, false, nil) 55 if err != nil { 56 return nil, err 57 } 58 spec.Pod = pod.ID() 59 opts = append(opts, rt.WithPod(pod)) 60 spec.CgroupParent = pod.CgroupParent() 61 infraCtr, err := ExecuteCreate(context.Background(), rt, rtSpec, spec, true, opts...) 62 if err != nil { 63 return nil, err 64 } 65 pod, err = rt.AddInfra(context.Background(), pod, infraCtr) 66 if err != nil { 67 return nil, err 68 } 69 } else { 70 // SavePod is used to save the pod state and trigger a create event even if infra is not created 71 err := rt.SavePod(pod) 72 if err != nil { 73 return nil, err 74 } 75 } 76 return pod, nil 77 } 78 79 func createPodOptions(p *specgen.PodSpecGenerator) ([]libpod.PodCreateOption, error) { 80 var ( 81 options []libpod.PodCreateOption 82 ) 83 if !p.NoInfra { 84 options = append(options, libpod.WithInfraContainer()) 85 if p.ShareParent == nil || (p.ShareParent != nil && *p.ShareParent) { 86 options = append(options, libpod.WithPodParent()) 87 } 88 nsOptions, err := GetNamespaceOptions(p.SharedNamespaces, p.InfraContainerSpec.NetNS.IsHost()) 89 if err != nil { 90 return nil, err 91 } 92 options = append(options, nsOptions...) 93 // Use pod user and infra userns only when --userns is not set to host 94 if !p.InfraContainerSpec.UserNS.IsHost() && !p.InfraContainerSpec.UserNS.IsDefault() { 95 options = append(options, libpod.WithPodUser()) 96 } 97 } 98 99 if len(p.ServiceContainerID) > 0 { 100 options = append(options, libpod.WithServiceContainer(p.ServiceContainerID)) 101 } 102 103 if len(p.CgroupParent) > 0 { 104 options = append(options, libpod.WithPodCgroupParent(p.CgroupParent)) 105 } 106 if len(p.Labels) > 0 { 107 options = append(options, libpod.WithPodLabels(p.Labels)) 108 } 109 if len(p.Name) > 0 { 110 options = append(options, libpod.WithPodName(p.Name)) 111 } 112 if p.PodCreateCommand != nil { 113 options = append(options, libpod.WithPodCreateCommand(p.PodCreateCommand)) 114 } 115 116 if len(p.Hostname) > 0 { 117 options = append(options, libpod.WithPodHostname(p.Hostname)) 118 } 119 120 options = append(options, libpod.WithPodExitPolicy(p.ExitPolicy)) 121 122 return options, nil 123 } 124 125 // MapSpec modifies the already filled Infra specgenerator, 126 // replacing necessary values with those specified in pod creation 127 func MapSpec(p *specgen.PodSpecGenerator) (*specgen.SpecGenerator, error) { 128 if len(p.PortMappings) > 0 { 129 ports, err := ParsePortMapping(p.PortMappings, nil) 130 if err != nil { 131 return nil, err 132 } 133 p.InfraContainerSpec.PortMappings = ports 134 } 135 switch p.NetNS.NSMode { 136 case specgen.Default, "": 137 if p.NoInfra { 138 logrus.Debugf("No networking because the infra container is missing") 139 break 140 } 141 case specgen.Bridge: 142 p.InfraContainerSpec.NetNS.NSMode = specgen.Bridge 143 logrus.Debugf("Pod using bridge network mode") 144 case specgen.Private: 145 p.InfraContainerSpec.NetNS.NSMode = specgen.Private 146 logrus.Debugf("Pod will use default network mode") 147 case specgen.Host: 148 logrus.Debugf("Pod will use host networking") 149 if len(p.InfraContainerSpec.PortMappings) > 0 || 150 len(p.InfraContainerSpec.Networks) > 0 || 151 p.InfraContainerSpec.NetNS.NSMode == specgen.NoNetwork { 152 return nil, errors.Wrapf(define.ErrInvalidArg, "cannot set host network if network-related configuration is specified") 153 } 154 p.InfraContainerSpec.NetNS.NSMode = specgen.Host 155 case specgen.Slirp: 156 logrus.Debugf("Pod will use slirp4netns") 157 if p.InfraContainerSpec.NetNS.NSMode != specgen.Host { 158 p.InfraContainerSpec.NetworkOptions = p.NetworkOptions 159 p.InfraContainerSpec.NetNS.NSMode = specgen.Slirp 160 } 161 case specgen.NoNetwork: 162 logrus.Debugf("Pod will not use networking") 163 if len(p.InfraContainerSpec.PortMappings) > 0 || 164 len(p.InfraContainerSpec.Networks) > 0 || 165 p.InfraContainerSpec.NetNS.NSMode == specgen.Host { 166 return nil, errors.Wrapf(define.ErrInvalidArg, "cannot disable pod network if network-related configuration is specified") 167 } 168 p.InfraContainerSpec.NetNS.NSMode = specgen.NoNetwork 169 default: 170 return nil, errors.Errorf("pods presently do not support network mode %s", p.NetNS.NSMode) 171 } 172 173 if len(p.InfraCommand) > 0 { 174 p.InfraContainerSpec.Entrypoint = p.InfraCommand 175 } 176 177 if len(p.HostAdd) > 0 { 178 p.InfraContainerSpec.HostAdd = p.HostAdd 179 } 180 if len(p.DNSServer) > 0 { 181 var dnsServers []net.IP 182 dnsServers = append(dnsServers, p.DNSServer...) 183 184 p.InfraContainerSpec.DNSServers = dnsServers 185 } 186 if len(p.DNSOption) > 0 { 187 p.InfraContainerSpec.DNSOptions = p.DNSOption 188 } 189 if len(p.DNSSearch) > 0 { 190 p.InfraContainerSpec.DNSSearch = p.DNSSearch 191 } 192 if p.NoManageResolvConf { 193 p.InfraContainerSpec.UseImageResolvConf = true 194 } 195 if len(p.Networks) > 0 { 196 p.InfraContainerSpec.Networks = p.Networks 197 } 198 // deprecated cni networks for api users 199 if len(p.CNINetworks) > 0 { 200 p.InfraContainerSpec.CNINetworks = p.CNINetworks 201 } 202 if p.NoManageHosts { 203 p.InfraContainerSpec.UseImageHosts = p.NoManageHosts 204 } 205 206 if len(p.InfraConmonPidFile) > 0 { 207 p.InfraContainerSpec.ConmonPidFile = p.InfraConmonPidFile 208 } 209 210 p.InfraContainerSpec.Image = p.InfraImage 211 return p.InfraContainerSpec, nil 212 }