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

Add configuration for COS_PERSISTENT partition size. (backport #499) #509

Merged
merged 1 commit into from
Jun 15, 2023
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
10 changes: 5 additions & 5 deletions pkg/config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,11 +30,9 @@ const (
)

const (
SoftMinDiskSizeGiB = 140
HardMinDiskSizeGiB = 60
MinCosPartSizeGiB = 25
NormalCosPartSizeGiB = 50
MaxPods = 200
HardMinDiskSizeGiB = 250
HardMinDataDiskSizeGiB = 50
MaxPods = 200
)

// refer: https://github.com/harvester/harvester/blob/master/pkg/settings/settings.go
Expand Down Expand Up @@ -153,6 +151,8 @@ type Install struct {
Webhooks []Webhook `json:"webhooks,omitempty"`
Addons map[string]Addon `json:"addons,omitempty"`
Harvester HarvesterChartValues `json:"harvester,omitempty"`

PersistentPartitionSize string `json:"persistentPartitionSize,omitempty"`
}

type Wifi struct {
Expand Down
7 changes: 7 additions & 0 deletions pkg/config/constants.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,4 +13,11 @@ const (
MgmtBondInterfaceName = "mgmt-bo"

RancherdConfigFile = "/etc/rancher/rancherd/config.yaml"

DefaultCosOemSizeMiB = 50
DefaultCosStateSizeMiB = 15360
DefaultCosRecoverySizeMiB = 8192

DefaultPersistentPercentageNum = 0.3
PersistentSizeMinGiB = 150
)
38 changes: 17 additions & 21 deletions pkg/config/cos.go
Original file line number Diff line number Diff line change
Expand Up @@ -707,53 +707,49 @@ func genBootstrapResources(config *HarvesterConfig) (map[string]string, error) {
return bootstrapConfs, nil
}

func calcCosPersistentPartSize(diskSizeGiB uint64) (uint64, error) {
switch {
case diskSizeGiB < HardMinDiskSizeGiB:
return 0, fmt.Errorf("disk too small: %dGB. Minimum %dGB is required", diskSizeGiB, HardMinDiskSizeGiB)
case diskSizeGiB < SoftMinDiskSizeGiB:
d := MinCosPartSizeGiB / float64(SoftMinDiskSizeGiB-HardMinDiskSizeGiB)
partSizeGiB := MinCosPartSizeGiB + float64(diskSizeGiB-HardMinDiskSizeGiB)*d
return uint64(partSizeGiB), nil
default:
partSizeGiB := NormalCosPartSizeGiB + ((diskSizeGiB-100)/100)*10
if partSizeGiB > 100 {
partSizeGiB = 100
}
return partSizeGiB, nil
func calcCosPersistentPartSize(diskSizeGiB uint64, partSize string) (uint64, error) {
size, err := util.ParsePartitionSize(util.GiToByte(diskSizeGiB), partSize)
if err != nil {
return 0, err
}
return util.ByteToMi(size), nil
}

func CreateRootPartitioningLayout(elementalConfig *ElementalConfig, devPath string) (*ElementalConfig, error) {
diskSizeBytes, err := util.GetDiskSizeBytes(devPath)
func CreateRootPartitioningLayout(elementalConfig *ElementalConfig, hvstConfig *HarvesterConfig) (*ElementalConfig, error) {
diskSizeBytes, err := util.GetDiskSizeBytes(hvstConfig.Install.Device)
if err != nil {
return nil, err
}

cosPersistentSizeGiB, err := calcCosPersistentPartSize(diskSizeBytes >> 30)
persistentSize := hvstConfig.Install.PersistentPartitionSize
if persistentSize == "" {
persistentSize = fmt.Sprintf("%dGi", PersistentSizeMinGiB)
}
cosPersistentSizeMiB, err := calcCosPersistentPartSize(util.ByteToGi(diskSizeBytes), persistentSize)
if err != nil {
return nil, err
}

logrus.Infof("Calculated COS_PERSISTENT partition size: %d MiB", cosPersistentSizeMiB)
elementalConfig.Install.Partitions = &ElementalDefaultPartition{
OEM: &ElementalPartition{
FilesystemLabel: "COS_OEM",
Size: 50,
Size: DefaultCosOemSizeMiB,
FS: "ext4",
},
State: &ElementalPartition{
FilesystemLabel: "COS_STATE",
Size: 15360,
Size: DefaultCosStateSizeMiB,
FS: "ext4",
},
Recovery: &ElementalPartition{
FilesystemLabel: "COS_RECOVERY",
Size: 8192,
Size: DefaultCosRecoverySizeMiB,
FS: "ext4",
},
Persistent: &ElementalPartition{
FilesystemLabel: "COS_PERSISTENT",
Size: uint(cosPersistentSizeGiB << 10),
Size: uint(cosPersistentSizeMiB),
FS: "ext4",
},
}
Expand Down
105 changes: 31 additions & 74 deletions pkg/config/cos_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,97 +10,54 @@ import (

func TestCalcCosPersistentPartSize(t *testing.T) {
testCases := []struct {
name string
input uint64
output uint64
expectError bool
diskSize uint64
partitionSize string
result uint64
err string
}{
{
name: "Disk too small",
input: 50,
output: 0,
expectError: true,
diskSize: 300,
partitionSize: "150Gi",
result: 153600,
},
{
name: "Disk meet hard requirement",
input: 60,
output: 25,
expectError: false,
diskSize: 500,
partitionSize: "153600Mi",
result: 153600,
},
{
name: "Disk a bit larger than hard requirement: 80G",
input: 80,
output: 31,
expectError: false,
diskSize: 250,
partitionSize: "240Gi",
err: "Partition size is too large. Maximum 176Gi is allowed",
},
{
name: "Disk a bit larger than hard requirement: 100G",
input: 100,
output: 37,
expectError: false,
diskSize: 150,
partitionSize: "100Gi",
err: "Disk size is too small. Minimum 250Gi is required",
},
{
name: "Disk close to the soft requirement",
input: 139,
output: 49,
expectError: false,
diskSize: 300,
partitionSize: "153600Ki",
err: "Partition size should be ended with 'Mi', 'Gi', and no dot and negative is allowed",
},
{
name: "Disk meet soft requirement",
input: SoftMinDiskSizeGiB,
output: 50,
expectError: false,
diskSize: 2000,
partitionSize: "1.5Ti",
err: "Partition size should be ended with 'Mi', 'Gi', and no dot and negative is allowed",
},
{
name: "200GiB",
input: 200,
output: 60,
expectError: false,
},
{
name: "300GiB",
input: 300,
output: 70,
expectError: false,
},
{
name: "400GiB",
input: 400,
output: 80,
expectError: false,
},
{
name: "500GiB",
input: 500,
output: 90,
expectError: false,
},
{
name: "600GiB",
input: 600,
output: 100,
expectError: false,
},
{
name: "Greater than 600GiB should still get 100",
input: 700,
output: 100,
expectError: false,
diskSize: 500,
partitionSize: "abcd",
err: "Partition size should be ended with 'Mi', 'Gi', and no dot and negative is allowed",
},
}

for _, testCase := range testCases {
t.Run(testCase.name, func(t *testing.T) {
sizeGiB, err := calcCosPersistentPartSize(testCase.input)
if testCase.expectError {
assert.NotNil(t, err)
} else {
if err != nil {
t.Log(err)
}
assert.Equal(t, sizeGiB, testCase.output)
}
})
for _, tc := range testCases {
result, err := calcCosPersistentPartSize(tc.diskSize, tc.partitionSize)
assert.Equal(t, tc.result, result)
if err != nil {
assert.EqualError(t, err, tc.err)
}
}
}

Expand Down
89 changes: 48 additions & 41 deletions pkg/console/constant.go
Original file line number Diff line number Diff line change
@@ -1,50 +1,56 @@
package console

const (
titlePanel = "title"
debugPanel = "debug"
diskPanel = "disk"
dataDiskPanel = "dataDisk"
dataDiskValidatorPanel = "dataDiskValidator"
askForceMBRTitlePanel = "askForceMBRTitle"
askForceMBRPanel = "askForceMBR"
forceMBRNotePanel = "forceMBRNote"
askCreatePanel = "askCreate"
serverURLPanel = "serverUrl"
passwordPanel = "osPassword"
passwordConfirmPanel = "osPasswordConfirm"
sshKeyPanel = "sshKey"
tokenPanel = "token"
proxyPanel = "proxy"
askInterfacePanel = "askInterface"
askVlanIDPanel = "askVlanID"
askBondModePanel = "askBondMode"
bondNotePanel = "bondNote"
askNetworkMethodPanel = "askNetworkMethod"
hostnamePanel = "hostname"
addressPanel = "address"
gatewayPanel = "gateway"
mtuPanel = "mtu"
dnsServersPanel = "dnsServers"
hostnameValidatorPanel = "hostnameValidator"
networkValidatorPanel = "networkValidator"
diskValidatorPanel = "diskValidator"
cloudInitPanel = "cloudInit"
validatorPanel = "validator"
notePanel = "note"
installPanel = "install"
footerPanel = "footer"
spinnerPanel = "spinner"
confirmInstallPanel = "confirmInstall"
confirmUpgradePanel = "confirmUpgrade"
upgradePanel = "upgrade"
askVipMethodPanel = "askVipMethodPanel"
vipPanel = "vipPanel"
vipTextPanel = "vipTextPanel"
ntpServersPanel = "ntpServersPanel"
titlePanel = "title"
debugPanel = "debug"
diskPanel = "disk"
persistentSizePanel = "persistentSize"
dataPersistentSizePanel = "dataPersistentSize"
dataPersistentSizeNotePanel = "dataPersistentSizeNote"
dataDiskPanel = "dataDisk"
dataDiskValidatorPanel = "dataDiskValidator"
askForceMBRTitlePanel = "askForceMBRTitle"
askForceMBRPanel = "askForceMBR"
diskNotePanel = "diskNote"
askCreatePanel = "askCreate"
serverURLPanel = "serverUrl"
passwordPanel = "osPassword"
passwordConfirmPanel = "osPasswordConfirm"
sshKeyPanel = "sshKey"
tokenPanel = "token"
proxyPanel = "proxy"
askInterfacePanel = "askInterface"
askVlanIDPanel = "askVlanID"
askBondModePanel = "askBondMode"
bondNotePanel = "bondNote"
askNetworkMethodPanel = "askNetworkMethod"
hostnamePanel = "hostname"
addressPanel = "address"
gatewayPanel = "gateway"
mtuPanel = "mtu"
dnsServersPanel = "dnsServers"
hostnameValidatorPanel = "hostnameValidator"
networkValidatorPanel = "networkValidator"
diskValidatorPanel = "diskValidator"
cloudInitPanel = "cloudInit"
validatorPanel = "validator"
notePanel = "note"
installPanel = "install"
footerPanel = "footer"
spinnerPanel = "spinner"
confirmInstallPanel = "confirmInstall"
confirmUpgradePanel = "confirmUpgrade"
upgradePanel = "upgrade"
askVipMethodPanel = "askVipMethodPanel"
vipPanel = "vipPanel"
vipTextPanel = "vipTextPanel"
ntpServersPanel = "ntpServersPanel"

hostnameTitle = "Configure hostname for this instance"
networkTitle = "Configure network"
diskLabel = "Installation disk"
dataDiskLabel = "Data disk"
persistentSizeLabel = "Persistent size"
askBondModeLabel = "Bond Mode"
askInterfaceLabel = "Management NIC"
askVlanIDLabel = "VLAN ID (optional)"
Expand Down Expand Up @@ -72,6 +78,7 @@ const (
dnsServersNote = "Note: You can use comma to add more DNS servers. Leave blank to use default DNS."
bondNote = "Note: Select one or more NICs for the Management NIC.\nUse the default value for the Bond Mode if only one NIC is selected."
forceMBRNote = "Note: GPT is used by default. You can use MBR if you encountered compatibility issues."
persistentSizeNote = "Note: persistent partition stores data like system package and container images, not the VM data. \nYou can specify a size like 200Gi or 15360Mi. \nLeave it blank to use the default value."

authorizedFile = "/home/rancher/.ssh/authorized_keys"
)
Loading