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

Make ovs-vswitchd service 'other_config' option configurable #823

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
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
3 changes: 3 additions & 0 deletions api/v1/sriovnetworknodestate_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,9 @@ type System struct {
// +kubebuilder:validation:Enum=shared;exclusive
//RDMA subsystem. Allowed value "shared", "exclusive".
RdmaMode string `json:"rdmaMode,omitempty"`
// OVS config. It will be provided for ovs-vswitchd service as other_config option
// +kubebuilder:default:= "hw-offload=true"
OvsConfig string `json:"ovsConfig,omitempty"`
Copy link
Collaborator

Choose a reason for hiding this comment

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

Can we use map[string]string here?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

I would like to support all available options, so this syntax will allow us to easly provide options like other-config:mtu!=1500

Copy link
Collaborator

Choose a reason for hiding this comment

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

I would like to support all available options, so this syntax will allow us to easly provide options like other-config:mtu!=1500

do we have a usecase for that for openvswitch table ?

}

// SriovNetworkNodeStateStatus defines the observed state of SriovNetworkNodeState
Expand Down
3 changes: 3 additions & 0 deletions api/v1/sriovnetworkpoolconfig_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,9 @@ type OvsHardwareOffloadConfig struct {
// On OpenShift:
// Name is the name of MachineConfigPool to be enabled with OVS hardware offload
Name string `json:"name,omitempty"`
// OVS config. It will be provided for ovs-vswitchd service as other_config option
// +kubebuilder:default:= "hw-offload=true"
OvsConfig string `json:"ovsConfig,omitempty"`
}

// SriovNetworkPoolConfigStatus defines the observed state of SriovNetworkPoolConfig
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,4 @@ dropins:
- name: 10-hw-offload.conf
contents: |
[Service]
ExecStartPre=/bin/ovs-vsctl --no-wait set Open_vSwitch . other_config:hw-offload=true
ExecStartPre=/bin/ovs-vsctl --no-wait set Open_vSwitch . other_config:{{ .OvsConfig }}
Original file line number Diff line number Diff line change
Expand Up @@ -176,6 +176,11 @@ spec:
type: array
system:
properties:
ovsConfig:
default: hw-offload=true
description: OVS config. It will be provided for ovs-vswitchd
service as other_config option
type: string
rdmaMode:
description: RDMA subsystem. Allowed value "shared", "exclusive".
enum:
Expand Down Expand Up @@ -346,6 +351,11 @@ spec:
type: string
system:
properties:
ovsConfig:
default: hw-offload=true
description: OVS config. It will be provided for ovs-vswitchd
service as other_config option
type: string
rdmaMode:
description: RDMA subsystem. Allowed value "shared", "exclusive".
enum:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,11 @@ spec:
On OpenShift:
Name is the name of MachineConfigPool to be enabled with OVS hardware offload
type: string
ovsConfig:
default: hw-offload=true
description: OVS config. It will be provided for ovs-vswitchd
service as other_config option
type: string
type: object
rdmaMode:
description: RDMA subsystem. Allowed value "shared", "exclusive".
Expand Down
1 change: 1 addition & 0 deletions controllers/sriovnetworknodepolicy_controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -305,6 +305,7 @@ func (r *SriovNetworkNodePolicyReconciler) syncAllSriovNetworkNodeStates(ctx con
}
if netPoolConfig != nil {
ns.Spec.System.RdmaMode = netPoolConfig.Spec.RdmaMode
ns.Spec.System.OvsConfig = netPoolConfig.Spec.OvsHardwareOffloadConfig.OvsConfig
}
j, _ := json.Marshal(ns)
logger.V(2).Info("SriovNetworkNodeState CR", "content", j)
Expand Down
1 change: 1 addition & 0 deletions controllers/sriovnetworkpoolconfig_controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -159,6 +159,7 @@ func (r *SriovNetworkPoolConfigReconciler) syncOvsHardwareOffloadMachineConfigs(
}

data := render.MakeRenderData()
data.Data["OvsConfig"] = "hw-offload=true"
mc, err := render.GenerateMachineConfig("bindata/manifests/switchdev-config", mcName, mcpName, true, &data)
if err != nil {
return err
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -176,6 +176,11 @@ spec:
type: array
system:
properties:
ovsConfig:
default: hw-offload=true
description: OVS config. It will be provided for ovs-vswitchd
service as other_config option
type: string
rdmaMode:
description: RDMA subsystem. Allowed value "shared", "exclusive".
enum:
Expand Down Expand Up @@ -346,6 +351,11 @@ spec:
type: string
system:
properties:
ovsConfig:
default: hw-offload=true
description: OVS config. It will be provided for ovs-vswitchd
service as other_config option
type: string
rdmaMode:
description: RDMA subsystem. Allowed value "shared", "exclusive".
enum:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,11 @@ spec:
On OpenShift:
Name is the name of MachineConfigPool to be enabled with OVS hardware offload
type: string
ovsConfig:
default: hw-offload=true
description: OVS config. It will be provided for ovs-vswitchd
service as other_config option
type: string
type: object
rdmaMode:
description: RDMA subsystem. Allowed value "shared", "exclusive".
Expand Down
7 changes: 1 addition & 6 deletions pkg/daemon/plugin.go
Original file line number Diff line number Diff line change
Expand Up @@ -52,12 +52,7 @@ func loadPlugins(ns *sriovnetworkv1.SriovNetworkNodeState, helpers helper.HostHe
loadedPlugins = loadedVendorPlugins

if vars.ClusterType != consts.ClusterTypeOpenshift {
k8sPlugin, err := K8sPlugin(helpers)
if err != nil {
log.Log.Error(err, "loadPlugins(): failed to load the k8s plugin")
return nil, err
}

k8sPlugin := K8sPlugin(helpers)
pluginName := k8sPlugin.Name()
if !isPluginDisabled(pluginName, disabledPlugins) {
loadedPlugins[pluginName] = k8sPlugin
Expand Down
4 changes: 2 additions & 2 deletions pkg/daemon/plugin_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -51,8 +51,8 @@ var _ = Describe("config daemon plugin loading tests", func() {

// k8s plugin is ATM the only plugin which require mocking/faking, as its New method performs additional logic
// other than simple plugin struct initialization
K8sPlugin = func(_ helper.HostHelpersInterface) (plugin.VendorPlugin, error) {
return &fakePlugin.FakePlugin{PluginName: "k8s"}, nil
K8sPlugin = func(_ helper.HostHelpersInterface) plugin.VendorPlugin {
return &fakePlugin.FakePlugin{PluginName: "k8s"}
}
})

Expand Down
8 changes: 4 additions & 4 deletions pkg/helper/mock/mock_helper.go

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

13 changes: 11 additions & 2 deletions pkg/host/internal/service/service.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import (

"github.com/k8snetworkplumbingwg/sriov-network-operator/pkg/consts"
"github.com/k8snetworkplumbingwg/sriov-network-operator/pkg/host/types"
"github.com/k8snetworkplumbingwg/sriov-network-operator/pkg/render"
"github.com/k8snetworkplumbingwg/sriov-network-operator/pkg/utils"
)

Expand Down Expand Up @@ -131,7 +132,7 @@ OUTER:
}

// ReadServiceInjectionManifestFile reads service injection file
func (s *service) ReadServiceInjectionManifestFile(path string) (*types.Service, error) {
func (s *service) ReadServiceInjectionManifestFile(path, ovsConfig string) (*types.Service, error) {
data, err := os.ReadFile(path)
if err != nil {
return nil, err
Expand All @@ -142,10 +143,18 @@ func (s *service) ReadServiceInjectionManifestFile(path string) (*types.Service,
return nil, err
}

d := render.MakeRenderData()
d.Data["OvsConfig"] = ovsConfig

srv, err := render.RenderTemplate(serviceContent.Dropins[0].Contents, &d)
if err != nil {
return nil, err
}

return &types.Service{
Name: serviceContent.Name,
Path: systemdDir + serviceContent.Name,
Content: serviceContent.Dropins[0].Contents,
Content: srv.String(),
}, nil
}

Expand Down
8 changes: 4 additions & 4 deletions pkg/host/mock/mock_host.go

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

2 changes: 1 addition & 1 deletion pkg/host/types/interfaces.go
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,7 @@ type ServiceInterface interface {
// ReadServiceManifestFile reads the systemd manifest for a specific service
ReadServiceManifestFile(path string) (*Service, error)
// ReadServiceInjectionManifestFile reads the injection manifest file for the systemd service
ReadServiceInjectionManifestFile(path string) (*Service, error)
ReadServiceInjectionManifestFile(path, ovsConfig string) (*Service, error)
// CompareServices returns true if serviceA needs update(doesn't contain all fields from service B)
CompareServices(serviceA, serviceB *Service) (bool, error)
// UpdateSystemService updates a system service on the host
Expand Down
18 changes: 12 additions & 6 deletions pkg/plugins/k8s/k8s_plugin.go
Original file line number Diff line number Diff line change
Expand Up @@ -93,15 +93,15 @@ const (
)

// Initialize our plugin and set up initial values
func NewK8sPlugin(helper helper.HostHelpersInterface) (plugins.VendorPlugin, error) {
func NewK8sPlugin(helper helper.HostHelpersInterface) plugins.VendorPlugin {
k8sPluging := &K8sPlugin{
PluginName: PluginName,
SpecVersion: "1.0",
hostHelper: helper,
updateTarget: &k8sUpdateTarget{},
}

return k8sPluging, k8sPluging.readManifestFiles()
return k8sPluging
}

// Name returns the name of the plugin
Expand All @@ -117,6 +117,12 @@ func (p *K8sPlugin) Spec() string {
// OnNodeStateChange Invoked when SriovNetworkNodeState CR is created or updated, return if need dain and/or reboot node
func (p *K8sPlugin) OnNodeStateChange(new *sriovnetworkv1.SriovNetworkNodeState) (needDrain bool, needReboot bool, err error) {
log.Log.Info("k8s plugin OnNodeStateChange()")
err = p.readManifestFiles(new.Spec.System.OvsConfig)
if err != nil {
log.Log.Error(err, "k8s plugin OnNodeStateChange(): failed to read manifests")
return
}

needDrain = false
needReboot = false

Expand Down Expand Up @@ -171,8 +177,8 @@ func (p *K8sPlugin) Apply() error {
return p.updateOVSService()
}

func (p *K8sPlugin) readOpenVSwitchdManifest() error {
openVSwitchService, err := p.hostHelper.ReadServiceInjectionManifestFile(ovsUnitFile)
func (p *K8sPlugin) readOpenVSwitchdManifest(ovsConfig string) error {
openVSwitchService, err := p.hostHelper.ReadServiceInjectionManifestFile(ovsUnitFile, ovsConfig)
if err != nil {
return err
}
Expand All @@ -198,8 +204,8 @@ func (p *K8sPlugin) readSriovPostNetworkServiceManifest() error {
return nil
}

func (p *K8sPlugin) readManifestFiles() error {
if err := p.readOpenVSwitchdManifest(); err != nil {
func (p *K8sPlugin) readManifestFiles(ovsConfig string) error {
if err := p.readOpenVSwitchdManifest(ovsConfig); err != nil {
return err
}
if err := p.readSriovServiceManifest(); err != nil {
Expand Down
6 changes: 2 additions & 4 deletions pkg/plugins/k8s/k8s_plugin_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,6 @@ func (snm *serviceNameMatcher) String() string {
var _ = Describe("K8s plugin", func() {
var (
k8sPlugin plugin.VendorPlugin
err error
testCtrl *gomock.Controller
hostHelper *mock_helper.MockHostHelpersInterface
)
Expand All @@ -91,10 +90,9 @@ var _ = Describe("K8s plugin", func() {
for _, s := range []string{
"bindata/manifests/switchdev-config/ovs-units/ovs-vswitchd.service.yaml",
} {
registerCall(hostHelper.EXPECT().ReadServiceInjectionManifestFile(s), realHostMgr.ReadServiceInjectionManifestFile)
registerCall(hostHelper.EXPECT().ReadServiceInjectionManifestFile(s, ""), realHostMgr.ReadServiceInjectionManifestFile)
}
k8sPlugin, err = NewK8sPlugin(hostHelper)
Expect(err).ToNot(HaveOccurred())
k8sPlugin = NewK8sPlugin(hostHelper)
})

AfterEach(func() {
Expand Down
39 changes: 24 additions & 15 deletions pkg/render/render.go
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ func RenderDir(manifestDir string, d *RenderData) ([]*unstructured.Unstructured,
return nil
}

objs, err := RenderTemplate(path, d)
objs, err := RenderFileTemplate(path, d)
if err != nil {
return err
}
Expand All @@ -77,10 +77,15 @@ func RenderDir(manifestDir string, d *RenderData) ([]*unstructured.Unstructured,
return out, nil
}

// RenderTemplate reads, renders, and attempts to parse a yaml or
// RenderTemplate renders provided template to string
func RenderTemplate(template string, d *RenderData) (*bytes.Buffer, error) {
return renderTemplate(template, d)
}

// RenderFileTemplate reads, renders, and attempts to parse a yaml or
// json file representing one or more k8s api objects
func RenderTemplate(path string, d *RenderData) ([]*unstructured.Unstructured, error) {
rendered, err := renderTemplate(path, d)
func RenderFileTemplate(path string, d *RenderData) ([]*unstructured.Unstructured, error) {
rendered, err := renderFileTemplate(path, d)
if err != nil {
return nil, err
}
Expand Down Expand Up @@ -112,8 +117,8 @@ func RenderTemplate(path string, d *RenderData) ([]*unstructured.Unstructured, e
return out, nil
}

func renderTemplate(path string, d *RenderData) (*bytes.Buffer, error) {
tmpl := template.New(path).Option("missingkey=error")
func renderTemplate(rawTemplate string, d *RenderData) (*bytes.Buffer, error) {
tmpl := template.New("template").Option("missingkey=error")
if d.Funcs != nil {
tmpl.Funcs(d.Funcs)
}
Expand All @@ -122,23 +127,27 @@ func renderTemplate(path string, d *RenderData) (*bytes.Buffer, error) {
tmpl.Funcs(template.FuncMap{"getOr": getOr, "isSet": isSet})
tmpl.Funcs(sprig.TxtFuncMap())

source, err := os.ReadFile(path)
if err != nil {
return nil, errors.Wrapf(err, "failed to read manifest %s", path)
}

if _, err := tmpl.Parse(string(source)); err != nil {
return nil, errors.Wrapf(err, "failed to parse manifest %s as template", path)
if _, err := tmpl.Parse(rawTemplate); err != nil {
return nil, errors.Wrapf(err, "failed to parse manifest %s as template", rawTemplate)
}

rendered := bytes.Buffer{}
if err := tmpl.Execute(&rendered, d.Data); err != nil {
return nil, errors.Wrapf(err, "failed to render manifest %s", path)
return nil, errors.Wrapf(err, "failed to render manifest %s", rawTemplate)
}

return &rendered, nil
}

func renderFileTemplate(path string, d *RenderData) (*bytes.Buffer, error) {
source, err := os.ReadFile(path)
if err != nil {
return nil, errors.Wrapf(err, "failed to read manifest %s", path)
}

return renderTemplate(string(source[:]), d)
}

func formateDeviceList(devs []DeviceInfo) string {
out := ""
for _, dev := range devs {
Expand Down Expand Up @@ -232,7 +241,7 @@ func filterTemplates(toFilter map[string]string, path string, d *RenderData) err
}

// Render the template file
renderedData, err := renderTemplate(path, d)
renderedData, err := renderFileTemplate(path, d)
if err != nil {
return err
}
Expand Down
Loading
Loading