]> git.ipfire.org Git - thirdparty/open-vm-tools.git/commitdiff
AppVisibility: Skip terminated/stopped containers.
authorJohn Wolfe <jwolfe@vmware.com>
Mon, 7 Feb 2022 17:40:00 +0000 (09:40 -0800)
committerJohn Wolfe <jwolfe@vmware.com>
Mon, 7 Feb 2022 17:40:00 +0000 (09:40 -0800)
Added code to skip terminated/stopped containers.  This is done
by using TaskStub to retrieve the pid for the running container.
If the pid cannot be retrieved, then that container is skipped.

The previously suppressed "default" namespace has been restored.

Fixed another minor issue with calculating the number of containers
that were added.

Note: This changeset introduces a dependency on Tasks.proto, and
Tasks.proto depends on a few other proto files like mount, metrics,
descriptor and task.  Modified the makefile to generate the necessary
C++ files from the proto files.

Additional notes:
 - .proto -> generates .pb.h, .pb.c and .grpc.pb.cc files.
 - For compiling and building the library (.so file), the .grpc.pb.{h,cc}
   and .pb.{h,cc} files are needed.
 - The protoc compiler generates .pb.h and .pb.c files when the --cpp_out
   option is specified.
 - The protoc compiler generates .grpc.pb.* when the --grpc_out option is
   specified.

open-vm-tools/configure.ac
open-vm-tools/services/plugins/containerInfo/Makefile.am
open-vm-tools/services/plugins/containerInfo/containerInfo.c
open-vm-tools/services/plugins/containerInfo/containerInfo_grpc.cc
open-vm-tools/tools.conf

index 3675d484a9e454b62fc38ae9cadc88843a3477f4..4d268f6457a988c84d2b28417bc5b1b1631c60b1 100644 (file)
@@ -1,5 +1,5 @@
 ################################################################################
-### Copyright (c) 2007-2021 VMware, Inc.  All rights reserved.
+### Copyright (c) 2007-2022 VMware, Inc.  All rights reserved.
 ###
 ### Configure script for building the VMware OSS Tools.
 ###
@@ -727,11 +727,29 @@ AC_DEFUN([AC_VMW_CONTAINERINFO_MSG],[
 # proto files needed by containerd grpc client.
 #
    shared_prefix=/usr/share/gocode/src/github.com
+   AC_SUBST(TYPES_DIR, github.com/containerd/containerd/api/types)
+   AC_SUBST(TASKS_PROTOPATH, $shared_prefix/containerd/containerd/api/services/tasks/v1)
+   AC_SUBST(DEP_PROTOPATH, /usr/share/gocode/src)
    AC_SUBST(CONTAINERD_PROTOPATH, $shared_prefix/containerd/containerd/api/services/containers/v1)
    AC_SUBST(GOGO_PROTOPATH, $shared_prefix/gogo/protobuf)
    AC_CHECK_FILE([${CONTAINERD_PROTOPATH}/containers.proto],
                  [],
                  [AC_VMW_CONTAINERINFO_MSG(["containerd package"])])
+   AC_CHECK_FILE([${TASKS_PROTOPATH}/tasks.proto],
+                 [],
+                 [AC_VMW_CONTAINERINFO_MSG(["containerd package"])])
+   AC_CHECK_FILE([${DEP_PROTOPATH}/${TYPES_DIR}/mount.proto],
+                 [],
+                 [AC_VMW_CONTAINERINFO_MSG(["containerd package"])])
+   AC_CHECK_FILE([${DEP_PROTOPATH}/${TYPES_DIR}/metrics.proto],
+                 [],
+                 [AC_VMW_CONTAINERINFO_MSG(["containerd package"])])
+   AC_CHECK_FILE([${DEP_PROTOPATH}/${TYPES_DIR}/descriptor.proto],
+                 [],
+                 [AC_VMW_CONTAINERINFO_MSG(["containerd package"])])
+   AC_CHECK_FILE([${DEP_PROTOPATH}/${TYPES_DIR}/task/task.proto],
+                 [],
+                 [AC_VMW_CONTAINERINFO_MSG(["containerd package"])])
    AC_CHECK_FILE([${GOGO_PROTOPATH}/gogoproto/gogo.proto],
                  [],
                  [AC_VMW_CONTAINERINFO_MSG(["gogoproto package"])])
index a3779ae66f4b767719ef75fc3bd22799f20f0871..488e35aaa8edbce158e6f5b7d2feb5628648766f 100644 (file)
@@ -1,5 +1,5 @@
 ################################################################################
-### Copyright (c) 2021 VMware, Inc.  All rights reserved.
+### Copyright (c) 2021-2022 VMware, Inc.  All rights reserved.
 ###
 ### This program is free software; you can redistribute it and/or modify
 ### it under the terms of version 2 of the GNU General Public License as
@@ -20,9 +20,6 @@ SUBDIRS =
 plugindir = @VMSVC_PLUGIN_INSTALLDIR@
 plugin_LTLIBRARIES = libcontainerInfo.la
 
-PWD = $(shell pwd)
-CONTAINERS_PROTO = $(PWD)/containers.proto
-
 libcontainerInfo_la_CPPFLAGS =
 libcontainerInfo_la_CPPFLAGS += @PLUGIN_CPPFLAGS@
 
@@ -45,28 +42,57 @@ libcontainerInfo_la_LIBADD += ../../../lib/jsmn/libJsmn.la
 
 libcontainerInfo_la_SOURCES += gogoproto/gogo.pb.h
 libcontainerInfo_la_SOURCES += gogoproto/gogo.pb.cc
-libcontainerInfo_la_SOURCES += containers.pb.cc
+libcontainerInfo_la_SOURCES += $(TYPES_DIR)/mount.pb.h
+libcontainerInfo_la_SOURCES += $(TYPES_DIR)/mount.pb.cc
+libcontainerInfo_la_SOURCES += $(TYPES_DIR)/metrics.pb.h
+libcontainerInfo_la_SOURCES += $(TYPES_DIR)/metrics.pb.cc
+libcontainerInfo_la_SOURCES += $(TYPES_DIR)/descriptor.pb.h
+libcontainerInfo_la_SOURCES += $(TYPES_DIR)/descriptor.pb.cc
+libcontainerInfo_la_SOURCES += $(TYPES_DIR)/task/task.pb.h
+libcontainerInfo_la_SOURCES += $(TYPES_DIR)/task/task.pb.cc
+libcontainerInfo_la_SOURCES += tasks.pb.h
+libcontainerInfo_la_SOURCES += tasks.pb.cc
 libcontainerInfo_la_SOURCES += containers.pb.h
-libcontainerInfo_la_SOURCES += containers.grpc.pb.cc
+libcontainerInfo_la_SOURCES += containers.pb.cc
+libcontainerInfo_la_SOURCES += tasks.grpc.pb.h
+libcontainerInfo_la_SOURCES += tasks.grpc.pb.cc
 libcontainerInfo_la_SOURCES += containers.grpc.pb.h
+libcontainerInfo_la_SOURCES += containers.grpc.pb.cc
 libcontainerInfo_la_SOURCES += containerInfo_grpc.cc
 
 libcontainerInfo_la_CPPFLAGS += @GRPC_CPPFLAGS@
 libcontainerInfo_la_LDFLAGS += -lprotobuf
 libcontainerInfo_la_LDFLAGS += -lgrpc++
 
-containers.grpc.pb.cc \
-containers.grpc.pb.h: $(CONTAINERS_PROTO)
-       $(PROTOC) -I$(PWD) -I$(GOGO_PROTOPATH) \
-             --grpc_out=. --plugin=protoc-gen-grpc=`which $(GRPC_CPP)` $^
-
-gogoproto/gogo.pb.cc \
-gogoproto/gogo.pb.h \
-containers.pb.cc \
-containers.pb.h: $(CONTAINERD_PROTOPATH)/containers.proto \
-                 $(GOGO_PROTOPATH)/gogoproto/gogo.proto
-       sed 's/import weak /import /' \
-           $(CONTAINERD_PROTOPATH)/containers.proto > $(CONTAINERS_PROTO)
-       $(MKDIR_P) gogoproto/
-       $(PROTOC) --cpp_out=. -I$(PWD) -I$(GOGO_PROTOPATH) \
-                        $(CONTAINERS_PROTO) $(GOGO_PROTOPATH)/gogoproto/gogo.proto
+tasks.grpc.pb.cc containers.grpc.pb.cc: %.grpc.pb.cc : %.proto %.pb.cc
+       $(PROTOC) -I. -I$(GOGO_PROTOPATH) \
+             --grpc_out=. --plugin=protoc-gen-grpc=`which $(GRPC_CPP)` $<
+
+containerInfo_grpc.cc : containers.grpc.pb.cc tasks.grpc.pb.cc
+
+$(TYPES_DIR)/mount.proto \
+$(TYPES_DIR)/metrics.proto \
+$(TYPES_DIR)/descriptor.proto \
+$(TYPES_DIR)/task/task.proto: %.proto : $(DEP_PROTOPATH)/%.proto
+       $(MKDIR_P) $(@D)
+       sed 's/import weak /import /' $< > $@
+
+$(TYPES_DIR)/mount.pb.cc \
+$(TYPES_DIR)/metrics.pb.cc \
+$(TYPES_DIR)/descriptor.pb.cc \
+$(TYPES_DIR)/task/task.pb.cc: %.pb.cc : %.proto
+       $(PROTOC) --cpp_out=. -I$(GOGO_PROTOPATH) -I. $<
+
+tasks.proto: $(TASKS_PROTOPATH)/tasks.proto
+       sed 's/import weak /import /' $< > $@
+
+containers.proto: $(CONTAINERD_PROTOPATH)/containers.proto
+       sed 's/import weak /import /' $< > $@
+
+tasks.pb.cc containers.pb.cc: %.pb.cc : %.proto
+       $(PROTOC) --cpp_out=. -I. -I$(GOGO_PROTOPATH) $<
+
+gogoproto/gogo.pb.cc: $(GOGO_PROTOPATH)/gogoproto/gogo.proto
+       $(MKDIR_P) $(@D)
+       $(PROTOC) --cpp_out=. -I$(GOGO_PROTOPATH) $<
+
index faa55de5e38523fba108c4fbd9110f9731b17bb7..9c63c7b76284d4dae650f2df560f19f517b0476c 100644 (file)
@@ -87,7 +87,7 @@ VM_EMBED_VERSION(VMTOOLSD_VERSION_STRING);
 /**
  * Default value for allowed-namespaces conf key.
  */
-#define CONTAINERINFO_DEFAULT_ALLOWED_NAMESPACES "moby,k8s.io"
+#define CONTAINERINFO_DEFAULT_ALLOWED_NAMESPACES "moby,k8s.io,default"
 
 /**
  * Name of the 'moby' namespace used by docker.
index c341d2c52dfe5442c9612d149b9275961b9093da..5f6aa7a68e5f8d3b99e3ebd53deca2977ecb2eba 100644 (file)
@@ -1,5 +1,5 @@
 /*********************************************************
- * Copyright (C) 2021 VMware, Inc. All rights reserved.
+ * Copyright (C) 2021-2022 VMware, Inc. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of the GNU Lesser General Public License as published
 
 #include "containerInfoInt.h"
 #include "containers.grpc.pb.h"
-#include "containers.pb.h"
+#include "tasks.grpc.pb.h"
 #include <grpc++/grpc++.h>
 #include <stdio.h>
 
 using namespace containerd::services::containers::v1;
+using namespace containerd::services::tasks::v1;
+using namespace containerd::v1::types;
 using namespace google::protobuf;
 
 
@@ -62,8 +64,10 @@ ContainerInfo_GetContainerList(const char *ns,                   // IN
    GSList *containerList = NULL;
    std::shared_ptr<grpc::ChannelInterface> channel;
    std::unique_ptr<Containers::Stub> containerStub;
+   std::unique_ptr<Tasks::Stub> taskStub;
    grpc::Status status;
    int i;
+   int containersAdded;
    const ListContainersRequest req;
    std::unique_ptr<ListContainersResponse> res;
    grpc::ClientContext containerContext;
@@ -94,6 +98,12 @@ ContainerInfo_GetContainerList(const char *ns,                   // IN
       goto exit;
    }
 
+   taskStub = Tasks::NewStub(channel);
+   if (taskStub == nullptr) {
+      g_warning("%s: Failed to create taskStub\n", __FUNCTION__);
+      goto exit;
+   }
+
    res = std::make_unique<ListContainersResponse>();
    status = containerStub->List(&containerContext, req, res.get());
 
@@ -106,18 +116,39 @@ ContainerInfo_GetContainerList(const char *ns,                   // IN
    g_debug("%s: Namespace: '%s', number of containers found: %d", __FUNCTION__,
            ns, res->containers_size());
 
-   for (i = 0; i < res->containers_size() && i < maxContainers; i++) {
+   for (i = 0, containersAdded = 0;
+        i < res->containers_size() && containersAdded < maxContainers; i++) {
       Container curContainer = res->containers(i);
       std::string id = curContainer.id();
       std::string image = curContainer.image();
-      ContainerInfo *info = (ContainerInfo *)g_malloc(sizeof(*info));
-
+      ContainerInfo *info;
+      GetRequest taskReq;
+      std::unique_ptr<GetResponse> taskRes;
+      grpc::Status taskStatus;
+      grpc::ClientContext taskContext;
+
+      taskContext.AddMetadata(namespaceKey, ns);
+
+      /*
+       * Get pid for container using taskStub.
+       */
+      taskRes = std::make_unique<GetResponse>();
+      taskReq.set_container_id(id);
+      taskStatus = taskStub->Get(&taskContext, taskReq, taskRes.get());
+      if (!taskStatus.ok()) {
+         g_debug("%s: Task get service failed: %s. skipping container: %s\n",
+                 __FUNCTION__, taskStatus.error_message().c_str(), id.c_str());
+         continue;
+      }
+
+      info = (ContainerInfo *)g_malloc(sizeof(*info));
       info->id = g_strdup(id.c_str());
       info->image = g_strdup(image.c_str());
 
       g_debug("%s: Found container id: %s and image: %s\n", __FUNCTION__,
               info->id, info->image);
       containerList = g_slist_prepend(containerList, info);
+      containersAdded++;
    }
 
 exit:
index 6d48ca7835d876367ca25602cb88133e9c09a54c..5679887492d397411eabf5ec97b35c8420114b1b 100644 (file)
 # User-defined poll interval in seconds. Set to 0 to disable the plugin.
 #poll-interval=21600
 
-# Maximum number of containers to be retrieved.
+# Maximum number of containers to be retrieved per namespace.
 #max-containers=256
 
 # Whether to remove the duplicate containers information in the
 
 # List of namespaces to be queried for the running containers.
 # The value for this key is a comman separated list.
-#allowed-namespaces=moby,k8s.io
+#allowed-namespaces=moby,k8s.io,default
 
 [servicediscovery]