Skip to content

Commit

Permalink
MGMT-16332: fix requirements base version
Browse files Browse the repository at this point in the history
  • Loading branch information
eifrach committed Jan 28, 2024
1 parent a79294b commit 4c85ac9
Show file tree
Hide file tree
Showing 4 changed files with 353 additions and 28 deletions.
62 changes: 62 additions & 0 deletions internal/operators/lvm/common.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
package lvm

import (
"encoding/json"
"fmt"
"io"
"net/http"
"os"
)

type baseHardware struct {
CPUCores int64 `json:"cpu_cores"`
RAMMib int64 `json:"ram_mib"`
}

type hardwareRequirement struct {
Version string `json:"version,omitempty"`
Master baseHardware `json:"master"`
Worker baseHardware `json:"worker"`
Sno baseHardware `json:"sno"`
}

const (
envRequirementsKey string = "HW_VALIDATOR_REQUIREMENTS"
urlRequirement string = "https://raw.githubusercontent.com/openshift/assisted-service/master/data/default_hw_requirements.json"
)

//TODO: move to common and use it for all operators

type pageDownloader func(s string) (*http.Response, error)

func downloadFromUrl(pageDownloadFunc pageDownloader) (*http.Response, error) {
return pageDownloadFunc(urlRequirement)
}

func get_page(url string) (*http.Response, error) {
return http.Get(url)
}

func getBaseRequiemnts(pageDownloadFunc pageDownloader) (hardwareRequirement, error) {
var baseHardwareRequirement = make([]hardwareRequirement, 1)

baseRequirement := os.Getenv(envRequirementsKey)
if baseRequirement != "" {
err := json.Unmarshal([]byte(baseRequirement), &baseHardwareRequirement)
if err == nil {
return baseHardwareRequirement[0], nil
}
}
resp, err := downloadFromUrl(pageDownloadFunc)
if err != nil {
return baseHardwareRequirement[0], fmt.Errorf("Couldn't download requirement file")
}
data, _ := io.ReadAll(resp.Body)
err = json.Unmarshal(data, &baseHardwareRequirement)
if err != nil {
return baseHardwareRequirement[0], fmt.Errorf("Couldn't marshal JSON from URL")

}

return baseHardwareRequirement[0], nil
}
95 changes: 95 additions & 0 deletions internal/operators/lvm/common_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
package lvm

import (
"encoding/json"
"fmt"
"io"
"net/http"
"os"
"strings"

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

var hwRequirement = `
[
{
"version": "default",
"master": {
"cpu_cores": 1,
"ram_mib": 2,
"disk_size_gb": 3,
"installation_disk_speed_threshold_ms": 10,
"network_latency_threshold_ms": 100,
"packet_loss_percentage": 0
},
"worker": {
"cpu_cores": 2,
"ram_mib": 2,
"disk_size_gb": 3,
"installation_disk_speed_threshold_ms": 10,
"network_latency_threshold_ms": 1000,
"packet_loss_percentage": 10
},
"sno": {
"cpu_cores": 3,
"ram_mib": 2,
"disk_size_gb": 3,
"installation_disk_speed_threshold_ms": 10,
"network_latency_threshold_ms": 1000,
"packet_loss_percentage": 10
}
}
]`

func mock_get_page(url string) (*http.Response, error) {
content := strings.NewReader(hwRequirement)
return &http.Response{
Body: io.NopCloser(content),
}, nil
}

func mock_failed_get_page(url string) (*http.Response, error) {
return &http.Response{}, fmt.Errorf("mock failure")
}

var _ = Describe("Lvm common", func() {

var testData []hardwareRequirement
_ = json.Unmarshal([]byte(hwRequirement), &testData)

Context("GetBaseRequirements", func() {

It("Base Requirements var", func() {
os.Setenv(envRequirementsKey, hwRequirement)
hwHardware, err := getBaseRequiemnts(get_page)
Expect(err).ShouldNot(HaveOccurred())

Expect(testData[0].Master.CPUCores).Should(Equal(hwHardware.Master.CPUCores))
Expect(testData[0].Worker.CPUCores).Should(Equal(hwHardware.Worker.CPUCores))
Expect(testData[0].Sno.CPUCores).Should(Equal(hwHardware.Sno.CPUCores))
os.Unsetenv(envRequirementsKey)

})
It("Base Requirements URL", func() {
hwHardware, err := getBaseRequiemnts(mock_get_page)
Expect(err).ShouldNot(HaveOccurred())

Expect(testData[0].Master.CPUCores).Should(Equal(hwHardware.Master.CPUCores))
Expect(testData[0].Worker.CPUCores).Should(Equal(hwHardware.Worker.CPUCores))
Expect(testData[0].Sno.CPUCores).Should(Equal(hwHardware.Sno.CPUCores))
})

It("Base Requirements URL failed", func() {
_, err := getBaseRequiemnts(mock_failed_get_page)
Expect(err).Should(HaveOccurred())

// failed download
failureMessage := fmt.Errorf("Couldn't download requirement file")
Expect(err).Should(Equal(failureMessage))

})
})
},
)
81 changes: 68 additions & 13 deletions internal/operators/lvm/lvm_operator.go
Original file line number Diff line number Diff line change
Expand Up @@ -168,13 +168,26 @@ func (o *operator) GetMonitoredOperator() *models.MonitoredOperator {
}

// GetHostRequirements provides operator's requirements towards the host
func (o *operator) GetHostRequirements(ctx context.Context, cluster *common.Cluster, _ *models.Host) (*models.ClusterHostRequirementsDetails, error) {
func (o *operator) GetHostRequirements(ctx context.Context, cluster *common.Cluster, host *models.Host) (*models.ClusterHostRequirementsDetails, error) {
log := logutil.FromContext(ctx, o.log)
preflightRequirements, err := o.GetPreflightRequirements(ctx, cluster)
if err != nil {
log.WithError(err).Errorf("Cannot retrieve preflight requirements for cluster %s", cluster.ID)
return nil, err
}

role := common.GetEffectiveRole(host)

if o.GetDeploymetMode(cluster) == common.ClusterDeploymentModeStandard {
if role == models.HostRoleWorker {
return preflightRequirements.Requirements.Worker.Quantitative, nil
}
if role == models.HostRoleAutoAssign {
preflightRequirements.Requirements.Master.Quantitative.CPUCores = 0
preflightRequirements.Requirements.Master.Quantitative.RAMMib = 0
}
}

return preflightRequirements.Requirements.Master.Quantitative, nil
}

Expand All @@ -189,28 +202,70 @@ func (o *operator) GetPreflightRequirements(context context.Context, cluster *co
Dependencies: dependecies,
Requirements: &models.HostTypeHardwareRequirementsWrapper{
Master: &models.HostTypeHardwareRequirements{
Qualitative: []string{},
Quantitative: &models.ClusterHostRequirementsDetails{},
Qualitative: []string{},
Quantitative: &models.ClusterHostRequirementsDetails{
CPUCores: 0,
RAMMib: 0,
},
},
Worker: &models.HostTypeHardwareRequirements{
Qualitative: []string{},
Quantitative: &models.ClusterHostRequirementsDetails{
CPUCores: o.config.LvmCPUPerHost,
RAMMib: o.config.LvmMemoryPerHostMiB,
CPUCores: 0,
RAMMib: 0,
},
},
},
}
if ok, _ := common.BaseVersionLessThan(LvmsMinOpenshiftVersionForNewResourceRequirements, cluster.OpenshiftVersion); ok {
requirements.Requirements.Master.Quantitative.RAMMib += LvmsMemoryRequirementBefore4_13
requirements.Requirements.Master.Quantitative.CPUCores += o.config.LvmCPUPerHost

// unsupportted before 4.11
if ok, _ := common.BaseVersionLessThan("4.11.0", cluster.OpenshiftVersion); ok {
return &requirements, nil
}
mode := o.GetDeploymetMode(cluster)
if mode == common.ClusterDeploymentModeSNO || mode == common.ClusterDeploymentModeCompact {
requirements.Requirements.Master.Quantitative.RAMMib += o.config.LvmMemoryPerHostMiB
requirements.Requirements.Master.Quantitative.CPUCores += o.config.LvmCPUPerHost

// unsupportted multi node before 4.15
clusterType := o.GetDeploymetMode(cluster)
if ok, _ := common.BaseVersionLessThan("4.15.0", cluster.OpenshiftVersion); ok {
if clusterType != common.ClusterDeploymentModeSNO {
return &requirements, nil
}
}

baseHardwareRequirement, _ := getBaseRequiemnts(get_page)

var memoryOverhead int64

if ok, _ := common.BaseVersionLessThan("4.13.0", cluster.OpenshiftVersion); ok {
memoryOverhead = LvmsMemoryRequirementBefore4_13 + baseHardwareRequirement.Sno.RAMMib
} else {
memoryOverhead = o.config.LvmMemoryPerHostMiB + baseHardwareRequirement.Sno.RAMMib
}
cpuOverhead := o.config.LvmCPUPerHost + baseHardwareRequirement.Sno.CPUCores

if ok, _ := common.BaseVersionGreaterOrEqual("4.15.0", cluster.OpenshiftVersion); ok {
if clusterType == common.ClusterDeploymentModeStandard {
memoryOverhead = o.config.LvmMemoryPerHostMiB + baseHardwareRequirement.Worker.RAMMib
cpuOverhead = o.config.LvmCPUPerHost + baseHardwareRequirement.Worker.CPUCores

} else {
memoryOverhead = o.config.LvmMemoryPerHostMiB + baseHardwareRequirement.Sno.RAMMib
}
}
qualitativeRequirements := []string{
"At least 1 non-boot disk on one or more host",
fmt.Sprintf("%v GiB of additional RAM", memoryOverhead),
fmt.Sprintf("%v additional CPUs for each non-boot disk", cpuOverhead),
}
if clusterType == common.ClusterDeploymentModeSNO || clusterType == common.ClusterDeploymentModeCompact {
requirements.Requirements.Master.Quantitative.CPUCores = cpuOverhead
requirements.Requirements.Master.Quantitative.RAMMib = memoryOverhead
requirements.Requirements.Master.Qualitative = qualitativeRequirements

} else {
requirements.Requirements.Master.Quantitative.CPUCores = baseHardwareRequirement.Master.CPUCores
requirements.Requirements.Master.Quantitative.RAMMib = baseHardwareRequirement.Master.RAMMib
requirements.Requirements.Worker.Quantitative.CPUCores = cpuOverhead
requirements.Requirements.Worker.Quantitative.RAMMib = memoryOverhead
requirements.Requirements.Worker.Qualitative = qualitativeRequirements

}

Expand Down

0 comments on commit 4c85ac9

Please sign in to comment.