forked from pkallberg/cx
-
Notifications
You must be signed in to change notification settings - Fork 0
/
services.go
198 lines (178 loc) · 4.97 KB
/
services.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
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
package main
import (
"fmt"
"io"
"os"
"sort"
"text/tabwriter"
"github.com/cloud66/cloud66"
"github.com/cloud66/cli"
)
var cmdServices = &Command{
Name: "services",
Build: buildServices,
Short: "commands to work with services",
NeedsStack: true,
}
func buildServices() cli.Command {
base := buildBasicCommand()
base.Subcommands = []cli.Command{
cli.Command{
Name: "list",
Usage: "lists all the services of a stack (or server)",
Action: runServices,
Flags: []cli.Flag{
cli.StringFlag{
Name: "server",
},
cli.StringFlag{
Name: "service",
},
},
Description: `List all the services and running containers of a stack or a server.
Examples:
$ cx services list -s mystack
$ cx services list -s mystack --server orca
$ cx services list -s mystack --server orca --service web
$ cx services list -s mystack --service web
`,
},
cli.Command{
Name: "stop",
Action: runServiceStop,
Usage: "stops all the containers from the given service",
Flags: []cli.Flag{
cli.StringFlag{
Name: "server",
},
},
Description: `Stops all the containers from the given service.
The list of available stack services can be obtained through the 'services' command.
If the server is provided it will only act on the specified server.
Examples:
$ cx services stop -s mystack my_web_service
$ cx services stop -s mystack a_backend_service
$ cx services stop -s mystack --server my_server my_web_service
`},
cli.Command{
Name: "scale",
Action: runServiceScale,
Usage: "starts containers from the given service",
Flags: []cli.Flag{
cli.StringFlag{
Name: "server",
},
cli.StringFlag{
Name: "group",
},
},
Description: `Starts <count> containers from the given service.
<count> can be an absolute value like "2" or a relative value like "+2" or "-3" etc.
If server is provided, will start <count> containers on that server.
If server is not provided, will start <count> containers on every server.
If group is provided, will scale the containers of the service across all servers of a group. Currently only web is a valid group name.
Examples:
$ cx services scale -s mystack my_web_service 1
$ cx services scale -s mystack --server backend a_backend_service +5
$ cx services sclae -s mystack a_backend_service -2
$ cx services sclae -s mystack --group web a_backend_service 15
`},
cli.Command{
Name: "restart",
Action: runServiceRestart,
Flags: []cli.Flag{
cli.StringFlag{
Name: "server",
},
},
Usage: "restarts all the containers from the given service",
Description: `Restarts all the containers from the given service.
The list of available stack services can be obtained through the 'services' command.
If the server is provided it will only act on the specified server.
Examples:
$ cx services restart -s mystack my_web_service
$ cx services restart -s mystack a_backend_service
$ cx services restart -s mystack --server my_server my_web_service
`,
},
}
return base
}
func runServices(c *cli.Context) {
flagServer := c.String("server")
flagServiceName := c.String("service")
stack := mustStack(c)
w := tabwriter.NewWriter(os.Stdout, 1, 2, 2, ' ', 0)
defer w.Flush()
var serverUid *string
if flagServer == "" {
serverUid = nil
} else {
servers, err := client.Servers(stack.Uid)
if err != nil {
printFatal(err.Error())
}
server, err := findServer(servers, flagServer)
if err != nil {
printFatal(err.Error())
}
if server == nil {
printFatal("Server '" + flagServer + "' not found")
}
if !server.HasRole("docker") {
printFatal("Server '" + flagServer + "' can not host containers")
}
fmt.Printf("Server: %s\n", server.Name)
serverUid = &server.Uid
}
var (
services []cloud66.Service
err error
)
if flagServiceName == "" {
services, err = client.GetServices(stack.Uid, serverUid)
must(err)
} else {
service, err := client.GetService(stack.Uid, flagServiceName, serverUid, nil)
must(err)
if service == nil {
printFatal("Service '" + flagServiceName + "' not found on specified stack")
} else {
services = make([]cloud66.Service, 1)
services[0] = *service
}
}
printServicesList(w, services, flagServer)
}
func printServicesList(w io.Writer, services []cloud66.Service, flagServer string) {
listRec(w,
"SERVICE NAME",
"SERVER",
"COUNT",
)
sort.Sort(ServiceByNameServer(services))
for _, a := range services {
listService(w, a, flagServer)
}
}
func listService(w io.Writer, a cloud66.Service, flagServer string) {
if len(a.Containers) != 0 {
for serverName, count := range a.ServerContainerCountMap() {
listRec(w,
a.Name,
serverName,
count,
)
}
} else if flagServer == "" {
listRec(w,
a.Name,
"n/a",
"0",
)
}
}
type ServiceByNameServer []cloud66.Service
func (a ServiceByNameServer) Len() int { return len(a) }
func (a ServiceByNameServer) Swap(i, j int) { a[i], a[j] = a[j], a[i] }
func (a ServiceByNameServer) Less(i, j int) bool { return a[i].Name < a[j].Name }