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

feat: Add ability to enable Longhorn V2 Data Engine #55

Merged
merged 4 commits into from
Aug 28, 2024
Merged
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
2 changes: 1 addition & 1 deletion Dockerfile.dapper
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ RUN go install k8s.io/code-generator/cmd/[email protected]

ENV DAPPER_ENV REPO TAG
ENV DAPPER_SOURCE /go/src/github.com/harvester/node-manager/
ENV DAPPER_OUTPUT ./bin ./manifests
ENV DAPPER_OUTPUT ./bin ./manifests ./pkg
ENV DAPPER_DOCKER_SOCKET true
ENV HOME ${DAPPER_SOURCE}
WORKDIR ${DAPPER_SOURCE}
Expand Down
5 changes: 5 additions & 0 deletions manifests/crds/node.harvesterhci.io_nodeconfigs.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,11 @@ spec:
type: object
spec:
properties:
longhornConfig:
properties:
enableV2DataEngine:
type: boolean
type: object
ntpConfigs:
properties:
ntpServers:
Expand Down
16 changes: 11 additions & 5 deletions manifests/daemonset.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -50,9 +50,12 @@ spec:
cpu: 10m
memory: 64Mi
volumeMounts:
- mountPath: /sys/kernel/mm/ksm
name: ksm
Vicente-Cheng marked this conversation as resolved.
Show resolved Hide resolved
- mountPath: /sys/kernel/mm
name: mm
readOnly: false
- mountPath: /lib/modules
name: modules
readOnly: true
- mountPath: /host/proc
name: proc
readOnly: true
Expand All @@ -64,9 +67,12 @@ spec:
- mountPath: /host/oem
name: host-oem
volumes:
- name: ksm
- name: mm
hostPath:
path: /sys/kernel/mm
- name: modules
hostPath:
path: /sys/kernel/mm/ksm
path: /lib/modules
- name: proc
hostPath:
path: /proc
Expand All @@ -81,4 +87,4 @@ spec:
- name: host-oem
hostPath:
path: /oem
type: ""
type: ""
2 changes: 2 additions & 0 deletions package/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,9 @@

FROM registry.suse.com/bci/bci-base:15.5

# kmod -> for `modprobe` command
RUN zypper -n rm container-suseconnect && \
zypper -n install kmod && \
zypper -n clean -a && rm -rf /tmp/* /var/tmp/* /usr/share/doc/packages/*

ARG TARGETPLATFORM
Expand Down
8 changes: 7 additions & 1 deletion pkg/apis/node.harvesterhci.io/v1beta1/nodeconfig.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,12 +22,18 @@ type NodeConfig struct {
}

type NodeConfigSpec struct {
NTPConfig *NTPConfig `json:"ntpConfigs,omitempty"`
NTPConfig *NTPConfig `json:"ntpConfigs,omitempty"`
LonghornConfig *LonghornConfig `json:"longhornConfig,omitempty"`
}

type NTPConfig struct {
NTPServers string `json:"ntpServers"`
}

type LonghornConfig struct {
EnableV2DataEngine bool `json:"enableV2DataEngine,omitempty"`
}

type NodeConfigStatus struct {
NTPConditions []ConfigStatus `json:"ntpConditions,omitempty"`
}
Expand Down
21 changes: 21 additions & 0 deletions pkg/apis/node.harvesterhci.io/v1beta1/zz_generated_deepcopy.go

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

105 changes: 104 additions & 1 deletion pkg/controller/nodeconfig/config/common.go
Original file line number Diff line number Diff line change
@@ -1,11 +1,28 @@
package config

import (
"fmt"
"os"
"slices"

"github.com/harvester/go-common/files"
"github.com/harvester/node-manager/pkg/utils"
"github.com/mudler/yip/pkg/schema"
"github.com/sirupsen/logrus"
)

const (
// we use `99_settings.yaml` because it needs to be run after `90_custom.yaml`
// with elemental works, the later change would override the previous one
yipStageInitramfs = "initramfs"
)

// The following would ordinarily be const, but we need to override them in unit tests

var (
oemPath = "/host/oem/"
settingsOEMPath = "/host/oem/99_settings.yaml"
settingsOEMPathBackupPath = "/host/oem/99_settings.yaml.bak"
yipStageInitramfs = "initramfs"
)

type NTPConfigTemplate struct {
Expand All @@ -20,3 +37,89 @@ func generateNTPConfigData() string {
{{- end }}
`
}

func UpdatePersistentOEMSettings(stage schema.Stage) error {
_, err := os.Stat(settingsOEMPath)
if err != nil && !os.IsNotExist(err) {
return fmt.Errorf("stat %s failed: %v", settingsOEMPath, err)
}

settings := utils.GenerateOEMTemplate()
doBackup := true
if os.IsNotExist(err) {
// New file, we can just set the stages to whatever was passed in.
settings.Stages = make(map[string][]schema.Stage)
settings.Stages[yipStageInitramfs] = []schema.Stage{stage}
doBackup = false
} else {
// Existing file, we need to load it...
err = utils.LoadYipConfigToTarget(settingsOEMPath, settings)
if err != nil {
return fmt.Errorf("load %s to YIP format failed: %v", settingsOEMPath, err)
}
logrus.Debugf("Loaded settings from file %s, content: %+v", settingsOEMPath, settings)
// ...then merge the new stage into whatever stages are already present,
// either overwriting or appending as necessary.
existingStage := slices.IndexFunc(settings.Stages[yipStageInitramfs], func(s schema.Stage) bool {
return s.Name == stage.Name
})
if existingStage == -1 {
settings.Stages[yipStageInitramfs] = append(settings.Stages[yipStageInitramfs], stage)
} else {
settings.Stages[yipStageInitramfs][existingStage] = stage
}
}

return writePersistentOEMSettings(settings, doBackup)
}

func RemovePersistentOEMSettings(stageName string) error {
yipConfig, err := utils.LoadYipConfig(settingsOEMPath)
if err != nil {
if os.IsNotExist(err) {
return nil
}
return fmt.Errorf("load %s failed: %v", settingsOEMPath, err)
}
logrus.Debugf("Loaded yipConfig: %+v, %p", yipConfig, yipConfig)

if _, found := yipConfig.Stages[yipStageInitramfs]; !found {
// this moment, we only have `initramfs` stage, so we could remove all OEM settings files.
logrus.Infof("No `initramfs` stage found, remove all OEM settings files.")
return files.RemoveFiles(settingsOEMPath)
}

pos := slices.IndexFunc(yipConfig.Stages[yipStageInitramfs], func(s schema.Stage) bool {
return s.Name == stageName
})

if pos >= 0 {
stages := yipConfig.Stages[yipStageInitramfs]
stages = append(stages[:pos], stages[pos+1:]...)
if len(stages) == 0 {
logrus.Infof("No other stages found, remove all OEM settings files.")
return files.RemoveFiles(settingsOEMPath)
}
yipConfig.Stages[yipStageInitramfs] = stages
}

// we still have other stages, so we need to backup/update OEM settings files
return writePersistentOEMSettings(yipConfig, true)
}

func writePersistentOEMSettings(yipConfig *schema.YipConfig, doBackup bool) error {
if doBackup {
if _, err := files.BackupFile(settingsOEMPath); err != nil {
return fmt.Errorf("backup %s failed: %v", settingsOEMPath, err)
}
}
logrus.Infof("Prepare to update new settings to persistent files: %+v", yipConfig)
tmpFileName, err := files.GenerateYAMLTempFileWithDir(yipConfig, "settings", oemPath)
if err != nil {
return fmt.Errorf("generate temp YAML file failed: %v", err)
}
if err = os.Rename(tmpFileName, settingsOEMPath); err != nil {
return fmt.Errorf("rename temp file to %s failed: %v", settingsOEMPath, err)
}
return nil
}
Loading
Loading