diff --git a/core/main.go b/core/main.go index 7ac2ab9c4..b4aa12113 100644 --- a/core/main.go +++ b/core/main.go @@ -14,8 +14,9 @@ import ( "github.com/mesg-foundation/engine/hash" "github.com/mesg-foundation/engine/logger" "github.com/mesg-foundation/engine/orchestrator" + "github.com/mesg-foundation/engine/protobuf/api" enginesdk "github.com/mesg-foundation/engine/sdk" - instancesdk "github.com/mesg-foundation/engine/sdk/instance" + runnersdk "github.com/mesg-foundation/engine/sdk/runner" "github.com/mesg-foundation/engine/server/grpc" "github.com/mesg-foundation/engine/version" "github.com/mesg-foundation/engine/x/xerrors" @@ -26,42 +27,38 @@ import ( db "github.com/tendermint/tm-db" ) -func initDatabases(cfg *config.Config) (*database.LevelDBInstanceDB, *database.LevelDBExecutionDB, *database.LevelDBProcessDB, error) { - // init instance db. - instanceDB, err := database.NewInstanceDB(filepath.Join(cfg.Path, cfg.Database.InstanceRelativePath)) - if err != nil { - return nil, nil, nil, err - } - +func initDatabases(cfg *config.Config) (*database.LevelDBExecutionDB, *database.LevelDBProcessDB, error) { // init execution db. executionDB, err := database.NewExecutionDB(filepath.Join(cfg.Path, cfg.Database.ExecutionRelativePath)) if err != nil { - return nil, nil, nil, err + return nil, nil, err } // init process db. processDB, err := database.NewProcessDB(filepath.Join(cfg.Path, cfg.Database.ProcessRelativePath)) if err != nil { - return nil, nil, nil, err + return nil, nil, err } - - return instanceDB, executionDB, processDB, nil + return executionDB, processDB, nil } -func stopRunningServices(sdk *enginesdk.SDK) error { - instances, err := sdk.Instance.List(&instancesdk.Filter{}) +func stopRunningServices(sdk *enginesdk.SDK, cfg *config.Config, address string) error { + runners, err := sdk.Runner.List(&runnersdk.Filter{Address: address}) if err != nil { return err } var ( - instancesLen = len(instances) - errC = make(chan error, instancesLen) - wg sync.WaitGroup + runnersLen = len(runners) + errC = make(chan error, runnersLen) + wg sync.WaitGroup ) - wg.Add(instancesLen) - for _, instance := range instances { + wg.Add(runnersLen) + for _, instance := range runners { go func(hash hash.Hash) { defer wg.Done() - err := sdk.Instance.Delete(hash, false) + err := sdk.Runner.Delete(&api.DeleteRunnerRequest{ + Hash: hash, + DeleteData: false, + }, cfg.Account.Name, cfg.Account.Password) if err != nil { errC <- err } @@ -82,7 +79,7 @@ func loadOrGenConfigAccount(kb *cosmos.Keybase, cfg *config.Config) (keys.Info, return nil, err } if exist { - return nil, nil + return kb.Get(cfg.Account.Name) } logrus.WithField("module", "main").Warn("Config account not found. Generating one for development...") mnemonic, err := kb.NewMnemonic() @@ -130,13 +127,13 @@ func main() { logger.Init(cfg.Log.Format, cfg.Log.Level, cfg.Log.ForceColors) // init databases - instanceDB, executionDB, processDB, err := initDatabases(cfg) + executionDB, processDB, err := initDatabases(cfg) if err != nil { logrus.WithField("module", "main").Fatalln(err) } // init container. - c, err := container.New(cfg.Name) + container, err := container.New(cfg.Name) if err != nil { logrus.WithField("module", "main").Fatalln(err) } @@ -168,7 +165,7 @@ func main() { } // gen config account - _, err = loadOrGenConfigAccount(kb, cfg) + acc, err := loadOrGenConfigAccount(kb, cfg) if err != nil { logrus.WithField("module", "main").Fatalln(err) } @@ -189,7 +186,7 @@ func main() { client := cosmos.NewClient(node, app.Cdc(), kb, genesis.ChainID) // init sdk - sdk := enginesdk.New(client, app.Cdc(), kb, c, instanceDB, executionDB, processDB, cfg.Name, strconv.Itoa(port), cfg.IpfsEndpoint) + sdk := enginesdk.New(client, app.Cdc(), kb, executionDB, processDB, container, cfg.Name, strconv.Itoa(port), cfg.IpfsEndpoint) // start tendermint node logrus.WithField("module", "main").WithField("seeds", cfg.Tendermint.Config.P2P.Seeds).Info("starting tendermint node") @@ -222,11 +219,11 @@ func main() { }() <-xsignal.WaitForInterrupt() - if err := stopRunningServices(sdk); err != nil { + if err := stopRunningServices(sdk, cfg, acc.GetAddress().String()); err != nil { logrus.WithField("module", "main").Fatalln(err) } - if err := c.Cleanup(); err != nil { + if err := container.Cleanup(); err != nil { logrus.WithField("module", "main").Fatalln(err) } server.Close() diff --git a/database/instance_db.go b/database/instance_db.go index 4704c8df7..34fb1fa9c 100644 --- a/database/instance_db.go +++ b/database/instance_db.go @@ -1,119 +1,93 @@ package database import ( - "encoding/json" "errors" "fmt" + "github.com/cosmos/cosmos-sdk/codec" + "github.com/mesg-foundation/engine/database/store" "github.com/mesg-foundation/engine/hash" "github.com/mesg-foundation/engine/instance" - "github.com/syndtr/goleveldb/leveldb" ) var ( - errSaveInstanceWithoutHash = errors.New("database: can't save instance without hash") + errCannotSaveInstanceWithoutHash = errors.New("database: can't save instance without hash") ) -// InstanceDB describes the API of Instance database. -type InstanceDB interface { - // Exist check if instance with given hash exist. - Exist(hash hash.Hash) (bool, error) - - // Get retrives instance by instance hash. - Get(hash hash.Hash) (*instance.Instance, error) - - // GetAll retrieves all instances. - GetAll() ([]*instance.Instance, error) - - // Save saves instance to database. - Save(i *instance.Instance) error - - // Delete an instance by instance hash. - Delete(hash hash.Hash) error - - // Close closes underlying database connection. - Close() error -} - -// LevelDBInstanceDB is a database for storing services' instances. -type LevelDBInstanceDB struct { - db *leveldb.DB +// InstanceDB is a database for storing instance definition. +type InstanceDB struct { + s store.Store + cdc *codec.Codec } // NewInstanceDB returns the database which is located under given path. -func NewInstanceDB(path string) (*LevelDBInstanceDB, error) { - db, err := leveldb.OpenFile(path, nil) - if err != nil { - return nil, err +func NewInstanceDB(s store.Store, cdc *codec.Codec) *InstanceDB { + return &InstanceDB{ + s: s, + cdc: cdc, } - return &LevelDBInstanceDB{db: db}, nil -} - -// marshal returns the byte slice from service. -func (d *LevelDBInstanceDB) marshal(i *instance.Instance) ([]byte, error) { - return json.Marshal(i) } -// unmarshal returns the service from byte slice. -func (d *LevelDBInstanceDB) unmarshal(hash hash.Hash, value []byte) (*instance.Instance, error) { +// unmarshal returns the instance from byte slice. +func (d *InstanceDB) unmarshalInstance(hash hash.Hash, value []byte) (*instance.Instance, error) { var s instance.Instance - if err := json.Unmarshal(value, &s); err != nil { - return nil, fmt.Errorf("database: could not decode instance %q: %s", hash, err) + if err := d.cdc.UnmarshalBinaryBare(value, &s); err != nil { + return nil, fmt.Errorf("database: could not decode instance %q: %w", hash.String(), err) } return &s, nil } -// Exist check if instance with given hash exist. -func (d *LevelDBInstanceDB) Exist(hash hash.Hash) (bool, error) { - return d.db.Has(hash, nil) -} - -// Get retrives instance by instance hash. -func (d *LevelDBInstanceDB) Get(hash hash.Hash) (*instance.Instance, error) { - b, err := d.db.Get(hash, nil) - if err != nil { - return nil, err - } - return d.unmarshal(hash, b) -} - -// GetAll retrieves all instances. -func (d *LevelDBInstanceDB) GetAll() ([]*instance.Instance, error) { - instances := []*instance.Instance{} - iter := d.db.NewIterator(nil, nil) +// All returns every instance in database. +func (d *InstanceDB) All() ([]*instance.Instance, error) { + var ( + instances []*instance.Instance + iter = d.s.NewIterator() + ) for iter.Next() { - i, err := d.unmarshal(iter.Key(), iter.Value()) + hash := hash.Hash(iter.Key()) + s, err := d.unmarshalInstance(hash, iter.Value()) if err != nil { - iter.Release() return nil, err } - instances = append(instances, i) + instances = append(instances, s) } iter.Release() return instances, iter.Error() } -// Save saves instance to database. -func (d *LevelDBInstanceDB) Save(i *instance.Instance) error { - if i.Hash.IsZero() { - return errSaveInstanceWithoutHash +// Save stores instance in database. +// If there is an another instance that uses the same sid, it'll be deleted. +func (d *InstanceDB) Save(r *instance.Instance) error { + if r.Hash.IsZero() { + return errCannotSaveInstanceWithoutHash } - - // encode service - b, err := d.marshal(i) + b, err := d.cdc.MarshalBinaryBare(r) if err != nil { return err } - - return d.db.Put(i.Hash, b, nil) + return d.s.Put(r.Hash, b) } // Close closes database. -func (d *LevelDBInstanceDB) Close() error { - return d.db.Close() +func (d *InstanceDB) Close() error { + return d.s.Close() +} + +// Exist check if instance with given hash exist. +func (d *InstanceDB) Exist(hash hash.Hash) (bool, error) { + return d.s.Has(hash) +} + +// Get retrives instance from database. +func (d *InstanceDB) Get(hash hash.Hash) (*instance.Instance, error) { + b, err := d.s.Get(hash) + if err != nil { + return nil, err + } + return d.unmarshalInstance(hash, b) } -// Delete deletes an instance from database. -func (d *LevelDBInstanceDB) Delete(hash hash.Hash) error { - return d.db.Delete(hash, nil) +// Delete deletes instance from database. +func (d *InstanceDB) Delete(hash hash.Hash) error { + return d.s.Delete(hash) } diff --git a/database/instance_db_test.go b/database/instance_db_test.go index 0eedfdd50..e461586dd 100644 --- a/database/instance_db_test.go +++ b/database/instance_db_test.go @@ -5,77 +5,74 @@ import ( "os" "testing" + "github.com/cosmos/cosmos-sdk/codec" + "github.com/mesg-foundation/engine/database/store" "github.com/mesg-foundation/engine/hash" "github.com/mesg-foundation/engine/instance" "github.com/stretchr/testify/require" ) -func instancedb(t *testing.T, dir string) InstanceDB { - db, err := NewInstanceDB(dir) - require.NoError(t, err) - return db -} +func TestInstanceDB(t *testing.T) { + cdc := codec.New() -func TestFindInstance(t *testing.T) { - dir, _ := ioutil.TempDir("", "TestFindInstance") + dir, _ := ioutil.TempDir("", "instance.db.test") defer os.RemoveAll(dir) - db := instancedb(t, dir) + + store, err := store.NewLevelDBStore(dir) + require.NoError(t, err) + db := NewInstanceDB(store, cdc) defer db.Close() - i := &instance.Instance{Hash: hash.Int(1)} - db.Save(i) - tests := []struct { - hash hash.Hash - hasError bool - }{ - {hash: i.Hash, hasError: false}, - {hash: hash.Int(2), hasError: true}, + p := &instance.Instance{ + Hash: hash.Int(1), + EnvHash: hash.Int(11), + ServiceHash: hash.Int(111), } - for _, test := range tests { - instance, err := db.Get(test.hash) - if test.hasError { - require.Error(t, err) - continue - } - - require.NoError(t, err) - require.Equal(t, instance, i) + p2 := &instance.Instance{ + Hash: hash.Int(2), + EnvHash: hash.Int(22), + ServiceHash: hash.Int(222), } -} -func TestSaveInstance(t *testing.T) { - dir, _ := ioutil.TempDir("", "TestSaveInstance") - defer os.RemoveAll(dir) - db := instancedb(t, dir) - defer db.Close() - tests := []struct { - instance *instance.Instance - hasError bool - }{ - {&instance.Instance{Hash: hash.Int(1)}, false}, - {&instance.Instance{}, true}, - } - for _, test := range tests { - err := db.Save(test.instance) - if test.hasError { - require.Error(t, err) - continue - } + t.Run("save", func(t *testing.T) { + require.Error(t, db.Save(&instance.Instance{})) + require.NoError(t, db.Save(p)) + require.NoError(t, db.Save(p2)) + }) + t.Run("all", func(t *testing.T) { + ps, err := db.All() require.NoError(t, err) - } -} - -func TestDeleteInstance(t *testing.T) { - dir, _ := ioutil.TempDir("", "TestDeleteInstance") - defer os.RemoveAll(dir) - db := instancedb(t, dir) - defer db.Close() - i := &instance.Instance{Hash: hash.Int(1)} - db.Save(i) - require.NoError(t, db.Delete(i.Hash)) - _, err := db.Get(i.Hash) - require.Error(t, err) - - require.NoError(t, db.Delete(i.Hash)) + require.Len(t, ps, 2) + require.True(t, p.Equal(ps[0])) + require.True(t, p2.Equal(ps[1])) + }) + t.Run("exist", func(t *testing.T) { + exist, err := db.Exist(hash.Int(1)) + require.NoError(t, err) + require.True(t, exist) + }) + t.Run("get", func(t *testing.T) { + get, err := db.Get(hash.Int(1)) + require.NoError(t, err) + require.True(t, p.Equal(get)) + }) + t.Run("delete", func(t *testing.T) { + require.NoError(t, db.Delete(hash.Int(1))) + t.Run("does not exist", func(t *testing.T) { + exist, err := db.Exist(hash.Int(1)) + require.NoError(t, err) + require.False(t, exist) + }) + t.Run("get not existing", func(t *testing.T) { + _, err := db.Get(hash.Int(1)) + require.Error(t, err) + }) + t.Run("all after delete", func(t *testing.T) { + ps, err := db.All() + require.NoError(t, err) + require.Len(t, ps, 1) + require.True(t, p2.Equal(ps[0])) + }) + }) } diff --git a/database/runner_db.go b/database/runner_db.go new file mode 100644 index 000000000..2c739c925 --- /dev/null +++ b/database/runner_db.go @@ -0,0 +1,93 @@ +package database + +import ( + "errors" + "fmt" + + "github.com/cosmos/cosmos-sdk/codec" + "github.com/mesg-foundation/engine/database/store" + "github.com/mesg-foundation/engine/hash" + "github.com/mesg-foundation/engine/runner" +) + +var ( + errCannotSaveRunnerWithoutHash = errors.New("database: can't save runner without hash") +) + +// RunnerDB is a database for storing runner definition. +type RunnerDB struct { + s store.Store + cdc *codec.Codec +} + +// NewRunnerDB returns the database which is located under given path. +func NewRunnerDB(s store.Store, cdc *codec.Codec) *RunnerDB { + return &RunnerDB{ + s: s, + cdc: cdc, + } +} + +// unmarshal returns the runner from byte slice. +func (d *RunnerDB) unmarshalRunner(hash hash.Hash, value []byte) (*runner.Runner, error) { + var s runner.Runner + if err := d.cdc.UnmarshalBinaryBare(value, &s); err != nil { + return nil, fmt.Errorf("database: could not decode runner %q: %w", hash.String(), err) + } + return &s, nil +} + +// All returns every runner in database. +func (d *RunnerDB) All() ([]*runner.Runner, error) { + var ( + runners []*runner.Runner + iter = d.s.NewIterator() + ) + for iter.Next() { + hash := hash.Hash(iter.Key()) + s, err := d.unmarshalRunner(hash, iter.Value()) + if err != nil { + return nil, err + } + runners = append(runners, s) + } + iter.Release() + return runners, iter.Error() +} + +// Save stores runner in database. +// If there is an another runner that uses the same sid, it'll be deleted. +func (d *RunnerDB) Save(r *runner.Runner) error { + if r.Hash.IsZero() { + return errCannotSaveRunnerWithoutHash + } + b, err := d.cdc.MarshalBinaryBare(r) + if err != nil { + return err + } + return d.s.Put(r.Hash, b) +} + +// Close closes database. +func (d *RunnerDB) Close() error { + return d.s.Close() +} + +// Exist check if runner with given hash exist. +func (d *RunnerDB) Exist(hash hash.Hash) (bool, error) { + return d.s.Has(hash) +} + +// Get retrives runner from database. +func (d *RunnerDB) Get(hash hash.Hash) (*runner.Runner, error) { + b, err := d.s.Get(hash) + if err != nil { + return nil, err + } + return d.unmarshalRunner(hash, b) +} + +// Delete deletes runner from database. +func (d *RunnerDB) Delete(hash hash.Hash) error { + return d.s.Delete(hash) +} diff --git a/database/runner_db_test.go b/database/runner_db_test.go new file mode 100644 index 000000000..61c060d95 --- /dev/null +++ b/database/runner_db_test.go @@ -0,0 +1,78 @@ +package database + +import ( + "io/ioutil" + "os" + "testing" + + "github.com/cosmos/cosmos-sdk/codec" + "github.com/mesg-foundation/engine/database/store" + "github.com/mesg-foundation/engine/hash" + "github.com/mesg-foundation/engine/runner" + "github.com/stretchr/testify/require" +) + +func TestRunnerDB(t *testing.T) { + cdc := codec.New() + + dir, _ := ioutil.TempDir("", "runner.db.test") + defer os.RemoveAll(dir) + + store, err := store.NewLevelDBStore(dir) + require.NoError(t, err) + db := NewRunnerDB(store, cdc) + defer db.Close() + + p := &runner.Runner{ + Hash: hash.Int(1), + Address: "alice", + InstanceHash: hash.Int(11), + } + + p2 := &runner.Runner{ + Hash: hash.Int(2), + Address: "bob", + InstanceHash: hash.Int(22), + } + + t.Run("save", func(t *testing.T) { + require.Error(t, db.Save(&runner.Runner{})) + require.NoError(t, db.Save(p)) + require.NoError(t, db.Save(p2)) + }) + t.Run("all", func(t *testing.T) { + ps, err := db.All() + require.NoError(t, err) + require.Len(t, ps, 2) + require.True(t, p.Equal(ps[0])) + require.True(t, p2.Equal(ps[1])) + }) + t.Run("exist", func(t *testing.T) { + exist, err := db.Exist(hash.Int(1)) + require.NoError(t, err) + require.True(t, exist) + }) + t.Run("get", func(t *testing.T) { + get, err := db.Get(hash.Int(1)) + require.NoError(t, err) + require.True(t, p.Equal(get)) + }) + t.Run("delete", func(t *testing.T) { + require.NoError(t, db.Delete(hash.Int(1))) + t.Run("does not exist", func(t *testing.T) { + exist, err := db.Exist(hash.Int(1)) + require.NoError(t, err) + require.False(t, exist) + }) + t.Run("get not existing", func(t *testing.T) { + _, err := db.Get(hash.Int(1)) + require.Error(t, err) + }) + t.Run("all after delete", func(t *testing.T) { + ps, err := db.All() + require.NoError(t, err) + require.Len(t, ps, 1) + require.True(t, p2.Equal(ps[0])) + }) + }) +} diff --git a/e2e/api_test.go b/e2e/api_test.go index d5565b1f8..c41d8fd5b 100644 --- a/e2e/api_test.go +++ b/e2e/api_test.go @@ -24,6 +24,7 @@ type apiclient struct { pb.ProcessClient pb.InstanceClient pb.OwnershipClient + pb.RunnerClient } var client apiclient @@ -44,6 +45,7 @@ func TestAPI(t *testing.T) { pb.NewProcessClient(conn), pb.NewInstanceClient(conn), pb.NewOwnershipClient(conn), + pb.NewRunnerClient(conn), } // wait for the first block @@ -56,8 +58,9 @@ func TestAPI(t *testing.T) { t.Run("account", testAccount) t.Run("service", testService) t.Run("ownership", testOwnership) + t.Run("runner", testRunner) t.Run("instance", testInstance) t.Run("event", testEvent) t.Run("execution", testExecution) - t.Run("instance/delete", testDeleteInstance) + t.Run("runner/delete", testDeleteRunner) } diff --git a/e2e/instance_test.go b/e2e/instance_test.go index eeda8287a..68ca4cd3f 100644 --- a/e2e/instance_test.go +++ b/e2e/instance_test.go @@ -5,37 +5,13 @@ import ( "testing" "github.com/mesg-foundation/engine/hash" - "github.com/mesg-foundation/engine/protobuf/acknowledgement" pb "github.com/mesg-foundation/engine/protobuf/api" "github.com/stretchr/testify/require" - "google.golang.org/grpc/metadata" ) var testInstanceHash hash.Hash func testInstance(t *testing.T) { - t.Run("create", func(t *testing.T) { - stream, err := client.EventClient.Stream(context.Background(), &pb.StreamEventRequest{ - Filter: &pb.StreamEventRequest_Filter{ - Key: "test_service_ready", - }, - }) - require.NoError(t, err) - acknowledgement.WaitForStreamToBeReady(stream) - - ctx := metadata.NewOutgoingContext(context.Background(), passmd) - resp, err := client.InstanceClient.Create(ctx, &pb.CreateInstanceRequest{ - ServiceHash: testServiceHash, - Env: []string{"BAR=3", "REQUIRED=4"}, - }) - require.NoError(t, err) - testInstanceHash = resp.Hash - - // wait for service to be ready - _, err = stream.Recv() - require.NoError(t, err) - }) - t.Run("get", func(t *testing.T) { resp, err := client.InstanceClient.Get(context.Background(), &pb.GetInstanceRequest{Hash: testInstanceHash}) require.NoError(t, err) @@ -56,17 +32,3 @@ func testInstance(t *testing.T) { require.Equal(t, testInstanceHash, resp.Instances[0].Hash) }) } - -func testDeleteInstance(t *testing.T) { - ctx := metadata.NewOutgoingContext(context.Background(), passmd) - _, err := client.InstanceClient.Delete(ctx, &pb.DeleteInstanceRequest{Hash: testInstanceHash}) - require.NoError(t, err) - - resp, err := client.InstanceClient.List(context.Background(), &pb.ListInstanceRequest{ - Filter: &pb.ListInstanceRequest_Filter{ - ServiceHash: testServiceHash, - }, - }) - require.NoError(t, err) - require.Len(t, resp.Instances, 0) -} diff --git a/e2e/runner_test.go b/e2e/runner_test.go new file mode 100644 index 000000000..a4cfb7da6 --- /dev/null +++ b/e2e/runner_test.go @@ -0,0 +1,63 @@ +package main + +import ( + "context" + "testing" + + "github.com/mesg-foundation/engine/hash" + "github.com/mesg-foundation/engine/protobuf/acknowledgement" + pb "github.com/mesg-foundation/engine/protobuf/api" + "github.com/stretchr/testify/require" + "google.golang.org/grpc/metadata" +) + +var testRunnerHash hash.Hash + +func testRunner(t *testing.T) { + t.Run("create", func(t *testing.T) { + stream, err := client.EventClient.Stream(context.Background(), &pb.StreamEventRequest{ + Filter: &pb.StreamEventRequest_Filter{ + Key: "test_service_ready", + }, + }) + require.NoError(t, err) + acknowledgement.WaitForStreamToBeReady(stream) + + ctx := metadata.NewOutgoingContext(context.Background(), passmd) + resp, err := client.RunnerClient.Create(ctx, &pb.CreateRunnerRequest{ + ServiceHash: testServiceHash, + Env: []string{"BAR=3", "REQUIRED=4"}, + }) + require.NoError(t, err) + testRunnerHash = resp.Hash + + // wait for service to be ready + _, err = stream.Recv() + require.NoError(t, err) + }) + + t.Run("get", func(t *testing.T) { + resp, err := client.RunnerClient.Get(context.Background(), &pb.GetRunnerRequest{Hash: testRunnerHash}) + require.NoError(t, err) + require.Equal(t, testRunnerHash, resp.Hash) + testInstanceHash = resp.InstanceHash + }) + + t.Run("list", func(t *testing.T) { + resp, err := client.RunnerClient.List(context.Background(), &pb.ListRunnerRequest{}) + require.NoError(t, err) + require.Len(t, resp.Runners, 1) + require.Equal(t, testInstanceHash, resp.Runners[0].InstanceHash) + require.Equal(t, testRunnerHash, resp.Runners[0].Hash) + }) +} + +func testDeleteRunner(t *testing.T) { + ctx := metadata.NewOutgoingContext(context.Background(), passmd) + _, err := client.RunnerClient.Delete(ctx, &pb.DeleteRunnerRequest{Hash: testRunnerHash}) + require.NoError(t, err) + + resp, err := client.RunnerClient.List(context.Background(), &pb.ListRunnerRequest{}) + require.NoError(t, err) + require.Len(t, resp.Runners, 0) +} diff --git a/instance/instance.pb.go b/instance/instance.pb.go index 30b1334e1..c32cd0924 100644 --- a/instance/instance.pb.go +++ b/instance/instance.pb.go @@ -4,6 +4,7 @@ package instance import ( + bytes "bytes" fmt "fmt" _ "github.com/gogo/protobuf/gogoproto" proto "github.com/gogo/protobuf/proto" @@ -63,7 +64,7 @@ func init() { func init() { proto.RegisterFile("instance.proto", fileDescriptor_fd22322185b2070b) } var fileDescriptor_fd22322185b2070b = []byte{ - // 222 bytes of a gzipped FileDescriptorProto + // 226 bytes of a gzipped FileDescriptorProto 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0xe2, 0xcb, 0xcc, 0x2b, 0x2e, 0x49, 0xcc, 0x4b, 0x4e, 0xd5, 0x2b, 0x28, 0xca, 0x2f, 0xc9, 0x17, 0xe2, 0xca, 0x4d, 0x2d, 0x4e, 0xd7, 0x2b, 0xa9, 0x2c, 0x48, 0x2d, 0x96, 0x52, 0x4a, 0xcf, 0x4f, 0xcf, 0xd7, 0x07, 0x8b, 0x27, @@ -75,7 +76,42 @@ var fileDescriptor_fd22322185b2070b = []byte{ 0x2c, 0xce, 0x08, 0x02, 0x1b, 0x20, 0x94, 0xc6, 0xc5, 0x5d, 0x9c, 0x5a, 0x54, 0x96, 0x99, 0x9c, 0x0a, 0x12, 0x94, 0x60, 0x02, 0x9b, 0xe7, 0x42, 0x86, 0x79, 0x9f, 0xee, 0xc9, 0xf3, 0x82, 0x38, 0x56, 0x4a, 0x79, 0x89, 0xb9, 0xa9, 0x56, 0x46, 0x4a, 0x41, 0xc8, 0x06, 0x0b, 0xc5, 0x71, 0xb1, - 0xa7, 0xe6, 0x95, 0x81, 0xed, 0x60, 0xa6, 0x96, 0x1d, 0xc6, 0x4a, 0x41, 0x30, 0x43, 0x9d, 0x0c, - 0x4e, 0x3c, 0x94, 0x63, 0x88, 0xd2, 0x22, 0x6c, 0x18, 0x2c, 0x16, 0x92, 0xd8, 0xc0, 0xc1, 0x6a, - 0x0c, 0x08, 0x00, 0x00, 0xff, 0xff, 0x66, 0xa1, 0x50, 0x16, 0x98, 0x01, 0x00, 0x00, + 0xa7, 0xe6, 0x95, 0x81, 0xed, 0x60, 0xa6, 0x96, 0x1d, 0xc6, 0x4a, 0x41, 0x30, 0x43, 0x9d, 0x4c, + 0x4e, 0x3c, 0x94, 0x63, 0x58, 0xf1, 0x48, 0x8e, 0x31, 0x4a, 0x8b, 0xb0, 0x81, 0xb0, 0x98, 0x48, + 0x62, 0x03, 0x07, 0xad, 0x31, 0x20, 0x00, 0x00, 0xff, 0xff, 0x82, 0x71, 0x79, 0x6a, 0x9c, 0x01, + 0x00, 0x00, +} + +func (this *Instance) Equal(that interface{}) bool { + if that == nil { + return this == nil + } + + that1, ok := that.(*Instance) + if !ok { + that2, ok := that.(Instance) + if ok { + that1 = &that2 + } else { + return false + } + } + if that1 == nil { + return this == nil + } else if this == nil { + return false + } + if !this.Hash.Equal(that1.Hash) { + return false + } + if !this.ServiceHash.Equal(that1.ServiceHash) { + return false + } + if !this.EnvHash.Equal(that1.EnvHash) { + return false + } + if !bytes.Equal(this.XXX_unrecognized, that1.XXX_unrecognized) { + return false + } + return true } diff --git a/protobuf/api/instance.pb.go b/protobuf/api/instance.pb.go index ecaaecc19..e96b69a57 100644 --- a/protobuf/api/instance.pb.go +++ b/protobuf/api/instance.pb.go @@ -6,8 +6,6 @@ package api import ( context "context" fmt "fmt" - math "math" - _ "github.com/gogo/protobuf/gogoproto" proto "github.com/gogo/protobuf/proto" github_com_mesg_foundation_engine_hash "github.com/mesg-foundation/engine/hash" @@ -15,6 +13,7 @@ import ( grpc "google.golang.org/grpc" codes "google.golang.org/grpc/codes" status "google.golang.org/grpc/status" + math "math" ) // Reference imports to suppress errors if they are not otherwise used. @@ -62,7 +61,7 @@ var xxx_messageInfo_GetInstanceRequest proto.InternalMessageInfo // The request's data for the `List` API. type ListInstanceRequest struct { - // Filter used to filter a stream of executions. + // Filter used to filter a list of instance. Filter *ListInstanceRequest_Filter `protobuf:"bytes,1,opt,name=filter,proto3" json:"filter,omitempty"` XXX_NoUnkeyedLiteral struct{} `json:"-"` XXX_unrecognized []byte `json:"-"` @@ -173,196 +172,38 @@ func (m *ListInstanceResponse) GetInstances() []*instance.Instance { return nil } -// The request's data for the `Create` API. -type CreateInstanceRequest struct { - // Service's hash. - ServiceHash github_com_mesg_foundation_engine_hash.Hash `protobuf:"bytes,1,opt,name=serviceHash,proto3,customtype=github.com/mesg-foundation/engine/hash.Hash" json:"serviceHash"` - // Environmental variables to apply to the Instance. - Env []string `protobuf:"bytes,2,rep,name=env,proto3" json:"env,omitempty"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` -} - -func (m *CreateInstanceRequest) Reset() { *m = CreateInstanceRequest{} } -func (m *CreateInstanceRequest) String() string { return proto.CompactTextString(m) } -func (*CreateInstanceRequest) ProtoMessage() {} -func (*CreateInstanceRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_71d44b8f4a870f63, []int{3} -} -func (m *CreateInstanceRequest) XXX_Unmarshal(b []byte) error { - return xxx_messageInfo_CreateInstanceRequest.Unmarshal(m, b) -} -func (m *CreateInstanceRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - return xxx_messageInfo_CreateInstanceRequest.Marshal(b, m, deterministic) -} -func (m *CreateInstanceRequest) XXX_Merge(src proto.Message) { - xxx_messageInfo_CreateInstanceRequest.Merge(m, src) -} -func (m *CreateInstanceRequest) XXX_Size() int { - return xxx_messageInfo_CreateInstanceRequest.Size(m) -} -func (m *CreateInstanceRequest) XXX_DiscardUnknown() { - xxx_messageInfo_CreateInstanceRequest.DiscardUnknown(m) -} - -var xxx_messageInfo_CreateInstanceRequest proto.InternalMessageInfo - -func (m *CreateInstanceRequest) GetEnv() []string { - if m != nil { - return m.Env - } - return nil -} - -// The response's data for the `Create` API. -type CreateInstanceResponse struct { - // The instance's hash created. - Hash github_com_mesg_foundation_engine_hash.Hash `protobuf:"bytes,1,opt,name=hash,proto3,customtype=github.com/mesg-foundation/engine/hash.Hash" json:"hash"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` -} - -func (m *CreateInstanceResponse) Reset() { *m = CreateInstanceResponse{} } -func (m *CreateInstanceResponse) String() string { return proto.CompactTextString(m) } -func (*CreateInstanceResponse) ProtoMessage() {} -func (*CreateInstanceResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_71d44b8f4a870f63, []int{4} -} -func (m *CreateInstanceResponse) XXX_Unmarshal(b []byte) error { - return xxx_messageInfo_CreateInstanceResponse.Unmarshal(m, b) -} -func (m *CreateInstanceResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - return xxx_messageInfo_CreateInstanceResponse.Marshal(b, m, deterministic) -} -func (m *CreateInstanceResponse) XXX_Merge(src proto.Message) { - xxx_messageInfo_CreateInstanceResponse.Merge(m, src) -} -func (m *CreateInstanceResponse) XXX_Size() int { - return xxx_messageInfo_CreateInstanceResponse.Size(m) -} -func (m *CreateInstanceResponse) XXX_DiscardUnknown() { - xxx_messageInfo_CreateInstanceResponse.DiscardUnknown(m) -} - -var xxx_messageInfo_CreateInstanceResponse proto.InternalMessageInfo - -// The request's data for the `Delete` API. -type DeleteInstanceRequest struct { - // Instance's hash - Hash github_com_mesg_foundation_engine_hash.Hash `protobuf:"bytes,1,opt,name=hash,proto3,customtype=github.com/mesg-foundation/engine/hash.Hash" json:"hash"` - // If true, any persistent data (volumes) that belongs to the instance and its dependencies will also be deleted. - DeleteData bool `protobuf:"varint,2,opt,name=deleteData,proto3" json:"deleteData,omitempty"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` -} - -func (m *DeleteInstanceRequest) Reset() { *m = DeleteInstanceRequest{} } -func (m *DeleteInstanceRequest) String() string { return proto.CompactTextString(m) } -func (*DeleteInstanceRequest) ProtoMessage() {} -func (*DeleteInstanceRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_71d44b8f4a870f63, []int{5} -} -func (m *DeleteInstanceRequest) XXX_Unmarshal(b []byte) error { - return xxx_messageInfo_DeleteInstanceRequest.Unmarshal(m, b) -} -func (m *DeleteInstanceRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - return xxx_messageInfo_DeleteInstanceRequest.Marshal(b, m, deterministic) -} -func (m *DeleteInstanceRequest) XXX_Merge(src proto.Message) { - xxx_messageInfo_DeleteInstanceRequest.Merge(m, src) -} -func (m *DeleteInstanceRequest) XXX_Size() int { - return xxx_messageInfo_DeleteInstanceRequest.Size(m) -} -func (m *DeleteInstanceRequest) XXX_DiscardUnknown() { - xxx_messageInfo_DeleteInstanceRequest.DiscardUnknown(m) -} - -var xxx_messageInfo_DeleteInstanceRequest proto.InternalMessageInfo - -func (m *DeleteInstanceRequest) GetDeleteData() bool { - if m != nil { - return m.DeleteData - } - return false -} - -// The response's data for the `Delete` API. -type DeleteInstanceResponse struct { - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` -} - -func (m *DeleteInstanceResponse) Reset() { *m = DeleteInstanceResponse{} } -func (m *DeleteInstanceResponse) String() string { return proto.CompactTextString(m) } -func (*DeleteInstanceResponse) ProtoMessage() {} -func (*DeleteInstanceResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_71d44b8f4a870f63, []int{6} -} -func (m *DeleteInstanceResponse) XXX_Unmarshal(b []byte) error { - return xxx_messageInfo_DeleteInstanceResponse.Unmarshal(m, b) -} -func (m *DeleteInstanceResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - return xxx_messageInfo_DeleteInstanceResponse.Marshal(b, m, deterministic) -} -func (m *DeleteInstanceResponse) XXX_Merge(src proto.Message) { - xxx_messageInfo_DeleteInstanceResponse.Merge(m, src) -} -func (m *DeleteInstanceResponse) XXX_Size() int { - return xxx_messageInfo_DeleteInstanceResponse.Size(m) -} -func (m *DeleteInstanceResponse) XXX_DiscardUnknown() { - xxx_messageInfo_DeleteInstanceResponse.DiscardUnknown(m) -} - -var xxx_messageInfo_DeleteInstanceResponse proto.InternalMessageInfo - func init() { proto.RegisterType((*GetInstanceRequest)(nil), "mesg.api.GetInstanceRequest") proto.RegisterType((*ListInstanceRequest)(nil), "mesg.api.ListInstanceRequest") proto.RegisterType((*ListInstanceRequest_Filter)(nil), "mesg.api.ListInstanceRequest.Filter") proto.RegisterType((*ListInstanceResponse)(nil), "mesg.api.ListInstanceResponse") - proto.RegisterType((*CreateInstanceRequest)(nil), "mesg.api.CreateInstanceRequest") - proto.RegisterType((*CreateInstanceResponse)(nil), "mesg.api.CreateInstanceResponse") - proto.RegisterType((*DeleteInstanceRequest)(nil), "mesg.api.DeleteInstanceRequest") - proto.RegisterType((*DeleteInstanceResponse)(nil), "mesg.api.DeleteInstanceResponse") } func init() { proto.RegisterFile("protobuf/api/instance.proto", fileDescriptor_71d44b8f4a870f63) } var fileDescriptor_71d44b8f4a870f63 = []byte{ - // 432 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xb4, 0x54, 0xcd, 0x6e, 0xd4, 0x30, - 0x10, 0x4e, 0x36, 0x10, 0x6d, 0x67, 0x39, 0x20, 0x53, 0xaa, 0x28, 0xd0, 0x6e, 0x64, 0x71, 0x88, - 0x84, 0x70, 0xa4, 0xf4, 0x08, 0xa7, 0x52, 0xb1, 0x05, 0xc1, 0x25, 0x12, 0x17, 0x24, 0x84, 0xbc, - 0xdb, 0xd9, 0xc4, 0x52, 0x6b, 0x87, 0xd8, 0xa9, 0xc4, 0x8d, 0x27, 0xe2, 0xc4, 0x43, 0xf0, 0x0c, - 0x1c, 0xfa, 0x2c, 0x28, 0xce, 0xfe, 0x84, 0x6c, 0xca, 0x85, 0xf6, 0x66, 0x8f, 0xbf, 0xf9, 0xe6, - 0xfb, 0x66, 0x26, 0x81, 0x27, 0x65, 0xa5, 0x8c, 0x9a, 0xd7, 0xcb, 0x84, 0x97, 0x22, 0x11, 0x52, - 0x1b, 0x2e, 0x17, 0xc8, 0x6c, 0x94, 0x8c, 0x2f, 0x51, 0xe7, 0x8c, 0x97, 0x22, 0xa4, 0xb9, 0xca, - 0x55, 0xb2, 0xc1, 0x36, 0x37, 0x7b, 0xb1, 0xa7, 0x16, 0x1d, 0x1e, 0x6e, 0x9e, 0xcd, 0xb7, 0x12, - 0x75, 0x8f, 0x8c, 0x7e, 0x06, 0x32, 0x43, 0xf3, 0x76, 0x15, 0xcc, 0xf0, 0x6b, 0x8d, 0xda, 0x90, - 0x19, 0xdc, 0x2b, 0xb8, 0x2e, 0x02, 0x37, 0x72, 0xe3, 0x07, 0x27, 0xc7, 0xbf, 0xae, 0xa7, 0xce, - 0xef, 0xeb, 0xe9, 0xf3, 0x5c, 0x98, 0xa2, 0x9e, 0xb3, 0x85, 0xba, 0x4c, 0x1a, 0x0d, 0x2f, 0x96, - 0xaa, 0x96, 0xe7, 0xdc, 0x08, 0x25, 0x13, 0x94, 0xb9, 0x90, 0x98, 0x34, 0x59, 0xec, 0x8c, 0xeb, - 0x22, 0xb3, 0x04, 0xf4, 0xa7, 0x0b, 0x8f, 0xde, 0x0b, 0xbd, 0x53, 0xe0, 0x15, 0xf8, 0x4b, 0x71, - 0x61, 0xb0, 0xb2, 0x25, 0x26, 0xe9, 0x33, 0xb6, 0x36, 0xc5, 0x06, 0xe0, 0xec, 0x8d, 0xc5, 0x66, - 0xab, 0x9c, 0xf0, 0x0b, 0xf8, 0x6d, 0x84, 0x7c, 0x84, 0x89, 0xc6, 0xea, 0x4a, 0x2c, 0xf0, 0xec, - 0x3f, 0xf5, 0x76, 0x79, 0xe8, 0x3b, 0xd8, 0xff, 0x5b, 0x86, 0x2e, 0x95, 0xd4, 0x48, 0x52, 0xd8, - 0x5b, 0xf7, 0x4f, 0x07, 0x6e, 0xe4, 0xc5, 0x93, 0x74, 0xbf, 0x55, 0x6e, 0x9b, 0xcb, 0x36, 0x09, - 0x5b, 0x18, 0xfd, 0xee, 0xc2, 0xe3, 0xd7, 0x15, 0x72, 0x83, 0xfd, 0x26, 0xdc, 0x8d, 0x78, 0xf2, - 0x10, 0x3c, 0x94, 0x57, 0xc1, 0x28, 0xf2, 0xe2, 0xbd, 0xac, 0x39, 0x52, 0x0e, 0x07, 0x7d, 0x05, - 0x2b, 0x43, 0xb7, 0x36, 0xe8, 0xc6, 0xe5, 0x29, 0x5e, 0xe0, 0xae, 0xcb, 0xdb, 0x2a, 0x41, 0x8e, - 0x00, 0xce, 0x6d, 0x85, 0x53, 0x6e, 0x78, 0x30, 0x8a, 0xdc, 0x78, 0x9c, 0x75, 0x22, 0x34, 0x80, - 0x83, 0xbe, 0x82, 0xd6, 0x65, 0xfa, 0x63, 0x04, 0xe3, 0x75, 0x90, 0xbc, 0x04, 0x6f, 0x86, 0x86, - 0x3c, 0xdd, 0x6e, 0xdc, 0xee, 0x07, 0x10, 0x0e, 0x4e, 0x95, 0x3a, 0x8d, 0x99, 0x66, 0x31, 0xc8, - 0xe1, 0x3f, 0xf7, 0x35, 0x3c, 0xba, 0xe9, 0xb9, 0x15, 0x44, 0x1d, 0xf2, 0x01, 0xfc, 0x76, 0x24, - 0x64, 0xba, 0xc5, 0x0e, 0xae, 0x49, 0x18, 0xdd, 0x0c, 0xe8, 0xd2, 0xb5, 0xde, 0xbb, 0x74, 0x83, - 0xf3, 0xe8, 0xd2, 0x0d, 0xb7, 0x8b, 0x3a, 0x27, 0xf7, 0x3f, 0x79, 0xbc, 0x14, 0x73, 0xdf, 0xfe, - 0x23, 0x8e, 0xff, 0x04, 0x00, 0x00, 0xff, 0xff, 0x91, 0xfe, 0x6f, 0x14, 0x8f, 0x04, 0x00, 0x00, + // 325 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xa4, 0x52, 0xb1, 0x4e, 0xeb, 0x30, + 0x14, 0x6d, 0xd4, 0xf7, 0xaa, 0xe2, 0x32, 0x99, 0x0e, 0x55, 0xa0, 0xb4, 0xb2, 0x18, 0x2a, 0x21, + 0x6c, 0x29, 0x1d, 0x61, 0xea, 0x40, 0x0b, 0x62, 0xaa, 0xc4, 0x82, 0x84, 0x90, 0x13, 0x6e, 0x12, + 0x4b, 0xd4, 0x36, 0xb1, 0x83, 0xc4, 0x5f, 0xf0, 0x31, 0x7c, 0x04, 0xdf, 0xc0, 0xd0, 0x6f, 0x41, + 0x71, 0x9a, 0x14, 0x68, 0x61, 0x61, 0xcb, 0x3d, 0xf7, 0xdc, 0x73, 0xcf, 0x3d, 0x31, 0xda, 0xd7, + 0x99, 0xb2, 0x2a, 0xcc, 0x63, 0xc6, 0xb5, 0x60, 0x42, 0x1a, 0xcb, 0x65, 0x04, 0xd4, 0xa1, 0xb8, + 0xbd, 0x00, 0x93, 0x50, 0xae, 0x85, 0x4f, 0x12, 0x95, 0x28, 0x56, 0x73, 0x8b, 0xca, 0x15, 0xee, + 0xab, 0x64, 0xfb, 0xfd, 0xba, 0x6d, 0x9f, 0x35, 0x98, 0x6f, 0x62, 0xe4, 0x16, 0xe1, 0x29, 0xd8, + 0x8b, 0x15, 0x38, 0x87, 0xc7, 0x1c, 0x8c, 0xc5, 0x53, 0xf4, 0x2f, 0xe5, 0x26, 0xed, 0x79, 0x43, + 0x6f, 0xb4, 0x3b, 0x19, 0xbf, 0x2d, 0x07, 0x8d, 0xf7, 0xe5, 0xe0, 0x38, 0x11, 0x36, 0xcd, 0x43, + 0x1a, 0xa9, 0x05, 0x2b, 0x3c, 0x9c, 0xc4, 0x2a, 0x97, 0xf7, 0xdc, 0x0a, 0x25, 0x19, 0xc8, 0x44, + 0x48, 0x60, 0xc5, 0x14, 0x9d, 0x71, 0x93, 0xce, 0x9d, 0x00, 0x79, 0xf5, 0xd0, 0xde, 0x95, 0x30, + 0x1b, 0x0b, 0xce, 0x50, 0x2b, 0x16, 0x0f, 0x16, 0x32, 0xb7, 0xa2, 0x13, 0x1c, 0xd1, 0xea, 0x28, + 0xba, 0x85, 0x4e, 0xcf, 0x1d, 0x77, 0xbe, 0x9a, 0xf1, 0xef, 0x50, 0xab, 0x44, 0xf0, 0x35, 0xea, + 0x18, 0xc8, 0x9e, 0x44, 0x04, 0xb3, 0x3f, 0xfa, 0xfd, 0xac, 0x43, 0x2e, 0x51, 0xf7, 0xab, 0x0d, + 0xa3, 0x95, 0x34, 0x80, 0x03, 0xb4, 0x53, 0xe5, 0x67, 0x7a, 0xde, 0xb0, 0x39, 0xea, 0x04, 0xdd, + 0xd2, 0xb9, 0x0b, 0x97, 0xd6, 0x03, 0x6b, 0x5a, 0xf0, 0xe2, 0xa1, 0x76, 0x85, 0xe3, 0x53, 0xd4, + 0x9c, 0x82, 0xc5, 0x07, 0xeb, 0x73, 0x37, 0xd3, 0xf7, 0xb7, 0x4a, 0x92, 0x46, 0xf1, 0x57, 0x0a, + 0x57, 0xb8, 0xff, 0x6b, 0x58, 0xfe, 0xe1, 0x4f, 0xed, 0xf2, 0x08, 0xd2, 0x98, 0xfc, 0xbf, 0x69, + 0x72, 0x2d, 0xc2, 0x96, 0x7b, 0x02, 0xe3, 0x8f, 0x00, 0x00, 0x00, 0xff, 0xff, 0x20, 0x1a, 0xa8, + 0xef, 0x6e, 0x02, 0x00, 0x00, } // Reference imports to suppress errors if they are not otherwise used. @@ -381,11 +222,6 @@ type InstanceClient interface { Get(ctx context.Context, in *GetInstanceRequest, opts ...grpc.CallOption) (*instance.Instance, error) // List returns all Instances matching the criteria of the request. List(ctx context.Context, in *ListInstanceRequest, opts ...grpc.CallOption) (*ListInstanceResponse, error) - // Create an Instance from a Service's hash and custom environmental variables. - // It will return an unique identifier which is used to interact with the Instance. - Create(ctx context.Context, in *CreateInstanceRequest, opts ...grpc.CallOption) (*CreateInstanceResponse, error) - // Delete an Instance. - Delete(ctx context.Context, in *DeleteInstanceRequest, opts ...grpc.CallOption) (*DeleteInstanceResponse, error) } type instanceClient struct { @@ -414,35 +250,12 @@ func (c *instanceClient) List(ctx context.Context, in *ListInstanceRequest, opts return out, nil } -func (c *instanceClient) Create(ctx context.Context, in *CreateInstanceRequest, opts ...grpc.CallOption) (*CreateInstanceResponse, error) { - out := new(CreateInstanceResponse) - err := c.cc.Invoke(ctx, "/mesg.api.Instance/Create", in, out, opts...) - if err != nil { - return nil, err - } - return out, nil -} - -func (c *instanceClient) Delete(ctx context.Context, in *DeleteInstanceRequest, opts ...grpc.CallOption) (*DeleteInstanceResponse, error) { - out := new(DeleteInstanceResponse) - err := c.cc.Invoke(ctx, "/mesg.api.Instance/Delete", in, out, opts...) - if err != nil { - return nil, err - } - return out, nil -} - // InstanceServer is the server API for Instance service. type InstanceServer interface { // Get returns an Instance matching the criteria of the request. Get(context.Context, *GetInstanceRequest) (*instance.Instance, error) // List returns all Instances matching the criteria of the request. List(context.Context, *ListInstanceRequest) (*ListInstanceResponse, error) - // Create an Instance from a Service's hash and custom environmental variables. - // It will return an unique identifier which is used to interact with the Instance. - Create(context.Context, *CreateInstanceRequest) (*CreateInstanceResponse, error) - // Delete an Instance. - Delete(context.Context, *DeleteInstanceRequest) (*DeleteInstanceResponse, error) } // UnimplementedInstanceServer can be embedded to have forward compatible implementations. @@ -455,12 +268,6 @@ func (*UnimplementedInstanceServer) Get(ctx context.Context, req *GetInstanceReq func (*UnimplementedInstanceServer) List(ctx context.Context, req *ListInstanceRequest) (*ListInstanceResponse, error) { return nil, status.Errorf(codes.Unimplemented, "method List not implemented") } -func (*UnimplementedInstanceServer) Create(ctx context.Context, req *CreateInstanceRequest) (*CreateInstanceResponse, error) { - return nil, status.Errorf(codes.Unimplemented, "method Create not implemented") -} -func (*UnimplementedInstanceServer) Delete(ctx context.Context, req *DeleteInstanceRequest) (*DeleteInstanceResponse, error) { - return nil, status.Errorf(codes.Unimplemented, "method Delete not implemented") -} func RegisterInstanceServer(s *grpc.Server, srv InstanceServer) { s.RegisterService(&_Instance_serviceDesc, srv) @@ -502,42 +309,6 @@ func _Instance_List_Handler(srv interface{}, ctx context.Context, dec func(inter return interceptor(ctx, in, info, handler) } -func _Instance_Create_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { - in := new(CreateInstanceRequest) - if err := dec(in); err != nil { - return nil, err - } - if interceptor == nil { - return srv.(InstanceServer).Create(ctx, in) - } - info := &grpc.UnaryServerInfo{ - Server: srv, - FullMethod: "/mesg.api.Instance/Create", - } - handler := func(ctx context.Context, req interface{}) (interface{}, error) { - return srv.(InstanceServer).Create(ctx, req.(*CreateInstanceRequest)) - } - return interceptor(ctx, in, info, handler) -} - -func _Instance_Delete_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { - in := new(DeleteInstanceRequest) - if err := dec(in); err != nil { - return nil, err - } - if interceptor == nil { - return srv.(InstanceServer).Delete(ctx, in) - } - info := &grpc.UnaryServerInfo{ - Server: srv, - FullMethod: "/mesg.api.Instance/Delete", - } - handler := func(ctx context.Context, req interface{}) (interface{}, error) { - return srv.(InstanceServer).Delete(ctx, req.(*DeleteInstanceRequest)) - } - return interceptor(ctx, in, info, handler) -} - var _Instance_serviceDesc = grpc.ServiceDesc{ ServiceName: "mesg.api.Instance", HandlerType: (*InstanceServer)(nil), @@ -550,14 +321,6 @@ var _Instance_serviceDesc = grpc.ServiceDesc{ MethodName: "List", Handler: _Instance_List_Handler, }, - { - MethodName: "Create", - Handler: _Instance_Create_Handler, - }, - { - MethodName: "Delete", - Handler: _Instance_Delete_Handler, - }, }, Streams: []grpc.StreamDesc{}, Metadata: "protobuf/api/instance.proto", diff --git a/protobuf/api/instance.proto b/protobuf/api/instance.proto index 2238f52c8..4574d7bb9 100644 --- a/protobuf/api/instance.proto +++ b/protobuf/api/instance.proto @@ -18,13 +18,6 @@ service Instance { // List returns all Instances matching the criteria of the request. rpc List (ListInstanceRequest) returns (ListInstanceResponse) {} - - // Create an Instance from a Service's hash and custom environmental variables. - // It will return an unique identifier which is used to interact with the Instance. - rpc Create (CreateInstanceRequest) returns (CreateInstanceResponse) {} - - // Delete an Instance. - rpc Delete (DeleteInstanceRequest) returns (DeleteInstanceResponse) {} } // The request's data for the `Get` API. @@ -55,39 +48,3 @@ message ListInstanceResponse { // List of instances that match the request's filters. repeated types.Instance instances = 1; } - -// The request's data for the `Create` API. -message CreateInstanceRequest { - // Service's hash. - bytes serviceHash = 1 [ - (gogoproto.customtype) = "github.com/mesg-foundation/engine/hash.Hash", - (gogoproto.nullable) = false - ]; - - // Environmental variables to apply to the Instance. - repeated string env = 2; -} - -// The response's data for the `Create` API. -message CreateInstanceResponse { - // The instance's hash created. - bytes hash = 1 [ - (gogoproto.customtype) = "github.com/mesg-foundation/engine/hash.Hash", - (gogoproto.nullable) = false - ]; -} - -// The request's data for the `Delete` API. -message DeleteInstanceRequest { - // Instance's hash - bytes hash = 1 [ - (gogoproto.customtype) = "github.com/mesg-foundation/engine/hash.Hash", - (gogoproto.nullable) = false - ]; - - // If true, any persistent data (volumes) that belongs to the instance and its dependencies will also be deleted. - bool deleteData = 2; -} - -// The response's data for the `Delete` API. -message DeleteInstanceResponse {} diff --git a/protobuf/api/runner.pb.go b/protobuf/api/runner.pb.go new file mode 100644 index 000000000..be395040e --- /dev/null +++ b/protobuf/api/runner.pb.go @@ -0,0 +1,574 @@ +// Code generated by protoc-gen-gogo. DO NOT EDIT. +// source: protobuf/api/runner.proto + +package api + +import ( + context "context" + fmt "fmt" + _ "github.com/gogo/protobuf/gogoproto" + proto "github.com/gogo/protobuf/proto" + github_com_mesg_foundation_engine_hash "github.com/mesg-foundation/engine/hash" + runner "github.com/mesg-foundation/engine/runner" + grpc "google.golang.org/grpc" + codes "google.golang.org/grpc/codes" + status "google.golang.org/grpc/status" + math "math" +) + +// Reference imports to suppress errors if they are not otherwise used. +var _ = proto.Marshal +var _ = fmt.Errorf +var _ = math.Inf + +// This is a compile-time assertion to ensure that this generated file +// is compatible with the proto package it is being compiled against. +// A compilation error at this line likely means your copy of the +// proto package needs to be updated. +const _ = proto.GoGoProtoPackageIsVersion3 // please upgrade the proto package + +// The request's data for the `Get` API. +type GetRunnerRequest struct { + Hash github_com_mesg_foundation_engine_hash.Hash `protobuf:"bytes,1,opt,name=hash,proto3,customtype=github.com/mesg-foundation/engine/hash.Hash" json:"hash"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *GetRunnerRequest) Reset() { *m = GetRunnerRequest{} } +func (m *GetRunnerRequest) String() string { return proto.CompactTextString(m) } +func (*GetRunnerRequest) ProtoMessage() {} +func (*GetRunnerRequest) Descriptor() ([]byte, []int) { + return fileDescriptor_66b76d1ada2874b2, []int{0} +} +func (m *GetRunnerRequest) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_GetRunnerRequest.Unmarshal(m, b) +} +func (m *GetRunnerRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_GetRunnerRequest.Marshal(b, m, deterministic) +} +func (m *GetRunnerRequest) XXX_Merge(src proto.Message) { + xxx_messageInfo_GetRunnerRequest.Merge(m, src) +} +func (m *GetRunnerRequest) XXX_Size() int { + return xxx_messageInfo_GetRunnerRequest.Size(m) +} +func (m *GetRunnerRequest) XXX_DiscardUnknown() { + xxx_messageInfo_GetRunnerRequest.DiscardUnknown(m) +} + +var xxx_messageInfo_GetRunnerRequest proto.InternalMessageInfo + +// The request's data for the `List` API. +type ListRunnerRequest struct { + // Filter used to filter runners. + Filter *ListRunnerRequest_Filter `protobuf:"bytes,1,opt,name=filter,proto3" json:"filter,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *ListRunnerRequest) Reset() { *m = ListRunnerRequest{} } +func (m *ListRunnerRequest) String() string { return proto.CompactTextString(m) } +func (*ListRunnerRequest) ProtoMessage() {} +func (*ListRunnerRequest) Descriptor() ([]byte, []int) { + return fileDescriptor_66b76d1ada2874b2, []int{1} +} +func (m *ListRunnerRequest) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_ListRunnerRequest.Unmarshal(m, b) +} +func (m *ListRunnerRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_ListRunnerRequest.Marshal(b, m, deterministic) +} +func (m *ListRunnerRequest) XXX_Merge(src proto.Message) { + xxx_messageInfo_ListRunnerRequest.Merge(m, src) +} +func (m *ListRunnerRequest) XXX_Size() int { + return xxx_messageInfo_ListRunnerRequest.Size(m) +} +func (m *ListRunnerRequest) XXX_DiscardUnknown() { + xxx_messageInfo_ListRunnerRequest.DiscardUnknown(m) +} + +var xxx_messageInfo_ListRunnerRequest proto.InternalMessageInfo + +func (m *ListRunnerRequest) GetFilter() *ListRunnerRequest_Filter { + if m != nil { + return m.Filter + } + return nil +} + +// Filter contains filtering criteria. +type ListRunnerRequest_Filter struct { + // Filter by instance hash. + InstanceHash github_com_mesg_foundation_engine_hash.Hash `protobuf:"bytes,1,opt,name=instanceHash,proto3,customtype=github.com/mesg-foundation/engine/hash.Hash" json:"instanceHash"` + // Filter by address + Address string `protobuf:"bytes,2,opt,name=address,proto3" json:"address,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *ListRunnerRequest_Filter) Reset() { *m = ListRunnerRequest_Filter{} } +func (m *ListRunnerRequest_Filter) String() string { return proto.CompactTextString(m) } +func (*ListRunnerRequest_Filter) ProtoMessage() {} +func (*ListRunnerRequest_Filter) Descriptor() ([]byte, []int) { + return fileDescriptor_66b76d1ada2874b2, []int{1, 0} +} +func (m *ListRunnerRequest_Filter) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_ListRunnerRequest_Filter.Unmarshal(m, b) +} +func (m *ListRunnerRequest_Filter) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_ListRunnerRequest_Filter.Marshal(b, m, deterministic) +} +func (m *ListRunnerRequest_Filter) XXX_Merge(src proto.Message) { + xxx_messageInfo_ListRunnerRequest_Filter.Merge(m, src) +} +func (m *ListRunnerRequest_Filter) XXX_Size() int { + return xxx_messageInfo_ListRunnerRequest_Filter.Size(m) +} +func (m *ListRunnerRequest_Filter) XXX_DiscardUnknown() { + xxx_messageInfo_ListRunnerRequest_Filter.DiscardUnknown(m) +} + +var xxx_messageInfo_ListRunnerRequest_Filter proto.InternalMessageInfo + +func (m *ListRunnerRequest_Filter) GetAddress() string { + if m != nil { + return m.Address + } + return "" +} + +// The response's data for the `List` API. +type ListRunnerResponse struct { + // List of runners that match the request's filters. + Runners []*runner.Runner `protobuf:"bytes,1,rep,name=runners,proto3" json:"runners,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *ListRunnerResponse) Reset() { *m = ListRunnerResponse{} } +func (m *ListRunnerResponse) String() string { return proto.CompactTextString(m) } +func (*ListRunnerResponse) ProtoMessage() {} +func (*ListRunnerResponse) Descriptor() ([]byte, []int) { + return fileDescriptor_66b76d1ada2874b2, []int{2} +} +func (m *ListRunnerResponse) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_ListRunnerResponse.Unmarshal(m, b) +} +func (m *ListRunnerResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_ListRunnerResponse.Marshal(b, m, deterministic) +} +func (m *ListRunnerResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_ListRunnerResponse.Merge(m, src) +} +func (m *ListRunnerResponse) XXX_Size() int { + return xxx_messageInfo_ListRunnerResponse.Size(m) +} +func (m *ListRunnerResponse) XXX_DiscardUnknown() { + xxx_messageInfo_ListRunnerResponse.DiscardUnknown(m) +} + +var xxx_messageInfo_ListRunnerResponse proto.InternalMessageInfo + +func (m *ListRunnerResponse) GetRunners() []*runner.Runner { + if m != nil { + return m.Runners + } + return nil +} + +// The request's data for the `Create` API. +type CreateRunnerRequest struct { + // Service's hash to start the runner with. + ServiceHash github_com_mesg_foundation_engine_hash.Hash `protobuf:"bytes,1,opt,name=serviceHash,proto3,customtype=github.com/mesg-foundation/engine/hash.Hash" json:"serviceHash"` + // Environmental variables to start the runner with. + Env []string `protobuf:"bytes,2,rep,name=env,proto3" json:"env,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *CreateRunnerRequest) Reset() { *m = CreateRunnerRequest{} } +func (m *CreateRunnerRequest) String() string { return proto.CompactTextString(m) } +func (*CreateRunnerRequest) ProtoMessage() {} +func (*CreateRunnerRequest) Descriptor() ([]byte, []int) { + return fileDescriptor_66b76d1ada2874b2, []int{3} +} +func (m *CreateRunnerRequest) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_CreateRunnerRequest.Unmarshal(m, b) +} +func (m *CreateRunnerRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_CreateRunnerRequest.Marshal(b, m, deterministic) +} +func (m *CreateRunnerRequest) XXX_Merge(src proto.Message) { + xxx_messageInfo_CreateRunnerRequest.Merge(m, src) +} +func (m *CreateRunnerRequest) XXX_Size() int { + return xxx_messageInfo_CreateRunnerRequest.Size(m) +} +func (m *CreateRunnerRequest) XXX_DiscardUnknown() { + xxx_messageInfo_CreateRunnerRequest.DiscardUnknown(m) +} + +var xxx_messageInfo_CreateRunnerRequest proto.InternalMessageInfo + +func (m *CreateRunnerRequest) GetEnv() []string { + if m != nil { + return m.Env + } + return nil +} + +// The response's data for the `Create` API. +type CreateRunnerResponse struct { + // The runner's hash created. + Hash github_com_mesg_foundation_engine_hash.Hash `protobuf:"bytes,1,opt,name=hash,proto3,customtype=github.com/mesg-foundation/engine/hash.Hash" json:"hash"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *CreateRunnerResponse) Reset() { *m = CreateRunnerResponse{} } +func (m *CreateRunnerResponse) String() string { return proto.CompactTextString(m) } +func (*CreateRunnerResponse) ProtoMessage() {} +func (*CreateRunnerResponse) Descriptor() ([]byte, []int) { + return fileDescriptor_66b76d1ada2874b2, []int{4} +} +func (m *CreateRunnerResponse) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_CreateRunnerResponse.Unmarshal(m, b) +} +func (m *CreateRunnerResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_CreateRunnerResponse.Marshal(b, m, deterministic) +} +func (m *CreateRunnerResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_CreateRunnerResponse.Merge(m, src) +} +func (m *CreateRunnerResponse) XXX_Size() int { + return xxx_messageInfo_CreateRunnerResponse.Size(m) +} +func (m *CreateRunnerResponse) XXX_DiscardUnknown() { + xxx_messageInfo_CreateRunnerResponse.DiscardUnknown(m) +} + +var xxx_messageInfo_CreateRunnerResponse proto.InternalMessageInfo + +// The request's data for the `Delete` API. +type DeleteRunnerRequest struct { + // Runner's hash + Hash github_com_mesg_foundation_engine_hash.Hash `protobuf:"bytes,1,opt,name=hash,proto3,customtype=github.com/mesg-foundation/engine/hash.Hash" json:"hash"` + // If true, any persistent data (volumes) that belongs to the runner's container and its dependencies will also be deleted. + DeleteData bool `protobuf:"varint,2,opt,name=deleteData,proto3" json:"deleteData,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *DeleteRunnerRequest) Reset() { *m = DeleteRunnerRequest{} } +func (m *DeleteRunnerRequest) String() string { return proto.CompactTextString(m) } +func (*DeleteRunnerRequest) ProtoMessage() {} +func (*DeleteRunnerRequest) Descriptor() ([]byte, []int) { + return fileDescriptor_66b76d1ada2874b2, []int{5} +} +func (m *DeleteRunnerRequest) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_DeleteRunnerRequest.Unmarshal(m, b) +} +func (m *DeleteRunnerRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_DeleteRunnerRequest.Marshal(b, m, deterministic) +} +func (m *DeleteRunnerRequest) XXX_Merge(src proto.Message) { + xxx_messageInfo_DeleteRunnerRequest.Merge(m, src) +} +func (m *DeleteRunnerRequest) XXX_Size() int { + return xxx_messageInfo_DeleteRunnerRequest.Size(m) +} +func (m *DeleteRunnerRequest) XXX_DiscardUnknown() { + xxx_messageInfo_DeleteRunnerRequest.DiscardUnknown(m) +} + +var xxx_messageInfo_DeleteRunnerRequest proto.InternalMessageInfo + +func (m *DeleteRunnerRequest) GetDeleteData() bool { + if m != nil { + return m.DeleteData + } + return false +} + +// The response's data for the `Delete` API. +type DeleteRunnerResponse struct { + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *DeleteRunnerResponse) Reset() { *m = DeleteRunnerResponse{} } +func (m *DeleteRunnerResponse) String() string { return proto.CompactTextString(m) } +func (*DeleteRunnerResponse) ProtoMessage() {} +func (*DeleteRunnerResponse) Descriptor() ([]byte, []int) { + return fileDescriptor_66b76d1ada2874b2, []int{6} +} +func (m *DeleteRunnerResponse) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_DeleteRunnerResponse.Unmarshal(m, b) +} +func (m *DeleteRunnerResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_DeleteRunnerResponse.Marshal(b, m, deterministic) +} +func (m *DeleteRunnerResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_DeleteRunnerResponse.Merge(m, src) +} +func (m *DeleteRunnerResponse) XXX_Size() int { + return xxx_messageInfo_DeleteRunnerResponse.Size(m) +} +func (m *DeleteRunnerResponse) XXX_DiscardUnknown() { + xxx_messageInfo_DeleteRunnerResponse.DiscardUnknown(m) +} + +var xxx_messageInfo_DeleteRunnerResponse proto.InternalMessageInfo + +func init() { + proto.RegisterType((*GetRunnerRequest)(nil), "mesg.api.GetRunnerRequest") + proto.RegisterType((*ListRunnerRequest)(nil), "mesg.api.ListRunnerRequest") + proto.RegisterType((*ListRunnerRequest_Filter)(nil), "mesg.api.ListRunnerRequest.Filter") + proto.RegisterType((*ListRunnerResponse)(nil), "mesg.api.ListRunnerResponse") + proto.RegisterType((*CreateRunnerRequest)(nil), "mesg.api.CreateRunnerRequest") + proto.RegisterType((*CreateRunnerResponse)(nil), "mesg.api.CreateRunnerResponse") + proto.RegisterType((*DeleteRunnerRequest)(nil), "mesg.api.DeleteRunnerRequest") + proto.RegisterType((*DeleteRunnerResponse)(nil), "mesg.api.DeleteRunnerResponse") +} + +func init() { proto.RegisterFile("protobuf/api/runner.proto", fileDescriptor_66b76d1ada2874b2) } + +var fileDescriptor_66b76d1ada2874b2 = []byte{ + // 452 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xac, 0x54, 0xc1, 0x6e, 0xd4, 0x30, + 0x10, 0xdd, 0x6c, 0x4a, 0xda, 0xce, 0xf6, 0x50, 0xdc, 0x0a, 0x85, 0x14, 0xda, 0x95, 0x4f, 0x91, + 0x00, 0x47, 0xda, 0x1e, 0x90, 0x38, 0x6e, 0x2b, 0xb6, 0x48, 0x9c, 0x22, 0x21, 0x24, 0x38, 0x20, + 0x6f, 0x33, 0x9b, 0x58, 0x6a, 0xed, 0x10, 0x3b, 0x95, 0x10, 0x52, 0xbf, 0x84, 0x0f, 0xe2, 0xc0, + 0x17, 0x70, 0xe8, 0xb7, 0xa0, 0xd8, 0xbb, 0x6d, 0xb2, 0x04, 0x2e, 0xed, 0xcd, 0x9e, 0x79, 0x7e, + 0x33, 0xef, 0xcd, 0x24, 0xf0, 0xb4, 0xac, 0x94, 0x51, 0xf3, 0x7a, 0x91, 0xf0, 0x52, 0x24, 0x55, + 0x2d, 0x25, 0x56, 0xcc, 0xc6, 0xc8, 0xd6, 0x25, 0xea, 0x9c, 0xf1, 0x52, 0x44, 0x34, 0x57, 0xb9, + 0x4a, 0x6e, 0x91, 0xcd, 0xcd, 0x5e, 0xec, 0xc9, 0xa1, 0xa3, 0x83, 0xdb, 0xb4, 0xf9, 0x56, 0xa2, + 0xee, 0x50, 0xd1, 0xcf, 0xb0, 0x3b, 0x43, 0x93, 0xda, 0x50, 0x8a, 0x5f, 0x6b, 0xd4, 0x86, 0xcc, + 0x60, 0xa3, 0xe0, 0xba, 0x08, 0xbd, 0xb1, 0x17, 0xef, 0x4c, 0x8f, 0x7f, 0xde, 0x1c, 0x0d, 0x7e, + 0xdf, 0x1c, 0xbd, 0xc8, 0x85, 0x29, 0xea, 0x39, 0x3b, 0x57, 0x97, 0x49, 0x53, 0xff, 0xd5, 0x42, + 0xd5, 0x32, 0xe3, 0x46, 0x28, 0x99, 0xa0, 0xcc, 0x85, 0xc4, 0xa4, 0x79, 0xc5, 0xce, 0xb8, 0x2e, + 0x52, 0x4b, 0x40, 0x7f, 0x79, 0xf0, 0xf8, 0xbd, 0xd0, 0x6b, 0xf4, 0x6f, 0x20, 0x58, 0x88, 0x0b, + 0x83, 0x95, 0x2d, 0x30, 0x9a, 0x50, 0xb6, 0x92, 0xc3, 0xfe, 0x02, 0xb3, 0xb7, 0x16, 0x99, 0x2e, + 0x5f, 0x44, 0xdf, 0x21, 0x70, 0x11, 0xf2, 0x11, 0x76, 0x84, 0xd4, 0x86, 0xcb, 0x73, 0x3c, 0xbb, + 0x67, 0xb3, 0x1d, 0x22, 0x12, 0xc2, 0x26, 0xcf, 0xb2, 0x0a, 0xb5, 0x0e, 0x87, 0x63, 0x2f, 0xde, + 0x4e, 0x57, 0x57, 0x3a, 0x05, 0xd2, 0x6e, 0x50, 0x97, 0x4a, 0x6a, 0x24, 0x2f, 0x61, 0xd3, 0x39, + 0xaa, 0x43, 0x6f, 0xec, 0xc7, 0xa3, 0x09, 0x71, 0x7a, 0xac, 0xd9, 0x6c, 0x09, 0x5e, 0x41, 0xe8, + 0x35, 0xec, 0x9d, 0x54, 0xc8, 0x0d, 0x76, 0x3d, 0xf9, 0x00, 0x23, 0x8d, 0xd5, 0x95, 0xb8, 0xbf, + 0x98, 0x36, 0x0f, 0xd9, 0x05, 0x1f, 0xe5, 0x55, 0x38, 0x1c, 0xfb, 0xf1, 0x76, 0xda, 0x1c, 0xe9, + 0x17, 0xd8, 0xef, 0xd6, 0x5f, 0xaa, 0x78, 0xb0, 0x99, 0x5f, 0xc3, 0xde, 0x29, 0x5e, 0xe0, 0xba, + 0xc0, 0x87, 0xe2, 0x27, 0x87, 0x00, 0x99, 0xe5, 0x3f, 0xe5, 0x86, 0xdb, 0x09, 0x6d, 0xa5, 0xad, + 0x08, 0x7d, 0x02, 0xfb, 0xdd, 0xfa, 0x4e, 0xe0, 0xe4, 0xc7, 0x10, 0x02, 0x17, 0x22, 0xaf, 0xc1, + 0x9f, 0xa1, 0x21, 0xd1, 0xdd, 0xde, 0xad, 0x7f, 0x02, 0x51, 0xcf, 0x0c, 0xe9, 0x80, 0x9c, 0xc0, + 0x46, 0xb3, 0x00, 0xe4, 0xe0, 0x3f, 0x1b, 0x1b, 0x3d, 0xeb, 0x4f, 0xba, 0x36, 0xe8, 0x80, 0xbc, + 0x83, 0xc0, 0x4d, 0x80, 0x3c, 0xbf, 0x43, 0xf6, 0xec, 0x44, 0x74, 0xf8, 0xaf, 0x74, 0x9b, 0xca, + 0x69, 0x6d, 0x53, 0xf5, 0xb8, 0xdf, 0xa6, 0xea, 0x33, 0x87, 0x0e, 0xa6, 0x8f, 0x3e, 0xf9, 0xbc, + 0x14, 0xf3, 0xc0, 0xfe, 0x15, 0x8e, 0xff, 0x04, 0x00, 0x00, 0xff, 0xff, 0x90, 0xbd, 0x2d, 0x88, + 0x7d, 0x04, 0x00, 0x00, +} + +// Reference imports to suppress errors if they are not otherwise used. +var _ context.Context +var _ grpc.ClientConn + +// This is a compile-time assertion to ensure that this generated file +// is compatible with the grpc package it is being compiled against. +const _ = grpc.SupportPackageIsVersion4 + +// RunnerClient is the client API for Runner service. +// +// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://godoc.org/google.golang.org/grpc#ClientConn.NewStream. +type RunnerClient interface { + // Get returns an Runner matching the criteria of the request. + Get(ctx context.Context, in *GetRunnerRequest, opts ...grpc.CallOption) (*runner.Runner, error) + // List returns all Runners matching the criteria of the request. + List(ctx context.Context, in *ListRunnerRequest, opts ...grpc.CallOption) (*ListRunnerResponse, error) + // Create an Runner from a Service's hash and custom environmental variables. + // It will return an unique identifier to identify the runner. + Create(ctx context.Context, in *CreateRunnerRequest, opts ...grpc.CallOption) (*CreateRunnerResponse, error) + // Delete an Runner. + Delete(ctx context.Context, in *DeleteRunnerRequest, opts ...grpc.CallOption) (*DeleteRunnerResponse, error) +} + +type runnerClient struct { + cc *grpc.ClientConn +} + +func NewRunnerClient(cc *grpc.ClientConn) RunnerClient { + return &runnerClient{cc} +} + +func (c *runnerClient) Get(ctx context.Context, in *GetRunnerRequest, opts ...grpc.CallOption) (*runner.Runner, error) { + out := new(runner.Runner) + err := c.cc.Invoke(ctx, "/mesg.api.Runner/Get", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *runnerClient) List(ctx context.Context, in *ListRunnerRequest, opts ...grpc.CallOption) (*ListRunnerResponse, error) { + out := new(ListRunnerResponse) + err := c.cc.Invoke(ctx, "/mesg.api.Runner/List", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *runnerClient) Create(ctx context.Context, in *CreateRunnerRequest, opts ...grpc.CallOption) (*CreateRunnerResponse, error) { + out := new(CreateRunnerResponse) + err := c.cc.Invoke(ctx, "/mesg.api.Runner/Create", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *runnerClient) Delete(ctx context.Context, in *DeleteRunnerRequest, opts ...grpc.CallOption) (*DeleteRunnerResponse, error) { + out := new(DeleteRunnerResponse) + err := c.cc.Invoke(ctx, "/mesg.api.Runner/Delete", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +// RunnerServer is the server API for Runner service. +type RunnerServer interface { + // Get returns an Runner matching the criteria of the request. + Get(context.Context, *GetRunnerRequest) (*runner.Runner, error) + // List returns all Runners matching the criteria of the request. + List(context.Context, *ListRunnerRequest) (*ListRunnerResponse, error) + // Create an Runner from a Service's hash and custom environmental variables. + // It will return an unique identifier to identify the runner. + Create(context.Context, *CreateRunnerRequest) (*CreateRunnerResponse, error) + // Delete an Runner. + Delete(context.Context, *DeleteRunnerRequest) (*DeleteRunnerResponse, error) +} + +// UnimplementedRunnerServer can be embedded to have forward compatible implementations. +type UnimplementedRunnerServer struct { +} + +func (*UnimplementedRunnerServer) Get(ctx context.Context, req *GetRunnerRequest) (*runner.Runner, error) { + return nil, status.Errorf(codes.Unimplemented, "method Get not implemented") +} +func (*UnimplementedRunnerServer) List(ctx context.Context, req *ListRunnerRequest) (*ListRunnerResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method List not implemented") +} +func (*UnimplementedRunnerServer) Create(ctx context.Context, req *CreateRunnerRequest) (*CreateRunnerResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method Create not implemented") +} +func (*UnimplementedRunnerServer) Delete(ctx context.Context, req *DeleteRunnerRequest) (*DeleteRunnerResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method Delete not implemented") +} + +func RegisterRunnerServer(s *grpc.Server, srv RunnerServer) { + s.RegisterService(&_Runner_serviceDesc, srv) +} + +func _Runner_Get_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(GetRunnerRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(RunnerServer).Get(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/mesg.api.Runner/Get", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(RunnerServer).Get(ctx, req.(*GetRunnerRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _Runner_List_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(ListRunnerRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(RunnerServer).List(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/mesg.api.Runner/List", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(RunnerServer).List(ctx, req.(*ListRunnerRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _Runner_Create_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(CreateRunnerRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(RunnerServer).Create(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/mesg.api.Runner/Create", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(RunnerServer).Create(ctx, req.(*CreateRunnerRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _Runner_Delete_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(DeleteRunnerRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(RunnerServer).Delete(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/mesg.api.Runner/Delete", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(RunnerServer).Delete(ctx, req.(*DeleteRunnerRequest)) + } + return interceptor(ctx, in, info, handler) +} + +var _Runner_serviceDesc = grpc.ServiceDesc{ + ServiceName: "mesg.api.Runner", + HandlerType: (*RunnerServer)(nil), + Methods: []grpc.MethodDesc{ + { + MethodName: "Get", + Handler: _Runner_Get_Handler, + }, + { + MethodName: "List", + Handler: _Runner_List_Handler, + }, + { + MethodName: "Create", + Handler: _Runner_Create_Handler, + }, + { + MethodName: "Delete", + Handler: _Runner_Delete_Handler, + }, + }, + Streams: []grpc.StreamDesc{}, + Metadata: "protobuf/api/runner.proto", +} diff --git a/protobuf/api/runner.proto b/protobuf/api/runner.proto new file mode 100644 index 000000000..f3b294801 --- /dev/null +++ b/protobuf/api/runner.proto @@ -0,0 +1,97 @@ +syntax = "proto3"; + +import "gogo/protobuf/gogoproto/gogo.proto"; +import "protobuf/types/runner.proto"; + +package mesg.api; +option go_package = "api"; + +// This is the API to interact with the Runner. +// +// This API is a [gRPC](https://grpc.io/) API. +// +// The source file of this API is hosted on [GitHub](https://github.com/mesg-foundation/engine/blob/master/protobuf/api/runner.proto). +service Runner { + + // Get returns an Runner matching the criteria of the request. + rpc Get(GetRunnerRequest) returns (types.Runner) {} + + // List returns all Runners matching the criteria of the request. + rpc List(ListRunnerRequest) returns (ListRunnerResponse) {} + + // Create an Runner from a Service's hash and custom environmental variables. + // It will return an unique identifier to identify the runner. + rpc Create(CreateRunnerRequest) returns (CreateRunnerResponse) {} + + // Delete an Runner. + rpc Delete(DeleteRunnerRequest) returns (DeleteRunnerResponse) {} +} + +// The request's data for the `Get` API. +message GetRunnerRequest { + bytes hash = 1 [ + (gogoproto.customtype) = "github.com/mesg-foundation/engine/hash.Hash", + (gogoproto.nullable) = false + ]; +} + +// The request's data for the `List` API. +message ListRunnerRequest { + // Filter contains filtering criteria. + message Filter { + // Filter by instance hash. + bytes instanceHash = 1 [ + (gogoproto.customtype) = "github.com/mesg-foundation/engine/hash.Hash", + (gogoproto.nullable) = false + ]; + + // Filter by address + string address = 2; + } + + // Filter used to filter runners. + Filter filter = 1; +} + +// The response's data for the `List` API. +message ListRunnerResponse { + // List of runners that match the request's filters. + repeated types.Runner runners = 1; +} + +// The request's data for the `Create` API. +message CreateRunnerRequest { + // Service's hash to start the runner with. + bytes serviceHash = 1 [ + (gogoproto.customtype) = "github.com/mesg-foundation/engine/hash.Hash", + (gogoproto.nullable) = false + ]; + + // Environmental variables to start the runner with. + repeated string env = 2; +} + +// The response's data for the `Create` API. +message CreateRunnerResponse { + // The runner's hash created. + bytes hash = 1 [ + (gogoproto.customtype) = "github.com/mesg-foundation/engine/hash.Hash", + (gogoproto.nullable) = false + ]; +} + +// The request's data for the `Delete` API. +message DeleteRunnerRequest { + // Runner's hash + bytes hash = 1 [ + (gogoproto.customtype) = "github.com/mesg-foundation/engine/hash.Hash", + (gogoproto.nullable) = false + ]; + + // If true, any persistent data (volumes) that belongs to the runner's container and its dependencies will also be deleted. + bool deleteData = 2; +} + +// The response's data for the `Delete` API. +message DeleteRunnerResponse {} + diff --git a/protobuf/types/instance.proto b/protobuf/types/instance.proto index aadbc3bc3..433fe7e90 100644 --- a/protobuf/types/instance.proto +++ b/protobuf/types/instance.proto @@ -6,6 +6,7 @@ package mesg.types; option go_package = "github.com/mesg-foundation/engine/instance"; option (gogoproto.goproto_getters_all) = false; +option (gogoproto.equal_all) = true; // Instance represents service's instance. message Instance { diff --git a/protobuf/types/runner.proto b/protobuf/types/runner.proto new file mode 100644 index 000000000..a97561e3a --- /dev/null +++ b/protobuf/types/runner.proto @@ -0,0 +1,31 @@ +syntax = "proto3"; + +import "gogo/protobuf/gogoproto/gogo.proto"; + +package mesg.types; +option go_package = "github.com/mesg-foundation/engine/runner"; + +option (gogoproto.goproto_getters_all) = false; +option (gogoproto.equal_all) = true; + +// Runner represents one node service's instance. +message Runner { + // Runner's hash + bytes hash = 1 [ + (gogoproto.moretags) = 'hash:"-"', + (gogoproto.customtype) = "github.com/mesg-foundation/engine/hash.Hash", + (gogoproto.nullable) = false + ]; + + // address of the engine of this runner + string address = 2 [ + (gogoproto.moretags) = 'hash:"name:2"' + ]; + + // instanceHash is hash of the instance that runner will handle + bytes instanceHash = 3 [ + (gogoproto.moretags) = 'hash:"name:3"', + (gogoproto.customtype) = "github.com/mesg-foundation/engine/hash.Hash", + (gogoproto.nullable) = false + ]; +} diff --git a/runner/runner.pb.go b/runner/runner.pb.go new file mode 100644 index 000000000..a81085103 --- /dev/null +++ b/runner/runner.pb.go @@ -0,0 +1,121 @@ +// Code generated by protoc-gen-gogo. DO NOT EDIT. +// source: runner.proto + +package runner + +import ( + bytes "bytes" + fmt "fmt" + _ "github.com/gogo/protobuf/gogoproto" + proto "github.com/gogo/protobuf/proto" + github_com_mesg_foundation_engine_hash "github.com/mesg-foundation/engine/hash" + math "math" +) + +// Reference imports to suppress errors if they are not otherwise used. +var _ = proto.Marshal +var _ = fmt.Errorf +var _ = math.Inf + +// This is a compile-time assertion to ensure that this generated file +// is compatible with the proto package it is being compiled against. +// A compilation error at this line likely means your copy of the +// proto package needs to be updated. +const _ = proto.GoGoProtoPackageIsVersion3 // please upgrade the proto package + +// Runner represents one node service's instance. +type Runner struct { + // Runner's hash + Hash github_com_mesg_foundation_engine_hash.Hash `protobuf:"bytes,1,opt,name=hash,proto3,customtype=github.com/mesg-foundation/engine/hash.Hash" json:"hash" hash:"-"` + // address of the engine of this runner + Address string `protobuf:"bytes,2,opt,name=address,proto3" json:"address,omitempty" hash:"name:2"` + // instanceHash is hash of the instance that runner will handle + InstanceHash github_com_mesg_foundation_engine_hash.Hash `protobuf:"bytes,3,opt,name=instanceHash,proto3,customtype=github.com/mesg-foundation/engine/hash.Hash" json:"instanceHash" hash:"name:3"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *Runner) Reset() { *m = Runner{} } +func (m *Runner) String() string { return proto.CompactTextString(m) } +func (*Runner) ProtoMessage() {} +func (*Runner) Descriptor() ([]byte, []int) { + return fileDescriptor_48eceea7e2abc593, []int{0} +} +func (m *Runner) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_Runner.Unmarshal(m, b) +} +func (m *Runner) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_Runner.Marshal(b, m, deterministic) +} +func (m *Runner) XXX_Merge(src proto.Message) { + xxx_messageInfo_Runner.Merge(m, src) +} +func (m *Runner) XXX_Size() int { + return xxx_messageInfo_Runner.Size(m) +} +func (m *Runner) XXX_DiscardUnknown() { + xxx_messageInfo_Runner.DiscardUnknown(m) +} + +var xxx_messageInfo_Runner proto.InternalMessageInfo + +func init() { + proto.RegisterType((*Runner)(nil), "mesg.types.Runner") +} + +func init() { proto.RegisterFile("runner.proto", fileDescriptor_48eceea7e2abc593) } + +var fileDescriptor_48eceea7e2abc593 = []byte{ + // 243 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0xe2, 0x29, 0x2a, 0xcd, 0xcb, + 0x4b, 0x2d, 0xd2, 0x2b, 0x28, 0xca, 0x2f, 0xc9, 0x17, 0xe2, 0xca, 0x4d, 0x2d, 0x4e, 0xd7, 0x2b, + 0xa9, 0x2c, 0x48, 0x2d, 0x96, 0x52, 0x4a, 0xcf, 0x4f, 0xcf, 0xd7, 0x07, 0x8b, 0x27, 0x95, 0xa6, + 0xe9, 0x83, 0x78, 0x60, 0x0e, 0x98, 0x05, 0x51, 0xaf, 0xf4, 0x85, 0x91, 0x8b, 0x2d, 0x08, 0x6c, + 0x80, 0x50, 0x30, 0x17, 0x4b, 0x46, 0x62, 0x71, 0x86, 0x04, 0xa3, 0x02, 0xa3, 0x06, 0x8f, 0x93, + 0xfd, 0x89, 0x7b, 0xf2, 0x0c, 0xb7, 0xee, 0xc9, 0x6b, 0xa7, 0x67, 0x96, 0x64, 0x94, 0x26, 0xe9, + 0x25, 0xe7, 0xe7, 0xea, 0x83, 0xcc, 0xd6, 0x4d, 0xcb, 0x2f, 0xcd, 0x4b, 0x49, 0x2c, 0xc9, 0xcc, + 0xcf, 0xd3, 0x4f, 0xcd, 0x4b, 0xcf, 0xcc, 0x4b, 0xd5, 0x07, 0xe9, 0xd2, 0xf3, 0x48, 0x2c, 0xce, + 0xf8, 0x74, 0x4f, 0x9e, 0x03, 0xc4, 0xb1, 0x52, 0xd2, 0x55, 0x0a, 0x02, 0x1b, 0x26, 0xa4, 0xcd, + 0xc5, 0x9e, 0x98, 0x92, 0x52, 0x94, 0x5a, 0x5c, 0x2c, 0xc1, 0xa4, 0xc0, 0xa8, 0xc1, 0xe9, 0x24, + 0xf8, 0xe9, 0x9e, 0x3c, 0x2f, 0x44, 0x51, 0x5e, 0x62, 0x6e, 0xaa, 0x95, 0x91, 0x52, 0x10, 0x4c, + 0x85, 0x50, 0x06, 0x17, 0x4f, 0x66, 0x5e, 0x71, 0x49, 0x62, 0x5e, 0x72, 0x2a, 0xc8, 0x38, 0x09, + 0x66, 0xb0, 0x4b, 0x5c, 0xc8, 0x73, 0x09, 0xb2, 0x25, 0xc6, 0x4a, 0x41, 0x28, 0x26, 0x3b, 0x19, + 0x9d, 0x78, 0x28, 0xc7, 0xb0, 0xe2, 0x91, 0x1c, 0x63, 0x94, 0x06, 0x61, 0x53, 0x21, 0x01, 0x9c, + 0xc4, 0x06, 0x0e, 0x31, 0x63, 0x40, 0x00, 0x00, 0x00, 0xff, 0xff, 0xe0, 0x39, 0x31, 0x5a, 0x71, + 0x01, 0x00, 0x00, +} + +func (this *Runner) Equal(that interface{}) bool { + if that == nil { + return this == nil + } + + that1, ok := that.(*Runner) + if !ok { + that2, ok := that.(Runner) + if ok { + that1 = &that2 + } else { + return false + } + } + if that1 == nil { + return this == nil + } else if this == nil { + return false + } + if !this.Hash.Equal(that1.Hash) { + return false + } + if this.Address != that1.Address { + return false + } + if !this.InstanceHash.Equal(that1.InstanceHash) { + return false + } + if !bytes.Equal(this.XXX_unrecognized, that1.XXX_unrecognized) { + return false + } + return true +} diff --git a/scripts/build-proto.sh b/scripts/build-proto.sh index d20c7142a..375eccc51 100755 --- a/scripts/build-proto.sh +++ b/scripts/build-proto.sh @@ -4,7 +4,7 @@ TYPES_PATH=protobuf/types APIS_PATH=protobuf/api # generate type -for file in "${TYPES_PATH}"/{account,event,execution,instance,service,process,ownership}.proto +for file in "${TYPES_PATH}"/{account,event,execution,instance,service,process,ownership,runner}.proto do file=$(basename ${file}) dir="${file%.*}" @@ -16,7 +16,7 @@ done protoc --gogo_out=paths=source_relative:. protobuf/types/struct.proto # generate services -for file in "${APIS_PATH}"/{account,event,execution,instance,service,process,ownership}.proto +for file in "${APIS_PATH}"/{account,event,execution,instance,service,process,ownership,runner}.proto do protoc --gogo_out=plugins=grpc:. --proto_path . "${file}" done diff --git a/sdk/backend.go b/sdk/backend.go index 58a4082db..b00535f54 100644 --- a/sdk/backend.go +++ b/sdk/backend.go @@ -12,13 +12,18 @@ import ( "github.com/cosmos/cosmos-sdk/x/staking" "github.com/cosmos/cosmos-sdk/x/supply" "github.com/mesg-foundation/engine/cosmos" + instancesdk "github.com/mesg-foundation/engine/sdk/instance" ownershipsdk "github.com/mesg-foundation/engine/sdk/ownership" + runnersdk "github.com/mesg-foundation/engine/sdk/runner" servicesdk "github.com/mesg-foundation/engine/sdk/service" ) // Backend handles all the backend functions. type Backend struct { - Service *servicesdk.Backend + Service *servicesdk.Backend + Ownership *ownershipsdk.Backend + Instance *instancesdk.Backend + Runner *runnersdk.Backend } // NewBackend creates a new backend and init the sub-backend modules. @@ -26,8 +31,13 @@ func NewBackend(appFactory *cosmos.AppFactory) *Backend { initDefaultCosmosModules(appFactory) ownership := ownershipsdk.NewBackend(appFactory) service := servicesdk.NewBackend(appFactory, ownership) + instance := instancesdk.NewBackend(appFactory) + runner := runnersdk.NewBackend(appFactory, instance) return &Backend{ - Service: service, + Service: service, + Ownership: ownership, + Instance: instance, + Runner: runner, } } diff --git a/sdk/event/event.go b/sdk/event/event.go index 8dd489b73..87319697a 100644 --- a/sdk/event/event.go +++ b/sdk/event/event.go @@ -17,12 +17,12 @@ const ( // Event exposes event APIs of MESG. type Event struct { ps *pubsub.PubSub - instance *instancesdk.Instance + instance *instancesdk.SDK service *servicesdk.SDK } // New creates a new Event SDK with given options. -func New(ps *pubsub.PubSub, service *servicesdk.SDK, instance *instancesdk.Instance) *Event { +func New(ps *pubsub.PubSub, service *servicesdk.SDK, instance *instancesdk.SDK) *Event { return &Event{ ps: ps, service: service, diff --git a/sdk/execution/execution.go b/sdk/execution/execution.go index 82e63c712..06d9920e0 100644 --- a/sdk/execution/execution.go +++ b/sdk/execution/execution.go @@ -23,13 +23,13 @@ const ( type Execution struct { ps *pubsub.PubSub service *servicesdk.SDK - instance *instancesdk.Instance + instance *instancesdk.SDK process *processesdk.Process execDB database.ExecutionDB } // New creates a new Execution SDK with given options. -func New(ps *pubsub.PubSub, service *servicesdk.SDK, instance *instancesdk.Instance, process *processesdk.Process, execDB database.ExecutionDB) *Execution { +func New(ps *pubsub.PubSub, service *servicesdk.SDK, instance *instancesdk.SDK, process *processesdk.Process, execDB database.ExecutionDB) *Execution { return &Execution{ ps: ps, service: service, diff --git a/sdk/execution/execution_test.go b/sdk/execution/execution_test.go index 2ab06175f..3d20354fd 100644 --- a/sdk/execution/execution_test.go +++ b/sdk/execution/execution_test.go @@ -12,7 +12,6 @@ import ( "github.com/mesg-foundation/engine/hash" instancesdk "github.com/mesg-foundation/engine/sdk/instance" processesdk "github.com/mesg-foundation/engine/sdk/process" - "github.com/mesg-foundation/engine/service" "github.com/stretchr/testify/require" ) @@ -27,7 +26,7 @@ type apiTesting struct { *testing.T serviceDB *database.ServiceDB executionDB *database.LevelDBExecutionDB - instanceDB *database.LevelDBInstanceDB + instanceDB *database.InstanceDB processDB *database.LevelDBProcessDB } @@ -47,9 +46,10 @@ func newTesting(t *testing.T) (*Execution, *apiTesting) { require.NoError(t, err) db := database.NewServiceDB(serviceStore, codec.New()) - instDB, err := database.NewInstanceDB(instdbname) + instanceStore, err := store.NewLevelDBStore(instdbname) require.NoError(t, err) - instance := instancesdk.New(nil, nil, instDB, "", "", "") + instDB := database.NewInstanceDB(instanceStore, codec.New()) + instance := instancesdk.New(nil) execDB, err := database.NewExecutionDB(execdbname) require.NoError(t, err) @@ -69,19 +69,19 @@ func newTesting(t *testing.T) (*Execution, *apiTesting) { } } -var hs1 = hash.Int(1) - -var testService = &service.Service{ - Name: "1", - Sid: "2", - Hash: hs1, - Tasks: []*service.Service_Task{ - {Key: "4"}, - }, - Dependencies: []*service.Service_Dependency{ - {Key: "5"}, - }, -} +// var hs1 = hash.Int(1) + +// var testService = &service.Service{ +// Name: "1", +// Sid: "2", +// Hash: hs1, +// Tasks: []*service.Service_Task{ +// {Key: "4"}, +// }, +// Dependencies: []*service.Service_Dependency{ +// {Key: "5"}, +// }, +// } func TestGet(t *testing.T) { sdk, at := newTesting(t) @@ -132,15 +132,15 @@ func TestGetStream(t *testing.T) { // require.Error(t, err) // } -func TestExecuteInvalidTaskKey(t *testing.T) { - sdk, at := newTesting(t) - defer at.close() +// func TestExecuteInvalidTaskKey(t *testing.T) { +// sdk, at := newTesting(t) +// defer at.close() - require.NoError(t, at.serviceDB.Save(testService)) +// require.NoError(t, at.serviceDB.Save(testService)) - _, err := sdk.Execute(nil, hs1, hash.Int(1), nil, "", "-", nil, nil) - require.Error(t, err) -} +// _, err := sdk.Execute(nil, hs1, hash.Int(1), nil, "", "-", nil, nil) +// require.Error(t, err) +// } func TestSubTopic(t *testing.T) { require.Equal(t, subTopic(hash.Hash{0}), "1.Execution") diff --git a/sdk/instance/backend.go b/sdk/instance/backend.go new file mode 100644 index 000000000..bccedc331 --- /dev/null +++ b/sdk/instance/backend.go @@ -0,0 +1,106 @@ +package instancesdk + +import ( + "errors" + "fmt" + + "github.com/cosmos/cosmos-sdk/codec" + cosmostypes "github.com/cosmos/cosmos-sdk/types" + "github.com/mesg-foundation/engine/cosmos" + "github.com/mesg-foundation/engine/database" + "github.com/mesg-foundation/engine/database/store" + "github.com/mesg-foundation/engine/hash" + "github.com/mesg-foundation/engine/instance" + abci "github.com/tendermint/tendermint/abci/types" +) + +const backendName = "instance" + +// Backend is the instance backend. +type Backend struct { + cdc *codec.Codec + storeKey *cosmostypes.KVStoreKey +} + +// NewBackend returns the backend of the instance sdk. +func NewBackend(appFactory *cosmos.AppFactory) *Backend { + backend := &Backend{ + cdc: appFactory.Cdc(), + storeKey: cosmostypes.NewKVStoreKey(backendName), + } + appBackendBasic := cosmos.NewAppModuleBasic(backendName) + appBackend := cosmos.NewAppModule(appBackendBasic, backend.cdc, backend.handler, backend.querier) + appFactory.RegisterModule(appBackend) + appFactory.RegisterStoreKey(backend.storeKey) + + return backend +} + +func (s *Backend) db(request cosmostypes.Request) *database.InstanceDB { + return database.NewInstanceDB(store.NewCosmosStore(request.KVStore(s.storeKey)), s.cdc) +} + +func (s *Backend) handler(request cosmostypes.Request, msg cosmostypes.Msg) cosmostypes.Result { + errmsg := fmt.Sprintf("Unrecognized instance Msg type: %v", msg.Type()) + return cosmostypes.ErrUnknownRequest(errmsg).Result() +} + +func (s *Backend) querier(request cosmostypes.Request, path []string, req abci.RequestQuery) (interface{}, error) { + switch path[0] { + case "get": + hash, err := hash.Decode(path[1]) + if err != nil { + return nil, err + } + return s.Get(request, hash) + case "list": + return s.List(request) + case "exists": + hash, err := hash.Decode(path[1]) + if err != nil { + return nil, err + } + return s.Exists(request, hash) + + default: + return nil, errors.New("unknown instance query endpoint" + path[0]) + } +} + +// FetchOrCreate creates a new instance if needed. +func (s *Backend) FetchOrCreate(request cosmostypes.Request, serviceHash hash.Hash, envHash hash.Hash) (*instance.Instance, error) { + db := s.db(request) + + // create instance hash + inst := &instance.Instance{ + ServiceHash: serviceHash, + EnvHash: envHash, + } + inst.Hash = hash.Dump(inst) + + // create instance if needed + if exists, err := db.Exist(inst.Hash); err != nil { + return nil, err + } else if !exists { + if err := db.Save(inst); err != nil { + return nil, err + } + } + + return inst, nil +} + +// Get returns the instance that matches given hash. +func (s *Backend) Get(request cosmostypes.Request, hash hash.Hash) (*instance.Instance, error) { + return s.db(request).Get(hash) +} + +// Exists returns true if a specific set of data exists in the database, false otherwise +func (s *Backend) Exists(request cosmostypes.Request, hash hash.Hash) (bool, error) { + return s.db(request).Exist(hash) +} + +// List returns all instances. +func (s *Backend) List(request cosmostypes.Request) ([]*instance.Instance, error) { + return s.db(request).All() +} diff --git a/sdk/instance/instance.go b/sdk/instance/instance.go deleted file mode 100644 index f58f84616..000000000 --- a/sdk/instance/instance.go +++ /dev/null @@ -1,142 +0,0 @@ -package instancesdk - -import ( - "fmt" - - "github.com/mesg-foundation/engine/container" - "github.com/mesg-foundation/engine/database" - "github.com/mesg-foundation/engine/hash" - "github.com/mesg-foundation/engine/instance" - servicesdk "github.com/mesg-foundation/engine/sdk/service" - "github.com/mesg-foundation/engine/x/xos" -) - -// Instance exposes service instance APIs of MESG. -type Instance struct { - container container.Container - service *servicesdk.SDK - instanceDB database.InstanceDB - - port string - engineName string - ipfsEndpoint string -} - -// New creates a new Instance SDK with given options. -func New(c container.Container, service *servicesdk.SDK, instanceDB database.InstanceDB, engineName, port, ipfsEndpoint string) *Instance { - return &Instance{ - container: c, - service: service, - instanceDB: instanceDB, - port: port, - engineName: engineName, - ipfsEndpoint: ipfsEndpoint, - } -} - -// Get retrieves instance by hash. -func (i *Instance) Get(hash hash.Hash) (*instance.Instance, error) { - return i.instanceDB.Get(hash) -} - -// Filter to apply while listing instances. -type Filter struct { - ServiceHash hash.Hash - InstanceHash hash.Hash -} - -// List instances by f filter. -func (i *Instance) List(f *Filter) ([]*instance.Instance, error) { - instances, err := i.instanceDB.GetAll() - if err != nil { - return nil, err - } - if f == nil { - return instances, nil - } - - ret := make([]*instance.Instance, 0) - for _, instance := range instances { - if (f.ServiceHash.IsZero() || instance.ServiceHash.Equal(f.ServiceHash)) && - (f.InstanceHash.IsZero() || instance.Hash.Equal(f.InstanceHash)) { - ret = append(ret, instance) - } - } - return ret, nil -} - -// Create creates a new service instance for service with id(sid/hash) and applies given env vars. -func (i *Instance) Create(serviceHash hash.Hash, env []string) (*instance.Instance, error) { - // get the service from service db. - srv, err := i.service.Get(serviceHash) - if err != nil { - return nil, err - } - - // build service's Docker image and apply to service. - imageHash, err := build(i.container, srv, i.ipfsEndpoint) - if err != nil { - return nil, err - } - - // calculate the final env vars by overwriting user defined one's with defaults. - instanceEnv := xos.EnvMergeSlices(srv.Configuration.Env, env) - - // calculate instance's hash. - inst := &instance.Instance{ - ServiceHash: srv.Hash, - EnvHash: hash.Dump(instanceEnv), - } - inst.Hash = hash.Dump(inst) - - // check if instance already exists - if exist, err := i.instanceDB.Exist(inst.Hash); err != nil { - return nil, err - } else if exist { - return nil, &AlreadyExistsError{Hash: inst.Hash} - } - - // save & start instance. - if err := i.instanceDB.Save(inst); err != nil { - return nil, err - } - - _, err = start(i.container, srv, inst.Hash, imageHash, instanceEnv, i.engineName, i.port) - return inst, err -} - -// Delete deletes an instance. -// if shouldDeleteData is true, any persistent data that belongs to -// the instance and to its dependencies will also be deleted. -func (i *Instance) Delete(hash hash.Hash, shouldDeleteData bool) error { - inst, err := i.instanceDB.Get(hash) - if err != nil { - return err - } - // get the service from service db. - srv, err := i.service.Get(inst.ServiceHash) - if err != nil { - return err - } - if err := stop(i.container, hash, srv.Dependencies); err != nil { - return err - } - // delete volumes first before the instance. this way if - // deleting volumes fails, process can be retried by the user again - // because instance still will be in the db. - if shouldDeleteData { - if err := deleteData(i.container, srv); err != nil { - return err - } - } - return i.instanceDB.Delete(hash) -} - -// AlreadyExistsError is an not found error. -type AlreadyExistsError struct { - Hash hash.Hash -} - -func (e *AlreadyExistsError) Error() string { - return fmt.Sprintf("instance %q already exists", e.Hash.String()) -} diff --git a/sdk/instance/sdk.go b/sdk/instance/sdk.go new file mode 100644 index 000000000..356caaa6e --- /dev/null +++ b/sdk/instance/sdk.go @@ -0,0 +1,67 @@ +package instancesdk + +import ( + "github.com/mesg-foundation/engine/cosmos" + "github.com/mesg-foundation/engine/hash" + "github.com/mesg-foundation/engine/instance" +) + +// SDK is the instance sdk. +type SDK struct { + client *cosmos.Client +} + +// Filter to apply while listing instances. +type Filter struct { + ServiceHash hash.Hash + InstanceHash hash.Hash +} + +// New returns the instance sdk. +func New(client *cosmos.Client) *SDK { + sdk := &SDK{ + client: client, + } + return sdk +} + +// Get returns the instance that matches given hash. +func (s *SDK) Get(hash hash.Hash) (*instance.Instance, error) { + var instance instance.Instance + if err := s.client.Query("custom/"+backendName+"/get/"+hash.String(), nil, &instance); err != nil { + return nil, err + } + return &instance, nil +} + +// List returns all instances. +func (s *SDK) List(f *Filter) ([]*instance.Instance, error) { + var instances []*instance.Instance + if err := s.client.Query("custom/"+backendName+"/list", nil, &instances); err != nil { + return nil, err + } + + // no filter, returns + if f == nil { + return instances, nil + } + + // filter results + ret := make([]*instance.Instance, 0) + for _, instance := range instances { + if (f.ServiceHash.IsZero() || instance.ServiceHash.Equal(f.ServiceHash)) && + (f.InstanceHash.IsZero() || instance.Hash.Equal(f.InstanceHash)) { + ret = append(ret, instance) + } + } + return ret, nil +} + +// Exists returns if a instance already exists. +func (s *SDK) Exists(hash hash.Hash) (bool, error) { + var exists bool + if err := s.client.Query("custom/"+backendName+"/exists/"+hash.String(), nil, &exists); err != nil { + return false, err + } + return exists, nil +} diff --git a/sdk/ownership/backend.go b/sdk/ownership/backend.go index a9df562d5..0964c0112 100644 --- a/sdk/ownership/backend.go +++ b/sdk/ownership/backend.go @@ -54,7 +54,7 @@ func (s *Backend) querier(request cosmostypes.Request, path []string, req abci.R } } -// CreateServiceOwnership creates a new ownership from definition. +// CreateServiceOwnership creates a new ownership. func (s *Backend) CreateServiceOwnership(request cosmostypes.Request, serviceHash hash.Hash, owner cosmostypes.AccAddress) (*ownership.Ownership, error) { db := s.db(request) // check if owner is authorized to create the ownership diff --git a/sdk/process/process.go b/sdk/process/process.go index 9c2b5ad89..cf37d7796 100644 --- a/sdk/process/process.go +++ b/sdk/process/process.go @@ -12,18 +12,18 @@ import ( // Process exposes process APIs of MESG. type Process struct { processDB database.ProcessDB - instance *instancesdk.Instance + instance *instancesdk.SDK } // New creates a new Process SDK with given options. -func New(instance *instancesdk.Instance, processDB database.ProcessDB) *Process { +func New(instance *instancesdk.SDK, processDB database.ProcessDB) *Process { return &Process{ processDB: processDB, instance: instance, } } -// Create creates a new service from definition. +// Create creates a new process. func (w *Process) Create(wf *process.Process) (*process.Process, error) { wf.Hash = hash.Dump(wf) diff --git a/sdk/runner/backend.go b/sdk/runner/backend.go new file mode 100644 index 000000000..e986fe6ac --- /dev/null +++ b/sdk/runner/backend.go @@ -0,0 +1,148 @@ +package runnersdk + +import ( + "errors" + "fmt" + + "github.com/cosmos/cosmos-sdk/codec" + cosmostypes "github.com/cosmos/cosmos-sdk/types" + "github.com/mesg-foundation/engine/cosmos" + "github.com/mesg-foundation/engine/database" + "github.com/mesg-foundation/engine/database/store" + "github.com/mesg-foundation/engine/hash" + "github.com/mesg-foundation/engine/runner" + instancesdk "github.com/mesg-foundation/engine/sdk/instance" + abci "github.com/tendermint/tendermint/abci/types" +) + +const backendName = "runner" + +// Backend is the runner backend. +type Backend struct { + cdc *codec.Codec + storeKey *cosmostypes.KVStoreKey + instanceBack *instancesdk.Backend +} + +// NewBackend returns the backend of the runner sdk. +func NewBackend(appFactory *cosmos.AppFactory, instanceBack *instancesdk.Backend) *Backend { + backend := &Backend{ + cdc: appFactory.Cdc(), + storeKey: cosmostypes.NewKVStoreKey(backendName), + instanceBack: instanceBack, + } + appBackendBasic := cosmos.NewAppModuleBasic(backendName) + appBackend := cosmos.NewAppModule(appBackendBasic, backend.cdc, backend.handler, backend.querier) + appFactory.RegisterModule(appBackend) + appFactory.RegisterStoreKey(backend.storeKey) + + backend.cdc.RegisterConcrete(msgCreateRunner{}, "runner/create", nil) + backend.cdc.RegisterConcrete(msgDeleteRunner{}, "runner/delete", nil) + + return backend +} + +func (s *Backend) db(request cosmostypes.Request) *database.RunnerDB { + return database.NewRunnerDB(store.NewCosmosStore(request.KVStore(s.storeKey)), s.cdc) +} + +func (s *Backend) handler(request cosmostypes.Request, msg cosmostypes.Msg) cosmostypes.Result { + switch msg := msg.(type) { + case msgCreateRunner: + run, err := s.Create(request, &msg) + if err != nil { + return cosmostypes.ErrInternal(err.Error()).Result() + } + return cosmostypes.Result{ + Data: run.Hash, + } + case msgDeleteRunner: + if err := s.Delete(request, &msg); err != nil { + return cosmostypes.ErrInternal(err.Error()).Result() + } + return cosmostypes.Result{} + default: + errmsg := fmt.Sprintf("Unrecognized runner Msg type: %v", msg.Type()) + return cosmostypes.ErrUnknownRequest(errmsg).Result() + } +} + +func (s *Backend) querier(request cosmostypes.Request, path []string, req abci.RequestQuery) (interface{}, error) { + switch path[0] { + case "get": + hash, err := hash.Decode(path[1]) + if err != nil { + return nil, err + } + return s.Get(request, hash) + case "list": + return s.List(request) + case "exists": + hash, err := hash.Decode(path[1]) + if err != nil { + return nil, err + } + return s.Exists(request, hash) + default: + return nil, errors.New("unknown runner query endpoint" + path[0]) + } +} + +// Create creates a new runner. +func (s *Backend) Create(request cosmostypes.Request, msg *msgCreateRunner) (*runner.Runner, error) { + db := s.db(request) + + // get instance and create it if needed + inst, err := s.instanceBack.FetchOrCreate(request, msg.ServiceHash, msg.EnvHash) + if err != nil { + return nil, err + } + + // create runner + run := &runner.Runner{ + Address: msg.Address.String(), + InstanceHash: inst.Hash, + } + run.Hash = hash.Dump(run) + + // check if runner already exists. + if exist, err := db.Exist(run.Hash); err != nil { + return nil, err + } else if exist { + return nil, errors.New("runner %q already exists" + run.Hash.String()) + } + + // save runner + if err := db.Save(run); err != nil { + return nil, err + } + return run, nil +} + +// Delete deletes a runner. +func (s *Backend) Delete(request cosmostypes.Request, msg *msgDeleteRunner) error { + db := s.db(request) + runner, err := db.Get(msg.RunnerHash) + if err != nil { + return err + } + if runner.Address != msg.Address.String() { + return errors.New("only the runner owner can remove itself") + } + return db.Delete(msg.RunnerHash) +} + +// Get returns the runner that matches given hash. +func (s *Backend) Get(request cosmostypes.Request, hash hash.Hash) (*runner.Runner, error) { + return s.db(request).Get(hash) +} + +// Exists returns true if a specific set of data exists in the database, false otherwise +func (s *Backend) Exists(request cosmostypes.Request, hash hash.Hash) (bool, error) { + return s.db(request).Exist(hash) +} + +// List returns all runners. +func (s *Backend) List(request cosmostypes.Request) ([]*runner.Runner, error) { + return s.db(request).All() +} diff --git a/sdk/instance/container.go b/sdk/runner/container.go similarity index 99% rename from sdk/instance/container.go rename to sdk/runner/container.go index b74165659..ff1f01d61 100644 --- a/sdk/instance/container.go +++ b/sdk/runner/container.go @@ -1,4 +1,4 @@ -package instancesdk +package runnersdk import ( "errors" diff --git a/sdk/runner/msgs.go b/sdk/runner/msgs.go new file mode 100644 index 000000000..f2576d472 --- /dev/null +++ b/sdk/runner/msgs.go @@ -0,0 +1,106 @@ +package runnersdk + +import ( + "github.com/cosmos/cosmos-sdk/codec" + cosmostypes "github.com/cosmos/cosmos-sdk/types" + "github.com/mesg-foundation/engine/hash" +) + +// msgCreateRunner defines a state transition to create a runner. +type msgCreateRunner struct { + Address cosmostypes.AccAddress `json:"address"` + ServiceHash hash.Hash `json:"serviceHash"` + EnvHash hash.Hash `json:"envHash"` + cdc *codec.Codec +} + +// newMsgCreateRunner is a constructor function for msgCreateRunner. +func newMsgCreateRunner(cdc *codec.Codec, address cosmostypes.AccAddress, serviceHash hash.Hash, envHash hash.Hash) *msgCreateRunner { + return &msgCreateRunner{ + Address: address, + ServiceHash: serviceHash, + EnvHash: envHash, + cdc: cdc, + } +} + +// Route should return the name of the module. +func (msg msgCreateRunner) Route() string { + return backendName +} + +// Type returns the action. +func (msg msgCreateRunner) Type() string { + return "create_runner" +} + +// ValidateBasic runs stateless checks on the message. +func (msg msgCreateRunner) ValidateBasic() cosmostypes.Error { + if msg.ServiceHash.IsZero() { + return cosmostypes.ErrInternal("serviceHash is missing") + } + if msg.EnvHash.IsZero() { + return cosmostypes.ErrInternal("envHash is missing") + } + if msg.Address.Empty() { + return cosmostypes.ErrInvalidAddress("address is missing") + } + return nil +} + +// GetSignBytes encodes the message for signing. +func (msg msgCreateRunner) GetSignBytes() []byte { + return cosmostypes.MustSortJSON(msg.cdc.MustMarshalJSON(msg)) +} + +// GetSigners defines whose signature is required. +func (msg msgCreateRunner) GetSigners() []cosmostypes.AccAddress { + return []cosmostypes.AccAddress{msg.Address} +} + +// msgDeleteRunner defines a state transition to delete a runner. +type msgDeleteRunner struct { + Address cosmostypes.AccAddress `json:"address"` + RunnerHash hash.Hash `json:"runnerHash"` + cdc *codec.Codec +} + +// newMsgDeleteRunner is a constructor function for msgDeleteRunner. +func newMsgDeleteRunner(cdc *codec.Codec, address cosmostypes.AccAddress, runnerHash hash.Hash) *msgDeleteRunner { + return &msgDeleteRunner{ + Address: address, + RunnerHash: runnerHash, + cdc: cdc, + } +} + +// Route should return the name of the module. +func (msg msgDeleteRunner) Route() string { + return backendName +} + +// Type returns the action. +func (msg msgDeleteRunner) Type() string { + return "delete_runner" +} + +// ValidateBasic runs stateless checks on the message. +func (msg msgDeleteRunner) ValidateBasic() cosmostypes.Error { + if msg.RunnerHash.IsZero() { + return cosmostypes.ErrInternal("runnerHash is missing") + } + if msg.Address.Empty() { + return cosmostypes.ErrInvalidAddress("address is missing") + } + return nil +} + +// GetSignBytes encodes the message for signing. +func (msg msgDeleteRunner) GetSignBytes() []byte { + return cosmostypes.MustSortJSON(msg.cdc.MustMarshalJSON(msg)) +} + +// GetSigners defines whose signature is required. +func (msg msgDeleteRunner) GetSigners() []cosmostypes.AccAddress { + return []cosmostypes.AccAddress{msg.Address} +} diff --git a/sdk/runner/sdk.go b/sdk/runner/sdk.go new file mode 100644 index 000000000..c1a702146 --- /dev/null +++ b/sdk/runner/sdk.go @@ -0,0 +1,198 @@ +package runnersdk + +import ( + "fmt" + + "github.com/cosmos/cosmos-sdk/codec" + cosmostypes "github.com/cosmos/cosmos-sdk/types" + "github.com/mesg-foundation/engine/container" + "github.com/mesg-foundation/engine/cosmos" + "github.com/mesg-foundation/engine/hash" + "github.com/mesg-foundation/engine/instance" + "github.com/mesg-foundation/engine/protobuf/api" + "github.com/mesg-foundation/engine/runner" + accountsdk "github.com/mesg-foundation/engine/sdk/account" + instancesdk "github.com/mesg-foundation/engine/sdk/instance" + servicesdk "github.com/mesg-foundation/engine/sdk/service" + "github.com/mesg-foundation/engine/x/xos" + "github.com/tendermint/tendermint/mempool" +) + +// SDK is the runner sdk. +type SDK struct { + cdc *codec.Codec + accountSDK *accountsdk.SDK + serviceSDK *servicesdk.SDK + instanceSDK *instancesdk.SDK + client *cosmos.Client + container container.Container + port string + engineName string + ipfsEndpoint string +} + +// Filter to apply while listing runners. +type Filter struct { + Address string + InstanceHash hash.Hash +} + +// New returns the runner sdk. +func New(cdc *codec.Codec, client *cosmos.Client, accountSDK *accountsdk.SDK, serviceSDK *servicesdk.SDK, instanceSDK *instancesdk.SDK, container container.Container, engineName, port, ipfsEndpoint string) *SDK { + sdk := &SDK{ + cdc: cdc, + container: container, + accountSDK: accountSDK, + serviceSDK: serviceSDK, + instanceSDK: instanceSDK, + client: client, + port: port, + engineName: engineName, + ipfsEndpoint: ipfsEndpoint, + } + return sdk +} + +// Create creates a new runner. +func (s *SDK) Create(req *api.CreateRunnerRequest, accountName, accountPassword string) (*runner.Runner, error) { + account, err := s.accountSDK.Get(accountName) + if err != nil { + return nil, err + } + // TODO: pass account by parameters + accNumber, accSeq := uint64(0), uint64(0) + user, err := cosmostypes.AccAddressFromBech32(account.Address) + if err != nil { + return nil, err + } + + // calculate instance's hash. + // TODO: this should be merged with the same logic currently in instance sdk + srv, err := s.serviceSDK.Get(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 + instanceHash := hash.Dump(&instance.Instance{ + ServiceHash: srv.Hash, + EnvHash: envHash, + }) + + // start the container + imageHash, err := build(s.container, srv, s.ipfsEndpoint) + if err != nil { + return nil, err + } + _, err = start(s.container, srv, instanceHash, imageHash, instanceEnv, s.engineName, s.port) + if err != nil { + return nil, err + } + onError := func() { + stop(s.container, instanceHash, srv.Dependencies) + } + + msg := newMsgCreateRunner(s.cdc, user, req.ServiceHash, envHash) + tx, err := s.client.BuildAndBroadcastMsg(msg, accountName, accountPassword, accNumber, accSeq) + if err != nil { + defer onError() + if err == mempool.ErrTxInCache { + return nil, fmt.Errorf("runner already exists: %w", err) + } + return nil, err + } + return s.Get(tx.Data) +} + +// Delete deletes an existing runner. +func (s *SDK) Delete(req *api.DeleteRunnerRequest, accountName, accountPassword string) error { + account, err := s.accountSDK.Get(accountName) + if err != nil { + return err + } + // TODO: pass account by parameters + accNumber, accSeq := uint64(0), uint64(0) + user, err := cosmostypes.AccAddressFromBech32(account.Address) + if err != nil { + return err + } + + // get runner before deleting it + runner, err := s.Get(req.Hash) + if err != nil { + return err + } + + msg := newMsgDeleteRunner(s.cdc, user, req.Hash) + _, err = s.client.BuildAndBroadcastMsg(msg, accountName, accountPassword, accNumber, accSeq) + if err != nil { + if err == mempool.ErrTxInCache { + return fmt.Errorf("runner already deleted: %w", err) + } + return err + } + + // get instance and service + inst, err := s.instanceSDK.Get(runner.InstanceHash) + if err != nil { + return err + } + srv, err := s.serviceSDK.Get(inst.ServiceHash) + if err != nil { + return err + } + + // stop the local running service + if err := stop(s.container, inst.Hash, srv.Dependencies); err != nil { + return err + } + + // remove local volume + if req.DeleteData { + if err := deleteData(s.container, srv); err != nil { + return err + } + } + + return nil +} + +// Get returns the runner that matches given hash. +func (s *SDK) Get(hash hash.Hash) (*runner.Runner, error) { + var runner runner.Runner + if err := s.client.Query("custom/"+backendName+"/get/"+hash.String(), nil, &runner); err != nil { + return nil, err + } + return &runner, nil +} + +// List returns all runners. +func (s *SDK) List(f *Filter) ([]*runner.Runner, error) { + var runners []*runner.Runner + if err := s.client.Query("custom/"+backendName+"/list", nil, &runners); err != nil { + return nil, err + } + // no filter, returns + if f == nil { + return runners, nil + } + // filter results + ret := make([]*runner.Runner, 0) + for _, runner := range runners { + if (f.Address == "" || runner.Address == f.Address) && + (f.InstanceHash.IsZero() || runner.Hash.Equal(f.InstanceHash)) { + ret = append(ret, runner) + } + } + return ret, nil +} + +// Exists returns if a runner already exists. +func (s *SDK) Exists(hash hash.Hash) (bool, error) { + var exists bool + if err := s.client.Query("custom/"+backendName+"/exists/"+hash.String(), nil, &exists); err != nil { + return false, err + } + return exists, nil +} diff --git a/sdk/sdk.go b/sdk/sdk.go index 6a94b264f..ee4cf1f7c 100644 --- a/sdk/sdk.go +++ b/sdk/sdk.go @@ -12,27 +12,30 @@ import ( instancesdk "github.com/mesg-foundation/engine/sdk/instance" ownershipsdk "github.com/mesg-foundation/engine/sdk/ownership" processesdk "github.com/mesg-foundation/engine/sdk/process" + runnersdk "github.com/mesg-foundation/engine/sdk/runner" servicesdk "github.com/mesg-foundation/engine/sdk/service" ) // SDK exposes all functionalities of MESG Engine. type SDK struct { Service *servicesdk.SDK - Instance *instancesdk.Instance + Instance *instancesdk.SDK Execution *executionsdk.Execution Event *eventsdk.Event Process *processesdk.Process Account *accountsdk.SDK Ownership *ownershipsdk.SDK + Runner *runnersdk.SDK } // New creates a new SDK with given options. -func New(client *cosmos.Client, cdc *codec.Codec, kb *cosmos.Keybase, c container.Container, instanceDB database.InstanceDB, execDB database.ExecutionDB, processDB database.ProcessDB, engineName, port, ipfsEndpoint string) *SDK { +func New(client *cosmos.Client, cdc *codec.Codec, kb *cosmos.Keybase, execDB database.ExecutionDB, processDB database.ProcessDB, container container.Container, engineName, port string, ipfsEndpoint string) *SDK { ps := pubsub.New(0) accountSDK := accountsdk.NewSDK(kb) serviceSDK := servicesdk.New(cdc, client, accountSDK) ownershipSDK := ownershipsdk.New(cdc, client) - instanceSDK := instancesdk.New(c, serviceSDK, instanceDB, engineName, port, ipfsEndpoint) + instanceSDK := instancesdk.New(client) + runnerSDK := runnersdk.New(cdc, client, accountSDK, serviceSDK, instanceSDK, container, engineName, port, ipfsEndpoint) processSDK := processesdk.New(instanceSDK, processDB) executionSDK := executionsdk.New(ps, serviceSDK, instanceSDK, processSDK, execDB) eventSDK := eventsdk.New(ps, serviceSDK, instanceSDK) @@ -44,5 +47,6 @@ func New(client *cosmos.Client, cdc *codec.Codec, kb *cosmos.Keybase, c containe Process: processSDK, Account: accountSDK, Ownership: ownershipSDK, + Runner: runnerSDK, } } diff --git a/sdk/service/backend.go b/sdk/service/backend.go index d8a81acba..a5f8d6e74 100644 --- a/sdk/service/backend.go +++ b/sdk/service/backend.go @@ -92,7 +92,7 @@ func (s *Backend) querier(request cosmostypes.Request, path []string, req abci.R } } -// Create creates a new service from definition. +// Create creates a new service. func (s *Backend) Create(request cosmostypes.Request, msg *msgCreateService) (*service.Service, error) { return create(s.db(request), msg.Request, msg.Owner, s.ownerships, request) } diff --git a/server/grpc/api/execution_test.go b/server/grpc/api/execution_test.go index e59380aa6..6fc1b8ed6 100644 --- a/server/grpc/api/execution_test.go +++ b/server/grpc/api/execution_test.go @@ -23,7 +23,7 @@ func TestGet(t *testing.T) { exec := execution.New(nil, nil, nil, nil, "", "", nil, nil) require.NoError(t, db.Save(exec)) - sdk := sdk.New(nil, nil, nil, nil, nil, db, nil, "", "", "") + sdk := sdk.New(nil, nil, nil, db, nil, nil, "", "", "") s := NewExecutionServer(sdk) got, err := s.Get(context.Background(), &api.GetExecutionRequest{Hash: exec.Hash}) @@ -40,7 +40,7 @@ func TestUpdate(t *testing.T) { exec := execution.New(nil, nil, nil, nil, "", "", nil, nil) require.NoError(t, db.Save(exec)) - sdk := sdk.New(nil, nil, nil, nil, nil, db, nil, "", "", "") + sdk := sdk.New(nil, nil, nil, db, nil, nil, "", "", "") s := NewExecutionServer(sdk) _, err = s.Update(context.Background(), &api.UpdateExecutionRequest{Hash: exec.Hash}) diff --git a/server/grpc/api/instance.go b/server/grpc/api/instance.go index eaa2c23a2..6a748e2df 100644 --- a/server/grpc/api/instance.go +++ b/server/grpc/api/instance.go @@ -33,24 +33,7 @@ func (s *InstanceServer) List(ctx context.Context, request *protobuf_api.ListIns return &protobuf_api.ListInstanceResponse{Instances: instances}, nil } -// Create creates a new instance from service. -func (s *InstanceServer) Create(ctx context.Context, request *protobuf_api.CreateInstanceRequest) (*protobuf_api.CreateInstanceResponse, error) { - i, err := s.sdk.Instance.Create(request.ServiceHash, request.Env) - if err != nil { - return nil, err - } - return &protobuf_api.CreateInstanceResponse{Hash: i.Hash}, nil -} - // Get retrives instance. func (s *InstanceServer) Get(ctx context.Context, request *protobuf_api.GetInstanceRequest) (*instance.Instance, error) { return s.sdk.Instance.Get(request.Hash) } - -// Delete an instance -func (s *InstanceServer) Delete(ctx context.Context, request *protobuf_api.DeleteInstanceRequest) (*protobuf_api.DeleteInstanceResponse, error) { - if err := s.sdk.Instance.Delete(request.Hash, request.DeleteData); err != nil { - return nil, err - } - return &protobuf_api.DeleteInstanceResponse{}, nil -} diff --git a/server/grpc/api/process.go b/server/grpc/api/process.go index f586e8fa3..e99f0c539 100644 --- a/server/grpc/api/process.go +++ b/server/grpc/api/process.go @@ -18,7 +18,7 @@ func NewProcessServer(sdk *sdk.SDK) *ProcessServer { return &ProcessServer{sdk: sdk} } -// Create creates a new service from definition. +// Create creates a new process. func (s *ProcessServer) Create(ctx context.Context, req *api.CreateProcessRequest) (*api.CreateProcessResponse, error) { wf, err := s.sdk.Process.Create(&process.Process{ Key: req.Key, @@ -31,12 +31,12 @@ func (s *ProcessServer) Create(ctx context.Context, req *api.CreateProcessReques return &api.CreateProcessResponse{Hash: wf.Hash}, nil } -// Delete deletes service by hash or sid. +// Delete deletes process by hash or sid. func (s *ProcessServer) Delete(ctx context.Context, request *api.DeleteProcessRequest) (*api.DeleteProcessResponse, error) { return &api.DeleteProcessResponse{}, s.sdk.Process.Delete(request.Hash) } -// Get returns service from given hash. +// Get returns process from given hash. func (s *ProcessServer) Get(ctx context.Context, req *api.GetProcessRequest) (*process.Process, error) { return s.sdk.Process.Get(req.Hash) } diff --git a/server/grpc/api/runner.go b/server/grpc/api/runner.go new file mode 100644 index 000000000..33d23ef48 --- /dev/null +++ b/server/grpc/api/runner.go @@ -0,0 +1,67 @@ +package api + +import ( + "context" + + protobuf_api "github.com/mesg-foundation/engine/protobuf/api" + "github.com/mesg-foundation/engine/runner" + "github.com/mesg-foundation/engine/sdk" + runnersdk "github.com/mesg-foundation/engine/sdk/runner" +) + +// RunnerServer is the type to aggregate all Runner APIs. +type RunnerServer struct { + sdk *sdk.SDK +} + +// NewRunnerServer creates a new RunnerServer. +func NewRunnerServer(sdk *sdk.SDK) *RunnerServer { + return &RunnerServer{sdk: sdk} +} + +// Create creates a new runner. +func (s *RunnerServer) Create(ctx context.Context, req *protobuf_api.CreateRunnerRequest) (*protobuf_api.CreateRunnerResponse, error) { + credUsername, credPassphrase, err := GetCredentialFromContext(ctx) + if err != nil { + return nil, err + } + srv, err := s.sdk.Runner.Create(req, credUsername, credPassphrase) + if err != nil { + return nil, err + } + return &protobuf_api.CreateRunnerResponse{Hash: srv.Hash}, nil +} + +// Delete deletes a runner. +func (s *RunnerServer) Delete(ctx context.Context, req *protobuf_api.DeleteRunnerRequest) (*protobuf_api.DeleteRunnerResponse, error) { + credUsername, credPassphrase, err := GetCredentialFromContext(ctx) + if err != nil { + return nil, err + } + if err := s.sdk.Runner.Delete(req, credUsername, credPassphrase); err != nil { + return nil, err + } + return &protobuf_api.DeleteRunnerResponse{}, nil +} + +// Get returns runner from given hash. +func (s *RunnerServer) Get(ctx context.Context, req *protobuf_api.GetRunnerRequest) (*runner.Runner, error) { + return s.sdk.Runner.Get(req.Hash) +} + +// List returns all runners. +func (s *RunnerServer) List(ctx context.Context, req *protobuf_api.ListRunnerRequest) (*protobuf_api.ListRunnerResponse, error) { + var filter *runnersdk.Filter + if req.Filter != nil { + filter = &runnersdk.Filter{ + Address: req.Filter.Address, + InstanceHash: req.Filter.InstanceHash, + } + } + runners, err := s.sdk.Runner.List(filter) + if err != nil { + return nil, err + } + + return &protobuf_api.ListRunnerResponse{Runners: runners}, nil +} diff --git a/server/grpc/server.go b/server/grpc/server.go index 4f6b85f34..35d8be256 100644 --- a/server/grpc/server.go +++ b/server/grpc/server.go @@ -78,6 +78,7 @@ func (s *Server) register() { protobuf_api.RegisterProcessServer(s.instance, api.NewProcessServer(s.sdk)) protobuf_api.RegisterAccountServer(s.instance, api.NewAccountServer(s.sdk)) protobuf_api.RegisterOwnershipServer(s.instance, api.NewOwnershipServer(s.sdk)) + protobuf_api.RegisterRunnerServer(s.instance, api.NewRunnerServer(s.sdk)) reflection.Register(s.instance) }