mirror of https://github.com/containers/podman.git
Fix rmi -f removing containers from storage without telling libpod
Signed-off-by: Matthew Heon <matthew.heon@gmail.com> Closes: #68 Approved by: rhatdan
This commit is contained in:
parent
4a68a5303c
commit
ce3081786b
|
@ -1,7 +1,6 @@
|
||||||
package libpod
|
package libpod
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/containers/storage"
|
|
||||||
spec "github.com/opencontainers/runtime-spec/specs-go"
|
spec "github.com/opencontainers/runtime-spec/specs-go"
|
||||||
"github.com/pkg/errors"
|
"github.com/pkg/errors"
|
||||||
"github.com/sirupsen/logrus"
|
"github.com/sirupsen/logrus"
|
||||||
|
@ -86,6 +85,12 @@ func (r *Runtime) RemoveContainer(c *Container, force bool) error {
|
||||||
r.lock.Lock()
|
r.lock.Lock()
|
||||||
defer r.lock.Unlock()
|
defer r.lock.Unlock()
|
||||||
|
|
||||||
|
return r.removeContainer(c, force)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Internal function to remove a container
|
||||||
|
// Locks the container, but does not lock the runtime
|
||||||
|
func (r *Runtime) removeContainer(c *Container, force bool) error {
|
||||||
c.lock.Lock()
|
c.lock.Lock()
|
||||||
defer c.lock.Unlock()
|
defer c.lock.Unlock()
|
||||||
|
|
||||||
|
@ -210,30 +215,3 @@ func (r *Runtime) GetContainers(filters ...ContainerFilter) ([]*Container, error
|
||||||
|
|
||||||
return ctrsFiltered, nil
|
return ctrsFiltered, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// getContainersWithImage returns a list of containers referencing imageID
|
|
||||||
func (r *Runtime) getContainersWithImage(imageID string) ([]storage.Container, error) {
|
|
||||||
var matchingContainers []storage.Container
|
|
||||||
containers, err := r.store.Containers()
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
for _, ctr := range containers {
|
|
||||||
if ctr.ImageID == imageID {
|
|
||||||
matchingContainers = append(matchingContainers, ctr)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return matchingContainers, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// removeMultipleContainers deletes a list of containers from the store
|
|
||||||
// TODO refactor this to remove libpod Containers
|
|
||||||
func (r *Runtime) removeMultipleContainers(containers []storage.Container) error {
|
|
||||||
for _, ctr := range containers {
|
|
||||||
if err := r.store.DeleteContainer(ctr.ID); err != nil {
|
|
||||||
return errors.Wrapf(err, "could not remove container %q", ctr)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
|
@ -798,20 +798,27 @@ func (r *Runtime) RemoveImage(image *storage.Image, force bool) (string, error)
|
||||||
return "", ErrRuntimeStopped
|
return "", ErrRuntimeStopped
|
||||||
}
|
}
|
||||||
|
|
||||||
containersWithImage, err := r.getContainersWithImage(image.ID)
|
// Get all containers, filter to only those using the image, and remove those containers
|
||||||
|
ctrs, err := r.state.AllContainers()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", errors.Wrapf(err, "error getting containers for image %q", image.ID)
|
|
||||||
}
|
|
||||||
if len(containersWithImage) > 0 && len(image.Names) <= 1 {
|
|
||||||
if force {
|
|
||||||
if err := r.removeMultipleContainers(containersWithImage); err != nil {
|
|
||||||
return "", err
|
return "", err
|
||||||
}
|
}
|
||||||
} else {
|
imageCtrs := []*Container{}
|
||||||
for _, ctr := range containersWithImage {
|
for _, ctr := range ctrs {
|
||||||
return "", fmt.Errorf("Could not remove image %q (must force) - container %q is using its reference image", image.ID, ctr.ImageID)
|
if ctr.config.RootfsImageID == image.ID {
|
||||||
|
imageCtrs = append(imageCtrs, ctr)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if len(imageCtrs) > 0 && len(image.Names) <= 1 {
|
||||||
|
if force {
|
||||||
|
for _, ctr := range imageCtrs {
|
||||||
|
if err := r.removeContainer(ctr, true); err != nil {
|
||||||
|
return "", errors.Wrapf(err, "error removing image %s: container %s using image could not be removed", image.ID, ctr.ID())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return "", fmt.Errorf("could not remove image %s as it is being used by %d containers", image.ID, len(imageCtrs))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(image.Names) > 1 && !force {
|
if len(image.Names) > 1 && !force {
|
||||||
|
|
Loading…
Reference in New Issue