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
6 changes: 6 additions & 0 deletions src/cmd/cli/command/commands_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -246,6 +246,12 @@ func (m *MockFabricControllerClient) ListDeployments(ctx context.Context, req *c
}), nil
}

func (m *MockFabricControllerClient) ListStacks(ctx context.Context, req *connect.Request[defangv1.ListStacksRequest]) (*connect.Response[defangv1.ListStacksResponse], error) {
return connect.NewResponse(&defangv1.ListStacksResponse{
Stacks: []*defangv1.Stack{},
}), nil
}

type FakeStdin struct {
*bytes.Reader
}
Expand Down
4 changes: 2 additions & 2 deletions src/cmd/cli/command/compose.go
Original file line number Diff line number Diff line change
Expand Up @@ -153,7 +153,7 @@ func makeComposeUpCmd() *cobra.Command {
term.Warnf("Defang cannot monitor status of the following managed service(s): %v.\n To check if the managed service is up, check the status of the service which depends on it.", managedServices)
}

deploy, project, err := cli.ComposeUp(ctx, global.Client, session.Provider, cli.ComposeUpParams{
deploy, project, err := cli.ComposeUp(ctx, global.Client, session.Provider, session.Stack, cli.ComposeUpParams{
Project: project,
UploadMode: upload,
Mode: global.Stack.Mode,
Expand Down Expand Up @@ -616,7 +616,7 @@ func makeComposeConfigCmd() *cobra.Command {
}, loadErr)
}

_, _, err = cli.ComposeUp(ctx, global.Client, session.Provider, cli.ComposeUpParams{
_, _, err = cli.ComposeUp(ctx, global.Client, session.Provider, session.Stack, cli.ComposeUpParams{
Project: project,
UploadMode: compose.UploadModeIgnore,
Mode: modes.ModeUnspecified,
Expand Down
4 changes: 2 additions & 2 deletions src/pkg/agent/tools/default_tool_cli.go
Original file line number Diff line number Diff line change
Expand Up @@ -50,8 +50,8 @@ func (DefaultToolCLI) Connect(ctx context.Context, cluster string) (*client.Grpc
return cli.ConnectWithTenant(ctx, cluster, types.TenantUnset)
}

func (DefaultToolCLI) ComposeUp(ctx context.Context, fabric *client.GrpcClient, provider client.Provider, params cli.ComposeUpParams) (*defangv1.DeployResponse, *compose.Project, error) {
return cli.ComposeUp(ctx, fabric, provider, params)
func (DefaultToolCLI) ComposeUp(ctx context.Context, fabric *client.GrpcClient, provider client.Provider, stack *stacks.StackParameters, params cli.ComposeUpParams) (*defangv1.DeployResponse, *compose.Project, error) {
return cli.ComposeUp(ctx, fabric, provider, stack, params)
}

func (DefaultToolCLI) Tail(ctx context.Context, provider client.Provider, projectName string, options cli.TailOptions) error {
Expand Down
2 changes: 1 addition & 1 deletion src/pkg/agent/tools/deploy.go
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ func HandleDeployTool(ctx context.Context, loader client.Loader, params DeployPa

term.Debug("Function invoked: cli.ComposeUp")
// Use ComposeUp to deploy the services
deployResp, project, err := cli.ComposeUp(ctx, client, provider, cliTypes.ComposeUpParams{
deployResp, project, err := cli.ComposeUp(ctx, client, provider, sc.Stack, cliTypes.ComposeUpParams{
Project: project,
UploadMode: compose.UploadModeDigest,
Mode: modes.ModeAffordable,
Expand Down
2 changes: 1 addition & 1 deletion src/pkg/agent/tools/deploy_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ func (m *MockDeployCLI) InteractiveLoginMCP(ctx context.Context, cluster string,
return m.InteractiveLoginMCPError
}

func (m *MockDeployCLI) ComposeUp(ctx context.Context, fabric *client.GrpcClient, provider client.Provider, params cli.ComposeUpParams) (*defangv1.DeployResponse, *compose.Project, error) {
func (m *MockDeployCLI) ComposeUp(ctx context.Context, fabric *client.GrpcClient, provider client.Provider, stack *stacks.StackParameters, params cli.ComposeUpParams) (*defangv1.DeployResponse, *compose.Project, error) {
m.CallLog = append(m.CallLog, "ComposeUp")
if m.ComposeUpError != nil {
return nil, nil, m.ComposeUpError
Expand Down
3 changes: 2 additions & 1 deletion src/pkg/agent/tools/interfaces.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,14 @@ import (
"github.com/DefangLabs/defang/src/pkg/cli/client"
"github.com/DefangLabs/defang/src/pkg/cli/compose"
"github.com/DefangLabs/defang/src/pkg/modes"
"github.com/DefangLabs/defang/src/pkg/stacks"
defangv1 "github.com/DefangLabs/defang/src/protos/io/defang/v1"
)

type CLIInterface interface {
CanIUseProvider(ctx context.Context, fabric *client.GrpcClient, provider client.Provider, projectName string, serviceCount int) error
ComposeDown(ctx context.Context, projectName string, fabric *client.GrpcClient, provider client.Provider) (string, error)
ComposeUp(ctx context.Context, fabric *client.GrpcClient, provider client.Provider, params cli.ComposeUpParams) (*defangv1.DeployResponse, *compose.Project, error)
ComposeUp(ctx context.Context, fabric *client.GrpcClient, provider client.Provider, stack *stacks.StackParameters, params cli.ComposeUpParams) (*defangv1.DeployResponse, *compose.Project, error)
ConfigDelete(ctx context.Context, projectName string, provider client.Provider, name string) error
ConfigSet(ctx context.Context, projectName string, provider client.Provider, name, value string) error
Connect(ctx context.Context, cluster string) (*client.GrpcClient, error)
Expand Down
2 changes: 1 addition & 1 deletion src/pkg/agent/tools/services_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ func (m *MockCLI) ComposeDown(ctx context.Context, projectName string, fabric *c
return "", nil
}

func (m *MockCLI) ComposeUp(ctx context.Context, fabric *client.GrpcClient, provider client.Provider, params cli.ComposeUpParams) (*defangv1.DeployResponse, *compose.Project, error) {
func (m *MockCLI) ComposeUp(ctx context.Context, fabric *client.GrpcClient, provider client.Provider, stack *stacks.StackParameters, params cli.ComposeUpParams) (*defangv1.DeployResponse, *compose.Project, error) {
return nil, nil, nil
}

Expand Down
2 changes: 1 addition & 1 deletion src/pkg/cli/cd.go
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ func CdCommand(ctx context.Context, projectName string, provider client.Provider
}

// Update deployment table to mark deployment as destroyed only after successful deletion of the subdomain
err = putDeployment(ctx, provider, fabric, putDeploymentParams{
err = putDeploymentAndStack(ctx, provider, fabric, nil, putDeploymentParams{
Action: defangv1.DeploymentAction_DEPLOYMENT_ACTION_DOWN,
ETag: etag,
ProjectName: projectName,
Expand Down
1 change: 1 addition & 0 deletions src/pkg/cli/client/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ type FabricClient interface {
Preview(context.Context, *defangv1.PreviewRequest) (*defangv1.PreviewResponse, error)
Publish(context.Context, *defangv1.PublishRequest) error
PutDeployment(context.Context, *defangv1.PutDeploymentRequest) error
PutStack(context.Context, *defangv1.PutStackRequest) error
RevokeToken(context.Context) error
SetSelectedProvider(context.Context, *defangv1.SetSelectedProviderRequest) error
// Subscribe(context.Context, *v1.SubscribeRequest) (*v1.SubscribeResponse, error)
Expand Down
9 changes: 9 additions & 0 deletions src/pkg/cli/client/grpc.go
Original file line number Diff line number Diff line change
Expand Up @@ -91,11 +91,20 @@ func (g GrpcClient) Publish(ctx context.Context, req *defangv1.PublishRequest) e
return err
}

func (g GrpcClient) PutStack(ctx context.Context, req *defangv1.PutStackRequest) error {
_, err := g.client.PutStack(ctx, connect.NewRequest(req))
return err
}

func (g GrpcClient) PutDeployment(ctx context.Context, req *defangv1.PutDeploymentRequest) error {
_, err := g.client.PutDeployment(ctx, connect.NewRequest(req))
return err
}

func (g GrpcClient) ListStacks(ctx context.Context, req *defangv1.ListStacksRequest) (*defangv1.ListStacksResponse, error) {
return getMsg(g.client.ListStacks(ctx, connect.NewRequest(req)))
}

func (g GrpcClient) ListDeployments(ctx context.Context, req *defangv1.ListDeploymentsRequest) (*defangv1.ListDeploymentsResponse, error) {
return getMsg(g.client.ListDeployments(ctx, connect.NewRequest(req)))
}
Expand Down
4 changes: 4 additions & 0 deletions src/pkg/cli/client/mock.go
Original file line number Diff line number Diff line change
Expand Up @@ -149,6 +149,10 @@ func (m MockFabricClient) CreateDelegateSubdomainZone(context.Context, *defangv1
return &defangv1.DelegateSubdomainZoneResponse{Zone: "example.com"}, nil
}

func (m MockFabricClient) PutStack(ctx context.Context, req *defangv1.PutStackRequest) error {
return nil
}

func (m MockFabricClient) PutDeployment(ctx context.Context, req *defangv1.PutDeploymentRequest) error {
return nil
}
Expand Down
28 changes: 26 additions & 2 deletions src/pkg/cli/common.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import (
"encoding/json"

"github.com/DefangLabs/defang/src/pkg/cli/client"
"github.com/DefangLabs/defang/src/pkg/stacks"
"github.com/DefangLabs/defang/src/pkg/term"
"github.com/DefangLabs/defang/src/pkg/types"
defangv1 "github.com/DefangLabs/defang/src/protos/io/defang/v1"
Expand Down Expand Up @@ -49,12 +50,35 @@ type putDeploymentParams struct {
EventsUrl string
}

func putDeployment(ctx context.Context, provider client.Provider, fabric client.FabricClient, req putDeploymentParams) error {
func putDeploymentAndStack(ctx context.Context, provider client.Provider, fabric client.FabricClient, stack *stacks.StackParameters, req putDeploymentParams) error {
accountInfo, err := provider.AccountInfo(ctx)
if err != nil {
return err
}

stackFileContent, err := stacks.Marshal(stack)
if err != nil {
return err
}

deployedAt := timestamppb.Now()

err = fabric.PutStack(ctx, &defangv1.PutStackRequest{
Stack: &defangv1.Stack{
Name: provider.GetStackName(),
Project: req.ProjectName,
Provider: accountInfo.Provider.Value(),
Region: accountInfo.Region,
Mode: req.Mode,
ProviderAccountId: accountInfo.AccountID,
LastDeployedAt: deployedAt,
StackFile: []byte(stackFileContent),
},
})
if err != nil {
return err
}

return fabric.PutDeployment(ctx, &defangv1.PutDeploymentRequest{
Deployment: &defangv1.Deployment{
Action: req.Action,
Expand All @@ -66,7 +90,7 @@ func putDeployment(ctx context.Context, provider client.Provider, fabric client.
Region: accountInfo.Region,
ServiceCount: int32(req.ServiceCount), // #nosec G115 - service count will not overflow int32
Stack: provider.GetStackName(),
Timestamp: timestamppb.Now(),
Timestamp: deployedAt,
Mode: req.Mode,
StatesUrl: req.StatesUrl,
EventsUrl: req.EventsUrl,
Expand Down
5 changes: 3 additions & 2 deletions src/pkg/cli/composeUp.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import (
"github.com/DefangLabs/defang/src/pkg/cli/compose"
"github.com/DefangLabs/defang/src/pkg/dryrun"
"github.com/DefangLabs/defang/src/pkg/modes"
"github.com/DefangLabs/defang/src/pkg/stacks"
"github.com/DefangLabs/defang/src/pkg/term"
defangv1 "github.com/DefangLabs/defang/src/protos/io/defang/v1"
)
Expand All @@ -27,7 +28,7 @@ type ComposeUpParams struct {
}

// ComposeUp validates a compose project and uploads the services using the client
func ComposeUp(ctx context.Context, fabric client.FabricClient, provider client.Provider, params ComposeUpParams) (*defangv1.DeployResponse, *compose.Project, error) {
func ComposeUp(ctx context.Context, fabric client.FabricClient, provider client.Provider, stack *stacks.StackParameters, params ComposeUpParams) (*defangv1.DeployResponse, *compose.Project, error) {
upload := params.UploadMode
project := params.Project
mode := params.Mode
Expand Down Expand Up @@ -143,7 +144,7 @@ func ComposeUp(ctx context.Context, fabric client.FabricClient, provider client.
action = defangv1.DeploymentAction_DEPLOYMENT_ACTION_UP
}

err = putDeployment(ctx, provider, fabric, putDeploymentParams{
err = putDeploymentAndStack(ctx, provider, fabric, stack, putDeploymentParams{
Action: action,
ETag: resp.Etag,
Mode: mode.Value(),
Expand Down
15 changes: 12 additions & 3 deletions src/pkg/cli/composeUp_dockerfile_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import (
"github.com/DefangLabs/defang/src/pkg/cli/client"
"github.com/DefangLabs/defang/src/pkg/cli/compose"
"github.com/DefangLabs/defang/src/pkg/modes"
"github.com/DefangLabs/defang/src/pkg/stacks"
)

func TestComposeUp_DockerfileValidation(t *testing.T) {
Expand Down Expand Up @@ -41,11 +42,15 @@ func TestComposeUp_DockerfileValidation(t *testing.T) {
t.Fatalf("Failed to load project: %v", err)
}

stack := &stacks.StackParameters{
Provider: client.ProviderDefang, // Use a valid provider to avoid panic
}

// Try to do a ComposeUp with the project
mockFabric := client.MockFabricClient{DelegateDomain: "example.com"}
mockProvider := &mockDeployProvider{MockProvider: client.MockProvider{}}

_, _, err = ComposeUp(ctx, mockFabric, mockProvider, ComposeUpParams{
_, _, err = ComposeUp(ctx, mockFabric, mockProvider, stack, ComposeUpParams{
Project: project,
UploadMode: compose.UploadModeDigest, // This should trigger validation
Mode: modes.ModeUnspecified,
Expand Down Expand Up @@ -80,11 +85,15 @@ func TestComposeUp_DockerfileValidationSkipped(t *testing.T) {
t.Fatalf("Failed to load project: %v", err)
}

stack := &stacks.StackParameters{
Provider: client.ProviderDefang, // Use a valid provider to avoid panic
}

mockFabric := client.MockFabricClient{DelegateDomain: "example.com"}
mockProvider := &mockDeployProvider{MockProvider: client.MockProvider{}}

// Test that validation is skipped for UploadModeIgnore (dry-run)
_, _, err = ComposeUp(ctx, mockFabric, mockProvider, ComposeUpParams{
_, _, err = ComposeUp(ctx, mockFabric, mockProvider, stack, ComposeUpParams{
Project: project,
UploadMode: compose.UploadModeIgnore, // Should skip validation
Mode: modes.ModeUnspecified,
Expand All @@ -96,7 +105,7 @@ func TestComposeUp_DockerfileValidationSkipped(t *testing.T) {
}

// Test that validation is skipped for UploadModeEstimate
_, _, err = ComposeUp(ctx, mockFabric, mockProvider, ComposeUpParams{
_, _, err = ComposeUp(ctx, mockFabric, mockProvider, stack, ComposeUpParams{
Project: project,
UploadMode: compose.UploadModeEstimate, // Should skip validation
Mode: modes.ModeUnspecified,
Expand Down
15 changes: 12 additions & 3 deletions src/pkg/cli/composeUp_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import (
"github.com/DefangLabs/defang/src/pkg/cli/compose"
"github.com/DefangLabs/defang/src/pkg/dryrun"
"github.com/DefangLabs/defang/src/pkg/modes"
"github.com/DefangLabs/defang/src/pkg/stacks"
"github.com/DefangLabs/defang/src/pkg/types"
defangv1 "github.com/DefangLabs/defang/src/protos/io/defang/v1"
)
Expand Down Expand Up @@ -100,7 +101,10 @@ func TestComposeUp(t *testing.T) {

mc := client.MockFabricClient{DelegateDomain: "example.com"}
mp := &mockDeployProvider{MockProvider: client.MockProvider{UploadUrl: server.URL + "/"}}
d, project, err := ComposeUp(t.Context(), mc, mp, ComposeUpParams{
stack := &stacks.StackParameters{
Provider: client.ProviderDefang,
}
d, project, err := ComposeUp(t.Context(), mc, mp, stack, ComposeUpParams{
Mode: modes.ModeAffordable,
Project: proj,
UploadMode: compose.UploadModeDigest,
Expand Down Expand Up @@ -288,7 +292,11 @@ func TestComposeUpStops(t *testing.T) {
deploymentStatus: tt.cdStatus,
}

resp, project, err := ComposeUp(ctx, fabric, provider, ComposeUpParams{
stack := &stacks.StackParameters{
Provider: client.ProviderDefang,
}

resp, project, err := ComposeUp(ctx, fabric, provider, stack, ComposeUpParams{
Mode: modes.ModeUnspecified,
Project: project,
UploadMode: compose.UploadModeDigest,
Expand Down Expand Up @@ -321,8 +329,9 @@ func TestComposeConfigWithoutLogin(t *testing.T) {
provider := &client.PlaygroundProvider{FabricClient: fabric}

project := &compose.Project{}
stack := &stacks.StackParameters{}

_, _, err := ComposeUp(t.Context(), fabric, provider, ComposeUpParams{
_, _, err := ComposeUp(t.Context(), fabric, provider, stack, ComposeUpParams{
Mode: modes.ModeUnspecified,
Project: project,
UploadMode: compose.UploadModeIgnore,
Expand Down
2 changes: 1 addition & 1 deletion src/pkg/cli/preview.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import (
)

func Preview(ctx context.Context, project *compose.Project, fabric client.FabricClient, provider client.Provider, params ComposeUpParams) error {
resp, project, err := ComposeUp(ctx, fabric, provider, params)
resp, project, err := ComposeUp(ctx, fabric, provider, nil, params)
if err != nil {
return err
}
Expand Down
Loading
Loading