Skip to content

Commit

Permalink
Add resize command boilerplate
Browse files Browse the repository at this point in the history
This adds a --disk-size command line argument to `crc start`, as well as
a 'disk-size' config option. The size is specified in GiB. Upon next crc
start, the size of the VM disk will be automatically resized.
This relies on machine driver support, the UpdateConfigRaw
implementation must be able to resize the disk image.
Once that is done, `xfs_growfs` is called on VM startup in order to grow
the size of the VM partition.
  • Loading branch information
cfergeau committed Oct 20, 2020
1 parent 50c72f7 commit 368707b
Show file tree
Hide file tree
Showing 8 changed files with 68 additions and 5 deletions.
2 changes: 2 additions & 0 deletions cmd/crc/cmd/config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ const (
Bundle = "bundle"
CPUs = "cpus"
Memory = "memory"
DiskSize = "disk-size"
NameServer = "nameserver"
PullSecretFile = "pull-secret-file"
DisableUpdateCheck = "disable-update-check"
Expand All @@ -28,6 +29,7 @@ func RegisterSettings(cfg *config.Config) {
cfg.AddSetting(Bundle, constants.DefaultBundlePath, config.ValidateBundle, config.SuccessfullyApplied)
cfg.AddSetting(CPUs, constants.DefaultCPUs, config.ValidateCPUs, config.RequiresRestartMsg)
cfg.AddSetting(Memory, constants.DefaultMemory, config.ValidateMemory, config.RequiresRestartMsg)
cfg.AddSetting(DiskSize, 0, config.ValidateDiskSize, config.RequiresRestartMsg)
cfg.AddSetting(NameServer, "", config.ValidateIPAddress, config.SuccessfullyApplied)
cfg.AddSetting(PullSecretFile, "", config.ValidatePath, config.SuccessfullyApplied)
cfg.AddSetting(DisableUpdateCheck, false, config.ValidateBool, config.SuccessfullyApplied)
Expand Down
5 changes: 5 additions & 0 deletions cmd/crc/cmd/start.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ func init() {
flagSet.StringP(cmdConfig.PullSecretFile, "p", "", fmt.Sprintf("File path of image pull secret (download from %s)", constants.CrcLandingPageURL))
flagSet.IntP(cmdConfig.CPUs, "c", constants.DefaultCPUs, "Number of CPU cores to allocate to the OpenShift cluster")
flagSet.IntP(cmdConfig.Memory, "m", constants.DefaultMemory, "MiB of memory to allocate to the OpenShift cluster")
flagSet.UintP(cmdConfig.DiskSize, "d", 0, "Total size in GiB of the disk used by the CodeReady Container instance")
flagSet.StringP(cmdConfig.NameServer, "n", "", "IPv4 address of nameserver to use for the OpenShift cluster")
flagSet.Bool(cmdConfig.DisableUpdateCheck, false, "Don't check for update")

Expand Down Expand Up @@ -65,6 +66,7 @@ func runStart(arguments []string) (*machine.StartResult, error) {
startConfig := machine.StartConfig{
BundlePath: config.Get(cmdConfig.Bundle).AsString(),
Memory: config.Get(cmdConfig.Memory).AsInt(),
DiskSize: config.Get(cmdConfig.DiskSize).AsInt(),
CPUs: config.Get(cmdConfig.CPUs).AsInt(),
NameServer: config.Get(cmdConfig.NameServer).AsString(),
PullSecret: &cluster.PullSecret{
Expand Down Expand Up @@ -161,6 +163,9 @@ func validateStartFlags() error {
if err := validation.ValidateCPUs(config.Get(cmdConfig.CPUs).AsInt()); err != nil {
return err
}
if err := validation.ValidateDiskSize(config.Get(cmdConfig.DiskSize).AsInt()); err != nil {
return err
}
if err := validation.ValidateBundle(config.Get(cmdConfig.Bundle).AsString()); err != nil {
return err
}
Expand Down
13 changes: 13 additions & 0 deletions pkg/crc/config/validations.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,19 @@ func ValidateBool(value interface{}) (bool, string) {
return false, "must be true or false"
}

// ValidateDiskSize checks if provided disk size is valid in the config
func ValidateDiskSize(value interface{}) (bool, string) {
diskSize, err := cast.ToIntE(value)
if err != nil {
return false, fmt.Sprintf("could not convert '%s' to integer", value)
}
if err := validation.ValidateDiskSize(diskSize); err != nil {
return false, err.Error()
}

return true, ""
}

// ValidateCPUs checks if provided cpus count is valid in the config
func ValidateCPUs(value interface{}) (bool, string) {
v, err := cast.ToIntE(value)
Expand Down
7 changes: 4 additions & 3 deletions pkg/crc/constants/constants.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,10 @@ import (
)

const (
DefaultName = "crc"
DefaultCPUs = 4
DefaultMemory = 9216
DefaultName = "crc"
DefaultCPUs = 4
DefaultMemory = 9216
DefaultDiskSize = 31

DefaultSSHUser = "core"
DefaultSSHPort = 22
Expand Down
12 changes: 12 additions & 0 deletions pkg/crc/machine/driver.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,3 +32,15 @@ func setVcpus(host *host.Host, vcpus int) error {

return updateDriverValue(host, vcpuSetter)
}

func convertGiBToBytes(gib int) uint64 {
return uint64(gib) * 1024 * 1024 * 1024
}

func setDiskSize(host *host.Host, diskSizeGiB int) error {
diskSizeSetter := func(driver *libmachine.VMDriver) {
driver.DiskCapacity = convertGiBToBytes(diskSizeGiB)
}

return updateDriverValue(host, diskSizeSetter)
}
18 changes: 18 additions & 0 deletions pkg/crc/machine/machine.go
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,19 @@ func (client *client) updateVMConfig(startConfig StartConfig, api libmachine.API
return err
}

/* Disk size */
if startConfig.DiskSize != 0 {
if err := setDiskSize(host, startConfig.DiskSize); err != nil {
logging.Debugf("Failed to update CRC disk configuration: %v", err)
if err != drivers.ErrNotImplemented {
return err
}
}
if err := api.Save(host); err != nil {
return err
}
}

return nil
}

Expand Down Expand Up @@ -262,6 +275,11 @@ func (client *client) Start(startConfig StartConfig) (*StartResult, error) {
return nil, errors.Wrap(err, "Error updating public key")
}

// Trigger disk resize, this will be a no-op if no disk size change is needed
if _, err = sshRunner.Run("sudo xfs_growfs / >/dev/null"); err != nil {
return nil, errors.Wrap(err, "Error updating filesystem size")
}

// Start network time synchronization if `CRC_DEBUG_ENABLE_STOP_NTP` is not set
if stopNtp, _ := strconv.ParseBool(os.Getenv("CRC_DEBUG_ENABLE_STOP_NTP")); !stopNtp {
logging.Info("Starting network time synchronization in CodeReady Containers VM")
Expand Down
5 changes: 3 additions & 2 deletions pkg/crc/machine/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,9 @@ type StartConfig struct {
BundlePath string

// Hypervisor
Memory int
CPUs int
Memory int // Memory size in MiB
CPUs int
DiskSize int // Disk size in GiB

// Nameserver
NameServer string
Expand Down
11 changes: 11 additions & 0 deletions pkg/crc/validation/validation.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,17 @@ func ValidateMemory(value int) error {
return ValidateEnoughMemory(value)
}

func ValidateDiskSize(value int) error {
/* If no disk size was set on the command line or in the preferences, we'll validate '0' */
if value == 0 {
return nil
}
if value < constants.DefaultDiskSize {
return fmt.Errorf("requires disk size in GiB >= %d", constants.DefaultDiskSize)
}
return nil
}

// ValidateEnoughMemory checks if enough memory is installed on the host
func ValidateEnoughMemory(value int) error {
totalMemory := memory.TotalMemory()
Expand Down

0 comments on commit 368707b

Please sign in to comment.