forked from liamjbennett/sous
-
Notifications
You must be signed in to change notification settings - Fork 0
/
otpl.go
144 lines (136 loc) · 4.06 KB
/
otpl.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
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
// Package otpl adds some OpenTable-specific interop methods. These will one day
// be removed.
package otpl
import (
"path"
"strconv"
"sync"
"github.com/opentable/sous/lib"
"github.com/opentable/sous/util/shell"
)
type (
// DeploySpecParser parses sous.DeploySpecs from otpl-deploy config files.
// NOTE: otpl-deploy config is an internal tool at OpenTable, one day this
// code will be removed.
DeploySpecParser struct {
debugf func(string, ...interface{})
debug func(...interface{})
WD shell.Shell
}
// SingularityJSON represents the JSON in an otpl-deploy singularity.json
// file.
SingularityJSON struct {
Resources SingularityResources
Env sous.Env
}
// SingularityResources represents the resources section in SingularityJSON.
SingularityResources map[string]float64
// SingularityRequestJSON represents JSON in an otpl-deploy
// singularity-request.json file.
SingularityRequestJSON struct {
// Instances is the number of instances in this deployment.
Instances int
// NOTE: Owners are not supported at DeploySpec level, only at Manifest
// level... Maybe that needs to change.
//Owners []string
// NOTE: We do not currently support Daemon, RackSensitive or LoadBalanced
//Daemon, RackSensitive, LoadBalanced bool
}
)
// SousResources returns the equivalent sous.Resources.
func (sr SingularityResources) SousResources() sous.Resources {
r := make(sous.Resources, len(sr))
for k, v := range sr {
if k == "numPorts" {
k = "ports"
}
if k == "memoryMb" {
k = "memory"
}
r[k] = strconv.FormatFloat(v, 'g', -1, 64)
}
return r
}
// NewDeploySpecParser generates a new DeploySpecParser with default logging.
func NewDeploySpecParser() *DeploySpecParser {
return &DeploySpecParser{debugf: sous.Log.Debug.Printf, debug: sous.Log.Debug.Println}
}
type namedDeploySpec struct {
Name string
Spec *sous.DeploySpec
}
// GetDeploySpecs searches the working directory of wd to find otpl-deploy
// config files in their standard locations (config/{cluster-name}), and
// converts them to sous.DeploySpecs.
func (dsp *DeploySpecParser) GetDeploySpecs(wd shell.Shell) sous.DeploySpecs {
wd = wd.Clone()
if err := wd.CD("config"); err != nil {
return nil
}
l, err := wd.List()
if err != nil {
dsp.debug(err)
return nil
}
c := make(chan namedDeploySpec)
wg := sync.WaitGroup{}
wg.Add(len(l))
go func() { wg.Wait(); close(c) }()
for _, f := range l {
f := f
go func() {
defer wg.Done()
if !f.IsDir() {
return
}
wd := wd.Clone()
if err := wd.CD(f.Name()); err != nil {
dsp.debug(err)
return
}
if otplConfig := dsp.GetSingleDeploySpec(wd); otplConfig != nil {
name := path.Base(wd.Dir())
c <- namedDeploySpec{name, otplConfig}
}
}()
}
deployConfigs := sous.DeploySpecs{}
for s := range c {
deployConfigs[s.Name] = *s.Spec
}
return deployConfigs
}
// GetSingleDeploySpec returns a single sous.DeploySpec from the working
// directory of wd. It assumes that this directory contains at least a file
// called singularity.json, and optionally an additional file called
// singularity-requst.json.
func (dsp *DeploySpecParser) GetSingleDeploySpec(wd shell.Shell) *sous.DeploySpec {
v := SingularityJSON{}
if !wd.Exists("singularity.json") {
dsp.debugf("no singularity.json in %s", wd.Dir())
return nil
}
if err := wd.JSON(&v, "cat", "singularity.json"); err != nil {
dsp.debugf("error reading %s: %s", path.Join(wd.Dir(),
"singularity.json"), err)
return nil
}
deploySpec := sous.DeploySpec{
DeployConfig: sous.DeployConfig{
Resources: v.Resources.SousResources(),
Env: v.Env,
},
}
request := SingularityRequestJSON{}
if !wd.Exists("singularity-request.json") {
dsp.debugf("no singularity-request.json in %s", wd.Dir())
return &deploySpec
}
dsp.debugf("%s/singularity-request.json exists, parsing it", wd.Dir())
if err := wd.JSON(&request, "cat", "singularity-request.json"); err != nil {
dsp.debugf("error reading singularity-request.json: %s", err)
return &deploySpec
}
deploySpec.NumInstances = request.Instances
return &deploySpec
}