Skip to content

Commit

Permalink
add mount support
Browse files Browse the repository at this point in the history
  • Loading branch information
pmenglund committed Nov 9, 2023
1 parent 83799d5 commit 8f3cd91
Show file tree
Hide file tree
Showing 9 changed files with 311 additions and 50 deletions.
171 changes: 171 additions & 0 deletions cmd/mount.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,171 @@
package cmd

import (
"fmt"
"github.com/rockset/cli/completion"
"github.com/rockset/cli/config"
"github.com/rockset/cli/format"
"github.com/rockset/cli/lookup"
"github.com/rockset/cli/sort"
"github.com/rockset/rockset-go-client/openapi"
"github.com/spf13/cobra"
"strings"
)

func NewListMountsCmd() *cobra.Command {
cmd := cobra.Command{
Use: "mounts [NAME | ID]",
Aliases: []string{"m", "mount"},
Args: cobra.ExactArgs(1),
Short: "list collection mounts for a virtual instance",
Annotations: group("mount"),
ValidArgsFunction: completion.VirtualInstance(Version),
RunE: func(cmd *cobra.Command, args []string) error {
ctx := cmd.Context()
rs, err := config.Client(cmd, Version)
if err != nil {
return err
}

id, err := lookup.VirtualInstanceNameOrIDtoID(ctx, rs, args[0])
if err != nil {
return err
}

mounts, err := rs.ListCollectionMounts(ctx, id)
if err != nil {
return err
}

ms := sort.Multi[openapi.CollectionMount]{
LessFuncs: []func(p1 *openapi.CollectionMount, p2 *openapi.CollectionMount) bool{
sort.ByCollectionPath[*openapi.CollectionMount],
},
}
ms.Sort(mounts)

return formatList(cmd, format.ToInterfaceArray(mounts))
},
}

return &cmd
}

func NewGetMountCmd() *cobra.Command {
cmd := cobra.Command{
Use: "mount PATH",
Aliases: []string{"m"},
Args: cobra.ExactArgs(1),
Short: "get collection mount information",
Annotations: group("mount"),
ValidArgsFunction: completion.CollectionMount(Version),
RunE: func(cmd *cobra.Command, args []string) error {
ctx := cmd.Context()
rs, err := config.Client(cmd, Version)
if err != nil {
return err
}

vi, _ := cmd.Flags().GetString("vi")
id, err := lookup.VirtualInstanceNameOrIDtoID(ctx, rs, vi)
if err != nil {
return err
}

mount, err := rs.GetCollectionMount(ctx, id, args[0])
if err != nil {
return err
}

return formatOne(cmd, mount)
},
}

cmd.Flags().String("vi", "", "virtual instance id or name")
cmd.MarkFlagRequired("vi")
_ = cmd.RegisterFlagCompletionFunc("vi", completion.VirtualInstance(Version))

return &cmd
}

func NewMountCollectionsCmd() *cobra.Command {
cmd := cobra.Command{
Use: "mount PATH",
Aliases: []string{"m"},
Args: cobra.MinimumNArgs(1),
Short: "mount one or more collections on a virtual instance",
Annotations: group("mount"),
RunE: func(cmd *cobra.Command, args []string) error {
ctx := cmd.Context()
rs, err := config.Client(cmd, Version)
if err != nil {
return err
}

vi, _ := cmd.Flags().GetString("vi")
id, err := lookup.VirtualInstanceNameOrIDtoID(ctx, rs, vi)
if err != nil {
return err
}

mounts, err := rs.MountCollections(ctx, id, args)
if err != nil {
return err
}

var mounted = make([]string, len(mounts))
for i, mount := range mounts {
mounted[i] = mount.GetCollectionPath()
}

_, _ = fmt.Fprintf(cmd.OutOrStdout(), "mounted %s on %s\n", strings.Join(mounted, ", "), vi)

return nil
},
}

cmd.Flags().String("vi", "", "virtual instance id or name")
cmd.MarkFlagRequired("vi")
_ = cmd.RegisterFlagCompletionFunc("vi", completion.VirtualInstance(Version))

return &cmd
}

func NewUnmountCollectionCmd() *cobra.Command {
cmd := cobra.Command{
Use: "unmount PATH",
Aliases: []string{"m"},
Args: cobra.MinimumNArgs(1),
Short: "unmount a collection from a virtual instance",
Annotations: group("mount"),
ValidArgsFunction: completion.CollectionMount(Version),
RunE: func(cmd *cobra.Command, args []string) error {
ctx := cmd.Context()
rs, err := config.Client(cmd, Version)
if err != nil {
return err
}

vi, _ := cmd.Flags().GetString("vi")
id, err := lookup.VirtualInstanceNameOrIDtoID(ctx, rs, vi)
if err != nil {
return err
}

mount, err := rs.UnmountCollection(ctx, id, args[0])
if err != nil {
return err
}

_, _ = fmt.Fprintf(cmd.OutOrStdout(), "unmounted %s from %s\n", mount.GetCollectionPath(), vi)

return nil
},
}

cmd.Flags().String("vi", "", "virtual instance id or name")
cmd.MarkFlagRequired("vi")
_ = cmd.RegisterFlagCompletionFunc("vi", completion.VirtualInstance(Version))

return &cmd
}
3 changes: 2 additions & 1 deletion cmd/query.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package cmd
import (
"context"
"fmt"
"github.com/rockset/cli/lookup"
"io"
"os"
"strings"
Expand Down Expand Up @@ -40,7 +41,7 @@ func newListQueryCmd() *cobra.Command {
if len(args) == 0 {
list, err = rs.ListActiveQueries(ctx)
} else {
id, err := viNameOrIDtoID(ctx, rs, args[0])
id, err := lookup.VirtualInstanceNameOrIDtoID(ctx, rs, args[0])
if err != nil {
return err
}
Expand Down
6 changes: 6 additions & 0 deletions cmd/verbs.go
Original file line number Diff line number Diff line change
Expand Up @@ -141,6 +141,12 @@ func addVerbs(root *cobra.Command) {
deleteCmd.AddCommand(NewDeleteAliasCmd())
updateCmd.AddCommand(NewUpdateAliasCmd())

// mounts
listCmd.AddCommand(NewListMountsCmd())
getCmd.AddCommand(NewGetMountCmd())
root.AddCommand(NewMountCollectionsCmd())
root.AddCommand(NewUnmountCollectionCmd())

// roles
getCmd.AddCommand(newGetRoleCommand())
listCmd.AddCommand(newListRolesCommand())
Expand Down
52 changes: 6 additions & 46 deletions cmd/virtual_instance.go
Original file line number Diff line number Diff line change
@@ -1,11 +1,8 @@
package cmd

import (
"context"
"errors"
"fmt"
"regexp"

"github.com/rockset/cli/lookup"
"github.com/rockset/rockset-go-client"
"github.com/rockset/rockset-go-client/openapi"
"github.com/rockset/rockset-go-client/option"
Expand Down Expand Up @@ -86,7 +83,7 @@ func newUpdateVirtualInstanceCmd() *cobra.Command {
return err
}

id, err := viNameOrIDtoID(ctx, rs, args[0])
id, err := lookup.VirtualInstanceNameOrIDtoID(ctx, rs, args[0])
if err != nil {
return err
}
Expand Down Expand Up @@ -174,7 +171,7 @@ func newGetVirtualInstancesCmd() *cobra.Command {
return err
}

id, err := viNameOrIDtoID(ctx, rs, args[0])
id, err := lookup.VirtualInstanceNameOrIDtoID(ctx, rs, args[0])
if err != nil {
return err
}
Expand Down Expand Up @@ -210,7 +207,7 @@ func newDeleteVirtualInstanceCmd() *cobra.Command {
return err
}

id, err := viNameOrIDtoID(ctx, rs, args[0])
id, err := lookup.VirtualInstanceNameOrIDtoID(ctx, rs, args[0])
if err != nil {
return err
}
Expand Down Expand Up @@ -246,7 +243,7 @@ func newSuspendVirtualInstanceCmd() *cobra.Command {
return err
}

id, err := viNameOrIDtoID(ctx, rs, args[0])
id, err := lookup.VirtualInstanceNameOrIDtoID(ctx, rs, args[0])
if err != nil {
return err
}
Expand Down Expand Up @@ -282,7 +279,7 @@ func newResumeVirtualInstanceCmd() *cobra.Command {
return err
}

id, err := viNameOrIDtoID(ctx, rs, args[0])
id, err := lookup.VirtualInstanceNameOrIDtoID(ctx, rs, args[0])
if err != nil {
return err
}
Expand All @@ -306,43 +303,6 @@ func newResumeVirtualInstanceCmd() *cobra.Command {
return &cmd
}

// TODO should this move to the Rockset go client instead?
func viNameOrIDtoID(ctx context.Context, rs *rockset.RockClient, nameOrID string) (string, error) {
if !isUUID(nameOrID) {
id, err := viNameToID(ctx, rs, nameOrID)
if err != nil {
return "", fmt.Errorf("failed to get virtual instance id for %s: %v", nameOrID, err)
}

return id, nil
}

return nameOrID, nil
}

var uuidRe = regexp.MustCompile(`[[:xdigit:]]{8}-[[:xdigit:]]{4}-[[:xdigit:]]{4}-[[:xdigit:]]{4-[[:xdigit:]]{12`)

func isUUID(id string) bool {
return uuidRe.MatchString(id)
}

func viNameToID(ctx context.Context, rs *rockset.RockClient, name string) (string, error) {
vis, err := rs.ListVirtualInstances(ctx)
if err != nil {
return "", err
}

for _, vi := range vis {
if vi.GetName() == name {
return vi.GetId(), nil
}
}

return "", VINotFoundErr
}

var VINotFoundErr = errors.New("virtual instance not found")

func waitUntilVIActive(rs *rockset.RockClient, cmd *cobra.Command, vID string) error {
wait, err := cmd.Flags().GetBool(flag.Wait)
if err != nil {
Expand Down
31 changes: 28 additions & 3 deletions completion/completions.go
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
package completion

import (
"github.com/rockset/rockset-go-client/option"
"github.com/spf13/cobra"

"github.com/rockset/cli/config"
"github.com/rockset/cli/flag"
"github.com/rockset/cli/lookup"
"github.com/rockset/rockset-go-client/option"
"github.com/spf13/cobra"
)

func Collection(version string) func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) {
Expand Down Expand Up @@ -310,3 +310,28 @@ func APIKey(version string) func(cmd *cobra.Command, args []string, toComplete s
return list, cobra.ShellCompDirectiveNoFileComp
}
}

func CollectionMount(version string) func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) {
return func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) {
ctx := cmd.Context()
rs, err := config.Client(cmd, version)
if err != nil {
return nil, cobra.ShellCompDirectiveError
}

vi, _ := cmd.Flags().GetString("vi")
id, err := lookup.VirtualInstanceNameOrIDtoID(ctx, rs, vi)

mounts, err := rs.ListCollectionMounts(ctx, id)
if err != nil {
return nil, cobra.ShellCompDirectiveError
}

list := make([]string, len(mounts))
for i, mount := range mounts {
list[i] = mount.GetCollectionPath()
}

return list, cobra.ShellCompDirectiveNoFileComp
}
}
2 changes: 2 additions & 0 deletions format/format.go
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,8 @@ func defaultSelectorFor(f any) (DefaultSelector, error) {
return WorkspaceDefaultSelector, nil
case openapi.Collection:
return CollectionDefaultSelector, nil
case openapi.CollectionMount:
return MountDefaultSelector, nil
case openapi.Integration:
return IntegrationDefaultSelector, nil
case openapi.QueryInfo:
Expand Down
41 changes: 41 additions & 0 deletions format/mount.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
package format

import "github.com/rockset/rockset-go-client/openapi"

var MountDefaultSelector = DefaultSelector{
Normal: []FieldSelection{
NewFieldSelection("Collection Path", "collection_path"),
NewFieldSelection("State", "state"),
{
ColumnName: "Last Queried",
Path: []PathElem{{FieldName: "stats"}, {FieldName: "last_queried_ms"}},
FieldFormatter: TimeSinceFormatter{},
},
},
Wide: []FieldSelection{
NewFieldSelection("Collection Path", "collection_path"),
NewFieldSelection("ID", "id"),
NewFieldSelection("State", "state"),
{
ColumnName: "Last Queried",
Path: []PathElem{{FieldName: "stats"}, {FieldName: "last_queried_ms"}},
FieldFormatter: TimeSinceFormatter{},
},
NewFieldSelection("Virtual Instance ID", "virtual_instance_id"),
},
}

var _ = openapi.CollectionMount{
CollectionPath: nil,
CreatedAt: nil,
Id: nil,
LastRefreshTimeMillis: nil,
Rrn: nil,
SnapshotExpirationTimeMillis: nil,
State: nil,
Stats: &openapi.CollectionMountStats{
LastQueriedMs: nil,
},
VirtualInstanceId: nil,
VirtualInstanceRrn: nil,
}
Loading

0 comments on commit 8f3cd91

Please sign in to comment.