From d5b3146a28b9a579fb182bbae4383b8e9a2d370e Mon Sep 17 00:00:00 2001 From: Kathryn Anne S Tan Date: Thu, 22 Aug 2024 23:08:33 +0300 Subject: [PATCH] Finalize initial working logic --- internal/command/scale/machines.go | 27 +----- internal/machine/update.go | 131 ++++++++++++----------------- 2 files changed, 54 insertions(+), 104 deletions(-) diff --git a/internal/command/scale/machines.go b/internal/command/scale/machines.go index 3b98886540..6fb52db33d 100644 --- a/internal/command/scale/machines.go +++ b/internal/command/scale/machines.go @@ -3,8 +3,6 @@ package scale import ( "context" "fmt" - "os" - "github.com/samber/lo" fly "github.com/superfly/fly-go" "github.com/superfly/fly-go/flaps" @@ -20,8 +18,6 @@ func v2ScaleVM(ctx context.Context, appName, group, sizeName string, memoryMB in if err != nil { return nil, err } - fmt.Println("Size Name") - fmt.Println(sizeName) ctx = flapsutil.NewContextWithClient(ctx, flapsClient) // Quickly validate sizeName before any network call @@ -55,9 +51,6 @@ func v2ScaleVM(ctx context.Context, appName, group, sizeName string, memoryMB in } for _, machine := range machines { - - fmt.Println(machine) - if sizeName != "" { machine.Config.Guest.SetSize(sizeName) } @@ -71,26 +64,12 @@ func v2ScaleVM(ctx context.Context, appName, group, sizeName string, memoryMB in Config: machine.Config, } - input.Config.Guest.CPUs = 2 - fmt.Println(input.Config.Guest.CPUs) - os.Exit(1) - - //fmt.Println("testing retry...") if err := mach.Update(ctx, machine, input); err != nil { - _, fix_err := err.(mach.InvalidConfigErr).AttemptFix() - fmt.Println(fix_err) + fix_err := err.(mach.InvalidConfigErr).AttemptFix( ctx, machine, input ) if fix_err!=nil{ - fmt.Println("unable to succeed!") - }else{ - fmt.Println("retrying scale memory...") - // Retry the updatre now - if second_err := mach.Update(ctx, machine, input); second_err != nil { - return nil, second_err - } + return nil, err } - return nil, err } - } // Return fly.VMSize to remain compatible with v1 scale app signature @@ -105,8 +84,6 @@ func v2ScaleVM(ctx context.Context, appName, group, sizeName string, memoryMB in func listMachinesWithGroup(ctx context.Context, group string) ([]*fly.Machine, error) { machines, err := mach.ListActive(ctx) - - fmt.Println( machines ) if err != nil { return nil, err } diff --git a/internal/machine/update.go b/internal/machine/update.go index 64ae375ca4..477d573e37 100644 --- a/internal/machine/update.go +++ b/internal/machine/update.go @@ -6,8 +6,7 @@ import ( "slices" "time" "github.com/superfly/flyctl/internal/prompt" - "os/exec" - "os" + fly "github.com/superfly/fly-go" "github.com/superfly/flyctl/internal/flapsutil" @@ -33,7 +32,6 @@ func Update(ctx context.Context, m *fly.Machine, input *fly.LaunchMachineInput) if input != nil && input.Config != nil && input.Config.Guest != nil { var invalidConfigErr InvalidConfigErr invalidConfigErr.guest = input.Config.Guest - invalidConfigErr.ctx = ctx // Check that there's a valid number of CPUs validNumCpus, ok := cpusPerKind[input.Config.Guest.CPUKind] @@ -130,7 +128,6 @@ const ( type InvalidConfigErr struct { Reason invalidConfigReason guest *fly.MachineGuest - ctx context.Context } func (e InvalidConfigErr) Description() string { @@ -205,97 +202,73 @@ func (e InvalidConfigErr) Error() string { } -func (e InvalidConfigErr) AttemptFix() (string,error) { + + +func (e InvalidConfigErr) AttemptFix( ctx context.Context, m *fly.Machine, input *fly.LaunchMachineInput ) (error) { unsuccessfull := "Unsuccessful at fixing the error attempt!" switch e.Reason { case memoryTooHigh: + // Get correct CPU count - required_cpu_count,err := getRequiredCPUForMemoryTooHighError(e) + required_cpu_count, err := getRequiredCPUForMemoryIncrease(e) if err==nil{ combo := string(fmt.Sprintf("%s-cpu-%dx",e.guest.CPUKind,required_cpu_count)) - // Notify of issue - //fmt.Println( "\nWarning! "+e.Description()+"! To scale your memory to "+string(fmt.Sprintf( "%d",e.guest.MemoryMB))+"MiB, - //you must first increase your CPU cores to "+string(fmt.Sprintf( "%d",required_cpu_count)) +", which can be accomodated by a \""+combo+"\" VM size.\n") - // Prompt - //If you would like to proceed with scaling your memory to %dMiB, your Machine's CPU count must be increased to %d CPUs.",e.Description(),e.guest.MemoryMB,required_cpu_count - prompt_str := fmt.Sprintf("Warning! %s! A memory of %dMiB requires %d CPU cores, "+ - "which can be accomodated by a \"%s\" VM size.\n Would you like to scale your VM size to %s by running the command `fly scale vm %s`?"+ - "\n Agreeing will update your VM to \"%s\" size first, then proceed with scaling the memory to the requested %dMiB", - e.Description(), e.guest.MemoryMB, required_cpu_count, combo, combo, combo,combo, e.guest.MemoryMB) - //combo, combo, combo, e.guest.MemoryMB ) - yesScaleCPUFirst, no := prompt.Confirm( e.ctx, prompt_str) - - // Scale CPU - fmt.Println(yesScaleCPUFirst) - fmt.Println(no) + fmt.Println("") + prompt_str := fmt.Sprintf("WARNING! \"Machine %s\": %s!\n > A memory of %dMiB requires %d CPU cores, "+ + "which can be accomodated by a \"%s\" VM size.\n > Would you like to scale your \"Machine %s\"'s VM size to \" %s\"?"+ + "\n ? Agreeing will update your \"Machine %s\"'s VM size to \"%s\" size, and proceed with scaling its memory to the requested %dMiB", + m.ID, + e.Description(), + e.guest.MemoryMB, + required_cpu_count, + combo, + m.ID, + combo, + m.ID, + combo, + e.guest.MemoryMB) + + yesScaleCPUFirst, _ := prompt.Confirm(ctx, prompt_str) if yesScaleCPUFirst{ - fmt.Println("Running fly scale vm command...") - flyctl, err := exec.LookPath("fly") - if err== nil{ - - // attempt to install bundle before proceeding - args := []string{"scale", "vm", fmt.Sprintf("%s-cpu-%dx",e.guest.CPUKind,required_cpu_count)} - fmt.Println(args) - cmd := exec.Command(flyctl, args...) - cmd.Stdin = os.Stdin - cmd.Stdout = os.Stdout - cmd.Stderr = os.Stderr - cmd.Run() - - fmt.Println("success!") - - return "success!",nil + // Update CPU count! + input.Config.Guest.CPUs = required_cpu_count + err:=Update( ctx, m, input) + if err!=nil{ + return err + }else{ + // Return fly.VMSize to remain compatible with v1 scale app signature + return nil } } - }else{ - fmt.Println("returning error...") - return err.Error(), err + return err } } - fmt.Println("returning last error..") - return unsuccessfull, fmt.Errorf( unsuccessfull ) + return fmt.Errorf( unsuccessfull ) } -//func getRequiredVmScaleCommandForMemoryTooHighError(){} -func getRequiredCPUForMemoryTooHighError( e InvalidConfigErr ) (int, error){ - var error_check = "" - var required_cpu_count = e.guest.CPUs - for error_check == ""{ - // Increment cpu count to see if that would satisfy the requested memory - required_cpu_count = required_cpu_count*2 - //fmt.Println("Checking if %d cpu count works!",required_cpu_count) - - // Validate new cpu count is valid - validNumCpus, ok := cpusPerKind[e.guest.CPUKind] - if !ok { - fmt.Println("Not valid cpu kind!") - error_check = string(invalidCpuKind) - } else if !slices.Contains(validNumCpus, required_cpu_count) { - fmt.Println("Not valid cpu count for kind!") - error_check = string(invalidNumCPUs) - }else{ - - // Validate that the new cpu count's max memory can accommodate the requested memory - var maxMemory int - - // Get the max memory the new cpu count can hold - if e.guest.CPUKind == "shared" { - maxMemory = required_cpu_count * fly.MAX_MEMORY_MB_PER_SHARED_CPU - } else if e.guest.CPUKind == "performance" { - maxMemory = required_cpu_count * fly.MAX_MEMORY_MB_PER_CPU - } +func getRequiredCPUForMemoryIncrease( e InvalidConfigErr ) (int, error) { + fmt.Println( fly.MAX_MEMORY_MB_PER_SHARED_CPU ) + + var required_cpu_count int + // Get cpu count whose max_memory can accommodate the requested memory increase + if e.guest.CPUKind == "shared" { + required_cpu_count = e.guest.MemoryMB / fly.MAX_MEMORY_MB_PER_SHARED_CPU + }else if e.guest.CPUKind == "performance"{ // performance + required_cpu_count = e.guest.MemoryMB / fly.MAX_MEMORY_MB_PER_CPU + } - // See if its max memory can hold the requested memory - if e.guest.MemoryMB <= maxMemory{ - return required_cpu_count, nil - } - } + // Check if cpu count is valid for the cpu kind + validNumCpus, ok := cpusPerKind[e.guest.CPUKind] + if !ok { + return 0, fmt.Errorf( string( invalidCpuKind ) ) + } else if !slices.Contains(validNumCpus, required_cpu_count) { + return 0, fmt.Errorf( string( invalidNumCPUs ) ) } - // Sorry, can't get the cpu count - general_error := "Unable to retrieve the required CPU count to accommodate requested memory!" - return required_cpu_count, fmt.Errorf( general_error+"\n\n"+error_check ) -} \ No newline at end of file + + return required_cpu_count, nil +} + \ No newline at end of file