github.com/containers/libpod@v1.9.4-0.20220419124438-4284fd425507/cmd/podmanV2/pods/create.go (about) 1 package pods 2 3 import ( 4 "context" 5 "fmt" 6 "os" 7 "strings" 8 9 "github.com/containers/libpod/cmd/podmanV2/common" 10 "github.com/containers/libpod/cmd/podmanV2/parse" 11 "github.com/containers/libpod/cmd/podmanV2/registry" 12 "github.com/containers/libpod/libpod/define" 13 "github.com/containers/libpod/pkg/domain/entities" 14 "github.com/containers/libpod/pkg/errorhandling" 15 "github.com/containers/libpod/pkg/specgen" 16 "github.com/containers/libpod/pkg/util" 17 "github.com/pkg/errors" 18 "github.com/spf13/cobra" 19 ) 20 21 var ( 22 podCreateDescription = `After creating the pod, the pod ID is printed to stdout. 23 24 You can then start it at any time with the podman pod start <pod_id> command. The pod will be created with the initial state 'created'.` 25 26 createCommand = &cobra.Command{ 27 Use: "create", 28 Args: cobra.NoArgs, 29 Short: "Create a new empty pod", 30 Long: podCreateDescription, 31 RunE: create, 32 } 33 ) 34 35 var ( 36 createOptions entities.PodCreateOptions 37 labels, labelFile []string 38 podIDFile string 39 share string 40 ) 41 42 func init() { 43 registry.Commands = append(registry.Commands, registry.CliCommand{ 44 Mode: []entities.EngineMode{entities.ABIMode, entities.TunnelMode}, 45 Command: createCommand, 46 Parent: podCmd, 47 }) 48 flags := createCommand.Flags() 49 flags.SetInterspersed(false) 50 flags.AddFlagSet(common.GetNetFlags()) 51 flags.StringVar(&createOptions.CGroupParent, "cgroup-parent", "", "Set parent cgroup for the pod") 52 flags.BoolVar(&createOptions.Infra, "infra", true, "Create an infra container associated with the pod to share namespaces with") 53 flags.StringVar(&createOptions.InfraImage, "infra-image", define.DefaultInfraImage, "The image of the infra container to associate with the pod") 54 flags.StringVar(&createOptions.InfraCommand, "infra-command", define.DefaultInfraCommand, "The command to run on the infra container when the pod is started") 55 flags.StringSliceVar(&labelFile, "label-file", []string{}, "Read in a line delimited file of labels") 56 flags.StringSliceVarP(&labels, "label", "l", []string{}, "Set metadata on pod (default [])") 57 flags.StringVarP(&createOptions.Name, "name", "n", "", "Assign a name to the pod") 58 flags.StringVarP(&createOptions.Hostname, "hostname", "", "", "Set a hostname to the pod") 59 flags.StringVar(&podIDFile, "pod-id-file", "", "Write the pod ID to the file") 60 flags.StringVar(&share, "share", common.DefaultKernelNamespaces, "A comma delimited list of kernel namespaces the pod will share") 61 } 62 63 func create(cmd *cobra.Command, args []string) error { 64 var ( 65 err error 66 podIdFile *os.File 67 ) 68 createOptions.Labels, err = parse.GetAllLabels(labelFile, labels) 69 if err != nil { 70 return errors.Wrapf(err, "unable to process labels") 71 } 72 73 if !createOptions.Infra && cmd.Flag("share").Changed && share != "none" && share != "" { 74 return errors.Errorf("You cannot share kernel namespaces on the pod level without an infra container") 75 } 76 createOptions.Share = strings.Split(share, ",") 77 if cmd.Flag("pod-id-file").Changed { 78 podIdFile, err = util.OpenExclusiveFile(podIDFile) 79 if err != nil && os.IsExist(err) { 80 return errors.Errorf("pod id file exists. Ensure another pod is not using it or delete %s", podIDFile) 81 } 82 if err != nil { 83 return errors.Errorf("error opening pod-id-file %s", podIDFile) 84 } 85 defer errorhandling.CloseQuiet(podIdFile) 86 defer errorhandling.SyncQuiet(podIdFile) 87 } 88 89 createOptions.Net, err = common.NetFlagsToNetOptions(cmd) 90 if err != nil { 91 return err 92 } 93 netInput, err := cmd.Flags().GetString("network") 94 if err != nil { 95 return err 96 } 97 n := specgen.Namespace{} 98 switch netInput { 99 case "bridge": 100 n.NSMode = specgen.Bridge 101 case "host": 102 n.NSMode = specgen.Host 103 case "slip4netns": 104 n.NSMode = specgen.Slirp 105 default: 106 if strings.HasPrefix(netInput, "container:") { //nolint 107 split := strings.Split(netInput, ":") 108 if len(split) != 2 { 109 return errors.Errorf("invalid network paramater: %q", netInput) 110 } 111 n.NSMode = specgen.FromContainer 112 n.Value = split[1] 113 } else if strings.HasPrefix(netInput, "ns:") { 114 return errors.New("the ns: network option is not supported for pods") 115 } else { 116 n.NSMode = specgen.Bridge 117 createOptions.Net.CNINetworks = strings.Split(netInput, ",") 118 } 119 } 120 if len(createOptions.Net.PublishPorts) > 0 { 121 if !createOptions.Infra { 122 return errors.Errorf("you must have an infra container to publish port bindings to the host") 123 } 124 } 125 126 if !createOptions.Infra { 127 if cmd.Flag("infra-command").Changed { 128 return errors.New("cannot set infra-command without an infra container") 129 } 130 createOptions.InfraCommand = "" 131 if cmd.Flag("infra-image").Changed { 132 return errors.New("cannot set infra-image without an infra container") 133 } 134 createOptions.InfraImage = "" 135 if cmd.Flag("share").Changed { 136 return errors.New("cannot set share namespaces without an infra container") 137 } 138 createOptions.Share = nil 139 } 140 141 response, err := registry.ContainerEngine().PodCreate(context.Background(), createOptions) 142 if err != nil { 143 return err 144 } 145 fmt.Println(response.Id) 146 return nil 147 }