Rename internal to pkg to make inner pkgs importable

Other small fixes and improvements included.

Change-Id: I878c4dce66e62e9128cbec658fc98e1ef71e8047
Signed-off-by: Ruslan Aliev <raliev@mirantis.com>
This commit is contained in:
Ruslan Aliev 2024-02-06 19:27:08 -06:00
parent ae24d1f21b
commit d557f99c8f
8 changed files with 41 additions and 26 deletions

View File

@ -35,7 +35,7 @@ import (
metricsserver "sigs.k8s.io/controller-runtime/pkg/metrics/server" metricsserver "sigs.k8s.io/controller-runtime/pkg/metrics/server"
armadav1 "opendev.org/airship/armada-operator/api/v1" armadav1 "opendev.org/airship/armada-operator/api/v1"
"opendev.org/airship/armada-operator/internal/controller" "opendev.org/airship/armada-operator/pkg/controller"
//+kubebuilder:scaffold:imports //+kubebuilder:scaffold:imports
) )

View File

@ -15,7 +15,7 @@ RUN go mod download
# Copy the go source # Copy the go source
COPY cmd/main.go cmd/main.go COPY cmd/main.go cmd/main.go
COPY api/ api/ COPY api/ api/
COPY internal/ internal/ COPY pkg/ pkg/
# Build # Build
# the GOARCH has not a default value to allow the binary be built according to the host where the command # the GOARCH has not a default value to allow the binary be built according to the host where the command

View File

@ -47,8 +47,9 @@ import (
"sigs.k8s.io/controller-runtime/pkg/predicate" "sigs.k8s.io/controller-runtime/pkg/predicate"
armadav1 "opendev.org/airship/armada-operator/api/v1" armadav1 "opendev.org/airship/armada-operator/api/v1"
"opendev.org/airship/armada-operator/internal/kube" "opendev.org/airship/armada-operator/pkg/kube"
"opendev.org/airship/armada-operator/internal/runner" "opendev.org/airship/armada-operator/pkg/runner"
"opendev.org/airship/armada-operator/pkg/waitutil"
) )
// ArmadaChartReconciler reconciles a ArmadaChart object // ArmadaChartReconciler reconciles a ArmadaChart object
@ -276,8 +277,8 @@ func (r *ArmadaChartReconciler) waitRelease(ctx context.Context, restCfg *rest.C
} }
} }
opts := kube.WaitOptions{ opts := waitutil.WaitOptions{
RestConfig: *restCfg, RestConfig: restCfg,
Namespace: hr.Spec.Namespace, Namespace: hr.Spec.Namespace,
LabelSelector: labelSelector, LabelSelector: labelSelector,
ResourceType: fmt.Sprintf("%ss", res.Type), ResourceType: fmt.Sprintf("%ss", res.Type),
@ -408,7 +409,7 @@ func isUpdateRequired(ctx context.Context, release *release.Release, chrt *chart
// return true // return true
case !cmp.Equal(release.Config, vals.AsMap(), cmpopts.EquateEmpty()): case !cmp.Equal(release.Config, vals.AsMap(), cmpopts.EquateEmpty()):
log.Info("There are CHART VALUES diffs") log.Info("There are chart values diffs found")
log.Info(cmp.Diff(release.Config, vals.AsMap(), cmpopts.EquateEmpty())) log.Info(cmp.Diff(release.Config, vals.AsMap(), cmpopts.EquateEmpty()))
return true return true
} }

View File

@ -14,13 +14,12 @@ See the License for the specific language governing permissions and
limitations under the License. limitations under the License.
*/ */
package kube package waitutil
import ( import (
"context" "context"
"errors" "errors"
"fmt" "fmt"
"io"
"math" "math"
"strconv" "strconv"
"strings" "strings"
@ -38,6 +37,8 @@ import (
"k8s.io/client-go/rest" "k8s.io/client-go/rest"
"k8s.io/client-go/tools/cache" "k8s.io/client-go/tools/cache"
watchtools "k8s.io/client-go/tools/watch" watchtools "k8s.io/client-go/tools/watch"
armadav1 "opendev.org/airship/armada-operator/api/v1"
) )
type StatusType string type StatusType string
@ -61,12 +62,11 @@ const (
// WaitOptions phase run command // WaitOptions phase run command
type WaitOptions struct { type WaitOptions struct {
RestConfig rest.Config RestConfig *rest.Config
Namespace string Namespace string
LabelSelector string LabelSelector string
ResourceType string ResourceType string
Timeout time.Duration Timeout time.Duration
Out io.Writer
MinReady string MinReady string
Logger logr.Logger Logger logr.Logger
} }
@ -85,25 +85,25 @@ func getObjectStatus(obj interface{}, minReady *MinReady) Status {
return isDaemonSetReady(v, minReady) return isDaemonSetReady(v, minReady)
case *appsv1.StatefulSet: case *appsv1.StatefulSet:
return isStatefulSetReady(v, minReady) return isStatefulSetReady(v, minReady)
case *armadav1.ArmadaChart:
return isArmadaChartReady(v)
default: default:
return Status{Error, fmt.Sprintf("Unable to cast an object to any type %s\n", obj)} return Status{Error, fmt.Sprintf("Unable to cast an object to any type %s", obj)}
} }
} }
func allMatch(logger logr.Logger, store cache.Store, minReady *MinReady, obj runtime.Object) (bool, error) { func allMatch(logger logr.Logger, store cache.Store, minReady *MinReady, obj runtime.Object) (bool, error) {
logger.Info(fmt.Sprintf("verifying ready status for %d number of objects", len(store.List())))
for _, item := range store.List() { for _, item := range store.List() {
if obj != nil && item == obj { if obj != nil && item == obj {
logger.Info(fmt.Sprintf("Skipping the item as status is already computed"))
continue continue
} }
status := getObjectStatus(item, minReady) status := getObjectStatus(item, minReady)
logger.Info(fmt.Sprintf("object %T status computed: %s %s\n", item, status.StatusType, status.Msg)) logger.Info(fmt.Sprintf("object %T status computed: %s %s", item, status.StatusType, status.Msg))
if status.StatusType != Ready && status.StatusType != Skipped { if status.StatusType != Ready && status.StatusType != Skipped {
return false, nil return false, nil
} }
} }
logger.Info("all objects are ready\n") logger.Info("all objects are ready")
return true, nil return true, nil
} }
@ -125,6 +125,17 @@ func processEvent(logger logr.Logger, event watch.Event, minReady *MinReady) (St
return status.StatusType, nil return status.StatusType, nil
} }
func isArmadaChartReady(ac *armadav1.ArmadaChart) Status {
if ac.Status.ObservedGeneration == ac.Generation {
for _, cond := range ac.Status.Conditions {
if cond.Type == "Ready" && cond.Status == "True" {
return Status{Ready, fmt.Sprintf("armadachart %s ready", ac.GetName())}
}
}
}
return Status{Unready, fmt.Sprintf("Waiting for armadachart %s to be ready", ac.GetName())}
}
func isPodReady(pod *corev1.Pod) Status { func isPodReady(pod *corev1.Pod) Status {
if isTestPod(pod) || pod.Status.Phase == "Evicted" || hasOwner(&pod.ObjectMeta, "Job") { if isTestPod(pod) || pod.Status.Phase == "Evicted" || hasOwner(&pod.ObjectMeta, "Job") {
return Status{Skipped, return Status{Skipped,
@ -174,7 +185,7 @@ func isDeploymentReady(deployment *appsv1.Deployment, minReady *MinReady) Status
if gen <= observed { if gen <= observed {
for _, cond := range status.Conditions { for _, cond := range status.Conditions {
if cond.Type == "Progressing" && cond.Reason == "ProgressDeadlineExceeded" { if cond.Type == "Progressing" && cond.Reason == "ProgressDeadlineExceeded" {
return Status{Unready, fmt.Sprintf("Deployment %s exceeded its progress deadline\n", name)} return Status{Unready, fmt.Sprintf("Deployment %s exceeded its progress deadline", name)}
} }
} }
replicas := int32(0) replicas := int32(0)
@ -185,12 +196,12 @@ func isDeploymentReady(deployment *appsv1.Deployment, minReady *MinReady) Status
available := status.AvailableReplicas available := status.AvailableReplicas
if updated < replicas { if updated < replicas {
return Status{Unready, fmt.Sprintf("Waiting for deployment %s rollout to finish: %d"+ return Status{Unready, fmt.Sprintf("Waiting for deployment %s rollout to finish: %d"+
" out of %d new replicas have been updated...\n", name, updated, replicas)} " out of %d new replicas have been updated...", name, updated, replicas)}
} }
if replicas > updated { if replicas > updated {
pending := replicas - updated pending := replicas - updated
return Status{Unready, fmt.Sprintf("Waiting for deployment %s rollout to finish: %d old "+ return Status{Unready, fmt.Sprintf("Waiting for deployment %s rollout to finish: %d old "+
"replicas are pending termination...\n", name, pending)} "replicas are pending termination...", name, pending)}
} }
if minReady.Percent { if minReady.Percent {
@ -199,13 +210,13 @@ func isDeploymentReady(deployment *appsv1.Deployment, minReady *MinReady) Status
if available < minReady.int32 { if available < minReady.int32 {
return Status{Unready, fmt.Sprintf("Waiting for deployment %s rollout to finish: %d of %d "+ return Status{Unready, fmt.Sprintf("Waiting for deployment %s rollout to finish: %d of %d "+
"updated replicas are available, with min_ready=%d\n", name, available, updated, minReady.int32)} "updated replicas are available, with min_ready=%d", name, available, updated, minReady.int32)}
} }
return Status{Ready, fmt.Sprintf("deployment %s successfully rolled out\n", name)} return Status{Ready, fmt.Sprintf("deployment %s successfully rolled out", name)}
} }
return Status{Unready, fmt.Sprintf("Waiting for deployment %s spec update to be observed...\n", name)} return Status{Unready, fmt.Sprintf("Waiting for deployment %s spec update to be observed...", name)}
} }
func isDaemonSetReady(daemonSet *appsv1.DaemonSet, minReady *MinReady) Status { func isDaemonSetReady(daemonSet *appsv1.DaemonSet, minReady *MinReady) Status {
@ -302,6 +313,10 @@ func hasOwner(ometa *metav1.ObjectMeta, kind string) bool {
} }
func getClient(resource string, config *rest.Config) (rest.Interface, error) { func getClient(resource string, config *rest.Config) (rest.Interface, error) {
if resource == "armadacharts" {
return armadav1.NewForConfig(config)
}
cs, err := kubernetes.NewForConfig(config) cs, err := kubernetes.NewForConfig(config)
if err != nil { if err != nil {
return nil, err return nil, err
@ -337,9 +352,9 @@ func getMinReady(minReady string) (*MinReady, error) {
} }
func (c *WaitOptions) Wait(parent context.Context) error { func (c *WaitOptions) Wait(parent context.Context) error {
c.Logger.Info(fmt.Sprintf("armada-operator wait , namespace %s labels %s type %s timeout %s", c.Namespace, c.LabelSelector, c.ResourceType, c.Timeout)) c.Logger.Info(fmt.Sprintf("starting wait for resources: namespace %s labels %s type %s timeout %s", c.Namespace, c.LabelSelector, c.ResourceType, c.Timeout))
clientSet, err := getClient(c.ResourceType, &c.RestConfig) clientSet, err := getClient(c.ResourceType, c.RestConfig)
if err != nil { if err != nil {
return err return err
} }
@ -349,7 +364,6 @@ func (c *WaitOptions) Wait(parent context.Context) error {
lw := cache.NewFilteredListWatchFromClient(clientSet, c.ResourceType, c.Namespace, func(options *metav1.ListOptions) { lw := cache.NewFilteredListWatchFromClient(clientSet, c.ResourceType, c.Namespace, func(options *metav1.ListOptions) {
options.LabelSelector = c.LabelSelector options.LabelSelector = c.LabelSelector
c.Logger.Info(fmt.Sprintf("Label selector applied %s", options))
}) })
minReady, err := getMinReady(c.MinReady) minReady, err := getMinReady(c.MinReady)
@ -363,7 +377,7 @@ func (c *WaitOptions) Wait(parent context.Context) error {
cacheStore = store cacheStore = store
c.Logger.Info(fmt.Sprintf("number of objects to watch: %d", len(store.List()))) c.Logger.Info(fmt.Sprintf("number of objects to watch: %d", len(store.List())))
if len(store.List()) == 0 { if len(store.List()) == 0 {
c.Logger.Info(fmt.Sprintf("Skipping non-required wait, no resources found.\n")) c.Logger.Info(fmt.Sprintf("Skipping non-required wait, no resources found"))
return true, nil return true, nil
} }
return allMatch(c.Logger, cacheStore, minReady, nil) return allMatch(c.Logger, cacheStore, minReady, nil)