-
Notifications
You must be signed in to change notification settings - Fork 85
/
types.go
188 lines (159 loc) · 5.96 KB
/
types.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
package models
import (
"encoding/json"
"errors"
"fmt"
"github.com/bacalhau-project/bacalhau/pkg/model"
"github.com/bacalhau-project/bacalhau/pkg/models"
"github.com/bacalhau-project/bacalhau/pkg/models/migration/legacy"
"github.com/bacalhau-project/bacalhau/pkg/storage"
"github.com/fatih/structs"
)
// EngineSpec contains necessary parameters to execute a wasm job.
type EngineSpec struct {
// EntryModule is a Spec containing the WASM code to start running.
EntryModule *models.InputSource `json:"EntryModule,omitempty"`
// Entrypoint is the name of the function in the EntryModule to call to run the job.
// For WASI jobs, this will should be `_start`, but jobs can choose to call other WASM functions instead.
// Entrypoint must be a zero-parameter zero-result function.
Entrypoint string `json:"EntryPoint,omitempty"`
// Parameters contains arguments supplied to the program (i.e. as ARGV).
Parameters []string `json:"Parameters,omitempty"`
// EnvironmentVariables contains variables available in the environment of the running program.
EnvironmentVariables map[string]string `json:"EnvironmentVariables,omitempty"`
// ImportModules is a slice of StorageSpec's containing WASM modules whose exports will be available as imports
// to the EntryModule.
ImportModules []*models.InputSource `json:"ImportModules,omitempty"`
}
func (c EngineSpec) Validate() error {
if c.EntryModule == nil {
return errors.New("invalid wasm engine entry module. cannot be nil")
}
if c.EntryModule.Source == nil {
return errors.New("invalid wasm engine entry module. source cannot be nil")
}
return nil
}
// ToArguments returns EngineArguments from the spec
func (c EngineSpec) ToArguments(entryModule storage.PreparedStorage, importModules ...storage.PreparedStorage) EngineArguments {
return EngineArguments{
EntryModule: entryModule,
EntryPoint: c.Entrypoint,
Parameters: c.Parameters,
EnvironmentVariables: c.EnvironmentVariables,
ImportModules: importModules,
}
}
func (c EngineSpec) ToMap() map[string]interface{} {
return structs.Map(c)
}
// legacyEngineSpec is first used to decode the passed spec with legacy model.StorageSpec,
// and then converted to EngineSpec with models.InputSource
type legacyEngineSpec struct {
EntryModule model.StorageSpec
Entrypoint string
Parameters []string
EnvironmentVariables map[string]string
ImportModules []model.StorageSpec
}
func DecodeSpec(spec *models.SpecConfig) (EngineSpec, error) {
if !spec.IsType(models.EngineWasm) {
//nolint:goconst
return EngineSpec{}, errors.New("invalid wasm engine type. expected " + models.EngineWasm + ", but received: " + spec.Type)
}
inputParams := spec.Params
if inputParams == nil {
return EngineSpec{}, errors.New("invalid wasm engine params. cannot be nil")
}
paramsBytes, err := json.Marshal(inputParams)
if err != nil {
return EngineSpec{}, fmt.Errorf("failed to encode wasm engine specs. %w", err)
}
var c *EngineSpec
err = json.Unmarshal(paramsBytes, &c)
if err != nil {
return EngineSpec{}, err
}
return *c, c.Validate()
}
func DecodeLegacySpec(spec *models.SpecConfig) (EngineSpec, error) {
if !spec.IsType(models.EngineWasm) {
return EngineSpec{}, errors.New("invalid wasm engine type. expected " + models.EngineWasm + ", but received: " + spec.Type)
}
inputParams := spec.Params
if inputParams == nil {
return EngineSpec{}, errors.New("invalid wasm engine params. cannot be nil")
}
paramsBytes, err := json.Marshal(inputParams)
if err != nil {
return EngineSpec{}, fmt.Errorf("failed to encode wasm engine specs. %w", err)
}
var c *legacyEngineSpec
err = json.Unmarshal(paramsBytes, &c)
if err != nil {
return EngineSpec{}, err
}
entryModule, err := legacy.FromLegacyStorageSpecToInputSource(c.EntryModule)
if err != nil {
return EngineSpec{}, err
}
importModules := make([]*models.InputSource, 0, len(c.ImportModules))
for _, module := range c.ImportModules {
newModule, err := legacy.FromLegacyStorageSpecToInputSource(module)
if err != nil {
return EngineSpec{}, err
}
importModules = append(importModules, newModule)
}
engineSpec := EngineSpec{
EntryModule: entryModule,
Entrypoint: c.Entrypoint,
Parameters: c.Parameters,
EnvironmentVariables: c.EnvironmentVariables,
ImportModules: importModules,
}
return engineSpec, engineSpec.Validate()
}
// EngineArguments is used to pass pre-processed engine specs to the executor.
// Currently used to pre-fetch entry and import modules remote resources by the compute
// node before triggering the executor.
// TODO: deprecate these arguments once we move remote resources from the engine spec to
// the upper layer
type EngineArguments struct {
EntryPoint string
Parameters []string
EnvironmentVariables map[string]string
EntryModule storage.PreparedStorage
ImportModules []storage.PreparedStorage
}
func (c EngineArguments) Validate() error {
if (c.EntryModule.InputSource == models.InputSource{}) {
return errors.New("invalid wasm engine entry module. cannot be empty")
}
if c.EntryModule.InputSource.Source == nil {
return errors.New("invalid wasm engine entry module. source cannot be nil")
}
return nil
}
func (c EngineArguments) ToMap() map[string]interface{} {
return structs.Map(c)
}
func DecodeArguments(spec *models.SpecConfig) (*EngineArguments, error) {
if !spec.IsType(models.EngineWasm) {
return nil, errors.New("invalid wasm engine type. expected " + models.EngineWasm + ", but received: " + spec.Type)
}
inputParams := spec.Params
if inputParams == nil {
return nil, errors.New("invalid wasm engine params. cannot be nil")
}
paramsBytes, err := json.Marshal(inputParams)
if err != nil {
return nil, fmt.Errorf("failed to encode wasm engine specs. %w", err)
}
var c *EngineArguments
err = json.Unmarshal(paramsBytes, &c)
if err != nil {
return nil, fmt.Errorf("failed to decode wasm engine specs. %w", err)
}
return c, c.Validate()
}