github.com/filecoin-project/bacalhau@v0.3.23-0.20230228154132-45c989550ace/pkg/model/v1beta1/task.go (about) 1 package v1beta1 2 3 import ( 4 "fmt" 5 "strings" 6 "time" 7 8 "github.com/c2h5oh/datasize" 9 "github.com/ipld/go-ipld-prime/codec/json" 10 "github.com/ipld/go-ipld-prime/datamodel" 11 ) 12 13 type TaskType string 14 15 const ( 16 TaskTypeDocker TaskType = "docker/run" 17 TaskTypeWasm TaskType = "wasm32-wasi/run" 18 TaskTypeNoop TaskType = "noop" 19 ) 20 21 type Task struct { 22 With string 23 Do TaskType 24 Inputs datamodel.Node 25 Meta IPLDMap[string, datamodel.Node] 26 } 27 28 type Resource struct { 29 IPFS *IPFSResource 30 HTTP *HTTPResource 31 } 32 33 type IPFSResource string 34 type HTTPResource string 35 36 type BacalhauConfig struct { 37 Publisher Publisher 38 Verifier Verifier 39 Timeout time.Duration 40 Resources ResourceSpec 41 Annotations []string 42 Dnt bool 43 } 44 45 type ResourceSpec struct { 46 Cpu Millicores //nolint:stylecheck // name required by IPLD 47 Disk datasize.ByteSize 48 Memory datasize.ByteSize 49 Gpu int 50 } 51 52 type JobType interface { 53 UnmarshalInto(with string, spec *Spec) error 54 } 55 56 type NoopTask struct{} 57 58 func (n NoopTask) UnmarshalInto(with string, spec *Spec) error { 59 spec.Engine = EngineNoop 60 return nil 61 } 62 63 var _ JobType = (*NoopTask)(nil) 64 65 func (task *Task) ToSpec() (*Spec, error) { 66 var inputs JobType 67 var err error 68 switch task.Do { 69 case TaskTypeDocker: 70 inputs, err = Reinterpret[DockerInputs](task.Inputs, BacalhauTaskSchema) 71 case TaskTypeWasm: 72 inputs, err = Reinterpret[WasmInputs](task.Inputs, BacalhauTaskSchema) 73 case TaskTypeNoop: 74 inputs = NoopTask{} 75 default: 76 return nil, fmt.Errorf("TODO: task type %q", task.Do) 77 } 78 if err != nil { 79 return nil, err 80 } 81 82 spec := new(Spec) 83 err = inputs.UnmarshalInto(task.With, spec) 84 if err != nil { 85 return nil, err 86 } 87 88 for key, node := range task.Meta.Values { 89 switch key { 90 case "bacalhau/config": 91 config, err := Reinterpret[BacalhauConfig](node, BacalhauTaskSchema) 92 if err != nil { 93 return nil, err 94 } 95 96 spec.Verifier = config.Verifier 97 spec.Publisher = config.Publisher 98 spec.Annotations = config.Annotations 99 spec.Timeout = config.Timeout.Seconds() 100 spec.Resources = ResourceUsageConfig{ 101 CPU: config.Resources.Cpu.String(), 102 Memory: config.Resources.Memory.String(), 103 Disk: config.Resources.Disk.String(), 104 GPU: fmt.Sprint(config.Resources.Gpu), 105 } 106 spec.DoNotTrack = config.Dnt 107 default: 108 return nil, fmt.Errorf("TODO: config type %q", key) 109 } 110 } 111 112 return spec, nil 113 } 114 115 func parseStorageSource(path string, resource *Resource) StorageSpec { 116 storageSpec := StorageSpec{Path: path} 117 if resource.IPFS != nil { 118 storageSpec.StorageSource = StorageSourceIPFS 119 storageSpec.CID = strings.TrimLeft(string(*resource.IPFS), ":/") 120 } else if resource.HTTP != nil { 121 storageSpec.StorageSource = StorageSourceURLDownload 122 storageSpec.URL = "http" + string(*resource.HTTP) 123 } 124 return storageSpec 125 } 126 127 func parseInputs(mounts IPLDMap[string, Resource]) ([]StorageSpec, error) { 128 inputs := []StorageSpec{} 129 for path, resource := range mounts.Values { 130 resource := resource 131 inputs = append(inputs, parseStorageSource(path, &resource)) 132 } 133 return inputs, nil 134 } 135 136 func parseResource(uri string) (*Resource, error) { 137 return UnmarshalIPLD[Resource]([]byte(`"`+uri+`"`), json.Decode, BacalhauTaskSchema) 138 }