Skip to content

Commit 7262cf2

Browse files
authored
fix(agents+sip): address some style and usability issues (#620)
* chore(sip): support project auth flow in sip commands * fix(agents): address some formatting and usability issues
1 parent c235504 commit 7262cf2

File tree

4 files changed

+123
-65
lines changed

4 files changed

+123
-65
lines changed

cmd/lk/agent.go

Lines changed: 97 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -483,19 +483,15 @@ func createAgentConfig(ctx context.Context, cmd *cli.Command) error {
483483
}
484484

485485
func deployAgent(ctx context.Context, cmd *cli.Command) error {
486-
configExists, err := requireConfig(workingDir, tomlFilename)
486+
var req *lkproto.DeployAgentRequest
487+
488+
agentId, err := getAgentID(ctx, cmd, workingDir, tomlFilename)
487489
if err != nil {
488490
return err
489491
}
490-
if !configExists {
491-
return fmt.Errorf("config file [%s] required to update agent", util.Accented(tomlFilename))
492-
}
493-
if !lkConfig.HasAgent() {
494-
return fmt.Errorf("no agent config found in [%s]", tomlFilename)
495-
}
496492

497-
req := &lkproto.DeployAgentRequest{
498-
AgentId: lkConfig.Agent.ID,
493+
req = &lkproto.DeployAgentRequest{
494+
AgentId: agentId,
499495
}
500496

501497
secrets, err := requireSecrets(ctx, cmd, false, true)
@@ -537,7 +533,7 @@ func deployAgent(ctx context.Context, cmd *cli.Command) error {
537533
}
538534

539535
func getAgentStatus(ctx context.Context, cmd *cli.Command) error {
540-
agentID, err := getAgentID(cmd, workingDir, tomlFilename)
536+
agentID, err := getAgentID(ctx, cmd, workingDir, tomlFilename)
541537
if err != nil {
542538
return err
543539
}
@@ -577,9 +573,11 @@ func getAgentStatus(ctx context.Context, cmd *cli.Command) error {
577573
}
578574

579575
rows = append(rows, []string{
576+
agent.AgentId,
577+
agent.Version,
580578
regionalAgent.Region,
581579
regionalAgent.Status,
582-
fmt.Sprintf("%.4g / %s", curCPU, regionalAgent.CpuLimit),
580+
fmt.Sprintf("%s / %s", curCPU, regionalAgent.CpuLimit),
583581
fmt.Sprintf("%s / %s", curMem, memLimit),
584582
fmt.Sprintf("%d / %d / %d", regionalAgent.Replicas, regionalAgent.MinReplicas, regionalAgent.MaxReplicas),
585583
agent.DeployedAt.AsTime().Format(time.RFC3339),
@@ -588,15 +586,15 @@ func getAgentStatus(ctx context.Context, cmd *cli.Command) error {
588586
}
589587

590588
t := util.CreateTable().
591-
Headers("Region", "Status", "CPU", "Mem", "Replicas/Min/Max", "Deployed At").
589+
Headers("ID", "Version", "Region", "Status", "CPU", "Mem", "Replicas", "Deployed At").
592590
Rows(rows...)
593591

594592
fmt.Println(t)
595593
return nil
596594
}
597595

598596
func restartAgent(ctx context.Context, cmd *cli.Command) error {
599-
agentID, err := getAgentID(cmd, workingDir, tomlFilename)
597+
agentID, err := getAgentID(ctx, cmd, workingDir, tomlFilename)
600598
if err != nil {
601599
return err
602600
}
@@ -645,7 +643,10 @@ func updateAgent(ctx context.Context, cmd *cli.Command) error {
645643
req.Secrets = secrets
646644
}
647645

648-
resp, err := agentsClient.UpdateAgent(ctx, req)
646+
var resp *lkproto.UpdateAgentResponse
647+
util.Await("Updating agent ["+util.Accented(lkConfig.Agent.ID)+"]", func() {
648+
resp, err = agentsClient.UpdateAgent(ctx, req)
649+
})
649650
if err != nil {
650651
if twerr, ok := err.(twirp.Error); ok {
651652
if twerr.Code() == twirp.PermissionDenied {
@@ -665,14 +666,17 @@ func updateAgent(ctx context.Context, cmd *cli.Command) error {
665666
}
666667

667668
func rollbackAgent(ctx context.Context, cmd *cli.Command) error {
668-
agentID, err := getAgentID(cmd, workingDir, tomlFilename)
669+
agentID, err := getAgentID(ctx, cmd, workingDir, tomlFilename)
669670
if err != nil {
670671
return err
671672
}
672673

673-
resp, err := agentsClient.RollbackAgent(ctx, &lkproto.RollbackAgentRequest{
674-
AgentId: agentID,
675-
Version: cmd.String("version"),
674+
var resp *lkproto.RollbackAgentResponse
675+
util.Await("Rolling back agent ["+util.Accented(agentID)+"]", func() {
676+
resp, err = agentsClient.RollbackAgent(ctx, &lkproto.RollbackAgentRequest{
677+
AgentId: agentID,
678+
Version: cmd.String("version"),
679+
})
676680
})
677681

678682
if err != nil {
@@ -688,13 +692,13 @@ func rollbackAgent(ctx context.Context, cmd *cli.Command) error {
688692
return fmt.Errorf("failed to rollback agent %s", resp.Message)
689693
}
690694

691-
fmt.Printf("Rolled back agent [%s] to version %s\n", util.Accented(agentID), cmd.String("version"))
695+
fmt.Printf("Rolled back agent [%s] to version [%s]\n", util.Accented(agentID), util.Accented(cmd.String("version")))
692696

693697
return nil
694698
}
695699

696700
func getLogs(ctx context.Context, cmd *cli.Command) error {
697-
agentID, err := getAgentID(cmd, workingDir, tomlFilename)
701+
agentID, err := getAgentID(ctx, cmd, workingDir, tomlFilename)
698702
if err != nil {
699703
return err
700704
}
@@ -703,7 +707,7 @@ func getLogs(ctx context.Context, cmd *cli.Command) error {
703707
}
704708

705709
func deleteAgent(ctx context.Context, cmd *cli.Command) error {
706-
agentID, err := getAgentID(cmd, workingDir, tomlFilename)
710+
agentID, err := getAgentID(ctx, cmd, workingDir, tomlFilename)
707711
if err != nil {
708712
return err
709713
}
@@ -758,7 +762,7 @@ func deleteAgent(ctx context.Context, cmd *cli.Command) error {
758762
}
759763

760764
func listAgentVersions(ctx context.Context, cmd *cli.Command) error {
761-
agentID, err := getAgentID(cmd, workingDir, tomlFilename)
765+
agentID, err := getAgentID(ctx, cmd, workingDir, tomlFilename)
762766
if err != nil {
763767
return err
764768
}
@@ -778,14 +782,14 @@ func listAgentVersions(ctx context.Context, cmd *cli.Command) error {
778782
}
779783

780784
table := util.CreateTable().
781-
Headers("Version", "Current", "Created At")
785+
Headers("Version", "Current", "Deployed At")
782786

783-
// Sort versions by created date ascending
787+
// Sort versions by created date descending
784788
slices.SortFunc(versions.Versions, func(a, b *lkproto.AgentVersion) int {
785-
return a.CreatedAt.AsTime().Compare(b.CreatedAt.AsTime())
789+
return b.CreatedAt.AsTime().Compare(a.CreatedAt.AsTime())
786790
})
787791
for _, version := range versions.Versions {
788-
table.Row(version.Version, fmt.Sprintf("%t", version.Current), fmt.Sprintf("%v", version.CreatedAt.AsTime().Format(time.RFC3339)))
792+
table.Row(version.Version, fmt.Sprintf("%t", version.Current), version.CreatedAt.AsTime().Format(time.RFC3339))
789793
}
790794

791795
fmt.Println(table)
@@ -830,25 +834,34 @@ func listAgents(ctx context.Context, cmd *cli.Command) error {
830834
return nil
831835
}
832836

837+
slices.SortFunc(items, func(a, b *lkproto.AgentInfo) int {
838+
return b.DeployedAt.AsTime().Compare(a.DeployedAt.AsTime())
839+
})
840+
833841
var rows [][]string
834842
for _, agent := range items {
835843
var regions []string
836844
for _, regionalAgent := range agent.AgentDeployments {
837845
regions = append(regions, regionalAgent.Region)
838846
}
839-
rows = append(rows, []string{agent.AgentId, strings.Join(regions, ",")})
847+
rows = append(rows, []string{
848+
agent.AgentId,
849+
strings.Join(regions, ","),
850+
agent.Version,
851+
agent.DeployedAt.AsTime().Format(time.RFC3339),
852+
})
840853
}
841854

842855
t := util.CreateTable().
843-
Headers("ID", "Regions").
856+
Headers("ID", "Regions", "Version", "Deployed At").
844857
Rows(rows...)
845858

846859
fmt.Println(t)
847860
return nil
848861
}
849862

850863
func listAgentSecrets(ctx context.Context, cmd *cli.Command) error {
851-
agentID, err := getAgentID(cmd, workingDir, tomlFilename)
864+
agentID, err := getAgentID(ctx, cmd, workingDir, tomlFilename)
852865
if err != nil {
853866
return err
854867
}
@@ -883,7 +896,7 @@ func listAgentSecrets(ctx context.Context, cmd *cli.Command) error {
883896
}
884897

885898
func updateAgentSecrets(ctx context.Context, cmd *cli.Command) error {
886-
agentID, err := getAgentID(cmd, workingDir, tomlFilename)
899+
agentID, err := getAgentID(ctx, cmd, workingDir, tomlFilename)
887900
if err != nil {
888901
return err
889902
}
@@ -917,31 +930,76 @@ func updateAgentSecrets(ctx context.Context, cmd *cli.Command) error {
917930
return fmt.Errorf("failed to update agent secrets: %s", resp.Message)
918931
}
919932

920-
func getAgentID(cmd *cli.Command, agentDir string, tomlFileName string) (string, error) {
933+
func getAgentID(ctx context.Context, cmd *cli.Command, agentDir string, tomlFileName string) (string, error) {
921934
agentID := cmd.String("id")
922935
if agentID == "" {
923936
configExists, err := requireConfig(agentDir, tomlFileName)
924937
if err != nil && configExists {
925938
return "", err
926939
}
927-
if !configExists {
928-
return "", fmt.Errorf("config file [%s] required to update agent", tomlFileName)
929-
}
930-
if !lkConfig.HasAgent() {
931-
return "", fmt.Errorf("no agent config found in [%s]", tomlFileName)
932-
}
933940

934-
agentID = lkConfig.Agent.ID
941+
if configExists {
942+
if !lkConfig.HasAgent() {
943+
return "", fmt.Errorf("no agent config found in [%s]", tomlFilename)
944+
}
945+
agentID = lkConfig.Agent.ID
946+
} else {
947+
agentID, err = selectAgent(ctx, cmd)
948+
if err != nil {
949+
return "", err
950+
}
951+
}
935952
}
936953

937954
if agentID == "" {
938955
// shouldn't happen, but check to ensure we have a name
939-
return "", fmt.Errorf("agent ID or %s required", tomlFileName)
956+
return "", fmt.Errorf("agent ID or [%s] required", util.Accented(tomlFileName))
940957
}
941958

959+
fmt.Printf("Using agent [%s]\n", util.Accented(agentID))
960+
942961
return agentID, nil
943962
}
944963

964+
func selectAgent(ctx context.Context, _ *cli.Command) (string, error) {
965+
var agents *lkproto.ListAgentsResponse
966+
var err error
967+
968+
util.Await("No agent ID provided, selecting from available agents...", func() {
969+
agents, err = agentsClient.ListAgents(ctx, &lkproto.ListAgentsRequest{})
970+
})
971+
if err != nil {
972+
if twerr, ok := err.(twirp.Error); ok {
973+
if twerr.Code() == twirp.PermissionDenied {
974+
return "", fmt.Errorf("agent hosting is disabled for this project -- join the beta program here [%s]", cloudAgentsBetaSignupURL)
975+
}
976+
}
977+
return "", err
978+
}
979+
980+
if len(agents.Agents) == 0 {
981+
return "", fmt.Errorf("no agents found")
982+
}
983+
984+
var agentNames []huh.Option[string]
985+
for _, agent := range agents.Agents {
986+
name := agent.AgentId + " " + util.Dimmed("deployed "+agent.DeployedAt.AsTime().Format(time.RFC3339))
987+
agentNames = append(agentNames, huh.Option[string]{Key: name, Value: agent.AgentId})
988+
}
989+
990+
var selectedAgent string
991+
if err := huh.NewSelect[string]().
992+
Title("Select an agent").
993+
Options(agentNames...).
994+
Value(&selectedAgent).
995+
WithTheme(util.Theme).
996+
Run(); err != nil {
997+
return "", err
998+
}
999+
1000+
return selectedAgent, nil
1001+
}
1002+
9451003
func requireSecrets(_ context.Context, cmd *cli.Command, required, lazy bool) ([]*lkproto.AgentSecret, error) {
9461004
silent := cmd.Bool("silent")
9471005
secrets := make(map[string]*lkproto.AgentSecret)

cmd/lk/app.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -171,7 +171,7 @@ func selectProject(ctx context.Context, cmd *cli.Command) (context.Context, erro
171171
if cliConfig != nil && len(cliConfig.Projects) > 0 {
172172
var options []huh.Option[*config.ProjectConfig]
173173
for _, p := range cliConfig.Projects {
174-
options = append(options, huh.NewOption(p.Name+" ["+util.ExtractSubdomain(p.URL)+"]", &p))
174+
options = append(options, huh.NewOption(p.Name+" "+util.Dimmed(util.ExtractSubdomain(p.URL)), &p))
175175
}
176176
if err = huh.NewForm(
177177
huh.NewGroup(huh.NewSelect[*config.ProjectConfig]().

0 commit comments

Comments
 (0)