// getBlockAPI returns a block api for listing blocks. func getBlockAPI(c *modelcmd.ModelCommandBase) (block.BlockListAPI, error) { root, err := c.NewAPIRoot() if err != nil { return nil, err } return apiblock.NewClient(root), nil }
// getBlockAPI returns a block api for listing blocks. func getBlockAPI(c *modelcmd.ModelCommandBase) (listBlocksAPI, error) { root, err := c.NewAPIRoot() if err != nil { return nil, errors.Trace(err) } return block.NewClient(root), nil }
// WaitForAgentInitialisation polls the bootstrapped controller with a read-only // command which will fail until the controller is fully initialised. // TODO(wallyworld) - add a bespoke command to maybe the admin facade for this purpose. func WaitForAgentInitialisation(ctx *cmd.Context, c *modelcmd.ModelCommandBase, controllerName, hostedModelName string) error { // TODO(katco): 2016-08-09: lp:1611427 attempts := utils.AttemptStrategy{ Min: bootstrapReadyPollCount, Delay: bootstrapReadyPollDelay, } var ( apiAttempts int err error ) // Make a best effort to find the new controller address so we can print it. addressInfo := "" controller, err := c.ClientStore().ControllerByName(controllerName) if err == nil && len(controller.APIEndpoints) > 0 { addr, err := network.ParseHostPort(controller.APIEndpoints[0]) if err == nil { addressInfo = fmt.Sprintf(" at %s", addr.Address.Value) } } ctx.Infof("Contacting Juju controller%s to verify accessibility...", addressInfo) apiAttempts = 1 for attempt := attempts.Start(); attempt.Next(); apiAttempts++ { err = tryAPI(c) if err == nil { ctx.Infof("Bootstrap complete, %q controller now available.", controllerName) ctx.Infof("Controller machines are in the %q model.", bootstrap.ControllerModelName) ctx.Infof("Initial model %q added.", hostedModelName) break } // As the API server is coming up, it goes through a number of steps. // Initially the upgrade steps run, but the api server allows some // calls to be processed during the upgrade, but not the list blocks. // Logins are also blocked during space discovery. // It is also possible that the underlying database causes connections // to be dropped as it is initialising, or reconfiguring. These can // lead to EOF or "connection is shut down" error messages. We skip // these too, hoping that things come back up before the end of the // retry poll count. errorMessage := errors.Cause(err).Error() switch { case errors.Cause(err) == io.EOF, strings.HasSuffix(errorMessage, "connection is shut down"), strings.HasSuffix(errorMessage, "no api connection available"), strings.Contains(errorMessage, "spaces are still being discovered"): ctx.Verbosef("Still waiting for API to become available") continue case params.ErrCode(err) == params.CodeUpgradeInProgress: ctx.Verbosef("Still waiting for API to become available: %v", err) continue } break } return errors.Annotatef(err, "unable to contact api server after %d attempts", apiAttempts) }
func connectionCredentials(c modelcmd.ModelCommandBase) (configstore.APICredentials, error) { return c.ConnectionCredentials() }
func connectionEndpoint(c modelcmd.ModelCommandBase, refresh bool) (configstore.APIEndpoint, error) { return c.ConnectionEndpoint(refresh) }