-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathgrpc.go
152 lines (134 loc) · 4.33 KB
/
grpc.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
package main
import (
"context"
"errors"
"log"
"os/exec"
"spaceco/proto"
"github.com/hashicorp/go-plugin"
"google.golang.org/grpc"
)
// Define the plugin map
var PluginMap = map[string]plugin.Plugin{
"spacecore": &Spacecore{Impl: &SpacecorePlugin{}},
}
var HandshakeConfig = plugin.HandshakeConfig{
ProtocolVersion: 1,
MagicCookieKey: "SPACECORE_PLUGIN",
MagicCookieValue: "v1",
}
// Extend SpacecorePlugin to include pluginId and demoCmd fields
type SpacecorePluginImpl struct {
demoCmd *exec.Cmd
demoLogs string
pid int
}
type SpacecorePlugin struct {
SpacecorePluginImpl
}
type Spacecore struct {
plugin.Plugin
plugin.GRPCPlugin
Impl *SpacecorePlugin
}
type GRPCServer struct {
Config HACConfig
Impl SpacecorePlugin
}
func (g *Spacecore) GRPCServer(broker *plugin.GRPCBroker, s *grpc.Server) error {
proto.RegisterScPluginServer(s, &GRPCServer{Impl: *g.Impl})
return nil
}
// let's think about hierarchy in configs. We want to use commands start, stop, status, logs from hac.toml if specified
// if hac.commands not specified, we want to use the default commands from the plugin
// if hac.commands are specified, we want to use them, if containerd backend is specified,
// containerd image exists and commands not specified, the plugin should run the container image
// if containerd backend is specified, containerd image exists and commands are specified, the plugin should run the commands
func (g *GRPCServer) validateHacConfig(hac HACConfig) error {
if hac.Spacecore.Backend != "binary" && hac.Spacecore.ContainerImage == "" {
return errors.New("container_image is required in hac.toml")
}
if hac.Spacecore.ContainerImage == "containerd" && hac.Commands.Start == "" {
// for now, if using containerd, we need to specify the commands
log.Printf("HAC config: %v\n", hac)
if hac.Commands.Start == "" {
return errors.New("start command is required in hac.toml")
}
if hac.Commands.Stop == "" {
return errors.New("stop command is required in hac.toml")
}
if hac.Commands.Status == "" {
return errors.New("status command is required in hac.toml")
}
if hac.Commands.Logs == "" {
return errors.New("logs command is required in hac.toml")
}
}
return nil
}
// WIP - this function is not complete
func (g *GRPCServer) useHacCommands(hac HACConfig, cmd string) (string, error) {
if hac.Spacecore.Backend == "containerd" && cmd != "" {
output, err := executeCommand(cmd)
log.Printf("output from HAC commands: %s\n %s", output, err)
if err != nil {
return "", err
}
return output, nil
}
return "", nil
}
func (g *GRPCServer) Start(ctx context.Context, in *proto.StartRequest) (*proto.StartResponse, error) {
log.Printf("Starting Spacecore...\n")
hac, _ := loadConfig()
if hac.Spacecore.Backend == "containerd" {
if err := g.validateHacConfig(hac); err != nil {
return nil, err
}
// runs docker on Mac. Linux uses runc or nerdctl to run containerd images
output, _ := g.useHacCommands(hac, hac.Commands.Start)
if output != "" {
return &proto.StartResponse{Status: output}, nil
}
}
msg, err := g.Impl.Start(ctx)
if err != nil {
return nil, err
}
return &proto.StartResponse{Status: msg}, nil
}
func (g *GRPCServer) Stop(ctx context.Context, in *proto.StopRequest) (*proto.StopResponse, error) {
hac, err := loadConfig()
output, _ := g.useHacCommands(hac, hac.Commands.Stop)
if output != "" {
return &proto.StopResponse{Status: output}, nil
}
msg, err := g.Impl.Stop(context.Background())
if err != nil {
return nil, err
}
return &proto.StopResponse{Status: msg}, nil
}
func (g *GRPCServer) Status(ctx context.Context, in *proto.StatusRequest) (*proto.StatusResponse, error) {
log.Printf("Checking Spacecore status...\n")
hac, _ := loadConfig()
output, _ := g.useHacCommands(hac, hac.Commands.Status)
if output != "" {
return &proto.StatusResponse{Status: output}, nil
}
msg, err := g.Impl.Status(ctx)
return &proto.StatusResponse{Status: msg}, err
}
func (g *GRPCServer) Logs(ctx context.Context, in *proto.LogsRequest) (*proto.LogsResponse, error) {
hac, _ := loadConfig()
output, _ := g.useHacCommands(hac, hac.Commands.Logs)
if output != "" {
return &proto.LogsResponse{Logs: []string{output}}, nil
}
msg, err := g.Impl.Logs(context.Background())
log.Printf("Checking Spacecore logs...\n %s", msg)
if err != nil {
return nil, err
}
return &proto.LogsResponse{}, nil
}