Skip to content

Commit

Permalink
Finalize initial working logic
Browse files Browse the repository at this point in the history
  • Loading branch information
Kathryn Anne S Tan committed Aug 22, 2024
1 parent ac5a884 commit d5b3146
Show file tree
Hide file tree
Showing 2 changed files with 54 additions and 104 deletions.
27 changes: 2 additions & 25 deletions internal/command/scale/machines.go
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand All @@ -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
Expand Down Expand Up @@ -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)
}
Expand All @@ -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
Expand All @@ -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
}
Expand Down
131 changes: 52 additions & 79 deletions internal/machine/update.go
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand All @@ -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]
Expand Down Expand Up @@ -130,7 +128,6 @@ const (
type InvalidConfigErr struct {
Reason invalidConfigReason
guest *fly.MachineGuest
ctx context.Context
}

func (e InvalidConfigErr) Description() string {
Expand Down Expand Up @@ -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))

Check failure on line 215 in internal/machine/update.go

View workflow job for this annotation

GitHub Actions / lint

unnecessary conversion (unconvert)
// 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 )
}

return required_cpu_count, nil
}

0 comments on commit d5b3146

Please sign in to comment.