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

Initial bpfman-operator support for Load/Attach Split #347

Draft
wants to merge 1 commit into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
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
95 changes: 3 additions & 92 deletions PROJECT
Original file line number Diff line number Diff line change
Expand Up @@ -11,69 +11,6 @@ plugins:
projectName: bpfman-operator
repo: github.com/bpfman
resources:
- api:
crdVersion: v1
controller: true
domain: bpfman.io
kind: BpfProgram
path: github.com/bpfman/bpfman-operator/apis/v1alpha1
version: v1alpha1
- api:
crdVersion: v1
controller: true
domain: bpfman.io
kind: XdpProgram
path: github.com/bpfman/bpfman-operator/apis/v1alpha1
version: v1alpha1
- api:
crdVersion: v1
controller: true
domain: bpfman.io
kind: TcProgram
path: github.com/bpfman/bpfman-operator/apis/v1alpha1
version: v1alpha1
- api:
crdVersion: v1
controller: true
domain: bpfman.io
kind: TcxProgram
path: github.com/bpfman/bpfman-operator/apis/v1alpha1
version: v1alpha1
- api:
crdVersion: v1
controller: true
domain: bpfman.io
kind: TracePointProgram
path: github.com/bpfman/bpfman-operator/apis/v1alpha1
version: v1alpha1
- api:
crdVersion: v1
controller: true
domain: bpfman.io
kind: KprobeProgram
path: github.com/bpfman/bpfman-operator/apis/v1alpha1
version: v1alpha1
- api:
crdVersion: v1
controller: true
domain: bpfman.io
kind: UprobeProgram
path: github.com/bpfman/bpfman-operator/apis/v1alpha1
version: v1alpha1
- api:
crdVersion: v1
controller: true
domain: bpfman.io
kind: FentryProgram
path: github.com/bpfman/bpfman-operator/apis/v1alpha1
version: v1alpha1
- api:
crdVersion: v1
controller: true
domain: bpfman.io
kind: FexitProgram
path: github.com/bpfman/bpfman-operator/apis/v1alpha1
version: v1alpha1
- api:
crdVersion: v1
controller: true
Expand All @@ -86,47 +23,21 @@ resources:
namespaced: true
controller: true
domain: bpfman.io
kind: BpfNsProgram
path: github.com/bpfman/bpfman-operator/apis/v1alpha1
version: v1alpha1
- api:
crdVersion: v1
namespaced: true
controller: true
domain: bpfman.io
kind: XdpNsProgram
path: github.com/bpfman/bpfman-operator/apis/v1alpha1
version: v1alpha1
- api:
crdVersion: v1
namespaced: true
controller: true
domain: bpfman.io
kind: TcNsProgram
path: github.com/bpfman/bpfman-operator/apis/v1alpha1
version: v1alpha1
- api:
crdVersion: v1
namespaced: true
controller: true
domain: bpfman.io
kind: TcxNsProgram
kind: BpfNsApplication
path: github.com/bpfman/bpfman-operator/apis/v1alpha1
version: v1alpha1
- api:
crdVersion: v1
namespaced: true
controller: true
domain: bpfman.io
kind: UprobeNsProgram
kind: BpfApplicationState
path: github.com/bpfman/bpfman-operator/apis/v1alpha1
version: v1alpha1
- api:
crdVersion: v1
namespaced: true
controller: true
domain: bpfman.io
kind: BpfNsApplication
kind: BpfNsApplicationState
path: github.com/bpfman/bpfman-operator/apis/v1alpha1
version: v1alpha1
version: "3"
37 changes: 37 additions & 0 deletions TODO.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
# Intro

The code has support for:
- XDP, TCX, and Fentry programs in the cluster-scoped BpfApplication, and
- XDP and TCX in the namespace-scoped BpfNsApplication

It's written so that Dave's load/attach split code should drop in pretty easily,
but it's not using it yet. I'm simulating the attachments by reloading the code
for each attachment (like we do today).

# Testing:

- Unit tests for the agent and the operator
- The following working samples contain all program types:
- config/samples/bpfman.io_v1alpha1_bpfapplication.yaml
- config/samples/bpfman.io_v1alpha1_fentry_bpfnsapplication.yaml

# TODO:

(In no particular order.)

- ~~Implement Fentry/Fexit solution.~~
- Integrate with the new bpfman code with load/attach split (of course)
- ~~Create a bpf.o file with all the application types for both cluster and~~
~~namespace scoped BpfApplicaitons.~~
- Review the status/condition values. I redid most of the *ApplicationState
item status values, but the actual overall status is still using an existing
ReconcileSuccess value.
- Review all comments and logs.
- ~~Support namespace-scoped BPF Application CRD~~
- ~~Support the rest of the program types.~~
- ~~Delete old directories.~~
- Rename cluster-scoped CRDs and structures to "Cluster*", and remove "ns" from
namespace-scoped CRDs and structures.
- Make sure we have all the old sample programs covered by BpfApplication-based
sample programs and then delete the *Program-based ones.
- More cleanup and testing.
154 changes: 154 additions & 0 deletions apis/v1alpha1/bpfApplicationState_types.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,154 @@
/*
Copyright 2023 The bpfman Authors.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

package v1alpha1

import (
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
metav1types "k8s.io/apimachinery/pkg/types"
"sigs.k8s.io/controller-runtime/pkg/client"
)

// BpfApplicationProgramState defines the desired state of BpfApplication
// +union
// +kubebuilder:validation:XValidation:rule="has(self.type) && self.type == 'XDP' ? has(self.xdp) : !has(self.xdp)",message="xdp configuration is required when type is XDP, and forbidden otherwise"
// +kubebuilder:validation:XValidation:rule="has(self.type) && self.type == 'TC' ? has(self.tc) : !has(self.tc)",message="tc configuration is required when type is TC, and forbidden otherwise"
// +kubebuilder:validation:XValidation:rule="has(self.type) && self.type == 'TCX' ? has(self.tcx) : !has(self.tcx)",message="tcx configuration is required when type is TCX, and forbidden otherwise"
// +kubebuilder:validation:XValidation:rule="has(self.type) && self.type == 'Fentry' ? has(self.fentry) : !has(self.fentry)",message="fentry configuration is required when type is Fentry, and forbidden otherwise"
// +kubebuilder:validation:XValidation:rule="has(self.type) && self.type == 'Fexit' ? has(self.fexit) : !has(self.fexit)",message="fexit configuration is required when type is Fexit, and forbidden otherwise"
// +kubebuilder:validation:XValidation:rule="has(self.type) && self.type == 'Kprobe' ? has(self.kprobe) : !has(self.kprobe)",message="kprobe configuration is required when type is Kprobe, and forbidden otherwise"
// +kubebuilder:validation:XValidation:rule="has(self.type) && self.type == 'Uprobe' ? has(self.uprobe) : !has(self.uprobe)",message="uprobe configuration is required when type is Uprobe, and forbidden otherwise"
// +kubebuilder:validation:XValidation:rule="has(self.type) && self.type == 'Tracepoint' ? has(self.tracepoint) : !has(self.tracepoint)",message="tracepoint configuration is required when type is Tracepoint, and forbidden otherwise"
type BpfApplicationProgramState struct {
BpfProgramStateCommon `json:",inline"`
// Type specifies the bpf program type
// +unionDiscriminator
// +kubebuilder:validation:Required
// +kubebuilder:validation:Enum:="XDP";"TC";"TCX";"Fentry";"Fexit";"Kprobe";"Uprobe";"Tracepoint"
Type EBPFProgType `json:"type,omitempty"`

// xdp defines the desired state of the application's XdpPrograms.
// +unionMember
// +optional
XDP *XdpProgramInfoState `json:"xdp,omitempty"`

// tc defines the desired state of the application's TcPrograms.
// +unionMember
// +optional
TC *TcProgramInfoState `json:"tc,omitempty"`

// tcx defines the desired state of the application's TcxPrograms.
// +unionMember
// +optional
TCX *TcxProgramInfoState `json:"tcx,omitempty"`

// fentry defines the desired state of the application's FentryPrograms.
// +unionMember
// +optional
Fentry *FentryProgramInfoState `json:"fentry,omitempty"`

// fexit defines the desired state of the application's FexitPrograms.
// +unionMember
// +optional
Fexit *FexitProgramInfoState `json:"fexit,omitempty"`

// kprobe defines the desired state of the application's KprobePrograms.
// +unionMember
// +optional
Kprobe *KprobeProgramInfoState `json:"kprobe,omitempty"`

// uprobe defines the desired state of the application's UprobePrograms.
// +unionMember
// +optional
Uprobe *UprobeProgramInfoState `json:"uprobe,omitempty"`

// tracepoint defines the desired state of the application's TracepointPrograms.
// +unionMember
// +optional
Tracepoint *TracepointProgramInfoState `json:"tracepoint,omitempty"`
}

// BpfApplicationSpec defines the desired state of BpfApplication
type BpfApplicationStateSpec struct {
// Node is the name of the node for this BpfApplicationStateSpec.
Node string `json:"node"`
// The number of times the BpfApplicationState has been updated. Set to 1
// when the object is created, then it is incremented prior to each update.
// This allows us to verify that the API server has the updated object prior
// to starting a new Reconcile operation.
UpdateCount int64 `json:"updatecount"`
// AppLoadStatus reflects the status of loading the bpf application on the
// given node.
AppLoadStatus AppLoadStatus `json:"apploadstatus"`
// Programs is a list of bpf programs contained in the parent application.
// It is a map from the bpf program name to BpfApplicationProgramState
// elements.
Programs []BpfApplicationProgramState `json:"programs,omitempty"`
}

// +genclient
// +genclient:nonNamespaced
// +kubebuilder:object:root=true
// +kubebuilder:subresource:status
// +kubebuilder:resource:scope=Cluster

// BpfApplicationState contains the per-node state of a BpfApplication.
// +kubebuilder:printcolumn:name="Node",type=string,JSONPath=".spec.node"
// +kubebuilder:printcolumn:name="Status",type=string,JSONPath=`.status.conditions[0].reason`
// +kubebuilder:printcolumn:name="Age",type="date",JSONPath=".metadata.creationTimestamp"
type BpfApplicationState struct {
metav1.TypeMeta `json:",inline"`
metav1.ObjectMeta `json:"metadata,omitempty"`

Spec BpfApplicationStateSpec `json:"spec,omitempty"`
Status BpfAppStatus `json:"status,omitempty"`
}

// +kubebuilder:object:root=true
// BpfApplicationStateList contains a list of BpfApplicationState objects
type BpfApplicationStateList struct {
metav1.TypeMeta `json:",inline"`
metav1.ListMeta `json:"metadata,omitempty"`
Items []BpfApplicationState `json:"items"`
}

func (an BpfApplicationState) GetName() string {
return an.Name
}

func (an BpfApplicationState) GetUID() metav1types.UID {
return an.UID

Check warning on line 133 in apis/v1alpha1/bpfApplicationState_types.go

View check run for this annotation

Codecov / codecov/patch

apis/v1alpha1/bpfApplicationState_types.go#L132-L133

Added lines #L132 - L133 were not covered by tests
}

func (an BpfApplicationState) GetAnnotations() map[string]string {
return an.Annotations

Check warning on line 137 in apis/v1alpha1/bpfApplicationState_types.go

View check run for this annotation

Codecov / codecov/patch

apis/v1alpha1/bpfApplicationState_types.go#L136-L137

Added lines #L136 - L137 were not covered by tests
}

func (an BpfApplicationState) GetLabels() map[string]string {
return an.Labels
}

func (an BpfApplicationState) GetStatus() *BpfAppStatus {
return &an.Status
}

func (an BpfApplicationState) GetClientObject() client.Object {
return &an

Check warning on line 149 in apis/v1alpha1/bpfApplicationState_types.go

View check run for this annotation

Codecov / codecov/patch

apis/v1alpha1/bpfApplicationState_types.go#L148-L149

Added lines #L148 - L149 were not covered by tests
}

func (anl BpfApplicationStateList) GetItems() []BpfApplicationState {
return anl.Items
}
Loading
Loading