diff options
45 files changed, 272 insertions, 94 deletions
@@ -91,9 +91,9 @@ in the [API.md](https://github.com/containers/libpod/blob/master/API.md) file in [func PausePod(name: string) string](#PausePod) -[func PullImage(name: string, certDir: string, creds: string, signaturePolicy: string, tlsVerify: bool) string](#PullImage) +[func PullImage(name: string, certDir: string, creds: string, signaturePolicy: string, tlsVerify: ?bool) string](#PullImage) -[func PushImage(name: string, tag: string, tlsverify: bool, signaturePolicy: string, creds: string, certDir: string, compress: bool, format: string, removeSignatures: bool, signBy: string) MoreResponse](#PushImage) +[func PushImage(name: string, tag: string, tlsverify: ?bool, signaturePolicy: string, creds: string, certDir: string, compress: bool, format: string, removeSignatures: bool, signBy: string) MoreResponse](#PushImage) [func ReceiveFile(path: string, delete: bool) int](#ReceiveFile) @@ -107,7 +107,7 @@ in the [API.md](https://github.com/containers/libpod/blob/master/API.md) file in [func RestartPod(name: string) string](#RestartPod) -[func SearchImages(query: string, limit: ) ImageSearchResult](#SearchImages) +[func SearchImages(quety: string, limit: int, tlsVerify: ?bool) ImageSearchResult](#SearchImages) [func SendFile(type: string, length: int) string](#SendFile) diff --git a/cmd/podman/attach.go b/cmd/podman/attach.go index ed175bdf4..7480bd6a2 100644 --- a/cmd/podman/attach.go +++ b/cmd/podman/attach.go @@ -22,7 +22,9 @@ var ( attachCommand.GlobalFlags = MainGlobalOpts return attachCmd(&attachCommand) }, - Example: "", + Example: `podman attach ctrID + podman attach 1234 + podman attach --no-stdin foobar`, } ) diff --git a/cmd/podman/checkpoint.go b/cmd/podman/checkpoint.go index aa4034ccd..3484e8957 100644 --- a/cmd/podman/checkpoint.go +++ b/cmd/podman/checkpoint.go @@ -29,7 +29,9 @@ var ( checkpointCommand.GlobalFlags = MainGlobalOpts return checkpointCmd(&checkpointCommand) }, - Example: "CONTAINER-NAME [CONTAINER-NAME ...]", + Example: `podman checkpoint --keep ctrID + podman checkpoint --all + podman checkpoint --leave-running --latest`, } ) diff --git a/cmd/podman/cliconfig/config.go b/cmd/podman/cliconfig/config.go index f5d6a8685..9c9be3618 100644 --- a/cmd/podman/cliconfig/config.go +++ b/cmd/podman/cliconfig/config.go @@ -340,6 +340,7 @@ type PsValues struct { type PullValues struct { PodmanCommand + AllTags bool Authfile string CertDir string Creds string diff --git a/cmd/podman/commit.go b/cmd/podman/commit.go index dc53e68d1..d8ced0e36 100644 --- a/cmd/podman/commit.go +++ b/cmd/podman/commit.go @@ -33,7 +33,9 @@ var ( commitCommand.GlobalFlags = MainGlobalOpts return commitCmd(&commitCommand) }, - Example: "CONTAINER [REPOSITORY[:TAG]]", + Example: `podman commit -q --message "committing container to image" reverent_golick image-commited + podman commit -q --author "firstName lastName" reverent_golick image-commited + podman commit -q --pause=false containerID image-commited`, } ) diff --git a/cmd/podman/common.go b/cmd/podman/common.go index 417e938b7..ec755c4a8 100644 --- a/cmd/podman/common.go +++ b/cmd/podman/common.go @@ -514,7 +514,7 @@ Aliases: {{.NameAndAliases}}{{end}}{{if .HasExample}} Examples: -{{.Example}}{{end}}{{if .HasAvailableSubCommands}} + {{.Example}}{{end}}{{if .HasAvailableSubCommands}} Available Commands:{{range .Commands}}{{if (or .IsAvailableCommand (eq .Name "help"))}} {{rpad .Name .NamePadding }} {{.Short}}{{end}}{{end}}{{end}}{{if .HasAvailableLocalFlags}} diff --git a/cmd/podman/create.go b/cmd/podman/create.go index 392163424..e7efe7502 100644 --- a/cmd/podman/create.go +++ b/cmd/podman/create.go @@ -49,7 +49,9 @@ var ( createCommand.GlobalFlags = MainGlobalOpts return createCmd(&createCommand) }, - Example: "IMAGE [COMMAND [ARG...]]", + Example: `podman create alpine ls + podman create --annotation HELLO=WORLD alpine ls + podman create -t -i --name myctr alpine ls`, } defaultEnvVariables = map[string]string{ @@ -397,9 +399,6 @@ func parseCreateOpts(ctx context.Context, c *cliconfig.PodmanCommand, runtime *l tty := c.Bool("tty") - if c.Bool("detach") && c.Bool("rm") { - return nil, errors.Errorf("--rm and --detach cannot be specified together") - } if c.Flag("cpu-period").Changed && c.Flag("cpus").Changed { return nil, errors.Errorf("--cpu-period and --cpus cannot be set together") } diff --git a/cmd/podman/diff.go b/cmd/podman/diff.go index 7d4cc1b58..e2d258ad4 100644 --- a/cmd/podman/diff.go +++ b/cmd/podman/diff.go @@ -46,7 +46,9 @@ var ( diffCommand.GlobalFlags = MainGlobalOpts return diffCmd(&diffCommand) }, - Example: "ID-NAME", + Example: `podman diff imageID + podman diff ctrID + podman diff --format json redis:alpine`, } ) diff --git a/cmd/podman/exec.go b/cmd/podman/exec.go index 74808768e..9599be528 100644 --- a/cmd/podman/exec.go +++ b/cmd/podman/exec.go @@ -29,7 +29,9 @@ var ( execCommand.GlobalFlags = MainGlobalOpts return execCmd(&execCommand) }, - Example: "CONTAINER-NAME", + Example: `podman exec -it ctrID ls + podman exec -it -w /tmp myCtr pwd + podman exec --user root ctrID ls`, } ) diff --git a/cmd/podman/exists.go b/cmd/podman/exists.go index 15ddaec06..7645bb716 100644 --- a/cmd/podman/exists.go +++ b/cmd/podman/exists.go @@ -41,7 +41,7 @@ var ( imageExistsCommand.GlobalFlags = MainGlobalOpts return imageExistsCmd(&imageExistsCommand) }, - Example: "IMAGE-NAME", + Example: `podman image exists imageID`, } _containerExistsCommand = &cobra.Command{ @@ -54,7 +54,7 @@ var ( return containerExistsCmd(&containerExistsCommand) }, - Example: "CONTAINER-NAME", + Example: `podman container exists containerID`, } _podExistsCommand = &cobra.Command{ @@ -66,7 +66,7 @@ var ( podExistsCommand.GlobalFlags = MainGlobalOpts return podExistsCmd(&podExistsCommand) }, - Example: "POD-NAME", + Example: `podman pod exists podID`, } ) diff --git a/cmd/podman/export.go b/cmd/podman/export.go index 2ce8186a1..a593a4753 100644 --- a/cmd/podman/export.go +++ b/cmd/podman/export.go @@ -25,7 +25,8 @@ var ( exportCommand.GlobalFlags = MainGlobalOpts return exportCmd(&exportCommand) }, - Example: "CONTAINER", + Example: `podman export ctrID > myCtr.tar + podman export --output="myCtr.tar" ctrID`, } ) diff --git a/cmd/podman/import.go b/cmd/podman/import.go index 32f79757b..053408ff3 100644 --- a/cmd/podman/import.go +++ b/cmd/podman/import.go @@ -25,7 +25,9 @@ var ( importCommand.GlobalFlags = MainGlobalOpts return importCmd(&importCommand) }, - Example: "TARBALL [REFERENCE]", + Example: `podman import http://example.com/ctr.tar url-image + cat ctr.tar | podman -q import --message "importing the ctr.tar tarball" - image-imported + cat ctr.tar | podman import -`, } ) diff --git a/cmd/podman/info.go b/cmd/podman/info.go index d60b8f84f..06dbbd748 100644 --- a/cmd/podman/info.go +++ b/cmd/podman/info.go @@ -26,7 +26,7 @@ var ( infoCommand.GlobalFlags = MainGlobalOpts return infoCmd(&infoCommand) }, - Example: "", + Example: `podman info`, } ) diff --git a/cmd/podman/inspect.go b/cmd/podman/inspect.go index a29eb790e..a1f3ef81f 100644 --- a/cmd/podman/inspect.go +++ b/cmd/podman/inspect.go @@ -34,7 +34,9 @@ var ( inspectCommand.GlobalFlags = MainGlobalOpts return inspectCmd(&inspectCommand) }, - Example: "CONTAINER-OR-IMAGE [CONTAINER-OR-IMAGE]...", + Example: `podman inspect alpine + podman inspect --format "imageId: {{.Id}} size: {{.Size}}" alpine + podman inspect --format "image: {{.ImageName}} driver: {{.Driver}}" myctr`, } ) diff --git a/cmd/podman/kill.go b/cmd/podman/kill.go index d922cf721..1be4fa959 100644 --- a/cmd/podman/kill.go +++ b/cmd/podman/kill.go @@ -28,7 +28,9 @@ var ( killCommand.GlobalFlags = MainGlobalOpts return killCmd(&killCommand) }, - Example: "CONTAINER-NAME [CONTAINER-NAME ...]", + Example: `podman kill mywebserver + podman kill 860a4b23 + podman kill --signal TERM ctrID`, } ) diff --git a/cmd/podman/libpodruntime/runtime.go b/cmd/podman/libpodruntime/runtime.go index 60acd1f5b..0b9568b8d 100644 --- a/cmd/podman/libpodruntime/runtime.go +++ b/cmd/podman/libpodruntime/runtime.go @@ -48,7 +48,7 @@ func GetRuntime(c *cliconfig.PodmanCommand) (*libpod.Runtime, error) { if c.Flags().Changed("storage-driver") { storageOpts.GraphDriverName = c.GlobalFlags.StorageDriver } - if c.Flags().Changed("storage-opt") { + if len(c.GlobalFlags.StorageOpts) > 0 { storageOpts.GraphDriverOptions = c.GlobalFlags.StorageOpts } diff --git a/cmd/podman/login.go b/cmd/podman/login.go index 0ae1ed7d0..b02a4b3f9 100644 --- a/cmd/podman/login.go +++ b/cmd/podman/login.go @@ -29,7 +29,9 @@ var ( loginCommand.GlobalFlags = MainGlobalOpts return loginCmd(&loginCommand) }, - Example: "REGISTRY", + Example: `podman login -u testuser -p testpassword localhost:5000 + podman login --authfile authdir/myauths.json quay.io + podman login -u testuser -p testpassword localhost:5000`, } ) diff --git a/cmd/podman/logout.go b/cmd/podman/logout.go index 5fecf814e..4108887f0 100644 --- a/cmd/podman/logout.go +++ b/cmd/podman/logout.go @@ -22,7 +22,9 @@ var ( logoutCommand.GlobalFlags = MainGlobalOpts return logoutCmd(&logoutCommand) }, - Example: "REGISTRY", + Example: `podman logout docker.io + podman logout --authfile authdir/myauths.json docker.io + podman logout --all`, } ) diff --git a/cmd/podman/pause.go b/cmd/podman/pause.go index a840cbe49..94bb0edfe 100644 --- a/cmd/podman/pause.go +++ b/cmd/podman/pause.go @@ -28,7 +28,9 @@ var ( pauseCommand.GlobalFlags = MainGlobalOpts return pauseCmd(&pauseCommand) }, - Example: "CONTAINER-NAME [CONTAINER-NAME ...]", + Example: `podman pause mywebserver + podman pause 860a4b23 + podman stop -a`, } ) diff --git a/cmd/podman/pod_inspect.go b/cmd/podman/pod_inspect.go index a0b691642..58b15328e 100644 --- a/cmd/podman/pod_inspect.go +++ b/cmd/podman/pod_inspect.go @@ -23,7 +23,7 @@ var ( podInspectCommand.GlobalFlags = MainGlobalOpts return podInspectCmd(&podInspectCommand) }, - Example: "[POD_NAME_OR_ID]", + Example: `podman pod inspect podID`, } ) diff --git a/cmd/podman/pod_rm.go b/cmd/podman/pod_rm.go index 389f44a20..54cee2a50 100644 --- a/cmd/podman/pod_rm.go +++ b/cmd/podman/pod_rm.go @@ -26,7 +26,9 @@ If --force is specified, all containers will be stopped, then removed. podRmCommand.GlobalFlags = MainGlobalOpts return podRmCmd(&podRmCommand) }, - Example: "[POD ...]", + Example: `podman pod rm mywebserverpod + podman pod rm -f 860a4b23 + podman pod rm -f -a`, } ) diff --git a/cmd/podman/pod_start.go b/cmd/podman/pod_start.go index 829fe2107..d093c51cf 100644 --- a/cmd/podman/pod_start.go +++ b/cmd/podman/pod_start.go @@ -26,7 +26,9 @@ var ( podStartCommand.GlobalFlags = MainGlobalOpts return podStartCmd(&podStartCommand) }, - Example: "POD-NAME [POD-NAME ...]", + Example: `podman pod start podID + podman pod start --latest + podman pod start --all`, } ) diff --git a/cmd/podman/pod_stats.go b/cmd/podman/pod_stats.go index 7afab6be9..b1779532f 100644 --- a/cmd/podman/pod_stats.go +++ b/cmd/podman/pod_stats.go @@ -32,7 +32,9 @@ var ( podStatsCommand.GlobalFlags = MainGlobalOpts return podStatsCmd(&podStatsCommand) }, - Example: "[POD_NAME_OR_ID]", + Example: `podman stats -a --no-stream + podman stats --no-reset ctrID + podman stats --no-stream --format "table {{.ID}} {{.Name}} {{.MemUsage}}" ctrID`, } ) diff --git a/cmd/podman/pod_top.go b/cmd/podman/pod_top.go index 411c782bd..790118496 100644 --- a/cmd/podman/pod_top.go +++ b/cmd/podman/pod_top.go @@ -33,7 +33,9 @@ the latest pod. podTopCommand.GlobalFlags = MainGlobalOpts return podTopCmd(&podTopCommand) }, - Example: "POD-NAME [format descriptors]", + Example: `podman top ctrID + podman top --latest + podman top --latest pid seccomp args %C`, } ) diff --git a/cmd/podman/ps.go b/cmd/podman/ps.go index 949f78a34..482e423b7 100644 --- a/cmd/podman/ps.go +++ b/cmd/podman/ps.go @@ -166,7 +166,9 @@ var ( psCommand.GlobalFlags = MainGlobalOpts return psCmd(&psCommand) }, - Example: "", + Example: `podman ps -a + podman ps -a --format "{{.ID}} {{.Image}} {{.Labels}} {{.Mounts}}" + podman ps --size --sort names`, } ) diff --git a/cmd/podman/pull.go b/cmd/podman/pull.go index 6d9d1a278..6e060d6f5 100644 --- a/cmd/podman/pull.go +++ b/cmd/podman/pull.go @@ -6,11 +6,13 @@ import ( "os" "strings" + "github.com/containers/image/docker" dockerarchive "github.com/containers/image/docker/archive" "github.com/containers/image/transports/alltransports" "github.com/containers/image/types" "github.com/containers/libpod/cmd/podman/cliconfig" "github.com/containers/libpod/libpod/adapter" + "github.com/containers/libpod/libpod/common" image2 "github.com/containers/libpod/libpod/image" "github.com/containers/libpod/pkg/util" "github.com/pkg/errors" @@ -42,6 +44,7 @@ func init() { pullCommand.Command = _pullCommand pullCommand.SetUsageTemplate(UsageTemplate()) flags := pullCommand.Flags() + flags.BoolVar(&pullCommand.AllTags, "all-tags", false, "All tagged images inthe repository will be pulled") flags.StringVar(&pullCommand.Authfile, "authfile", "", "Path of the authentication file. Default is ${XDG_RUNTIME_DIR}/containers/auth.json. Use REGISTRY_AUTH_FILE environment variable to override") flags.StringVar(&pullCommand.CertDir, "cert-dir", "", "`Pathname` of a directory containing TLS certificates and keys") flags.StringVar(&pullCommand.Creds, "creds", "", "`Credentials` (USERNAME:PASSWORD) to use for authenticating to a registry") @@ -69,6 +72,15 @@ func pullCmd(c *cliconfig.PullValues) error { logrus.Errorf("too many arguments. Requires exactly 1") return nil } + + arr := strings.SplitN(args[0], ":", 2) + if len(arr) == 2 { + if c.Bool("all-tags") { + logrus.Errorf("tag can't be used with --all-tags") + return nil + } + } + ctx := getContext() image := args[0] var registryCreds *types.DockerAuthConfig @@ -83,7 +95,6 @@ func pullCmd(c *cliconfig.PullValues) error { var ( writer io.Writer - imgID string ) if !c.Quiet { writer = os.Stderr @@ -107,18 +118,58 @@ func pullCmd(c *cliconfig.PullValues) error { if err != nil { return errors.Wrapf(err, "error pulling image from %q", image) } - imgID = newImage[0].ID() + fmt.Println(newImage[0].ID()) } else { - authfile := getAuthFile(c.Authfile) - newImage, err := runtime.New(getContext(), image, c.SignaturePolicy, authfile, writer, &dockerRegistryOptions, image2.SigningOptions{}, true, nil) + authfile := getAuthFile(c.String("authfile")) + spec := image + systemContext := common.GetSystemContext("", authfile, false) + srcRef, err := alltransports.ParseImageName(spec) if err != nil { + dockerTransport := "docker://" + logrus.Debugf("error parsing image name %q, trying with transport %q: %v", spec, dockerTransport, err) + spec = dockerTransport + spec + srcRef2, err2 := alltransports.ParseImageName(spec) + if err2 != nil { + return errors.Wrapf(err2, "error parsing image name %q", image) + } + srcRef = srcRef2 + } + var names []string + if c.Bool("all-tags") { + if srcRef.DockerReference() == nil { + return errors.New("Non-docker transport is currently not supported") + } + tags, err := docker.GetRepositoryTags(ctx, systemContext, srcRef) + if err != nil { + return errors.Wrapf(err, "error getting repository tags") + } + for _, tag := range tags { + name := spec + ":" + tag + names = append(names, name) + } + } else { + names = append(names, spec) + } + var foundIDs []string + foundImage := true + for _, name := range names { + newImage, err := runtime.New(getContext(), name, c.String("signature-policy"), authfile, writer, &dockerRegistryOptions, image2.SigningOptions{}, true, nil) + if err != nil { + println(errors.Wrapf(err, "error pulling image %q", name)) + foundImage = false + continue + } + foundIDs = append(foundIDs, newImage.ID()) + } + if len(names) == 1 && !foundImage { return errors.Wrapf(err, "error pulling image %q", image) } - imgID = newImage.ID() - } - - // Intentionally choosing to ignore if there is an error because - // outputting the image ID is a NTH and not integral to the pull - fmt.Println(imgID) + if len(names) > 1 { + fmt.Println("Pulled Images:") + } + for _, id := range foundIDs { + fmt.Println(id) + } + } // end else if strings.HasPrefix(image, dockerarchive.Transport.Name()+":") return nil } diff --git a/cmd/podman/sign.go b/cmd/podman/sign.go index ac0d985f5..6e8f9ee95 100644 --- a/cmd/podman/sign.go +++ b/cmd/podman/sign.go @@ -32,7 +32,8 @@ var ( signCommand.GlobalFlags = MainGlobalOpts return signCmd(&signCommand) }, - Example: "IMAGE-NAME [IMAGE-NAME ...]", + Example: `podman sign --sign-by mykey imageID + podman sign --sign-by mykey --directory ./mykeydir imageID`, } ) diff --git a/cmd/podman/start.go b/cmd/podman/start.go index 3a606d662..1f671aefd 100644 --- a/cmd/podman/start.go +++ b/cmd/podman/start.go @@ -1,14 +1,12 @@ package main import ( - "encoding/json" "fmt" "os" "github.com/containers/libpod/cmd/podman/cliconfig" "github.com/containers/libpod/cmd/podman/libpodruntime" "github.com/containers/libpod/libpod" - cc "github.com/containers/libpod/pkg/spec" "github.com/pkg/errors" "github.com/sirupsen/logrus" "github.com/spf13/cobra" @@ -124,12 +122,22 @@ func startCmd(c *cliconfig.StartValues) error { } if ecode, err := ctr.Wait(); err != nil { - logrus.Errorf("unable to get exit code of container %s: %q", ctr.ID(), err) + if errors.Cause(err) == libpod.ErrNoSuchCtr { + // The container may have been removed + // Go looking for an exit file + ctrExitCode, err := readExitFile(runtime.GetConfig().TmpDir, ctr.ID()) + if err != nil { + logrus.Errorf("Cannot get exit code: %v", err) + exitCode = 127 + } else { + exitCode = ctrExitCode + } + } } else { exitCode = int(ecode) } - return ctr.Cleanup(ctx) + return nil } if ctrRunning { fmt.Println(ctr.ID()) @@ -137,18 +145,6 @@ func startCmd(c *cliconfig.StartValues) error { } // Handle non-attach start if err := ctr.Start(ctx); err != nil { - var createArtifact cc.CreateConfig - artifact, artifactErr := ctr.GetArtifact("create-config") - if artifactErr == nil { - if jsonErr := json.Unmarshal(artifact, &createArtifact); jsonErr != nil { - logrus.Errorf("unable to detect if container %s should be deleted", ctr.ID()) - } - if createArtifact.Rm { - if rmErr := runtime.RemoveContainer(ctx, ctr, true, false); rmErr != nil { - logrus.Errorf("unable to remove container %s after it failed to start", ctr.ID()) - } - } - } if lastError != nil { fmt.Fprintln(os.Stderr, lastError) } diff --git a/cmd/podman/trust_set_show.go b/cmd/podman/trust_set_show.go index f3d1cadce..0a4783d0a 100644 --- a/cmd/podman/trust_set_show.go +++ b/cmd/podman/trust_set_show.go @@ -26,7 +26,7 @@ var ( Use: "set", Short: "Set default trust policy or a new trust policy for a registry", Long: setTrustDescription, - Example: "default | REGISTRY[/REPOSITORY]", + Example: "", RunE: func(cmd *cobra.Command, args []string) error { setTrustCommand.InputArgs = args setTrustCommand.GlobalFlags = MainGlobalOpts diff --git a/cmd/podman/umount.go b/cmd/podman/umount.go index 20ea410c2..afa0e86db 100644 --- a/cmd/podman/umount.go +++ b/cmd/podman/umount.go @@ -31,7 +31,9 @@ An unmount can be forced with the --force flag. umountCommand.GlobalFlags = MainGlobalOpts return umountCmd(&umountCommand) }, - Example: "CONTAINER-NAME-OR-ID", + Example: `podman umount ctrID + podman umount ctrID1 ctrID2 ctrID3 + podman umount --all`, } ) diff --git a/cmd/podman/unpause.go b/cmd/podman/unpause.go index c8f85cfd3..efd9a20a3 100644 --- a/cmd/podman/unpause.go +++ b/cmd/podman/unpause.go @@ -29,7 +29,8 @@ var ( unpauseCommand.GlobalFlags = MainGlobalOpts return unpauseCmd(&unpauseCommand) }, - Example: "CONTAINER-NAME [CONTAINER-NAME ...]", + Example: `podman unpause ctrID + podman unpause --all`, } ) diff --git a/cmd/podman/varlink/io.podman.varlink b/cmd/podman/varlink/io.podman.varlink index d6d9936f2..697d9ed90 100644 --- a/cmd/podman/varlink/io.podman.varlink +++ b/cmd/podman/varlink/io.podman.varlink @@ -412,7 +412,7 @@ type Runlabel( name: string, pull: bool, signaturePolicyPath: string, - tlsVerify: bool, + tlsVerify: ?bool, label: string, extraArgs: []string, opts: [string]string @@ -658,7 +658,7 @@ method HistoryImage(name: string) -> (history: []ImageHistory) # and a boolean as to whether tls-verify should be used (with false disabling TLS, not affecting the default behavior). # It will return an [ImageNotFound](#ImageNotFound) error if # the image cannot be found in local storage; otherwise it will return a [MoreResponse](#MoreResponse) -method PushImage(name: string, tag: string, tlsverify: bool, signaturePolicy: string, creds: string, certDir: string, compress: bool, format: string, removeSignatures: bool, signBy: string) -> (reply: MoreResponse) +method PushImage(name: string, tag: string, tlsverify: ?bool, signaturePolicy: string, creds: string, certDir: string, compress: bool, format: string, removeSignatures: bool, signBy: string) -> (reply: MoreResponse) # TagImage takes the name or ID of an image in local storage as well as the desired tag name. If the image cannot # be found, an [ImageNotFound](#ImageNotFound) error will be returned; otherwise, the ID of the image is returned on success. @@ -679,7 +679,7 @@ method RemoveImage(name: string, force: bool) -> (image: string) # SearchImages searches available registries for images that contain the # contents of "query" in their name. If "limit" is given, limits the amount of # search results per registry. -method SearchImages(query: string, limit: ?int) -> (results: []ImageSearchResult) +method SearchImages(query: string, limit: ?int, tlsVerify: ?bool) -> (results: []ImageSearchResult) # DeleteUnusedImages deletes any images not associated with a container. The IDs of the deleted images are returned # in a string array. @@ -726,7 +726,7 @@ method ExportImage(name: string, destination: string, compress: bool, tags: []st # "id": "426866d6fa419873f97e5cbd320eeb22778244c1dfffa01c944db3114f55772e" # } # ~~~ -method PullImage(name: string, certDir: string, creds: string, signaturePolicy: string, tlsVerify: bool) -> (id: string) +method PullImage(name: string, certDir: string, creds: string, signaturePolicy: string, tlsVerify: ?bool) -> (id: string) # CreatePod creates a new empty pod. It uses a [PodCreate](#PodCreate) type for input. # On success, the ID of the newly created pod will be returned. diff --git a/cmd/podman/volume_create.go b/cmd/podman/volume_create.go index fe5d69e0b..6c8a78922 100644 --- a/cmd/podman/volume_create.go +++ b/cmd/podman/volume_create.go @@ -26,7 +26,9 @@ be created at.` volumeCreateCommand.GlobalFlags = MainGlobalOpts return volumeCreateCmd(&volumeCreateCommand) }, - Example: "[VOLUME-NAME]", + Example: `podman volume create myvol + podman volume create + podman volume create --label foo=bar myvol`, } ) diff --git a/cmd/podman/volume_inspect.go b/cmd/podman/volume_inspect.go index 928ef37d0..3b4ba51d5 100644 --- a/cmd/podman/volume_inspect.go +++ b/cmd/podman/volume_inspect.go @@ -24,7 +24,9 @@ from JSON to a Go template. volumeInspectCommand.GlobalFlags = MainGlobalOpts return volumeInspectCmd(&volumeInspectCommand) }, - Example: "[VOLUME-NAME ...]", + Example: `podman volume inspect myvol + podman volume inspect --all + podman volume inspect --format "{{.Driver}} {{.Scope}}" myvol`, } ) diff --git a/docs/libpod.conf.5.md b/docs/libpod.conf.5.md index 98eb5bece..0c11e2013 100644 --- a/docs/libpod.conf.5.md +++ b/docs/libpod.conf.5.md @@ -12,8 +12,11 @@ libpod to manage containers. **image_default_transport**="" Default transport method for pulling and pushing images -**runtime_path**="" - Paths to search for a valid OCI runtime binary +**runtime**="" + Default OCI runtime to use if nothing is specified + +**runtimes** + For each OCI runtime, specify a list of paths to look for. The first one found is used. **conmon_path**="" Paths to search for the Conmon container manager binary diff --git a/docs/podman-commit.1.md b/docs/podman-commit.1.md index 79e14aba6..acde51859 100644 --- a/docs/podman-commit.1.md +++ b/docs/podman-commit.1.md @@ -76,7 +76,7 @@ e3ce4d93051ceea088d1c242624d659be32cf1667ef62f1d16d6b60193e2c7a8 ``` ``` -$ podman commit -q --pause=false reverent_golick image-commited +$ podman commit -q --pause=false containerID image-commited e3ce4d93051ceea088d1c242624d659be32cf1667ef62f1d16d6b60193e2c7a8 ``` diff --git a/docs/podman-create.1.md b/docs/podman-create.1.md index 2dffaff3b..342ef59c3 100644 --- a/docs/podman-create.1.md +++ b/docs/podman-create.1.md @@ -783,6 +783,24 @@ can override the working directory by using the **-w** option. ## EXAMPLES +### Create a container using a local image + +``` +$ podman create alpine ls +``` + +### Create a container using a local image and annotate it + +``` +$ podman create --annotation HELLO=WORLD alpine ls +``` + +### Create a container using a local image, allocating a pseudo-TTY, keeping stdin open and name it myctr + +``` + podman create -t -i --name myctr alpine ls +``` + ### Set UID/GID mapping in a new user namespace Running a container in a new user namespace requires a mapping of diff --git a/docs/podman-exec.1.md b/docs/podman-exec.1.md index 77317b0ca..6f464a8f2 100644 --- a/docs/podman-exec.1.md +++ b/docs/podman-exec.1.md @@ -4,7 +4,7 @@ podman\-exec - Execute a command in a running container ## SYNOPSIS -**podman exec** *container* [*options*] [*command* [*arg* ...]] +**podman exec** [*options*] *container* [*command* [*arg* ...]] ## DESCRIPTION **podman exec** executes a command in a running container. @@ -46,6 +46,12 @@ The default working directory for running binaries within a container is the roo The image developer can set a different default with the WORKDIR instruction, which can be overridden when creating the container. +## EXAMPLES + +$ podman exec -it ctrID ls +$ podman exec -it -w /tmp myCtr pwd +$ podman exec --user root ctrID ls + ## SEE ALSO podman(1), podman-run(1) diff --git a/docs/podman-pull.1.md b/docs/podman-pull.1.md index 2196e251e..bce11b096 100644 --- a/docs/podman-pull.1.md +++ b/docs/podman-pull.1.md @@ -45,6 +45,10 @@ Image stored in local container/storage ## OPTIONS +**--all-tags, a** + +All tagged images in the repository will be pulled. + **--authfile** Path of the authentication file. Default is ${XDG_RUNTIME\_DIR}/containers/auth.json, which is set using `podman login`. diff --git a/libpod.conf b/libpod.conf index acd6c8982..c4e7dc628 100644 --- a/libpod.conf +++ b/libpod.conf @@ -88,6 +88,8 @@ pause_command = "/pause" # Default libpod support for container labeling # label=true +runtime = "runc" + # Paths to look for a valid OCI runtime (runc, runv, etc) [runtimes] runc = [ diff --git a/libpod/adapter/runtime_remote.go b/libpod/adapter/runtime_remote.go index d0a3c5b1f..f63b5875d 100644 --- a/libpod/adapter/runtime_remote.go +++ b/libpod/adapter/runtime_remote.go @@ -163,7 +163,8 @@ func (r *LocalRuntime) NewImageFromLocal(name string) (*ContainerImage, error) { func (r *LocalRuntime) LoadFromArchiveReference(ctx context.Context, srcRef types.ImageReference, signaturePolicyPath string, writer io.Writer) ([]*ContainerImage, error) { // TODO We need to find a way to leak certDir, creds, and the tlsverify into this function, normally this would // come from cli options but we don't want want those in here either. - imageID, err := iopodman.PullImage().Call(r.Conn, srcRef.DockerReference().String(), "", "", signaturePolicyPath, true) + tlsverify := true + imageID, err := iopodman.PullImage().Call(r.Conn, srcRef.DockerReference().String(), "", "", signaturePolicyPath, &tlsverify) if err != nil { return nil, err } @@ -179,15 +180,21 @@ func (r *LocalRuntime) New(ctx context.Context, name, signaturePolicyPath, authf if label != nil { return nil, errors.New("the remote client function does not support checking a remote image for a label") } - // TODO Creds needs to be figured out here too, like above - tlsBool := dockeroptions.DockerInsecureSkipTLSVerify - // Remember SkipTlsVerify is the opposite of tlsverify - // If tlsBook is true or undefined, we do not skip - SkipTlsVerify := false - if tlsBool == types.OptionalBoolFalse { - SkipTlsVerify = true + var ( + tlsVerify bool + tlsVerifyPtr *bool + ) + if dockeroptions.DockerInsecureSkipTLSVerify == types.OptionalBoolFalse { + tlsVerify = true + tlsVerifyPtr = &tlsVerify + + } + if dockeroptions.DockerInsecureSkipTLSVerify == types.OptionalBoolTrue { + tlsVerify = false + tlsVerifyPtr = &tlsVerify } - imageID, err := iopodman.PullImage().Call(r.Conn, name, dockeroptions.DockerCertPath, "", signaturePolicyPath, SkipTlsVerify) + + imageID, err := iopodman.PullImage().Call(r.Conn, name, dockeroptions.DockerCertPath, "", signaturePolicyPath, tlsVerifyPtr) if err != nil { return nil, err } @@ -577,10 +584,19 @@ func (r *LocalRuntime) RemoveVolumes(ctx context.Context, c *cliconfig.VolumeRmV func (r *LocalRuntime) Push(ctx context.Context, srcName, destination, manifestMIMEType, authfile, signaturePolicyPath string, writer io.Writer, forceCompress bool, signingOptions image.SigningOptions, dockerRegistryOptions *image.DockerRegistryOptions, additionalDockerArchiveTags []reference.NamedTagged) error { - tls := true + var ( + tls *bool + tlsVerify bool + ) if dockerRegistryOptions.DockerInsecureSkipTLSVerify == types.OptionalBoolTrue { - tls = false + tlsVerify = false + tls = &tlsVerify } + if dockerRegistryOptions.DockerInsecureSkipTLSVerify == types.OptionalBoolFalse { + tlsVerify = true + tls = &tlsVerify + } + reply, err := iopodman.PushImage().Send(r.Conn, varlink.More, srcName, destination, tls, signaturePolicyPath, "", dockerRegistryOptions.DockerCertPath, forceCompress, manifestMIMEType, signingOptions.RemoveSignatures, signingOptions.SignBy) if err != nil { return err diff --git a/libpod/runtime.go b/libpod/runtime.go index c975f628b..4f5d1e292 100644 --- a/libpod/runtime.go +++ b/libpod/runtime.go @@ -130,6 +130,12 @@ type RuntimeConfig struct { OCIRuntime string `toml:"runtime"` // OCIRuntimes are the set of configured OCI runtimes (default is runc) OCIRuntimes map[string][]string `toml:"runtimes"` + // RuntimePath is the path to OCI runtime binary for launching + // containers. + // The first path pointing to a valid file will be used + // This is used only when there are no OCIRuntime/OCIRuntimes defined. It + // is used only to be backward compatible with older versions of Podman. + RuntimePath []string `toml:"runtime_path"` // ConmonPath is the path to the Conmon binary used for managing // containers // The first path pointing to a valid file will be used @@ -389,7 +395,7 @@ func NewRuntime(options ...RuntimeOption) (runtime *Runtime, err error) { // If the configuration file was not found but we are running in rootless, a subset of the // global config file is used. for _, path := range []string{OverrideConfigPath, ConfigPath} { - contents, err := ioutil.ReadFile(OverrideConfigPath) + contents, err := ioutil.ReadFile(path) if err != nil { // Ignore any error, the file might not be readable by us. continue @@ -403,6 +409,7 @@ func NewRuntime(options ...RuntimeOption) (runtime *Runtime, err error) { runtime.config.ConmonPath = tmpConfig.ConmonPath runtime.config.ConmonEnvVars = tmpConfig.ConmonEnvVars runtime.config.OCIRuntimes = tmpConfig.OCIRuntimes + runtime.config.RuntimePath = tmpConfig.RuntimePath runtime.config.CNIPluginDir = tmpConfig.CNIPluginDir runtime.config.NoPivotRoot = tmpConfig.NoPivotRoot break @@ -485,10 +492,25 @@ func NewRuntimeFromConfig(configPath string, options ...RuntimeOption) (runtime // Make a new runtime based on the given configuration // Sets up containers/storage, state store, OCI runtime func makeRuntime(runtime *Runtime) (err error) { + + // Backward compatibility for `runtime_path` + if runtime.config.RuntimePath != nil { + // Don't print twice in rootless mode. + if os.Geteuid() == 0 { + logrus.Warningf("The configuration is using `runtime_path`, which is deprecated and will be removed in future. Please use `runtimes` and `runtime`") + logrus.Warningf("If you are using both `runtime_path` and `runtime`, the configuration from `runtime_path` is used") + } + + // Transform `runtime_path` into `runtimes` and `runtime`. + name := filepath.Base(runtime.config.RuntimePath[0]) + runtime.config.OCIRuntime = name + runtime.config.OCIRuntimes = map[string][]string{name: runtime.config.RuntimePath} + } + // Find a working OCI runtime binary foundRuntime := false // If runtime is an absolute path, then use it as it is. - if runtime.config.OCIRuntime[0] == '/' { + if runtime.config.OCIRuntime != "" && runtime.config.OCIRuntime[0] == '/' { foundRuntime = true runtime.ociRuntimePath = OCIRuntimePath{Name: filepath.Base(runtime.config.OCIRuntime), Paths: []string{runtime.config.OCIRuntime}} } else { diff --git a/pkg/varlinkapi/images.go b/pkg/varlinkapi/images.go index 534419f6f..b3090d2dd 100644 --- a/pkg/varlinkapi/images.go +++ b/pkg/varlinkapi/images.go @@ -313,7 +313,7 @@ func (i *LibpodAPI) HistoryImage(call iopodman.VarlinkCall, name string) error { } // PushImage pushes an local image to registry -func (i *LibpodAPI) PushImage(call iopodman.VarlinkCall, name, tag string, tlsVerify bool, signaturePolicy, creds, certDir string, compress bool, format string, removeSignatures bool, signBy string) error { +func (i *LibpodAPI) PushImage(call iopodman.VarlinkCall, name, tag string, tlsVerify *bool, signaturePolicy, creds, certDir string, compress bool, format string, removeSignatures bool, signBy string) error { var ( registryCreds *types.DockerAuthConfig manifestType string @@ -337,8 +337,8 @@ func (i *LibpodAPI) PushImage(call iopodman.VarlinkCall, name, tag string, tlsVe DockerRegistryCreds: registryCreds, DockerCertPath: certDir, } - if !tlsVerify { - dockerRegistryOptions.DockerInsecureSkipTLSVerify = types.OptionalBoolTrue + if tlsVerify != nil { + dockerRegistryOptions.DockerInsecureSkipTLSVerify = types.NewOptionalBool(!*tlsVerify) } if format != "" { switch format { @@ -441,8 +441,11 @@ func (i *LibpodAPI) RemoveImage(call iopodman.VarlinkCall, name string, force bo // SearchImages searches all registries configured in /etc/containers/registries.conf for an image // Requires an image name and a search limit as int -func (i *LibpodAPI) SearchImages(call iopodman.VarlinkCall, query string, limit *int64) error { +func (i *LibpodAPI) SearchImages(call iopodman.VarlinkCall, query string, limit *int64, tlsVerify *bool) error { sc := image.GetSystemContext("", "", false) + if tlsVerify != nil { + sc.DockerInsecureSkipTLSVerify = types.NewOptionalBool(!*tlsVerify) + } registries, err := sysreg.GetRegistries() if err != nil { return call.ReplyErrorOccurred(fmt.Sprintf("unable to get system registries: %q", err)) @@ -583,7 +586,7 @@ func (i *LibpodAPI) ExportImage(call iopodman.VarlinkCall, name, destination str } // PullImage pulls an image from a registry to the image store. -func (i *LibpodAPI) PullImage(call iopodman.VarlinkCall, name string, certDir, creds, signaturePolicy string, tlsVerify bool) error { +func (i *LibpodAPI) PullImage(call iopodman.VarlinkCall, name string, certDir, creds, signaturePolicy string, tlsVerify *bool) error { var ( registryCreds *types.DockerAuthConfig imageID string @@ -600,8 +603,8 @@ func (i *LibpodAPI) PullImage(call iopodman.VarlinkCall, name string, certDir, c DockerRegistryCreds: registryCreds, DockerCertPath: certDir, } - if tlsVerify { - dockerRegistryOptions.DockerInsecureSkipTLSVerify = types.NewOptionalBool(!tlsVerify) + if tlsVerify != nil { + dockerRegistryOptions.DockerInsecureSkipTLSVerify = types.NewOptionalBool(!*tlsVerify) } so := image.SigningOptions{} @@ -644,8 +647,8 @@ func (i *LibpodAPI) ContainerRunlabel(call iopodman.VarlinkCall, input iopodman. dockerRegistryOptions := image.DockerRegistryOptions{ DockerCertPath: input.CertDir, } - if !input.TlsVerify { - dockerRegistryOptions.DockerInsecureSkipTLSVerify = types.OptionalBoolTrue + if input.TlsVerify != nil { + dockerRegistryOptions.DockerInsecureSkipTLSVerify = types.NewOptionalBool(!*input.TlsVerify) } stdErr := os.Stderr diff --git a/test/e2e/pull_test.go b/test/e2e/pull_test.go index bfae15152..faad8202e 100644 --- a/test/e2e/pull_test.go +++ b/test/e2e/pull_test.go @@ -163,4 +163,20 @@ var _ = Describe("Podman pull", func() { Expect(pull.OutputToString()).To(ContainSubstring(shortImageId)) }) + + It("podman pull check all tags", func() { + session := podmanTest.Podman([]string{"pull", "--all-tags", "alpine"}) + session.WaitWithDefaultTimeout() + Expect(session.ExitCode()).To(Equal(0)) + Expect(session.LineInOuputStartsWith("Pulled Images:")).To(BeTrue()) + + session = podmanTest.Podman([]string{"images"}) + session.WaitWithDefaultTimeout() + Expect(session.ExitCode()).To(Equal(0)) + Expect(len(session.OutputToStringArray())).To(BeNumerically(">", 4)) + + rmi := podmanTest.Podman([]string{"rmi", "-a", "-f"}) + rmi.WaitWithDefaultTimeout() + Expect(rmi.ExitCode()).To(Equal(0)) + }) }) diff --git a/test/utils/utils.go b/test/utils/utils.go index 23dcb95e3..aace018cd 100644 --- a/test/utils/utils.go +++ b/test/utils/utils.go @@ -270,7 +270,7 @@ func (s *PodmanSession) LineInOuputStartsWith(term string) bool { } //LineInOutputContains returns true if a line in a -// session output starts with the supplied string +// session output contains the supplied string func (s *PodmanSession) LineInOutputContains(term string) bool { for _, i := range s.OutputToStringArray() { if strings.Contains(i, term) { |