forked from liamjbennett/sous
-
Notifications
You must be signed in to change notification settings - Fork 0
/
sous_update.go
129 lines (111 loc) · 3.66 KB
/
sous_update.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
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
package cli
import (
"flag"
"github.com/opentable/sous/config"
"github.com/opentable/sous/graph"
"github.com/opentable/sous/lib"
"github.com/opentable/sous/util/cmdr"
"github.com/samsalisbury/semv"
)
// SousUpdate is the command description for `sous update`
type SousUpdate struct {
DeployFilterFlags config.DeployFilterFlags
OTPLFlags config.OTPLFlags
Manifest graph.TargetManifest
GDM graph.CurrentGDM
State *sous.State
StateWriter graph.StateWriter
StateReader graph.StateReader
*sous.ResolveFilter
}
func init() { TopLevelCommands["update"] = &SousUpdate{} }
const sousUpdateHelp = `update the version to be deployed in a cluster
usage: sous update -cluster <name> -tag <semver> [-use-otpl-deploy|-ignore-otpl-deploy]
sous update will update the version tag for this application in the named
cluster. You can then use 'sous rectify' to have that version deployed.
`
// Help returns the help string for this command
func (su *SousUpdate) Help() string { return sousUpdateHelp }
// AddFlags adds the flags for sous init.
func (su *SousUpdate) AddFlags(fs *flag.FlagSet) {
MustAddFlags(fs, &su.DeployFilterFlags, DeployFilterFlagsHelp)
MustAddFlags(fs, &su.OTPLFlags, OtplFlagsHelp)
}
// RegisterOn adds the DeploymentConfig to the psyringe to configure the
// labeller and registrar
func (su *SousUpdate) RegisterOn(psy Addable) {
psy.Add(&su.DeployFilterFlags)
psy.Add(&su.OTPLFlags)
}
// Execute fulfills the cmdr.Executor interface.
func (su *SousUpdate) Execute(args []string) cmdr.Result {
sl := su.Manifest.ID()
sid, did, err := getIDs(su.ResolveFilter, sl)
if err != nil {
return EnsureErrorResult(err)
}
_, ok := su.State.Manifests.Get(sl)
if !ok {
sous.Log.Info.Printf("adding new manifest %q", did)
su.State.Manifests.Add(su.Manifest.Manifest)
if err := su.StateWriter.WriteState(su.State); err != nil {
return EnsureErrorResult(err)
}
newState, err := su.StateReader.ReadState()
if err != nil {
return EnsureErrorResult(err)
}
su.State = newState
newGDM, err := su.State.Deployments()
if err != nil {
return EnsureErrorResult(err)
}
su.GDM = graph.CurrentGDM{Deployments: newGDM}
_, ok := su.State.Manifests.Get(sl)
if !ok {
return GeneralErrorf("failed to add manifest %q", did)
}
}
if err := updateState(su.State, su.GDM, sid, did); err != nil {
return EnsureErrorResult(err)
}
if err := su.StateWriter.WriteState(su.State); err != nil {
return EnsureErrorResult(err)
}
return cmdr.Success()
}
func updateState(s *sous.State, gdm graph.CurrentGDM, sid sous.SourceID, did sous.DeployID) error {
deployment, ok := gdm.Get(did)
if !ok {
sous.Log.Warn.Printf("Deployment %q does not exist, creating.\n", did)
deployment = &sous.Deployment{}
}
deployment.SourceID = sid
deployment.ClusterName = did.Cluster
// XXX switch to .UpdateDeployments
gdm.Set(did, deployment)
manifests, err := gdm.Manifests(s.Defs)
if err != nil {
return EnsureErrorResult(err)
}
s.Manifests = manifests
return nil
}
func getIDs(filter *sous.ResolveFilter, mid sous.ManifestID) (sous.SourceID, sous.DeployID, error) {
var sid sous.SourceID
var did sous.DeployID
clusterName, tag := filter.Cluster, filter.Tag
if clusterName == "" {
return sid, did, cmdr.UsageErrorf("update: You must select a cluster using the -cluster flag.")
}
if tag == "" {
return sid, did, cmdr.UsageErrorf("update: You must provide the -tag flag.")
}
newVersion, err := semv.Parse(tag)
if err != nil {
return sid, did, cmdr.UsageErrorf("update: Version %q not valid: %s", tag, err)
}
sid = mid.Source.SourceID(newVersion)
did = sous.DeployID{ManifestID: mid, Cluster: clusterName}
return sid, did, nil
}