/
builder.go
122 lines (105 loc) · 2.96 KB
/
builder.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
package builder
import (
"errors"
"fmt"
"github.com/mesg-foundation/engine/container"
"github.com/mesg-foundation/engine/cosmos"
"github.com/mesg-foundation/engine/ext/xos"
"github.com/mesg-foundation/engine/hash"
instancepb "github.com/mesg-foundation/engine/instance"
"github.com/mesg-foundation/engine/protobuf/api"
runnerpb "github.com/mesg-foundation/engine/runner"
)
// Builder is the runner builder.
type Builder struct {
mc *cosmos.ModuleClient
container container.Container
engineName string
port string
ipfsEndpoint string
}
// New returns the runner sdk.
func New(mc *cosmos.ModuleClient, container container.Container, engineName, port, ipfsEndpoint string) *Builder {
sdk := &Builder{
container: container,
mc: mc,
engineName: engineName,
port: port,
ipfsEndpoint: ipfsEndpoint,
}
return sdk
}
// Create creates a new runner.
func (b *Builder) Create(req *api.CreateRunnerRequest) (*runnerpb.Runner, error) {
// calculate instance's hash.
// TODO: this should be merged with the same logic currently in instance sdk
srv, err := b.mc.GetService(req.ServiceHash)
if err != nil {
return nil, err
}
instanceEnv := xos.EnvMergeSlices(srv.Configuration.Env, req.Env)
envHash := hash.Dump(instanceEnv)
// TODO: should be done by instance or runner
instanceHash := hash.Dump(&instancepb.Instance{
ServiceHash: srv.Hash,
EnvHash: envHash,
})
acc, err := b.mc.GetAccount()
if err != nil {
return nil, err
}
expRunner := runnerpb.New(acc.GetAddress().String(), instanceHash)
expRunnerHash := expRunner.Hash
if runExisting, _ := b.mc.GetRunner(expRunnerHash); runExisting != nil {
return nil, fmt.Errorf("runner %q already exists", runExisting.Hash)
}
// start the container
imageHash, err := build(b.container, srv, b.ipfsEndpoint)
if err != nil {
return nil, err
}
_, err = start(b.container, srv, instanceHash, expRunnerHash, imageHash, instanceEnv, b.engineName, b.port)
if err != nil {
return nil, err
}
run, err := b.mc.CreateRunner(req)
if err != nil {
stop(b.container, expRunnerHash, srv.Dependencies)
return nil, err
}
if !run.Hash.Equal(expRunnerHash) {
stop(b.container, expRunnerHash, srv.Dependencies)
return nil, errors.New("calculated runner hash is not the same")
}
return run, nil
}
// Delete deletes an existing runner.
func (b *Builder) Delete(req *api.DeleteRunnerRequest) error {
// get runner before deleting it
r, err := b.mc.GetRunner(req.Hash)
if err != nil {
return err
}
if err := b.mc.DeleteRunner(req); err != nil {
return err
}
inst, err := b.mc.GetInstance(r.InstanceHash)
if err != nil {
return err
}
srv, err := b.mc.GetService(inst.ServiceHash)
if err != nil {
return err
}
// stop the local running service
if err := stop(b.container, r.Hash, srv.Dependencies); err != nil {
return err
}
// remove local volume
if req.DeleteData {
if err := deleteData(b.container, srv); err != nil {
return err
}
}
return nil
}