This repository has been archived by the owner on Jun 18, 2020. It is now read-only.
forked from waffle-iron/core0
/
rtinfo.go
115 lines (92 loc) · 2.19 KB
/
rtinfo.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
package builtin
import (
"encoding/json"
"fmt"
"sync"
"github.com/pborman/uuid"
"github.com/threefoldtech/0-core/base/pm"
)
const cmdbin = "rtinfo-client"
type rtinfoMgr struct {
info map[string]*rtinfoParams
m sync.RWMutex
}
type rtinfoParams struct {
Host string `json:"host"`
Port uint `json:"port"`
Disks []string `json:"disks"`
job string
}
func init() {
rtm := &rtinfoMgr{info: make(map[string]*rtinfoParams)}
pm.RegisterBuiltIn("rtinfo.start", rtm.start)
pm.RegisterBuiltIn("rtinfo.list", rtm.list)
pm.RegisterBuiltIn("rtinfo.stop", rtm.stop)
}
func (rtm *rtinfoMgr) start(cmd *pm.Command) (interface{}, error) {
var args rtinfoParams
if err := json.Unmarshal(*cmd.Arguments, &args); err != nil {
return nil, err
}
cmdargs := []string{
"--host", args.Host, "--port", fmt.Sprintf("%d", args.Port),
}
for _, d := range args.Disks {
cmdargs = append(cmdargs, "--disk", d)
}
rtm.m.Lock()
defer rtm.m.Unlock()
key := fmt.Sprintf("%s:%d", args.Host, args.Port)
_, exists := rtm.info[key]
if exists {
return nil, pm.NotAcceptableError("an rtinfo agent running already for this daemon")
}
args.job = uuid.New()
rtm.info[key] = &args
rtinfocmd := &pm.Command{
ID: args.job,
Command: pm.CommandSystem,
Arguments: pm.MustArguments(
pm.SystemCommandArguments{
Name: cmdbin,
Args: cmdargs,
},
),
}
onExit := &pm.ExitHook{
Action: func(state bool) {
rtm.m.Lock()
delete(rtm.info, key)
rtm.m.Unlock()
},
}
_, err := pm.Run(rtinfocmd, onExit)
if err != nil {
//the process manager failed to start
//hence we need to clean it up ourselvies
rtm.m.Lock()
delete(rtm.info, key)
rtm.m.Unlock()
}
return nil, err
}
func (rtm *rtinfoMgr) list(cmd *pm.Command) (interface{}, error) {
return rtm.info, nil
}
func (rtm *rtinfoMgr) stop(cmd *pm.Command) (interface{}, error) {
var args struct {
Host string `json:"host"`
Port uint `json:"port"`
}
if err := json.Unmarshal(*cmd.Arguments, &args); err != nil {
return nil, err
}
key := fmt.Sprintf("%s:%d", args.Host, args.Port)
rtm.m.RLock()
defer rtm.m.RUnlock()
info, exists := rtm.info[key]
if !exists {
return nil, nil
}
return nil, pm.Kill(info.job)
}