summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.copr/Makefile4
-rw-r--r--.copr/prepare.sh17
-rw-r--r--Makefile16
-rw-r--r--cmd/podman/cliconfig/config.go3
-rw-r--r--cmd/podman/containers_prune.go21
-rw-r--r--cmd/podman/shared/container.go22
-rw-r--r--cmd/podman/system_prune.go2
-rw-r--r--cmd/podman/version.go66
-rw-r--r--completions/bash/podman3
-rw-r--r--contrib/build_rpm.sh8
-rw-r--r--contrib/spec/podman.spec.in40
-rw-r--r--docs/source/markdown/podman-container-prune.1.md22
-rw-r--r--docs/source/markdown/podman-version.1.md4
-rw-r--r--install.md2
-rw-r--r--libpod/oci_util.go6
-rw-r--r--libpod/runtime.go18
-rw-r--r--libpod/volume_internal.go12
-rw-r--r--pkg/adapter/containers.go31
-rw-r--r--pkg/adapter/containers_remote.go2
-rw-r--r--rootless.md2
-rw-r--r--test/e2e/prune_test.go2
-rw-r--r--test/e2e/version_test.go16
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
diff --git a/Makefile b/Makefile
index dd948fc8e..d7c3cf7bd 100644
--- a/Makefile
+++ b/Makefile
@@ -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))
})