Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
f4543d5
Fix indentation and add comments to lint_register_apis.sh (#5628)
jmatth Dec 31, 2025
5f06bae
Fix trace test (#5621)
jmatth Dec 31, 2025
e179eec
RSDK-12890 - support default org and loc functionality in CLI (#5601)
stuqdog Jan 2, 2026
cc7a19e
Parameterize name (source) in Windows event logger (#5632)
aldenh-viam Jan 2, 2026
a943a58
APP-14417: Remove cloud build option (#5614)
allisonschiang Jan 2, 2026
75b65ff
RSDK-11831 — Make ReadImage call GetImages under the hood (#5337)
hexbabe Jan 5, 2026
ae7b4df
RSDK-11732 — Remove feature flag and make GetImages the main code pat…
hexbabe Jan 5, 2026
3106bd8
Select matching mimetype image if available
hexbabe Sep 30, 2025
58701d9
Remove ctx with value
hexbabe Sep 30, 2025
a9e7945
PR stacking 3 (#5625)
hexbabe Dec 31, 2025
a9192df
For PR stacking 2 (#5624)
hexbabe Dec 31, 2025
1fa1719
PR stacking 3 (#5625)
hexbabe Dec 31, 2025
737477c
Remove feature flag and make the GetImages path the main code path
hexbabe Dec 17, 2025
afd3927
Fix new decondeconfig logic with helper and test helper
hexbabe Dec 18, 2025
48d4f28
Make ReadImage call GetImages under the hood
hexbabe Sep 30, 2025
a49d0a9
Select matching mimetype image if available
hexbabe Sep 30, 2025
1465767
Fix affected tests
hexbabe Oct 1, 2025
c5e780f
Make lint
hexbabe Oct 1, 2025
d0f4bb3
Remove GetImage, Format from Go SDK/RDK
hexbabe Dec 31, 2025
afa8784
Remove lint errs
hexbabe Dec 31, 2025
3763960
Deprecate Image for webcam
hexbabe Dec 31, 2025
7dabb72
Remove duplicate mock func
hexbabe Dec 31, 2025
2f08785
Log deprecation, don't remove
hexbabe Jan 2, 2026
e9bc11b
Fix errors
hexbabe Jan 2, 2026
df384b6
Clean up
hexbabe Jan 5, 2026
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
71 changes: 52 additions & 19 deletions cli/app.go
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,6 @@ const (
moduleFlagVisibility = "visibility"
moduleFlagResourceType = "resource-type"
moduleFlagModelName = "model-name"
moduleFlagEnableCloud = "enable-cloud"
moduleFlagRegister = "register"
moduleFlagDryRun = "dry-run"
moduleFlagUpload = "upload"
Expand All @@ -100,7 +99,6 @@ const (
moduleBuildFlagGroupLogs = "group-logs"
moduleBuildRestartOnly = "restart-only"
moduleBuildFlagNoBuild = "no-build"
moduleBuildFlagCloudBuild = "cloud-build"
moduleBuildFlagCloudConfig = "cloud-config"
moduleBuildFlagID = "build-id"
moduleBuildFlagOAuthLink = "oauth-link"
Expand Down Expand Up @@ -469,6 +467,49 @@ var app = &cli.App{
},
},
Commands: []*cli.Command{
{
Name: "defaults",
Usage: "Set or clear default argument values",
UsageText: createUsageText("defaults", nil, false, false),
Subcommands: []*cli.Command{
{
Name: "set-org",
Usage: "Set default organization argument",
Flags: []cli.Flag{
&AliasStringFlag{
cli.StringFlag{
Name: generalFlagOrgID, // some functions require an ID, so we should do the same for defaults
Required: true,
},
},
},
Action: createCommandWithT(defaultsSetOrgAction),
},
{
Name: "clear-org",
Usage: "Clear default organization argument",
Action: createCommandWithT(defaultsClearOrgAction),
},
{
Name: "set-location",
Usage: "Set default location argument",
Flags: []cli.Flag{
&AliasStringFlag{
cli.StringFlag{
Name: generalFlagLocationID, // some functions require an ID, so we should do the same for defaults
Required: true,
},
},
},
Action: createCommandWithT(defaultsSetLocationAction),
},
{
Name: "clear-location",
Usage: "Clear default location argument",
Action: createCommandWithT(defaultsClearLocationAction),
},
},
},
{
Name: "traces",
Usage: "Work with viam-server traces",
Expand Down Expand Up @@ -1001,9 +1042,9 @@ Note: There is no progress meter while copying is in progress.
UsageText: createUsageText("organizations api-key create", []string{generalFlagOrgID}, true, false),
Flags: []cli.Flag{
&cli.StringFlag{
Name: generalFlagOrgID,
Required: true,
Usage: "the org to create an api key for",
Name: generalFlagOrgID,
Usage: "the org to create an api key for",
DefaultText: "the default org set with `viam defaults set-org`",
},
&cli.StringFlag{
Name: generalFlagName,
Expand Down Expand Up @@ -1034,7 +1075,7 @@ Note: There is no progress meter while copying is in progress.
cli.StringFlag{
Name: generalFlagOrganization,
Aliases: []string{generalFlagAliasOrg, generalFlagOrgID, generalFlagAliasOrgName},
DefaultText: "first organization alphabetically",
DefaultText: "the org set by `viam defaults set-org` if it exists, else the first one alphabetically",
},
},
},
Expand All @@ -1051,9 +1092,9 @@ Note: There is no progress meter while copying is in progress.
UsageText: createUsageText("locations api-key create", []string{generalFlagLocationID}, true, false),
Flags: []cli.Flag{
&cli.StringFlag{
Name: generalFlagLocationID,
Required: true,
Usage: "id of the location to create an api-key for",
Name: generalFlagLocationID,
Usage: "id of the location to create an api-key for",
DefaultText: "the default location set with `viam defaults set-location`",
},
&cli.StringFlag{
Name: generalFlagName,
Expand Down Expand Up @@ -2318,14 +2359,14 @@ Note: There is no progress meter while copying is in progress.
cli.StringFlag{
Name: generalFlagOrganization,
Aliases: []string{generalFlagAliasOrg, generalFlagOrgID, generalFlagAliasOrgName},
DefaultText: "first organization alphabetically",
DefaultText: "the default org argument if set, else the first organization alphabetically",
},
},
&AliasStringFlag{
cli.StringFlag{
Name: generalFlagLocation,
Aliases: []string{generalFlagLocationID, generalFlagAliasLocationName},
DefaultText: "first location alphabetically",
DefaultText: "the default location argument if set, else the first location alphabetically",
},
},
&cli.BoolFlag{
Expand Down Expand Up @@ -2950,10 +2991,6 @@ After creation, use 'viam module update' to push your new module to app.viam.com
Usage: "name for the particular resource subtype implementation." +
" for example, a sensor model that detects moisture might be named 'moisture'",
},
&cli.BoolFlag{
Name: moduleFlagEnableCloud,
Usage: "generate Github workflows to build module",
},
&cli.BoolFlag{
Name: moduleFlagRegister,
Usage: "register module with Viam to associate with your organization",
Expand Down Expand Up @@ -3010,10 +3047,6 @@ viam module upload --version "0.1.0" --platform "linux/amd64" --upload "./bin/my
Example uploading a whole directory:
viam module upload --version "0.1.0" --platform "linux/amd64" --upload "./bin"
(this example requires the entrypoint in the meta.json to be inside the bin directory like "./bin/[your path here]")

Example uploading a custom tarball of your module:
tar -czf packaged-module.tar.gz ./src requirements.txt run.sh
viam module upload --version "0.1.0" --platform "linux/amd64" --upload "packaged-module.tar.gz"
`,
UsageText: createUsageText("module upload", []string{generalFlagVersion, moduleFlagPlatform, moduleFlagUpload}, true, false),
Flags: []cli.Flag{
Expand Down
37 changes: 33 additions & 4 deletions cli/auth.go
Original file line number Diff line number Diff line change
Expand Up @@ -313,7 +313,13 @@ func OrganizationsAPIKeyCreateAction(cCtx *cli.Context, args organizationsAPIKey
}

func (c *viamClient) organizationsAPIKeyCreateAction(cCtx *cli.Context, args organizationsAPIKeyCreateArgs) error {
var err error
orgID := args.OrgID
if orgID == "" {
if orgID, err = getDefaultOrg(cCtx); err != nil {
return errors.New("must specify an org ID to create an API key for")
}
}
keyName := args.Name
if keyName == "" {
keyName = c.generateDefaultKeyName()
Expand Down Expand Up @@ -367,6 +373,10 @@ func LocationAPIKeyCreateAction(cCtx *cli.Context, args locationAPIKeyCreateArgs

func (c *viamClient) locationAPIKeyCreateAction(cCtx *cli.Context, args locationAPIKeyCreateArgs) error {
locationID := args.LocationID
if locationID == "" {
//nolint:errcheck // if there's an error we just fallback to the old logic
locationID, _ = getDefaultLocation(cCtx)
}
orgID := args.OrgID
keyName := args.Name

Expand Down Expand Up @@ -480,6 +490,11 @@ func (c *viamClient) ensureLoggedInInner() error {
return nil
}

globalArgs, err := getGlobalArgs(c.c)
if err != nil {
return err
}

if c.conf.Auth == nil {
return errors.New("not logged in: run the following command to login:\n\tviam login")
}
Expand All @@ -494,10 +509,7 @@ func (c *viamClient) ensureLoggedInInner() error {
// expired.
newToken, err := c.authFlow.refreshToken(c.c.Context, authToken)
if err != nil {
debugFlag := false
if globalArgs, err := getGlobalArgs(c.c); err == nil {
debugFlag = globalArgs.Debug
}
debugFlag := globalArgs.Debug
debugf(c.c.App.Writer, debugFlag, "Token refresh error: %v", err)
utils.UncheckedError(c.logout()) // clear cache if failed to refresh
return errors.New("error while refreshing token, logging out. Please log in again")
Expand Down Expand Up @@ -534,6 +546,23 @@ func (c *viamClient) ensureLoggedInInner() error {
c.mlInferenceClient = mlinferencepb.NewMLInferenceServiceClient(conn)
c.buildClient = buildpb.NewBuildServiceClient(conn)

// if there's no default org and we're in a profile, there should only be the one org
// so we can automatically set that as the default
if c.conf.DefaultOrg == "" {
whichProfile, _ := whichProfile(globalArgs)
if !globalArgs.DisableProfiles && whichProfile != nil {
orgs, err := c.listOrganizations()
if err != nil && !globalArgs.Quiet {
warningf(c.c.App.ErrWriter, "no default org set for profile and unable to infer one")
// this should always be true for now, but might change if/when user level API keys exist
} else if len(orgs) == 1 {
if err = c.writeDefaultOrg(c.c, c.conf, orgs[0].Id); err != nil && !globalArgs.Quiet {
warningf(c.c.App.ErrWriter, "unable to set default org for profile %s", *whichProfile)
}
}
}
}

return nil
}

Expand Down
2 changes: 1 addition & 1 deletion cli/auth_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ func TestAPIKeyCreateAction(t *testing.T) {
asc := &inject.AppServiceClient{
CreateKeyFunc: createKeyFunc,
}
cCtx, ac, out, errOut := setup(asc, nil, nil, nil, "token")
cCtx, ac, out, errOut := setup(asc, nil, nil, map[string]any{"org-id": "my-org"}, "token")

test.That(t, ac.organizationsAPIKeyCreateAction(cCtx, parseStructFromCtx[organizationsAPIKeyCreateArgs](cCtx)), test.ShouldBeNil)
test.That(t, len(errOut.messages), test.ShouldEqual, 0)
Expand Down
14 changes: 13 additions & 1 deletion cli/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -605,7 +605,11 @@ func ListLocationsAction(c *cli.Context, args listLocationsArgs) error {
if orgStr == "" {
orgStr = c.Args().First()
}
if orgStr == "" {
if orgStr == "" { // first, see if we have a default set
//nolint:errcheck // if there's an error then we'll just fall back to the old logic
orgStr, _ = getDefaultOrg(c)
}
if orgStr == "" { // if there's still not an orgStr, then we can fall back to the alphabetically first
orgs, err := client.listOrganizations()
if err != nil {
return errors.Wrap(err, "could not list organizations")
Expand Down Expand Up @@ -951,6 +955,14 @@ func ListRobotsAction(c *cli.Context, args listRobotsActionArgs) error {
}
orgStr := args.Organization
locStr := args.Location
if orgStr == "" {
//nolint:errcheck // if there's an error we fallback to old logic
orgStr, _ = getDefaultOrg(c)
}
if locStr == "" {
//nolint:errcheck // if there's an error we fallback to old logic
locStr, _ = getDefaultLocation(c)
}
if args.All {
return client.listAllRobotsInOrg(c, orgStr)
}
Expand Down
2 changes: 2 additions & 0 deletions cli/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,8 @@ type Config struct {
LastUpdateCheck string `json:"last_update_check"`
LatestVersion string `json:"latest_version"`
profile string
DefaultOrg string `json:"default_org"`
DefaultLocation string `json:"default_location"`
}

func (conf *Config) tryUnmarshallWithToken(configBytes []byte) error {
Expand Down
Loading
Loading