diff options
-rw-r--r-- | .copr/Makefile | 4 | ||||
-rw-r--r-- | .copr/prepare.sh | 17 | ||||
-rw-r--r-- | Makefile | 16 | ||||
-rw-r--r-- | cmd/podman/cliconfig/config.go | 3 | ||||
-rw-r--r-- | cmd/podman/containers_prune.go | 21 | ||||
-rw-r--r-- | cmd/podman/shared/container.go | 22 | ||||
-rw-r--r-- | cmd/podman/system_prune.go | 2 | ||||
-rw-r--r-- | cmd/podman/version.go | 66 | ||||
-rw-r--r-- | completions/bash/podman | 3 | ||||
-rw-r--r-- | contrib/build_rpm.sh | 8 | ||||
-rw-r--r-- | contrib/spec/podman.spec.in | 40 | ||||
-rw-r--r-- | docs/source/markdown/podman-container-prune.1.md | 22 | ||||
-rw-r--r-- | docs/source/markdown/podman-version.1.md | 4 | ||||
-rw-r--r-- | install.md | 2 | ||||
-rw-r--r-- | libpod/oci_util.go | 6 | ||||
-rw-r--r-- | libpod/runtime.go | 18 | ||||
-rw-r--r-- | libpod/volume_internal.go | 12 | ||||
-rw-r--r-- | pkg/adapter/containers.go | 31 | ||||
-rw-r--r-- | pkg/adapter/containers_remote.go | 2 | ||||
-rw-r--r-- | rootless.md | 2 | ||||
-rw-r--r-- | test/e2e/prune_test.go | 2 | ||||
-rw-r--r-- | test/e2e/version_test.go | 16 |
22 files changed, 241 insertions, 78 deletions
diff --git a/.copr/Makefile b/.copr/Makefile index 71142920b..465a52b15 100644 --- a/.copr/Makefile +++ b/.copr/Makefile @@ -8,11 +8,11 @@ SHORT_COMMIT ?= $(shell git rev-parse --short=8 HEAD) srpm: mkdir -p $(topdir) sh $(current_dir)/prepare.sh - rpmbuild -bs -D "dist %{nil}" -D "_sourcedir build/" -D "_srcrpmdir $(outdir)" -D "_topdir $(topdir)" --nodeps contrib/spec/podman.spec + rpmbuild -bs -D "dist %{nil}" -D "_sourcedir build/" -D "_srcrpmdir $(outdir)" -D "_topdir $(topdir)" --nodeps ${extra_arg:-""} contrib/spec/podman.spec build_binary: mkdir -p $(topdir) - rpmbuild --rebuild -D "_rpmdir $(outdir)" -D "_topdir $(topdir)" $(outdir)/podman-*.git$(SHORT_COMMIT).src.rpm + rpmbuild --rebuild -D "_rpmdir $(outdir)" -D "_topdir $(topdir)" ${extra_arg:-""} $(outdir)/podman-*.git$(SHORT_COMMIT).src.rpm clean: rm -fr rpms diff --git a/.copr/prepare.sh b/.copr/prepare.sh index d8ad34d08..713cdc2ee 100644 --- a/.copr/prepare.sh +++ b/.copr/prepare.sh @@ -1,12 +1,14 @@ #!/bin/sh -euf -set -x +set -euxo pipefail OS_TEST=${OS_TEST:=0} if [ ! -e /usr/bin/git ]; then dnf -y install git-core fi -git fetch --unshallow || : +if [ -f $(git rev-parse --git-dir)/shallow ]; then + git fetch --unshallow +fi COMMIT=$(git rev-parse HEAD) COMMIT_SHORT=$(git rev-parse --short=8 HEAD) @@ -26,7 +28,12 @@ if [ ${OS_TEST} -eq 0 ]; then sed -i "s/${BR}/${NEWBR}/g" contrib/spec/podman.spec fi -mkdir build/ +mkdir -p build/ git archive --prefix "libpod-${COMMIT_SHORT}/" --format "tar.gz" HEAD -o "build/libpod-${COMMIT_SHORT}.tar.gz" -git clone https://github.com/containers/conmon -cd conmon && git checkout 6f3572558b97bc60dd8f8c7f0807748e6ce2c440 && git archive --prefix "conmon/" --format "tar.gz" HEAD -o "../build/conmon.tar.gz" +if [ ! -d conmon ]; then + git clone -n --quiet https://github.com/containers/conmon +fi +pushd conmon +git checkout 6f3572558b97bc60dd8f8c7f0807748e6ce2c440 +git archive --prefix "conmon/" --format "tar.gz" HEAD -o "../build/conmon.tar.gz" +popd @@ -318,7 +318,7 @@ $(MANPAGES): %: %.md .gopathok docdir: mkdir -p docs/build/man -docs: docdir $(MANPAGES) ## Generate documentation +docs: .install.md2man docdir $(MANPAGES) ## Generate documentation install-podman-remote-%-docs: podman-remote docs $(MANPAGES) rm -rf docs/build/remote @@ -532,19 +532,23 @@ vendor-in-container: .PHONY: \ .gopathok \ binaries \ + changelog \ clean \ - validate.completions \ default \ docs \ gofmt \ + golangci-lint \ help \ install \ - golangci-lint \ + install.libseccomp.sudo \ lint \ pause \ - uninstall \ shell \ - changelog \ + uninstall \ validate \ - install.libseccomp.sudo \ + validate.completions \ vendor + +rpm: + @echo "Building rpms ..." + ./contrib/build_rpm.sh diff --git a/cmd/podman/cliconfig/config.go b/cmd/podman/cliconfig/config.go index df7ea6c33..c15ce8829 100644 --- a/cmd/podman/cliconfig/config.go +++ b/cmd/podman/cliconfig/config.go @@ -183,7 +183,8 @@ type PruneImagesValues struct { type PruneContainersValues struct { PodmanCommand - Force bool + Force bool + Filter []string } type PodPruneValues struct { diff --git a/cmd/podman/containers_prune.go b/cmd/podman/containers_prune.go index 3d0fef37d..78c50268c 100644 --- a/cmd/podman/containers_prune.go +++ b/cmd/podman/containers_prune.go @@ -1,6 +1,11 @@ package main import ( + "bufio" + "fmt" + "os" + "strings" + "github.com/containers/libpod/cmd/podman/cliconfig" "github.com/containers/libpod/cmd/podman/shared" "github.com/containers/libpod/libpod/define" @@ -36,9 +41,23 @@ func init() { pruneContainersCommand.SetUsageTemplate(UsageTemplate()) flags := pruneContainersCommand.Flags() flags.BoolVarP(&pruneContainersCommand.Force, "force", "f", false, "Force removal of a running container. The default is false") + flags.StringArrayVar(&pruneContainersCommand.Filter, "filter", []string{}, "Provide filter values (e.g. 'until=<timestamp>')") } func pruneContainersCmd(c *cliconfig.PruneContainersValues) error { + if !c.Force { + reader := bufio.NewReader(os.Stdin) + fmt.Printf(`WARNING! This will remove all stopped containers. +Are you sure you want to continue? [y/N] `) + ans, err := reader.ReadString('\n') + if err != nil { + return errors.Wrapf(err, "error reading input") + } + if strings.ToLower(ans)[0] != 'y' { + return nil + } + } + runtime, err := adapter.GetRuntime(getContext(), &c.PodmanCommand) if err != nil { return errors.Wrapf(err, "could not get runtime") @@ -49,7 +68,7 @@ func pruneContainersCmd(c *cliconfig.PruneContainersValues) error { if c.GlobalIsSet("max-workers") { maxWorkers = c.GlobalFlags.MaxWorks } - ok, failures, err := runtime.Prune(getContext(), maxWorkers, c.Force) + ok, failures, err := runtime.Prune(getContext(), maxWorkers, c.Force, c.Filter) if err != nil { if errors.Cause(err) == define.ErrNoSuchCtr { if len(c.InputArgs) > 1 { diff --git a/cmd/podman/shared/container.go b/cmd/podman/shared/container.go index 0a2e96cf7..4f2002992 100644 --- a/cmd/podman/shared/container.go +++ b/cmd/podman/shared/container.go @@ -17,6 +17,7 @@ import ( "github.com/containers/libpod/libpod" "github.com/containers/libpod/libpod/define" "github.com/containers/libpod/libpod/image" + "github.com/containers/libpod/pkg/timetype" "github.com/containers/libpod/pkg/util" "github.com/cri-o/ocicni/pkg/ocicni" "github.com/docker/go-units" @@ -274,7 +275,8 @@ func worker(wg *sync.WaitGroup, jobs <-chan workerInput, results chan<- PsContai } } -func generateContainerFilterFuncs(filter, filterValue string, r *libpod.Runtime) (func(container *libpod.Container) bool, error) { +// GenerateContainerFilterFuncs return ContainerFilter functions based of filter. +func GenerateContainerFilterFuncs(filter, filterValue string, r *libpod.Runtime) (func(container *libpod.Container) bool, error) { switch filter { case "id": return func(c *libpod.Container) bool { @@ -396,6 +398,22 @@ func generateContainerFilterFuncs(filter, filterValue string, r *libpod.Runtime) } return hcStatus == filterValue }, nil + case "until": + ts, err := timetype.GetTimestamp(filterValue, time.Now()) + if err != nil { + return nil, err + } + seconds, nanoseconds, err := timetype.ParseTimestamps(ts, 0) + if err != nil { + return nil, err + } + until := time.Unix(seconds, nanoseconds) + return func(c *libpod.Container) bool { + if !until.IsZero() && c.CreatedTime().After((until)) { + return true + } + return false + }, nil } return nil, errors.Errorf("%s is an invalid filter", filter) } @@ -413,7 +431,7 @@ func GetPsContainerOutput(r *libpod.Runtime, opts PsOptions, filters []string, m if len(filterSplit) < 2 { return nil, errors.Errorf("filter input must be in the form of filter=value: %s is invalid", f) } - generatedFunc, err := generateContainerFilterFuncs(filterSplit[0], filterSplit[1], r) + generatedFunc, err := GenerateContainerFilterFuncs(filterSplit[0], filterSplit[1], r) if err != nil { return nil, errors.Wrapf(err, "invalid filter") } diff --git a/cmd/podman/system_prune.go b/cmd/podman/system_prune.go index ae5d7ed2d..74fdcde99 100644 --- a/cmd/podman/system_prune.go +++ b/cmd/podman/system_prune.go @@ -92,7 +92,7 @@ Are you sure you want to continue? [y/N] `, volumeString) rmWorkers := shared.Parallelize("rm") fmt.Println("Deleted Containers") - ok, failures, err = runtime.Prune(ctx, rmWorkers, false) + ok, failures, err = runtime.Prune(ctx, rmWorkers, false, []string{}) if err != nil { if lasterr != nil { logrus.Errorf("%q", err) diff --git a/cmd/podman/version.go b/cmd/podman/version.go index 314b2e266..5907241ff 100644 --- a/cmd/podman/version.go +++ b/cmd/podman/version.go @@ -37,13 +37,40 @@ func init() { flags := versionCommand.Flags() flags.StringVarP(&versionCommand.Format, "format", "f", "", "Change the output format to JSON or a Go template") } +func getRemoteVersion(c *cliconfig.VersionValues) (version define.Version, err error) { + runtime, err := adapter.GetRuntime(getContext(), &c.PodmanCommand) + if err != nil { + return version, errors.Wrapf(err, "could not get runtime") + } + defer runtime.DeferredShutdown(false) + + return runtime.GetVersion() +} + +type versionStruct struct { + Client define.Version + Server define.Version +} // versionCmd gets and prints version info for version command func versionCmd(c *cliconfig.VersionValues) error { - clientVersion, err := define.GetVersion() + + var ( + v versionStruct + err error + ) + v.Client, err = define.GetVersion() if err != nil { return errors.Wrapf(err, "unable to determine version") } + if remote { + v.Server, err = getRemoteVersion(c) + if err != nil { + return err + } + } else { + v.Server = v.Client + } versionOutputFormat := c.Format if versionOutputFormat != "" { @@ -53,11 +80,20 @@ func versionCmd(c *cliconfig.VersionValues) error { var out formats.Writer switch versionOutputFormat { case formats.JSONString: - out = formats.JSONStruct{Output: clientVersion} + out = formats.JSONStruct{Output: v} + return out.Out() default: - out = formats.StdoutTemplate{Output: clientVersion, Template: versionOutputFormat} + out = formats.StdoutTemplate{Output: v, Template: versionOutputFormat} + err := out.Out() + if err != nil { + // On Failure, assume user is using older version of podman version --format and check client + out = formats.StdoutTemplate{Output: v.Client, Template: versionOutputFormat} + if err1 := out.Out(); err1 != nil { + return err + } + } } - return out.Out() + return nil } w := tabwriter.NewWriter(os.Stdout, 0, 0, 2, ' ', 0) defer w.Flush() @@ -66,25 +102,13 @@ func versionCmd(c *cliconfig.VersionValues) error { if _, err := fmt.Fprintf(w, "Client:\n"); err != nil { return err } - } - formatVersion(w, clientVersion) - - if remote { - if _, err := fmt.Fprintf(w, "\nService:\n"); err != nil { - return err - } - - runtime, err := adapter.GetRuntime(getContext(), &c.PodmanCommand) - if err != nil { - return errors.Wrapf(err, "could not get runtime") - } - defer runtime.DeferredShutdown(false) - - serviceVersion, err := runtime.GetVersion() - if err != nil { + formatVersion(w, v.Client) + if _, err := fmt.Fprintf(w, "\nServer:\n"); err != nil { return err } - formatVersion(w, serviceVersion) + formatVersion(w, v.Server) + } else { + formatVersion(w, v.Client) } return nil } diff --git a/completions/bash/podman b/completions/bash/podman index 5634a5d8c..18e2460ec 100644 --- a/completions/bash/podman +++ b/completions/bash/podman @@ -2832,9 +2832,12 @@ _podman_images_prune() { _podman_container_prune() { local options_with_args=" + --filter " local boolean_options=" + -f + --force -h --help " diff --git a/contrib/build_rpm.sh b/contrib/build_rpm.sh index b2560fb1a..507c03591 100644 --- a/contrib/build_rpm.sh +++ b/contrib/build_rpm.sh @@ -22,7 +22,6 @@ declare -a PKGS=(device-mapper-devel \ glib2-devel \ glibc-static \ golang \ - golang-github-cpuguy83-go-md2man \ gpgme-devel \ libassuan-devel \ libseccomp-devel \ @@ -41,14 +40,19 @@ if [ $pkg_manager == "/usr/bin/dnf" ]; then PKGS+=(btrfs-progs-devel) fi +fi +# golang-github-cpuguy83-go-md2man is needed for building man pages +# It is not available by default in CentOS 8 making it optional +if [ -z "$extra_arg" ]; then + PKGS+=(golang-github-cpuguy83-go-md2man) fi echo ${PKGS[*]} $pkg_manager install -y ${PKGS[*]} make -f .copr/Makefile -rpmbuild --rebuild podman-*.src.rpm +rpmbuild --rebuild ${extra_arg:-""} podman-*.src.rpm # Test to make sure the install of the binary works $pkg_manager -y install ~/rpmbuild/RPMS/x86_64/podman-*.x86_64.rpm diff --git a/contrib/spec/podman.spec.in b/contrib/spec/podman.spec.in index f282642f3..4a3704811 100644 --- a/contrib/spec/podman.spec.in +++ b/contrib/spec/podman.spec.in @@ -1,9 +1,9 @@ %global with_devel 0 %global with_bundled 1 -%global with_debug 1 %global with_check 0 %global with_unit_test 0 -%global with_doc 1 +%bcond_without doc +%bcond_without debug %if 0%{?fedora} >= 28 %bcond_without varlink @@ -11,7 +11,7 @@ %bcond_with varlink %endif -%if 0%{?with_debug} +%if %{with debug} %global _find_debuginfo_dwz_opts %{nil} %global _dwz_low_mem_die_limit 0 %else @@ -61,7 +61,7 @@ BuildRequires: glib2-devel BuildRequires: glibc-devel BuildRequires: glibc-static BuildRequires: git -%if 0%{?with_doc} +%if %{with doc} BuildRequires: go-md2man %endif BuildRequires: gpgme-devel @@ -355,6 +355,15 @@ This package contains unit tests for project providing packages with %{import_path} prefix. %endif +%if %{with doc} +%package manpages +Summary: Man pages for the %{name} commands +BuildArch: noarch + +%description manpages +Man pages for the %{name} commands +%endif + %prep %autosetup -Sgit -n %{repo}-%{shortcommit0} @@ -363,7 +372,7 @@ tar zxf %{SOURCE1} sed -i 's/install.remote: podman-remote/install.remote:/' Makefile sed -i 's/install.bin: podman/install.bin:/' Makefile -%if 0%{?with_doc} +%if %{with doc} sed -i 's/install.man: docs/install.man:/' Makefile %endif @@ -379,7 +388,7 @@ export BUILDTAGS="varlink selinux seccomp $(hack/btrfs_installed_tag.sh) $(hack/ GOPATH=$GOPATH go generate ./cmd/podman/varlink/... -%if 0%{?with_doc} +%if %{with doc} BUILDTAGS=$BUILDTAGS make binaries docs %else BUILDTAGS=$BUILDTAGS make binaries @@ -400,6 +409,7 @@ popd %install install -dp %{buildroot}%{_unitdir} install -dp %{buildroot}%{_usr}/lib/systemd/user +%if %{with doc} PODMAN_VERSION=%{version} %{__make} PREFIX=%{buildroot}%{_prefix} ETCDIR=%{buildroot}%{_sysconfdir} \ install.bin \ install.remote \ @@ -407,6 +417,14 @@ PODMAN_VERSION=%{version} %{__make} PREFIX=%{buildroot}%{_prefix} ETCDIR=%{build install.cni \ install.systemd \ install.completions +%else +PODMAN_VERSION=%{version} %{__make} PREFIX=%{buildroot}%{_prefix} ETCDIR=%{buildroot}%{_sysconfdir} \ + install.bin \ + install.remote \ + install.cni \ + install.systemd \ + install.completions +%endif mv pkg/hooks/README.md pkg/hooks/README-hooks.md @@ -489,10 +507,6 @@ export GOPATH=%{buildroot}/%{gopath}:$(pwd)/vendor:%{gopath} %license LICENSE %doc README.md CONTRIBUTING.md pkg/hooks/README-hooks.md install.md code-of-conduct.md transfer.md %{_bindir}/%{name} -%if 0%{?with_doc} -%{_mandir}/man1/*.1* -%{_mandir}/man5/*.5* -%endif %{_datadir}/bash-completion/completions/* %{_datadir}/zsh/site-functions/* %{_libexecdir}/%{name}/conmon @@ -522,6 +536,12 @@ export GOPATH=%{buildroot}/%{gopath}:$(pwd)/vendor:%{gopath} %doc README.md CONTRIBUTING.md pkg/hooks/README-hooks.md install.md code-of-conduct.md transfer.md %{_bindir}/%{name}-remote +%if %{with doc} +%files manpages +%{_mandir}/man1/*.1* +%{_mandir}/man5/*.5* +%endif + %changelog * Sat Aug 4 2018 Dan Walsh <dwalsh@redhat.com> - 0.8.1-1.git6b4ab2a - Bump to v0.8.1 diff --git a/docs/source/markdown/podman-container-prune.1.md b/docs/source/markdown/podman-container-prune.1.md index d8a4b7f4e..856843a80 100644 --- a/docs/source/markdown/podman-container-prune.1.md +++ b/docs/source/markdown/podman-container-prune.1.md @@ -20,6 +20,8 @@ Print usage statement Remove all stopped containers from local storage ``` $ sudo podman container prune +WARNING! This will remove all stopped containers. +Are you sure you want to continue? [y/N] y 878392adf2e6c5c9bb1fc19b69d37d2e98c8abf9d539c0bce4b15b46bbcce471 37664467fbe3618bf9479c34393ac29c02696675addf1750f9e346581636cde7 ed0c6468b8e1cb641b4621d1fe30cb477e1fefc5c0bceb66feaf2f7cb50e5962 @@ -28,6 +30,26 @@ fff1c5b6c3631746055ec40598ce8ecaa4b82aef122f9e3a85b03b55c0d06c23 602d343cd47e7cb3dfc808282a9900a3e4555747787ec6723bb68cedab8384d5 ``` +Remove all stopped containers from local storage without confirmation. +``` +$ sudo podman container prune -f +878392adf2e6c5c9bb1fc19b69d37d2e98c8abf9d539c0bce4b15b46bbcce471 +37664467fbe3618bf9479c34393ac29c02696675addf1750f9e346581636cde7 +ed0c6468b8e1cb641b4621d1fe30cb477e1fefc5c0bceb66feaf2f7cb50e5962 +6ac6c8f0067b7a4682e6b8e18902665b57d1a0e07e885d9abcd382232a543ccd +fff1c5b6c3631746055ec40598ce8ecaa4b82aef122f9e3a85b03b55c0d06c23 +602d343cd47e7cb3dfc808282a9900a3e4555747787ec6723bb68cedab8384d5 + +``` + +Remove all stopped containers from local storage created within last 10 minutes +``` +$ sudo podman container prune --filter until="10m" +WARNING! This will remove all stopped containers. +Are you sure you want to continue? [y/N] y +3d366295e33d8cc612c4d873199bacadd55088d90d17dcafaa9a2d317ad50b4e +``` + ## SEE ALSO podman(1), podman-ps diff --git a/docs/source/markdown/podman-version.1.md b/docs/source/markdown/podman-version.1.md index 4499f6338..de22c4800 100644 --- a/docs/source/markdown/podman-version.1.md +++ b/docs/source/markdown/podman-version.1.md @@ -34,8 +34,8 @@ OS/Arch: linux/amd64 Filtering out only the version: ``` -$ podman version --format '{{.Version}}' -0.11.2 +$ podman version --format '{{.Client.Version}}' +1.6.3 ``` ## SEE ALSO diff --git a/install.md b/install.md index 39b639176..bd3732083 100644 --- a/install.md +++ b/install.md @@ -68,7 +68,7 @@ The latest builds are available in a PPA. Take note of the [Build and Run Depend ```bash sudo apt-get update -qq -sudo apt-get install -qq -y software-properties-common uidmap +sudo apt-get install -qq -y software-properties-common uidmap slirp4netns sudo add-apt-repository -y ppa:projectatomic/ppa sudo apt-get update -qq sudo apt-get -qq -y install podman diff --git a/libpod/oci_util.go b/libpod/oci_util.go index 3345220ac..53567d2d0 100644 --- a/libpod/oci_util.go +++ b/libpod/oci_util.go @@ -82,18 +82,16 @@ func bindPorts(ports []ocicni.PortMapping) ([]*os.File, error) { } func getOCIRuntimeError(runtimeMsg string) error { - r := strings.ToLower(runtimeMsg) - includeFullOutput := logrus.GetLevel() == logrus.DebugLevel - if match := regexp.MustCompile(".*permission denied.*|.*operation not permitted.*").FindString(r); match != "" { + if match := regexp.MustCompile("(?i).*permission denied.*|.*operation not permitted.*").FindString(runtimeMsg); match != "" { errStr := match if includeFullOutput { errStr = runtimeMsg } return errors.Wrapf(define.ErrOCIRuntimePermissionDenied, "%s", strings.Trim(errStr, "\n")) } - if match := regexp.MustCompile(".*executable file not found in.*|.*no such file or directory.*").FindString(r); match != "" { + if match := regexp.MustCompile("(?i).*executable file not found in.*|.*no such file or directory.*").FindString(runtimeMsg); match != "" { errStr := match if includeFullOutput { errStr = runtimeMsg diff --git a/libpod/runtime.go b/libpod/runtime.go index 42e6782e9..3873079ce 100644 --- a/libpod/runtime.go +++ b/libpod/runtime.go @@ -625,7 +625,8 @@ func (r *Runtime) refresh(alivePath string) error { } // Next refresh the state of all containers to recreate dirs and - // namespaces, and all the pods to recreate cgroups + // namespaces, and all the pods to recreate cgroups. + // Containers, pods, and volumes must also reacquire their locks. ctrs, err := r.state.AllContainers() if err != nil { return errors.Wrapf(err, "error retrieving all containers from state") @@ -634,10 +635,14 @@ func (r *Runtime) refresh(alivePath string) error { if err != nil { return errors.Wrapf(err, "error retrieving all pods from state") } - // No locks are taken during pod and container refresh. - // Furthermore, the pod and container refresh() functions are not + vols, err := r.state.AllVolumes() + if err != nil { + return errors.Wrapf(err, "error retrieving all volumes from state") + } + // No locks are taken during pod, volume, and container refresh. + // Furthermore, the pod/volume/container refresh() functions are not // allowed to take locks themselves. - // We cannot assume that any pod or container has a valid lock until + // We cannot assume that any pod/volume/container has a valid lock until // after this function has returned. // The runtime alive lock should suffice to provide mutual exclusion // until this has run. @@ -651,6 +656,11 @@ func (r *Runtime) refresh(alivePath string) error { logrus.Errorf("Error refreshing pod %s: %v", pod.ID(), err) } } + for _, vol := range vols { + if err := vol.refresh(); err != nil { + logrus.Errorf("Error refreshing volume %s: %v", vol.Name(), err) + } + } // Create a file indicating the runtime is alive and ready file, err := os.OpenFile(alivePath, os.O_RDONLY|os.O_CREATE, 0644) diff --git a/libpod/volume_internal.go b/libpod/volume_internal.go index 42b935e7c..e89b3484d 100644 --- a/libpod/volume_internal.go +++ b/libpod/volume_internal.go @@ -5,6 +5,7 @@ import ( "path/filepath" "github.com/containers/libpod/libpod/define" + "github.com/pkg/errors" ) // Creates a new volume @@ -46,3 +47,14 @@ func (v *Volume) update() error { func (v *Volume) save() error { return v.runtime.state.SaveVolume(v) } + +// Refresh volume state after a restart. +func (v *Volume) refresh() error { + lock, err := v.runtime.lockManager.AllocateAndRetrieveLock(v.config.LockID) + if err != nil { + return errors.Wrapf(err, "error acquiring lock %d for volume %s", v.config.LockID, v.Name()) + } + v.lock = lock + + return nil +} diff --git a/pkg/adapter/containers.go b/pkg/adapter/containers.go index bc9554193..0c73977c7 100644 --- a/pkg/adapter/containers.go +++ b/pkg/adapter/containers.go @@ -461,7 +461,8 @@ func (r *LocalRuntime) Run(ctx context.Context, c *cliconfig.RunValues, exitCode if c.IsSet("rm") { if err := r.Runtime.RemoveContainer(ctx, ctr, false, true); err != nil { - if errors.Cause(err) == define.ErrNoSuchCtr { + if errors.Cause(err) == define.ErrNoSuchCtr || + errors.Cause(err) == define.ErrCtrRemoved { logrus.Warnf("Container %s does not exist: %v", ctr.ID(), err) } else { logrus.Errorf("Error removing container %s: %v", ctr.ID(), err) @@ -1009,16 +1010,30 @@ func (r *LocalRuntime) ExecContainer(ctx context.Context, cli *cliconfig.ExecVal } // Prune removes stopped containers -func (r *LocalRuntime) Prune(ctx context.Context, maxWorkers int, force bool) ([]string, map[string]error, error) { +func (r *LocalRuntime) Prune(ctx context.Context, maxWorkers int, force bool, filters []string) ([]string, map[string]error, error) { var ( - ok = []string{} - failures = map[string]error{} - err error + ok = []string{} + failures = map[string]error{} + err error + filterFunc []libpod.ContainerFilter ) logrus.Debugf("Setting maximum rm workers to %d", maxWorkers) - filter := func(c *libpod.Container) bool { + for _, filter := range filters { + filterSplit := strings.SplitN(filter, "=", 2) + if len(filterSplit) < 2 { + return ok, failures, errors.Errorf("filter input must be in the form of filter=value: %s is invalid", filter) + } + + f, err := shared.GenerateContainerFilterFuncs(filterSplit[0], filterSplit[1], r.Runtime) + if err != nil { + return ok, failures, err + } + filterFunc = append(filterFunc, f) + } + + containerStateFilter := func(c *libpod.Container) bool { state, err := c.State() if err != nil { logrus.Error(err) @@ -1032,7 +1047,9 @@ func (r *LocalRuntime) Prune(ctx context.Context, maxWorkers int, force bool) ([ } return false } - delContainers, err := r.Runtime.GetContainers(filter) + filterFunc = append(filterFunc, containerStateFilter) + + delContainers, err := r.Runtime.GetContainers(filterFunc...) if err != nil { return ok, failures, err } diff --git a/pkg/adapter/containers_remote.go b/pkg/adapter/containers_remote.go index e34b8ffd9..36db4af68 100644 --- a/pkg/adapter/containers_remote.go +++ b/pkg/adapter/containers_remote.go @@ -922,7 +922,7 @@ func (r *LocalRuntime) Top(cli *cliconfig.TopValues) ([]string, error) { } // Prune removes stopped containers -func (r *LocalRuntime) Prune(ctx context.Context, maxWorkers int, force bool) ([]string, map[string]error, error) { +func (r *LocalRuntime) Prune(ctx context.Context, maxWorkers int, force bool, filter []string) ([]string, map[string]error, error) { var ( ok = []string{} diff --git a/rootless.md b/rootless.md index 4fb3c7deb..69de6db21 100644 --- a/rootless.md +++ b/rootless.md @@ -42,3 +42,5 @@ can easily fail * Pause and Unpause (Works with cgroup V2 support) * Issues with higher UIDs can cause builds to fail * If a build is attempting to use a UID that is not mapped into the user namespace mapping for a container, then builds will not be able to put the UID in an image. +* Making device nodes within a container fails, even when running --privileged. + * Kernel does not allow non root user processes (processes without CAP_MKNOD) to create device nodes. If container needs to create device nodes, it must be run as root. diff --git a/test/e2e/prune_test.go b/test/e2e/prune_test.go index 16522785b..c9b01ad4a 100644 --- a/test/e2e/prune_test.go +++ b/test/e2e/prune_test.go @@ -52,7 +52,7 @@ var _ = Describe("Podman prune", func() { stop.WaitWithDefaultTimeout() Expect(stop.ExitCode()).To(Equal(0)) - prune := podmanTest.Podman([]string{"container", "prune"}) + prune := podmanTest.Podman([]string{"container", "prune", "-f"}) prune.WaitWithDefaultTimeout() Expect(prune.ExitCode()).To(Equal(0)) diff --git a/test/e2e/version_test.go b/test/e2e/version_test.go index 0db2e2cf2..c2af613aa 100644 --- a/test/e2e/version_test.go +++ b/test/e2e/version_test.go @@ -33,7 +33,6 @@ var _ = Describe("Podman version", func() { }) It("podman version", func() { - SkipIfRemote() session := podmanTest.Podman([]string{"version"}) session.WaitWithDefaultTimeout() Expect(session.ExitCode()).To(Equal(0)) @@ -43,7 +42,6 @@ var _ = Describe("Podman version", func() { }) It("podman -v", func() { - SkipIfRemote() session := podmanTest.Podman([]string{"-v"}) session.WaitWithDefaultTimeout() Expect(session.ExitCode()).To(Equal(0)) @@ -52,7 +50,6 @@ var _ = Describe("Podman version", func() { }) It("podman --version", func() { - SkipIfRemote() session := podmanTest.Podman([]string{"--version"}) session.WaitWithDefaultTimeout() Expect(session.ExitCode()).To(Equal(0)) @@ -61,7 +58,6 @@ var _ = Describe("Podman version", func() { }) It("podman version --format json", func() { - SkipIfRemote() session := podmanTest.Podman([]string{"version", "--format", "json"}) session.WaitWithDefaultTimeout() Expect(session.ExitCode()).To(Equal(0)) @@ -69,7 +65,6 @@ var _ = Describe("Podman version", func() { }) It("podman version --format json", func() { - SkipIfRemote() session := podmanTest.Podman([]string{"version", "--format", "{{ json .}}"}) session.WaitWithDefaultTimeout() Expect(session.ExitCode()).To(Equal(0)) @@ -77,8 +72,15 @@ var _ = Describe("Podman version", func() { }) It("podman version --format GO template", func() { - SkipIfRemote() - session := podmanTest.Podman([]string{"version", "--format", "{{ .Version }}"}) + session := podmanTest.Podman([]string{"version", "--format", "{{ .Client.Version }}"}) + session.WaitWithDefaultTimeout() + Expect(session.ExitCode()).To(Equal(0)) + + session = podmanTest.Podman([]string{"version", "--format", "{{ .Server.Version }}"}) + session.WaitWithDefaultTimeout() + Expect(session.ExitCode()).To(Equal(0)) + + session = podmanTest.Podman([]string{"version", "--format", "{{ .Version }}"}) session.WaitWithDefaultTimeout() Expect(session.ExitCode()).To(Equal(0)) }) |