@@ -79,10 +79,14 @@ func Execute(ctx context.Context) error {
79
79
printDefangHint ("Fix the error and try again. To validate the compose file, use:" , compose + " config" )
80
80
}
81
81
82
- if strings .Contains (err .Error (), "secret " ) {
82
+ if strings .Contains (err .Error (), "config " ) {
83
83
printDefangHint ("To manage sensitive service config, use:" , "config" )
84
84
}
85
85
86
+ if err .Error () == "resource_exhausted: maximum number of projects reached" {
87
+ printDefangHint ("To deactivate a project, do:" , "compose down" )
88
+ }
89
+
86
90
var cerr * cli.CancelError
87
91
if errors .As (err , & cerr ) {
88
92
printDefangHint ("Detached. The process will keep running.\n To continue the logs from where you left off, do:" , cerr .Error ())
@@ -820,7 +824,6 @@ var composeUpCmd = &cobra.Command{
820
824
var force , _ = cmd .Flags ().GetBool ("force" )
821
825
var detach , _ = cmd .Flags ().GetBool ("detach" )
822
826
823
- targetState := defangv1 .ServiceState_SERVICE_COMPLETED
824
827
since := time .Now ()
825
828
deploy , project , err := cli .ComposeUp (cmd .Context (), client , force )
826
829
if err != nil {
@@ -839,35 +842,38 @@ var composeUpCmd = &cobra.Command{
839
842
}
840
843
841
844
tailCtx , cancelTail := context .WithCancelCause (cmd .Context ())
842
- defer cancelTail (nil ) // to cancel waitServiceState
845
+ defer cancelTail (nil ) // to cancel WaitServiceState and clean-up context
843
846
844
- errSuccess := errors .New ("deployment succeeded" )
847
+ errCompleted := errors .New ("deployment succeeded" ) // tail canceled because of deployment completion
848
+ const targetState = defangv1 .ServiceState_DEPLOYMENT_COMPLETED
845
849
targetStateReached := false
846
850
847
851
go func () {
848
852
services := make ([]string , len (deploy .Services ))
849
853
for i , serviceInfo := range deploy .Services {
850
854
services [i ] = serviceInfo .Service .Name
851
855
}
852
- if err := waitServiceState (tailCtx , targetState , deploy .Etag , services ); err != nil {
853
- if errors .Is (err , errDeploymentFailed ) {
856
+
857
+ if err := cli .WaitServiceState (tailCtx , client , targetState , deploy .Etag , services ); err != nil {
858
+ var errDeploymentFailed cli.ErrDeploymentFailed
859
+ if errors .As (err , & errDeploymentFailed ) {
854
860
cancelTail (err )
855
861
} else if ! errors .Is (err , context .Canceled ) {
856
- term .Warnf ("failed to wait for service status: %v" , err )
862
+ term .Warnf ("failed to wait for service status: %v" , err ) // TODO: don't print in Go-routine
857
863
}
858
864
} else {
859
865
targetStateReached = true
860
- cancelTail (errSuccess )
866
+ cancelTail (errCompleted )
861
867
}
862
868
}()
863
869
864
870
// show users the current streaming logs
865
- services := "all services"
871
+ tailSource := "all services"
866
872
if deploy .Etag != "" {
867
- services = "deployment ID " + deploy .Etag
873
+ tailSource = "deployment ID " + deploy .Etag
868
874
}
869
875
870
- term .Info ("Tailing logs for" , services , "; press Ctrl+C to detach:" )
876
+ term .Info ("Tailing logs for" , tailSource , "; press Ctrl+C to detach:" )
871
877
tailParams := cli.TailOptions {
872
878
Etag : deploy .Etag ,
873
879
Since : since ,
@@ -876,29 +882,42 @@ var composeUpCmd = &cobra.Command{
876
882
877
883
// blocking call to tail
878
884
if err := cli .Tail (tailCtx , client , tailParams ); err != nil {
879
- if errors .Is (context .Cause (tailCtx ), errDeploymentFailed ) {
880
- term .Warn ("Deployment FAILED. Service(s) not running." )
885
+ term .Debugf ("Tail failed with %v" , err )
886
+ if connect .CodeOf (err ) == connect .CodePermissionDenied {
887
+ // If tail fails because of missing permission, we wait for the deployment to finish
888
+ term .Warn ("Unable to tail logs. Waiting for the deployment to finish." )
889
+ <- tailCtx .Done ()
890
+ } else if ! errors .Is (tailCtx .Err (), context .Canceled ) {
891
+ return err // any error other than cancelation
892
+ }
881
893
882
- _ , isPlayground := client .(* cliClient.PlaygroundClient )
883
- if ! nonInteractive && isPlayground {
894
+ // Tail got canceled; if it was by anything other than completion, prompt to show debugger
895
+ if ! errors .Is (context .Cause (tailCtx ), errCompleted ) {
896
+ var failedServices []string
897
+ var errDeploymentFailed cli.ErrDeploymentFailed
898
+ if errors .As (context .Cause (tailCtx ), & errDeploymentFailed ) {
899
+ term .Warn (errDeploymentFailed )
900
+ failedServices = []string {errDeploymentFailed .Service , errDeploymentFailed .Service + "-image" } // HACK: also grab Kaniko logs
901
+ } else {
902
+ term .Warn ("Deployment is not finished. Service(s) might not be running." )
903
+ // TODO: some services might be OK and we should only debug the ones that are not
904
+ }
905
+
906
+ if _ , isPlayground := client .(* cliClient.PlaygroundClient ); ! nonInteractive && isPlayground {
884
907
var aiDebug bool
885
908
if err := survey .AskOne (& survey.Confirm {
886
909
Message : "Would you like to debug the deployment with AI?" ,
887
910
Help : "This will send logs and artifacts to our backend and attempt to diagnose the issue and provide a solution." ,
888
911
}, & aiDebug ); err != nil {
889
912
term .Debugf ("failed to ask for AI debug: %v" , err )
890
913
} else if aiDebug {
891
- // Call the AI debug endpoint using the original command context (not the tailCtx which is canceled)
892
- if err := cli .Debug (cmd .Context (), client , deploy .Etag , project .WorkingDir ); err != nil {
914
+ // Call the AI debug endpoint using the original command context (not the tailCtx which is canceled); HACK: cmd might be canceled too
915
+ // TODO: use the WorkingDir of the failed service, might not be the project's root
916
+ if err := cli .Debug (context .TODO (), client , deploy .Etag , project .WorkingDir , failedServices ); err != nil {
893
917
term .Warnf ("failed to debug deployment: %v" , err )
894
918
}
895
919
}
896
920
}
897
- } else if connect .CodeOf (err ) == connect .CodePermissionDenied {
898
- // If tail fails because of missing permission, we wait for the deployment to finish
899
- term .Warn ("Failed to tail logs. Waiting for the deployment to finish." )
900
- <- tailCtx .Done ()
901
- } else if ! errors .Is (context .Cause (tailCtx ), errSuccess ) {
902
921
return err
903
922
}
904
923
}
@@ -952,7 +971,8 @@ var debugCmd = &cobra.Command{
952
971
RunE : func (cmd * cobra.Command , args []string ) error {
953
972
etag , _ := cmd .Flags ().GetString ("etag" )
954
973
955
- return cli .Debug (cmd .Context (), client , etag , "." )
974
+ // TODO: use the WorkingDir of the current project instead of current folder
975
+ return cli .Debug (cmd .Context (), client , etag , "." , nil )
956
976
},
957
977
}
958
978
0 commit comments