Skip to content

Commit

Permalink
feat(pro): filter Desktop and CLI by pro ownership, defaults to own w…
Browse files Browse the repository at this point in the history
…orkspaces
  • Loading branch information
pascalbreuninger committed Mar 4, 2025
1 parent 6b567ff commit 1754c17
Show file tree
Hide file tree
Showing 31 changed files with 308 additions and 178 deletions.
4 changes: 2 additions & 2 deletions cmd/build.go
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ func NewBuildCmd(flags *flags.GlobalFlags) *cobra.Command {
}

// create a temporary workspace
exists := workspace2.Exists(ctx, devPodConfig, args, "", log.Default)
exists := workspace2.Exists(ctx, devPodConfig, args, "", cmd.Owner, log.Default)
sshConfigFile, err := os.CreateTemp("", "devpodssh.config")
if err != nil {
return err
Expand All @@ -92,8 +92,8 @@ func NewBuildCmd(flags *flags.GlobalFlags) *cobra.Command {
nil,
cmd.UID,
false,
cmd.Owner,
log.Default,
"",
)
if err != nil {
return err
Expand Down
2 changes: 1 addition & 1 deletion cmd/delete.go
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ func NewDeleteCmd(flags *flags.GlobalFlags) *cobra.Command {

// Run runs the command logic
func (cmd *DeleteCmd) Run(ctx context.Context, devPodConfig *config.Config, args []string) error {
workspaceName, err := workspace.Delete(ctx, devPodConfig, args, cmd.IgnoreNotFound, cmd.Force, cmd.DeleteOptions, log.Default)
workspaceName, err := workspace.Delete(ctx, devPodConfig, args, cmd.IgnoreNotFound, cmd.Force, cmd.DeleteOptions, cmd.Owner, log.Default)
if err != nil {
return err
}
Expand Down
2 changes: 1 addition & 1 deletion cmd/export.go
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ func NewExportCmd(flags *flags.GlobalFlags) *cobra.Command {
func (cmd *ExportCmd) Run(ctx context.Context, devPodConfig *config.Config, args []string) error {
// try to load workspace
logger := log.Default.ErrorStreamOnly()
client, err := workspace2.Get(ctx, devPodConfig, args, false, logger)
client, err := workspace2.Get(ctx, devPodConfig, args, false, cmd.Owner, logger)
if err != nil {
return err
}
Expand Down
24 changes: 11 additions & 13 deletions cmd/flags/flags.go
Original file line number Diff line number Diff line change
@@ -1,22 +1,21 @@
package flags

import (
"github.com/loft-sh/devpod/pkg/platform"
flag "github.com/spf13/pflag"
)

type GlobalFlags struct {
Context string
Provider string
LogOutput string

Debug bool
Silent bool

AgentDir string

Context string
Provider string
AgentDir string
DevPodHome string
UID string
Owner platform.OwnerFilter

UID string
LogOutput string
Debug bool
Silent bool
}

// SetGlobalFlags applies the global flags
Expand All @@ -30,11 +29,10 @@ func SetGlobalFlags(flags *flag.FlagSet) *GlobalFlags {
flags.BoolVar(&globalFlags.Debug, "debug", false, "Prints the stack trace if an error occurs")
flags.BoolVar(&globalFlags.Silent, "silent", false, "Run in silent mode and prevents any devpod log output except panics & fatals")

_ = flags.MarkHidden("git-username")
_ = flags.MarkHidden("git-token")
flags.Var(&globalFlags.Owner, "owner", "Show pro workspaces for owner")
flags.MarkHidden("owner")
flags.StringVar(&globalFlags.UID, "uid", "", "Set UID for workspace")
_ = flags.MarkHidden("uid")

flags.StringVar(&globalFlags.AgentDir, "agent-dir", "", "The data folder where agent data is stored.")
_ = flags.MarkHidden("agent-dir")
return globalFlags
Expand Down
2 changes: 1 addition & 1 deletion cmd/import.go
Original file line number Diff line number Diff line change
Expand Up @@ -262,7 +262,7 @@ func (cmd *ImportCmd) importProvider(devPodConfig *config.Config, exportConfig *
}

func (cmd *ImportCmd) checkForConflictingIDs(ctx context.Context, exportConfig *provider.ExportConfig, devPodConfig *config.Config, log log.Logger) error {
workspaces, err := workspace.List(ctx, devPodConfig, false, log)
workspaces, err := workspace.List(ctx, devPodConfig, false, cmd.Owner, log)
if err != nil {
return fmt.Errorf("error listing workspaces: %w", err)
}
Expand Down
16 changes: 10 additions & 6 deletions cmd/list.go
Original file line number Diff line number Diff line change
Expand Up @@ -54,14 +54,14 @@ func (cmd *ListCmd) Run(ctx context.Context) error {
return err
}

workspaces, err := workspace.List(ctx, devPodConfig, cmd.SkipPro, log.Default)
workspaces, err := workspace.List(ctx, devPodConfig, cmd.SkipPro, cmd.Owner, log.Default)
if err != nil {
return err
}

if cmd.Output == "json" {
sort.SliceStable(workspaces, func(i, j int) bool {
return workspaces[i].ID < workspaces[j].ID
return workspaces[i].LastUsedTimestamp.Time.Unix() > workspaces[j].LastUsedTimestamp.Time.Unix()
})
out, err := json.Marshal(workspaces)
if err != nil {
Expand All @@ -70,9 +70,16 @@ func (cmd *ListCmd) Run(ctx context.Context) error {
fmt.Print(string(out))
} else if cmd.Output == "plain" {
tableEntries := [][]string{}
sort.SliceStable(workspaces, func(i, j int) bool {
return workspaces[i].LastUsedTimestamp.Time.Unix() > workspaces[j].LastUsedTimestamp.Time.Unix()
})
for _, entry := range workspaces {
name := entry.ID
if entry.IsPro() && entry.Pro.DisplayName != "" && entry.ID != entry.Pro.DisplayName {
name = fmt.Sprintf("%s (%s)", entry.Pro.DisplayName, entry.ID)
}
tableEntries = append(tableEntries, []string{
entry.ID,
name,
entry.Source.String(),
entry.Machine.ID,
entry.Provider.Name,
Expand All @@ -83,9 +90,6 @@ func (cmd *ListCmd) Run(ctx context.Context) error {
})
}

sort.SliceStable(tableEntries, func(i, j int) bool {
return tableEntries[i][0] < tableEntries[j][0]
})
table.PrintTable(log.Default, []string{
"Name",
"Source",
Expand Down
3 changes: 1 addition & 2 deletions cmd/logs.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@ import (
"github.com/loft-sh/log"
"github.com/sirupsen/logrus"
"github.com/spf13/cobra"
// tsClient "tailscale.com/client/tailscale"
)

// LogsCmd holds the configuration
Expand Down Expand Up @@ -46,7 +45,7 @@ func (cmd *LogsCmd) Run(ctx context.Context, args []string) error {
return err
}

baseClient, err := workspace.Get(ctx, devPodConfig, args, false, log.Default)
baseClient, err := workspace.Get(ctx, devPodConfig, args, false, cmd.Owner, log.Default)
if err != nil {
return err
}
Expand Down
2 changes: 1 addition & 1 deletion cmd/logs_daemon.go
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ func (cmd *LogsDaemonCmd) Run(ctx context.Context, args []string) error {
return err
}

baseClient, err := workspace.Get(ctx, devPodConfig, args, false, log.Default)
baseClient, err := workspace.Get(ctx, devPodConfig, args, false, cmd.Owner, log.Default)
if err != nil {
return err
} else if baseClient.WorkspaceConfig().Machine.ID == "" {
Expand Down
3 changes: 2 additions & 1 deletion cmd/machine/delete.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import (
"github.com/loft-sh/devpod/cmd/flags"
"github.com/loft-sh/devpod/pkg/client"
"github.com/loft-sh/devpod/pkg/config"
"github.com/loft-sh/devpod/pkg/platform"
"github.com/loft-sh/devpod/pkg/workspace"
"github.com/loft-sh/log"
"github.com/spf13/cobra"
Expand Down Expand Up @@ -51,7 +52,7 @@ func (cmd *DeleteCmd) Run(ctx context.Context, args []string) error {
}

// check if there are workspaces that still use this machine
workspaces, err := workspace.List(ctx, devPodConfig, false, log.Default)
workspaces, err := workspace.List(ctx, devPodConfig, false, platform.SelfOwnerFilter, log.Default)
if err != nil {
return err
}
Expand Down
2 changes: 1 addition & 1 deletion cmd/ping.go
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ func (cmd *PingCmd) Run(ctx context.Context, args []string) error {
return err
}

client, err := workspace2.Get(ctx, devPodConfig, args, true, log.Default.ErrorStreamOnly())
client, err := workspace2.Get(ctx, devPodConfig, args, true, cmd.Owner, log.Default.ErrorStreamOnly())
if err != nil {
return err
}
Expand Down
9 changes: 5 additions & 4 deletions cmd/pro/delete.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import (
"github.com/loft-sh/devpod/pkg/client/clientimplementation"
"github.com/loft-sh/devpod/pkg/config"
platformdaemon "github.com/loft-sh/devpod/pkg/daemon/platform"
"github.com/loft-sh/devpod/pkg/platform"
"github.com/loft-sh/devpod/pkg/provider"
provider2 "github.com/loft-sh/devpod/pkg/provider"
"github.com/loft-sh/devpod/pkg/workspace"
Expand Down Expand Up @@ -77,11 +78,11 @@ func (cmd *DeleteCmd) Run(ctx context.Context, args []string) error {
return err
}

workspaces, err := workspace.List(ctx, devPodConfig, true, log.Default)
workspaces, err := workspace.List(ctx, devPodConfig, true, cmd.Owner, log.Default)
if err != nil {
log.Default.Warnf("Failed to list workspaces: %v", err)
} else {
cleanupLocalWorkspaces(ctx, devPodConfig, workspaces, providerConfig.Name, log.Default)
cleanupLocalWorkspaces(ctx, devPodConfig, workspaces, providerConfig.Name, cmd.Owner, log.Default)
}

daemonClient := platformdaemon.NewLocalClient(daemonDir, proInstanceConfig.Provider)
Expand Down Expand Up @@ -112,7 +113,7 @@ func (cmd *DeleteCmd) Run(ctx context.Context, args []string) error {
return nil
}

func cleanupLocalWorkspaces(ctx context.Context, devPodConfig *config.Config, workspaces []*provider2.Workspace, providerName string, log log.Logger) {
func cleanupLocalWorkspaces(ctx context.Context, devPodConfig *config.Config, workspaces []*provider2.Workspace, providerName string, owner platform.OwnerFilter, log log.Logger) {
usedWorkspaces := []*provider2.Workspace{}

for _, workspace := range workspaces {
Expand All @@ -128,7 +129,7 @@ func cleanupLocalWorkspaces(ctx context.Context, devPodConfig *config.Config, wo
wg.Add(1)
go func(w provider2.Workspace) {
defer wg.Done()
client, err := workspace.Get(ctx, devPodConfig, []string{w.ID}, false, log)
client, err := workspace.Get(ctx, devPodConfig, []string{w.ID}, true, owner, log)
if err != nil {
log.Errorf("Failed to get workspace %s: %v", w.ID, err)
return
Expand Down
3 changes: 2 additions & 1 deletion cmd/provider/delete.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import (

"github.com/loft-sh/devpod/cmd/flags"
"github.com/loft-sh/devpod/pkg/config"
"github.com/loft-sh/devpod/pkg/platform"
provider2 "github.com/loft-sh/devpod/pkg/provider"
"github.com/loft-sh/devpod/pkg/workspace"
logpkg "github.com/loft-sh/log"
Expand Down Expand Up @@ -77,7 +78,7 @@ func (cmd *DeleteCmd) Run(ctx context.Context, args []string) error {

func DeleteProvider(ctx context.Context, devPodConfig *config.Config, provider string, ignoreNotFound bool, log logpkg.Logger) error {
// check if there are workspaces that still use this provider
workspaces, err := workspace.List(ctx, devPodConfig, true, log)
workspaces, err := workspace.List(ctx, devPodConfig, true, platform.AllOwnerFilter, log)
if err != nil {
return err
}
Expand Down
2 changes: 1 addition & 1 deletion cmd/ssh.go
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ func NewSSHCmd(f *flags.GlobalFlags) *cobra.Command {
}

ctx := cobraCmd.Context()
client, err := workspace2.Get(ctx, devPodConfig, args, true, log.Default.ErrorStreamOnly())
client, err := workspace2.Get(ctx, devPodConfig, args, true, cmd.Owner, log.Default.ErrorStreamOnly())
if err != nil {
return err
}
Expand Down
2 changes: 1 addition & 1 deletion cmd/status.go
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ func NewStatusCmd(flags *flags.GlobalFlags) *cobra.Command {
}

logger := log.Default.ErrorStreamOnly()
client, err := workspace2.Get(ctx, devPodConfig, args, false, logger)
client, err := workspace2.Get(ctx, devPodConfig, args, false, cmd.Owner, logger)
if err != nil {
return err
}
Expand Down
4 changes: 2 additions & 2 deletions cmd/stop.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ func NewStopCmd(flags *flags.GlobalFlags) *cobra.Command {
return err
}

client, err := workspace2.Get(ctx, devPodConfig, args, false, log.Default)
client, err := workspace2.Get(ctx, devPodConfig, args, false, cmd.Owner, log.Default)
if err != nil {
return err
}
Expand Down Expand Up @@ -88,7 +88,7 @@ func (cmd *StopCmd) stopSingleMachine(ctx context.Context, client client2.BaseWo
}

// try to find other workspace with same machine
workspaces, err := workspace2.List(ctx, devPodConfig, false, log.Default)
workspaces, err := workspace2.List(ctx, devPodConfig, false, cmd.Owner, log.Default)
if err != nil {
return false, errors.Wrap(err, "list workspaces")
}
Expand Down
2 changes: 1 addition & 1 deletion cmd/troubleshoot.go
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@ func (cmd *TroubleshootCmd) Run(ctx context.Context, args []string) {
info.Errors = append(info.Errors, PrintableError{fmt.Errorf("collect platform info: %w", err)})
}

workspaceClient, err := workspace.Get(ctx, info.Config, args, false, logger)
workspaceClient, err := workspace.Get(ctx, info.Config, args, false, cmd.Owner, logger)
if err == nil {
info.Workspace = workspaceClient.WorkspaceConfig()
info.WorkspaceStatus, err = workspaceClient.Status(ctx, client.StatusOptions{})
Expand Down
2 changes: 1 addition & 1 deletion cmd/up.go
Original file line number Diff line number Diff line change
Expand Up @@ -1370,8 +1370,8 @@ func (cmd *UpCmd) prepareClient(ctx context.Context, devPodConfig *config.Config
source,
cmd.UID,
true,
cmd.Owner,
logger,
cmd.Platform.WorkspaceHost,
)
if err != nil {
return nil, logger, err
Expand Down
4 changes: 4 additions & 0 deletions desktop/src/client/pro/client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import {
import { TAURI_SERVER_URL } from "../tauriClient"
import { TDebuggable, TStreamEventListenerFn } from "../types"
import { ProCommands } from "./proCommands"
import { TWorkspaceOwnerFilterState } from "@/components"

export class ProClient implements TDebuggable {
constructor(protected readonly id: string) {}
Expand Down Expand Up @@ -66,6 +67,7 @@ export class ProClient implements TDebuggable {

public watchWorkspaces(
projectName: string,
ownerFilter: TWorkspaceOwnerFilterState,
listener: (newWorkspaces: readonly ProWorkspaceInstance[]) => void,
errorListener?: (failed: Failed) => void
) {
Expand Down Expand Up @@ -260,6 +262,7 @@ export class DaemonClient extends ProClient {

public watchWorkspaces(
projectName: string,
ownerFilter: TWorkspaceOwnerFilterState,
listener: (newWorkspaces: readonly ProWorkspaceInstance[]) => void,
errorListener?: (failed: Failed) => void
) {
Expand Down Expand Up @@ -314,6 +317,7 @@ export class DaemonClient extends ProClient {
const abortController = new AbortController()
const url = new URL(`${TAURI_SERVER_URL}/daemon-proxy/${this.id}/watch-workspaces`)
url.searchParams.set("project", projectName)
url.searchParams.set("owner", ownerFilter)

this.waitDaemonRunning().then(() => {
// start long-lived request. This should never stop unless cancelled trough abortController
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import {
} from "@chakra-ui/react"
import { useCallback } from "react"

export type TWorkspaceOwnerFilterState = "user" | "all"
export type TWorkspaceOwnerFilterState = "self" | "all"

export function WorkspaceOwnerFilter({
ownerFilter,
Expand All @@ -28,11 +28,11 @@ export function WorkspaceOwnerFilter({
return (
<Menu offset={[0, 2]}>
<MenuButton as={Button} variant="outline" rightIcon={<ChevronDownIcon boxSize={4} />}>
Workspaces: {ownerFilter == "user" ? "Mine" : "All"}
Workspaces: {ownerFilter == "self" ? "Mine" : "All"}
</MenuButton>
<MenuList>
<MenuOptionGroup type="radio" value={ownerFilter} onChange={onChange}>
<MenuItemOption key="user" value="user">
<MenuItemOption key="self" value="self">
Mine
</MenuItemOption>
<MenuItemOption key="all" value="all">
Expand Down
Loading

0 comments on commit 1754c17

Please sign in to comment.