-
Notifications
You must be signed in to change notification settings - Fork 3
feat(pages/cli): Added "Fields" page to CLI docs #182
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
Draft
danielvallance
wants to merge
1
commit into
prod-staging
Choose a base branch
from
danielvallance/cli_field_section
base: prod-staging
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
+380
−167
Draft
Changes from all commits
Commits
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
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
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,376 @@ | ||
| --- | ||
| title: Fields | ||
| description: Display, sort, filter, and edit resource fields in the unikraft CLI | ||
| navigation_icon: table | ||
| --- | ||
|
|
||
| Every resource in the `unikraft` CLI (instances, images, services, volumes, and so on) is described by a set of **fields**. | ||
|
danielvallance marked this conversation as resolved.
|
||
| Fields are the named pieces of data the platform stores about a resource, such as its `name`, `state`, `image`, or memory `resources`. | ||
| The same fields power table output, sorting, filtering, and editing, so once you learn a resource's field names you can use them everywhere. | ||
|
|
||
| This page covers what fields are, how to control which fields are shown, how to sort and filter on them, and how to edit them with `edit`. | ||
|
danielvallance marked this conversation as resolved.
|
||
|
|
||
| ## The field model | ||
|
|
||
| To see the full field model for a resource, inspect it with `get`. | ||
| The output is a tree of fields, where some fields are scalars and others are nested objects or lists. | ||
|
danielvallance marked this conversation as resolved.
|
||
|
|
||
| ```console | ||
| $ unikraft instance get httpserver-rust175-tokio-ngh8r | ||
| metro: fra | ||
| name: httpserver-rust175-tokio-ngh8r | ||
| uuid: 78ad8c05-ed7a-4886-abd3-07613dce7c28 | ||
| state: standby | ||
| image: <my-org>/httpserver-rust175-tokio | ||
| resources: | ||
| memory: 256MiB | ||
| vcpus: 1 | ||
| service: | ||
| name: nameless-silence-donj1yl2 | ||
| uuid: cd2910d2-b709-410c-9e04-f5539a7d020a | ||
| domains: | ||
| - fqdn: nameless-silence-donj1yl2.fra.unikraft.app | ||
| networks: | ||
| - uuid: d8700d21-63c0-448a-806d-54014584b082 | ||
| private-ip: 10.0.0.25 | ||
| mac: 12:b0:0a:00:00:19 | ||
| timestamps: | ||
| created: 1 day ago | ||
| scale-to-zero: | ||
| enabled: true | ||
| policy: on | ||
| cooldown-time: 1s | ||
| stop: | ||
| reason: platform stop | ||
| exit-code: 1 | ||
| ``` | ||
|
|
||
| ### Field paths | ||
|
|
||
| Nested fields are addressed with dot-separated paths. | ||
|
danielvallance marked this conversation as resolved.
|
||
| A path walks down the tree, one field name per segment. | ||
|
|
||
| ``` | ||
| name # top-level field | ||
| resources.memory # nested field | ||
| service.name # nested field | ||
| timestamps.created # nested field | ||
| networks.0.private-ip # array element by zero-based index | ||
| ``` | ||
|
|
||
| These same paths are used by `--field`, `--sort`, `--filter`, and the `edit` flags described below. | ||
|
danielvallance marked this conversation as resolved.
|
||
|
|
||
| ## Choosing which fields to display | ||
|
|
||
| Listing resources prints a default set of columns. | ||
| Use `--field` (short form `-f`) to select which fields are displayed. | ||
|
danielvallance marked this conversation as resolved.
|
||
|
|
||
| When you pass a parent field, the CLI expands it into a column for each of its child fields. | ||
|
|
||
| ```console | ||
| $ unikraft instance ls --field service | ||
| NAME UUID FQDN | ||
| falling-sky-k20dl7a7 32b81f2f-8767-4961-a55f-520e7462395b falling-sky-k20dl7a7.fra.unikraft.app | ||
| nameless-silence-donj1yl2 cd2910d2-b709-410c-9e04-f5539a7d020a nameless-silence-donj1yl2.fra.unikraf… | ||
| ``` | ||
|
|
||
| Pass a specific field path to display just that one value. | ||
|
danielvallance marked this conversation as resolved.
|
||
|
|
||
| ```console | ||
| $ unikraft instance ls --field service.name | ||
| NAME | ||
| falling-sky-k20dl7a7 | ||
| nameless-silence-donj1yl2 | ||
| ``` | ||
|
|
||
| You can repeat `--field` to add several fields at once. | ||
|
danielvallance marked this conversation as resolved.
|
||
|
|
||
| ```console | ||
| $ unikraft instance ls --field service.name --field resources.memory | ||
| NAME MEMORY | ||
| falling-sky-k20dl7a7 256MiB | ||
| nameless-silence-donj1yl2 256MiB | ||
| ``` | ||
|
|
||
| ## Sorting | ||
|
|
||
| Use `--sort` with a field path to order the output by that field. | ||
|
|
||
| ```console | ||
| $ unikraft instance ls --sort timestamps.created | ||
| METRO NAME STATE IMAGE ARGS MEMORY VCPUS FQDN CREATED | ||
| fra httpserver-rust175-to… standby <my-org>/httpserver-rust17… 256MiB 2 nameless-silence-donj1… 1 day ago | ||
| fra nginx-fj704 running <my-org>/nginx 256MiB 1 falling-sky-k20dl7a7.f… 1 hour ago | ||
| ``` | ||
|
|
||
| ## Filtering | ||
|
|
||
| Use `--filter` with a field path and an operator to show only the resources that match. | ||
|
|
||
| ```console | ||
| $ unikraft instance ls --filter state==standby | ||
| METRO NAME STATE IMAGE ARGS MEMORY VCPUS FQDN CREATED | ||
| fra httpserver-rust175-tok… standby <my-org>/httpserver-rust17… 256MiB 2 nameless-silence-donj1… 1 day ago | ||
| ``` | ||
|
|
||
| `--filter` is available on `list`, `wait`, and `delete` subcommands throughout the `unikraft` CLI. | ||
| It isn't available in the legacy `kraft cloud` CLI. | ||
|
|
||
| The filter expression language supports nested paths, wildcards, regular expressions, and combining multiple expressions. | ||
|
danielvallance marked this conversation as resolved.
|
||
| See the [filter expression reference](#filter-expression-reference) for the full grammar, operators, and examples. | ||
|
|
||
| ## The `--until` flag | ||
|
|
||
| The `--until` flag uses the same expression syntax as `--filter`. | ||
| It's available on `wait` subcommands (and aliases to `--filter` there). | ||
| The command polls until every targeted resource matches the expression. | ||
|
|
||
| ```bash | ||
| unikraft instance wait my-instance --until state==running | ||
| ``` | ||
|
|
||
| ## Editing fields | ||
|
|
||
| The `edit` command modifies a resource's fields in place. | ||
| It prints a diff of the change, where `+` lines are additions and `-`/`+` pairs show a value being replaced. | ||
|
danielvallance marked this conversation as resolved.
|
||
|
|
||
| ### Setting a field with `--set` | ||
|
|
||
| Use `--set <path>=<value>` to set or replace a field. | ||
| Setting a field that doesn't exist yet creates it, including any parent fields. | ||
|
|
||
| ```console | ||
| $ unikraft instance edit httpserver-rust175-tokio-ngh8r --set runtime.env=MYSECRET=secret | ||
| metro: fra | ||
| name: httpserver-rust175-tokio-ngh8r | ||
| uuid: 78ad8c05-ed7a-4886-abd3-07613dce7c28 | ||
| state: standby | ||
| image: <my-org>/httpserver-rust175-tokio | ||
| + runtime: | ||
| + env: | ||
| + MYSECRET: * | ||
| resources: | ||
| memory: 256MiB | ||
| vcpus: 1 | ||
| ... | ||
| ``` | ||
|
|
||
| ### Adding and removing with `--add` and `--del` | ||
|
|
||
| Use `--add <name>=<value>` to append to a list or map field, and `--del <name>=<value>` to remove an entry from one. | ||
|
|
||
| For example, remove a previously set environment variable: | ||
|
danielvallance marked this conversation as resolved.
|
||
|
|
||
| ```console | ||
| $ unikraft instance edit httpserver-rust175-tokio-ngh8r --del runtime.env=MYSECRET | ||
| metro: fra | ||
| name: httpserver-rust175-tokio-ngh8r | ||
| uuid: 78ad8c05-ed7a-4886-abd3-07613dce7c28 | ||
| state: standby | ||
| image: <my-org>/httpserver-rust175-tokio | ||
| - runtime: | ||
| - env: | ||
| - MYSECRET: * | ||
| resources: | ||
| memory: 256MiB | ||
| vcpus: 2 | ||
| service: | ||
| name: nameless-silence-donj1yl2 | ||
| uuid: cd2910d2-b709-410c-9e04-f5539a7d020a | ||
| domains: | ||
| - fqdn: nameless-silence-donj1yl2.fra.unikraft.app | ||
| networks: | ||
| - uuid: d8700d21-63c0-448a-806d-54014584b082 | ||
| private-ip: 10.0.0.25 | ||
| mac: 12:b0:0a:00:00:19 | ||
| timestamps: | ||
| created: 1 day ago | ||
| scale-to-zero: | ||
| enabled: true | ||
| policy: on | ||
| cooldown-time: 1s | ||
| stop: | ||
| reason: platform stop | ||
| exit-code: 1 | ||
| ``` | ||
|
|
||
| The `--add` flag works the same way, appending the given value instead of removing it. | ||
| You can combine multiple `--set`, `--add`, and `--del` flags in a single `edit` invocation. | ||
|
danielvallance marked this conversation as resolved.
|
||
|
|
||
| ## Visual editing | ||
|
|
||
| Pass `--visual` to open the resource in your editor and modify its fields interactively. | ||
|
danielvallance marked this conversation as resolved.
|
||
| The CLI launches the program named by the `$VISUAL` or `$EDITOR` environment variable. | ||
|
|
||
| ```bash | ||
| export EDITOR=vim | ||
| unikraft instance edit httpserver-rust175-tokio-ngh8r --visual | ||
| ``` | ||
|
|
||
| If neither variable is set, the command fails with `no editor set: please set $VISUAL or $EDITOR`. | ||
|
danielvallance marked this conversation as resolved.
|
||
|
|
||
| When you save and close the editor, the CLI applies your changes and prints the resulting diff. | ||
|
|
||
| ```console | ||
| $ unikraft instance edit httpserver-rust175-tokio-ngh8r --visual | ||
| metro: fra | ||
| name: httpserver-rust175-tokio-ngh8r | ||
| uuid: 78ad8c05-ed7a-4886-abd3-07613dce7c28 | ||
| state: standby | ||
| image: demo/httpserver-rust175-tokio | ||
| runtime: | ||
| env: | ||
| MYSECRET: * | ||
| resources: | ||
| memory: 256MiB | ||
| - vcpus: 1 | ||
| + vcpus: 2 | ||
| ... | ||
| ``` | ||
|
|
||
| ## Filter expression reference | ||
|
|
||
| The `--filter` and `--until` flags accept filter expressions that match resources based on their field values. | ||
| The syntax extends the [containerd filter grammar](https://github.com/containerd/containerd/blob/main/pkg/filters/filter.go) with negated regex matching, wildcards, and alternative quoting. | ||
|
|
||
| ### Grammar | ||
|
|
||
| ``` | ||
| expression := selector ( "," selector )* | ||
| selector := fieldpath [ operator value ] | ||
| | fieldpath? "*" ( "." selector | operator value )? | ||
| fieldpath := field ( "." field )* | ||
| field := quoted-string | identifier | ||
| identifier := [A-Za-z] [A-Za-z0-9_]+ | ||
| operator := "=" | "==" | "!=" | "!==" | "~=" | "!~=" | ||
| value := quoted-string | regex-string | unquoted-string | ||
| ``` | ||
|
|
||
| A **quoted-string** uses Go string syntax (double quotes with standard | ||
| backslash escapes: `\n`, `\t`, `\\`, `\"`, `\xNN`, `\uNNNN`, `\UNNNNNNNN`, | ||
| octal `\NNN`). | ||
|
|
||
| A **regex-string** may only appear after `~=` or `!~=`. | ||
| You can delimit it with `/` or `|` instead of `"`, which is convenient when the pattern contains double-quotes or backslashes (for example, `name~=/[abc]{0,2}/` or `path~=|foo/bar|`). | ||
|
|
||
| An **unquoted-string** is any run of non-whitespace, non-comma characters. | ||
|
|
||
| ### Operators | ||
|
|
||
| | Operator | Alias | Description | Example | | ||
| | -------- | ----- | --------------------------------- | ----------------- | | ||
| | `==` | `=` | Equals | `state==running` | | ||
| | `!=` | `!==` | Not equals | `state!=stopped` | | ||
| | `~=` | | Matches regular expression | `name~="^web-.*"` | | ||
| | `!~=` | | Doesn't match regular expression | `name!~="^test-"` | | ||
| | _(none)_ | | Field is present and non-empty | `description` | | ||
|
|
||
| Regular expressions use Go `regexp` syntax. | ||
|
|
||
| ### Field paths in expressions | ||
|
|
||
| Fields use their output name (the name shown in `kv` or `table` output). | ||
| Nested fields use dot-separated paths. | ||
|
|
||
| ``` | ||
| name # top-level field | ||
| settings.bar # nested field | ||
| timestamps.created-at # hyphenated field name | ||
| labels."my complex key" # quoted path segment | ||
| ``` | ||
|
|
||
| #### Wildcards | ||
|
|
||
| A `*` in a field path iterates over all entries of a map or array field. | ||
| The wildcard can appear at any level, and you can chain wildcards. | ||
|
|
||
| ``` | ||
| labels.* # true if any label entry exists | ||
| labels.*==value # true if any label entry equals "value" | ||
| authors.*.email==a@b.com # true if any author's email matches | ||
| nested.*.*==true # double wildcard | ||
| ``` | ||
|
|
||
| **Negation semantics with wildcards:** positive operators (`==`, `~=`) match if | ||
| **any** entry meets the condition. | ||
| Negated operators (`!=`, `!~=`) match only if **all** entries meet the condition (that is, no entry matches the negated pattern). | ||
|
|
||
| #### Indexed access | ||
|
|
||
| You can also access array elements by zero-based numeric index. | ||
|
|
||
| ``` | ||
| authors.0.name==Alice # first author's name | ||
| authors.1.email==b@b.com # second author's email | ||
| ``` | ||
|
|
||
| ### Combining expressions | ||
|
|
||
| #### And (comma-separated within one flag) | ||
|
|
||
| Comma-separated selectors within a single `--filter` value must **all** match for the filter to include a resource. | ||
|
|
||
| ```bash | ||
| --filter 'state==running,name~="^web"' | ||
| ``` | ||
|
|
||
| #### Or (repeated flags) | ||
|
|
||
| When you specify `--filter` several times, the filter includes a resource if it matches **any** of the expressions. | ||
|
|
||
| ```bash | ||
| --filter 'state==running' --filter 'state==stopped' | ||
| ``` | ||
|
|
||
| #### Combining both operators | ||
|
|
||
| The two mechanisms compose: | ||
|
|
||
| ```bash | ||
| --filter 'state==running,metro==fra0' --filter 'state==stopped,metro==was1' | ||
| ``` | ||
|
|
||
| This matches resources that are (running in fra0) **or** (stopped in was1). | ||
|
|
||
| ### Special fields | ||
|
|
||
| The `metro` field receives special handling: when present in a filter, it restricts which metros the CLI queries rather than filtering results after the fact. | ||
| This means `--filter metro==fra0` avoids fetching data from other metros entirely. | ||
|
|
||
| ### Examples | ||
|
|
||
| ```bash | ||
| # List only running instances | ||
| unikraft instance list --filter state==running | ||
|
|
||
| # List instances NOT in the "stopped" state | ||
| unikraft instance list --filter 'state!=stopped' | ||
|
|
||
| # List images whose ref contains "nginx" | ||
| unikraft image list --filter 'ref~="/nginx"' | ||
|
|
||
| # Exclude images matching a pattern | ||
| unikraft image list --filter 'ref!~="test"' | ||
|
|
||
| # Regex with slash delimiters (avoids escaping issues) | ||
| unikraft image list --filter 'ref~=/nginx[0-9]{1,3}/' | ||
|
|
||
| # Wait for an instance to reach the running state | ||
| unikraft instance wait my-instance --until state==running | ||
|
|
||
| # Delete all stopped instances (with confirmation) | ||
| unikraft instance remove --filter state==stopped | ||
|
|
||
| # Combine filters: running instances in fra0, OR stopped in was1 | ||
| unikraft instance list --filter 'state==running,metro==fra0' \ | ||
| --filter 'state==stopped,metro==was1' | ||
|
|
||
| # Filter on nested fields | ||
| unikraft instance list --filter 'settings.autoscale==true' | ||
|
|
||
| # Filter using array wildcard | ||
| unikraft instance list --filter 'volumes.*.name==data' | ||
|
|
||
| # Check that no label matches a pattern (all must satisfy !=) | ||
| unikraft instance list --filter 'labels.*!=temporary' | ||
| ``` | ||
Oops, something went wrong.
Oops, something went wrong.
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.