213 lines
5.3 KiB
Go
213 lines
5.3 KiB
Go
package common
|
|
|
|
import (
|
|
"fmt"
|
|
v1 "github.com/alibaba/polardbx-operator/api/v1"
|
|
"github.com/alibaba/polardbx-operator/api/v1/systemtask"
|
|
"github.com/alibaba/polardbx-operator/pkg/k8s/cache"
|
|
"github.com/alibaba/polardbx-operator/pkg/k8s/control"
|
|
"github.com/alibaba/polardbx-operator/pkg/operator/v1/config"
|
|
polardbxmeta "github.com/alibaba/polardbx-operator/pkg/operator/v1/polardbx/meta"
|
|
xstoremeta "github.com/alibaba/polardbx-operator/pkg/operator/v1/xstore/meta"
|
|
corev1 "k8s.io/api/core/v1"
|
|
"k8s.io/apimachinery/pkg/types"
|
|
ctrl "sigs.k8s.io/controller-runtime"
|
|
"sigs.k8s.io/controller-runtime/pkg/client"
|
|
)
|
|
|
|
type Context struct {
|
|
*control.BaseReconcileContext
|
|
|
|
// Caches
|
|
taskKey types.NamespacedName
|
|
taskChanged bool
|
|
systemTask *v1.SystemTask
|
|
objectCache cache.ObjectLoadingCache
|
|
|
|
// Hint cache
|
|
controllerHints []string
|
|
// Config
|
|
configLoader func() config.Config
|
|
|
|
//balance resource
|
|
brTargetPod *corev1.Pod
|
|
brTargetNodeName string
|
|
}
|
|
|
|
func (ctx *Context) ConfigLoader() func() config.Config {
|
|
return ctx.configLoader
|
|
}
|
|
|
|
func (ctx *Context) BrTargetPod() *corev1.Pod {
|
|
return ctx.brTargetPod
|
|
}
|
|
|
|
func (ctx *Context) SetBrTargetPod(brTargetPod *corev1.Pod) {
|
|
ctx.brTargetPod = brTargetPod
|
|
}
|
|
|
|
func (ctx *Context) BrTargetNodeName() string {
|
|
return ctx.brTargetNodeName
|
|
}
|
|
|
|
func (ctx *Context) SetBrTargetNodeName(brTargetNodeName string) {
|
|
ctx.brTargetNodeName = brTargetNodeName
|
|
}
|
|
|
|
func NewContext(base *control.BaseReconcileContext, configLoader func() config.Config) *Context {
|
|
return &Context{
|
|
BaseReconcileContext: base,
|
|
objectCache: cache.NewObjectCache(base.Client(), base.Scheme()),
|
|
configLoader: configLoader,
|
|
}
|
|
}
|
|
|
|
func (ctx *Context) SetKey(taskKey types.NamespacedName) {
|
|
ctx.taskKey = taskKey
|
|
}
|
|
|
|
func (ctx *Context) MustGetSystemTask() *v1.SystemTask {
|
|
if ctx.systemTask == nil {
|
|
var systemTask v1.SystemTask
|
|
err := ctx.Client().Get(ctx.Context(), ctx.taskKey, &systemTask)
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
if systemTask.Status.StBalanceResourceStatus == nil {
|
|
systemTask.Status.StBalanceResourceStatus = &systemtask.StBalanceResourceStatus{}
|
|
}
|
|
ctx.systemTask = &systemTask
|
|
}
|
|
return ctx.systemTask
|
|
}
|
|
|
|
func (ctx *Context) IsSystemTaskChanged() bool {
|
|
return ctx.taskChanged
|
|
}
|
|
|
|
func (ctx *Context) MarkSystemTaskChanged() {
|
|
ctx.taskChanged = true
|
|
return
|
|
}
|
|
|
|
func (ctx *Context) UpdateSystemTask() error {
|
|
err := ctx.Client().Update(ctx.Context(), ctx.systemTask)
|
|
return err
|
|
}
|
|
|
|
func (ctx *Context) GetAllXStores() ([]v1.XStore, error) {
|
|
var xstoreList v1.XStoreList
|
|
err := ctx.Client().List(ctx.Context(), &xstoreList, client.InNamespace(ctx.Namespace()))
|
|
return xstoreList.Items, err
|
|
}
|
|
|
|
func (ctx *Context) GetXStoreByName(name string) (*v1.XStore, error) {
|
|
var xstore v1.XStore
|
|
objKey := types.NamespacedName{
|
|
Name: name,
|
|
Namespace: ctx.Namespace(),
|
|
}
|
|
err := ctx.Client().Get(ctx.Context(), objKey, &xstore)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
return &xstore, nil
|
|
}
|
|
|
|
func (ctx *Context) GetAllXStorePods() ([]corev1.Pod, error) {
|
|
pods := make([]corev1.Pod, 0)
|
|
for _, role := range []string{polardbxmeta.RoleDN} {
|
|
var podList corev1.PodList
|
|
err := ctx.Client().List(ctx.Context(), &podList, client.InNamespace(ctx.Namespace()), client.MatchingLabels(map[string]string{
|
|
polardbxmeta.LabelRole: role,
|
|
}))
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
pods = append(pods, podList.Items...)
|
|
}
|
|
return pods, nil
|
|
}
|
|
|
|
func (ctx *Context) GetNodeXStorePodMap(separateRole bool, logger bool) (map[string][]corev1.Pod, error) {
|
|
pods, err := ctx.GetAllXStorePods()
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
newPods := make([]corev1.Pod, 0)
|
|
if separateRole {
|
|
for _, pod := range pods {
|
|
if logger {
|
|
if xstoremeta.IsPodRoleVoter(&pod) {
|
|
newPods = append(newPods, pod)
|
|
}
|
|
} else {
|
|
if !xstoremeta.IsPodRoleVoter(&pod) {
|
|
newPods = append(newPods, pod)
|
|
}
|
|
}
|
|
}
|
|
} else {
|
|
newPods = pods
|
|
}
|
|
|
|
result := make(map[string][]corev1.Pod)
|
|
for _, pod := range newPods {
|
|
nodeName := pod.Spec.NodeName
|
|
if nodeName == "" {
|
|
return nil, fmt.Errorf("node name not found, pod name: %s", pod.Name)
|
|
}
|
|
nodePods, ok := result[nodeName]
|
|
if !ok {
|
|
nodePods = make([]corev1.Pod, 0)
|
|
}
|
|
result[nodeName] = append(nodePods, pod)
|
|
}
|
|
nodes, err := ctx.GetAllNodes()
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
for _, node := range nodes {
|
|
_, ok := result[node.Name]
|
|
if !ok {
|
|
result[node.Name] = make([]corev1.Pod, 0)
|
|
}
|
|
}
|
|
return result, nil
|
|
}
|
|
|
|
func (ctx *Context) GetAllNodes() ([]corev1.Node, error) {
|
|
systemtask := ctx.MustGetSystemTask()
|
|
var nodeList corev1.NodeList
|
|
err := ctx.Client().List(ctx.Context(), &nodeList)
|
|
result := make([]corev1.Node, 0)
|
|
if len(systemtask.Spec.Nodes) > 0 {
|
|
nodeMap := make(map[string]bool, len(systemtask.Spec.Nodes))
|
|
for _, nodeName := range systemtask.Spec.Nodes {
|
|
nodeMap[nodeName] = true
|
|
}
|
|
for _, item := range nodeList.Items {
|
|
if _, ok := nodeMap[item.Name]; ok {
|
|
result = append(result, item)
|
|
}
|
|
}
|
|
}
|
|
|
|
return result, err
|
|
}
|
|
|
|
func (rc *Context) SetControllerRef(obj client.Object) error {
|
|
if obj == nil {
|
|
return nil
|
|
}
|
|
systemTask := rc.MustGetSystemTask()
|
|
return ctrl.SetControllerReference(systemTask, obj, rc.Scheme())
|
|
}
|
|
|
|
func (rc *Context) SetControllerRefAndCreate(obj client.Object) error {
|
|
if err := rc.SetControllerRef(obj); err != nil {
|
|
return err
|
|
}
|
|
return rc.Client().Create(rc.Context(), obj)
|
|
}
|