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
2 changes: 2 additions & 0 deletions cmd/pro/check_update.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@ type CheckUpdateCmd struct {
}

// NewCheckUpdateCmd creates a new command.
//
//nolint:dupl // structurally similar to NewHealthCmd; intentional sibling factory
func NewCheckUpdateCmd(globalFlags *flags.GlobalFlags) *cobra.Command {
cmd := &CheckUpdateCmd{
GlobalFlags: globalFlags,
Expand Down
2 changes: 2 additions & 0 deletions cmd/pro/daemon/netcheck.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,8 @@ type NetcheckCmd struct {
}

// NewNetcheckCmd creates a new command.
//
//nolint:dupl // structurally similar to NewStatusCmd; intentional sibling factory
func NewNetcheckCmd(flags *proflags.GlobalFlags) *cobra.Command {
cmd := &NetcheckCmd{
GlobalFlags: flags,
Expand Down
2 changes: 2 additions & 0 deletions cmd/pro/daemon/status.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@ type StatusCmd struct {
}

// NewStatusCmd creates a new command.
//
//nolint:dupl // structurally similar to NewNetcheckCmd; intentional sibling factory
func NewStatusCmd(flags *proflags.GlobalFlags) *cobra.Command {
cmd := &StatusCmd{
GlobalFlags: flags,
Expand Down
54 changes: 54 additions & 0 deletions cmd/pro/provider/exec.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
package provider

import (
"context"
"fmt"
"io"
"net/url"

"github.com/devsy-org/devsy/pkg/platform"
"github.com/devsy-org/devsy/pkg/platform/client"
"github.com/devsy-org/devsy/pkg/platform/remotecommand"
)

type dialAndExecuteParams struct {
configPath string
action string
envFlags url.Values
stdin io.Reader
stdout io.Writer
stderr io.Writer
}

// dialAndExecute finds the current workspace, dials the given sub-resource
// action on it, and streams the resulting connection through stdin/stdout/stderr.
func dialAndExecute(ctx context.Context, params dialAndExecuteParams) error {
baseClient, err := client.InitClientFromPath(ctx, params.configPath)
if err != nil {
return err
}

info, err := platform.GetWorkspaceInfoFromEnv()
if err != nil {
return err
}
opts := platform.FindInstanceOptions{UID: info.UID, ProjectName: info.ProjectName}
workspace, err := platform.FindInstance(ctx, baseClient, opts)
if err != nil {
return err
} else if workspace == nil {
return fmt.Errorf("couldn't find workspace")
}

conn, err := platform.DialInstance(baseClient, workspace, params.action, params.envFlags)
if err != nil {
return err
}

_, err = remotecommand.ExecuteConn(ctx, conn, params.stdin, params.stdout, params.stderr)
if err != nil {
return fmt.Errorf("error executing: %w", err)
}

return nil
}
51 changes: 9 additions & 42 deletions cmd/pro/provider/ssh.go
Original file line number Diff line number Diff line change
@@ -1,16 +1,14 @@
//nolint:dupl // structurally similar to stop.go; intentional sibling command sharing dialAndExecute
package provider

import (
"context"
"fmt"
"io"
"os"

"github.com/devsy-org/devsy/cmd/pro/flags"
"github.com/devsy-org/devsy/pkg/config"
"github.com/devsy-org/devsy/pkg/platform"
"github.com/devsy-org/devsy/pkg/platform/client"
"github.com/devsy-org/devsy/pkg/platform/remotecommand"
"github.com/spf13/cobra"
)

Expand Down Expand Up @@ -43,43 +41,12 @@ func (cmd *SshCmd) Run(
stdout io.Writer,
stderr io.Writer,
) error {
baseClient, err := client.InitClientFromPath(ctx, cmd.Config)
if err != nil {
return err
}

info, err := platform.GetWorkspaceInfoFromEnv()
if err != nil {
return err
}
opts := platform.FindInstanceOptions{UID: info.UID, ProjectName: info.ProjectName}
workspace, err := platform.FindInstance(ctx, baseClient, opts)
if err != nil {
return err
} else if workspace == nil {
return fmt.Errorf("couldn't find workspace")
}

conn, err := platform.DialInstance(
baseClient,
workspace,
"ssh",
platform.OptionsFromEnv(config.EnvFlagsSSH),
)
if err != nil {
return err
}

_, err = remotecommand.ExecuteConn(
ctx,
conn,
stdin,
stdout,
stderr,
)
if err != nil {
return fmt.Errorf("error executing: %w", err)
}

return nil
return dialAndExecute(ctx, dialAndExecuteParams{
configPath: cmd.Config,
action: "ssh",
envFlags: platform.OptionsFromEnv(config.EnvFlagsSSH),
stdin: stdin,
stdout: stdout,
stderr: stderr,
})
}
51 changes: 9 additions & 42 deletions cmd/pro/provider/stop.go
Original file line number Diff line number Diff line change
@@ -1,16 +1,14 @@
//nolint:dupl // structurally similar to ssh.go; intentional sibling command sharing dialAndExecute
package provider

import (
"context"
"fmt"
"io"
"os"

storagev1 "github.com/devsy-org/api/pkg/apis/storage/v1"
"github.com/devsy-org/devsy/cmd/pro/flags"
"github.com/devsy-org/devsy/pkg/platform"
"github.com/devsy-org/devsy/pkg/platform/client"
"github.com/devsy-org/devsy/pkg/platform/remotecommand"
"github.com/spf13/cobra"
)

Expand Down Expand Up @@ -43,43 +41,12 @@ func (cmd *StopCmd) Run(
stdout io.Writer,
stderr io.Writer,
) error {
baseClient, err := client.InitClientFromPath(ctx, cmd.Config)
if err != nil {
return err
}

info, err := platform.GetWorkspaceInfoFromEnv()
if err != nil {
return err
}
opts := platform.FindInstanceOptions{UID: info.UID, ProjectName: info.ProjectName}
workspace, err := platform.FindInstance(ctx, baseClient, opts)
if err != nil {
return err
} else if workspace == nil {
return fmt.Errorf("couldn't find workspace")
}

conn, err := platform.DialInstance(
baseClient,
workspace,
"stop",
platform.OptionsFromEnv(storagev1.DevsyFlagsStop),
)
if err != nil {
return err
}

_, err = remotecommand.ExecuteConn(
ctx,
conn,
stdin,
stdout,
stderr,
)
if err != nil {
return fmt.Errorf("error executing: %w", err)
}

return nil
return dialAndExecute(ctx, dialAndExecuteParams{
configPath: cmd.Config,
action: "stop",
envFlags: platform.OptionsFromEnv(storagev1.DevsyFlagsStop),
stdin: stdin,
stdout: stdout,
stderr: stderr,
})
}
32 changes: 16 additions & 16 deletions pkg/options/resolver/resolver_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -215,14 +215,7 @@ func (suite *ResolverTestSuite) TestResolveOptions_ExpiredCache() {
}

func (suite *ResolverTestSuite) TestResolveOptions_PreserveChildWhenParentUnchanged() {
suite.resolver.graph = graph.NewGraph[*types.Option]()

parentOption := &types.Option{Description: "Parent", Default: "new_parent_value"}
childOption := &types.Option{Description: "Child", Default: "child_default"}

suite.Require().NoError(suite.resolver.graph.AddNode("parent", parentOption))
suite.Require().NoError(suite.resolver.graph.AddNode("child", childOption))
suite.Require().NoError(suite.resolver.graph.AddEdge("parent", "child"))
suite.setupParentChildGraph()

existingValues := map[string]config.OptionValue{
"parent": {Value: "old_parent_value", UserProvided: true},
Expand All @@ -237,14 +230,7 @@ func (suite *ResolverTestSuite) TestResolveOptions_PreserveChildWhenParentUnchan
}

func (suite *ResolverTestSuite) TestResolveOptions_PreserveUserProvidedChild() {
suite.resolver.graph = graph.NewGraph[*types.Option]()

parentOption := &types.Option{Description: "Parent", Default: "new_parent_value"}
childOption := &types.Option{Description: "Child", Default: "child_default"}

suite.Require().NoError(suite.resolver.graph.AddNode("parent", parentOption))
suite.Require().NoError(suite.resolver.graph.AddNode("child", childOption))
suite.Require().NoError(suite.resolver.graph.AddEdge("parent", "child"))
suite.setupParentChildGraph()

existingValues := map[string]config.OptionValue{
"parent": {Value: "old_parent_value", UserProvided: true},
Expand Down Expand Up @@ -321,3 +307,17 @@ func (suite *ResolverTestSuite) TestAddOptionsToGraph_MultipleCalls() {
nodes := g.GetNodes()
suite.Len(nodes, 2, "Multiple calls to addOptionsToGraph should not duplicate nodes.")
}

// setupParentChildGraph creates a resolver graph with a "parent" option that
// has a "child" option depending on it, used by tests that verify
// user-provided-value precedence during resolution.
func (suite *ResolverTestSuite) setupParentChildGraph() {
suite.resolver.graph = graph.NewGraph[*types.Option]()

parentOption := &types.Option{Description: "Parent", Default: "new_parent_value"}
childOption := &types.Option{Description: "Child", Default: "child_default"}

suite.Require().NoError(suite.resolver.graph.AddNode("parent", parentOption))
suite.Require().NoError(suite.resolver.graph.AddNode("child", childOption))
suite.Require().NoError(suite.resolver.graph.AddEdge("parent", "child"))
}
Loading