package couchctl import ( "context" "fmt" "time" dsapi "edge-infra.dev/pkg/edge/datasync/apis/v1alpha1" "edge-infra.dev/pkg/k8s/meta/status" "edge-infra.dev/pkg/k8s/runtime/conditions" "github.com/go-logr/logr" "k8s.io/apimachinery/pkg/fields" kwatch "k8s.io/apimachinery/pkg/watch" "sigs.k8s.io/controller-runtime/pkg/client" ) // WatchCouchDBUser watch couchdb user resource. // TODO make generic to watch any couchdb resource. func WatchCouchDBUser(ctx context.Context, cl client.WithWatch, user *dsapi.CouchDBUser, timeout time.Duration) error { log := logr.FromContextOrDiscard(ctx) list := &dsapi.CouchDBUserList{} watch, err := cl.Watch(ctx, list, &client.ListOptions{ FieldSelector: fields.OneTermEqualSelector("metadata.name", user.Name), Namespace: user.Namespace, }) if err != nil { log.Error(err, "fail to setup watch for CouchDBUser status") return err } loop: for { select { case event := <-watch.ResultChan(): u := event.Object.(*dsapi.CouchDBUser) switch event.Type { case kwatch.Added, kwatch.Modified: ready := conditions.IsReady(u) if !ready { log.Info("CouchDBUser is not ready, will watch until timeout", "reason", conditions.GetReason(u, status.ReadyCondition)) continue } break loop case kwatch.Error: err := fmt.Errorf("error retrieving CouchDBUser") log.Error(err, "event error") return err } case <-time.After(timeout): err := fmt.Errorf("error timing out while retrieving CouchDBUser") log.Error(err, "timeout error") return err } } return nil }