2022-08-10 16:55:20 +00:00
|
|
|
package role
|
|
|
|
|
|
|
|
import (
|
|
|
|
"math/rand"
|
|
|
|
"time"
|
|
|
|
|
2022-09-16 15:42:45 +00:00
|
|
|
"github.com/kairos-io/kairos/pkg/config"
|
2022-08-10 16:55:20 +00:00
|
|
|
|
2022-09-16 15:42:45 +00:00
|
|
|
providerConfig "github.com/kairos-io/provider-kairos/internal/provider/config"
|
2022-08-10 16:55:20 +00:00
|
|
|
service "github.com/mudler/edgevpn/api/client/service"
|
|
|
|
)
|
|
|
|
|
2022-12-01 17:14:05 +00:00
|
|
|
// func assignIPs(cidr string, client *service.Client, nodes []string, pconfig *providerConfig.Config) (error, bool) {
|
|
|
|
// address, _, err := net.ParseCIDR(cidr)
|
|
|
|
// if err != nil {
|
|
|
|
// return err, false
|
|
|
|
// }
|
|
|
|
|
|
|
|
// currentIPS := []string{}
|
|
|
|
// toAssign := []string{}
|
|
|
|
// for _, a := range nodes {
|
|
|
|
// ip, _ := client.Get("ip", a)
|
|
|
|
// if ip != "" {
|
|
|
|
// currentIPS = append(currentIPS, ip)
|
|
|
|
// } else {
|
|
|
|
// toAssign = append(toAssign, a)
|
|
|
|
// }
|
|
|
|
// }
|
|
|
|
|
|
|
|
// if len(toAssign) == 0 {
|
|
|
|
// return nil, false
|
|
|
|
// }
|
|
|
|
|
|
|
|
// ip := utils.NextIP(address.String(), currentIPS)
|
|
|
|
// if err := client.Set("ip", toAssign[0], ip); err != nil {
|
|
|
|
// return err, false
|
|
|
|
// }
|
|
|
|
|
|
|
|
// return nil, len(toAssign) != 0
|
|
|
|
// }
|
|
|
|
|
2022-08-10 16:55:20 +00:00
|
|
|
// scheduleRoles assigns roles to nodes. Meant to be called only by leaders
|
|
|
|
// TODO: HA-Auto.
|
|
|
|
func scheduleRoles(nodes []string, c *service.RoleConfig, cc *config.Config, pconfig *providerConfig.Config) error {
|
|
|
|
rand.Seed(time.Now().Unix())
|
|
|
|
|
|
|
|
// Assign roles to nodes
|
2022-12-01 17:14:05 +00:00
|
|
|
unassignedNodes, currentRoles := getRoles(c.Client, nodes)
|
2022-08-10 16:55:20 +00:00
|
|
|
c.Logger.Infof("I'm the leader. My UUID is: %s.\n Current assigned roles: %+v", c.UUID, currentRoles)
|
2022-12-01 17:14:05 +00:00
|
|
|
|
|
|
|
existsMaster := false
|
|
|
|
|
|
|
|
masterRole := "master"
|
|
|
|
workerRole := "worker"
|
|
|
|
|
|
|
|
if pconfig.Kairos.Hybrid {
|
|
|
|
// err, reschedule := assignIPs(pconfig.KubeVIP.CIDR, c.Client, nodes, pconfig)
|
|
|
|
// if reschedule {
|
|
|
|
// return fmt.Errorf("asked to reschedule")
|
|
|
|
// }
|
|
|
|
// if err != nil {
|
|
|
|
// return err
|
|
|
|
// }
|
|
|
|
// ip, _ := c.Client.Get("ip", c.UUID)
|
|
|
|
// c.Logger.Infof("KubeVIP IP: %+v", ip)
|
|
|
|
c.Logger.Info("hybrid p2p enabled")
|
|
|
|
// masterRole = "kubevip/master"
|
|
|
|
// workerRole = "kubevip/worker"
|
|
|
|
}
|
|
|
|
|
|
|
|
for _, r := range currentRoles {
|
|
|
|
if r == masterRole {
|
|
|
|
existsMaster = true
|
|
|
|
}
|
|
|
|
}
|
2022-08-10 16:55:20 +00:00
|
|
|
c.Logger.Infof("Master already present: %t", existsMaster)
|
|
|
|
c.Logger.Infof("Unassigned nodes: %+v", unassignedNodes)
|
2022-12-01 17:14:05 +00:00
|
|
|
selectedMaster := ""
|
2022-08-10 16:55:20 +00:00
|
|
|
if !existsMaster && len(unassignedNodes) > 0 {
|
|
|
|
var selected string
|
|
|
|
toSelect := unassignedNodes
|
|
|
|
|
|
|
|
// Avoid to schedule to ourselves if we have a static role
|
2022-09-19 09:59:28 +00:00
|
|
|
if pconfig.Kairos.Role != "" {
|
2022-08-10 16:55:20 +00:00
|
|
|
toSelect = []string{}
|
|
|
|
for _, u := range unassignedNodes {
|
|
|
|
if u != c.UUID {
|
|
|
|
toSelect = append(toSelect, u)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// select one node without roles to become master
|
|
|
|
if len(toSelect) == 1 {
|
|
|
|
selected = toSelect[0]
|
|
|
|
} else {
|
|
|
|
selected = toSelect[rand.Intn(len(toSelect)-1)]
|
|
|
|
}
|
|
|
|
|
2022-12-01 17:14:05 +00:00
|
|
|
if err := c.Client.Set("role", selected, masterRole); err != nil {
|
2022-08-10 16:55:20 +00:00
|
|
|
return err
|
|
|
|
}
|
|
|
|
c.Logger.Info("-> Set master to", selected)
|
2022-12-01 17:14:05 +00:00
|
|
|
currentRoles[selected] = masterRole
|
|
|
|
selectedMaster = selected
|
2022-08-10 16:55:20 +00:00
|
|
|
// Return here, so next time we get called
|
|
|
|
// makes sure master is set.
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
|
|
|
// cycle all empty roles and assign worker roles
|
|
|
|
for _, uuid := range unassignedNodes {
|
2022-12-01 17:14:05 +00:00
|
|
|
if selectedMaster == uuid {
|
|
|
|
continue
|
|
|
|
}
|
|
|
|
if err := c.Client.Set("role", uuid, workerRole); err != nil {
|
2022-08-10 16:55:20 +00:00
|
|
|
c.Logger.Error(err)
|
|
|
|
return err
|
|
|
|
}
|
2022-12-01 17:14:05 +00:00
|
|
|
c.Logger.Infof("-> Set %s to %s", workerRole, uuid)
|
2022-08-10 16:55:20 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
c.Logger.Info("Done scheduling")
|
|
|
|
|
|
|
|
return nil
|
|
|
|
}
|