Uh oh!
There was an error while loading. Please reload this page.
- Notifications
You must be signed in to change notification settings - Fork 0
feat(cli): --verbose + cluster doctor auth checks + resume hint & install log (cli#101)#121
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Uh oh!
There was an error while loading. Please reload this page.
Merged
Changes from all commits
Commits
Show all changes
4 commits
Select commit
Hold shift + click to select a range
d6d59ba
feat(cli): --verbose + cluster doctor auth checks + resume hint & ins…
saadqbal ed2f736
fix(cli): don't log a cancelled provision as "done" (cli#101, Bugbot)
saadqbal b9a1497
fix(cli): resume command includes prompted name/location, not just fl…
saadqbal c712dc7
fix(cli): doctor folds auth into the kubeconfig-exit code; install lo…
saadqbal File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Uh oh!
There was an error while loading. Please reload this page.
Jump to
Jump to file
Failed to load files.
Loading
Uh oh!
There was an error while loading. Please reload this page.
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -130,11 +130,38 @@ func authedClient() (*api.Client, *config.Config, error) { | ||
| return client, cfg, nil | ||
| } | ||
| func runClientCreate(ctx context.Context, p *ui.Printer, pr prompter, opts clientCreateOpts) error { | ||
| func runClientCreate(ctx context.Context, p *ui.Printer, pr prompter, opts clientCreateOpts) (err error) { | ||
| // Always leave a full provision trace on disk, even on a quiet/headless run | ||
| // (RFC-0001 §8.5). On any failure, point at the (idempotent) resume command | ||
| // + `cluster doctor`, so a zero-prompt connect that breaks isn't a dead end. | ||
| ilog, logPath := newInstallLog() | ||
| defer ilog.Close() | ||
| ilog.Logf("client create: name=%q location=%q", opts.name, opts.location) | ||
| defer func() { | ||
| if err != nil { | ||
| ilog.Logf("FAILED: %v", err) | ||
| p.Newline() | ||
| p.Hintf("Provisioning didn't complete. Re-running is safe — on the same cluster it adopts the existing client instead of minting a duplicate (idempotent):") | ||
| p.Hintf(" %s", resumeCommand(opts)) | ||
| p.Hintf("Diagnose auth / cluster problems with: tracebloc cluster doctor") | ||
| if logPath != "" { | ||
| p.Hintf("Full log: %s", logPath) | ||
| } | ||
| return | ||
| } | ||
| // Success/cancel: the terminal outcome was already logged at its own | ||
| // branch (minted / adopted / cancelled), so don't blanket-log "done" | ||
| // here — a declined confirm must not read as a successful provision. | ||
| if logPath != "" { | ||
| p.Detailf("full log: %s", logPath) | ||
| } | ||
| }() | ||
saadqbal marked this conversation as resolved.
Uh oh!There was an error while loading. Please reload this page. | ||
| client, cfg, err := authedClient() | ||
| if err != nil { | ||
| return &exitError{code: 1, err: err} | ||
| } | ||
| ilog.Logf("authenticated; provisioning against the signed-in account") | ||
| name, location := opts.name, opts.location | ||
| @@ -158,6 +185,10 @@ func runClientCreate(ctx context.Context, p *ui.Printer, pr prompter, opts clien | ||
| return mapClientErr(err) | ||
| } | ||
| } | ||
| // Reflect the resolved (possibly prompted) name + location back into opts, so | ||
| // the failure-path resume command includes them — opts otherwise carries only | ||
| // the flags, omitting anything the user typed at a prompt (Bugbot). | ||
| opts.name, opts.location = name, location | ||
| // Read the cluster anchor (kube-system UID) so create is get-or-create keyed on | ||
| // it — re-running on the same cluster adopts the existing client instead of | ||
| @@ -168,6 +199,7 @@ func runClientCreate(ctx context.Context, p *ui.Printer, pr prompter, opts clien | ||
| if cidErr != nil { | ||
| p.Hintf("Couldn't read the target cluster's identity — provisioning without a cluster anchor, so re-running won't be idempotent. Point --kubeconfig/--context at the reachable cluster to enable that.") | ||
| } | ||
| ilog.Logf("cluster anchor: %q (read err: %v)", clusterID, cidErr) | ||
| // Derive the namespace slug from the name, avoiding collisions with existing | ||
| // clients (best-effort: if the list call fails we still derive a base slug). | ||
| @@ -198,6 +230,7 @@ func runClientCreate(ctx context.Context, p *ui.Printer, pr prompter, opts clien | ||
| return mapClientErr(cerr) | ||
| } | ||
| if !ok { | ||
| ilog.Logf("cancelled by user at the confirm prompt") | ||
| p.Hintf("Cancelled.") | ||
| return nil | ||
| } | ||
| @@ -241,6 +274,7 @@ func runClientCreate(ctx context.Context, p *ui.Printer, pr prompter, opts clien | ||
| // where the backend instead matches a live in-cluster TB_CLIENT_ID whose | ||
| // cluster_id is still null and the CLI backfills it via PATCH, is the | ||
| // installer's orchestration — #838 — not done here.) | ||
| ilog.Logf("adopted existing client id=%d namespace=%s", pc.ID, pc.Namespace) | ||
| p.Successf("This cluster is already registered as client %q (namespace %s) — adopted it.", pc.Name, pc.Namespace) | ||
| p.Hintf("No new credential issued; the existing one stands. This machine is set to enroll as client %d.", pc.ID) | ||
| if opts.credentialFile != "" { | ||
| @@ -287,12 +321,48 @@ func runClientCreate(ctx context.Context, p *ui.Printer, pr prompter, opts clien | ||
| p.Field("username", pc.Username) | ||
| p.Field("password", password) | ||
| } | ||
| ilog.Logf("minted client id=%d namespace=%s", pc.ID, pc.Namespace) | ||
| if serr := cfg.Save(); serr != nil { | ||
| p.Hintf("Couldn't save the active-client pointer (%v) — run `tracebloc client use %d` to set it.", serr, pc.ID) | ||
| } | ||
| return nil | ||
| } | ||
| // resumeCommand reconstructs the `tracebloc client create` invocation to retry a | ||
| // failed provision. Re-running is idempotent (RFC-0001 §7.2): on the same cluster | ||
| // it adopts the existing client rather than minting a duplicate. | ||
| func resumeCommand(opts clientCreateOpts) string { | ||
| parts := []string{"tracebloc client create"} | ||
| if opts.name != "" { | ||
| parts = append(parts, "--name "+shellArg(opts.name)) | ||
| } | ||
| if opts.location != "" { | ||
| parts = append(parts, "--location "+shellArg(opts.location)) | ||
| } | ||
| if opts.kubeconfigPath != "" { | ||
| parts = append(parts, "--kubeconfig "+shellArg(opts.kubeconfigPath)) | ||
| } | ||
| if opts.contextOverride != "" { | ||
| parts = append(parts, "--context "+shellArg(opts.contextOverride)) | ||
| } | ||
| if opts.credentialFile != "" { | ||
| parts = append(parts, "--credential-file "+shellArg(opts.credentialFile)) | ||
| } | ||
| if opts.yes { | ||
| parts = append(parts, "--yes") | ||
| } | ||
| return strings.Join(parts, " ") | ||
| } | ||
| // shellArg single-quotes an argument containing whitespace so the resume command | ||
| // stays copy-pasteable for values like "Lab One". | ||
| func shellArg(s string) string { | ||
| if strings.ContainsAny(s, " \t") { | ||
| return "'" + s + "'" | ||
| } | ||
| return s | ||
| } | ||
| // writeClientCredential writes the machine credential to path (mode 0600) as a | ||
| // shell-sourceable env file — the installer (#838) sources it to feed the chart, | ||
| // so the secret lands in a 0600 file, never the terminal (RFC §9 never-show). The | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Uh oh!
There was an error while loading. Please reload this page.
Oops, something went wrong.
Uh oh!
There was an error while loading. Please reload this page.
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.