diff options
-rw-r--r-- | Makefile | 2 | ||||
-rw-r--r-- | RELEASE_NOTES.md | 20 | ||||
-rw-r--r-- | changelog.txt | 50 | ||||
-rw-r--r-- | cmd/podman/cliconfig/config.go | 1 | ||||
-rw-r--r-- | cmd/podman/main.go | 3 | ||||
-rw-r--r-- | cmd/podman/main_local.go | 2 | ||||
-rw-r--r-- | cmd/podman/rm.go | 9 | ||||
-rw-r--r-- | completions/bash/podman | 1 | ||||
-rw-r--r-- | contrib/spec/podman.spec.in | 2 | ||||
-rw-r--r-- | docs/podman-rm.1.md | 7 | ||||
-rw-r--r-- | libpod/runtime_cstorage.go | 118 | ||||
-rw-r--r-- | libpod/runtime_ctr.go | 15 | ||||
-rw-r--r-- | pkg/adapter/containers.go | 14 | ||||
-rw-r--r-- | pkg/apparmor/apparmor_linux.go | 9 | ||||
-rw-r--r-- | pkg/spec/createconfig.go | 4 | ||||
-rw-r--r-- | test/e2e/runlabel_test.go | 1 | ||||
-rw-r--r-- | version/version.go | 2 |
17 files changed, 235 insertions, 25 deletions
@@ -1,6 +1,6 @@ GO ?= go DESTDIR ?= / -EPOCH_TEST_COMMIT ?= 1f31892a9fd8573d4b25274b208e6b9f860cdf81 +EPOCH_TEST_COMMIT ?= 90e3c9002b2293569e0cec168a30ecb962b00034 HEAD ?= HEAD CHANGELOG_BASE ?= HEAD~ CHANGELOG_TARGET ?= HEAD diff --git a/RELEASE_NOTES.md b/RELEASE_NOTES.md index fbb6a78b0..d5717f7db 100644 --- a/RELEASE_NOTES.md +++ b/RELEASE_NOTES.md @@ -1,5 +1,25 @@ # Release Notes +## 1.4.1 +### Features +- The `podman exec` command now sets its error code differently based on whether the container does not exist, and the command in the container does not exist +- The `podman inspect` command on containers now outputs Mounts JSON that matches that of `docker inspect`, only including user-specified volumes and differentiating bind mounts and named volumes +- The `podman inspect` command now reports the path to a container's OCI spec with the `OCIConfigPath` key (only included when the container is initialized or running) +- The `podman run --mount` command now supports the `bind-nonrecursive` option for bind mounts ([#3314](https://github.com/containers/libpod/issues/3314)) + +### Bugfixes +- Fixed a bug where `podman play kube` would fail to create containers due to an unspecified log driver +- Fixed a bug where Podman would fail to build with [musl libc](https://www.musl-libc.org/) ([#3284](https://github.com/containers/libpod/issues/3284)) +- Fixed a bug where rootless Podman using `slirp4netns` networking in an environment with no nameservers on the host other than localhost would result in nonfunctional networking ([#3277](https://github.com/containers/libpod/issues/3277)) +- Fixed a bug where `podman import` would not properly set environment variables, discarding their values and retaining only keys +- Fixed a bug where Podman would fail to run when built with Apparmor support but run on systems without the Apparmor kernel module loaded ([#3331](https://github.com/containers/libpod/issues/3331)) + +### Misc +- Remote Podman will now default the username it uses to log in to remote systems to the username of the current user +- Podman now uses JSON logging with OCI runtimes that support it, allowing for better error reporting +- Updated vendored Buildah to v1.8.4 +- Updated vendored containers/image to v2.0 + ## 1.4.0 ### Features - The `podman checkpoint` and `podman restore` commands can now be used to migrate containers between Podman installations on different systems ([#1618](https://github.com/containers/libpod/issues/1618)) diff --git a/changelog.txt b/changelog.txt index ece82e15b..3b1260c90 100644 --- a/changelog.txt +++ b/changelog.txt @@ -1,3 +1,53 @@ +- Changelog for v1.4.1 (2019-06-14) + * Completely disable global options test + * Update release notes for 1.4.1 + * Skip runlabel global options test for podman-in-podman + * pkg/apparmor: fix when AA is disabled + * Fix ENV parsing on `podman import` + * Fix storage-opts type in Cobra + * Use the logical registry location instead of the physical one in (podman info) + * Update containers/image to v2.0.0, and buildah to v1.8.4 + * Document exit codes for podman exec + * Add --storage flag to 'podman rm' (local only) + * When creating exit command, pass storage options on + * Bump cirrus images + * Mention the new Podman mailing list in contributing.md + * Update 1.4.0 release notes with ID -> Id in inspect + * Bump conmon to 0.3.0 + * Cirrus: Guarantee ssh is running for rootless + * Purge all use of easyjson and ffjson in libpod + * Split mount options in inspect further + * storage: support --mount type=bind,bind-nonrecursive + * oci: allow to specify what runtimes support JSON + * storage: fix typo + * oci: use json formatted errors from the runtime + * Make Inspect's mounts struct accurate to Docker + * Provide OCI spec path in `podman inspect` output + * If container is not in correct state podman exec should exit with 126 + * rootless: use the slirp4netns builtin DNS first + * Add --filename option to generate kube + * Fix podman-remote to user default username + * Prohibit use of positional args with --import + * BATS tests - get working again + * Add a test for 'podman play kube' to prevent regression + * Cirrus: New images w/o buildah + * Remove source-built buildah from CI + * standardize documentation formatting + * Touchup upstream Dockerfile + * only set log driver if it isn't empty + * Fix cgo includes for musl + * When you change the storage driver we ignore the storage-options + * Update vendor on containers/storage to v1.12.10 + * Bump gitvalidation epoch + * Bump to v1.4.1-dev + * Default 'pause' to false for 'podman cp' + * Update c/storage to 9b10041d7b2ef767ce9c42b5862b6c51eeb82214 + * Fix spelling + * fix tutorial link to install.md + * Cirrus: Minor cleanup of dependencies and docs + * Begin to break up pkg/inspect + * docs: Add CI section and links + - Changelog for v1.4.0 (2019-06-07) * Update release notes for v1.4.0 * Update release notes for v1.4.0 diff --git a/cmd/podman/cliconfig/config.go b/cmd/podman/cliconfig/config.go index 545166d05..4a4c839cc 100644 --- a/cmd/podman/cliconfig/config.go +++ b/cmd/podman/cliconfig/config.go @@ -439,6 +439,7 @@ type RmValues struct { All bool Force bool Latest bool + Storage bool Volumes bool } diff --git a/cmd/podman/main.go b/cmd/podman/main.go index a149a47f9..cbca32cc8 100644 --- a/cmd/podman/main.go +++ b/cmd/podman/main.go @@ -104,6 +104,9 @@ func before(cmd *cobra.Command, args []string) error { logrus.Errorf(err.Error()) os.Exit(1) } + if err := setSyslog(); err != nil { + return err + } if err := setupRootless(cmd, args); err != nil { return err } diff --git a/cmd/podman/main_local.go b/cmd/podman/main_local.go index b4f21bd0c..132f35ab5 100644 --- a/cmd/podman/main_local.go +++ b/cmd/podman/main_local.go @@ -48,7 +48,7 @@ func init() { rootCmd.PersistentFlags().StringVar(&MainGlobalOpts.Runtime, "runtime", "", "Path to the OCI-compatible binary used to run containers, default is /usr/bin/runc") // -s is depracated due to conflict with -s on subcommands rootCmd.PersistentFlags().StringVar(&MainGlobalOpts.StorageDriver, "storage-driver", "", "Select which storage driver is used to manage storage of images and containers (default is overlay)") - rootCmd.PersistentFlags().StringSliceVar(&MainGlobalOpts.StorageOpts, "storage-opt", []string{}, "Used to pass an option to the storage driver") + rootCmd.PersistentFlags().StringArrayVar(&MainGlobalOpts.StorageOpts, "storage-opt", []string{}, "Used to pass an option to the storage driver") rootCmd.PersistentFlags().BoolVar(&MainGlobalOpts.Syslog, "syslog", false, "Output logging information to syslog as well as the console") rootCmd.PersistentFlags().StringVar(&MainGlobalOpts.TmpDir, "tmpdir", "", "Path to the tmp directory") diff --git a/cmd/podman/rm.go b/cmd/podman/rm.go index 1bf56b782..2710a8194 100644 --- a/cmd/podman/rm.go +++ b/cmd/podman/rm.go @@ -42,7 +42,9 @@ func init() { flags.BoolVarP(&rmCommand.All, "all", "a", false, "Remove all containers") flags.BoolVarP(&rmCommand.Force, "force", "f", false, "Force removal of a running container. The default is false") flags.BoolVarP(&rmCommand.Latest, "latest", "l", false, "Act on the latest container podman is aware of") + flags.BoolVar(&rmCommand.Storage, "storage", false, "Remove container from storage library") flags.BoolVarP(&rmCommand.Volumes, "volumes", "v", false, "Remove the volumes associated with the container") + markFlagHiddenForRemoteClient("storage", flags) markFlagHiddenForRemoteClient("latest", flags) } @@ -54,6 +56,13 @@ func rmCmd(c *cliconfig.RmValues) error { } defer runtime.Shutdown(false) + // Storage conflicts with --all/--latest/--volumes + if c.Storage { + if c.All || c.Latest || c.Volumes { + return errors.Errorf("--storage conflicts with --volumes, --all, and --latest") + } + } + ok, failures, err := runtime.RemoveContainers(getContext(), c) if err != nil { if errors.Cause(err) == libpod.ErrNoSuchCtr { diff --git a/completions/bash/podman b/completions/bash/podman index b049f309a..65c6308cc 100644 --- a/completions/bash/podman +++ b/completions/bash/podman @@ -2041,6 +2041,7 @@ _podman_rm() { -h --latest -l + --storage --volumes -v " diff --git a/contrib/spec/podman.spec.in b/contrib/spec/podman.spec.in index d755fd1aa..d0ad07044 100644 --- a/contrib/spec/podman.spec.in +++ b/contrib/spec/podman.spec.in @@ -39,7 +39,7 @@ %global shortcommit_conmon %(c=%{commit_conmon}; echo ${c:0:7}) Name: podman -Version: 1.4.1 +Version: 1.4.2 Release: #COMMITDATE#.git%{shortcommit0}%{?dist} Summary: Manage Pods, Containers and Container Images License: ASL 2.0 diff --git a/docs/podman-rm.1.md b/docs/podman-rm.1.md index c7ff23bdf..32a8c2943 100644 --- a/docs/podman-rm.1.md +++ b/docs/podman-rm.1.md @@ -30,6 +30,13 @@ to run containers such as CRI-O, the last started container could be from either The latest option is not supported on the remote client. +**--storage** + +Remove the container from the storage library only. +This is only possible with containers that are not present in libpod (cannot be seen by `podman ps`). +It is used to remove containers from `podman build` and `buildah`, and orphan containers which were only partially removed by `podman rm`. +The storage option conflicts with the **--all**, **--latest**, and **--volumes** options. + **--volumes**, **-v** Remove the volumes associated with the container. diff --git a/libpod/runtime_cstorage.go b/libpod/runtime_cstorage.go new file mode 100644 index 000000000..569f63322 --- /dev/null +++ b/libpod/runtime_cstorage.go @@ -0,0 +1,118 @@ +package libpod + +import ( + "github.com/containers/storage" + "github.com/pkg/errors" + "github.com/sirupsen/logrus" +) + +// StorageContainer represents a container present in c/storage but not in +// libpod. +type StorageContainer struct { + ID string + Names []string + PresentInLibpod bool +} + +// ListStorageContainers lists all containers visible to c/storage. +func (r *Runtime) ListStorageContainers() ([]*StorageContainer, error) { + r.lock.RLock() + defer r.lock.RUnlock() + + finalCtrs := []*StorageContainer{} + + ctrs, err := r.store.Containers() + if err != nil { + return nil, err + } + + for _, ctr := range ctrs { + storageCtr := new(StorageContainer) + storageCtr.ID = ctr.ID + storageCtr.Names = ctr.Names + + // Look up if container is in state + hasCtr, err := r.state.HasContainer(ctr.ID) + if err != nil { + return nil, errors.Wrapf(err, "error looking up container %s in state", ctr.ID) + } + + storageCtr.PresentInLibpod = hasCtr + + finalCtrs = append(finalCtrs, storageCtr) + } + + return finalCtrs, nil +} + +// RemoveStorageContainer removes a container from c/storage. +// The container WILL NOT be removed if it exists in libpod. +// Accepts ID or full name of container. +// If force is set, the container will be unmounted first to ensure removal. +func (r *Runtime) RemoveStorageContainer(idOrName string, force bool) error { + r.lock.Lock() + defer r.lock.Unlock() + + targetID, err := r.store.Lookup(idOrName) + if err != nil { + if err == storage.ErrLayerUnknown { + return errors.Wrapf(ErrNoSuchCtr, "no container with ID or name %q found", idOrName) + } + return errors.Wrapf(err, "error looking up container %q", idOrName) + } + + // Lookup returns an ID but it's not guaranteed to be a container ID. + // So we can still error here. + ctr, err := r.store.Container(targetID) + if err != nil { + if err == storage.ErrContainerUnknown { + return errors.Wrapf(ErrNoSuchCtr, "%q does not refer to a container", idOrName) + } + return errors.Wrapf(err, "error retrieving container %q", idOrName) + } + + // Error out if the container exists in libpod + exists, err := r.state.HasContainer(ctr.ID) + if err != nil { + return err + } + if exists { + return errors.Wrapf(ErrCtrExists, "refusing to remove %q as it exists in libpod as container %s", idOrName, ctr.ID) + } + + if !force { + timesMounted, err := r.store.Mounted(ctr.ID) + if err != nil { + if err == storage.ErrContainerUnknown { + // Container was removed from under us. + // It's gone, so don't bother erroring. + logrus.Warnf("Storage for container %s already removed", ctr.ID) + return nil + } + return errors.Wrapf(err, "error looking up container %q mounts", idOrName) + } + if timesMounted > 0 { + return errors.Wrapf(ErrCtrStateInvalid, "container %q is mounted and cannot be removed without using force", idOrName) + } + } else { + if _, err := r.store.Unmount(ctr.ID, true); err != nil { + if err == storage.ErrContainerUnknown { + // Container again gone, no error + logrus.Warnf("Storage for container %s already removed", ctr.ID) + return nil + } + return errors.Wrapf(err, "error unmounting container %q", idOrName) + } + } + + if err := r.store.DeleteContainer(ctr.ID); err != nil { + if err == storage.ErrContainerUnknown { + // Container again gone, no error + logrus.Warnf("Storage for container %s already removed", ctr.ID) + return nil + } + return errors.Wrapf(err, "error removing storage for container %q", idOrName) + } + + return nil +} diff --git a/libpod/runtime_ctr.go b/libpod/runtime_ctr.go index cf1f5701d..0871b83a7 100644 --- a/libpod/runtime_ctr.go +++ b/libpod/runtime_ctr.go @@ -9,9 +9,7 @@ import ( "time" "github.com/containers/libpod/libpod/events" - "github.com/containers/libpod/libpod/image" "github.com/containers/libpod/pkg/rootless" - "github.com/containers/storage" "github.com/containers/storage/pkg/stringid" spec "github.com/opencontainers/runtime-spec/specs-go" "github.com/opencontainers/runtime-tools/generate" @@ -614,16 +612,3 @@ func (r *Runtime) GetLatestContainer() (*Container, error) { } return ctrs[lastCreatedIndex], nil } - -// RemoveContainersFromStorage attempt to remove containers from storage that do not exist in libpod database -func (r *Runtime) RemoveContainersFromStorage(ctrs []string) { - for _, i := range ctrs { - // if the container does not exist in database, attempt to remove it from storage - if _, err := r.LookupContainer(i); err != nil && errors.Cause(err) == image.ErrNoSuchCtr { - r.storageService.UnmountContainerImage(i, true) - if err := r.storageService.DeleteContainer(i); err != nil && errors.Cause(err) != storage.ErrContainerUnknown { - logrus.Errorf("Failed to remove container %q from storage: %s", i, err) - } - } - } -} diff --git a/pkg/adapter/containers.go b/pkg/adapter/containers.go index 29297fbd5..40b1e6b43 100644 --- a/pkg/adapter/containers.go +++ b/pkg/adapter/containers.go @@ -190,12 +190,18 @@ func (r *LocalRuntime) RemoveContainers(ctx context.Context, cli *cliconfig.RmVa } logrus.Debugf("Setting maximum rm workers to %d", maxWorkers) + if cli.Storage { + for _, ctr := range cli.InputArgs { + if err := r.RemoveStorageContainer(ctr, cli.Force); err != nil { + failures[ctr] = err + } + ok = append(ok, ctr) + } + return ok, failures, nil + } + ctrs, err := shortcuts.GetContainersByContext(cli.All, cli.Latest, cli.InputArgs, r.Runtime) if err != nil { - // Force may be used to remove containers no longer found in the database - if cli.Force && len(cli.InputArgs) > 0 && errors.Cause(err) == libpod.ErrNoSuchCtr { - r.RemoveContainersFromStorage(cli.InputArgs) - } return ok, failures, err } diff --git a/pkg/apparmor/apparmor_linux.go b/pkg/apparmor/apparmor_linux.go index 2c5022c1f..0d01f41e9 100644 --- a/pkg/apparmor/apparmor_linux.go +++ b/pkg/apparmor/apparmor_linux.go @@ -225,8 +225,13 @@ func CheckProfileAndLoadDefault(name string) (string, error) { } } - if name != "" && !runcaa.IsEnabled() { - return "", fmt.Errorf("profile %q specified but AppArmor is disabled on the host", name) + // Check if AppArmor is disabled and error out if a profile is to be set. + if !runcaa.IsEnabled() { + if name == "" { + return "", nil + } else { + return "", fmt.Errorf("profile %q specified but AppArmor is disabled on the host", name) + } } // If the specified name is not empty or is not a default libpod one, diff --git a/pkg/spec/createconfig.go b/pkg/spec/createconfig.go index ed8036a54..a8413d6c7 100644 --- a/pkg/spec/createconfig.go +++ b/pkg/spec/createconfig.go @@ -162,6 +162,10 @@ func (c *CreateConfig) createExitCommand(runtime *libpod.Runtime) ([]string, err if config.StorageConfig.GraphDriverName != "" { command = append(command, []string{"--storage-driver", config.StorageConfig.GraphDriverName}...) } + for _, opt := range config.StorageConfig.GraphDriverOptions { + command = append(command, []string{"--storage-opt", opt}...) + } + if c.Syslog { command = append(command, "--syslog", "true") } diff --git a/test/e2e/runlabel_test.go b/test/e2e/runlabel_test.go index 5ef68603e..4e2cb501e 100644 --- a/test/e2e/runlabel_test.go +++ b/test/e2e/runlabel_test.go @@ -85,6 +85,7 @@ var _ = Describe("podman container runlabel", func() { }) It("podman container runlabel global options", func() { + Skip("Test nonfunctional for podman-in-podman testing") image := "podman-global-test:ls" podmanTest.BuildImage(GlobalDockerfile, image, "false") result := podmanTest.Podman([]string{"--syslog", "--log-level", "debug", "container", "runlabel", "RUN", image}) diff --git a/version/version.go b/version/version.go index c3917c016..2ef7a9c65 100644 --- a/version/version.go +++ b/version/version.go @@ -4,7 +4,7 @@ package version // NOTE: remember to bump the version at the top // of the top-level README.md file when this is // bumped. -const Version = "1.4.1-dev" +const Version = "1.4.2-dev" // RemoteAPIVersion is the version for the remote // client API. It is used to determine compatibility |