Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

hotplug feature: add pod networks annotation controller #777

Closed
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
41 commits
Select commit Hold shift + click to select a range
71ea3b5
thick-plugin: refactor multus
maiqueb Dec 16, 2021
bba9474
react to maintainers review
maiqueb Jan 13, 2022
aed83d5
thick, deployment: update the daemonset spec
maiqueb Jan 20, 2022
c163cc7
thick, config: validate the cni config passed by the runtime
maiqueb Jan 20, 2022
6e22328
thick: model client / server config
maiqueb Jan 24, 2022
3f31f0d
SQUASH candidate, thick, config: cleanup the configuration
maiqueb Feb 9, 2022
41ce328
multus: use args.args instead of an env variable
maiqueb Feb 1, 2022
ddcd865
unit tests: remove weird tests that check an impossible scenario
maiqueb Feb 1, 2022
7fcfe77
docs, thick: document the thick plugin variant
maiqueb Feb 9, 2022
1d228ee
thick, server, multus: re-use common types
maiqueb Feb 9, 2022
b800e09
Merge pull request #771 from maiqueb/thick-arch
dougbtv Feb 21, 2022
9a66450
Replace setenv with runtimeConfig set (#785)
s1061123 Feb 21, 2022
b652f86
Make binary file and directory name consistent
s1061123 Feb 22, 2022
20224de
Simplify e2e scripts (#795)
s1061123 Feb 22, 2022
e6e854a
Split multus unit tests into several files
s1061123 Feb 24, 2022
efde67b
check version incompatibility (#762) (#798)
s1061123 Feb 28, 2022
5b3f05e
Merge pull request #797 from s1061123/dev/refine_multus_ut
dougbtv Feb 28, 2022
107121c
Support CNI 1.0.0
s1061123 Mar 1, 2022
c7be533
Merge pull request #800 from s1061123/dev/cni100
dougbtv Mar 3, 2022
0864e88
Fix thick plugin to run kind-e2e test
s1061123 Mar 4, 2022
1a0fcf0
only warn when netns can't be opened (#803)
dougbtv Mar 3, 2022
d373015
crio: mount /run rslave (#802)
dougbtv Mar 3, 2022
804ab0d
fix the usage of flag "overrideNetworkName" (#805)
cyclinder Mar 4, 2022
4c70e05
Refine unit test in pkg/multus
s1061123 Mar 4, 2022
9d9ff18
Merge pull request #806 from s1061123/dev/refine-multus-ut
dougbtv Mar 4, 2022
ebb7bdf
Merge pull request #807 from s1061123/dev/fix-thick-e2e
dougbtv Mar 4, 2022
497ddfe
Fix install binary for thick plugin
s1061123 Mar 8, 2022
49d49d6
controller: listen to pod network annotation updates
maiqueb Oct 27, 2021
2dbaef1
controller, containerd: add CRI runtime
maiqueb Oct 28, 2021
ed66763
controller, cni: invoke cni API add/remove network
maiqueb Nov 2, 2021
da7adbe
controller, crio: add new runtime
maiqueb Jan 13, 2022
544418b
yaml templating: remove unnecessary config
maiqueb Mar 14, 2022
1e06a12
e2e, tests: re-write macvlan tests in golang
maiqueb Jan 21, 2022
c7e9da6
e2e tests, hotplug: test hotplug interface
maiqueb Mar 15, 2022
1dd0059
ci: only run golang e2e on the thick img variant
maiqueb Mar 16, 2022
9641f7c
config, cri: specify the cri in the multus server config
maiqueb Mar 28, 2022
297d6ed
controller: user informer factories
maiqueb Mar 28, 2022
62f899c
controller: use net-attach-def informer & lister
maiqueb Mar 17, 2022
1728706
controller: use a workqueue, to provide a level trigger controller
maiqueb Mar 22, 2022
a6dc413
containerd, unit tests: add unit tests to containerd runtime
maiqueb Mar 24, 2022
a8ce32c
crio, unit tests: add unit tests to cri-o runtime
maiqueb Mar 25, 2022
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 3 additions & 2 deletions cmd/multus-daemon/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -366,12 +366,13 @@ func handleSignals(stopChannel chan struct{}, signals ...os.Signal) {
func newRuntime(config types.ControllerNetConf) (containerruntimes.ContainerRuntime, error) {
var runtime containerruntimes.ContainerRuntime

timeout := time.Second
rtType, err := parseRuntimeType(config.CriType)
switch rtType {
case containerruntimes.Crio:
runtime, err = crio.NewCrioRuntime(config.CriSocketPath, 5*time.Second)
runtime, err = crio.NewCrioRuntime(config.CriSocketPath, timeout)
case containerruntimes.Containerd:
runtime, err = containerd.NewContainerdRuntime(config.CriSocketPath, time.Second)
runtime, err = containerd.NewContainerdRuntime(config.CriSocketPath, timeout)
}

if err != nil {
Expand Down
45 changes: 15 additions & 30 deletions pkg/containerruntimes/crio/crio.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import (

"github.com/pkg/errors"

"gopkg.in/k8snetworkplumbingwg/multus-cni.v3/pkg/containerruntimes/crio/types"
crioruntime "k8s.io/cri-api/pkg/apis/runtime/v1alpha2"
"k8s.io/kubernetes/pkg/kubelet/util"
)
Expand All @@ -21,28 +22,6 @@ type CrioRuntime struct {
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 == "" {
Expand Down Expand Up @@ -98,17 +77,11 @@ func (cr *CrioRuntime) NetNS(containerID string) (string, error) {
Verbose: true,
})
if err != nil {
return "", errors.Wrap(err, "failed to get pod sandbox info")
return "", fmt.Errorf("failed to get pod sandbox info: %w", err) //errors.Wrap(err, "failed to get pod sandbox info")
}

mapInfo := reply.GetInfo()
var podStatusResponseInfo PodStatusResponseInfo
info := mapInfo["info"]
err = json.Unmarshal([]byte(info), &podStatusResponseInfo)
podStatusResponseInfo, err := ContainerStatus(reply)
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
}

Expand All @@ -120,3 +93,15 @@ func (cr *CrioRuntime) NetNS(containerID string) (string, error) {
}
return "", nil
}

func ContainerStatus(reply *crioruntime.ContainerStatusResponse) (types.PodStatusResponseInfo, error) {
var podStatusResponseInfo types.PodStatusResponseInfo
info := reply.GetInfo()["info"]
if err := json.Unmarshal([]byte(info), &podStatusResponseInfo); err != nil {
if e, ok := err.(*json.SyntaxError); ok {
return types.PodStatusResponseInfo{}, fmt.Errorf("error unmarshalling cri-o's response: syntax error at byte offset %d. Error: %w", e.Offset, e)
}
return types.PodStatusResponseInfo{}, err
}
return podStatusResponseInfo, nil
}
61 changes: 61 additions & 0 deletions pkg/containerruntimes/crio/crio_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
package crio

import (
"context"
"testing"

. "github.com/onsi/ginkgo"
. "github.com/onsi/gomega"

"gopkg.in/k8snetworkplumbingwg/multus-cni.v3/pkg/containerruntimes/crio/fake"
)

func TestController(t *testing.T) {
RegisterFailHandler(Fail)
RunSpecs(t, "Dynamic network attachment controller suite")
}

var _ = Describe("CRI-O runtime", func() {
var runtime *CrioRuntime

When("the runtime *does not* feature any containers", func() {
BeforeEach(func() {
runtime = newDummyCrioRuntime()
})

It("cannot extract the network namespace of a container", func() {
_, err := runtime.NetNS("1234")
Expect(err).To(MatchError("failed to get pod sandbox info: container 1234 not found"))
})
})

When("a live container is provisioned in the runtime", func() {
const (
containerID = "1234"
netnsPath = "bottom-drawer"
)
BeforeEach(func() {
runtime = newDummyCrioRuntime(fake.WithCachedContainer(containerID, netnsPath))
})

It("cannot extract the network namespace of a container", func() {
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the it clause description is wrong, probably a copy paste error.

Expect(runtime.NetNS(containerID)).To(Equal(netnsPath))
})
})
})

func newDummyCrioRuntime(opts ...fake.ClientOpt) *CrioRuntime {
runtimeClient := fake.NewFakeClient()

for _, opt := range opts {
opt(runtimeClient)
}

ctx := context.TODO()
ctxWithCancel, cancelFunc := context.WithCancel(ctx)
return &CrioRuntime{
client: runtimeClient,
context: ctxWithCancel,
cancelFunc: cancelFunc,
}
}
147 changes: 147 additions & 0 deletions pkg/containerruntimes/crio/fake/crio.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,147 @@
package fake

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

"google.golang.org/grpc"

crioruntime "k8s.io/cri-api/pkg/apis/runtime/v1alpha2"

"gopkg.in/k8snetworkplumbingwg/multus-cni.v3/pkg/containerruntimes/crio/types"
)

type CrioClient struct {
cache map[string]string
}

type ClientOpt func(client *CrioClient)

func NewFakeClient(opts ...ClientOpt) *CrioClient {
client := &CrioClient{cache: map[string]string{}}
for _, opt := range opts {
opt(client)
}
return client
}

func WithCachedContainer(containerID string, netnsPath string) ClientOpt {
return func(client *CrioClient) {
client.cache[containerID] = netnsPath
}
}

func (CrioClient) Version(ctx context.Context, in *crioruntime.VersionRequest, opts ...grpc.CallOption) (*crioruntime.VersionResponse, error) {
return nil, nil
}

func (CrioClient) RunPodSandbox(ctx context.Context, in *crioruntime.RunPodSandboxRequest, opts ...grpc.CallOption) (*crioruntime.RunPodSandboxResponse, error) {
return nil, nil
}

func (CrioClient) StopPodSandbox(ctx context.Context, in *crioruntime.StopPodSandboxRequest, opts ...grpc.CallOption) (*crioruntime.StopPodSandboxResponse, error) {
return nil, nil
}

func (CrioClient) RemovePodSandbox(ctx context.Context, in *crioruntime.RemovePodSandboxRequest, opts ...grpc.CallOption) (*crioruntime.RemovePodSandboxResponse, error) {
return nil, nil
}

func (CrioClient) PodSandboxStatus(ctx context.Context, in *crioruntime.PodSandboxStatusRequest, opts ...grpc.CallOption) (*crioruntime.PodSandboxStatusResponse, error) {
return nil, nil
}

func (CrioClient) ListPodSandbox(ctx context.Context, in *crioruntime.ListPodSandboxRequest, opts ...grpc.CallOption) (*crioruntime.ListPodSandboxResponse, error) {
return nil, nil
}

func (CrioClient) CreateContainer(ctx context.Context, in *crioruntime.CreateContainerRequest, opts ...grpc.CallOption) (*crioruntime.CreateContainerResponse, error) {
return nil, nil
}

func (CrioClient) StartContainer(ctx context.Context, in *crioruntime.StartContainerRequest, opts ...grpc.CallOption) (*crioruntime.StartContainerResponse, error) {
return nil, nil
}

func (CrioClient) StopContainer(ctx context.Context, in *crioruntime.StopContainerRequest, opts ...grpc.CallOption) (*crioruntime.StopContainerResponse, error) {
return nil, nil
}

func (CrioClient) RemoveContainer(ctx context.Context, in *crioruntime.RemoveContainerRequest, opts ...grpc.CallOption) (*crioruntime.RemoveContainerResponse, error) {
return nil, nil
}

func (CrioClient) ListContainers(ctx context.Context, in *crioruntime.ListContainersRequest, opts ...grpc.CallOption) (*crioruntime.ListContainersResponse, error) {
return nil, nil
}

func (cc CrioClient) ContainerStatus(ctx context.Context, in *crioruntime.ContainerStatusRequest, opts ...grpc.CallOption) (*crioruntime.ContainerStatusResponse, error) {
containerId := in.ContainerId
netnsPath, wasFound := cc.cache[containerId]
if !wasFound {
return nil, fmt.Errorf("container %s not found", containerId)
}

containerStatus := types.PodStatusResponseInfo{
RunTimeSpec: types.RunTimeSpecInfo{
Linux: types.NamespacesInfo{
Namespaces: []types.NameSpaceInfo{
{
Type: "network",
Path: netnsPath,
},
},
},
},
}

marshalledContainerStatus, err := json.Marshal(&containerStatus)
if err != nil {
return nil, fmt.Errorf("error marshalling the container status: %v", err)
}

return &crioruntime.ContainerStatusResponse{
Info: map[string]string{"info": string(marshalledContainerStatus)},
}, nil
}

func (CrioClient) UpdateContainerResources(ctx context.Context, in *crioruntime.UpdateContainerResourcesRequest, opts ...grpc.CallOption) (*crioruntime.UpdateContainerResourcesResponse, error) {
return nil, nil
}

func (CrioClient) ReopenContainerLog(ctx context.Context, in *crioruntime.ReopenContainerLogRequest, opts ...grpc.CallOption) (*crioruntime.ReopenContainerLogResponse, error) {
return nil, nil
}

func (CrioClient) ExecSync(ctx context.Context, in *crioruntime.ExecSyncRequest, opts ...grpc.CallOption) (*crioruntime.ExecSyncResponse, error) {
return nil, nil
}

func (CrioClient) Exec(ctx context.Context, in *crioruntime.ExecRequest, opts ...grpc.CallOption) (*crioruntime.ExecResponse, error) {
return nil, nil
}

func (CrioClient) Attach(ctx context.Context, in *crioruntime.AttachRequest, opts ...grpc.CallOption) (*crioruntime.AttachResponse, error) {
return nil, nil
}

func (CrioClient) PortForward(ctx context.Context, in *crioruntime.PortForwardRequest, opts ...grpc.CallOption) (*crioruntime.PortForwardResponse, error) {
return nil, nil
}

func (CrioClient) ContainerStats(ctx context.Context, in *crioruntime.ContainerStatsRequest, opts ...grpc.CallOption) (*crioruntime.ContainerStatsResponse, error) {
return nil, nil
}

func (CrioClient) ListContainerStats(ctx context.Context, in *crioruntime.ListContainerStatsRequest, opts ...grpc.CallOption) (*crioruntime.ListContainerStatsResponse, error) {
return nil, nil
}

func (CrioClient) UpdateRuntimeConfig(ctx context.Context, in *crioruntime.UpdateRuntimeConfigRequest, opts ...grpc.CallOption) (*crioruntime.UpdateRuntimeConfigResponse, error) {
return nil, nil
}

func (CrioClient) Status(ctx context.Context, in *crioruntime.StatusRequest, opts ...grpc.CallOption) (*crioruntime.StatusResponse, error) {
return nil, nil
}
23 changes: 23 additions & 0 deletions pkg/containerruntimes/crio/types/types.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
package types

// 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
}