diff --git a/oci/container.go b/oci/container.go index cd020fcb..7a5ba81e 100644 --- a/oci/container.go +++ b/oci/container.go @@ -2,6 +2,7 @@ package oci import ( "fmt" + "path/filepath" "sync" "time" @@ -64,6 +65,11 @@ func NewContainer(id string, name string, bundlePath string, logPath string, net return c, nil } +// StatePath returns the containers state.json path +func (c *Container) StatePath() string { + return filepath.Join(c.dir, "state.json") +} + // CreatedAt returns the container creation time func (c *Container) CreatedAt() time.Time { return c.state.Created diff --git a/server/container_create.go b/server/container_create.go index f4037a51..c15985e9 100644 --- a/server/container_create.go +++ b/server/container_create.go @@ -310,6 +310,8 @@ func (s *Server) CreateContainer(ctx context.Context, req *pb.CreateContainerReq return nil, err } + s.containerStateToDisk(container) + resp := &pb.CreateContainerResponse{ ContainerId: containerID, } diff --git a/server/container_start.go b/server/container_start.go index 128cc5fc..a426def9 100644 --- a/server/container_start.go +++ b/server/container_start.go @@ -20,6 +20,8 @@ func (s *Server) StartContainer(ctx context.Context, req *pb.StartContainerReque return nil, fmt.Errorf("failed to start container %s: %v", c.ID(), err) } + s.containerStateToDisk(c) + resp := &pb.StartContainerResponse{} logrus.Debugf("StartContainerResponse %+v", resp) return resp, nil diff --git a/server/container_stop.go b/server/container_stop.go index 6503b3fa..5ea53bf7 100644 --- a/server/container_stop.go +++ b/server/container_stop.go @@ -27,6 +27,8 @@ func (s *Server) StopContainer(ctx context.Context, req *pb.StopContainerRequest } } + s.containerStateToDisk(c) + resp := &pb.StopContainerResponse{} logrus.Debugf("StopContainerResponse: %+v", resp) return resp, nil diff --git a/server/sandbox_run.go b/server/sandbox_run.go index bb7e41ec..71662c9e 100644 --- a/server/sandbox_run.go +++ b/server/sandbox_run.go @@ -425,6 +425,8 @@ func (s *Server) RunPodSandbox(ctx context.Context, req *pb.RunPodSandboxRequest return nil, err } + s.containerStateToDisk(container) + resp = &pb.RunPodSandboxResponse{PodSandboxId: id} logrus.Debugf("RunPodSandboxResponse: %+v", resp) return resp, nil diff --git a/server/sandbox_stop.go b/server/sandbox_stop.go index 76a0cadf..b932afb2 100644 --- a/server/sandbox_stop.go +++ b/server/sandbox_stop.go @@ -52,6 +52,7 @@ func (s *Server) StopPodSandbox(ctx context.Context, req *pb.StopPodSandboxReque return nil, fmt.Errorf("failed to stop container %s in pod sandbox %s: %v", c.Name(), sb.id, err) } } + s.containerStateToDisk(c) } resp := &pb.StopPodSandboxResponse{} diff --git a/server/server.go b/server/server.go index e2f9e4df..2b0db7af 100644 --- a/server/server.go +++ b/server/server.go @@ -19,6 +19,7 @@ import ( "github.com/kubernetes-incubator/cri-o/pkg/storage" "github.com/kubernetes-incubator/cri-o/server/apparmor" "github.com/kubernetes-incubator/cri-o/server/seccomp" + "github.com/moby/moby/pkg/ioutils" rspec "github.com/opencontainers/runtime-spec/specs-go" "github.com/opencontainers/selinux/go-selinux/label" pb "k8s.io/kubernetes/pkg/kubelet/api/v1alpha1/runtime" @@ -155,6 +156,20 @@ func (s *Server) loadContainer(id string) error { return s.ctrIDIndex.Add(id) } +func (s *Server) containerStateToDisk(c *oci.Container) error { + // ignore errors, this is a best effort to have up-to-date info about + // a given container before its state gets stored + s.runtime.UpdateStatus(c) + + jsonSource, err := ioutils.NewAtomicFileWriter(c.StatePath(), 0644) + if err != nil { + return err + } + defer jsonSource.Close() + enc := json.NewEncoder(jsonSource) + return enc.Encode(s.runtime.ContainerStatus(c)) +} + func configNetNsPath(spec rspec.Spec) (string, error) { for _, ns := range spec.Linux.Namespaces { if ns.Type != rspec.NetworkNamespace {