Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 15 additions & 6 deletions docs/runware_serverless_apps_workers.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,11 @@ List and inspect workers for a serverless application

List workers observed for an application.

The default page is the active version only. An application with no active
version therefore answers an empty default page: it has no pinned version, not
that it has no workers. Pass --version all to include every version, or
--version <id> to scope to one.

The default state is all: terminal stopped rows stay in the page until they
are purged. Pass --state live to drop them. --state live with --status stopped
is refused by the API (422), because an empty page would read as "this app
Expand All @@ -18,9 +23,12 @@ runware serverless apps workers <appId> [flags]
### Examples

```
# list workers for an application
# list workers for the active version
runware serverless apps workers my-app

# include workers from every version
runware serverless apps workers my-app --version all

# omit terminal stopped rows
runware serverless apps workers my-app --state live

Expand All @@ -34,11 +42,12 @@ runware serverless apps workers <appId> [flags]
### Options

```
--cursor string Pagination cursor from a previous nextCursor
-h, --help help for workers
--limit int Maximum number of workers to return (1-100)
--state string Include stopped rows (all, the API default) or drop them (live)
--status string Filter by status (ready, busy, pending, …)
--cursor string Pagination cursor from a previous nextCursor
-h, --help help for workers
--limit int Maximum number of workers to return (1-100)
--state string Include stopped rows (all, the API default) or drop them (live)
--status string Filter by status (ready, busy, pending, …)
--version string Scope to a version ID, or all (default: the active version)
```

### Options inherited from parent commands
Expand Down
49 changes: 40 additions & 9 deletions internal/cmd/serverless/apps.go
Original file line number Diff line number Diff line change
Expand Up @@ -287,24 +287,33 @@ for worker output.`,

func newAppsWorkersCmd(logger *log.Logger) *cobra.Command {
var (
limit int
cursor string
status string
state string
limit int
cursor string
status string
state string
version string
)

cmd := &cobra.Command{
Use: "workers <appId>",
Short: "List and inspect workers for a serverless application",
Long: `List workers observed for an application.

The default page is the active version only. An application with no active
version therefore answers an empty default page: it has no pinned version, not
that it has no workers. Pass --version all to include every version, or
--version <id> to scope to one.

The default state is all: terminal stopped rows stay in the page until they
are purged. Pass --state live to drop them. --state live with --status stopped
is refused by the API (422), because an empty page would read as "this app
has never run".`,
Example: ` # list workers for an application
Example: ` # list workers for the active version
runware serverless apps workers my-app

# include workers from every version
runware serverless apps workers my-app --version all

# omit terminal stopped rows
runware serverless apps workers my-app --state live

Expand All @@ -327,12 +336,17 @@ has never run".`,
if err != nil {
return err
}
versionVal, err := parseWorkersVersion(version)
if err != nil {
return err
}
var params *serverlessapi.ListWorkersParams
if limit > 0 || cursor != "" || status != "" || state != "" {
if limit > 0 || cursor != "" || status != "" || state != "" || versionVal != "" {
params = &serverlessapi.ListWorkersParams{}
params.Limit, params.Cursor = listPageParams(limit, cursor)
params.Status = statusVal
params.State = stateVal
params.VersionId = optionalStringPtr(versionVal)
}

spin := cmdutil.NewSpinner(fmt.Sprintf("Fetching workers for %s...", id))
Expand All @@ -346,14 +360,15 @@ has never run".`,
}
spin.Stop()

return printPage(cmdutil.FormatFor(cmd), page, workersResult(page.Data), cmd.ErrOrStderr(), extraWorkersCursorFlags(state, status))
return printPage(cmdutil.FormatFor(cmd), page, workersResult(page.Data), cmd.ErrOrStderr(), extraWorkersCursorFlags(state, status, versionVal))
},
}

cmd.Flags().IntVar(&limit, "limit", 0, "Maximum number of workers to return (1-100)")
cmd.Flags().StringVar(&cursor, "cursor", "", "Pagination cursor from a previous nextCursor")
cmd.Flags().StringVar(&status, "status", "", "Filter by status (ready, busy, pending, …)")
cmd.Flags().StringVar(&state, "state", "", "Include stopped rows (all, the API default) or drop them (live)")
cmd.Flags().StringVar(&version, "version", "", "Scope to a version ID, or all (default: the active version)")
Comment thread
Ryank90 marked this conversation as resolved.
cmd.AddCommand(newAppsWorkersShowCmd(logger))
return cmd
}
Expand Down Expand Up @@ -454,10 +469,26 @@ func extraStatusCursorFlag(value string) string {
return strings.Join(appendFlag(nil, "--status", value), " ")
}

// parseWorkersVersion accepts "all" (any case) or a version UUID. A typo
// fails here instead of as a 4xx from the API.
func parseWorkersVersion(version string) (string, error) {
if version == "" {
return "", nil
}
if strings.EqualFold(version, "all") {
return "all", nil
}
if _, err := uuid.Parse(version); err != nil {
return "", fmt.Errorf("--version must be a version ID or all")
}
return version, nil
}

// extraWorkersCursorFlags repeats workers list filters a next-page --cursor is bound to.
func extraWorkersCursorFlags(state, status string) string {
func extraWorkersCursorFlags(state, status, version string) string {
parts := appendFlag(nil, "--state", state)
return strings.Join(appendFlag(parts, "--status", status), " ")
parts = appendFlag(parts, "--status", status)
return strings.Join(appendFlag(parts, "--version", version), " ")
}

func extraTypeCursorFlag(value string) string {
Expand Down
34 changes: 30 additions & 4 deletions internal/cmd/serverless/display_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -188,20 +188,46 @@ func TestExtraStatusCursorFlag(t *testing.T) {
}

func TestExtraWorkersCursorFlags(t *testing.T) {
if got := extraWorkersCursorFlags("live", "ready"); got != "--state live --status ready" {
if got := extraWorkersCursorFlags("live", "ready", ""); got != "--state live --status ready" {
t.Fatalf("both: got %q", got)
}
if got := extraWorkersCursorFlags("live", ""); got != "--state live" {
if got := extraWorkersCursorFlags("live", "", ""); got != "--state live" {
t.Fatalf("state only: got %q", got)
}
if got := extraWorkersCursorFlags("", "ready"); got != "--status ready" {
if got := extraWorkersCursorFlags("", "ready", ""); got != "--status ready" {
t.Fatalf("status only: got %q", got)
}
if got := extraWorkersCursorFlags("", ""); got != "" {
if got := extraWorkersCursorFlags("", "", "all"); got != "--version all" {
Comment thread
Ryank90 marked this conversation as resolved.
t.Fatalf("version only: got %q", got)
}
if got := extraWorkersCursorFlags("live", "ready", "all"); got != "--state live --status ready --version all" {
t.Fatalf("all three: got %q", got)
}
if got := extraWorkersCursorFlags("", "", ""); got != "" {
t.Fatalf("empty: got %q", got)
}
}

func TestParseWorkersVersion(t *testing.T) {
got, err := parseWorkersVersion("")
if err != nil || got != "" {
t.Fatalf("empty: got=%q err=%v", got, err)
}
got, err = parseWorkersVersion("ALL")
if err != nil || got != "all" {
t.Fatalf("all: got=%q err=%v", got, err)
}
id := "22222222-2222-2222-2222-222222222222"
got, err = parseWorkersVersion(id)
if err != nil || got != id {
t.Fatalf("uuid: got=%q err=%v", got, err)
}
_, err = parseWorkersVersion("nope")
if err == nil || !strings.Contains(err.Error(), "version ID or all") {
t.Fatalf("typo: %v", err)
}
}

func TestParseAppEventType(t *testing.T) {
got, err := parseAppEventType("")
if err != nil || got != nil {
Expand Down
Loading