-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathservice.go
131 lines (114 loc) · 3.54 KB
/
service.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
// Copyright 2014 Canonical Ltd.
// Licensed under the AGPLv3, see LICENCE file for details.
package mongo
import (
"fmt"
"path/filepath"
"strconv"
"github.com/juju/errors"
"github.com/juju/utils"
"github.com/juju/juju/service"
"github.com/juju/juju/service/common"
)
const (
maxFiles = 65000
maxProcs = 20000
serviceName = "juju-db"
// SharedSecretFile is the name of the Mongo shared secret file
// located within the Juju data directory.
SharedSecretFile = "shared-secret"
// ReplicaSetName is the name of the replica set that juju uses for its
// state servers.
ReplicaSetName = "juju"
)
var (
// This is the name of the variable to use in ExtraScript
// fragment to substitute into init script template.
multinodeVarName = "MULTI_NODE"
// This value will be used to wrap desired mongo cmd in numactl if wanted/needed
numaCtlWrap = "$%v"
// Extra shell script fragment for init script template.
// This determines if we are dealing with multi-node environment
detectMultiNodeScript = `%v=""
if [ $(find /sys/devices/system/node/ -maxdepth 1 -mindepth 1 -type d -name node\* | wc -l ) -gt 1 ]
then
%v=" numactl --interleave=all "
# Ensure sysctl turns off zone_reclaim_mode if not already set
(grep -q vm.zone_reclaim_mode /etc/sysctl.conf || echo vm.zone_reclaim_mode = 0 >> /etc/sysctl.conf) && sysctl -p
fi
`
)
type mongoService interface {
Install() error
Start() error
Stop() error
Remove() error
Exists() bool
Running() bool
}
var newService = func(name string, conf common.Conf) (mongoService, error) {
return service.DiscoverService(name, conf)
}
var discoverService = func(name string) (mongoService, error) {
return service.DiscoverService(name, common.Conf{})
}
// RemoveService removes the mongoDB init service from this machine.
func RemoveService(namespace string) error {
svc, err := discoverService(ServiceName(namespace))
if err != nil {
return errors.Trace(err)
}
if err := svc.Stop(); err != nil {
return errors.Trace(err)
}
if err := svc.Remove(); err != nil {
return errors.Trace(err)
}
return nil
}
// ServiceName returns the name of the init service config for mongo using
// the given namespace.
func ServiceName(namespace string) string {
if namespace != "" {
return fmt.Sprintf("%s-%s", serviceName, namespace)
}
return serviceName
}
func sslKeyPath(dataDir string) string {
return filepath.Join(dataDir, "server.pem")
}
func sharedSecretPath(dataDir string) string {
return filepath.Join(dataDir, SharedSecretFile)
}
// newConf returns the init system config for the mongo state service.
func newConf(dataDir, dbDir, mongoPath string, port, oplogSizeMB int, wantNumaCtl bool) common.Conf {
mongoCmd := mongoPath + " --auth" +
" --dbpath=" + utils.ShQuote(dbDir) +
" --sslOnNormalPorts" +
" --sslPEMKeyFile " + utils.ShQuote(sslKeyPath(dataDir)) +
" --sslPEMKeyPassword ignored" +
" --port " + fmt.Sprint(port) +
" --noprealloc" +
" --syslog" +
" --smallfiles" +
" --journal" +
" --keyFile " + utils.ShQuote(sharedSecretPath(dataDir)) +
" --replSet " + ReplicaSetName +
" --ipv6 " +
" --oplogSize " + strconv.Itoa(oplogSizeMB)
extraScript := ""
if wantNumaCtl {
extraScript = fmt.Sprintf(detectMultiNodeScript, multinodeVarName, multinodeVarName)
mongoCmd = fmt.Sprintf(numaCtlWrap, multinodeVarName) + mongoCmd
}
conf := common.Conf{
Desc: "juju state database",
Limit: map[string]string{
"nofile": fmt.Sprintf("%d %d", maxFiles, maxFiles),
"nproc": fmt.Sprintf("%d %d", maxProcs, maxProcs),
},
ExtraScript: extraScript,
ExecStart: mongoCmd,
}
return conf
}