Skip to content

Commit

Permalink
controller, crio: add new runtime
Browse files Browse the repository at this point in the history
Signed-off-by: Miguel Duarte Barroso <[email protected]>
  • Loading branch information
maiqueb committed Jan 13, 2022
1 parent 24354ed commit f99f08e
Show file tree
Hide file tree
Showing 9 changed files with 35,563 additions and 1 deletion.
1 change: 1 addition & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ require (
k8s.io/api v0.20.10
k8s.io/apimachinery v0.20.10
k8s.io/client-go v0.20.10
k8s.io/cri-api v0.20.6
k8s.io/klog v1.0.0
k8s.io/kubelet v0.0.0
k8s.io/kubernetes v1.20.10
Expand Down
1 change: 1 addition & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -1220,6 +1220,7 @@ k8s.io/component-base v0.20.10 h1:QNlekT6M2zBb4feHHmZ+YHZHcDbhbrYS7xHHY+v+kOE=
k8s.io/component-base v0.20.10/go.mod h1:ZKOEin1xu68aJzxgzl5DZSp5J1IrjAOPlPN90/t6OI8=
k8s.io/component-helpers v0.20.10/go.mod h1:9SuOCO69yzUr8t9oajyO40NPAYK3JCYXwwyLS3YINR4=
k8s.io/controller-manager v0.20.10/go.mod h1:NwFcdJR5ZK0pjKNUZuZbus/tO8I0zSkGpp0ifQi2DK0=
k8s.io/cri-api v0.20.10 h1:oxLlS4secm8hQ/roV3Pt1PxB9j3YZimRODm//wS0EO8=
k8s.io/cri-api v0.20.10/go.mod h1:ew44AjNXwyn1s0U4xCKGodU7J1HzBeZ1MpGrpa5r8Yc=
k8s.io/csi-translation-lib v0.20.10/go.mod h1:dVQvr/Y/74jFZU955V/KqgZJ4E4hRF4IcsxUq0WbUrc=
k8s.io/gengo v0.0.0-20190128074634-0689ccc1d7d6/go.mod h1:ezvh/TsK7cY6rbqRK0oQQ8IAqLxYwwyPxAX1Pzy0ii0=
Expand Down
122 changes: 122 additions & 0 deletions pkg/containerruntimes/crio.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,122 @@
package containerruntimes

import (
"context"
"encoding/json"
"fmt"
"time"

"google.golang.org/grpc"

"github.com/pkg/errors"

crioruntime "k8s.io/cri-api/pkg/apis/runtime/v1alpha2"
"k8s.io/kubernetes/pkg/kubelet/util"
)

// CrioRuntime represents a connection to the CRI-O runtime
type CrioRuntime struct {
cancelFunc context.CancelFunc
client crioruntime.RuntimeServiceClient
context context.Context
}

// PodStatusResponseInfo represents the container status reply - crictl ps <containerID>
type PodStatusResponseInfo struct {
SandboxID string
RunTimeSpec RunTimeSpecInfo
}

// RunTimeSpecInfo represents the relevant part of the container status spec
type RunTimeSpecInfo struct {
Linux NamespacesInfo
}

// NamespacesInfo represents the container status namespaces
type NamespacesInfo struct {
Namespaces []NameSpaceInfo
}

// NameSpaceInfo represents the ns info
type NameSpaceInfo struct {
Type string
Path string
}

// NewCrioRuntime returns a connection to the CRI-O runtime
func NewCrioRuntime(socketPath string, timeout time.Duration) (*CrioRuntime, error) {
if socketPath == "" {
return nil, fmt.Errorf("path to cri-o socket missing")
}

ctx, cancelFunc := context.WithTimeout(context.Background(), timeout)
clientConnection, err := getConnection([]string{socketPath})
if err != nil {
cancelFunc()
return nil, errors.Wrap(err, "connect")
}
runtimeClient := crioruntime.NewRuntimeServiceClient(clientConnection)

return &CrioRuntime{
client: runtimeClient,
context: ctx,
cancelFunc: cancelFunc,
}, nil
}

func getConnection(endPoints []string) (*grpc.ClientConn, error) {
if endPoints == nil || len(endPoints) == 0 {
return nil, fmt.Errorf("endpoint is not set")
}
endPointsLen := len(endPoints)
var conn *grpc.ClientConn
for i, endPoint := range endPoints {
addr, dialer, err := util.GetAddressAndDialer(endPoint)
if err != nil {
if i == endPointsLen-1 {
return nil, err
}
continue
}
conn, err = grpc.Dial(addr, grpc.WithInsecure(), grpc.WithBlock(), grpc.WithTimeout(5*time.Second), grpc.WithContextDialer(dialer))
if err != nil {
errMsg := errors.Wrapf(err, "connect endpoint '%s', make sure you are running as root and the endpoint has been started", endPoint)
if i == endPointsLen-1 {
return nil, errMsg
}
} else {
break
}
}
return conn, nil
}

// NetNS returns the network namespace of the given containerID.
func (cr *CrioRuntime) NetNS(containerID string) (string, error) {
reply, err := cr.client.ContainerStatus(context.Background(), &crioruntime.ContainerStatusRequest{
ContainerId: containerID,
Verbose: true,
})
if err != nil {
return "", errors.Wrap(err, "failed to get pod sandbox info")
}

mapInfo := reply.GetInfo()
var podStatusResponseInfo PodStatusResponseInfo
info := mapInfo["info"]
err = json.Unmarshal([]byte(info), &podStatusResponseInfo)
if err != nil {
if e, ok := err.(*json.SyntaxError); ok {
return "", fmt.Errorf("error unmarshalling cri-o's response: syntax error at byte offset %d. Error: %w", e.Offset, e)
}
return "", err
}

namespaces := podStatusResponseInfo.RunTimeSpec.Linux.Namespaces
for _, namespace := range namespaces {
if namespace.Type == "network" {
return namespace.Path, nil
}
}
return "", nil
}
2 changes: 1 addition & 1 deletion pkg/containerruntimes/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ func NewRuntime(socketPath string, runtimeType RuntimeType) (*ContainerRuntime,

switch runtimeType {
case Crio:
// TODO
runtime, err = NewCrioRuntime(socketPath, 5*time.Second)
case Containerd:
runtime, err = NewContainerdRuntime(socketPath, time.Second)
}
Expand Down
201 changes: 201 additions & 0 deletions vendor/k8s.io/cri-api/LICENSE

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading

0 comments on commit f99f08e

Please sign in to comment.