@@ -67,6 +67,15 @@ func (s State) String() string {
6767 return string (s [len ("update:state:" ):])
6868}
6969
70+ func (s State ) IsOneOf (states ... State ) bool {
71+ for _ , st := range states {
72+ if s == st {
73+ return true
74+ }
75+ }
76+ return false
77+ }
78+
7079func NewUpdate (cfg * compose.Config , ref string ) (Runner , error ) {
7180 _ , err := GetCurrentUpdate (cfg )
7281 if err == nil {
@@ -231,14 +240,12 @@ func (u *runnerImpl) Init(ctx context.Context, appURIs []string, options ...Init
231240
232241func (u * runnerImpl ) Fetch (ctx context.Context , options ... compose.FetchOption ) error {
233242 return u .store .lock (func (db * session ) error {
234- var err error
235- switch u .State {
236- case StateFetching , StateInitialized :
237- // the current state is correct to fetch updates
238- default :
239- return fmt .Errorf ("cannot fetch update when it is in state '%s'" , u .State .String ())
243+ // Allow re-fetching when it is already fetched
244+ if ! u .State .IsOneOf (StateInitialized , StateFetching , StateFetched ) {
245+ return fmt .Errorf ("cannot fetch update when it is in state %q" , u .State )
240246 }
241247
248+ var err error
242249 u .State = StateFetching
243250 u .Progress = 0
244251 err = db .write (& u .Update )
@@ -276,13 +283,12 @@ func (u *runnerImpl) Fetch(ctx context.Context, options ...compose.FetchOption)
276283
277284func (u * runnerImpl ) Install (ctx context.Context , options ... compose.InstallOption ) error {
278285 return u .store .lock (func (db * session ) error {
279- var err error
280- switch u .State {
281- case StateFetched , StateInstalling , StateInstalled :
282- // the current state is correct to install updates
283- default :
284- return fmt .Errorf ("cannot install update when it is in state '%s'" , u .State .String ())
286+ // Allow re-installing an update that is already installed.
287+ if ! u .State .IsOneOf (StateFetched , StateInstalling , StateInstalled ) {
288+ return fmt .Errorf ("cannot install update when it is in state %q" , u .State )
285289 }
290+
291+ var err error
286292 u .State = StateInstalling
287293 u .Progress = 0
288294 err = db .write (& u .Update )
@@ -309,11 +315,9 @@ func (u *runnerImpl) Install(ctx context.Context, options ...compose.InstallOpti
309315
310316func (u * runnerImpl ) Start (ctx context.Context ) error {
311317 return u .store .lock (func (db * session ) error {
312- switch u .State {
313- case StateInstalled , StateStarting :
314- // the current state is correct to start updates
315- default :
316- return fmt .Errorf ("cannot start update when it is in state '%s'" , u .State .String ())
318+ // Allow re-starting an update that is already started.
319+ if ! u .State .IsOneOf (StateInstalled , StateStarting , StateStarted ) {
320+ return fmt .Errorf ("cannot start update when it is in state %q" , u .State )
317321 }
318322
319323 u .State = StateStarting
@@ -342,14 +346,12 @@ func (u *runnerImpl) Start(ctx context.Context) error {
342346
343347func (u * runnerImpl ) Cancel (ctx context.Context ) error {
344348 return u .store .lock (func (db * session ) error {
345- var err error
346- switch u .State {
347- case StateCreated , StateInitializing , StateInitialized , StateFetching , StateFetched , StateInstalling , StateInstalled :
348- // the current state is correct to cancel updates
349- default :
350- return fmt .Errorf ("cannot cancel update when it is in state '%s'" , u .State .String ())
349+ if ! u .State .IsOneOf (StateCreated , StateInitializing , StateInitialized ,
350+ StateFetching , StateFetched , StateInstalling , StateInstalled ) {
351+ return fmt .Errorf ("cannot cancel update when it is in state %q" , u .State )
351352 }
352353
354+ var err error
353355 u .State = StateCancelling
354356 u .Progress = 0
355357 err = db .write (& u .Update )
@@ -376,14 +378,11 @@ func (u *runnerImpl) Cancel(ctx context.Context) error {
376378
377379func (u * runnerImpl ) Complete (ctx context.Context , options ... CompleteOpt ) error {
378380 return u .store .lock (func (db * session ) error {
379- var err error
380- switch u .State {
381- case StateStarted , StateCompleting :
382- // the current state is correct to complete updates
383- default :
384- return fmt .Errorf ("cannot complete update when it is in state '%s'" , u .State .String ())
381+ if ! u .State .IsOneOf (StateStarted , StateCompleting ) {
382+ return fmt .Errorf ("cannot complete update when it is in state %q" , u .State )
385383 }
386384
385+ var err error
387386 u .State = StateCompleting
388387 u .Progress = 0
389388 err = db .write (& u .Update )
0 commit comments