Hello community,

here is the log from the commit of package cri-o for openSUSE:Factory checked 
in at 2018-04-11 14:03:40
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/cri-o (Old)
 and      /work/SRC/openSUSE:Factory/.cri-o.new (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "cri-o"

Wed Apr 11 14:03:40 2018 rev:7 rq:595521 version:1.9.11

Changes:
--------
--- /work/SRC/openSUSE:Factory/cri-o/cri-o.changes      2018-03-16 
10:45:20.452170052 +0100
+++ /work/SRC/openSUSE:Factory/.cri-o.new/cri-o.changes 2018-04-11 
14:05:29.307214570 +0200
@@ -1,0 +2,14 @@
+Wed Apr 11 06:44:34 UTC 2018 - vrothb...@suse.com
+
+- Update cri-o to v1.9.11:
+  * oci: avoid race on container stop
+  * server/sandbox_stop: Pass context through StopAllPodSandboxes
+  * conmon: Add container ID to syslog
+  * Add logging support for base condition in debug
+  * Simplify filter block
+  * Specifying a filter with no filtering expressions is now idempotent
+  * Add methods for listing and fetching container stats
+  * Implement the stats for the image_fs_info command
+  * Return error for container exec
+
+-------------------------------------------------------------------

Old:
----
  cri-o-1.9.10.tar.xz

New:
----
  cri-o-1.9.11.tar.xz

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ cri-o.spec ++++++
--- /var/tmp/diff_new_pack.541LYB/_old  2018-04-11 14:05:31.247144011 +0200
+++ /var/tmp/diff_new_pack.541LYB/_new  2018-04-11 14:05:31.247144011 +0200
@@ -31,7 +31,7 @@
 %define        name_source2 sysconfig.crio
 %define        name_source3 crio.conf
 Name:           cri-o
-Version:        1.9.10
+Version:        1.9.11
 Release:        0
 Summary:        OCI-based implementation of Kubernetes Container Runtime 
Interface
 License:        Apache-2.0

++++++ _service ++++++
--- /var/tmp/diff_new_pack.541LYB/_old  2018-04-11 14:05:31.287142556 +0200
+++ /var/tmp/diff_new_pack.541LYB/_new  2018-04-11 14:05:31.287142556 +0200
@@ -2,8 +2,8 @@
 <service name="tar_scm" mode="disabled">
 <param name="url">https://github.com/kubernetes-incubator/cri-o</param>
 <param name="scm">git</param>
-<param name="versionformat">1.9.10</param>
-<param name="revision">v1.9.10</param>
+<param name="versionformat">1.9.11</param>
+<param name="revision">v1.9.11</param>
 </service>
 <service name="recompress" mode="disabled">
 <param name="file">cri-o-*.tar</param>

++++++ cri-o-1.9.10.tar.xz -> cri-o-1.9.11.tar.xz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/cri-o-1.9.10/cmd/crio/main.go 
new/cri-o-1.9.11/cmd/crio/main.go
--- old/cri-o-1.9.10/cmd/crio/main.go   2018-03-12 17:46:45.000000000 +0100
+++ new/cri-o-1.9.11/cmd/crio/main.go   2018-04-09 20:22:42.000000000 +0200
@@ -164,11 +164,12 @@
                                continue
                        }
                        *signalled = true
+                       ctx := context.Background()
                        gserver.GracefulStop()
-                       hserver.Shutdown(context.Background())
+                       hserver.Shutdown(ctx)
                        sserver.StopStreamServer()
                        sserver.StopExitMonitor()
-                       if err := sserver.Shutdown(); err != nil {
+                       if err := sserver.Shutdown(ctx); err != nil {
                                logrus.Warnf("error shutting down main service 
%v", err)
                        }
                        return
@@ -408,6 +409,7 @@
        }
 
        app.Action = func(c *cli.Context) error {
+               ctx := context.Background()
                if c.GlobalBool("profile") {
                        profilePort := c.GlobalInt("profile-port")
                        profileEndpoint := fmt.Sprintf("localhost:%v", 
profilePort)
@@ -454,7 +456,7 @@
 
                s := grpc.NewServer()
 
-               service, err := server.New(config)
+               service, err := server.New(ctx, config)
                if err != nil {
                        logrus.Fatal(err)
                }
@@ -522,7 +524,7 @@
                case <-serverCloseCh:
                }
 
-               service.Shutdown()
+               service.Shutdown(ctx)
 
                <-streamServerCloseCh
                logrus.Debug("closed stream server")
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/cri-o-1.9.10/conmon/conmon.c 
new/cri-o-1.9.11/conmon/conmon.c
--- old/cri-o-1.9.10/conmon/conmon.c    2018-03-12 17:46:45.000000000 +0100
+++ new/cri-o-1.9.11/conmon/conmon.c    2018-04-09 20:22:42.000000000 +0200
@@ -28,32 +28,6 @@
 
 #include "cmsg.h"
 
-#define pexit(fmt, ...)                                                        
  \
-       do {                                                                    
 \
-               fprintf(stderr, "[conmon:e]: " fmt " %m\n", ##__VA_ARGS__);     
 \
-               syslog(LOG_ERR, "conmon <error>: " fmt ": %m\n", 
##__VA_ARGS__); \
-               exit(EXIT_FAILURE);                                             
 \
-       } while (0)
-
-#define nexit(fmt, ...)                                                       \
-       do {                                                                  \
-               fprintf(stderr, "[conmon:e]: " fmt "\n", ##__VA_ARGS__);      \
-               syslog(LOG_ERR, "conmon <error>: " fmt " \n", ##__VA_ARGS__); \
-               exit(EXIT_FAILURE);                                           \
-       } while (0)
-
-#define nwarn(fmt, ...)                                                        
\
-       do {                                                                   \
-               fprintf(stderr, "[conmon:w]: " fmt "\n", ##__VA_ARGS__);       \
-               syslog(LOG_INFO, "conmon <nwarn>: " fmt " \n", ##__VA_ARGS__); \
-       } while (0)
-
-#define ninfo(fmt, ...)                                                        
\
-       do {                                                                   \
-               fprintf(stderr, "[conmon:i]: " fmt "\n", ##__VA_ARGS__);       \
-               syslog(LOG_INFO, "conmon <ninfo>: " fmt " \n", ##__VA_ARGS__); \
-       } while (0)
-
 #define _cleanup_(x) __attribute__((cleanup(x)))
 
 static inline void freep(void *p)
@@ -142,6 +116,33 @@
 
 static int log_fd = -1;
 
+#define pexit(fmt, ...)                                                        
                 \
+       do {                                                                    
                \
+               fprintf(stderr, "[conmon:e]: " fmt " %m\n", ##__VA_ARGS__);     
                \
+               syslog(LOG_ERR, "conmon %.20s <error>: " fmt ": %m\n", opt_cid, 
##__VA_ARGS__); \
+               exit(EXIT_FAILURE);                                             
                \
+       } while (0)
+
+#define nexit(fmt, ...)                                                        
              \
+       do {                                                                    
             \
+               fprintf(stderr, "[conmon:e]: " fmt "\n", ##__VA_ARGS__);        
             \
+               syslog(LOG_ERR, "conmon %.20s <error>: " fmt " \n", opt_cid, 
##__VA_ARGS__); \
+               exit(EXIT_FAILURE);                                             
             \
+       } while (0)
+
+#define nwarn(fmt, ...)                                                        
               \
+       do {                                                                    
              \
+               fprintf(stderr, "[conmon:w]: " fmt "\n", ##__VA_ARGS__);        
              \
+               syslog(LOG_INFO, "conmon %.20s <nwarn>: " fmt " \n", opt_cid, 
##__VA_ARGS__); \
+       } while (0)
+
+#define ninfo(fmt, ...)                                                        
               \
+       do {                                                                    
              \
+               fprintf(stderr, "[conmon:i]: " fmt "\n", ##__VA_ARGS__);        
              \
+               syslog(LOG_INFO, "conmon %.20s <ninfo>: " fmt " \n", opt_cid, 
##__VA_ARGS__); \
+       } while (0)
+
+
 static ssize_t write_all(int fd, const void *buf, size_t count)
 {
        size_t remaining = count;
@@ -1107,8 +1108,10 @@
                exit(1);
        }
 
-       if (opt_cid == NULL)
-               nexit("Container ID not provided. Use --cid");
+       if (opt_cid == NULL) {
+               fprintf(stderr, "Container ID not provided. Use --cid");
+               exit(EXIT_FAILURE);
+       }
 
        if (!opt_exec && opt_cuuid == NULL)
                nexit("Container UUID not provided. Use --cuuid");
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/cri-o-1.9.10/lib/stats.go 
new/cri-o-1.9.11/lib/stats.go
--- old/cri-o-1.9.10/lib/stats.go       2018-03-12 17:46:45.000000000 +0100
+++ new/cri-o-1.9.11/lib/stats.go       2018-04-09 20:22:42.000000000 +0200
@@ -15,8 +15,8 @@
 type ContainerStats struct {
        Container   string
        CPU         float64
-       cpuNano     uint64
-       systemNano  uint64
+       CPUNano     uint64
+       SystemNano  int64
        MemUsage    uint64
        MemLimit    uint64
        MemPerc     float64
@@ -29,8 +29,8 @@
 
 // GetContainerStats gets the running stats for a given container
 func (c *ContainerServer) GetContainerStats(ctr *oci.Container, previousStats 
*ContainerStats) (*ContainerStats, error) {
-       previousCPU := previousStats.cpuNano
-       previousSystem := previousStats.systemNano
+       previousCPU := previousStats.CPUNano
+       previousSystem := previousStats.SystemNano
        libcontainerStats, err := c.LibcontainerStats(ctr)
        if err != nil {
                return nil, err
@@ -38,6 +38,8 @@
        cgroupStats := libcontainerStats.CgroupStats
        stats := new(ContainerStats)
        stats.Container = ctr.ID()
+       stats.CPUNano = cgroupStats.CpuStats.CpuUsage.TotalUsage
+       stats.SystemNano = time.Now().UnixNano()
        stats.CPU = calculateCPUPercent(libcontainerStats, previousCPU, 
previousSystem)
        stats.MemUsage = cgroupStats.MemoryStats.Usage.Usage
        stats.MemLimit = getMemLimit(cgroupStats.MemoryStats.Usage.Limit)
@@ -84,11 +86,11 @@
        return
 }
 
-func calculateCPUPercent(stats *libcontainer.Stats, previousCPU, 
previousSystem uint64) float64 {
+func calculateCPUPercent(stats *libcontainer.Stats, previousCPU uint64, 
previousSystem int64) float64 {
        var (
                cpuPercent  = 0.0
                cpuDelta    = 
float64(stats.CgroupStats.CpuStats.CpuUsage.TotalUsage - previousCPU)
-               systemDelta = float64(uint64(time.Now().UnixNano()) - 
previousSystem)
+               systemDelta = float64(uint64(time.Now().UnixNano()) - 
uint64(previousSystem))
        )
        if systemDelta > 0.0 && cpuDelta > 0.0 {
                // gets a ratio of container cpu usage total, multiplies it by 
the number of cores (4 cores running
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/cri-o-1.9.10/oci/oci.go new/cri-o-1.9.11/oci/oci.go
--- old/cri-o-1.9.10/oci/oci.go 2018-03-12 17:46:45.000000000 +0100
+++ new/cri-o-1.9.11/oci/oci.go 2018-04-09 20:22:42.000000000 +0200
@@ -14,6 +14,7 @@
        "time"
 
        "github.com/containerd/cgroups"
+       "github.com/kubernetes-incubator/cri-o/pkg/findprocess"
        "github.com/kubernetes-incubator/cri-o/utils"
        rspec "github.com/opencontainers/runtime-spec/specs-go"
        "github.com/sirupsen/logrus"
@@ -573,12 +574,18 @@
                        case <-chControl:
                                return
                        default:
-                               // Check if the process is still around
-                               err := unix.Kill(c.state.Pid, 0)
-                               if err == unix.ESRCH {
+                               process, err := 
findprocess.FindProcess(c.state.Pid)
+                               if err != nil {
+                                       if err != findprocess.ErrNotFound {
+                                               logrus.Warnf("failed to find 
process %d for container %q: %v", c.state.Pid, c.ID(), err)
+                                       }
                                        close(done)
                                        return
                                }
+                               err = process.Release()
+                               if err != nil {
+                                       logrus.Warnf("failed to release process 
%d for container %q: %v", c.state.Pid, c.ID(), err)
+                               }
                                time.Sleep(100 * time.Millisecond)
                        }
                }
@@ -607,15 +614,25 @@
        defer c.opLock.Unlock()
 
        // Check if the process is around before sending a signal
-       err := unix.Kill(c.state.Pid, 0)
-       if err == unix.ESRCH {
+       process, err := findprocess.FindProcess(c.state.Pid)
+       if err == findprocess.ErrNotFound {
                c.state.Finished = time.Now()
                return nil
        }
+       if err != nil {
+               logrus.Warnf("failed to find process %d for container %q: %v", 
c.state.Pid, c.ID(), err)
+       } else {
+               err = process.Release()
+               if err != nil {
+                       logrus.Warnf("failed to release process %d for 
container %q: %v", c.state.Pid, c.ID(), err)
+               }
+       }
 
        if timeout > 0 {
                if err := utils.ExecCmdWithStdStreams(os.Stdin, os.Stdout, 
os.Stderr, r.Path(c), "kill", c.id, c.GetStopSignal()); err != nil {
-                       return fmt.Errorf("failed to stop container %s, %v", 
c.id, err)
+                       if err := checkProcessGone(c); err != nil {
+                               return fmt.Errorf("failed to stop container %q: 
%v", c.id, err)
+                       }
                }
                err = waitContainerStop(ctx, c, 
time.Duration(timeout)*time.Second)
                if err == nil {
@@ -625,12 +642,29 @@
        }
 
        if err := utils.ExecCmdWithStdStreams(os.Stdin, os.Stdout, os.Stderr, 
r.Path(c), "kill", "--all", c.id, "KILL"); err != nil {
-               return fmt.Errorf("failed to stop container %s, %v", c.id, err)
+               if err := checkProcessGone(c); err != nil {
+                       return fmt.Errorf("failed to stop container %q: %v", 
c.id, err)
+               }
        }
 
        return waitContainerStop(ctx, c, killContainerTimeout)
 }
 
+func checkProcessGone(c *Container) error {
+       process, perr := findprocess.FindProcess(c.state.Pid)
+       if perr == findprocess.ErrNotFound {
+               c.state.Finished = time.Now()
+               return nil
+       }
+       if perr == nil {
+               err := process.Release()
+               if err != nil {
+                       logrus.Warnf("failed to release process %d for 
container %q: %v", c.state.Pid, c.ID(), err)
+               }
+       }
+       return fmt.Errorf("failed to find process: %v", perr)
+}
+
 // DeleteContainer deletes a container.
 func (r *Runtime) DeleteContainer(c *Container) error {
        c.opLock.Lock()
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/cri-o-1.9.10/pkg/findprocess/findprocess.go 
new/cri-o-1.9.11/pkg/findprocess/findprocess.go
--- old/cri-o-1.9.10/pkg/findprocess/findprocess.go     1970-01-01 
01:00:00.000000000 +0100
+++ new/cri-o-1.9.11/pkg/findprocess/findprocess.go     2018-04-09 
20:22:42.000000000 +0200
@@ -0,0 +1,26 @@
+// Package findprocess provides an os.FindProcess wrapper that
+// portably detects non-existent processes.
+package findprocess
+
+import (
+       "errors"
+       "os"
+)
+
+// ErrNotFound represents a target process that does not exist or is
+// otherwise not available to the calling process.
+var ErrNotFound = errors.New("process not found")
+
+// FindProcess wraps os.Findprocess [1] to return a public ErrNotFound
+// if the process does not exist.  The returned process will be nil if
+// and only if the returned err is non-nil.
+//
+// [1]: https://golang.org/pkg/os/#FindProcess
+func FindProcess(pid int) (process *os.Process, err error) {
+       process, err = findProcess(pid)
+       if err != nil {
+               process.Release()
+               process = nil
+       }
+       return process, err
+}
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/cri-o-1.9.10/pkg/findprocess/findprocess_test.go 
new/cri-o-1.9.11/pkg/findprocess/findprocess_test.go
--- old/cri-o-1.9.10/pkg/findprocess/findprocess_test.go        1970-01-01 
01:00:00.000000000 +0100
+++ new/cri-o-1.9.11/pkg/findprocess/findprocess_test.go        2018-04-09 
20:22:42.000000000 +0200
@@ -0,0 +1,41 @@
+package findprocess
+
+import (
+       "os/exec"
+       "testing"
+)
+
+func TestFindEngine(t *testing.T) {
+       cmd := exec.Command("sleep", "1")
+       err := cmd.Start()
+       if err != nil {
+               t.Fatal(err)
+       }
+
+       process, err := FindProcess(cmd.Process.Pid)
+       if err != nil {
+               t.Fatal(err)
+       }
+       err = process.Release()
+       if err != nil {
+               t.Fatal(err)
+       }
+
+       err = cmd.Wait()
+       if err != nil {
+               t.Fatal(err)
+       }
+
+       process, err = FindProcess(cmd.Process.Pid)
+       if err == ErrNotFound {
+               return
+       }
+       if err == nil {
+               err = process.Release()
+               if err != nil {
+                       t.Fatal(err)
+               }
+               t.Fatalf("found the reaped process %d", cmd.Process.Pid)
+       }
+       t.Fatal(err)
+}
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/cri-o-1.9.10/pkg/findprocess/findprocess_unix.go 
new/cri-o-1.9.11/pkg/findprocess/findprocess_unix.go
--- old/cri-o-1.9.10/pkg/findprocess/findprocess_unix.go        1970-01-01 
01:00:00.000000000 +0100
+++ new/cri-o-1.9.11/pkg/findprocess/findprocess_unix.go        2018-04-09 
20:22:42.000000000 +0200
@@ -0,0 +1,23 @@
+// +build darwin dragonfly freebsd linux nacl netbsd openbsd solaris
+
+package findprocess
+
+import (
+       "os"
+       "syscall"
+)
+
+func findProcess(pid int) (process *os.Process, err error) {
+       process, err = os.FindProcess(pid)
+       if err != nil {
+               return process, err
+       }
+       err = process.Signal(syscall.Signal(0))
+       if err == nil {
+               return process, nil
+       }
+       if err.Error() == "os: process already finished" {
+               return process, ErrNotFound
+       }
+       return process, err
+}
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/cri-o-1.9.10/pkg/findprocess/findprocess_windows.go 
new/cri-o-1.9.11/pkg/findprocess/findprocess_windows.go
--- old/cri-o-1.9.10/pkg/findprocess/findprocess_windows.go     1970-01-01 
01:00:00.000000000 +0100
+++ new/cri-o-1.9.11/pkg/findprocess/findprocess_windows.go     2018-04-09 
20:22:42.000000000 +0200
@@ -0,0 +1,14 @@
+package findprocess
+
+import (
+       "os"
+)
+
+func findProcess(pid int) (process *os.Process, err error) {
+       process, err := os.FindProcess(pid)
+       if err != nil {
+               // FIXME: is there an analog to POSIX's ESRCH we can check for?
+               return process, err
+       }
+       return process, nil
+}
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/cri-o-1.9.10/server/container_exec.go 
new/cri-o-1.9.11/server/container_exec.go
--- old/cri-o-1.9.10/server/container_exec.go   2018-03-12 17:46:45.000000000 
+0100
+++ new/cri-o-1.9.11/server/container_exec.go   2018-04-09 20:22:42.000000000 
+0200
@@ -30,7 +30,7 @@
 
        resp, err = s.GetExec(req)
        if err != nil {
-               return nil, fmt.Errorf("unable to prepare exec endpoint")
+               return nil, fmt.Errorf("unable to prepare exec endpoint: %v", 
err)
        }
 
        return resp, nil
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/cri-o-1.9.10/server/container_list.go 
new/cri-o-1.9.11/server/container_list.go
--- old/cri-o-1.9.10/server/container_list.go   2018-03-12 17:46:45.000000000 
+0100
+++ new/cri-o-1.9.11/server/container_list.go   2018-04-09 20:22:42.000000000 
+0200
@@ -28,6 +28,42 @@
        return true
 }
 
+// filterContainerList applies a protobuf-defined filter to retrieve only 
intended containers. Not matching
+// the filter is not considered an error but will return an empty response.
+func (s *Server) filterContainerList(filter *pb.ContainerFilter, origCtrList 
[]*oci.Container) []*oci.Container {
+       // Filter using container id and pod id first.
+       if filter.Id != "" {
+               id, err := s.CtrIDIndex().Get(filter.Id)
+               if err != nil {
+                       // If we don't find a container ID with a filter, it 
should not
+                       // be considered an error.  Log a warning and return an 
empty struct
+                       logrus.Warn("unable to find container ID %s", filter.Id)
+                       return []*oci.Container{}
+               }
+               c := s.ContainerServer.GetContainer(id)
+               if c != nil {
+                       switch {
+                       case filter.PodSandboxId == "":
+                               return []*oci.Container{c}
+                       case c.Sandbox() == filter.PodSandboxId:
+                               return []*oci.Container{c}
+                       default:
+                               return []*oci.Container{}
+                       }
+               }
+       } else {
+               if filter.PodSandboxId != "" {
+                       pod := s.ContainerServer.GetSandbox(filter.PodSandboxId)
+                       if pod == nil {
+                               return []*oci.Container{}
+                       }
+                       return pod.Containers().List()
+               }
+       }
+       logrus.Debug("no filters were applied, returning full container list")
+       return origCtrList
+}
+
 // ListContainers lists all containers by filters.
 func (s *Server) ListContainers(ctx context.Context, req 
*pb.ListContainersRequest) (resp *pb.ListContainersResponse, err error) {
        const operation = "list_containers"
@@ -45,39 +81,7 @@
        }
 
        if filter != nil {
-
-               // Filter using container id and pod id first.
-               if filter.Id != "" {
-                       id, err := s.CtrIDIndex().Get(filter.Id)
-                       if err != nil {
-                               // If we don't find a container ID with a 
filter, it should not
-                               // be considered an error.  Log a warning and 
return an empty struct
-                               logrus.Warn("unable to find container ID %s", 
filter.Id)
-                               return &pb.ListContainersResponse{}, nil
-                       }
-                       c := s.ContainerServer.GetContainer(id)
-                       if c != nil {
-                               if filter.PodSandboxId != "" {
-                                       if c.Sandbox() == filter.PodSandboxId {
-                                               ctrList = []*oci.Container{c}
-                                       } else {
-                                               ctrList = []*oci.Container{}
-                                       }
-
-                               } else {
-                                       ctrList = []*oci.Container{c}
-                               }
-                       }
-               } else {
-                       if filter.PodSandboxId != "" {
-                               pod := 
s.ContainerServer.GetSandbox(filter.PodSandboxId)
-                               if pod == nil {
-                                       ctrList = []*oci.Container{}
-                               } else {
-                                       ctrList = pod.Containers().List()
-                               }
-                       }
-               }
+               ctrList = s.filterContainerList(filter, ctrList)
        }
 
        for _, ctr := range ctrList {
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/cri-o-1.9.10/server/container_stats.go 
new/cri-o-1.9.11/server/container_stats.go
--- old/cri-o-1.9.10/server/container_stats.go  2018-03-12 17:46:45.000000000 
+0100
+++ new/cri-o-1.9.11/server/container_stats.go  2018-04-09 20:22:42.000000000 
+0200
@@ -4,10 +4,32 @@
        "fmt"
        "time"
 
+       "github.com/kubernetes-incubator/cri-o/lib"
+       "github.com/kubernetes-incubator/cri-o/oci"
        "golang.org/x/net/context"
        pb "k8s.io/kubernetes/pkg/kubelet/apis/cri/v1alpha1/runtime"
 )
 
+func buildContainerStats(stats *lib.ContainerStats, container *oci.Container) 
*pb.ContainerStats {
+       return &pb.ContainerStats{
+               Attributes: &pb.ContainerAttributes{
+                       Id:          container.ID(),
+                       Metadata:    container.Metadata(),
+                       Labels:      container.Labels(),
+                       Annotations: container.Annotations(),
+               },
+               Cpu: &pb.CpuUsage{
+                       Timestamp:            stats.SystemNano,
+                       UsageCoreNanoSeconds: &pb.UInt64Value{Value: 
stats.CPUNano},
+               },
+               Memory: &pb.MemoryUsage{
+                       Timestamp:       stats.SystemNano,
+                       WorkingSetBytes: &pb.UInt64Value{Value: stats.MemUsage},
+               },
+               WritableLayer: nil,
+       }
+}
+
 // ContainerStats returns stats of the container. If the container does not
 // exist, the call returns an error.
 func (s *Server) ContainerStats(ctx context.Context, req 
*pb.ContainerStatsRequest) (resp *pb.ContainerStatsResponse, err error) {
@@ -16,5 +38,16 @@
                recordOperation(operation, time.Now())
                recordError(operation, err)
        }()
-       return nil, fmt.Errorf("not implemented")
+
+       container := s.GetContainer(req.ContainerId)
+       if container == nil {
+               return nil, fmt.Errorf("invalid container")
+       }
+
+       stats, err := s.GetContainerStats(container, &lib.ContainerStats{})
+       if err != nil {
+               return nil, err
+       }
+
+       return &pb.ContainerStatsResponse{Stats: buildContainerStats(stats, 
container)}, nil
 }
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/cri-o-1.9.10/server/container_stats_list.go 
new/cri-o-1.9.11/server/container_stats_list.go
--- old/cri-o-1.9.10/server/container_stats_list.go     2018-03-12 
17:46:45.000000000 +0100
+++ new/cri-o-1.9.11/server/container_stats_list.go     2018-04-09 
20:22:42.000000000 +0200
@@ -1,9 +1,10 @@
 package server
 
 import (
-       "fmt"
        "time"
 
+       "github.com/kubernetes-incubator/cri-o/lib"
+       "github.com/sirupsen/logrus"
        "golang.org/x/net/context"
        pb "k8s.io/kubernetes/pkg/kubelet/apis/cri/v1alpha1/runtime"
 )
@@ -15,5 +16,34 @@
                recordOperation(operation, time.Now())
                recordError(operation, err)
        }()
-       return nil, fmt.Errorf("not implemented")
+
+       ctrList, err := s.ContainerServer.ListContainers()
+       if err != nil {
+               return nil, err
+       }
+       filter := req.GetFilter()
+       if filter != nil {
+               cFilter := &pb.ContainerFilter{
+                       Id:            req.Filter.Id,
+                       PodSandboxId:  req.Filter.PodSandboxId,
+                       LabelSelector: req.Filter.LabelSelector,
+               }
+               ctrList = s.filterContainerList(cFilter, ctrList)
+       }
+
+       var allStats []*pb.ContainerStats
+
+       for _, container := range ctrList {
+               stats, err := s.GetContainerStats(container, 
&lib.ContainerStats{})
+               if err != nil {
+                       logrus.Warn("unable to get stats for container %s", 
container.ID())
+                       continue
+               }
+               response := buildContainerStats(stats, container)
+               allStats = append(allStats, response)
+       }
+
+       return &pb.ListContainerStatsResponse{
+               Stats: allStats,
+       }, nil
 }
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/cri-o-1.9.10/server/image_fs_info.go 
new/cri-o-1.9.11/server/image_fs_info.go
--- old/cri-o-1.9.10/server/image_fs_info.go    2018-03-12 17:46:45.000000000 
+0100
+++ new/cri-o-1.9.11/server/image_fs_info.go    2018-04-09 20:22:42.000000000 
+0200
@@ -1,13 +1,42 @@
 package server
 
 import (
-       "fmt"
+       "path"
        "time"
 
+       "github.com/containers/storage"
+       crioStorage "github.com/kubernetes-incubator/cri-o/utils"
        "golang.org/x/net/context"
        pb "k8s.io/kubernetes/pkg/kubelet/apis/cri/v1alpha1/runtime"
 )
 
+func getStorageFsInfo(store storage.Store) (*pb.FilesystemUsage, error) {
+       rootPath := store.GraphRoot()
+       storageDriver := store.GraphDriverName()
+       imagesPath := path.Join(rootPath, storageDriver+"-images")
+
+       deviceName, err := crioStorage.GetDeviceNameFromPath(imagesPath)
+
+       uuid, err := crioStorage.GetDeviceUUIDFromPath(deviceName)
+       if err != nil {
+               return nil, err
+       }
+
+       bytesUsed, inodesUsed, err := crioStorage.GetDiskUsageStats(imagesPath)
+       if err != nil {
+               return nil, err
+       }
+
+       usage := pb.FilesystemUsage{
+               Timestamp:  time.Now().UnixNano(),
+               StorageId:  &pb.StorageIdentifier{uuid},
+               UsedBytes:  &pb.UInt64Value{bytesUsed},
+               InodesUsed: &pb.UInt64Value{inodesUsed},
+       }
+
+       return &usage, nil
+}
+
 // ImageFsInfo returns information of the filesystem that is used to store 
images.
 func (s *Server) ImageFsInfo(ctx context.Context, req *pb.ImageFsInfoRequest) 
(resp *pb.ImageFsInfoResponse, err error) {
        const operation = "image_fs_info"
@@ -16,5 +45,14 @@
                recordError(operation, err)
        }()
 
-       return nil, fmt.Errorf("not implemented")
+       store := s.StorageImageServer().GetStore()
+       fsUsage, err := getStorageFsInfo(store)
+
+       if err != nil {
+               return nil, err
+       }
+
+       return &pb.ImageFsInfoResponse{
+               ImageFilesystems: []*pb.FilesystemUsage{fsUsage},
+       }, nil
 }
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/cri-o-1.9.10/server/sandbox_stop.go 
new/cri-o-1.9.11/server/sandbox_stop.go
--- old/cri-o-1.9.10/server/sandbox_stop.go     2018-03-12 17:46:45.000000000 
+0100
+++ new/cri-o-1.9.11/server/sandbox_stop.go     2018-04-09 20:22:42.000000000 
+0200
@@ -116,13 +116,13 @@
 }
 
 // StopAllPodSandboxes removes all pod sandboxes
-func (s *Server) StopAllPodSandboxes() {
+func (s *Server) StopAllPodSandboxes(ctx context.Context) {
        logrus.Debugf("StopAllPodSandboxes")
        for _, sb := range s.ContainerServer.ListSandboxes() {
                pod := &pb.StopPodSandboxRequest{
                        PodSandboxId: sb.ID(),
                }
-               if _, err := s.StopPodSandbox(nil, pod); err != nil {
+               if _, err := s.StopPodSandbox(ctx, pod); err != nil {
                        logrus.Warnf("could not StopPodSandbox %s: %v", 
sb.ID(), err)
                }
        }
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/cri-o-1.9.10/server/server.go 
new/cri-o-1.9.11/server/server.go
--- old/cri-o-1.9.10/server/server.go   2018-03-12 17:46:45.000000000 +0100
+++ new/cri-o-1.9.11/server/server.go   2018-04-09 20:22:42.000000000 +0200
@@ -1,6 +1,7 @@
 package server
 
 import (
+       "context"
        "encoding/json"
        "fmt"
        "io/ioutil"
@@ -146,11 +147,11 @@
 }
 
 // cleanupSandboxesOnShutdown Remove all running Sandboxes on system shutdown
-func (s *Server) cleanupSandboxesOnShutdown() {
+func (s *Server) cleanupSandboxesOnShutdown(ctx context.Context) {
        _, err := os.Stat(shutdownFile)
        if err == nil || !os.IsNotExist(err) {
                logrus.Debugf("shutting down all sandboxes, on shutdown")
-               s.StopAllPodSandboxes()
+               s.StopAllPodSandboxes(ctx)
                err = os.Remove(shutdownFile)
                if err != nil {
                        logrus.Warnf("Failed to remove %q", shutdownFile)
@@ -160,12 +161,12 @@
 }
 
 // Shutdown attempts to shut down the server's storage cleanly
-func (s *Server) Shutdown() error {
+func (s *Server) Shutdown(ctx context.Context) error {
        // why do this on clean shutdown! we want containers left running when 
crio
        // is down for whatever reason no?!
        // notice this won't trigger just on system halt but also on normal
        // crio.service restart!!!
-       s.cleanupSandboxesOnShutdown()
+       s.cleanupSandboxesOnShutdown(ctx)
        return s.ContainerServer.Shutdown()
 }
 
@@ -187,7 +188,7 @@
 }
 
 // New creates a new Server with options provided
-func New(config *Config) (*Server, error) {
+func New(ctx context.Context, config *Config) (*Server, error) {
        if err := os.MkdirAll("/var/run/crio", 0755); err != nil {
                return nil, err
        }
@@ -245,7 +246,7 @@
        }
 
        s.restore()
-       s.cleanupSandboxesOnShutdown()
+       s.cleanupSandboxesOnShutdown(ctx)
 
        bindAddress := net.ParseIP(config.StreamAddress)
        if bindAddress == nil {
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/cri-o-1.9.10/test/ctr.bats 
new/cri-o-1.9.11/test/ctr.bats
--- old/cri-o-1.9.10/test/ctr.bats      2018-03-12 17:46:45.000000000 +0100
+++ new/cri-o-1.9.11/test/ctr.bats      2018-04-09 20:22:42.000000000 +0200
@@ -882,11 +882,19 @@
        run crictl start "$ctr_id"
        echo "$output"
        [ "$status" -eq 0 ]
-       run crictl inspect "$ctr_id"
-       echo "$output"
-       [ "$status" -eq 0 ]
-       [[ "$output" =~ "State: CONTAINER_EXITED" ]]
-       [[ "$output" =~ "Exit Code: 0" ]]
+       # Wait for container to exit
+       attempt=0
+       while [ $attempt -le 100 ]; do
+               attempt=$((attempt+1))
+               run crictl inspect "$ctr_id"
+               echo "$output"
+               [ "$status" -eq 0 ]
+               if [[ "$output" =~ "State: CONTAINER_EXITED" ]]; then
+                       [[ "$output" =~ "Exit Code: 0" ]]
+                       break
+               fi
+               sleep 1
+       done
 
        run crictl create "$pod_id" 
"$TESTDATA"/container_config_resolvconf_ro.json "$TESTDATA"/sandbox_config.json
        echo "$output"
@@ -895,10 +903,18 @@
        run crictl start "$ctr_id"
        echo "$output"
        [ "$status" -eq 0 ]
-       run crictl inspect "$ctr_id"
-       echo "$output"
-       [ "$status" -eq 0 ]
-       [[ "$output" =~ "State: CONTAINER_EXITED" ]]
+       # Wait for container to exit
+       attempt=0
+       while [ $attempt -le 100 ]; do
+               attempt=$((attempt+1))
+               run crictl inspect "$ctr_id"
+               echo "$output"
+               [ "$status" -eq 0 ]
+               if [[ "$output" =~ "State: CONTAINER_EXITED" ]]; then
+                       break
+               fi
+               sleep 1
+       done
 
        cleanup_ctrs
        cleanup_pods
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/cri-o-1.9.10/utils/filesystem.go 
new/cri-o-1.9.11/utils/filesystem.go
--- old/cri-o-1.9.10/utils/filesystem.go        1970-01-01 01:00:00.000000000 
+0100
+++ new/cri-o-1.9.11/utils/filesystem.go        2018-04-09 20:22:42.000000000 
+0200
@@ -0,0 +1,109 @@
+package utils
+
+import (
+       "fmt"
+       "golang.org/x/sys/unix"
+       "io/ioutil"
+       "os"
+       "path/filepath"
+       "strings"
+       "syscall"
+
+       "github.com/docker/docker/pkg/mount"
+)
+
+// GetDiskUsageStats accepts a path to a directory or file
+// and returns the number of bytes and inodes used by the path
+func GetDiskUsageStats(path string) (uint64, uint64, error) {
+       var dirSize, inodeCount uint64
+
+       err := filepath.Walk(path, func(path string, info os.FileInfo, err 
error) error {
+               fileStat, error := os.Lstat(path)
+               if error != nil {
+                       if fileStat.Mode()&os.ModeSymlink != 0 {
+                               // Is a symlink; no error should be returned
+                               return nil
+                       }
+                       return error
+               }
+
+               dirSize += uint64(info.Size())
+               inodeCount++
+
+               return nil
+       })
+
+       if err != nil {
+               return 0, 0, err
+       }
+
+       return dirSize, inodeCount, err
+}
+
+// GetDeviceUUIDFromPath accepts a path, and will find the device
+// corresponding to the path and return the UUID of that device
+func GetDeviceUUIDFromPath(devicePath string) (string, error) {
+       const dir = "/dev/disk/by-uuid"
+
+       if _, err := os.Stat(dir); os.IsNotExist(err) {
+               return "", nil
+       }
+
+       files, err := ioutil.ReadDir(dir)
+       if err != nil {
+               return "", err
+       }
+
+       for _, file := range files {
+               path := filepath.Join(dir, file.Name())
+               target, err := os.Readlink(path)
+               if err != nil {
+                       continue
+               }
+               device, err := filepath.Abs(filepath.Join(dir, target))
+               if err != nil {
+                       return "", fmt.Errorf("failed to resolve the absolute 
path of %q", filepath.Join(dir, target))
+               }
+               if strings.Compare(device, devicePath) == 0 {
+                       return file.Name(), nil
+               }
+       }
+
+       return "", fmt.Errorf("device path %s not found", devicePath)
+}
+
+// GetStattFromPath is a helper function that returns the Stat_t
+// object for a given path
+func GetStattFromPath(path string) (syscall.Stat_t, error) {
+       statInfo := syscall.Stat_t{}
+       err := syscall.Lstat(path, &statInfo)
+       if err != nil {
+               return statInfo, err
+       }
+       return statInfo, nil
+}
+
+// GetDeviceNameFromPath iterates through the mounts and matches
+// the one that the provided path is on
+func GetDeviceNameFromPath(path string) (string, error) {
+       statInfo, err := GetStattFromPath(path)
+       if err != nil {
+               return "", err
+       }
+
+       mounts, err := mount.GetMounts()
+       if err != nil {
+               return "", err
+       }
+
+       queryMajor := int(unix.Major(uint64(statInfo.Dev)))
+       queryMinor := int(unix.Minor(uint64(statInfo.Dev)))
+
+       for _, mount := range mounts {
+               if mount.Minor == queryMinor && mount.Major == queryMajor {
+                       return mount.Source, nil
+               }
+       }
+
+       return "", fmt.Errorf("no match found")
+}
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/cri-o-1.9.10/version/version.go 
new/cri-o-1.9.11/version/version.go
--- old/cri-o-1.9.10/version/version.go 2018-03-12 17:46:45.000000000 +0100
+++ new/cri-o-1.9.11/version/version.go 2018-04-09 20:22:42.000000000 +0200
@@ -1,4 +1,4 @@
 package version
 
 // Version is the version of the build.
-const Version = "1.9.10"
+const Version = "1.9.11"


Reply via email to