port smoke to go
This commit is contained in:
parent
b0a9d64f4a
commit
9ed44bfd75
20 changed files with 2118 additions and 1573 deletions
|
|
@ -149,7 +149,7 @@ func splitVMRunArgs(cmd *cobra.Command, args []string) (pathArgs, commandArgs []
|
|||
// for guest ssh, optionally materialise a workspace and kick off the
|
||||
// tooling bootstrap, then either attach interactively or run the
|
||||
// user's command and propagate its exit status.
|
||||
func (d *deps) runVMRun(ctx context.Context, socketPath string, cfg model.DaemonConfig, stdin io.Reader, stdout, stderr io.Writer, params api.VMCreateParams, repo *vmRunRepo, command []string, removeOnExit, detach, skipBootstrap bool) error {
|
||||
func (d *deps) runVMRun(ctx context.Context, socketPath string, cfg model.DaemonConfig, stdin io.Reader, stdout, stderr io.Writer, params api.VMCreateParams, repo *vmRunRepo, command []string, removeOnExit, detach, skipBootstrap, verbose bool) error {
|
||||
if repo != nil && !skipBootstrap && !params.NATEnabled {
|
||||
hasMise, err := repoHasMiseFiles(repo.sourcePath)
|
||||
if err != nil {
|
||||
|
|
@ -159,8 +159,9 @@ func (d *deps) runVMRun(ctx context.Context, socketPath string, cfg model.Daemon
|
|||
return errors.New("tooling bootstrap requires --nat (or pass --no-bootstrap to skip)")
|
||||
}
|
||||
}
|
||||
progress := newVMRunProgressRenderer(stderr)
|
||||
vm, err := d.runVMCreate(ctx, socketPath, stderr, params)
|
||||
progress := newVMRunProgressRenderer(stderr, verbose)
|
||||
defer progress.clear()
|
||||
vm, err := d.runVMCreate(ctx, socketPath, stderr, params, verbose)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
|
@ -183,8 +184,10 @@ func (d *deps) runVMRun(ctx context.Context, socketPath string, cfg model.Daemon
|
|||
cleanupCtx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
|
||||
defer cancel()
|
||||
if err := d.vmDelete(cleanupCtx, socketPath, vmRef); err != nil {
|
||||
progress.clear()
|
||||
printVMRunWarning(stderr, fmt.Sprintf("--rm cleanup failed: %v (leaked vm %q; delete manually)", err, vmRef))
|
||||
} else if err := removeUserKnownHosts(vm); err != nil {
|
||||
progress.clear()
|
||||
printVMRunWarning(stderr, fmt.Sprintf("known_hosts cleanup failed: %v", err))
|
||||
}
|
||||
}()
|
||||
|
|
@ -223,6 +226,7 @@ func (d *deps) runVMRun(ctx context.Context, socketPath string, cfg model.Daemon
|
|||
fromRef = repo.fromRef
|
||||
}
|
||||
if !repo.includeUntracked {
|
||||
progress.clear()
|
||||
d.noteUntrackedSkipped(ctx, stderr, repo.sourcePath)
|
||||
}
|
||||
prepared, err := d.vmWorkspacePrepare(ctx, socketPath, api.VMWorkspacePrepareParams{
|
||||
|
|
@ -246,13 +250,14 @@ func (d *deps) runVMRun(ctx context.Context, socketPath string, cfg model.Daemon
|
|||
return fmt.Errorf("vm %q is running but guest ssh is unavailable: %w", vmRef, err)
|
||||
}
|
||||
if err := d.startVMRunToolingHarness(ctx, client, prepared.Workspace.RepoRoot, prepared.Workspace.RepoName, progress, detach, stderr); err != nil {
|
||||
progress.clear()
|
||||
printVMRunWarning(stderr, fmt.Sprintf("guest tooling bootstrap start failed: %v", err))
|
||||
}
|
||||
_ = client.Close()
|
||||
}
|
||||
}
|
||||
if detach {
|
||||
progress.render(fmt.Sprintf("vm %s running; reconnect with: banger vm ssh %s", vmRef, vmRef))
|
||||
progress.commitLine(fmt.Sprintf("vm %s running; reconnect with: banger vm ssh %s", vmRef, vmRef))
|
||||
return nil
|
||||
}
|
||||
sshArgs, err := sshCommandArgs(cfg, vm.Runtime.GuestIP, command)
|
||||
|
|
@ -261,6 +266,7 @@ func (d *deps) runVMRun(ctx context.Context, socketPath string, cfg model.Daemon
|
|||
}
|
||||
if len(command) > 0 {
|
||||
progress.render("running command in guest")
|
||||
progress.clear()
|
||||
if err := d.sshExec(ctx, stdin, stdout, stderr, sshArgs); err != nil {
|
||||
var exitErr *exec.ExitError
|
||||
if errors.As(err, &exitErr) {
|
||||
|
|
@ -271,6 +277,7 @@ func (d *deps) runVMRun(ctx context.Context, socketPath string, cfg model.Daemon
|
|||
return nil
|
||||
}
|
||||
progress.render("attaching to guest")
|
||||
progress.clear()
|
||||
return d.runSSHSession(ctx, socketPath, vmRef, stdin, stdout, stderr, sshArgs, removeOnExit)
|
||||
}
|
||||
|
||||
|
|
@ -442,13 +449,24 @@ func formatVMRunStepError(action string, err error, log string) error {
|
|||
type vmRunProgressRenderer struct {
|
||||
out io.Writer
|
||||
enabled bool
|
||||
inline bool
|
||||
active bool
|
||||
lastLine string
|
||||
}
|
||||
|
||||
func newVMRunProgressRenderer(out io.Writer) *vmRunProgressRenderer {
|
||||
// newVMRunProgressRenderer wires up progress for `vm run`. Unlike the
|
||||
// vm_create renderer, this one emits in line mode even on non-TTY
|
||||
// writers (covers tests and piped output that the existing tooling
|
||||
// already parses); inline mode kicks in only when stderr is a TTY,
|
||||
// verbose is unset, and BANGER_NO_PROGRESS is unset.
|
||||
func newVMRunProgressRenderer(out io.Writer, verbose bool) *vmRunProgressRenderer {
|
||||
if out == nil {
|
||||
return &vmRunProgressRenderer{}
|
||||
}
|
||||
return &vmRunProgressRenderer{
|
||||
out: out,
|
||||
enabled: out != nil,
|
||||
enabled: true,
|
||||
inline: writerSupportsProgress(out) && !verbose && !progressDisabledByEnv(),
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -461,6 +479,47 @@ func (r *vmRunProgressRenderer) render(detail string) {
|
|||
return
|
||||
}
|
||||
r.lastLine = line
|
||||
if r.inline {
|
||||
_, _ = fmt.Fprint(r.out, "\r\x1b[K", line)
|
||||
r.active = true
|
||||
return
|
||||
}
|
||||
_, _ = fmt.Fprintln(r.out, line)
|
||||
}
|
||||
|
||||
// clear erases the live inline line so the caller can write a clean
|
||||
// terminating message (warning, ssh attach, command output). No-op
|
||||
// outside inline mode.
|
||||
func (r *vmRunProgressRenderer) clear() {
|
||||
if r == nil || !r.enabled || !r.inline || !r.active {
|
||||
return
|
||||
}
|
||||
_, _ = fmt.Fprint(r.out, "\r\x1b[K")
|
||||
r.active = false
|
||||
r.lastLine = ""
|
||||
}
|
||||
|
||||
// commitLine prints detail as a final, persistent line. In inline
|
||||
// mode it overwrites the live status; in line mode it just appends.
|
||||
// Used for terminal messages like the --detach hand-off summary.
|
||||
func (r *vmRunProgressRenderer) commitLine(detail string) {
|
||||
if r == nil || !r.enabled {
|
||||
return
|
||||
}
|
||||
line := formatVMRunProgress(detail)
|
||||
if line == "" {
|
||||
return
|
||||
}
|
||||
if r.inline {
|
||||
_, _ = fmt.Fprint(r.out, "\r\x1b[K", line, "\n")
|
||||
r.active = false
|
||||
r.lastLine = ""
|
||||
return
|
||||
}
|
||||
if line == r.lastLine {
|
||||
return
|
||||
}
|
||||
r.lastLine = line
|
||||
_, _ = fmt.Fprintln(r.out, line)
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue