@@ -2,14 +2,17 @@ package cmd
22
33import (
44 "fmt"
5- runtimevar "github.com/loft-sh/devspace/pkg/devspace/config/loader/variable/runtime"
6- "github.com/loft-sh/devspace/pkg/devspace/imageselector"
75 "io"
86 "os"
7+ "os/exec"
98 "strings"
109 "sync"
1110 "time"
1211
12+ runtimevar "github.com/loft-sh/devspace/pkg/devspace/config/loader/variable/runtime"
13+ "github.com/loft-sh/devspace/pkg/devspace/imageselector"
14+ "github.com/loft-sh/devspace/pkg/util/command"
15+
1316 "github.com/loft-sh/devspace/pkg/devspace/config"
1417 "github.com/loft-sh/devspace/pkg/devspace/config/legacy"
1518 "github.com/loft-sh/devspace/pkg/devspace/dependency/types"
@@ -600,30 +603,52 @@ func (cmd *DevCmd) startOutput(configInterface config.Config, dependencies []typ
600603 return 0 , pluginErr
601604 }
602605
603- selectorOptions := targetselector .NewDefaultOptions ().ApplyCmdParameter ("" , "" , cmd .Namespace , "" )
604- if config .Dev .Terminal != nil {
605- selectorOptions = selectorOptions .ApplyConfigParameter (config .Dev .Terminal .LabelSelector , config .Dev .Terminal .Namespace , config .Dev .Terminal .ContainerName , "" )
606- }
606+ stdout , stderr , stdin := defaultStdStreams (cmd .Stdout , cmd .Stderr , cmd .Stdin )
607607
608- var imageSelectors []imageselector.ImageSelector
609- if config .Dev .Terminal != nil && config .Dev .Terminal .ImageSelector != "" {
610- imageSelector , err := runtimevar .NewRuntimeResolver (true ).FillRuntimeVariablesAsImageSelector (config .Dev .Terminal .ImageSelector , configInterface , dependencies )
608+ // if config.Dev.Terminal is defined
609+ // config.Dev.Terminal.ImageSelector is empty &&
610+ // config.Dev.Terminal.LabelSelector is also empty &&
611+ // config.Dev.Terminal.Command is defined then
612+ // run the command locally instead on in container
613+ if config .Dev .Terminal .ImageSelector == "" &&
614+ config .Dev .Terminal .LabelSelector == nil &&
615+ config .Dev .Terminal .Command != nil &&
616+ len (config .Dev .Terminal .Command ) > 0 {
617+ c := command .NewStreamCommand (config .Dev .Terminal .Command [0 ], config .Dev .Terminal .Command [1 :])
618+ err := c .Run (stdout , stderr , stdin )
611619 if err != nil {
612- return 0 , err
620+ if exitError , ok := err .(* exec.ExitError ); ok {
621+ cmd .log .Failf ("Command '%s' returned an error: %s" , config .Dev .Terminal .Command [0 ], err )
622+ return exitError .ExitCode (), err
623+ }
624+ }
625+ return 0 , nil
626+ } else {
627+ selectorOptions := targetselector .NewDefaultOptions ().ApplyCmdParameter ("" , "" , cmd .Namespace , "" )
628+ if config .Dev .Terminal != nil {
629+ selectorOptions = selectorOptions .ApplyConfigParameter (config .Dev .Terminal .LabelSelector , config .Dev .Terminal .Namespace , config .Dev .Terminal .ContainerName , "" )
613630 }
614631
615- imageSelectors = append (imageSelectors , * imageSelector )
616- }
632+ var imageSelectors []imageselector.ImageSelector
633+ if config .Dev .Terminal != nil && config .Dev .Terminal .ImageSelector != "" {
634+ imageSelector , err := runtimevar .NewRuntimeResolver (true ).FillRuntimeVariablesAsImageSelector (config .Dev .Terminal .ImageSelector , configInterface , dependencies )
635+ if err != nil {
636+ return 0 , err
637+ }
617638
618- cmd .log .Info ("Terminal: Waiting for containers to start..." )
619- selectorOptions .ImageSelector = imageSelectors
620- stdout , stderr , stdin := defaultStdStreams (cmd .Stdout , cmd .Stderr , cmd .Stdin )
621- code , err := servicesClient .StartTerminal (selectorOptions , args , cmd .WorkingDirectory , exitChan , true , cmd .TerminalReconnect , stdout , stderr , stdin )
622- if services .IsUnexpectedExitCode (code ) {
623- cmd .log .Warnf ("Command terminated with exit code %d" , code )
624- }
639+ imageSelectors = append (imageSelectors , * imageSelector )
640+ }
625641
626- return code , err
642+ cmd .log .Info ("Terminal: Waiting for containers to start..." )
643+ selectorOptions .ImageSelector = imageSelectors
644+
645+ code , err := servicesClient .StartTerminal (selectorOptions , args , cmd .WorkingDirectory , exitChan , true , cmd .TerminalReconnect , stdout , stderr , stdin )
646+ if services .IsUnexpectedExitCode (code ) {
647+ cmd .log .Warnf ("Command terminated with exit code %d" , code )
648+ }
649+
650+ return code , err
651+ }
627652 } else if config .Dev .Logs == nil || config .Dev .Logs .Disabled == nil || ! * config .Dev .Logs .Disabled {
628653 pluginErr := hook .ExecuteHooks (client , configInterface , dependencies , nil , cmd .log , "devCommand:before:streamLogs" )
629654 if pluginErr != nil {
@@ -754,32 +779,31 @@ func (cmd *DevCmd) loadConfig(configOptions *loader.ConfigOptions) (config.Confi
754779 // check if terminal is enabled
755780 c := configInterface .Config ()
756781
757- if cmd .Terminal || (c .Dev .Terminal != nil && ! c .Dev .Terminal .Disabled ) {
758- if c .Dev .Terminal == nil || (c .Dev .Terminal .ImageSelector == "" && len (c .Dev .Terminal .LabelSelector ) == 0 ) {
759- imageNames := make ([]string , 0 , len (c .Images ))
760- for k := range c .Images {
761- imageNames = append (imageNames , k )
762- }
782+ if cmd .Terminal && c .Dev .Terminal == nil {
783+ if len (c .Images ) == 0 {
784+ return nil , errors .New ("No image available in devspace config" )
785+ }
763786
764- // if only one image exists, use it, otherwise show image picker
765- imageName := ""
766- if len (imageNames ) == 1 {
767- imageName = imageNames [0 ]
768- } else {
769- imageName , err = cmd .log .Question (& survey.QuestionOptions {
770- Question : "Which image do you want to open a terminal to?" ,
771- Options : imageNames ,
772- })
773- if err != nil {
774- return nil , err
775- }
776- }
787+ imageNames := make ([]string , 0 , len (c .Images ))
788+ for k := range c .Images {
789+ imageNames = append (imageNames , k )
790+ }
777791
778- c .Dev .Terminal = & latest.Terminal {
779- ImageSelector : fmt .Sprintf ("${runtime.images.%s.image}:${runtime.images.%s.tag}" , imageName , imageName ),
780- }
792+ // if only one image exists, use it, otherwise show image picker
793+ imageName := ""
794+ if len (imageNames ) == 1 {
795+ imageName = imageNames [0 ]
781796 } else {
782- c .Dev .Terminal .Disabled = false
797+ imageName , err = cmd .log .Question (& survey.QuestionOptions {
798+ Question : "Which image do you want to open a terminal to?" ,
799+ Options : imageNames ,
800+ })
801+ if err != nil {
802+ return nil , err
803+ }
804+ }
805+ c .Dev .Terminal = & latest.Terminal {
806+ ImageSelector : fmt .Sprintf ("${runtime.images.%s.image}:${runtime.images.%s.tag}" , imageName , imageName ),
783807 }
784808 }
785809
0 commit comments