diff --git a/Makefile b/Makefile index c197e9e6..df610cf3 100644 --- a/Makefile +++ b/Makefile @@ -134,6 +134,7 @@ install.completions: install.systemd: install -D -m 644 contrib/systemd/ocid.service $(PREFIX)/lib/systemd/system/ocid.service + install -D -m 644 contrib/systemd/ocid-shutdown.service $(PREFIX)/lib/systemd/system/ocid-shutdown.service uninstall: rm -f $(BINDIR)/ocid diff --git a/contrib/systemd/ocid-shutdown.service b/contrib/systemd/ocid-shutdown.service new file mode 100644 index 00000000..eff6a11f --- /dev/null +++ b/contrib/systemd/ocid-shutdown.service @@ -0,0 +1,14 @@ +[Unit] +Description=Shutdown OCID containers before shutting down the system +Wants=ocid.service +After=ocid.service +Documentation=man:ocid(8) + +[Service] +Type=oneshot +ExecStart=/usr/bin/true +ExecStop=mkdir -p /var/lib/ocid; touch /var/lib/ocid/ocid.shutdown +RemainAfterExit=yes + +[Install] +WantedBy=multi-user.target diff --git a/server/sandbox_remove.go b/server/sandbox_remove.go index bf7d18cb..b361a7ef 100644 --- a/server/sandbox_remove.go +++ b/server/sandbox_remove.go @@ -40,7 +40,8 @@ func (s *Server) RemovePodSandbox(ctx context.Context, req *pb.RemovePodSandboxR cState := s.runtime.ContainerStatus(c) if cState.Status == oci.ContainerStateCreated || cState.Status == oci.ContainerStateRunning { if err := s.runtime.StopContainer(c); err != nil { - return nil, fmt.Errorf("failed to stop container %s: %v", c.Name(), err) + // Assume container is already stopped + logrus.Warnf("failed to stop container %s: %v", c.Name(), err) } } @@ -107,3 +108,17 @@ func (s *Server) RemovePodSandbox(ctx context.Context, req *pb.RemovePodSandboxR logrus.Debugf("RemovePodSandboxResponse %+v", resp) return resp, nil } + +// RemoveAllPodSandboxes removes all pod sandboxes +func (s *Server) RemoveAllPodSandboxes() { + logrus.Debugf("RemoveAllPodSandboxes") + s.Update() + for _, sb := range s.state.sandboxes { + pod := &pb.RemovePodSandboxRequest{ + PodSandboxId: sb.id, + } + if _, err := s.RemovePodSandbox(nil, pod); err != nil { + logrus.Warnf("could not RemovePodSandbox %s: %v", sb.id, err) + } + } +} diff --git a/server/server.go b/server/server.go index 2710cc13..003dbdd4 100644 --- a/server/server.go +++ b/server/server.go @@ -25,6 +25,7 @@ import ( const ( runtimeAPIVersion = "v1alpha1" + shutdownFile = "/var/lib/ocid/ocid.shutdown" ) // Server implements the RuntimeService and ImageService @@ -431,8 +432,23 @@ func (s *Server) releaseContainerName(name string) { s.ctrNameIndex.Release(name) } +// cleanupSandboxesOnShutdown Remove all running Sandboxes on system shutdown +func (s *Server) cleanupSandboxesOnShutdown() { + _, err := os.Stat(shutdownFile) + if err == nil || !os.IsNotExist(err) { + logrus.Debugf("shutting down all sandboxes, on shutdown") + s.RemoveAllPodSandboxes() + err = os.Remove(shutdownFile) + if err != nil { + logrus.Warnf("Failed to remove %q", shutdownFile) + } + + } +} + // Shutdown attempts to shut down the server's storage cleanly func (s *Server) Shutdown() error { + s.cleanupSandboxesOnShutdown() _, err := s.store.Shutdown(false) return err } @@ -511,6 +527,7 @@ func New(config *Config) (*Server, error) { } s.restore() + s.cleanupSandboxesOnShutdown() logrus.Debugf("sandboxes: %v", s.state.sandboxes) logrus.Debugf("containers: %v", s.state.containers)