Mohammed Naser 5dcc0bf0b2 Update to Go 1.21
This patch updates the whole code to use the latest Go version 1.21
and also updates the dependencies to the latest versions.

Change-Id: Ie0b346e4622c56825aeda176f63ae4e55f06a2ce
2024-03-26 15:10:40 +00:00

112 lines
2.9 KiB
Go

package pod
import (
"context"
"fmt"
"os"
v1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
entry "opendev.org/airship/kubernetes-entrypoint/entrypoint"
"opendev.org/airship/kubernetes-entrypoint/logger"
"opendev.org/airship/kubernetes-entrypoint/util/env"
)
const (
PodNameEnvVar = "POD_NAME"
PodNameNotSetErrorFormat = "env POD_NAME not set, pod dependency in namespace %s will be ignored"
)
type Pod struct {
namespace string
labels map[string]string
requireSameNode bool
podName string
}
func init() {
podEnv := fmt.Sprintf("%sPOD%s", entry.DependencyPrefix, entry.JsonSuffix)
podDeps := env.SplitPodEnvToDeps(podEnv)
for _, dep := range podDeps {
pod, err := NewPod(dep.Labels, dep.Namespace, dep.RequireSameNode)
if err != nil {
logger.Error.Printf("Cannot initialize pod: %v", err)
continue
}
entry.Register(pod)
}
}
func NewPod(labels map[string]string, namespace string, requireSameNode bool) (*Pod, error) {
if os.Getenv(PodNameEnvVar) == "" {
return nil, fmt.Errorf(PodNameNotSetErrorFormat, namespace)
}
return &Pod{
labels: labels,
namespace: namespace,
requireSameNode: requireSameNode,
podName: os.Getenv(PodNameEnvVar),
}, nil
}
func (p Pod) IsResolved(ctx context.Context, entrypoint entry.EntrypointInterface) (bool, error) {
myPod, err := entrypoint.Client().Pods(env.GetBaseNamespace()).Get(ctx, p.podName, metav1.GetOptions{})
if err != nil {
return false, fmt.Errorf("getting POD: %v failed : %v", p.podName, err)
}
myHost := myPod.Status.HostIP
labelSelector := &metav1.LabelSelector{MatchLabels: p.labels}
label := metav1.FormatLabelSelector(labelSelector)
opts := metav1.ListOptions{LabelSelector: label}
matchingPodList, err := entrypoint.Client().Pods(p.namespace).List(ctx, opts)
if err != nil {
return false, err
}
matchingPods := matchingPodList.Items
if len(matchingPods) == 0 {
return false, fmt.Errorf("found no pods matching labels: %v", p.labels)
}
podCount := 0
for _, pod := range matchingPods {
podCount++
pod := pod // pinning
if p.requireSameNode && !isPodOnHost(&pod, myHost) {
continue
}
if isPodReady(pod) {
return true, nil
}
}
onHostClause := ""
if p.requireSameNode {
onHostClause = " on host"
}
if podCount == 0 {
return false, fmt.Errorf("found no pods%v matching labels: %v", onHostClause, p.labels)
} else {
return false, fmt.Errorf("found %v pods%v, but none ready, matching labels: %v", podCount, onHostClause, p.labels)
}
}
func isPodOnHost(pod *v1.Pod, hostIP string) bool {
return pod.Status.HostIP == hostIP
}
func isPodReady(pod v1.Pod) bool {
for _, condition := range pod.Status.Conditions {
if condition.Type == v1.PodReady && condition.Status == "True" {
return true
}
}
return false
}
func (p Pod) String() string {
return fmt.Sprintf("Pod on same host with labels %v in namespace %s", p.labels, p.namespace)
}