summaryrefslogtreecommitdiff
path: root/libpod
diff options
context:
space:
mode:
Diffstat (limited to 'libpod')
-rw-r--r--libpod/container_inspect.go2
-rw-r--r--libpod/container_validate.go2
-rw-r--r--libpod/runtime.go2
-rw-r--r--libpod/runtime_ctr.go26
-rw-r--r--libpod/service.go15
5 files changed, 39 insertions, 8 deletions
diff --git a/libpod/container_inspect.go b/libpod/container_inspect.go
index 5d809644d..93240812d 100644
--- a/libpod/container_inspect.go
+++ b/libpod/container_inspect.go
@@ -171,7 +171,7 @@ func (c *Container) getContainerInspectData(size bool, driverData *define.Driver
Mounts: inspectMounts,
Dependencies: c.Dependencies(),
IsInfra: c.IsInfra(),
- IsService: c.isService(),
+ IsService: c.IsService(),
}
if c.state.ConfigPath != "" {
diff --git a/libpod/container_validate.go b/libpod/container_validate.go
index d939c94e6..cfbdd2b1e 100644
--- a/libpod/container_validate.go
+++ b/libpod/container_validate.go
@@ -31,7 +31,7 @@ func (c *Container) validate() error {
// A container cannot be marked as an infra and service container at
// the same time.
- if c.IsInfra() && c.isService() {
+ if c.IsInfra() && c.IsService() {
return fmt.Errorf("cannot be infra and service container at the same time: %w", define.ErrInvalidArg)
}
diff --git a/libpod/runtime.go b/libpod/runtime.go
index f4cd9cf00..58f20ef5b 100644
--- a/libpod/runtime.go
+++ b/libpod/runtime.go
@@ -349,7 +349,7 @@ func makeRuntime(runtime *Runtime) (retErr error) {
// it will try to use existing XDG_RUNTIME_DIR
// if current user has no write access to XDG_RUNTIME_DIR we will fail later
if err := unix.Access(runtime.storageConfig.RunRoot, unix.W_OK); err != nil {
- msg := "XDG_RUNTIME_DIR is pointing to a path which is not writable. Most likely podman will fail."
+ msg := fmt.Sprintf("RunRoot is pointing to a path (%s) which is not writable. Most likely podman will fail.", runtime.storageConfig.RunRoot)
if errors.Is(err, os.ErrNotExist) {
// if dir does not exists try to create it
if err := os.MkdirAll(runtime.storageConfig.RunRoot, 0700); err != nil {
diff --git a/libpod/runtime_ctr.go b/libpod/runtime_ctr.go
index df7174ac6..2eaa77572 100644
--- a/libpod/runtime_ctr.go
+++ b/libpod/runtime_ctr.go
@@ -644,6 +644,16 @@ func (r *Runtime) removeContainer(ctx context.Context, c *Container, force, remo
return err
}
+ if c.IsService() {
+ canStop, err := c.canStopServiceContainer()
+ if err != nil {
+ return err
+ }
+ if !canStop {
+ return fmt.Errorf("container %s is the service container of pod(s) %s and cannot be removed without removing the pod(s)", c.ID(), strings.Join(c.state.Service.Pods, ","))
+ }
+ }
+
// If we're not force-removing, we need to check if we're in a good
// state to remove.
if !force {
@@ -732,7 +742,11 @@ func (r *Runtime) removeContainer(ctx context.Context, c *Container, force, remo
// after setting the state to ContainerStateRemoving will prevent that the container is
// restarted
if err := c.removeAllExecSessions(); err != nil {
- return err
+ if cleanupErr == nil {
+ cleanupErr = err
+ } else {
+ logrus.Errorf("Remove exec sessions: %v", err)
+ }
}
// Stop the container's storage
@@ -903,6 +917,16 @@ func (r *Runtime) evictContainer(ctx context.Context, idOrName string, removeVol
}
}
+ if c.IsService() {
+ canStop, err := c.canStopServiceContainer()
+ if err != nil {
+ return id, err
+ }
+ if !canStop {
+ return id, fmt.Errorf("container %s is the service container of pod(s) %s and cannot be removed without removing the pod(s)", c.ID(), strings.Join(c.state.Service.Pods, ","))
+ }
+ }
+
var cleanupErr error
// Remove the container from the state
if c.config.Pod != "" {
diff --git a/libpod/service.go b/libpod/service.go
index ad147e87b..c14f5e51d 100644
--- a/libpod/service.go
+++ b/libpod/service.go
@@ -54,11 +54,12 @@ func (c *Container) addServicePodLocked(id string) error {
return c.save()
}
-func (c *Container) isService() bool {
+// IsService returns true when the container is a "service container".
+func (c *Container) IsService() bool {
return c.config.IsService
}
-// canStopServiceContainer returns true if all pods of the service are stopped.
+// canStopServiceContainerLocked returns true if all pods of the service are stopped.
// Note that the method acquires the container lock.
func (c *Container) canStopServiceContainerLocked() (bool, error) {
c.lock.Lock()
@@ -67,10 +68,16 @@ func (c *Container) canStopServiceContainerLocked() (bool, error) {
return false, err
}
- if !c.isService() {
+ if !c.IsService() {
return false, fmt.Errorf("internal error: checking service: container %s is not a service container", c.ID())
}
+ return c.canStopServiceContainer()
+}
+
+// canStopServiceContainer returns true if all pods of the service are stopped.
+// Note that the method expects the container to be locked.
+func (c *Container) canStopServiceContainer() (bool, error) {
for _, id := range c.state.Service.Pods {
pod, err := c.runtime.LookupPod(id)
if err != nil {
@@ -163,7 +170,7 @@ func (c *Container) canRemoveServiceContainerLocked() (bool, error) {
return false, err
}
- if !c.isService() {
+ if !c.IsService() {
return false, fmt.Errorf("internal error: checking service: container %s is not a service container", c.ID())
}