mirror of
https://github.com/containers/podman.git
synced 2025-08-06 11:32:07 +08:00
Merge pull request #23846 from flouthoc/prune-cleancachemount
prune: add `--build-cache` to support clearing build cache using `CleanCacheMount`
This commit is contained in:
@ -46,6 +46,7 @@ func init() {
|
||||
|
||||
flags := pruneCmd.Flags()
|
||||
flags.BoolVarP(&pruneOpts.All, "all", "a", false, "Remove all images not in use by containers, not just dangling ones")
|
||||
flags.BoolVarP(&pruneOpts.BuildCache, "build-cache", "", false, "Remove persistent build cache created by --mount=type=cache")
|
||||
flags.BoolVarP(&pruneOpts.External, "external", "", false, "Remove images even when they are used by external containers (e.g., by build containers)")
|
||||
flags.BoolVarP(&force, "force", "f", false, "Do not prompt for confirmation")
|
||||
|
||||
|
@ -17,6 +17,10 @@ The image prune command does not prune cache images that only use layers that ar
|
||||
|
||||
Remove dangling images and images that have no associated containers.
|
||||
|
||||
#### **--build-cache**
|
||||
|
||||
Remove persistent build cache create for `--mount=type=cache`.
|
||||
|
||||
#### **--external**
|
||||
|
||||
Remove images even when they are used by external containers (e.g., build containers).
|
||||
|
@ -120,6 +120,7 @@ func PruneImages(w http.ResponseWriter, r *http.Request) {
|
||||
query := struct {
|
||||
All bool `schema:"all"`
|
||||
External bool `schema:"external"`
|
||||
BuildCache bool `schema:"buildcache"`
|
||||
}{
|
||||
// override any golang type defaults
|
||||
}
|
||||
@ -160,6 +161,7 @@ func PruneImages(w http.ResponseWriter, r *http.Request) {
|
||||
All: query.All,
|
||||
External: query.External,
|
||||
Filter: libpodFilters,
|
||||
BuildCache: query.BuildCache,
|
||||
}
|
||||
imagePruneReports, err := imageEngine.Prune(r.Context(), pruneOptions)
|
||||
if err != nil {
|
||||
|
@ -1129,6 +1129,12 @@ func (s *APIServer) registerImagesHandlers(r *mux.Router) error {
|
||||
// description: |
|
||||
// Remove images even when they are used by external containers (e.g, by build containers)
|
||||
// - in: query
|
||||
// name: buildcache
|
||||
// default: false
|
||||
// type: boolean
|
||||
// description: |
|
||||
// Remove persistent build cache created by build instructions such as `--mount=type=cache`.
|
||||
// - in: query
|
||||
// name: filters
|
||||
// type: string
|
||||
// description: |
|
||||
|
@ -93,6 +93,8 @@ type PruneOptions struct {
|
||||
All *bool
|
||||
// Prune images even when they're used by external containers
|
||||
External *bool
|
||||
// Prune persistent build cache
|
||||
BuildCache *bool
|
||||
// Filters to apply when pruning images
|
||||
Filters map[string][]string
|
||||
}
|
||||
|
@ -47,6 +47,21 @@ func (o *PruneOptions) GetExternal() bool {
|
||||
return *o.External
|
||||
}
|
||||
|
||||
// WithBuildCache set field BuildCache to given value
|
||||
func (o *PruneOptions) WithBuildCache(value bool) *PruneOptions {
|
||||
o.BuildCache = &value
|
||||
return o
|
||||
}
|
||||
|
||||
// GetBuildCache returns value of field BuildCache
|
||||
func (o *PruneOptions) GetBuildCache() bool {
|
||||
if o.BuildCache == nil {
|
||||
var z bool
|
||||
return z
|
||||
}
|
||||
return *o.BuildCache
|
||||
}
|
||||
|
||||
// WithFilters set field Filters to given value
|
||||
func (o *PruneOptions) WithFilters(value map[string][]string) *PruneOptions {
|
||||
o.Filters = value
|
||||
|
@ -251,6 +251,7 @@ type ImageListOptions struct {
|
||||
type ImagePruneOptions struct {
|
||||
All bool `json:"all" schema:"all"`
|
||||
External bool `json:"external" schema:"external"`
|
||||
BuildCache bool `json:"buildcache" schema:"buildcache"`
|
||||
Filter []string `json:"filter" schema:"filter"`
|
||||
}
|
||||
|
||||
|
@ -19,6 +19,7 @@ import (
|
||||
"time"
|
||||
|
||||
bdefine "github.com/containers/buildah/define"
|
||||
"github.com/containers/buildah/pkg/volumes"
|
||||
"github.com/containers/common/libimage"
|
||||
"github.com/containers/common/libimage/filter"
|
||||
"github.com/containers/common/pkg/config"
|
||||
@ -107,6 +108,13 @@ func (ir *ImageEngine) Prune(ctx context.Context, opts entities.ImagePruneOption
|
||||
numPreviouslyRemovedImages = numRemovedImages
|
||||
}
|
||||
|
||||
if opts.BuildCache || opts.All {
|
||||
// Clean build cache if any
|
||||
if err := volumes.CleanCacheMount(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
return pruneReports, nil
|
||||
}
|
||||
|
||||
|
@ -102,7 +102,7 @@ func (ir *ImageEngine) Prune(ctx context.Context, opts entities.ImagePruneOption
|
||||
f := strings.Split(filter, "=")
|
||||
filters[f[0]] = f[1:]
|
||||
}
|
||||
options := new(images.PruneOptions).WithAll(opts.All).WithFilters(filters).WithExternal(opts.External)
|
||||
options := new(images.PruneOptions).WithAll(opts.All).WithFilters(filters).WithExternal(opts.External).WithBuildCache(opts.BuildCache)
|
||||
reports, err := images.Prune(ir.ClientCtx, options)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
4
test/e2e/build/buildkit-mount/Containerfilecacheread
Normal file
4
test/e2e/build/buildkit-mount/Containerfilecacheread
Normal file
@ -0,0 +1,4 @@
|
||||
FROM alpine
|
||||
RUN mkdir /test
|
||||
# use option z if selinux is enabled
|
||||
RUN --mount=type=cache,target=/test,z cat /test/world
|
4
test/e2e/build/buildkit-mount/Containerfilecachewrite
Normal file
4
test/e2e/build/buildkit-mount/Containerfilecachewrite
Normal file
@ -0,0 +1,4 @@
|
||||
FROM alpine
|
||||
RUN mkdir /test
|
||||
# use option z if selinux is enabled
|
||||
RUN --mount=type=cache,target=/test,z echo hello > /test/world
|
@ -41,6 +41,37 @@ var _ = Describe("Podman build", func() {
|
||||
Expect(session).Should(ExitCleanly())
|
||||
})
|
||||
|
||||
It("podman image prune should clean build cache", Serial, func() {
|
||||
// try writing something to persistent cache
|
||||
session := podmanTest.Podman([]string{"build", "-f", "build/buildkit-mount/Containerfilecachewrite"})
|
||||
session.WaitWithDefaultTimeout()
|
||||
Expect(session).Should(ExitCleanly())
|
||||
|
||||
// try reading something from persistent cache
|
||||
session = podmanTest.Podman([]string{"build", "-f", "build/buildkit-mount/Containerfilecacheread"})
|
||||
session.WaitWithDefaultTimeout()
|
||||
Expect(session).Should(ExitCleanly())
|
||||
Expect(session.OutputToString()).To(ContainSubstring("hello"))
|
||||
|
||||
// Prune build cache
|
||||
session = podmanTest.Podman([]string{"image", "prune", "-f", "--build-cache"})
|
||||
session.WaitWithDefaultTimeout()
|
||||
Expect(session).Should(ExitCleanly())
|
||||
|
||||
expectedErr := "open '/test/world': No such file or directory"
|
||||
// try reading something from persistent cache should fail
|
||||
session = podmanTest.Podman([]string{"build", "-f", "build/buildkit-mount/Containerfilecacheread"})
|
||||
session.WaitWithDefaultTimeout()
|
||||
if IsRemote() {
|
||||
// In the case of podman remote the error from build is not being propogated to `stderr` instead it appears
|
||||
// on the `stdout` this could be a potential bug in `remote build` which needs to be fixed and visited.
|
||||
Expect(session.OutputToString()).To(ContainSubstring(expectedErr))
|
||||
Expect(session).Should(ExitWithError(1, "exit status 1"))
|
||||
} else {
|
||||
Expect(session).Should(ExitWithError(1, expectedErr))
|
||||
}
|
||||
})
|
||||
|
||||
It("podman build and remove basic alpine with TMPDIR as relative", func() {
|
||||
// preserve TMPDIR if it was originally set
|
||||
if cacheDir, found := os.LookupEnv("TMPDIR"); found {
|
||||
|
Reference in New Issue
Block a user