@@ -16,37 +16,49 @@ import (
1616)
1717
1818const (
19- FlagTimeout = "timeout"
20- FlagProgress = "progress"
21- DefaultTimeout = 600
19+ FlagTimeout = "timeout"
20+ FlagPollInterval = "poll-interval"
21+ FlagCancelOnTimeout = "cancel-on-timeout"
22+ FlagProgress = "progress"
23+ DefaultTimeout = 600
24+ DefaultPollInterval = 10
2225)
2326
2427type WaitOptions struct {
2528 * cmd.Dependencies
26- TaskIDs []string
27- GetServerTasksCallback ServerTasksCallback
28- GetTaskDetailsCallback TaskDetailsCallback
29- Timeout int
30- ShowProgress bool
29+ TaskIDs []string
30+ GetServerTasksCallback ServerTasksCallback
31+ GetTaskDetailsCallback TaskDetailsCallback
32+ CancelServerTasksCallback ServerTasksCallback
33+ Timeout int
34+ PollInterval int
35+ CancelOnTimeout bool
36+ ShowProgress bool
3137}
3238
3339type ServerTasksCallback func ([]string ) ([]* tasks.Task , error )
3440type TaskDetailsCallback func (string ) (* tasks.TaskDetailsResource , error )
3541
36- func NewWaitOps (dependencies * cmd.Dependencies , taskIDs []string ) * WaitOptions {
42+ func NewWaitOps (dependencies * cmd.Dependencies , taskIDs []string , timeout int , pollInterval int , cancelOnTimeout bool , showProgress bool ) * WaitOptions {
3743 return & WaitOptions {
38- Dependencies : dependencies ,
39- TaskIDs : taskIDs ,
40- GetServerTasksCallback : GetServerTasksCallback (dependencies .Client ),
41- GetTaskDetailsCallback : GetTaskDetailsCallback (dependencies .Client ),
42- Timeout : DefaultTimeout ,
43- ShowProgress : false ,
44+ Dependencies : dependencies ,
45+ TaskIDs : taskIDs ,
46+ GetServerTasksCallback : getServerTasksCallback (dependencies .Client ),
47+ GetTaskDetailsCallback : getTaskDetailsCallback (dependencies .Client ),
48+ CancelServerTasksCallback : cancelServerTasksCallback (dependencies .Client ),
49+ Timeout : timeout ,
50+ PollInterval : pollInterval ,
51+ CancelOnTimeout : cancelOnTimeout ,
52+ ShowProgress : showProgress ,
4453 }
4554}
4655
4756func NewCmdWait (f factory.Factory ) * cobra.Command {
4857 var timeout int
58+ var pollInterval int
59+ var cancelOnTimeout bool
4960 var showProgress bool
61+
5062 cmd := & cobra.Command {
5163 Use : "wait [TaskIDs]" ,
5264 Short : "Wait for task(s) to finish" ,
@@ -57,18 +69,17 @@ func NewCmdWait(f factory.Factory) *cobra.Command {
5769 copy (taskIDs , args )
5870
5971 taskIDs = append (taskIDs , util .ReadValuesFromPipe ()... )
60-
6172 dependencies := cmd .NewDependencies (f , c )
62- opts := NewWaitOps (dependencies , taskIDs )
63- opts .Timeout = timeout
64- opts .ShowProgress = showProgress
73+ opts := NewWaitOps (dependencies , taskIDs , timeout , pollInterval , cancelOnTimeout , showProgress )
6574
6675 return WaitRun (opts )
6776 },
6877 }
6978
7079 flags := cmd .Flags ()
71- flags .IntVar (& timeout , FlagTimeout , DefaultTimeout , "Duration to wait (in seconds) before stopping execution" )
80+ flags .IntVar (& timeout , FlagTimeout , DefaultTimeout , "Time in seconds to wait for the tasks to complete" )
81+ flags .IntVar (& pollInterval , FlagPollInterval , DefaultPollInterval , "Polling interval in seconds to check task status during wait" )
82+ flags .BoolVar (& cancelOnTimeout , FlagCancelOnTimeout , false , "Cancel the tasks if the wait timeout is reached" )
7283 flags .BoolVar (& showProgress , FlagProgress , false , "Show detailed progress of the tasks" )
7384
7485 return cmd
@@ -83,20 +94,20 @@ func WaitRun(opts *WaitOptions) error {
8394 return fmt .Errorf ("--progress flag is only supported when waiting for a single task" )
8495 }
8596
86- tasks , err := opts .GetServerTasksCallback (opts .TaskIDs )
97+ serverTasks , err := opts .GetServerTasksCallback (opts .TaskIDs )
8798 if err != nil {
8899 return err
89100 }
90101
91- if len (tasks ) == 0 {
102+ if len (serverTasks ) == 0 {
92103 return fmt .Errorf ("no server tasks found" )
93104 }
94105
95106 pendingTaskIDs := make ([]string , 0 )
96107 failedTaskIDs := make ([]string , 0 )
97108 formatter := NewTaskOutputFormatter (opts .Out )
98109
99- for _ , t := range tasks {
110+ for _ , t := range serverTasks {
100111 if t .IsCompleted == nil || ! * t .IsCompleted {
101112 pendingTaskIDs = append (pendingTaskIDs , t .ID )
102113 }
@@ -109,7 +120,7 @@ func WaitRun(opts *WaitOptions) error {
109120
110121 if len (pendingTaskIDs ) == 0 {
111122 if len (failedTaskIDs ) != 0 {
112- return fmt .Errorf ("One or more deployment tasks failed: %s" , strings .Join (failedTaskIDs , ", " ))
123+ return fmt .Errorf ("one or more deployment tasks failed: %s" , strings .Join (failedTaskIDs , ", " ))
113124 }
114125 return nil
115126 }
@@ -120,13 +131,13 @@ func WaitRun(opts *WaitOptions) error {
120131
121132 go func () {
122133 for len (pendingTaskIDs ) != 0 {
123- time .Sleep (5 * time .Second )
124- tasks , err = opts .GetServerTasksCallback (pendingTaskIDs )
134+ time .Sleep (time . Duration ( opts . PollInterval ) * time .Second )
135+ serverTasks , err = opts .GetServerTasksCallback (pendingTaskIDs )
125136 if err != nil {
126137 gotError <- err
127138 return
128139 }
129- for _ , t := range tasks {
140+ for _ , t := range serverTasks {
130141 if opts .ShowProgress {
131142 details , err := opts .GetTaskDetailsCallback (t .ID )
132143 if err != nil {
@@ -151,7 +162,7 @@ func WaitRun(opts *WaitOptions) error {
151162 }
152163 }
153164 if len (failedTaskIDs ) != 0 {
154- gotError <- fmt .Errorf ("One or more deployment tasks failed: %s" , strings .Join (failedTaskIDs , ", " ))
165+ gotError <- fmt .Errorf ("one or more deployment tasks failed: %s" , strings .Join (failedTaskIDs , ", " ))
155166 return
156167 }
157168 done <- true
@@ -163,11 +174,18 @@ func WaitRun(opts *WaitOptions) error {
163174 case err := <- gotError :
164175 return err
165176 case <- time .After (time .Duration (opts .Timeout ) * time .Second ):
177+ if opts .CancelOnTimeout {
178+ fmt .Fprintf (opts .Dependencies .Out , "Cancelling remaining tasks: %s\n " , strings .Join (pendingTaskIDs , ", " ))
179+ _ , err := opts .CancelServerTasksCallback (pendingTaskIDs )
180+ if err != nil {
181+ return err
182+ }
183+ }
166184 return fmt .Errorf ("timeout while waiting for pending tasks" )
167185 }
168186}
169187
170- func GetServerTasksCallback (octopus * client.Client ) ServerTasksCallback {
188+ func getServerTasksCallback (octopus * client.Client ) ServerTasksCallback {
171189 return func (taskIDs []string ) ([]* tasks.Task , error ) {
172190 query := tasks.TasksQuery {
173191 IDs : taskIDs ,
@@ -187,12 +205,26 @@ func GetServerTasksCallback(octopus *client.Client) ServerTasksCallback {
187205 }
188206}
189207
190- func GetTaskDetailsCallback (octopus * client.Client ) TaskDetailsCallback {
208+ func getTaskDetailsCallback (octopus * client.Client ) TaskDetailsCallback {
191209 return func (taskID string ) (* tasks.TaskDetailsResource , error ) {
192210 return tasks .GetDetails (octopus , octopus .GetSpaceID (), taskID )
193211 }
194212}
195213
214+ func cancelServerTasksCallback (octopus * client.Client ) ServerTasksCallback {
215+ return func (taskIDs []string ) ([]* tasks.Task , error ) {
216+ serverTasks := make ([]* tasks.Task , len (taskIDs ))
217+ for _ , taskID := range taskIDs {
218+ serverTask , err := tasks .Cancel (octopus , octopus .GetSpaceID (), taskID )
219+ if err != nil {
220+ return nil , err
221+ }
222+ serverTasks = append (serverTasks , serverTask )
223+ }
224+ return serverTasks , nil
225+ }
226+ }
227+
196228func removeTaskID (taskIDs []string , taskID string ) []string {
197229 for i , p := range taskIDs {
198230 if p == taskID {
0 commit comments