github.com/containers/libpod@v1.9.4-0.20220419124438-4284fd425507/cmd/podman/runlabel.go (about) 1 package main 2 3 import ( 4 "fmt" 5 "io" 6 "os" 7 "strings" 8 9 buildahcli "github.com/containers/buildah/pkg/cli" 10 "github.com/containers/image/v5/types" 11 "github.com/containers/libpod/cmd/podman/cliconfig" 12 "github.com/containers/libpod/cmd/podman/libpodruntime" 13 "github.com/containers/libpod/cmd/podman/shared" 14 "github.com/containers/libpod/libpod/define" 15 "github.com/containers/libpod/libpod/image" 16 "github.com/containers/libpod/pkg/util" 17 "github.com/containers/libpod/utils" 18 "github.com/pkg/errors" 19 "github.com/sirupsen/logrus" 20 "github.com/spf13/cobra" 21 ) 22 23 var ( 24 runlabelCommand cliconfig.RunlabelValues 25 runlabelDescription = ` 26 Executes a command as described by a container image label. 27 ` 28 _runlabelCommand = &cobra.Command{ 29 Use: "runlabel [flags] LABEL IMAGE [ARG...]", 30 Short: "Execute the command described by an image label", 31 Long: runlabelDescription, 32 RunE: func(cmd *cobra.Command, args []string) error { 33 runlabelCommand.InputArgs = args 34 runlabelCommand.GlobalFlags = MainGlobalOpts 35 runlabelCommand.Remote = remoteclient 36 return runlabelCmd(&runlabelCommand) 37 }, 38 Example: `podman container runlabel run imageID 39 podman container runlabel --pull install imageID arg1 arg2 40 podman container runlabel --display run myImage`, 41 } 42 ) 43 44 func init() { 45 runlabelCommand.Command = _runlabelCommand 46 runlabelCommand.SetHelpTemplate(HelpTemplate()) 47 runlabelCommand.SetUsageTemplate(UsageTemplate()) 48 flags := runlabelCommand.Flags() 49 flags.StringVar(&runlabelCommand.Creds, "creds", "", "`Credentials` (USERNAME:PASSWORD) to use for authenticating to a registry") 50 flags.BoolVar(&runlabelCommand.Display, "display", false, "Preview the command that the label would run") 51 flags.BoolVar(&runlabelCommand.Replace, "replace", false, "Replace existing container with a new one from the image") 52 flags.StringVarP(&runlabelCommand.Name, "name", "n", "", "Assign a name to the container") 53 54 flags.StringVar(&runlabelCommand.Opt1, "opt1", "", "Optional parameter to pass for install") 55 flags.StringVar(&runlabelCommand.Opt2, "opt2", "", "Optional parameter to pass for install") 56 flags.StringVar(&runlabelCommand.Opt3, "opt3", "", "Optional parameter to pass for install") 57 markFlagHidden(flags, "opt1") 58 markFlagHidden(flags, "opt2") 59 markFlagHidden(flags, "opt3") 60 flags.BoolP("pull", "p", false, "Pull the image if it does not exist locally prior to executing the label contents") 61 flags.BoolVarP(&runlabelCommand.Quiet, "quiet", "q", false, "Suppress output information when installing images") 62 // Disabled flags for the remote client 63 if !remote { 64 flags.StringVar(&runlabelCommand.Authfile, "authfile", buildahcli.GetDefaultAuthFile(), "Path of the authentication file. Use REGISTRY_AUTH_FILE environment variable to override") 65 flags.StringVar(&runlabelCommand.CertDir, "cert-dir", "", "`Pathname` of a directory containing TLS certificates and keys") 66 flags.StringVar(&runlabelCommand.SignaturePolicy, "signature-policy", "", "`Pathname` of signature policy file (not usually used)") 67 flags.BoolVar(&runlabelCommand.TlsVerify, "tls-verify", true, "Require HTTPS and verify certificates when contacting registries") 68 69 if err := flags.MarkDeprecated("pull", "podman will pull if not found in local storage"); err != nil { 70 logrus.Error("unable to mark pull flag deprecated") 71 } 72 markFlagHidden(flags, "signature-policy") 73 } 74 } 75 76 // installCmd gets the data from the command line and calls installImage 77 // to copy an image from a registry to a local machine 78 func runlabelCmd(c *cliconfig.RunlabelValues) error { 79 var ( 80 imageName string 81 stdErr, stdOut io.Writer 82 stdIn io.Reader 83 extraArgs []string 84 ) 85 86 // Evil images could trick into recursively executing the runlabel 87 // command. Avoid this by setting the "PODMAN_RUNLABEL_NESTED" env 88 // variable when executing a label first. 89 nested := os.Getenv("PODMAN_RUNLABEL_NESTED") 90 if nested == "1" { 91 return fmt.Errorf("nested runlabel calls: runlabels cannot execute the runlabel command") 92 } 93 94 opts := make(map[string]string) 95 runtime, err := libpodruntime.GetRuntime(getContext(), &c.PodmanCommand) 96 if err != nil { 97 return errors.Wrapf(err, "could not get runtime") 98 } 99 defer runtime.DeferredShutdown(false) 100 101 if c.Authfile != "" { 102 if _, err := os.Stat(c.Authfile); err != nil { 103 return errors.Wrapf(err, "error getting authfile %s", c.Authfile) 104 } 105 } 106 107 args := c.InputArgs 108 if len(args) < 2 { 109 return errors.Errorf("the runlabel command requires at least 2 arguments: LABEL IMAGE") 110 } 111 if c.Display && c.Quiet { 112 return errors.Errorf("the display and quiet flags cannot be used together.") 113 } 114 115 if len(args) > 2 { 116 extraArgs = args[2:] 117 } 118 label := args[0] 119 120 runlabelImage := args[1] 121 122 if c.Flag("opt1").Changed { 123 opts["opt1"] = c.Opt1 124 } 125 126 if c.Flag("opt2").Changed { 127 opts["opt2"] = c.Opt2 128 } 129 if c.Flag("opt3").Changed { 130 opts["opt3"] = c.Opt3 131 } 132 133 ctx := getContext() 134 135 stdErr = os.Stderr 136 stdOut = os.Stdout 137 stdIn = os.Stdin 138 139 if c.Quiet { 140 stdErr = nil 141 stdOut = nil 142 stdIn = nil 143 } 144 145 dockerRegistryOptions := image.DockerRegistryOptions{ 146 DockerCertPath: c.CertDir, 147 } 148 if c.Flag("tls-verify").Changed { 149 dockerRegistryOptions.DockerInsecureSkipTLSVerify = types.NewOptionalBool(!c.TlsVerify) 150 } 151 152 runLabel, imageName, err := shared.GetRunlabel(label, runlabelImage, ctx, runtime, true, c.Creds, dockerRegistryOptions, c.Authfile, c.SignaturePolicy, stdOut) 153 if err != nil { 154 return err 155 } 156 if runLabel == "" { 157 return errors.Errorf("%s does not have a label of %s", runlabelImage, label) 158 } 159 160 globalOpts := util.GetGlobalOpts(c) 161 cmd, env, err := shared.GenerateRunlabelCommand(runLabel, imageName, c.Name, opts, extraArgs, globalOpts) 162 if err != nil { 163 return err 164 } 165 if !c.Quiet { 166 fmt.Printf("command: %s\n", strings.Join(append([]string{os.Args[0]}, cmd[1:]...), " ")) 167 if c.Display { 168 return nil 169 } 170 } 171 172 // If container already exists && --replace given -- Nuke it 173 if c.Replace { 174 for i, entry := range cmd { 175 if entry == "--name" { 176 name := cmd[i+1] 177 ctr, err := runtime.LookupContainer(name) 178 if err != nil { 179 if errors.Cause(err) != define.ErrNoSuchCtr { 180 logrus.Debugf("Error occurred searching for container %s: %s", name, err.Error()) 181 return err 182 } 183 } else { 184 logrus.Debugf("Runlabel --replace option given. Container %s will be deleted. The new container will be named %s", ctr.ID(), name) 185 if err := runtime.RemoveContainer(ctx, ctr, true, false); err != nil { 186 return err 187 } 188 } 189 break 190 } 191 } 192 } 193 194 return utils.ExecCmdWithStdStreams(stdIn, stdOut, stdErr, env, cmd[0], cmd[1:]...) 195 }