Kubernetes has two very similar versions for their CRI API (v1 and v1alpha), defined here:
https://github.com/kubernetes/cri-api/blob/release-1.25/pkg/apis/runtime/v1/api.proto
https://github.com/kubernetes/cri-api/blob/release-1.25/pkg/apis/runtime/v1alpha/api.proto
These get converted using protoc to C++ headers which clients use to make remote API calls. Some Kubernetes clusters support only v1alpha, some only v1 and some both.
The client code looks like this:
auto stub = runtime::v1::RuntimeService::NewStub(unixSockPath);
runtime::v1::ListContainersRequest req;
runtime::v1::ListContainersResponse resp;
stub->ListContainers(req, &res);
or like this, depending on which version is supported by the server:
auto stub = runtime::v1alpha::RuntimeService::NewStub(unixSockPath);
runtime::v1alpha::ListContainersRequest req;
runtime::v1alpha::ListContainersResponse resp;
stub->ListContainers(req, &res);
(only the type names have changed.)
So clients have to try with v1 first and fallback to v1alpha if v1 is not supported.
Is there a way to write a template function that issues the above requests and uses the namespace (runtime::v1, runtime::v1alpha) as a template parameter ? This would enable writing code like:
std::list<std::string> listContainers() {
try {
if (g_useV1)
return __listContainers<runtime::v1>();
} catch (const not_supported &ex) {
g_useV1 = false;
}
return __listContainers<runtime::v1alpha>();
}
Or is passing all the used typenames (RuntimeService::NewStub, ListContainerRequest etc) as template parameters the only option ?