Skip to content

Commit

Permalink
Add configuration for COS_PERSISTENT partition size.
Browse files Browse the repository at this point in the history
Signed-off-by: masteryyh <[email protected]>
  • Loading branch information
masteryyh authored and Vicente-Cheng committed Jun 15, 2023
1 parent 0540832 commit 2dbc7b5
Show file tree
Hide file tree
Showing 11 changed files with 590 additions and 252 deletions.
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

0 comments on commit 2dbc7b5

Please sign in to comment.