feat(cli): include license status in support bundle (#18472)

Closes #18207

This PR adds license status to support bundle to help with
troubleshooting license-related issues.

- `license-status.txt`, is added to the support bundle.
    - it contains the same output as the `coder license list` command.
- license output formatter logic has been extracted into a separate
function.
- this allows it to be reused both in the `coder license list` cmd and
in the support bundle generation.
This commit is contained in:
Kacper Sawicki
2025-06-24 11:16:31 +02:00
committed by GitHub
parent 2afd1a203e
commit 7c40f86a6a
6 changed files with 129 additions and 72 deletions

View File

@ -3,6 +3,7 @@ package cli
import (
"archive/zip"
"bytes"
"context"
"encoding/base64"
"encoding/json"
"fmt"
@ -13,6 +14,8 @@ import (
"text/tabwriter"
"time"
"github.com/coder/coder/v2/cli/cliutil"
"github.com/google/uuid"
"golang.org/x/xerrors"
@ -48,6 +51,7 @@ var supportBundleBlurb = cliui.Bold("This will collect the following information
- Agent details (with environment variable sanitized)
- Agent network diagnostics
- Agent logs
- License status
` + cliui.Bold("Note: ") +
cliui.Wrap("While we try to sanitize sensitive data from support bundles, we cannot guarantee that they do not contain information that you or your organization may consider sensitive.\n") +
cliui.Bold("Please confirm that you will:\n") +
@ -302,6 +306,11 @@ func writeBundle(src *support.Bundle, dest *zip.Writer) error {
return xerrors.Errorf("decode template zip from base64")
}
licenseStatus, err := humanizeLicenses(src.Deployment.Licenses)
if err != nil {
return xerrors.Errorf("format license status: %w", err)
}
// The below we just write as we have them:
for k, v := range map[string]string{
"agent/logs.txt": string(src.Agent.Logs),
@ -315,6 +324,7 @@ func writeBundle(src *support.Bundle, dest *zip.Writer) error {
"network/tailnet_debug.html": src.Network.TailnetDebug,
"workspace/build_logs.txt": humanizeBuildLogs(src.Workspace.BuildLogs),
"workspace/template_file.zip": string(templateVersionBytes),
"license-status.txt": licenseStatus,
} {
f, err := dest.Create(k)
if err != nil {
@ -359,3 +369,13 @@ func humanizeBuildLogs(ls []codersdk.ProvisionerJobLog) string {
_ = tw.Flush()
return buf.String()
}
func humanizeLicenses(licenses []codersdk.License) (string, error) {
formatter := cliutil.NewLicenseFormatter()
if len(licenses) == 0 {
return "No licenses found", nil
}
return formatter.Format(context.Background(), licenses)
}