@@ -3,13 +3,17 @@ package cmd
33import (
44 "context"
55 "fmt"
6+ "os"
67 "strconv"
8+ "time"
79
10+ "github.com/logrusorgru/aurora"
811 "github.com/uselagoon/lagoon-cli/pkg/output"
912
1013 lclient "github.com/uselagoon/machinery/api/lagoon/client"
1114
1215 "github.com/spf13/cobra"
16+ lagoonssh "github.com/uselagoon/lagoon-cli/pkg/lagoon/ssh"
1317 "github.com/uselagoon/machinery/api/lagoon"
1418 "github.com/uselagoon/machinery/api/schema"
1519)
@@ -47,6 +51,10 @@ use 'lagoon deploy latest' instead`,
4751 if err != nil {
4852 return err
4953 }
54+ follow , err := cmd .Flags ().GetBool ("follow" )
55+ if err != nil {
56+ return err
57+ }
5058 if err := requiredInputCheck ("Project name" , cmdProjectName , "Branch name" , branch ); err != nil {
5159 return err
5260 }
@@ -85,6 +93,10 @@ use 'lagoon deploy latest' instead`,
8593 resultData := output.Result {Result : result .DeployEnvironmentBranch }
8694 r := output .RenderResult (resultData , outputOptions )
8795 fmt .Fprintf (cmd .OutOrStdout (), "%s" , r )
96+
97+ if follow {
98+ return followDeployLogs (cmd , cmdProjectName , branch , resultData .Result , debug )
99+ }
88100 }
89101 return nil
90102 },
@@ -115,6 +127,10 @@ var deployPromoteCmd = &cobra.Command{
115127 if err != nil {
116128 return err
117129 }
130+ follow , err := cmd .Flags ().GetBool ("follow" )
131+ if err != nil {
132+ return err
133+ }
118134 if err := requiredInputCheck ("Project name" , cmdProjectName , "Source environment" , sourceEnvironment , "Destination environment" , destinationEnvironment ); err != nil {
119135 return err
120136 }
@@ -150,6 +166,10 @@ var deployPromoteCmd = &cobra.Command{
150166 resultData := output.Result {Result : result .DeployEnvironmentPromote }
151167 r := output .RenderResult (resultData , outputOptions )
152168 fmt .Fprintf (cmd .OutOrStdout (), "%s" , r )
169+
170+ if follow {
171+ return followDeployLogs (cmd , cmdProjectName , destinationEnvironment , resultData .Result , debug )
172+ }
153173 }
154174 return nil
155175 },
@@ -175,6 +195,10 @@ This environment should already exist in lagoon. It is analogous with the 'Deplo
175195 if err != nil {
176196 return err
177197 }
198+ follow , err := cmd .Flags ().GetBool ("follow" )
199+ if err != nil {
200+ return err
201+ }
178202
179203 buildVarStrings , err := cmd .Flags ().GetStringArray ("buildvar" )
180204 if err != nil {
@@ -213,6 +237,10 @@ This environment should already exist in lagoon. It is analogous with the 'Deplo
213237 resultData := output.Result {Result : result .DeployEnvironmentLatest }
214238 r := output .RenderResult (resultData , outputOptions )
215239 fmt .Fprintf (cmd .OutOrStdout (), "%s" , r )
240+
241+ if follow {
242+ return followDeployLogs (cmd , cmdProjectName , cmdProjectEnvironment , resultData .Result , debug )
243+ }
216244 }
217245 return nil
218246 },
@@ -273,6 +301,11 @@ This pullrequest may not already exist as an environment in lagoon.`,
273301 if err != nil {
274302 return err
275303 }
304+ follow , err := cmd .Flags ().GetBool ("follow" )
305+ if err != nil {
306+ return err
307+ }
308+
276309 if yesNo (fmt .Sprintf ("You are attempting to deploy pull request '%v' for project '%s', are you sure?" , prNumber , cmdProjectName )) {
277310 current := lagoonCLIConfig .Current
278311 token := lagoonCLIConfig .Lagoons [current ].Token
@@ -302,6 +335,10 @@ This pullrequest may not already exist as an environment in lagoon.`,
302335 resultData := output.Result {Result : result .DeployEnvironmentPullrequest }
303336 r := output .RenderResult (resultData , outputOptions )
304337 fmt .Fprintf (cmd .OutOrStdout (), "%s" , r )
338+
339+ if follow {
340+ return followDeployLogs (cmd , cmdProjectName , fmt .Sprintf ("pr-%d" , prNumber ), resultData .Result , debug )
341+ }
305342 }
306343 return nil
307344 },
@@ -315,16 +352,19 @@ func init() {
315352
316353 const returnDataUsageText = "Returns the build name instead of success text"
317354 deployLatestCmd .Flags ().Bool ("returndata" , false , returnDataUsageText )
355+ deployLatestCmd .Flags ().Bool ("follow" , false , "Follow the deploy logs" )
318356 deployLatestCmd .Flags ().StringArray ("buildvar" , []string {}, "Add one or more build variables to deployment (--buildvar KEY1=VALUE1 [--buildvar KEY2=VALUE2])" )
319357
320358 deployBranchCmd .Flags ().StringP ("branch" , "b" , "" , "Branch name to deploy" )
321359 deployBranchCmd .Flags ().StringP ("branch-ref" , "r" , "" , "Branch ref to deploy" )
322360 deployBranchCmd .Flags ().Bool ("returndata" , false , returnDataUsageText )
361+ deployBranchCmd .Flags ().Bool ("follow" , false , "Follow the deploy logs" )
323362 deployBranchCmd .Flags ().StringArray ("buildvar" , []string {}, "Add one or more build variables to deployment (--buildvar KEY1=VALUE1 [--buildvar KEY2=VALUE2])" )
324363
325364 deployPromoteCmd .Flags ().StringP ("destination" , "d" , "" , "Destination environment name to create" )
326365 deployPromoteCmd .Flags ().StringP ("source" , "s" , "" , "Source environment name to use as the base to deploy from" )
327366 deployPromoteCmd .Flags ().Bool ("returndata" , false , returnDataUsageText )
367+ deployPromoteCmd .Flags ().Bool ("follow" , false , "Follow the deploy logs" )
328368 deployPromoteCmd .Flags ().StringArray ("buildvar" , []string {}, "Add one or more build variables to deployment (--buildvar KEY1=VALUE1 [--buildvar KEY2=VALUE2])" )
329369
330370 deployPullrequestCmd .Flags ().StringP ("title" , "t" , "" , "Pullrequest title" )
@@ -334,5 +374,87 @@ func init() {
334374 deployPullrequestCmd .Flags ().StringP ("head-branch-name" , "H" , "" , "Pullrequest head branch name" )
335375 deployPullrequestCmd .Flags ().StringP ("head-branch-ref" , "M" , "" , "Pullrequest head branch reference hash" )
336376 deployPullrequestCmd .Flags ().Bool ("returndata" , false , returnDataUsageText )
377+ deployPullrequestCmd .Flags ().Bool ("follow" , false , "Follow the deploy logs" )
337378 deployPullrequestCmd .Flags ().StringArray ("buildvar" , []string {}, "Add one or more build variables to deployment (--buildvar KEY1=VALUE1 [--buildvar KEY2=VALUE2])" )
338379}
380+
381+ func followDeployLogs (
382+ cmd * cobra.Command ,
383+ projectName ,
384+ environmentName ,
385+ buildName string ,
386+ debug bool ,
387+ ) error {
388+ safeEnvName := makeSafe (shortenEnvironment (projectName , environmentName ))
389+ sshHost , sshPort , username , _ , err := getSSHHostPort (safeEnvName , debug )
390+ if err != nil {
391+ return fmt .Errorf ("couldn't get SSH endpoint: %v" , err )
392+ }
393+ ignoreHostKey , acceptNewHostKey :=
394+ lagoonssh .CheckStrictHostKey (strictHostKeyCheck )
395+ sshConfig , closeSSHAgent , err := getSSHClientConfig (
396+ username ,
397+ fmt .Sprintf ("%s:%s" , sshHost , sshPort ),
398+ ignoreHostKey ,
399+ acceptNewHostKey )
400+ if err != nil {
401+ return fmt .Errorf ("couldn't get SSH client config: %v" , err )
402+ }
403+ defer func () {
404+ err = closeSSHAgent ()
405+ if err != nil {
406+ fmt .Fprintf (os .Stderr , "error closing ssh agent:%v\n " , err )
407+ }
408+ }()
409+ ctx , cancel := context .WithCancel (context .Background ())
410+ defer cancel ()
411+ // start background ticker to close session when deploy completes
412+ ticker := time .NewTicker (10 * time .Second )
413+ defer ticker .Stop ()
414+ go func () {
415+ defer cancel ()
416+ for {
417+ select {
418+ case <- ctx .Done ():
419+ return
420+ case <- ticker .C :
421+ validateToken (lagoonCLIConfig .Current )
422+ current := lagoonCLIConfig .Current
423+ token := lagoonCLIConfig .Lagoons [current ].Token
424+ lc := lclient .New (
425+ lagoonCLIConfig .Lagoons [current ].GraphQL ,
426+ lagoonCLIVersion ,
427+ lagoonCLIConfig .Lagoons [current ].Version ,
428+ & token ,
429+ debug )
430+ // ignore errors here since we can't really do anything about them
431+ deployment , _ := lagoon .GetDeploymentByName (
432+ ctx , cmdProjectName , cmdProjectEnvironment , buildName , false , lc )
433+ if deployment .Completed != "" && deployment .Status != "running" {
434+ var status string
435+ switch deployment .Status {
436+ case "complete" :
437+ status = "complete ✅"
438+ case "failed" :
439+ status = "failed ❌"
440+ case "cancelled" :
441+ status = "cancelled 🛑"
442+ default :
443+ status = deployment .Status
444+ }
445+ fmt .Fprintf (
446+ cmd .OutOrStdout (),
447+ "Deployment %s finished with status: %s\n " ,
448+ aurora .Yellow (buildName ),
449+ status )
450+ return
451+ }
452+ }
453+ }
454+ }()
455+ fmt .Fprintf (cmd .OutOrStdout (), "Streaming deploy logs...\n " )
456+ return lagoonssh .LogStream (ctx , sshConfig , sshHost , sshPort , []string {
457+ "lagoonSystem=build" ,
458+ "logs=tailLines=32,follow" ,
459+ })
460+ }
0 commit comments