diff options
| -rw-r--r-- | cmd/podman/system/reset.go | 14 | ||||
| -rw-r--r-- | contrib/podmanimage/stable/Containerfile | 56 | ||||
| -rw-r--r-- | contrib/podmanimage/stable/Dockerfile | 36 | ||||
| -rw-r--r-- | contrib/podmanimage/stable/storage.conf | 6 | ||||
| -rw-r--r-- | contrib/podmanimage/testing/Containerfile | 61 | ||||
| -rw-r--r-- | contrib/podmanimage/testing/Dockerfile | 36 | ||||
| -rw-r--r-- | contrib/podmanimage/upstream/Containerfile | 62 | ||||
| -rw-r--r-- | contrib/podmanimage/upstream/Dockerfile | 85 | ||||
| -rw-r--r-- | libpod/options.go | 15 | ||||
| -rw-r--r-- | libpod/reset.go | 72 | ||||
| -rw-r--r-- | libpod/runtime.go | 60 | ||||
| -rw-r--r-- | pkg/api/handlers/libpod/play.go | 4 | ||||
| -rw-r--r-- | pkg/domain/infra/abi/system.go | 2 | ||||
| -rw-r--r-- | pkg/domain/infra/runtime_abi.go | 2 | ||||
| -rw-r--r-- | pkg/domain/infra/runtime_libpod.go | 21 | ||||
| -rw-r--r-- | test/e2e/save_test.go | 8 |
16 files changed, 363 insertions, 177 deletions
diff --git a/cmd/podman/system/reset.go b/cmd/podman/system/reset.go index 176573bf6..20f15a34f 100644 --- a/cmd/podman/system/reset.go +++ b/cmd/podman/system/reset.go @@ -91,18 +91,10 @@ func reset(cmd *cobra.Command, args []string) { registry.ContainerEngine().Shutdown(registry.Context()) registry.ImageEngine().Shutdown(registry.Context()) - engine, err := infra.NewSystemEngine(entities.ResetMode, registry.PodmanConfig()) - if err != nil { - logrus.Error(err) - os.Exit(define.ExecErrorCodeGeneric) - } - defer engine.Shutdown(registry.Context()) - - if err := engine.Reset(registry.Context()); err != nil { + // Do not try to shut the engine down, as a Reset engine is not valid + // after its creation. + if _, err := infra.NewSystemEngine(entities.ResetMode, registry.PodmanConfig()); err != nil { logrus.Error(err) - // FIXME change this to return the error like other commands - // defer will never run on os.Exit() - //nolint:gocritic os.Exit(define.ExecErrorCodeGeneric) } diff --git a/contrib/podmanimage/stable/Containerfile b/contrib/podmanimage/stable/Containerfile new file mode 100644 index 000000000..40a2cb5f3 --- /dev/null +++ b/contrib/podmanimage/stable/Containerfile @@ -0,0 +1,56 @@ +# stable/Containerfile +# +# Build a Podman container image from the latest +# stable version of Podman on the Fedoras Updates System. +# https://bodhi.fedoraproject.org/updates/?search=podman +# This image can be used to create a secured container +# that runs safely with privileges within the container. +# +FROM registry.fedoraproject.org/fedora:latest + +# Don't include container-selinux and remove +# directories used by dnf that are just taking +# up space. +RUN dnf -y update && \ + rpm --setcaps shadow-utils 2>/dev/null && \ + dnf -y install podman fuse-overlayfs \ + --exclude container-selinux && \ + dnf clean all && \ + rm -rf /var/cache /var/log/dnf* /var/log/yum.* + +RUN useradd podman; \ +echo -e "podman:1:999\npodman:1001:64535" > /etc/subuid; \ +echo -e "podman:1:999\npodman:1001:64535" > /etc/subgid; + +ARG _REPO_URL="https://raw.githubusercontent.com/containers/podman/main/contrib/podmanimage/stable" +ADD $_REPO_URL/storage.conf /etc/containers/storage.conf +ADD $_REPO_URL/containers.conf /etc/containers/containers.conf +ADD $_REPO_URL/podman-containers.conf /home/podman/.config/containers/containers.conf + +RUN mkdir -p /home/podman/.local/share/containers && \ + chown podman:podman -R /home/podman && \ + chmod 644 /etc/containers/containers.conf + +# Copy & modify the defaults to provide reference if runtime changes needed. +# Changes here are required for running with fuse-overlay storage inside container. +RUN sed -i -e 's|^#mount_program|mount_program|g' \ + -e '/additionalimage.*/a "/var/lib/shared",' \ + -e 's|^mountopt[[:space:]]*=.*$|mountopt = "nodev,fsync=0"|g' \ + /usr/share/containers/storage.conf \ + > /etc/containers/storage.conf + +# Note VOLUME options must always happen after the chown call above +# RUN commands can not modify existing volumes +VOLUME /var/lib/containers +VOLUME /home/podman/.local/share/containers + +RUN mkdir -p /var/lib/shared/overlay-images \ + /var/lib/shared/overlay-layers \ + /var/lib/shared/vfs-images \ + /var/lib/shared/vfs-layers && \ + touch /var/lib/shared/overlay-images/images.lock && \ + touch /var/lib/shared/overlay-layers/layers.lock && \ + touch /var/lib/shared/vfs-images/images.lock && \ + touch /var/lib/shared/vfs-layers/layers.lock + +ENV _CONTAINERS_USERNS_CONFIGURED="" diff --git a/contrib/podmanimage/stable/Dockerfile b/contrib/podmanimage/stable/Dockerfile deleted file mode 100644 index 78d820458..000000000 --- a/contrib/podmanimage/stable/Dockerfile +++ /dev/null @@ -1,36 +0,0 @@ -# stable/Dockerfile -# -# Build a Podman container image from the latest -# stable version of Podman on the Fedoras Updates System. -# https://bodhi.fedoraproject.org/updates/?search=podman -# This image can be used to create a secured container -# that runs safely with privileges within the container. -# -FROM registry.fedoraproject.org/fedora:latest - -# Don't include container-selinux and remove -# directories used by yum that are just taking -# up space. -RUN dnf -y update; rpm --restore shadow-utils 2>/dev/null; \ -yum -y install podman fuse-overlayfs --exclude container-selinux; \ -rm -rf /var/cache /var/log/dnf* /var/log/yum.* - -RUN useradd podman; \ -echo -e "podman:1:999\npodman:1001:64535" > /etc/subuid; \ -echo -e "podman:1:999\npodman:1001:64535" > /etc/subgid; - -ADD https://raw.githubusercontent.com/containers/podman/main/contrib/podmanimage/stable/containers.conf /etc/containers/containers.conf -ADD https://raw.githubusercontent.com/containers/podman/main/contrib/podmanimage/stable/podman-containers.conf /home/podman/.config/containers/containers.conf - -RUN mkdir -p /home/podman/.local/share/containers; chown podman:podman -R /home/podman - -# Note VOLUME options must always happen after the chown call above -# RUN commands can not modify existing volumes -VOLUME /var/lib/containers -VOLUME /home/podman/.local/share/containers - -# chmod containers.conf and adjust storage.conf to enable Fuse storage. -RUN chmod 644 /etc/containers/containers.conf; sed -i -e 's|^#mount_program|mount_program|g' -e '/additionalimage.*/a "/var/lib/shared",' -e 's|^mountopt[[:space:]]*=.*$|mountopt = "nodev,fsync=0"|g' /etc/containers/storage.conf -RUN mkdir -p /var/lib/shared/overlay-images /var/lib/shared/overlay-layers /var/lib/shared/vfs-images /var/lib/shared/vfs-layers; touch /var/lib/shared/overlay-images/images.lock; touch /var/lib/shared/overlay-layers/layers.lock; touch /var/lib/shared/vfs-images/images.lock; touch /var/lib/shared/vfs-layers/layers.lock - -ENV _CONTAINERS_USERNS_CONFIGURED="" diff --git a/contrib/podmanimage/stable/storage.conf b/contrib/podmanimage/stable/storage.conf new file mode 100644 index 000000000..bc8d8c111 --- /dev/null +++ b/contrib/podmanimage/stable/storage.conf @@ -0,0 +1,6 @@ +[storage.options] +additionalimagestores = ["/var/lib/shared"] + +[storage.options.overlay] +mountopt = "nodev,fsync=0" +mount_program = "/usr/bin/fuse-overlayfs" diff --git a/contrib/podmanimage/testing/Containerfile b/contrib/podmanimage/testing/Containerfile new file mode 100644 index 000000000..5fa794baf --- /dev/null +++ b/contrib/podmanimage/testing/Containerfile @@ -0,0 +1,61 @@ +# testing/Containerfile +# +# Build a Podman container image from the latest +# stable version of Podman on the Fedoras Updates System. +# https://bodhi.fedoraproject.org/updates/?search=podman +# This image can be used to create a secured container +# that runs safely with privileges within the container. +# +FROM registry.fedoraproject.org/fedora:latest + +# Don't include container-selinux and remove +# directories used by dnf that are just taking +# up space. +RUN dnf -y update && \ + rpm --setcaps shadow-utils 2>/dev/null && \ + dnf -y install podman fuse-overlayfs \ + --exclude container-selinux --enablerepo updates-testing && \ + dnf clean all && \ + rm -rf /var/cache /var/log/dnf* /var/log/yum.* + +RUN useradd podman; \ +echo -e "podman:1:999\npodman:1001:64535" > /etc/subuid; \ +echo -e "podman:1:999\npodman:1001:64535" > /etc/subgid; + +ARG _REPO_URL="https://raw.githubusercontent.com/containers/podman/main/contrib/podmanimage/stable" +ADD $_REPO_URL/storage.conf /etc/containers/storage.conf +ADD $_REPO_URL/containers.conf /etc/containers/containers.conf +ADD $_REPO_URL/podman-containers.conf /home/podman/.config/containers/containers.conf + +RUN mkdir -p /home/podman/.local/share/containers && \ + chown podman:podman -R /home/podman + +# Copy & modify the defaults to provide reference if runtime changes needed. +# Changes here are required for running with fuse-overlay storage inside container. +RUN sed -i -e 's|^#mount_program|mount_program|g' \ + -e '/additionalimage.*/a "/var/lib/shared",' \ + -e 's|^mountopt[[:space:]]*=.*$|mountopt = "nodev,fsync=0"|g' \ + /usr/share/containers/storage.conf \ + > /etc/containers/storage.conf + +# Note VOLUME options must always happen after the chown call above +# RUN commands can not modify existing volumes +VOLUME /var/lib/containers +VOLUME /home/podman/.local/share/containers + +# chmod containers.conf and adjust storage.conf to enable Fuse storage. +RUN chmod 644 /etc/containers/containers.conf && \ + sed -i -e 's|^#mount_program|mount_program|g' \ + -e '/additionalimage.*/a "/var/lib/shared",' \ + -e 's|^mountopt[[:space:]]*=.*$|mountopt = "nodev,fsync=0"|g' \ + /etc/containers/storage.conf +RUN mkdir -p /var/lib/shared/overlay-images \ + /var/lib/shared/overlay-layers \ + /var/lib/shared/vfs-images \ + /var/lib/shared/vfs-layers && \ + touch /var/lib/shared/overlay-images/images.lock && \ + touch /var/lib/shared/overlay-layers/layers.lock && \ + touch /var/lib/shared/vfs-images/images.lock && \ + touch /var/lib/shared/vfs-layers/layers.lock + +ENV _CONTAINERS_USERNS_CONFIGURED="" diff --git a/contrib/podmanimage/testing/Dockerfile b/contrib/podmanimage/testing/Dockerfile deleted file mode 100644 index 41af1c849..000000000 --- a/contrib/podmanimage/testing/Dockerfile +++ /dev/null @@ -1,36 +0,0 @@ -# testing/Dockerfile -# -# Build a Podman image using the latest -# version of Podman that is in updates-testing -# on the Fedoras Updates System. At times this -# may be the same the latest stable version. -# https://bodhi.fedoraproject.org/updates/?search=podman -# This image can be used to create a secured container -# that runs safely with privileges within the container. -# -FROM registry.fedoraproject.org/fedora:latest - -# Don't include container-selinux and remove -# directories used by yum that are just taking -# up space. -RUN yum -y update; rpm --restore shadow-utils 2>/dev/null; yum -y install podman fuse-overlayfs --exclude container-selinux --enablerepo updates-testing; rm -rf /var/cache /var/log/dnf* /var/log/yum.* - -RUN useradd podman; \ -echo -e "podman:1:999\npodman:1001:64535" > /etc/subuid; \ -echo -e "podman:1:999\npodman:1001:64535" > /etc/subgid; - -ADD https://raw.githubusercontent.com/containers/podman/main/contrib/podmanimage/stable/containers.conf /etc/containers/containers.conf -ADD https://raw.githubusercontent.com/containers/podman/main/contrib/podmanimage/stable/podman-containers.conf /home/podman/.config/containers/containers.conf - -RUN mkdir -p /home/podman/.local/share/containers; chown podman:podman -R /home/podman - -# Note VOLUME options must always happen after the chown call above -# RUN commands can not modify existing volumes -VOLUME /var/lib/containers -VOLUME /home/podman/.local/share/containers - -# chmod containers.conf and adjust storage.conf to enable Fuse storage. -RUN chmod 644 /etc/containers/containers.conf; sed -i -e 's|^#mount_program|mount_program|g' -e '/additionalimage.*/a "/var/lib/shared",' -e 's|^mountopt[[:space:]]*=.*$|mountopt = "nodev,fsync=0"|g' /etc/containers/storage.conf -RUN mkdir -p /var/lib/shared/overlay-images /var/lib/shared/overlay-layers /var/lib/shared/vfs-images /var/lib/shared/vfs-layers; touch /var/lib/shared/overlay-images/images.lock; touch /var/lib/shared/overlay-layers/layers.lock; touch /var/lib/shared/vfs-images/images.lock; touch /var/lib/shared/vfs-layers/layers.lock - -ENV _CONTAINERS_USERNS_CONFIGURED="" diff --git a/contrib/podmanimage/upstream/Containerfile b/contrib/podmanimage/upstream/Containerfile new file mode 100644 index 000000000..b338a33ae --- /dev/null +++ b/contrib/podmanimage/upstream/Containerfile @@ -0,0 +1,62 @@ +# upstream/Containerfile +# +# Build a Podman container image from the latest +# upstream version of Podman on GitHub. +# https://github.com/containers/podman +# This image can be used to create a secured container +# that runs safely with privileges within the container. +# The containers created by this image also come with a +# Podman development environment in /root/podman. +# +FROM registry.fedoraproject.org/fedora:latest + +# Don't include container-selinux and remove +# directories used by dnf that are just taking +# up space. The latest podman + deps. come from +# https://copr.fedorainfracloud.org/coprs/rhcontainerbot/podman-next/ +RUN dnf -y update && \ + rpm --setcaps shadow-utils 2>/dev/null && \ + dnf -y install 'dnf-command(copr)' --enablerepo=updates-testing && \ + dnf -y copr enable rhcontainerbot/podman-next && \ + dnf -y install podman fuse-overlayfs \ + --exclude container-selinux \ + --enablerepo=updates-testing && \ + dnf clean all && \ + rm -rf /var/cache /var/log/dnf* /var/log/yum.* + +RUN useradd podman; \ +echo -e "podman:1:999\npodman:1001:64535" > /etc/subuid; \ +echo -e "podman:1:999\npodman:1001:64535" > /etc/subgid; + +ARG _REPO_URL="https://raw.githubusercontent.com/containers/podman/main/contrib/podmanimage/stable" +ADD $_REPO_URL/storage.conf /etc/containers/storage.conf +ADD $_REPO_URL/containers.conf /etc/containers/containers.conf +ADD $_REPO_URL/podman-containers.conf /home/podman/.config/containers/containers.conf + +RUN mkdir -p /home/podman/.local/share/containers && \ + chown podman:podman -R /home/podman && \ + chmod 644 /etc/containers/containers.conf + +# Copy & modify the defaults to provide reference if runtime changes needed. +# Changes here are required for running with fuse-overlay storage inside container. +RUN sed -i -e 's|^#mount_program|mount_program|g' \ + -e '/additionalimage.*/a "/var/lib/shared",' \ + -e 's|^mountopt[[:space:]]*=.*$|mountopt = "nodev,fsync=0"|g' \ + /usr/share/containers/storage.conf \ + > /etc/containers/storage.conf + +# Note VOLUME options must always happen after the chown call above +# RUN commands can not modify existing volumes +VOLUME /var/lib/containers +VOLUME /home/podman/.local/share/containers + +RUN mkdir -p /var/lib/shared/overlay-images \ + /var/lib/shared/overlay-layers \ + /var/lib/shared/vfs-images \ + /var/lib/shared/vfs-layers && \ + touch /var/lib/shared/overlay-images/images.lock && \ + touch /var/lib/shared/overlay-layers/layers.lock && \ + touch /var/lib/shared/vfs-images/images.lock && \ + touch /var/lib/shared/vfs-layers/layers.lock + +ENV _CONTAINERS_USERNS_CONFIGURED="" diff --git a/contrib/podmanimage/upstream/Dockerfile b/contrib/podmanimage/upstream/Dockerfile deleted file mode 100644 index 0769a7612..000000000 --- a/contrib/podmanimage/upstream/Dockerfile +++ /dev/null @@ -1,85 +0,0 @@ -# git/Dockerfile -# -# Build a Podman container image from the latest -# upstream version of Podman on GitHub. -# https://github.com/containers/podman -# This image can be used to create a secured container -# that runs safely with privileges within the container. -# The containers created by this image also come with a -# Podman development environment in /root/podman. -# -FROM registry.fedoraproject.org/fedora:latest -ENV GOPATH=/root/podman - -# Install the software required to build Podman. -# Then create a directory and clone from the Podman -# GitHub repository, make and install Podman -# to the container. -# Finally remove the podman directory and a few other packages -# that are needed for building but not running Podman -RUN yum -y update; rpm --restore shadow-utils 2>/dev/null; yum -y install --exclude container-selinux \ - --enablerepo=updates-testing \ - btrfs-progs-devel \ - containernetworking-cni \ - conmon \ - device-mapper-devel \ - git \ - glib2-devel \ - glibc-devel \ - glibc-static \ - go \ - golang-github-cpuguy83-md2man \ - gpgme-devel \ - iptables \ - libassuan-devel \ - libgpg-error-devel \ - libseccomp-devel \ - libselinux-devel \ - make \ - pkgconfig \ - crun \ - fuse-overlayfs \ - fuse3 \ - containers-common \ - podman-plugins; \ - mkdir /root/podman; \ - git clone https://github.com/containers/podman /root/podman/src/github.com/containers/podman; \ - cd /root/podman/src/github.com/containers/podman; \ - make BUILDTAGS="selinux seccomp"; \ - make install PREFIX=/usr; \ - cd /root/podman; \ - git clone https://github.com/containers/conmon /root/podman/conmon; \ - cd conmon; \ - make; \ - install -D -m 755 bin/conmon /usr/libexec/podman/conmon; \ - git clone https://github.com/containernetworking/plugins.git $GOPATH/src/github.com/containernetworking/plugins; \ - cd $GOPATH/src/github.com/containernetworking/plugins; \ - ./build_linux.sh; \ - mkdir -p /usr/libexec/cni; \ - \cp -fR bin/* /usr/libexec/cni; \ - mkdir -p /etc/cni/net.d; \ - curl -qsSL https://raw.githubusercontent.com/containers/podman/main/cni/87-podman-bridge.conflist | tee /etc/cni/net.d/99-loopback.conf; \ - mkdir -p /usr/share/containers; \ - rm -rf /root/podman/*; \ - yum -y remove git golang go-md2man make; \ - yum clean all; - -RUN useradd podman; \ -echo -e "podman:1:999\npodman:1001:64535" > /etc/subuid; \ -echo -e "podman:1:999\npodman:1001:64535" > /etc/subgid; - -ADD https://raw.githubusercontent.com/containers/podman/main/contrib/podmanimage/stable/containers.conf /etc/containers/containers.conf -ADD https://raw.githubusercontent.com/containers/podman/main/contrib/podmanimage/stable/podman-containers.conf /home/podman/.config/containers/containers.conf - -RUN mkdir -p /home/podman/.local/share/containers; chown podman:podman -R /home/podman - -# Note VOLUME options must always happen after the chown call above -# RUN commands can not modify existing volumes -VOLUME /var/lib/containers -VOLUME /home/podman/.local/share/containers - -# chmod containers.conf and adjust storage.conf to enable Fuse storage. -RUN chmod 644 /etc/containers/containers.conf; sed -i -e 's|^#mount_program|mount_program|g' -e '/additionalimage.*/a "/var/lib/shared",' -e 's|^mountopt[[:space:]]*=.*$|mountopt = "nodev,fsync=0"|g' /etc/containers/storage.conf -RUN mkdir -p /var/lib/shared/overlay-images /var/lib/shared/overlay-layers /var/lib/shared/vfs-images /var/lib/shared/vfs-layers; touch /var/lib/shared/overlay-images/images.lock; touch /var/lib/shared/overlay-layers/layers.lock; touch /var/lib/shared/vfs-images/images.lock; touch /var/lib/shared/vfs-layers/layers.lock - -ENV _CONTAINERS_USERNS_CONFIGURED="" diff --git a/libpod/options.go b/libpod/options.go index a02c05537..4b6803c3f 100644 --- a/libpod/options.go +++ b/libpod/options.go @@ -435,6 +435,21 @@ func WithDefaultInfraCommand(cmd string) RuntimeOption { } } +// WithReset instructs libpod to reset all storage to factory defaults. +// All containers, pods, volumes, images, and networks will be removed. +// All directories created by Libpod will be removed. +func WithReset() RuntimeOption { + return func(rt *Runtime) error { + if rt.valid { + return define.ErrRuntimeFinalized + } + + rt.doReset = true + + return nil + } +} + // WithRenumber instructs libpod to perform a lock renumbering while // initializing. This will handle migrations from early versions of libpod with // file locks to newer versions with SHM locking, as well as changes in the diff --git a/libpod/reset.go b/libpod/reset.go index 28d0ee3f6..30eab50fb 100644 --- a/libpod/reset.go +++ b/libpod/reset.go @@ -17,8 +17,78 @@ import ( "github.com/sirupsen/logrus" ) +// removeAllDirs removes all Podman storage directories. It is intended to be +// used as a backup for reset() when that function cannot be used due to +// failures in initializing libpod. +// It does not expect that all the directories match what is in use by Podman, +// as this is a common failure point for `system reset`. As such, our ability to +// interface with containers and pods is somewhat limited. +// This function assumes that we do not have a working c/storage store. +func (r *Runtime) removeAllDirs() error { + var lastErr error + + // Grab the runtime alive lock. + // This ensures that no other Podman process can run while we are doing + // a reset, so no race conditions with containers/pods/etc being created + // while we are resetting storage. + // TODO: maybe want a helper for getting the path? This is duped from + // runtime.go + runtimeAliveLock := filepath.Join(r.config.Engine.TmpDir, "alive.lck") + aliveLock, err := storage.GetLockfile(runtimeAliveLock) + if err != nil { + logrus.Errorf("Lock runtime alive lock %s: %v", runtimeAliveLock, err) + } else { + aliveLock.Lock() + defer aliveLock.Unlock() + } + + // We do not have a store - so we can't really try and remove containers + // or pods or volumes... + // Try and remove the directories, in hopes that they are unmounted. + // This is likely to fail but it's the best we can do. + + // Volume path + if err := os.RemoveAll(r.config.Engine.VolumePath); err != nil { + lastErr = errors.Wrapf(err, "removing volume path") + } + + // Tmpdir + if err := os.RemoveAll(r.config.Engine.TmpDir); err != nil { + if lastErr != nil { + logrus.Errorf("Reset: %v", lastErr) + } + lastErr = errors.Wrapf(err, "removing tmp dir") + } + + // Runroot + if err := os.RemoveAll(r.storageConfig.RunRoot); err != nil { + if lastErr != nil { + logrus.Errorf("Reset: %v", lastErr) + } + lastErr = errors.Wrapf(err, "removing run root") + } + + // Static dir + if err := os.RemoveAll(r.config.Engine.StaticDir); err != nil { + if lastErr != nil { + logrus.Errorf("Reset: %v", lastErr) + } + lastErr = errors.Wrapf(err, "removing static dir") + } + + // Graph root + if err := os.RemoveAll(r.storageConfig.GraphRoot); err != nil { + if lastErr != nil { + logrus.Errorf("Reset: %v", lastErr) + } + lastErr = errors.Wrapf(err, "removing graph root") + } + + return lastErr +} + // Reset removes all storage -func (r *Runtime) Reset(ctx context.Context) error { +func (r *Runtime) reset(ctx context.Context) error { var timeout *uint pods, err := r.GetAllPods() if err != nil { diff --git a/libpod/runtime.go b/libpod/runtime.go index e268c2d17..10c6d21c5 100644 --- a/libpod/runtime.go +++ b/libpod/runtime.go @@ -96,6 +96,10 @@ type Runtime struct { // This bool is just needed so that we can set it for netavark interface. syslog bool + // doReset indicates that the runtime should perform a system reset. + // All Podman files will be removed. + doReset bool + // doRenumber indicates that the runtime should perform a lock renumber // during initialization. // Once the runtime has been initialized and returned, this variable is @@ -235,6 +239,11 @@ func newRuntimeFromConfig(conf *config.Config, options ...RuntimeOption) (*Runti runtime.config.CheckCgroupsAndAdjustConfig() + // If resetting storage, do *not* return a runtime. + if runtime.doReset { + return nil, nil + } + return runtime, nil } @@ -305,6 +314,13 @@ func makeRuntime(runtime *Runtime) (retErr error) { } runtime.conmonPath = cPath + if runtime.noStore && runtime.doReset { + return errors.Wrapf(define.ErrInvalidArg, "cannot perform system reset if runtime is not creating a store") + } + if runtime.doReset && runtime.doRenumber { + return errors.Wrapf(define.ErrInvalidArg, "cannot perform system reset while renumbering locks") + } + // Make the static files directory if it does not exist if err := os.MkdirAll(runtime.config.Engine.StaticDir, 0700); err != nil { // The directory is allowed to exist @@ -339,6 +355,20 @@ func makeRuntime(runtime *Runtime) (retErr error) { // Grab config from the database so we can reset some defaults dbConfig, err := runtime.state.GetDBConfig() if err != nil { + if runtime.doReset { + // We can at least delete the DB and the static files + // directory. + // Can't safely touch anything else because we aren't + // sure of other directories. + if err := runtime.state.Close(); err != nil { + logrus.Errorf("Closing database connection: %v", err) + } else { + if err := os.RemoveAll(runtime.config.Engine.StaticDir); err != nil { + logrus.Errorf("Removing static files directory %v: %v", runtime.config.Engine.StaticDir, err) + } + } + } + return errors.Wrapf(err, "error retrieving runtime configuration from database") } @@ -372,7 +402,13 @@ func makeRuntime(runtime *Runtime) (retErr error) { // Validate our config against the database, now that we've set our // final storage configuration if err := runtime.state.ValidateDBConfig(runtime); err != nil { - return err + // If we are performing a storage reset: continue on with a + // warning. Otherwise we can't `system reset` after a change to + // the core paths. + if !runtime.doReset { + return err + } + logrus.Errorf("Runtime paths differ from those stored in database, storage reset may not remove all files") } if err := runtime.state.SetNamespace(runtime.config.Engine.Namespace); err != nil { @@ -394,6 +430,14 @@ func makeRuntime(runtime *Runtime) (retErr error) { } else if runtime.noStore { logrus.Debug("No store required. Not opening container store.") } else if err := runtime.configureStore(); err != nil { + // Make a best-effort attempt to clean up if performing a + // storage reset. + if runtime.doReset { + if err := runtime.removeAllDirs(); err != nil { + logrus.Errorf("Removing libpod directories: %v", err) + } + } + return err } defer func() { @@ -575,6 +619,18 @@ func makeRuntime(runtime *Runtime) (retErr error) { return err } + // If we're resetting storage, do it now. + // We will not return a valid runtime. + // TODO: Plumb this context out so it can be set. + if runtime.doReset { + // Mark the runtime as valid, so normal functionality "mostly" + // works and we can use regular functions to remove + // ctrs/pods/etc + runtime.valid = true + + return runtime.reset(context.Background()) + } + // If we're renumbering locks, do it now. // It breaks out of normal runtime init, and will not return a valid // runtime. @@ -818,7 +874,7 @@ func (r *Runtime) DeferredShutdown(force bool) { // still containers running or mounted func (r *Runtime) Shutdown(force bool) error { if !r.valid { - return define.ErrRuntimeStopped + return nil } if r.workerChannel != nil { diff --git a/pkg/api/handlers/libpod/play.go b/pkg/api/handlers/libpod/play.go index b71afc28c..36e61c986 100644 --- a/pkg/api/handlers/libpod/play.go +++ b/pkg/api/handlers/libpod/play.go @@ -77,7 +77,7 @@ func PlayKube(w http.ResponseWriter, r *http.Request) { utils.Error(w, http.StatusInternalServerError, err) return } - query.LogDriver = config.Containers.LogDriver + logDriver = config.Containers.LogDriver } containerEngine := abi.ContainerEngine{Libpod: runtime} @@ -89,7 +89,7 @@ func PlayKube(w http.ResponseWriter, r *http.Request) { Networks: query.Network, NoHosts: query.NoHosts, Quiet: true, - LogDriver: query.LogDriver, + LogDriver: logDriver, LogOptions: query.LogOptions, StaticIPs: staticIPs, StaticMACs: staticMACs, diff --git a/pkg/domain/infra/abi/system.go b/pkg/domain/infra/abi/system.go index 2ce190464..762f0d79a 100644 --- a/pkg/domain/infra/abi/system.go +++ b/pkg/domain/infra/abi/system.go @@ -328,7 +328,7 @@ func (ic *ContainerEngine) SystemDf(ctx context.Context, options entities.System } func (se *SystemEngine) Reset(ctx context.Context) error { - return se.Libpod.Reset(ctx) + return nil } func (se *SystemEngine) Renumber(ctx context.Context, flags *pflag.FlagSet, config *entities.PodmanConfig) error { diff --git a/pkg/domain/infra/runtime_abi.go b/pkg/domain/infra/runtime_abi.go index 39989c96b..7b5198d2f 100644 --- a/pkg/domain/infra/runtime_abi.go +++ b/pkg/domain/infra/runtime_abi.go @@ -53,7 +53,7 @@ func NewSystemEngine(setup entities.EngineSetup, facts *entities.PodmanConfig) ( case entities.RenumberMode: r, err = GetRuntimeRenumber(context.Background(), facts.FlagSet, facts) case entities.ResetMode: - r, err = GetRuntimeRenumber(context.Background(), facts.FlagSet, facts) + r, err = GetRuntimeReset(context.Background(), facts.FlagSet, facts) case entities.MigrateMode: name, flagErr := facts.FlagSet.GetString("new-runtime") if flagErr != nil { diff --git a/pkg/domain/infra/runtime_libpod.go b/pkg/domain/infra/runtime_libpod.go index daa6f0cbf..03e7ffb5d 100644 --- a/pkg/domain/infra/runtime_libpod.go +++ b/pkg/domain/infra/runtime_libpod.go @@ -37,6 +37,7 @@ type engineOpts struct { migrate bool noStore bool withFDS bool + reset bool config *entities.PodmanConfig } @@ -48,6 +49,7 @@ func GetRuntimeMigrate(ctx context.Context, fs *flag.FlagSet, cfg *entities.Podm migrate: true, noStore: false, withFDS: true, + reset: false, config: cfg, }) } @@ -59,6 +61,7 @@ func GetRuntimeDisableFDs(ctx context.Context, fs *flag.FlagSet, cfg *entities.P migrate: false, noStore: false, withFDS: false, + reset: false, config: cfg, }) } @@ -70,6 +73,7 @@ func GetRuntimeRenumber(ctx context.Context, fs *flag.FlagSet, cfg *entities.Pod migrate: false, noStore: false, withFDS: true, + reset: false, config: cfg, }) } @@ -82,6 +86,7 @@ func GetRuntime(ctx context.Context, flags *flag.FlagSet, cfg *entities.PodmanCo migrate: false, noStore: false, withFDS: true, + reset: false, config: cfg, }) }) @@ -95,6 +100,18 @@ func GetRuntimeNoStore(ctx context.Context, fs *flag.FlagSet, cfg *entities.Podm migrate: false, noStore: true, withFDS: true, + reset: false, + config: cfg, + }) +} + +func GetRuntimeReset(ctx context.Context, fs *flag.FlagSet, cfg *entities.PodmanConfig) (*libpod.Runtime, error) { + return getRuntime(ctx, fs, &engineOpts{ + renumber: false, + migrate: false, + noStore: false, + withFDS: true, + reset: true, config: cfg, }) } @@ -161,6 +178,10 @@ func getRuntime(ctx context.Context, fs *flag.FlagSet, opts *engineOpts) (*libpo } } + if opts.reset { + options = append(options, libpod.WithReset()) + } + if opts.renumber { options = append(options, libpod.WithRenumber()) } diff --git a/test/e2e/save_test.go b/test/e2e/save_test.go index 897e49ef7..7a1fb0fc2 100644 --- a/test/e2e/save_test.go +++ b/test/e2e/save_test.go @@ -226,13 +226,17 @@ default-docker: }) It("podman save --multi-image-archive (untagged images)", func() { - // Refer to images via ID instead of tag. - session := podmanTest.Podman([]string{"images", "--format", "{{.ID}}"}) + // #14468: to make execution time more predictable, save at + // most three images and sort them by size. + session := podmanTest.Podman([]string{"images", "--sort", "size", "--format", "{{.ID}}"}) session.WaitWithDefaultTimeout() Expect(session).Should(Exit(0)) ids := session.OutputToStringArray() Expect(len(ids)).To(BeNumerically(">", 1), "We need to have *some* images to save") + if len(ids) > 3 { + ids = ids[:3] + } multiImageSave(podmanTest, ids) }) }) |
