summaryrefslogtreecommitdiffstats
path: root/client
diff options
context:
space:
mode:
authorMartin Polden <mpolden@mpolden.no>2022-08-30 13:24:13 +0200
committerMartin Polden <mpolden@mpolden.no>2022-08-30 13:24:13 +0200
commitcb05c47ae39fc487cfa73b4096e19d7384dd18cd (patch)
treea85cfd6111389606ed90201995d8377638bad98c /client
parenta940f868e2e2ef1e6121e76b643d64f8b1b9037a (diff)
Print hints if service discovery fails
Diffstat (limited to 'client')
-rw-r--r--client/go/cmd/deploy.go4
-rw-r--r--client/go/cmd/root.go6
-rw-r--r--client/go/cmd/status.go16
-rw-r--r--client/go/vespa/deploy.go17
-rw-r--r--client/go/vespa/target.go3
-rw-r--r--client/go/vespa/target_cloud.go2
-rw-r--r--client/go/vespa/target_custom.go2
7 files changed, 29 insertions, 21 deletions
diff --git a/client/go/cmd/deploy.go b/client/go/cmd/deploy.go
index 012570c5471..df08c90768b 100644
--- a/client/go/cmd/deploy.go
+++ b/client/go/cmd/deploy.go
@@ -78,13 +78,13 @@ $ vespa deploy -t cloud -z perf.aws-us-east-1c`,
}
log.Println()
- if opts.IsCloud() {
+ if opts.Target.IsCloud() {
cli.printSuccess("Triggered deployment of ", color.CyanString(pkg.Path), " with run ID ", color.CyanString(strconv.FormatInt(result.ID, 10)))
} else {
cli.printSuccess("Deployed ", color.CyanString(pkg.Path))
printPrepareLog(cli.Stderr, result)
}
- if opts.IsCloud() {
+ if opts.Target.IsCloud() {
log.Printf("\nUse %s for deployment status, or follow this deployment at", color.CyanString("vespa status"))
log.Print(color.CyanString(fmt.Sprintf("%s/tenant/%s/application/%s/%s/instance/%s/job/%s-%s/run/%d",
opts.Target.Deployment().System.ConsoleURL,
diff --git a/client/go/cmd/root.go b/client/go/cmd/root.go
index c8c49efbe07..d41be3fa097 100644
--- a/client/go/cmd/root.go
+++ b/client/go/cmd/root.go
@@ -403,7 +403,11 @@ func (c *CLI) service(target vespa.Target, name string, sessionOrRunID int64, cl
}
s, err := target.Service(name, timeout, sessionOrRunID, cluster)
if err != nil {
- return nil, fmt.Errorf("service '%s' is unavailable: %w", name, err)
+ err := fmt.Errorf("service '%s' is unavailable: %w", name, err)
+ if target.IsCloud() {
+ return nil, errHint(err, "Confirm that you're communicating with the correct zone and cluster", "The -z option controls the zone", "The -C option controls the cluster")
+ }
+ return nil, err
}
return s, nil
}
diff --git a/client/go/cmd/status.go b/client/go/cmd/status.go
index c44bbddb98a..56f394d94ee 100644
--- a/client/go/cmd/status.go
+++ b/client/go/cmd/status.go
@@ -74,25 +74,27 @@ func printServiceStatus(cli *CLI, name string) error {
if err != nil {
return err
}
- timeout, err := cli.config.timeout()
+ cluster := cli.config.cluster()
+ s, err := cli.service(t, name, 0, cluster)
if err != nil {
return err
}
- if timeout > 0 {
- log.Printf("Waiting up to %s for service to become ready ...", color.CyanString(timeout.String()))
- }
- s, err := t.Service(name, timeout, 0, cli.config.cluster())
+ timeout, err := cli.config.timeout()
if err != nil {
return err
}
status, err := s.Wait(timeout)
+ clusterPart := ""
+ if cluster != "" {
+ clusterPart = fmt.Sprintf(" named %s", color.CyanString(cluster))
+ }
if status/100 == 2 {
- log.Print(s.Description(), " at ", color.CyanString(s.BaseURL), " is ", color.GreenString("ready"))
+ log.Print(s.Description(), clusterPart, " at ", color.CyanString(s.BaseURL), " is ", color.GreenString("ready"))
} else {
if err == nil {
err = fmt.Errorf("status %d", status)
}
- return fmt.Errorf("%s at %s is %s: %w", s.Description(), color.CyanString(s.BaseURL), color.RedString("not ready"), err)
+ return fmt.Errorf("%s%s at %s is %s: %w", s.Description(), clusterPart, color.CyanString(s.BaseURL), color.RedString("not ready"), err)
}
return nil
}
diff --git a/client/go/vespa/deploy.go b/client/go/vespa/deploy.go
index 0e086979d72..b98679aadd8 100644
--- a/client/go/vespa/deploy.go
+++ b/client/go/vespa/deploy.go
@@ -80,11 +80,6 @@ func (d DeploymentOptions) String() string {
return fmt.Sprintf("%s to %s", d.Target.Deployment(), d.Target.Type())
}
-// IsCloud returns whether this is a deployment to Vespa Cloud or hosted Vespa
-func (d *DeploymentOptions) IsCloud() bool {
- return d.Target.Type() == TargetCloud || d.Target.Type() == TargetHosted
-}
-
func (d *DeploymentOptions) url(path string) (*url.URL, error) {
service, err := d.Target.Service(DeployService, 0, 0, "")
if err != nil {
@@ -115,7 +110,7 @@ func ZoneFromString(s string) (ZoneID, error) {
// Prepare deployment and return the session ID
func Prepare(deployment DeploymentOptions) (PrepareResult, error) {
- if deployment.IsCloud() {
+ if deployment.Target.IsCloud() {
return PrepareResult{}, fmt.Errorf("prepare is not supported with %s target", deployment.Target.Type())
}
sessionURL, err := deployment.url("/application/v2/tenant/default/session")
@@ -164,7 +159,7 @@ func Prepare(deployment DeploymentOptions) (PrepareResult, error) {
// Activate deployment with sessionID from a past prepare
func Activate(sessionID int64, deployment DeploymentOptions) error {
- if deployment.IsCloud() {
+ if deployment.Target.IsCloud() {
return fmt.Errorf("activate is not supported with %s target", deployment.Target.Type())
}
u, err := deployment.url(fmt.Sprintf("/application/v2/tenant/default/session/%d/active", sessionID))
@@ -186,7 +181,7 @@ func Activate(sessionID int64, deployment DeploymentOptions) error {
func Deploy(opts DeploymentOptions) (PrepareResult, error) {
path := "/application/v2/tenant/default/prepareandactivate"
- if opts.IsCloud() {
+ if opts.Target.IsCloud() {
if err := checkDeploymentOpts(opts); err != nil {
return PrepareResult{}, err
}
@@ -225,7 +220,7 @@ func copyToPart(dst *multipart.Writer, src io.Reader, fieldname, filename string
}
func Submit(opts DeploymentOptions) error {
- if !opts.IsCloud() {
+ if !opts.Target.IsCloud() {
return fmt.Errorf("%s: submit is unsupported by %s target", opts, opts.Target.Type())
}
if err := checkDeploymentOpts(opts); err != nil {
@@ -282,7 +277,7 @@ func checkDeploymentOpts(opts DeploymentOptions) error {
if opts.Target.Type() == TargetCloud && !opts.ApplicationPackage.HasCertificate() {
return fmt.Errorf("%s: missing certificate in package", opts)
}
- if !opts.IsCloud() && !opts.Version.IsZero() {
+ if !opts.Target.IsCloud() && !opts.Version.IsZero() {
return fmt.Errorf("%s: custom runtime version is not supported by %s target", opts, opts.Target.Type())
}
return nil
@@ -295,7 +290,7 @@ func newDeploymentRequest(url *url.URL, opts DeploymentOptions) (*http.Request,
}
var body io.Reader
header := http.Header{}
- if opts.IsCloud() {
+ if opts.Target.IsCloud() {
var buf bytes.Buffer
form := multipart.NewWriter(&buf)
formFile, err := form.CreateFormFile("applicationZip", filepath.Base(opts.ApplicationPackage.Path))
diff --git a/client/go/vespa/target.go b/client/go/vespa/target.go
index 9a2bb770906..34dda889c5a 100644
--- a/client/go/vespa/target.go
+++ b/client/go/vespa/target.go
@@ -52,6 +52,9 @@ type Target interface {
// Type returns this target's type, e.g. local or cloud.
Type() string
+ // IsCloud returns whether this target is Vespa Cloud or hosted Vespa
+ IsCloud() bool
+
// Deployment returns the deployment managed by this target.
Deployment() Deployment
diff --git a/client/go/vespa/target_cloud.go b/client/go/vespa/target_cloud.go
index 8e8a7b57f3e..c89e6f6ecef 100644
--- a/client/go/vespa/target_cloud.go
+++ b/client/go/vespa/target_cloud.go
@@ -114,6 +114,8 @@ func (t *cloudTarget) Type() string {
return TargetCloud
}
+func (t *cloudTarget) IsCloud() bool { return true }
+
func (t *cloudTarget) Deployment() Deployment { return t.deploymentOptions.Deployment }
func (t *cloudTarget) Service(name string, timeout time.Duration, runID int64, cluster string) (*Service, error) {
diff --git a/client/go/vespa/target_custom.go b/client/go/vespa/target_custom.go
index bc25f19bf1a..c34f801641c 100644
--- a/client/go/vespa/target_custom.go
+++ b/client/go/vespa/target_custom.go
@@ -33,6 +33,8 @@ func CustomTarget(httpClient util.HTTPClient, baseURL string) Target {
func (t *customTarget) Type() string { return t.targetType }
+func (t *customTarget) IsCloud() bool { return false }
+
func (t *customTarget) Deployment() Deployment { return Deployment{} }
func (t *customTarget) createService(name string) (*Service, error) {