Skip to content

Commit

Permalink
Merge pull request #473 from DefangLabs/edw-load-proj-name-from-remote
Browse files Browse the repository at this point in the history
Load project name from remote when not in a compose folder
  • Loading branch information
lionello committed Jun 14, 2024
2 parents 2a7a943 + b0bd462 commit 6bef820
Show file tree
Hide file tree
Showing 17 changed files with 117 additions and 26 deletions.
7 changes: 7 additions & 0 deletions src/cmd/cli/command/commands.go
Original file line number Diff line number Diff line change
Expand Up @@ -674,6 +674,13 @@ var configSetCmd = &cobra.Command{
Aliases: []string{"set", "add", "put"},
Short: "Adds or updates a sensitive config value",
RunE: func(cmd *cobra.Command, args []string) error {

// Make sure we have a project to set config for before asking for a value
_, err := client.LoadProjectName(cmd.Context())
if err != nil {
return err
}

parts := strings.SplitN(args[0], "=", 2)
name := parts[0]

Expand Down
4 changes: 2 additions & 2 deletions src/pkg/cli/bootstrap.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,12 @@ import (
)

func BootstrapCommand(ctx context.Context, client client.Client, command string) error {
project, err := client.LoadProject(ctx)
projectName, err := client.LoadProjectName(ctx)
if err != nil {
return err
}

term.Debug("Running CD command", command, "in project", project.Name)
term.Debug("Running CD command", command, "in project", projectName)
if DoDryRun {
return ErrDryRun
}
Expand Down
5 changes: 2 additions & 3 deletions src/pkg/cli/cert.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,12 +27,11 @@ var resolver dns.Resolver = dns.RootResolver{}
var httpClient HTTPClient = http.DefaultClient

func GenerateLetsEncryptCert(ctx context.Context, client cliClient.Client) error {
project, err := client.LoadProject(ctx)
projectName, err := client.LoadProjectName(ctx)
if err != nil {
return err
}

term.Debug("Generating TLS cert for project", project.Name)
term.Debug("Generating TLS cert for project", projectName)

services, err := client.GetServices(ctx)
if err != nil {
Expand Down
6 changes: 3 additions & 3 deletions src/pkg/cli/client/byoc/aws/byoc.go
Original file line number Diff line number Diff line change
Expand Up @@ -46,10 +46,10 @@ var _ client.Client = (*ByocAws)(nil)

func NewByoc(ctx context.Context, grpcClient client.GrpcClient, tenantId types.TenantID) *ByocAws {
b := &ByocAws{
ByocBaseClient: byoc.NewByocBaseClient(ctx, grpcClient, tenantId),
cdTasks: make(map[string]ecs.TaskArn),
driver: cfn.New(byoc.CdTaskPrefix, aws.Region("")), // default region
cdTasks: make(map[string]ecs.TaskArn),
driver: cfn.New(byoc.CdTaskPrefix, aws.Region("")), // default region
}
b.ByocBaseClient = byoc.NewByocBaseClient(ctx, grpcClient, tenantId, b)
return b
}

Expand Down
58 changes: 56 additions & 2 deletions src/pkg/cli/client/byoc/baseclient.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,20 @@ package byoc

import (
"context"
"errors"
"fmt"
"os"
"slices"
"strings"
"sync"

"github.com/DefangLabs/defang/src/pkg"
"github.com/DefangLabs/defang/src/pkg/cli/client"
"github.com/DefangLabs/defang/src/pkg/quota"
"github.com/DefangLabs/defang/src/pkg/term"
"github.com/DefangLabs/defang/src/pkg/types"
defangv1 "github.com/DefangLabs/defang/src/protos/io/defang/v1"
"github.com/compose-spec/compose-go/v2/consts"
compose "github.com/compose-spec/compose-go/v2/types"
)

Expand All @@ -32,6 +38,10 @@ func DnsSafe(fqdn string) string {
return strings.ToLower(fqdn)
}

type BootstrapLister interface {
BootstrapList(context.Context) ([]string, error)
}

type ByocBaseClient struct {
client.GrpcClient

Expand All @@ -46,10 +56,11 @@ type ByocBaseClient struct {
ShouldDelegateSubdomain bool
TenantID string

loadProjOnce func() (*compose.Project, error)
loadProjOnce func() (*compose.Project, error)
bootstrapLister BootstrapLister
}

func NewByocBaseClient(ctx context.Context, grpcClient client.GrpcClient, tenantID types.TenantID) *ByocBaseClient {
func NewByocBaseClient(ctx context.Context, grpcClient client.GrpcClient, tenantID types.TenantID, bl BootstrapLister) *ByocBaseClient {
b := &ByocBaseClient{
GrpcClient: grpcClient,
TenantID: string(tenantID),
Expand All @@ -64,6 +75,7 @@ func NewByocBaseClient(ctx context.Context, grpcClient client.GrpcClient, tenant
Services: 40,
ShmSizeMiB: 30720,
},
bootstrapLister: bl,
}
b.loadProjOnce = sync.OnceValues(func() (*compose.Project, error) {
proj, err := b.GrpcClient.Loader.LoadCompose(ctx)
Expand All @@ -86,6 +98,48 @@ func (b *ByocBaseClient) LoadProject(ctx context.Context) (*compose.Project, err
return b.loadProjOnce()
}

func (b *ByocBaseClient) LoadProjectName(ctx context.Context) (string, error) {

proj, err := b.Loader.LoadCompose(ctx)
if err == nil {
b.PulumiProject = proj.Name
return proj.Name, nil
}
if !errors.Is(err, types.ErrComposeFileNotFound) {
return "", err
}

// Get the list of projects from remote
projectNames, err := b.bootstrapLister.BootstrapList(ctx)
if err != nil {
return "", err
}
for i, name := range projectNames {
projectNames[i] = strings.Split(name, "/")[0] // Remove the stack name
}

if len(projectNames) == 0 {
return "", errors.New("no projects found")
}
if len(projectNames) == 1 {
term.Debug("Using default project: ", projectNames[0])
b.PulumiProject = projectNames[0]
return projectNames[0], nil
}

// When there are multiple projects, take a hint from COMPOSE_PROJECT_NAME environment variable if set
if projectName, ok := os.LookupEnv(consts.ComposeProjectName); ok {
if !slices.Contains(projectNames, projectName) {
return "", fmt.Errorf("project %q specified by COMPOSE_PROJECT_NAME not found", projectName)
}
term.Debug("Using project from COMPOSE_PROJECT_NAME environment variable:", projectNames[0])
b.PulumiProject = projectName
return projectName, nil
}

return "", errors.New("multiple projects found; please go to the correct project directory where the compose file is or set COMPOSE_PROJECT_NAME")
}

func (b *ByocBaseClient) ServiceDNS(name string) string {
return DnsSafeLabel(name) // TODO: consider merging this with getPrivateFqdn
}
6 changes: 3 additions & 3 deletions src/pkg/cli/client/byoc/do/byoc.go
Original file line number Diff line number Diff line change
Expand Up @@ -40,9 +40,9 @@ func NewByoc(ctx context.Context, grpcClient client.GrpcClient, tenantId types.T
}

b := &ByocDo{
ByocBaseClient: byoc.NewByocBaseClient(ctx, grpcClient, tenantId),
driver: appPlatform.New(byoc.CdTaskPrefix, do.Region(regionString)),
driver: appPlatform.New(byoc.CdTaskPrefix, do.Region(regionString)),
}
b.ByocBaseClient = byoc.NewByocBaseClient(ctx, grpcClient, tenantId, b)

return b
}
Expand Down Expand Up @@ -132,7 +132,7 @@ func (b *ByocDo) BootstrapCommand(ctx context.Context, command string) (string,
}

func (b *ByocDo) BootstrapList(ctx context.Context) ([]string, error) {
return nil, nil
return nil, client.ErrNotImplemented("not implemented for ByocDo")
}

func (b *ByocDo) CreateUploadURL(ctx context.Context, req *defangv1.UploadURLRequest) (*defangv1.UploadURLResponse, error) {
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 @@ -57,6 +57,7 @@ type Client interface {
WhoAmI(context.Context) (*defangv1.WhoAmIResponse, error)

LoadProject(context.Context) (*compose.Project, error)
LoadProjectName(context.Context) (string, error)
}

type Property struct {
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 @@ -30,6 +30,10 @@ func (m MockClient) LoadProject(ctx context.Context) (*compose.Project, error) {
return m.Project, nil
}

func (m MockClient) LoadProjectName(ctx context.Context) (string, error) {
return m.Project.Name, nil
}

func (m MockClient) Tail(ctx context.Context, req *defangv1.TailRequest) (ServerStream[defangv1.TailResponse], error) {
if m.ServerStream != nil {
return m.ServerStream, nil
Expand Down
20 changes: 20 additions & 0 deletions src/pkg/cli/client/playground.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import (
"errors"
"fmt"

"github.com/DefangLabs/defang/src/pkg/term"
"github.com/DefangLabs/defang/src/pkg/types"
defangv1 "github.com/DefangLabs/defang/src/protos/io/defang/v1"
"github.com/bufbuild/connect-go"
Expand Down Expand Up @@ -123,3 +124,22 @@ func (g *PlaygroundClient) Restart(ctx context.Context, names ...string) (types.
func (g PlaygroundClient) ServiceDNS(name string) string {
return string(g.tenantID) + "-" + name
}

func (g PlaygroundClient) LoadProjectName(ctx context.Context) (string, error) {
proj, err := g.Loader.LoadCompose(ctx)
if err == nil {
return proj.Name, nil
}
if !errors.Is(err, types.ErrComposeFileNotFound) {
return "", err
}

// Hack: Use GetServices to get the current project name
// TODO: Use BootstrapList to get the list of projects after playground supports multiple projects
resp, err := g.GetServices(ctx)
if err != nil {
return "", err
}
term.Debug("Using default playground project: ", resp.Project)
return resp.Project, nil
}
4 changes: 2 additions & 2 deletions src/pkg/cli/composeDown.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,11 @@ import (
)

func ComposeDown(ctx context.Context, client client.Client) (types.ETag, error) {
project, err := client.LoadProject(ctx)
projectName, err := client.LoadProjectName(ctx)
if err != nil {
return "", err
}
term.Debug("Destroying project", project.Name)
term.Debug("Destroying project", projectName)

if DoDryRun {
return "", ErrDryRun
Expand Down
4 changes: 2 additions & 2 deletions src/pkg/cli/configDelete.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,11 @@ import (
)

func ConfigDelete(ctx context.Context, client client.Client, names ...string) error {
project, err := client.LoadProject(ctx)
projectName, err := client.LoadProjectName(ctx)
if err != nil {
return err
}
term.Debug("Deleting config", names, "in project", project.Name)
term.Debug("Deleting config", names, "in project", projectName)

if DoDryRun {
return ErrDryRun
Expand Down
4 changes: 2 additions & 2 deletions src/pkg/cli/configList.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,11 @@ import (
)

func ConfigList(ctx context.Context, client client.Client) error {
project, err := client.LoadProject(ctx)
projectName, err := client.LoadProjectName(ctx)
if err != nil {
return err
}
term.Debug("Listing config in project", project.Name)
term.Debug("Listing config in project", projectName)

config, err := client.ListConfig(ctx)
if err != nil {
Expand Down
4 changes: 2 additions & 2 deletions src/pkg/cli/configSet.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,11 @@ import (
)

func ConfigSet(ctx context.Context, client client.Client, name string, value string) error {
project, err := client.LoadProject(ctx)
projectName, err := client.LoadProjectName(ctx)
if err != nil {
return err
}
term.Debug("Setting config", name, "in project", project.Name)
term.Debug("Setting config", name, "in project", projectName)

if DoDryRun {
return ErrDryRun
Expand Down
4 changes: 2 additions & 2 deletions src/pkg/cli/getServices.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,11 @@ import (
)

func GetServices(ctx context.Context, client client.Client, long bool) error {
project, err := client.LoadProject(ctx)
projectName, err := client.LoadProjectName(ctx)
if err != nil {
return err
}
term.Debug("Listing services in project", project.Name)
term.Debug("Listing services in project", projectName)

serviceList, err := client.GetServices(ctx)
if err != nil {
Expand Down
3 changes: 2 additions & 1 deletion src/pkg/cli/loader.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import (
"path/filepath"

"github.com/DefangLabs/defang/src/pkg/term"
"github.com/DefangLabs/defang/src/pkg/types"
"github.com/compose-spec/compose-go/v2/cli"
compose "github.com/compose-spec/compose-go/v2/types"
"github.com/sirupsen/logrus"
Expand Down Expand Up @@ -157,7 +158,7 @@ func getComposeFilePath(userSpecifiedComposeFile string) (string, error) {
nextPath := filepath.Dir(path)
if nextPath == path {
// previous search was of root, we're done
err = fmt.Errorf("no Compose file found")
err = types.ErrComposeFileNotFound
break
}

Expand Down
4 changes: 2 additions & 2 deletions src/pkg/cli/tail.go
Original file line number Diff line number Diff line change
Expand Up @@ -136,11 +136,11 @@ func (cerr *CancelError) Unwrap() error {
}

func Tail(ctx context.Context, client client.Client, params TailOptions) error {
project, err := client.LoadProject(ctx) // TODO: Do we need to load the projects here if it is not used at all?
projectName, err := client.LoadProjectName(ctx)
if err != nil {
return err
}
term.Debug("Tailing logs in project", project.Name)
term.Debug("Tailing logs in project", projectName)

if len(params.Services) > 0 {
for _, service := range params.Services {
Expand Down
5 changes: 5 additions & 0 deletions src/pkg/types/error.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
package types

import "errors"

var ErrComposeFileNotFound = errors.New("no compose file found")

0 comments on commit 6bef820

Please sign in to comment.