-
Notifications
You must be signed in to change notification settings - Fork 491
/
remoteinit.go
67 lines (62 loc) · 2.26 KB
/
remoteinit.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
// Copyright 2020 Canonical Ltd.
// Licensed under the AGPLv3, see LICENCE file for details.
package container
import (
"github.com/juju/juju/worker/uniter/operation"
"github.com/juju/juju/worker/uniter/remotestate"
"github.com/juju/juju/worker/uniter/resolver"
)
type remoteContainerInitResolver struct{}
// NewRemoteContainerInitResolver returns a new resolver with determines which container related operation
// should be run based on local and remote uniter states.
func NewRemoteContainerInitResolver() resolver.Resolver {
return &remoteContainerInitResolver{}
}
// NextOp implements the resolver.Resolver interface.
func (r *remoteContainerInitResolver) NextOp(
localState resolver.LocalState,
remoteState remotestate.Snapshot,
opFactory operation.Factory,
) (operation.Operation, error) {
noOp := func() (operation.Operation, error) {
if localState.Kind == operation.RemoteInit {
// If we are resuming from an unexpected state, skip init.
// Retry will occur when remotestate updates.
return opFactory.NewSkipRemoteInit(false)
}
return nil, resolver.ErrNoOperation
}
if remoteState.ContainerRunningStatus == nil {
return noOp()
}
// Check if init or workload containers are running.
if !remoteState.ContainerRunningStatus.Initialising &&
!remoteState.ContainerRunningStatus.Running {
return noOp()
}
// If we haven't yet handled the init container.
if !localState.OutdatedRemoteCharm && localState.ContainerRunningStatus != nil {
if localState.ContainerRunningStatus.InitialisingTime == remoteState.ContainerRunningStatus.InitialisingTime {
// We've already initialised the container.
return noOp()
}
} else if !localState.OutdatedRemoteCharm {
// Nothing to do
return noOp()
}
switch localState.Kind {
case operation.RunHook:
if localState.Step == operation.Pending {
return opFactory.NewRemoteInit(*remoteState.ContainerRunningStatus)
}
case operation.Continue:
return opFactory.NewRemoteInit(*remoteState.ContainerRunningStatus)
case operation.RemoteInit:
if localState.Step == operation.Pending {
return opFactory.NewRemoteInit(*remoteState.ContainerRunningStatus)
}
// If we are resuming from an unexpected state, skip init but retry the remote init op.
return opFactory.NewSkipRemoteInit(true)
}
return noOp()
}