Skip to content

Commit

Permalink
Really sort instances by launch date
Browse files Browse the repository at this point in the history
Sort instances by launch date starting from newest and select
instance at the place of use instead of using function
that returns the newest instance and the rest.
  • Loading branch information
ingvagabund committed Nov 27, 2018
1 parent 4ba52c7 commit a65d554
Show file tree
Hide file tree
Showing 3 changed files with 40 additions and 51 deletions.
11 changes: 6 additions & 5 deletions pkg/cloud/aws/actuators/machine/actuator.go
Original file line number Diff line number Diff line change
Expand Up @@ -301,20 +301,21 @@ func (a *Actuator) Update(cluster *clusterv1.Cluster, machine *clusterv1.Machine
glog.Errorf("attempted to update machine but no instances found")
return fmt.Errorf("attempted to update machine but no instances found")
}
newestInstance, terminateInstances := SortInstances(instances)

// In very unusual circumstances, there could be more than one machine running matching this
// machine name and cluster ID. In this scenario we will keep the newest, and delete all others.
glog.Info("instance found")

// In very unusual circumstances, there could be more than one machine running matching this
// machine name and cluster ID. In this scenario we will keep the newest, and delete all others.
sortInstances(instances)
if len(instances) > 1 {
err = TerminateInstances(client, terminateInstances)
err = TerminateInstances(client, instances[1:])
if err != nil {
return err
}

}

newestInstance := instances[0]

err = a.UpdateLoadBalancers(client, machineProviderConfig, newestInstance)
if err != nil {
glog.Errorf("error updating load balancers: %v", err)
Expand Down
32 changes: 32 additions & 0 deletions pkg/cloud/aws/actuators/machine/instances.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package machine
import (
"encoding/base64"
"fmt"
"sort"
"time"

"github.com/golang/glog"
Expand Down Expand Up @@ -262,3 +263,34 @@ func launchInstance(machine *clusterv1.Machine, machineProviderConfig *providerc

return runResult.Instances[0], nil
}

type instanceList []*ec2.Instance

func (il instanceList) Len() int {
return len(il)
}

func (il instanceList) Swap(i, j int) {
il[i], il[j] = il[j], il[i]
}

func (il instanceList) Less(i, j int) bool {
if il[i].LaunchTime == nil && il[j].LaunchTime == nil {
return false
}
if il[i].LaunchTime != nil && il[j].LaunchTime == nil {
return false
}
if il[i].LaunchTime == nil && il[j].LaunchTime != nil {
return true
}
return (*il[i].LaunchTime).After(*il[j].LaunchTime)
}

// sortInstances will sort a list of instance based on an instace launch time
// from the newest to the oldest.
// This function should only be called with running instances, not those which are stopped or
// terminated.
func sortInstances(instances []*ec2.Instance) {
sort.Sort(instanceList(instances))
}
48 changes: 2 additions & 46 deletions pkg/cloud/aws/actuators/machine/utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,50 +35,6 @@ import (
"github.com/ghodss/yaml"
)

// SortInstances will examine the given slice of instances and return the current active instance for
// the machine, as well as a slice of all other instances which the caller may want to terminate. The
// active instance is calculated as the most recently launched instance.
// This function should only be called with running instances, not those which are stopped or
// terminated.
func SortInstances(instances []*ec2.Instance) (*ec2.Instance, []*ec2.Instance) {
if len(instances) == 0 {
return nil, []*ec2.Instance{}
}
var newestInstance *ec2.Instance
inactiveInstances := make([]*ec2.Instance, 0, len(instances)-1)
for _, i := range instances {
if newestInstance == nil {
newestInstance = i
continue
}
tempInstance := chooseNewest(newestInstance, i)
if *tempInstance.InstanceId != *newestInstance.InstanceId {
inactiveInstances = append(inactiveInstances, newestInstance)
} else {
inactiveInstances = append(inactiveInstances, i)
}
newestInstance = tempInstance
}
return newestInstance, inactiveInstances
}

func chooseNewest(instance1, instance2 *ec2.Instance) *ec2.Instance {
if instance1.LaunchTime == nil && instance2.LaunchTime == nil {
// No idea what to do here, should not be possible, just return the first.
return instance1
}
if instance1.LaunchTime != nil && instance2.LaunchTime == nil {
return instance1
}
if instance1.LaunchTime == nil && instance2.LaunchTime != nil {
return instance2
}
if (*instance1.LaunchTime).After(*instance2.LaunchTime) {
return instance1
}
return instance2
}

// GetRunningInstance returns the AWS instance for a given machine. If multiple instances match our machine,
// the most recently launched will be returned. If no instance exists, an error will be returned.
func GetRunningInstance(machine *clusterv1.Machine, client awsclient.Client) (*ec2.Instance, error) {
Expand All @@ -90,8 +46,8 @@ func GetRunningInstance(machine *clusterv1.Machine, client awsclient.Client) (*e
return nil, fmt.Errorf("no instance found for machine: %s", machine.Name)
}

instance, _ := SortInstances(instances)
return instance, nil
sortInstances(instances)
return instances[0], nil
}

// GetRunningInstances returns all running instances that have a tag matching our machine name,
Expand Down

0 comments on commit a65d554

Please sign in to comment.