// WatchOfferStatus starts an OfferStatusWatcher for watching the status
// of the specified offer in the remote model.
972970
func (c *Client) WatchOfferStatus(arg params.OfferArg) (watcher.OfferStatusWatcher, error) {
	args := params.OfferArgs{Args: []params.OfferArg{arg}}
	// Use any previously cached discharge macaroons.
	if ms, ok := c.getCachedMacaroon("watch offer status", arg.OfferUUID); ok {
		args.Args[0].Macaroons = ms
	}

	var results params.OfferStatusWatchResults
	apiCall := func() error {
		// Reset the results struct before each api call.
		results = params.OfferStatusWatchResults{}
		if err := c.facade.FacadeCall("WatchOfferStatus", args, &results); err != nil {
			return errors.Trace(err)
		}
		if len(results.Results) != 1 {
			return errors.Errorf("expected 1 result, got %d", len(results.Results))
		}
		return nil
	}

	// Make the api call the first time.
	if err := apiCall(); err != nil {
		return nil, errors.Trace(err)
	}

	// On error, possibly discharge the macaroon and retry.
	result := results.Results[0]
	if result.Error != nil {
		mac, err := c.handleError(result.Error)
		if err != nil {
			result.Error.Message = err.Error()
			return nil, result.Error
		}
		args.Args[0].Macaroons = mac
		c.cache.Upsert(args.Args[0].OfferUUID, mac)

		if err := apiCall(); err != nil {
			return nil, errors.Trace(err)
		}
		result = results.Results[0]
	}
	if result.Error != nil {
		return nil, result.Error
	}

	w := apiwatcher.NewOfferStatusWatcher(c.facade.RawAPICaller(), result)
	return w, nil
}
312162
func (c *Client) XPackWatchPut(watchId string) *XPackWatcherPutWatchService {
	return NewXPackWatcherPutWatchService(c).Id(watchId)
}
206707
func (u *UniterAPIV8) WatchUnitAddresses(args params.Entities) (params.NotifyWatchResults, error) {
	result := params.NotifyWatchResults{
		Results: make([]params.NotifyWatchResult, len(args.Entities)),
	}
	canAccess, err := u.accessUnit()
	if err != nil {
		return params.NotifyWatchResults{}, err
	}
	for i, entity := range args.Entities {
		unit, err := names.ParseUnitTag(entity.Tag)
		if err != nil {
			result.Results[i].Error = common.ServerError(common.ErrPerm)
			continue
		}
		err = common.ErrPerm
		watcherId := ""
		if canAccess(unit) {
			watcherId, err = u.watchOneUnitAddresses(unit)
		}
		result.Results[i].NotifyWatcherId = watcherId
		result.Results[i].Error = common.ServerError(err)
	}
	return result, nil
}
971151
func (util *RBDUtil) rbdStatus(b *rbdMounter) (bool, string, error) {
	var err error
	var output string
	var cmd []byte

	// If we don't have admin id/secret (e.g. attaching), fallback to user id/secret.
	id := b.adminId
	secret := b.adminSecret
	if id == "" {
		id = b.Id
		secret = b.Secret
	}

	mon := util.kernelRBDMonitorsOpt(b.Mon)
	// cmd "rbd status" list the rbd client watch with the following output:
	//
	// # there is a watcher (exit=0)
	// Watchers:
	//   watcher=10.16.153.105:0/710245699 client.14163 cookie=1
	//
	// # there is no watcher (exit=0)
	// Watchers: none
	//
	// Otherwise, exit is non-zero, for example:
	//
	// # image does not exist (exit=2)
	// rbd: error opening image kubernetes-dynamic-pvc-<UUID>: (2) No such file or directory
	//
	klog.V(4).Infof("rbd: status %s using mon %s, pool %s id %s key %s", b.Image, mon, b.Pool, id, secret)
	cmd, err = b.exec.Run("rbd",
		"status", b.Image, "--pool", b.Pool, "-m", mon, "--id", id, "--key="+secret)
	output = string(cmd)

	if err, ok := err.(*exec.Error); ok {
		if err.Err == exec.ErrNotFound {
			klog.Errorf("rbd cmd not found")
			// fail fast if command not found
			return false, output, err
		}
	}

	// If command never succeed, returns its last error.
	if err != nil {
		return false, output, err
	}

	if strings.Contains(output, imageWatcherStr) {
		klog.V(4).Infof("rbd: watchers on %s: %s", b.Image, output)
		return true, output, nil
	} else {
		klog.Warningf("rbd: no watchers on %s", b.Image)
		return false, output, nil
	}
}
289611
func (c *Client) Watch(application string) (watcher.NotifyWatcher, error) {
	tag, err := c.appTag(application)
	if err != nil {
		return nil, errors.Trace(err)
	}
	return common.Watch(c.facade, "Watch", tag)
}
934678
func (api *CloudSpecAPI) WatchCloudSpecChanges() (watcher.NotifyWatcher, error) {
	var results params.NotifyWatchResults
	args := params.Entities{Entities: []params.Entity{{api.modelTag.String()}}}
	err := api.facade.FacadeCall("WatchCloudSpecsChanges", args, &results)
	if err != nil {
		return nil, err
	}
	if n := len(results.Results); n != 1 {
		return nil, errors.Errorf("expected 1 result, got %d", n)
	}
	result := results.Results[0]
	if result.Error != nil {
		return nil, errors.Annotate(result.Error, "API request failed")
	}
	return apiwatcher.NewNotifyWatcher(api.facade.RawAPICaller(), result), nil
}
240450
func (w *deployWatcher) Watch(name string, serviceNames []string, statusUpdates chan serviceStatus) error {
	errC := make(chan error, 1)
	defer close(errC)

	handlers := runtimeutil.ErrorHandlers

	// informer errors are reported using global error handlers
	runtimeutil.ErrorHandlers = append(handlers, func(err error) {
		errC <- err
	})
	defer func() {
		runtimeutil.ErrorHandlers = handlers
	}()

	ctx, cancel := context.WithCancel(context.Background())
	wg := sync.WaitGroup{}
	defer func() {
		cancel()
		wg.Wait()
	}()
	wg.Add(2)
	go func() {
		defer wg.Done()
		w.watchStackStatus(ctx, name, errC)
	}()
	go func() {
		defer wg.Done()
		w.waitForPods(ctx, name, serviceNames, errC, statusUpdates)
	}()

	return <-errC
}
636033
func (api *CrossModelRelationsAPI) WatchRelationsSuspendedStatus(
	remoteRelationArgs params.RemoteEntityArgs,
) (params.RelationStatusWatchResults, error) {
	results := params.RelationStatusWatchResults{
		Results: make([]params.RelationLifeSuspendedStatusWatchResult, len(remoteRelationArgs.Args)),
	}

	for i, arg := range remoteRelationArgs.Args {
		relationTag, err := api.st.GetRemoteEntity(arg.Token)
		if err != nil {
			results.Results[i].Error = common.ServerError(err)
			continue
		}
		if err := api.checkMacaroonsForRelation(relationTag, arg.Macaroons); err != nil {
			results.Results[i].Error = common.ServerError(err)
			continue
		}
		w, err := api.relationStatusWatcher(api.st, relationTag.(names.RelationTag))
		if err != nil {
			results.Results[i].Error = common.ServerError(err)
			continue
		}
		changes, ok := <-w.Changes()
		if !ok {
			results.Results[i].Error = common.ServerError(watcher.EnsureErr(w))
			continue
		}
		changesParams := make([]params.RelationLifeSuspendedStatusChange, len(changes))
		for j, key := range changes {
			change, err := commoncrossmodel.GetRelationLifeSuspendedStatusChange(api.st, key)
			if err != nil {
				results.Results[i].Error = common.ServerError(err)
				changesParams = nil
				w.Stop()
				break
			}
			changesParams[j] = *change
		}
		results.Results[i].Changes = changesParams
		results.Results[i].RelationStatusWatcherId = api.resources.Register(w)
	}
	return results, nil
}
934239
func (m *MockUpgradeSeriesMachine) WatchUpgradeSeriesNotifications() (state.NotifyWatcher, error) {
	ret := m.ctrl.Call(m, "WatchUpgradeSeriesNotifications")
	ret0, _ := ret[0].(state.NotifyWatcher)
	ret1, _ := ret[1].(error)
	return ret0, ret1
}
812011
func (m *Monitor) ScheduleStatus(key *aurora.JobKey, instanceCount int32, desiredStatuses map[aurora.ScheduleStatus]bool, interval, timeout int) (bool, error) {

	ticker := time.NewTicker(time.Second * time.Duration(interval))
	defer ticker.Stop()
	timer := time.NewTimer(time.Second * time.Duration(timeout))
	defer timer.Stop()

	wantedStatuses := make([]aurora.ScheduleStatus, 0)

	for status := range desiredStatuses {
		wantedStatuses = append(wantedStatuses, status)
	}

	for {
		select {
		case <-ticker.C:

			// Query Aurora for the state of the job key ever interval
			instCount, cliErr := m.Client.GetInstanceIds(key, wantedStatuses)
			if cliErr != nil {
				return false, errors.Wrap(cliErr, "Unable to communicate with Aurora")
			}
			if len(instCount) == int(instanceCount) {
				return true, nil
			}
		case <-timer.C:

			// If the timer runs out, return a timeout error to user
			return false, newTimedoutError(errors.New("schedule status monitor timed out"))
		}
	}
}
360853
func (u *UniterAPIV8) WatchConfigSettings(args params.Entities) (params.NotifyWatchResults, error) {
	watcherFn := func(u *state.Unit) (state.NotifyWatcher, error) {
		return u.WatchConfigSettings()
	}
	result, err := u.WatchSettings(args, watcherFn)
	if err != nil {
		return params.NotifyWatchResults{}, errors.Trace(err)
	}

	return result, nil
}
1276356
func OptionDiscoveryWatcher(watcher discovery.Watcher) Option {
	return func(c *Config) {
		c.Cluster.Watcher = watcher
	}
}
793171
func statusViewer(mapping *meta.RESTMapping) (kubectl.StatusViewer, error) {
	return kubectl.StatusViewerFor(mapping.GroupVersionKind.GroupKind())
}
769708
func newStatusInfo(node *core.Node) *statusInfo {
	out := statusInfo{
		node:    node,
		watches: make(map[int64]ResponseWatch),
	}
	return &out
}
319323
func (a *API) WatchUnitAssignments() (params.StringsWatchResult, error) {
	watch := a.st.WatchForUnitAssignment()
	if changes, ok := <-watch.Changes(); ok {
		return params.StringsWatchResult{
			StringsWatcherId: a.res.Register(watch),
			Changes:          changes,
		}, nil
	}
	return params.StringsWatchResult{}, watcher.EnsureErr(watch)
}
355483
func (c *Client) XPackWatchActivate(watchId string) *XPackWatcherActivateWatchService {
	return NewXPackWatcherActivateWatchService(c).WatchId(watchId)
}
616767
func fetchOffers(st Backend, applications map[string]*state.Application) (map[string]offerStatus, error) {
	offersMap := make(map[string]offerStatus)
	offers, err := st.AllApplicationOffers()
	if err != nil {
		return nil, err
	}
	for _, offer := range offers {
		offerInfo := offerStatus{
			ApplicationOffer: crossmodel.ApplicationOffer{
				OfferName:       offer.OfferName,
				OfferUUID:       offer.OfferUUID,
				ApplicationName: offer.ApplicationName,
				Endpoints:       offer.Endpoints,
			},
		}
		app, ok := applications[offer.ApplicationName]
		if !ok {
			continue
		}
		curl, _ := app.CharmURL()
		offerInfo.charmURL = curl.String()
		rc, err := st.RemoteConnectionStatus(offer.OfferUUID)
		if err != nil && !errors.IsNotFound(err) {
			offerInfo.err = err
			continue
		} else if err == nil {
			offerInfo.totalConnectedCount = rc.TotalConnectionCount()
			offerInfo.activeConnectedCount = rc.ActiveConnectionCount()
		}
		offersMap[offer.OfferName] = offerInfo
	}
	return offersMap, nil
}