From b454bf3e01caf4749d91c6a35fa480c0ee6f472a Mon Sep 17 00:00:00 2001 From: vsoch Date: Sun, 11 Feb 2024 21:48:41 -0700 Subject: [PATCH] add job submit commands, database, and new client This change adds the JobSubmit, to proto, and to each of the client and server. At this point we can request a job to be submit to a specific cluster, and the token that was generated on register of the cluster is required to "authenticate." We then validate those things and add the job to the database! Next we need a small client to run from within a flux instance and check for jobs assigned to it, and when it receives one, it will be removed from the database. I think I want to make flux-core "bindings" for Go first. Signed-off-by: vsoch --- Makefile | 3 +- README.md | 57 ++++- api/v1/api.proto | 30 ++- cmd/rainbow/rainbow.go | 73 ++++++ cmd/rainbow/register/register.go | 29 +++ cmd/rainbow/submit/submit.go | 55 +++++ cmd/register/register.go | 42 ---- cmd/server/server.go | 10 +- go.mod | 5 +- go.sum | 12 +- pkg/api/v1/api.pb.go | 390 +++++++++++++++++++++---------- pkg/api/v1/api_grpc.pb.go | 12 +- pkg/client/client.go | 5 +- pkg/client/endpoint.go | 53 ++++- pkg/client/stream.go | 12 +- pkg/provider/message.go | 2 +- pkg/server/database.go | 131 ++++++++++- pkg/server/endpoint.go | 28 +++ pkg/server/server.go | 2 + pkg/types/job.go | 9 + pkg/types/message.go | 31 +++ pkg/types/version.go | 20 ++ pkg/utils/utils.go | 19 ++ 23 files changed, 788 insertions(+), 242 deletions(-) create mode 100644 cmd/rainbow/rainbow.go create mode 100644 cmd/rainbow/register/register.go create mode 100644 cmd/rainbow/submit/submit.go delete mode 100755 cmd/register/register.go create mode 100644 pkg/types/job.go create mode 100644 pkg/types/message.go create mode 100644 pkg/types/version.go create mode 100644 pkg/utils/utils.go diff --git a/Makefile b/Makefile index f21a341..1a9950b 100644 --- a/Makefile +++ b/Makefile @@ -50,7 +50,7 @@ stream: ## Runs the interface client .PHONY: register register: ## Run mock registration - go run cmd/register/register.go + go run cmd/rainbow/rainbow.go register .PHONY: tag tag: ## Creates release tag @@ -64,6 +64,7 @@ tagless: ## Delete the current release tag .PHONY: clean clean: ## Cleans bin and temp directories + rm -rf ./rainbow.db go clean rm -fr ./vendor rm -fr ./bin diff --git a/README.md b/README.md index 250a1c3..b0e3401 100755 --- a/README.md +++ b/README.md @@ -54,7 +54,7 @@ go run cmd/server/server.go 2024/02/11 18:06:57 server listening: [::]:50051 2024/02/11 18:06:59 📝️ received register: keebler SELECT count(*) from clusters WHERE name LIKE "keebler": (0) -INSERT into clusters VALUES ("keebler", "2804a013-89df-433d-a904-4666a6415ad0"): (1) +INSERT into clusters VALUES ("keebler", "712747b7-b2a9-4bea-b630-056cd64856e6"): (1) ``` And then mock a registration: @@ -68,11 +68,55 @@ go run cmd/register/register.go 2024/02/11 18:06:59 🌈️ starting client (localhost:50051)... 2024/02/11 18:06:59 registering cluster: keebler 2024/02/11 18:06:59 status: REGISTER_SUCCESS -2024/02/11 18:06:59 token: 2804a013-89df-433d-a904-4666a6415ad0 +2024/02/11 18:06:59 token: 712747b7-b2a9-4bea-b630-056cd64856e6 ``` -In the above, we are providing a cluster name (keebler) and it is being registered to the database, and a token and status returned. -We would then use this token for subsequent requests to interact with the cluster. +In the above, we are providing a cluster name (keebler) and it is being registered to the database, and a token and status returned. Note that if we want to submit a job to the "keebler" cluster, from anywhere, we need this token! Let's try that next. + +```bash +# Look at help +go run ./cmd/rainbow/rainbow.go submit --help +``` +``` +usage: rainbow submit [-h|--help] [-s|--secret ""] [-n|--nodes + ] [-t|--tasks ] [-c|--command ""] + [--job-name ""] [--host ""] [--cluster-name + ""] + + Submit a job to a rainbow cluster + +Arguments: + + -h --help Print help information + -s --secret Registration 'secret'. Default: chocolate-cookies + -n --nodes Number of nodes to request. Default: 1 + -t --tasks Number of tasks to request (per node? total?) + -c --command Command to submit. Default: chocolate-cookies + --job-name Name for the job (defaults to first command). + --host Scheduler server address (host:port). Default: + localhost:50051 + --cluster-name Name of cluster to register. Default: keebler +``` +Let's try doing that. + +```bash +go run ./cmd/rainbow/rainbow.go submit --secret "712747b7-b2a9-4bea-b630-056cd64856e6" --command hostname +``` +```console +2024/02/11 21:43:17 🌈️ starting client (localhost:50051)... +2024/02/11 21:43:17 submit job: hostname +2024/02/11 21:43:17 status:SUBMIT_SUCCESS +``` + +Hooray! On the server log side we see... + +```console +SELECT * from clusters WHERE name LIKE "keebler" LIMIT 1: keebler +2024/02/11 21:43:17 📝️ received job hostname for cluster keebler +``` + +Now we have a job in the database, and it's oriented for a specific cluster. +Now we need to write the logic for the cluster to poll asking for jobs assigned to it to receive it! I'll work on that next. ## Container Images @@ -80,10 +124,7 @@ We would then use this token for subsequent requests to interact with the cluste ## TODO -- Write the job submission endpoint, which should take a cluster name and command, and return status (success, denied, etc.) -- Make a nicer (single UI entrypoint) for client with different functions - -At this point we will have a dumb little database with jobs assigned to clusters. We can then modify the client to add a polling command (intended to be run on a flux instance) that will use the cluster-specific token to say "Do you have any jobs for me?" at some interval. This can run anywhere there is a Flux instance. It can receive the job, and run it. When it receives the job, the job will be deleted from the database, because we don't care anymore. +At this point we have a dumb little database with jobs assigned to clusters. We can then modify the client to add a polling command (intended to be run on a flux instance) that will use the cluster-specific token to say "Do you have any jobs for me?" at some interval. This can run anywhere there is a Flux instance. It can receive the job, and run it. When it receives the job, the job will be deleted from the database, because we don't care anymore. And that should be a very basic prototype - we can then build this into containers and deploy in different places (and deploy a client separate from a Flux instance) and demonstrate submitting jobs across different places. For the Flux instance logic, we could write the grpc endpoints in Python, but it would be more fun to (finally) make Go bindings for flux core. diff --git a/api/v1/api.proto b/api/v1/api.proto index 8370176..ce9ac40 100755 --- a/api/v1/api.proto +++ b/api/v1/api.proto @@ -15,7 +15,7 @@ service Service { rpc Register(RegisterRequest) returns (RegisterResponse); // Job Submission - request for submitting a job to a named cluster - rpc SubmitJob(Request) returns (SubmitJobResponse); + rpc SubmitJob(SubmitJobRequest) returns (SubmitJobResponse); // TESTING ENDPOINTS // Serial checks the connectivity and response time of the service. @@ -41,19 +41,31 @@ message Content { // Request represents the request for a method invocation. // It includes the content to be sent and a timestamp. message Request { - // The content to be sent in the request. Content content = 1; - - // Timestamp when the message was sent, represented in Unix epoch format. google.protobuf.Timestamp sent = 2; } +// RegisterRequest registers a cluster to the scheduler service +// The shared secret is required to validate the request message RegisterRequest { string name = 1; string secret = 2; google.protobuf.Timestamp sent = 3; } +// SubmitJobRequest takes a job name, cluster name +// and requires the cluster token. Since we want to be generic, +// we currently accept nodes, tasks, and the command +message SubmitJobRequest { + string name = 1; + string cluster = 2; + string token = 3; + int32 nodes = 4; + int32 tasks = 5; + string command = 6; + google.protobuf.Timestamp sent = 7; +} + // Testing response - the server's response to a request. message Response { @@ -65,16 +77,9 @@ message Response { RESULT_TYPE_ERROR = 2; } - // Unique identifier correlating to the request. string request_id = 1; - - // Total number of messages received in the request. int64 message_count = 2; - - // Number of messages successfully processed. int64 messages_processed = 3; - - // Detailed information or description of the processing result. string processing_details = 4; } @@ -105,5 +110,6 @@ message SubmitJobResponse { SUBMIT_DENIED = 3; } string request_id = 1; - string job_id = 2; + int32 jobid = 2; + ResultType status = 3; } \ No newline at end of file diff --git a/cmd/rainbow/rainbow.go b/cmd/rainbow/rainbow.go new file mode 100644 index 0000000..4454ebc --- /dev/null +++ b/cmd/rainbow/rainbow.go @@ -0,0 +1,73 @@ +package main + +import ( + "fmt" + "log" + "os" + + "github.com/akamensky/argparse" + register "github.com/converged-computing/rainbow/cmd/rainbow/register" + submit "github.com/converged-computing/rainbow/cmd/rainbow/submit" + "github.com/converged-computing/rainbow/pkg/types" +) + +var ( + Header = ` + • ┓ +┏┓┏┓┓┏┓┣┓┏┓┓┏┏ +┛ ┗┻┗┛┗┗┛┗┛┗┻┛ +` + + defaultSecret = "chocolate-cookies" +) + +func RunVersion() { + fmt.Printf("🌈️ rainbow version %s\n", types.Version) +} + +func main() { + + parser := argparse.NewParser("rainbow", "Interact with a rainbow multi-cluster") + versionCmd := parser.NewCommand("version", "See the version of compspec") + registerCmd := parser.NewCommand("register", "Register a new cluster") + submitCmd := parser.NewCommand("submit", "Submit a job to a rainbow cluster") + + // Shared values + host := parser.String("", "host", &argparse.Options{Default: "localhost:50051", Help: "Scheduler server address (host:port)"}) + clusterName := parser.String("", "cluster-name", &argparse.Options{Default: "keebler", Help: "Name of cluster to register"}) + + // Register + secret := registerCmd.String("s", "secret", &argparse.Options{Default: defaultSecret, Help: "Registration 'secret'"}) + + // Submit (note that command for now needs to be in quotes to get the whole thing) + submitSecret := submitCmd.String("s", "secret", &argparse.Options{Default: defaultSecret, Help: "Registration 'secret'"}) + nodes := submitCmd.Int("n", "nodes", &argparse.Options{Default: 1, Help: "Number of nodes to request"}) + tasks := submitCmd.Int("t", "tasks", &argparse.Options{Help: "Number of tasks to request (per node? total?)"}) + command := submitCmd.String("c", "command", &argparse.Options{Default: defaultSecret, Help: "Command to submit"}) + jobName := submitCmd.String("", "job-name", &argparse.Options{Help: "Name for the job (defaults to first command)"}) + + // Now parse the arguments + err := parser.Parse(os.Args) + if err != nil { + fmt.Println(Header) + fmt.Println(parser.Usage(err)) + return + } + + if registerCmd.Happened() { + err := register.Run(*host, *clusterName, *secret) + if err != nil { + log.Fatalf("Issue with register: %s\n", err) + } + } else if submitCmd.Happened() { + err := submit.Run(*host, *jobName, *command, *nodes, *tasks, *submitSecret, *clusterName) + if err != nil { + log.Fatal(err.Error()) + } + } else if versionCmd.Happened() { + RunVersion() + } else { + fmt.Println(Header) + fmt.Println(parser.Usage(nil)) + } +} diff --git a/cmd/rainbow/register/register.go b/cmd/rainbow/register/register.go new file mode 100644 index 0000000..58a664b --- /dev/null +++ b/cmd/rainbow/register/register.go @@ -0,0 +1,29 @@ +package extract + +import ( + "context" + "log" + + "github.com/converged-computing/rainbow/pkg/client" +) + +// Run will run an extraction of host metadata +func Run(host, clusterName, secret string) error { + c, err := client.NewClient(host) + if err != nil { + return err + } + + log.Printf("registering cluster: %s", clusterName) + + // Last argument is secret, empty for now + response, err := c.Register(context.Background(), clusterName, secret) + if err != nil { + return err + } + + // If we get here, success! Dump all the stuff. + log.Printf("status: %s", response.Status) + log.Printf(" token: %s", response.Token) + return nil +} diff --git a/cmd/rainbow/submit/submit.go b/cmd/rainbow/submit/submit.go new file mode 100644 index 0000000..a5567a8 --- /dev/null +++ b/cmd/rainbow/submit/submit.go @@ -0,0 +1,55 @@ +package match + +import ( + "context" + "fmt" + "log" + "strings" + + "github.com/converged-computing/rainbow/pkg/client" + "github.com/converged-computing/rainbow/pkg/types" +) + +// Run will check a manifest list of artifacts against a host machine +// For now, the host machine parameters will be provided as flags +func Run( + host, jobName, command string, + nodes, tasks int, + submitSecret, clusterName string, +) error { + + c, err := client.NewClient(host) + if err != nil { + return nil + } + + // Further validation of job happens with client below + if command == "" { + return fmt.Errorf("a command is required") + } + log.Printf("submit job: %s", command) + + // Prepare a JobSpec + if jobName == "" { + parts := strings.Split(command, " ") + jobName = parts[0] + } + jobspec := types.JobSpec{ + Name: jobName, + Nodes: int32(nodes), + Tasks: int32(tasks), + Command: command, + } + + // Last argument is secret, empty for now + response, err := c.SubmitJob(context.Background(), jobspec, clusterName, submitSecret) + if err != nil { + return err + } + + // If we get here, success! Dump all the stuff. + //log.Printf("status: %s", response.Status) + //log.Printf(" token: %s", response.Token) + log.Println(response) + return nil +} diff --git a/cmd/register/register.go b/cmd/register/register.go deleted file mode 100755 index 6531ea4..0000000 --- a/cmd/register/register.go +++ /dev/null @@ -1,42 +0,0 @@ -package main - -import ( - "context" - "flag" - "log" - - "github.com/converged-computing/rainbow/pkg/client" -) - -var ( - host string - clusterName string - secret string - version = "v0.0.1-default" -) - -func main() { - flag.StringVar(&host, "host", "localhost:50051", "Scheduler server address (host:port)") - flag.StringVar(&clusterName, "cluster", "keebler", "Name of cluster to register") - flag.StringVar(&secret, "secret", "chocolate-cookies", "Registration 'secret'") - flag.Parse() - - log.Printf("creating client (%s)...", version) - - c, err := client.NewClient(host) - if err != nil { - log.Fatalf("error while creating client: %v", err) - } - - log.Printf("registering cluster: %s", clusterName) - - // Last argument is secret, empty for now - response, err := c.Register(context.Background(), clusterName, secret) - if err != nil { - log.Fatalf("error while running client: %v", err) - } - - // If we get here, success! Dump all the stuff. - log.Printf("status: %s", response.Status) - log.Printf(" token: %s", response.Token) -} diff --git a/cmd/server/server.go b/cmd/server/server.go index 53e84bf..5208f6a 100755 --- a/cmd/server/server.go +++ b/cmd/server/server.go @@ -6,6 +6,7 @@ import ( "log" "github.com/converged-computing/rainbow/pkg/server" + "github.com/converged-computing/rainbow/pkg/types" ) var ( @@ -13,11 +14,8 @@ var ( name = "rainbow" sqliteFile = "rainbow.db" environment = "development" - - // Remove the previous database - skipCleanup = false + cleanup = false secret = "chocolate-cookies" - version = "v0.0.1-default" ) func main() { @@ -26,12 +24,12 @@ func main() { flag.StringVar(&sqliteFile, "db", sqliteFile, "sqlite3 database file (default: rainbow.db)") flag.StringVar(&secret, "secret", secret, "secret to validate registration (default: chocolate-cookies)") flag.StringVar(&environment, "environment", environment, "environment (default: development)") - flag.BoolVar(&skipCleanup, "skip-cleanup", skipCleanup, "skip cleanup of previous sqlite database (default: false)") + flag.BoolVar(&cleanup, "cleanup", cleanup, "cleanup previous sqlite database (default: false)") flag.Parse() // create server log.Print("creating 🌈️ server...") - s, err := server.NewServer(name, version, environment, sqliteFile, !skipCleanup, secret) + s, err := server.NewServer(name, types.Version, environment, sqliteFile, cleanup, secret) if err != nil { log.Fatalf("error while creating server: %v", err) } diff --git a/go.mod b/go.mod index 067ddb6..806be85 100644 --- a/go.mod +++ b/go.mod @@ -3,21 +3,18 @@ module github.com/converged-computing/rainbow go 1.20 require ( + github.com/akamensky/argparse v1.4.0 github.com/google/uuid v1.6.0 github.com/mattn/go-sqlite3 v1.14.22 github.com/pkg/errors v0.9.1 - github.com/stretchr/testify v1.8.4 google.golang.org/grpc v1.61.0 google.golang.org/protobuf v1.32.0 ) require ( - github.com/davecgh/go-spew v1.1.1 // indirect github.com/golang/protobuf v1.5.3 // indirect - github.com/pmezard/go-difflib v1.0.0 // indirect golang.org/x/net v0.18.0 // indirect golang.org/x/sys v0.14.0 // indirect golang.org/x/text v0.14.0 // indirect google.golang.org/genproto/googleapis/rpc v0.0.0-20231106174013-bbf56f31fb17 // indirect - gopkg.in/yaml.v3 v3.0.1 // indirect ) diff --git a/go.sum b/go.sum index e9aeb56..c928b13 100644 --- a/go.sum +++ b/go.sum @@ -1,5 +1,5 @@ -github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= -github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/akamensky/argparse v1.4.0 h1:YGzvsTqCvbEZhL8zZu2AiA5nq805NZh75JNj4ajn1xc= +github.com/akamensky/argparse v1.4.0/go.mod h1:S5kwC7IuDcEr5VeXtGPRVZ5o/FdhcMlQz4IZQuw64xA= github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= github.com/golang/protobuf v1.5.3 h1:KhyjKVUg7Usr/dYsdSqoFveMYd5ko72D+zANwlG1mmg= github.com/golang/protobuf v1.5.3/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= @@ -11,10 +11,6 @@ github.com/mattn/go-sqlite3 v1.14.22 h1:2gZY6PC6kBnID23Tichd1K+Z0oS6nE/XwU+Vz/5o github.com/mattn/go-sqlite3 v1.14.22/go.mod h1:Uh1q+B4BYcTPb+yiD3kU8Ct7aC0hY9fxUwlHK0RXw+Y= github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= -github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= -github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= -github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk= -github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= golang.org/x/net v0.18.0 h1:mIYleuAkSbHh0tCv7RvjL3F6ZVbLjq4+R7zbOn3Kokg= golang.org/x/net v0.18.0/go.mod h1:/czyP5RqHAH4odGYxBJ1qz0+CE5WZ+2j1YgoEo8F2jQ= golang.org/x/sys v0.14.0 h1:Vz7Qs629MkJkGyHxUlRHizWJRG2j8fbQKjELVSNhy7Q= @@ -30,7 +26,3 @@ google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp0 google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= google.golang.org/protobuf v1.32.0 h1:pPC6BG5ex8PDFnkbrGU3EixyhKcQ2aDuBS36lqK/C7I= google.golang.org/protobuf v1.32.0/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos= -gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM= -gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= -gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= diff --git a/pkg/api/v1/api.pb.go b/pkg/api/v1/api.pb.go index 6c5909f..be2a559 100644 --- a/pkg/api/v1/api.pb.go +++ b/pkg/api/v1/api.pb.go @@ -69,7 +69,7 @@ func (x Response_ResultType) Number() protoreflect.EnumNumber { // Deprecated: Use Response_ResultType.Descriptor instead. func (Response_ResultType) EnumDescriptor() ([]byte, []int) { - return file_api_proto_rawDescGZIP(), []int{3, 0} + return file_api_proto_rawDescGZIP(), []int{4, 0} } // Registration statuses @@ -125,7 +125,7 @@ func (x RegisterResponse_ResultType) Number() protoreflect.EnumNumber { // Deprecated: Use RegisterResponse_ResultType.Descriptor instead. func (RegisterResponse_ResultType) EnumDescriptor() ([]byte, []int) { - return file_api_proto_rawDescGZIP(), []int{4, 0} + return file_api_proto_rawDescGZIP(), []int{5, 0} } // Enum to represent the result types of the operation. @@ -178,7 +178,7 @@ func (x SubmitJobResponse_ResultType) Number() protoreflect.EnumNumber { // Deprecated: Use SubmitJobResponse_ResultType.Descriptor instead. func (SubmitJobResponse_ResultType) EnumDescriptor() ([]byte, []int) { - return file_api_proto_rawDescGZIP(), []int{5, 0} + return file_api_proto_rawDescGZIP(), []int{6, 0} } // Content represents the message content with metadata. @@ -255,10 +255,8 @@ type Request struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - // The content to be sent in the request. - Content *Content `protobuf:"bytes,1,opt,name=content,proto3" json:"content,omitempty"` - // Timestamp when the message was sent, represented in Unix epoch format. - Sent *timestamppb.Timestamp `protobuf:"bytes,2,opt,name=sent,proto3" json:"sent,omitempty"` + Content *Content `protobuf:"bytes,1,opt,name=content,proto3" json:"content,omitempty"` + Sent *timestamppb.Timestamp `protobuf:"bytes,2,opt,name=sent,proto3" json:"sent,omitempty"` } func (x *Request) Reset() { @@ -307,6 +305,8 @@ func (x *Request) GetSent() *timestamppb.Timestamp { return nil } +// RegisterRequest registers a cluster to the scheduler service +// The shared secret is required to validate the request type RegisterRequest struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -370,26 +370,120 @@ func (x *RegisterRequest) GetSent() *timestamppb.Timestamp { return nil } +// SubmitJobRequest takes a job name, cluster name +// and requires the cluster token. Since we want to be generic, +// we currently accept nodes, tasks, and the command +type SubmitJobRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` + Cluster string `protobuf:"bytes,2,opt,name=cluster,proto3" json:"cluster,omitempty"` + Token string `protobuf:"bytes,3,opt,name=token,proto3" json:"token,omitempty"` + Nodes int32 `protobuf:"varint,4,opt,name=nodes,proto3" json:"nodes,omitempty"` + Tasks int32 `protobuf:"varint,5,opt,name=tasks,proto3" json:"tasks,omitempty"` + Command string `protobuf:"bytes,6,opt,name=command,proto3" json:"command,omitempty"` + Sent *timestamppb.Timestamp `protobuf:"bytes,7,opt,name=sent,proto3" json:"sent,omitempty"` +} + +func (x *SubmitJobRequest) Reset() { + *x = SubmitJobRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_api_proto_msgTypes[3] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *SubmitJobRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*SubmitJobRequest) ProtoMessage() {} + +func (x *SubmitJobRequest) ProtoReflect() protoreflect.Message { + mi := &file_api_proto_msgTypes[3] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use SubmitJobRequest.ProtoReflect.Descriptor instead. +func (*SubmitJobRequest) Descriptor() ([]byte, []int) { + return file_api_proto_rawDescGZIP(), []int{3} +} + +func (x *SubmitJobRequest) GetName() string { + if x != nil { + return x.Name + } + return "" +} + +func (x *SubmitJobRequest) GetCluster() string { + if x != nil { + return x.Cluster + } + return "" +} + +func (x *SubmitJobRequest) GetToken() string { + if x != nil { + return x.Token + } + return "" +} + +func (x *SubmitJobRequest) GetNodes() int32 { + if x != nil { + return x.Nodes + } + return 0 +} + +func (x *SubmitJobRequest) GetTasks() int32 { + if x != nil { + return x.Tasks + } + return 0 +} + +func (x *SubmitJobRequest) GetCommand() string { + if x != nil { + return x.Command + } + return "" +} + +func (x *SubmitJobRequest) GetSent() *timestamppb.Timestamp { + if x != nil { + return x.Sent + } + return nil +} + // Testing response - the server's response to a request. type Response struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - // Unique identifier correlating to the request. - RequestId string `protobuf:"bytes,1,opt,name=request_id,json=requestId,proto3" json:"request_id,omitempty"` - // Total number of messages received in the request. - MessageCount int64 `protobuf:"varint,2,opt,name=message_count,json=messageCount,proto3" json:"message_count,omitempty"` - // Number of messages successfully processed. - MessagesProcessed int64 `protobuf:"varint,3,opt,name=messages_processed,json=messagesProcessed,proto3" json:"messages_processed,omitempty"` - // Detailed information or description of the processing result. + RequestId string `protobuf:"bytes,1,opt,name=request_id,json=requestId,proto3" json:"request_id,omitempty"` + MessageCount int64 `protobuf:"varint,2,opt,name=message_count,json=messageCount,proto3" json:"message_count,omitempty"` + MessagesProcessed int64 `protobuf:"varint,3,opt,name=messages_processed,json=messagesProcessed,proto3" json:"messages_processed,omitempty"` ProcessingDetails string `protobuf:"bytes,4,opt,name=processing_details,json=processingDetails,proto3" json:"processing_details,omitempty"` } func (x *Response) Reset() { *x = Response{} if protoimpl.UnsafeEnabled { - mi := &file_api_proto_msgTypes[3] + mi := &file_api_proto_msgTypes[4] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -402,7 +496,7 @@ func (x *Response) String() string { func (*Response) ProtoMessage() {} func (x *Response) ProtoReflect() protoreflect.Message { - mi := &file_api_proto_msgTypes[3] + mi := &file_api_proto_msgTypes[4] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -415,7 +509,7 @@ func (x *Response) ProtoReflect() protoreflect.Message { // Deprecated: Use Response.ProtoReflect.Descriptor instead. func (*Response) Descriptor() ([]byte, []int) { - return file_api_proto_rawDescGZIP(), []int{3} + return file_api_proto_rawDescGZIP(), []int{4} } func (x *Response) GetRequestId() string { @@ -460,7 +554,7 @@ type RegisterResponse struct { func (x *RegisterResponse) Reset() { *x = RegisterResponse{} if protoimpl.UnsafeEnabled { - mi := &file_api_proto_msgTypes[4] + mi := &file_api_proto_msgTypes[5] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -473,7 +567,7 @@ func (x *RegisterResponse) String() string { func (*RegisterResponse) ProtoMessage() {} func (x *RegisterResponse) ProtoReflect() protoreflect.Message { - mi := &file_api_proto_msgTypes[4] + mi := &file_api_proto_msgTypes[5] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -486,7 +580,7 @@ func (x *RegisterResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use RegisterResponse.ProtoReflect.Descriptor instead. func (*RegisterResponse) Descriptor() ([]byte, []int) { - return file_api_proto_rawDescGZIP(), []int{4} + return file_api_proto_rawDescGZIP(), []int{5} } func (x *RegisterResponse) GetRequestId() string { @@ -516,14 +610,15 @@ type SubmitJobResponse struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - RequestId string `protobuf:"bytes,1,opt,name=request_id,json=requestId,proto3" json:"request_id,omitempty"` - JobId string `protobuf:"bytes,2,opt,name=job_id,json=jobId,proto3" json:"job_id,omitempty"` + RequestId string `protobuf:"bytes,1,opt,name=request_id,json=requestId,proto3" json:"request_id,omitempty"` + Jobid int32 `protobuf:"varint,2,opt,name=jobid,proto3" json:"jobid,omitempty"` + Status SubmitJobResponse_ResultType `protobuf:"varint,3,opt,name=status,proto3,enum=convergedcomputing.org.grpc.v1.SubmitJobResponse_ResultType" json:"status,omitempty"` } func (x *SubmitJobResponse) Reset() { *x = SubmitJobResponse{} if protoimpl.UnsafeEnabled { - mi := &file_api_proto_msgTypes[5] + mi := &file_api_proto_msgTypes[6] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -536,7 +631,7 @@ func (x *SubmitJobResponse) String() string { func (*SubmitJobResponse) ProtoMessage() {} func (x *SubmitJobResponse) ProtoReflect() protoreflect.Message { - mi := &file_api_proto_msgTypes[5] + mi := &file_api_proto_msgTypes[6] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -549,7 +644,7 @@ func (x *SubmitJobResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use SubmitJobResponse.ProtoReflect.Descriptor instead. func (*SubmitJobResponse) Descriptor() ([]byte, []int) { - return file_api_proto_rawDescGZIP(), []int{5} + return file_api_proto_rawDescGZIP(), []int{6} } func (x *SubmitJobResponse) GetRequestId() string { @@ -559,11 +654,18 @@ func (x *SubmitJobResponse) GetRequestId() string { return "" } -func (x *SubmitJobResponse) GetJobId() string { +func (x *SubmitJobResponse) GetJobid() int32 { if x != nil { - return x.JobId + return x.Jobid } - return "" + return 0 +} + +func (x *SubmitJobResponse) GetStatus() SubmitJobResponse_ResultType { + if x != nil { + return x.Status + } + return SubmitJobResponse_SUBMIT_UNSPECIFIED } var File_api_proto protoreflect.FileDescriptor @@ -603,82 +705,101 @@ var file_api_proto_rawDesc = []byte{ 0x28, 0x09, 0x52, 0x06, 0x73, 0x65, 0x63, 0x72, 0x65, 0x74, 0x12, 0x2e, 0x0a, 0x04, 0x73, 0x65, 0x6e, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, - 0x74, 0x61, 0x6d, 0x70, 0x52, 0x04, 0x73, 0x65, 0x6e, 0x74, 0x22, 0x87, 0x02, 0x0a, 0x08, 0x52, - 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x1d, 0x0a, 0x0a, 0x72, 0x65, 0x71, 0x75, 0x65, - 0x73, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x72, 0x65, 0x71, - 0x75, 0x65, 0x73, 0x74, 0x49, 0x64, 0x12, 0x23, 0x0a, 0x0d, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, - 0x65, 0x5f, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0c, 0x6d, - 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x2d, 0x0a, 0x12, 0x6d, - 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x73, 0x5f, 0x70, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x65, - 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x03, 0x52, 0x11, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, - 0x73, 0x50, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x65, 0x64, 0x12, 0x2d, 0x0a, 0x12, 0x70, 0x72, - 0x6f, 0x63, 0x65, 0x73, 0x73, 0x69, 0x6e, 0x67, 0x5f, 0x64, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x73, - 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x11, 0x70, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x69, - 0x6e, 0x67, 0x44, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x73, 0x22, 0x59, 0x0a, 0x0a, 0x52, 0x65, 0x73, - 0x75, 0x6c, 0x74, 0x54, 0x79, 0x70, 0x65, 0x12, 0x1b, 0x0a, 0x17, 0x52, 0x45, 0x53, 0x55, 0x4c, - 0x54, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, - 0x45, 0x44, 0x10, 0x00, 0x12, 0x17, 0x0a, 0x13, 0x52, 0x45, 0x53, 0x55, 0x4c, 0x54, 0x5f, 0x54, - 0x59, 0x50, 0x45, 0x5f, 0x53, 0x55, 0x43, 0x43, 0x45, 0x53, 0x53, 0x10, 0x01, 0x12, 0x15, 0x0a, - 0x11, 0x52, 0x45, 0x53, 0x55, 0x4c, 0x54, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x45, 0x52, 0x52, - 0x4f, 0x52, 0x10, 0x02, 0x22, 0x98, 0x02, 0x0a, 0x10, 0x52, 0x65, 0x67, 0x69, 0x73, 0x74, 0x65, - 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x1d, 0x0a, 0x0a, 0x72, 0x65, 0x71, - 0x75, 0x65, 0x73, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x72, - 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x49, 0x64, 0x12, 0x14, 0x0a, 0x05, 0x74, 0x6f, 0x6b, 0x65, - 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x12, 0x53, - 0x0a, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x3b, - 0x2e, 0x63, 0x6f, 0x6e, 0x76, 0x65, 0x72, 0x67, 0x65, 0x64, 0x63, 0x6f, 0x6d, 0x70, 0x75, 0x74, - 0x69, 0x6e, 0x67, 0x2e, 0x6f, 0x72, 0x67, 0x2e, 0x67, 0x72, 0x70, 0x63, 0x2e, 0x76, 0x31, 0x2e, - 0x52, 0x65, 0x67, 0x69, 0x73, 0x74, 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, - 0x2e, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x54, 0x79, 0x70, 0x65, 0x52, 0x06, 0x73, 0x74, 0x61, - 0x74, 0x75, 0x73, 0x22, 0x7a, 0x0a, 0x0a, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x54, 0x79, 0x70, - 0x65, 0x12, 0x18, 0x0a, 0x14, 0x52, 0x45, 0x47, 0x49, 0x53, 0x54, 0x45, 0x52, 0x5f, 0x55, 0x4e, - 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x14, 0x0a, 0x10, 0x52, - 0x45, 0x47, 0x49, 0x53, 0x54, 0x45, 0x52, 0x5f, 0x53, 0x55, 0x43, 0x43, 0x45, 0x53, 0x53, 0x10, - 0x01, 0x12, 0x12, 0x0a, 0x0e, 0x52, 0x45, 0x47, 0x49, 0x53, 0x54, 0x45, 0x52, 0x5f, 0x45, 0x52, - 0x52, 0x4f, 0x52, 0x10, 0x02, 0x12, 0x13, 0x0a, 0x0f, 0x52, 0x45, 0x47, 0x49, 0x53, 0x54, 0x45, - 0x52, 0x5f, 0x44, 0x45, 0x4e, 0x49, 0x45, 0x44, 0x10, 0x03, 0x12, 0x13, 0x0a, 0x0f, 0x52, 0x45, - 0x47, 0x49, 0x53, 0x54, 0x45, 0x52, 0x5f, 0x45, 0x58, 0x49, 0x53, 0x54, 0x53, 0x10, 0x04, 0x22, - 0xa8, 0x01, 0x0a, 0x11, 0x53, 0x75, 0x62, 0x6d, 0x69, 0x74, 0x4a, 0x6f, 0x62, 0x52, 0x65, 0x73, - 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x1d, 0x0a, 0x0a, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, - 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x72, 0x65, 0x71, 0x75, 0x65, - 0x73, 0x74, 0x49, 0x64, 0x12, 0x15, 0x0a, 0x06, 0x6a, 0x6f, 0x62, 0x5f, 0x69, 0x64, 0x18, 0x02, - 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x6a, 0x6f, 0x62, 0x49, 0x64, 0x22, 0x5d, 0x0a, 0x0a, 0x52, - 0x65, 0x73, 0x75, 0x6c, 0x74, 0x54, 0x79, 0x70, 0x65, 0x12, 0x16, 0x0a, 0x12, 0x53, 0x55, 0x42, - 0x4d, 0x49, 0x54, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, - 0x00, 0x12, 0x12, 0x0a, 0x0e, 0x53, 0x55, 0x42, 0x4d, 0x49, 0x54, 0x5f, 0x53, 0x55, 0x43, 0x43, - 0x45, 0x53, 0x53, 0x10, 0x01, 0x12, 0x10, 0x0a, 0x0c, 0x53, 0x55, 0x42, 0x4d, 0x49, 0x54, 0x5f, - 0x45, 0x52, 0x52, 0x4f, 0x52, 0x10, 0x02, 0x12, 0x11, 0x0a, 0x0d, 0x53, 0x55, 0x42, 0x4d, 0x49, - 0x54, 0x5f, 0x44, 0x45, 0x4e, 0x49, 0x45, 0x44, 0x10, 0x03, 0x32, 0x9f, 0x03, 0x0a, 0x07, 0x53, - 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x6d, 0x0a, 0x08, 0x52, 0x65, 0x67, 0x69, 0x73, 0x74, - 0x65, 0x72, 0x12, 0x2f, 0x2e, 0x63, 0x6f, 0x6e, 0x76, 0x65, 0x72, 0x67, 0x65, 0x64, 0x63, 0x6f, - 0x6d, 0x70, 0x75, 0x74, 0x69, 0x6e, 0x67, 0x2e, 0x6f, 0x72, 0x67, 0x2e, 0x67, 0x72, 0x70, 0x63, - 0x2e, 0x76, 0x31, 0x2e, 0x52, 0x65, 0x67, 0x69, 0x73, 0x74, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, - 0x65, 0x73, 0x74, 0x1a, 0x30, 0x2e, 0x63, 0x6f, 0x6e, 0x76, 0x65, 0x72, 0x67, 0x65, 0x64, 0x63, - 0x6f, 0x6d, 0x70, 0x75, 0x74, 0x69, 0x6e, 0x67, 0x2e, 0x6f, 0x72, 0x67, 0x2e, 0x67, 0x72, 0x70, - 0x63, 0x2e, 0x76, 0x31, 0x2e, 0x52, 0x65, 0x67, 0x69, 0x73, 0x74, 0x65, 0x72, 0x52, 0x65, 0x73, - 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x67, 0x0a, 0x09, 0x53, 0x75, 0x62, 0x6d, 0x69, 0x74, 0x4a, - 0x6f, 0x62, 0x12, 0x27, 0x2e, 0x63, 0x6f, 0x6e, 0x76, 0x65, 0x72, 0x67, 0x65, 0x64, 0x63, 0x6f, - 0x6d, 0x70, 0x75, 0x74, 0x69, 0x6e, 0x67, 0x2e, 0x6f, 0x72, 0x67, 0x2e, 0x67, 0x72, 0x70, 0x63, - 0x2e, 0x76, 0x31, 0x2e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x31, 0x2e, 0x63, 0x6f, - 0x6e, 0x76, 0x65, 0x72, 0x67, 0x65, 0x64, 0x63, 0x6f, 0x6d, 0x70, 0x75, 0x74, 0x69, 0x6e, 0x67, - 0x2e, 0x6f, 0x72, 0x67, 0x2e, 0x67, 0x72, 0x70, 0x63, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x75, 0x62, - 0x6d, 0x69, 0x74, 0x4a, 0x6f, 0x62, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x5b, - 0x0a, 0x06, 0x53, 0x65, 0x72, 0x69, 0x61, 0x6c, 0x12, 0x27, 0x2e, 0x63, 0x6f, 0x6e, 0x76, 0x65, + 0x74, 0x61, 0x6d, 0x70, 0x52, 0x04, 0x73, 0x65, 0x6e, 0x74, 0x22, 0xcc, 0x01, 0x0a, 0x10, 0x53, + 0x75, 0x62, 0x6d, 0x69, 0x74, 0x4a, 0x6f, 0x62, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, + 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, + 0x61, 0x6d, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x63, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x18, 0x02, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x63, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x12, 0x14, 0x0a, + 0x05, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x74, 0x6f, + 0x6b, 0x65, 0x6e, 0x12, 0x14, 0x0a, 0x05, 0x6e, 0x6f, 0x64, 0x65, 0x73, 0x18, 0x04, 0x20, 0x01, + 0x28, 0x05, 0x52, 0x05, 0x6e, 0x6f, 0x64, 0x65, 0x73, 0x12, 0x14, 0x0a, 0x05, 0x74, 0x61, 0x73, + 0x6b, 0x73, 0x18, 0x05, 0x20, 0x01, 0x28, 0x05, 0x52, 0x05, 0x74, 0x61, 0x73, 0x6b, 0x73, 0x12, + 0x18, 0x0a, 0x07, 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x07, 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x12, 0x2e, 0x0a, 0x04, 0x73, 0x65, 0x6e, + 0x74, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, + 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, + 0x61, 0x6d, 0x70, 0x52, 0x04, 0x73, 0x65, 0x6e, 0x74, 0x22, 0x87, 0x02, 0x0a, 0x08, 0x52, 0x65, + 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x1d, 0x0a, 0x0a, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, + 0x74, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x72, 0x65, 0x71, 0x75, + 0x65, 0x73, 0x74, 0x49, 0x64, 0x12, 0x23, 0x0a, 0x0d, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, + 0x5f, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0c, 0x6d, 0x65, + 0x73, 0x73, 0x61, 0x67, 0x65, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x2d, 0x0a, 0x12, 0x6d, 0x65, + 0x73, 0x73, 0x61, 0x67, 0x65, 0x73, 0x5f, 0x70, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x65, 0x64, + 0x18, 0x03, 0x20, 0x01, 0x28, 0x03, 0x52, 0x11, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x73, + 0x50, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x65, 0x64, 0x12, 0x2d, 0x0a, 0x12, 0x70, 0x72, 0x6f, + 0x63, 0x65, 0x73, 0x73, 0x69, 0x6e, 0x67, 0x5f, 0x64, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x73, 0x18, + 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x11, 0x70, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x69, 0x6e, + 0x67, 0x44, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x73, 0x22, 0x59, 0x0a, 0x0a, 0x52, 0x65, 0x73, 0x75, + 0x6c, 0x74, 0x54, 0x79, 0x70, 0x65, 0x12, 0x1b, 0x0a, 0x17, 0x52, 0x45, 0x53, 0x55, 0x4c, 0x54, + 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, + 0x44, 0x10, 0x00, 0x12, 0x17, 0x0a, 0x13, 0x52, 0x45, 0x53, 0x55, 0x4c, 0x54, 0x5f, 0x54, 0x59, + 0x50, 0x45, 0x5f, 0x53, 0x55, 0x43, 0x43, 0x45, 0x53, 0x53, 0x10, 0x01, 0x12, 0x15, 0x0a, 0x11, + 0x52, 0x45, 0x53, 0x55, 0x4c, 0x54, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x45, 0x52, 0x52, 0x4f, + 0x52, 0x10, 0x02, 0x22, 0x98, 0x02, 0x0a, 0x10, 0x52, 0x65, 0x67, 0x69, 0x73, 0x74, 0x65, 0x72, + 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x1d, 0x0a, 0x0a, 0x72, 0x65, 0x71, 0x75, + 0x65, 0x73, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x72, 0x65, + 0x71, 0x75, 0x65, 0x73, 0x74, 0x49, 0x64, 0x12, 0x14, 0x0a, 0x05, 0x74, 0x6f, 0x6b, 0x65, 0x6e, + 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x12, 0x53, 0x0a, + 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x3b, 0x2e, + 0x63, 0x6f, 0x6e, 0x76, 0x65, 0x72, 0x67, 0x65, 0x64, 0x63, 0x6f, 0x6d, 0x70, 0x75, 0x74, 0x69, + 0x6e, 0x67, 0x2e, 0x6f, 0x72, 0x67, 0x2e, 0x67, 0x72, 0x70, 0x63, 0x2e, 0x76, 0x31, 0x2e, 0x52, + 0x65, 0x67, 0x69, 0x73, 0x74, 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x2e, + 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x54, 0x79, 0x70, 0x65, 0x52, 0x06, 0x73, 0x74, 0x61, 0x74, + 0x75, 0x73, 0x22, 0x7a, 0x0a, 0x0a, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x54, 0x79, 0x70, 0x65, + 0x12, 0x18, 0x0a, 0x14, 0x52, 0x45, 0x47, 0x49, 0x53, 0x54, 0x45, 0x52, 0x5f, 0x55, 0x4e, 0x53, + 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x14, 0x0a, 0x10, 0x52, 0x45, + 0x47, 0x49, 0x53, 0x54, 0x45, 0x52, 0x5f, 0x53, 0x55, 0x43, 0x43, 0x45, 0x53, 0x53, 0x10, 0x01, + 0x12, 0x12, 0x0a, 0x0e, 0x52, 0x45, 0x47, 0x49, 0x53, 0x54, 0x45, 0x52, 0x5f, 0x45, 0x52, 0x52, + 0x4f, 0x52, 0x10, 0x02, 0x12, 0x13, 0x0a, 0x0f, 0x52, 0x45, 0x47, 0x49, 0x53, 0x54, 0x45, 0x52, + 0x5f, 0x44, 0x45, 0x4e, 0x49, 0x45, 0x44, 0x10, 0x03, 0x12, 0x13, 0x0a, 0x0f, 0x52, 0x45, 0x47, + 0x49, 0x53, 0x54, 0x45, 0x52, 0x5f, 0x45, 0x58, 0x49, 0x53, 0x54, 0x53, 0x10, 0x04, 0x22, 0xfd, + 0x01, 0x0a, 0x11, 0x53, 0x75, 0x62, 0x6d, 0x69, 0x74, 0x4a, 0x6f, 0x62, 0x52, 0x65, 0x73, 0x70, + 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x1d, 0x0a, 0x0a, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x5f, + 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, + 0x74, 0x49, 0x64, 0x12, 0x14, 0x0a, 0x05, 0x6a, 0x6f, 0x62, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, + 0x28, 0x05, 0x52, 0x05, 0x6a, 0x6f, 0x62, 0x69, 0x64, 0x12, 0x54, 0x0a, 0x06, 0x73, 0x74, 0x61, + 0x74, 0x75, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x3c, 0x2e, 0x63, 0x6f, 0x6e, 0x76, + 0x65, 0x72, 0x67, 0x65, 0x64, 0x63, 0x6f, 0x6d, 0x70, 0x75, 0x74, 0x69, 0x6e, 0x67, 0x2e, 0x6f, + 0x72, 0x67, 0x2e, 0x67, 0x72, 0x70, 0x63, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x75, 0x62, 0x6d, 0x69, + 0x74, 0x4a, 0x6f, 0x62, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x2e, 0x52, 0x65, 0x73, + 0x75, 0x6c, 0x74, 0x54, 0x79, 0x70, 0x65, 0x52, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x22, + 0x5d, 0x0a, 0x0a, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x54, 0x79, 0x70, 0x65, 0x12, 0x16, 0x0a, + 0x12, 0x53, 0x55, 0x42, 0x4d, 0x49, 0x54, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, + 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x12, 0x0a, 0x0e, 0x53, 0x55, 0x42, 0x4d, 0x49, 0x54, 0x5f, + 0x53, 0x55, 0x43, 0x43, 0x45, 0x53, 0x53, 0x10, 0x01, 0x12, 0x10, 0x0a, 0x0c, 0x53, 0x55, 0x42, + 0x4d, 0x49, 0x54, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x10, 0x02, 0x12, 0x11, 0x0a, 0x0d, 0x53, + 0x55, 0x42, 0x4d, 0x49, 0x54, 0x5f, 0x44, 0x45, 0x4e, 0x49, 0x45, 0x44, 0x10, 0x03, 0x32, 0xa8, + 0x03, 0x0a, 0x07, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x6d, 0x0a, 0x08, 0x52, 0x65, + 0x67, 0x69, 0x73, 0x74, 0x65, 0x72, 0x12, 0x2f, 0x2e, 0x63, 0x6f, 0x6e, 0x76, 0x65, 0x72, 0x67, + 0x65, 0x64, 0x63, 0x6f, 0x6d, 0x70, 0x75, 0x74, 0x69, 0x6e, 0x67, 0x2e, 0x6f, 0x72, 0x67, 0x2e, + 0x67, 0x72, 0x70, 0x63, 0x2e, 0x76, 0x31, 0x2e, 0x52, 0x65, 0x67, 0x69, 0x73, 0x74, 0x65, 0x72, + 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x30, 0x2e, 0x63, 0x6f, 0x6e, 0x76, 0x65, 0x72, + 0x67, 0x65, 0x64, 0x63, 0x6f, 0x6d, 0x70, 0x75, 0x74, 0x69, 0x6e, 0x67, 0x2e, 0x6f, 0x72, 0x67, + 0x2e, 0x67, 0x72, 0x70, 0x63, 0x2e, 0x76, 0x31, 0x2e, 0x52, 0x65, 0x67, 0x69, 0x73, 0x74, 0x65, + 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x70, 0x0a, 0x09, 0x53, 0x75, 0x62, + 0x6d, 0x69, 0x74, 0x4a, 0x6f, 0x62, 0x12, 0x30, 0x2e, 0x63, 0x6f, 0x6e, 0x76, 0x65, 0x72, 0x67, + 0x65, 0x64, 0x63, 0x6f, 0x6d, 0x70, 0x75, 0x74, 0x69, 0x6e, 0x67, 0x2e, 0x6f, 0x72, 0x67, 0x2e, + 0x67, 0x72, 0x70, 0x63, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x75, 0x62, 0x6d, 0x69, 0x74, 0x4a, 0x6f, + 0x62, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x31, 0x2e, 0x63, 0x6f, 0x6e, 0x76, 0x65, 0x72, 0x67, 0x65, 0x64, 0x63, 0x6f, 0x6d, 0x70, 0x75, 0x74, 0x69, 0x6e, 0x67, 0x2e, 0x6f, 0x72, - 0x67, 0x2e, 0x67, 0x72, 0x70, 0x63, 0x2e, 0x76, 0x31, 0x2e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, - 0x74, 0x1a, 0x28, 0x2e, 0x63, 0x6f, 0x6e, 0x76, 0x65, 0x72, 0x67, 0x65, 0x64, 0x63, 0x6f, 0x6d, - 0x70, 0x75, 0x74, 0x69, 0x6e, 0x67, 0x2e, 0x6f, 0x72, 0x67, 0x2e, 0x67, 0x72, 0x70, 0x63, 0x2e, - 0x76, 0x31, 0x2e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x5f, 0x0a, 0x06, 0x53, - 0x74, 0x72, 0x65, 0x61, 0x6d, 0x12, 0x27, 0x2e, 0x63, 0x6f, 0x6e, 0x76, 0x65, 0x72, 0x67, 0x65, + 0x67, 0x2e, 0x67, 0x72, 0x70, 0x63, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x75, 0x62, 0x6d, 0x69, 0x74, + 0x4a, 0x6f, 0x62, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x5b, 0x0a, 0x06, 0x53, + 0x65, 0x72, 0x69, 0x61, 0x6c, 0x12, 0x27, 0x2e, 0x63, 0x6f, 0x6e, 0x76, 0x65, 0x72, 0x67, 0x65, 0x64, 0x63, 0x6f, 0x6d, 0x70, 0x75, 0x74, 0x69, 0x6e, 0x67, 0x2e, 0x6f, 0x72, 0x67, 0x2e, 0x67, 0x72, 0x70, 0x63, 0x2e, 0x76, 0x31, 0x2e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x28, 0x2e, 0x63, 0x6f, 0x6e, 0x76, 0x65, 0x72, 0x67, 0x65, 0x64, 0x63, 0x6f, 0x6d, 0x70, 0x75, 0x74, 0x69, 0x6e, 0x67, 0x2e, 0x6f, 0x72, 0x67, 0x2e, 0x67, 0x72, 0x70, 0x63, 0x2e, 0x76, 0x31, 0x2e, - 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x28, 0x01, 0x30, 0x01, 0x42, 0x33, 0x5a, 0x31, - 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x63, 0x6f, 0x6e, 0x76, 0x65, - 0x72, 0x67, 0x65, 0x64, 0x2d, 0x63, 0x6f, 0x6d, 0x70, 0x75, 0x74, 0x69, 0x6e, 0x67, 0x2f, 0x72, - 0x61, 0x69, 0x6e, 0x62, 0x6f, 0x77, 0x2f, 0x70, 0x6b, 0x67, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x76, - 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x5f, 0x0a, 0x06, 0x53, 0x74, 0x72, 0x65, + 0x61, 0x6d, 0x12, 0x27, 0x2e, 0x63, 0x6f, 0x6e, 0x76, 0x65, 0x72, 0x67, 0x65, 0x64, 0x63, 0x6f, + 0x6d, 0x70, 0x75, 0x74, 0x69, 0x6e, 0x67, 0x2e, 0x6f, 0x72, 0x67, 0x2e, 0x67, 0x72, 0x70, 0x63, + 0x2e, 0x76, 0x31, 0x2e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x28, 0x2e, 0x63, 0x6f, + 0x6e, 0x76, 0x65, 0x72, 0x67, 0x65, 0x64, 0x63, 0x6f, 0x6d, 0x70, 0x75, 0x74, 0x69, 0x6e, 0x67, + 0x2e, 0x6f, 0x72, 0x67, 0x2e, 0x67, 0x72, 0x70, 0x63, 0x2e, 0x76, 0x31, 0x2e, 0x52, 0x65, 0x73, + 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x28, 0x01, 0x30, 0x01, 0x42, 0x33, 0x5a, 0x31, 0x67, 0x69, 0x74, + 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x63, 0x6f, 0x6e, 0x76, 0x65, 0x72, 0x67, 0x65, + 0x64, 0x2d, 0x63, 0x6f, 0x6d, 0x70, 0x75, 0x74, 0x69, 0x6e, 0x67, 0x2f, 0x72, 0x61, 0x69, 0x6e, + 0x62, 0x6f, 0x77, 0x2f, 0x70, 0x6b, 0x67, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x76, 0x31, 0x62, 0x06, + 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( @@ -694,7 +815,7 @@ func file_api_proto_rawDescGZIP() []byte { } var file_api_proto_enumTypes = make([]protoimpl.EnumInfo, 3) -var file_api_proto_msgTypes = make([]protoimpl.MessageInfo, 7) +var file_api_proto_msgTypes = make([]protoimpl.MessageInfo, 8) var file_api_proto_goTypes = []interface{}{ (Response_ResultType)(0), // 0: convergedcomputing.org.grpc.v1.Response.ResultType (RegisterResponse_ResultType)(0), // 1: convergedcomputing.org.grpc.v1.RegisterResponse.ResultType @@ -702,33 +823,36 @@ var file_api_proto_goTypes = []interface{}{ (*Content)(nil), // 3: convergedcomputing.org.grpc.v1.Content (*Request)(nil), // 4: convergedcomputing.org.grpc.v1.Request (*RegisterRequest)(nil), // 5: convergedcomputing.org.grpc.v1.RegisterRequest - (*Response)(nil), // 6: convergedcomputing.org.grpc.v1.Response - (*RegisterResponse)(nil), // 7: convergedcomputing.org.grpc.v1.RegisterResponse - (*SubmitJobResponse)(nil), // 8: convergedcomputing.org.grpc.v1.SubmitJobResponse - nil, // 9: convergedcomputing.org.grpc.v1.Content.MetadataEntry - (*anypb.Any)(nil), // 10: google.protobuf.Any - (*timestamppb.Timestamp)(nil), // 11: google.protobuf.Timestamp + (*SubmitJobRequest)(nil), // 6: convergedcomputing.org.grpc.v1.SubmitJobRequest + (*Response)(nil), // 7: convergedcomputing.org.grpc.v1.Response + (*RegisterResponse)(nil), // 8: convergedcomputing.org.grpc.v1.RegisterResponse + (*SubmitJobResponse)(nil), // 9: convergedcomputing.org.grpc.v1.SubmitJobResponse + nil, // 10: convergedcomputing.org.grpc.v1.Content.MetadataEntry + (*anypb.Any)(nil), // 11: google.protobuf.Any + (*timestamppb.Timestamp)(nil), // 12: google.protobuf.Timestamp } var file_api_proto_depIdxs = []int32{ - 10, // 0: convergedcomputing.org.grpc.v1.Content.data:type_name -> google.protobuf.Any - 9, // 1: convergedcomputing.org.grpc.v1.Content.metadata:type_name -> convergedcomputing.org.grpc.v1.Content.MetadataEntry + 11, // 0: convergedcomputing.org.grpc.v1.Content.data:type_name -> google.protobuf.Any + 10, // 1: convergedcomputing.org.grpc.v1.Content.metadata:type_name -> convergedcomputing.org.grpc.v1.Content.MetadataEntry 3, // 2: convergedcomputing.org.grpc.v1.Request.content:type_name -> convergedcomputing.org.grpc.v1.Content - 11, // 3: convergedcomputing.org.grpc.v1.Request.sent:type_name -> google.protobuf.Timestamp - 11, // 4: convergedcomputing.org.grpc.v1.RegisterRequest.sent:type_name -> google.protobuf.Timestamp - 1, // 5: convergedcomputing.org.grpc.v1.RegisterResponse.status:type_name -> convergedcomputing.org.grpc.v1.RegisterResponse.ResultType - 5, // 6: convergedcomputing.org.grpc.v1.Service.Register:input_type -> convergedcomputing.org.grpc.v1.RegisterRequest - 4, // 7: convergedcomputing.org.grpc.v1.Service.SubmitJob:input_type -> convergedcomputing.org.grpc.v1.Request - 4, // 8: convergedcomputing.org.grpc.v1.Service.Serial:input_type -> convergedcomputing.org.grpc.v1.Request - 4, // 9: convergedcomputing.org.grpc.v1.Service.Stream:input_type -> convergedcomputing.org.grpc.v1.Request - 7, // 10: convergedcomputing.org.grpc.v1.Service.Register:output_type -> convergedcomputing.org.grpc.v1.RegisterResponse - 8, // 11: convergedcomputing.org.grpc.v1.Service.SubmitJob:output_type -> convergedcomputing.org.grpc.v1.SubmitJobResponse - 6, // 12: convergedcomputing.org.grpc.v1.Service.Serial:output_type -> convergedcomputing.org.grpc.v1.Response - 6, // 13: convergedcomputing.org.grpc.v1.Service.Stream:output_type -> convergedcomputing.org.grpc.v1.Response - 10, // [10:14] is the sub-list for method output_type - 6, // [6:10] is the sub-list for method input_type - 6, // [6:6] is the sub-list for extension type_name - 6, // [6:6] is the sub-list for extension extendee - 0, // [0:6] is the sub-list for field type_name + 12, // 3: convergedcomputing.org.grpc.v1.Request.sent:type_name -> google.protobuf.Timestamp + 12, // 4: convergedcomputing.org.grpc.v1.RegisterRequest.sent:type_name -> google.protobuf.Timestamp + 12, // 5: convergedcomputing.org.grpc.v1.SubmitJobRequest.sent:type_name -> google.protobuf.Timestamp + 1, // 6: convergedcomputing.org.grpc.v1.RegisterResponse.status:type_name -> convergedcomputing.org.grpc.v1.RegisterResponse.ResultType + 2, // 7: convergedcomputing.org.grpc.v1.SubmitJobResponse.status:type_name -> convergedcomputing.org.grpc.v1.SubmitJobResponse.ResultType + 5, // 8: convergedcomputing.org.grpc.v1.Service.Register:input_type -> convergedcomputing.org.grpc.v1.RegisterRequest + 6, // 9: convergedcomputing.org.grpc.v1.Service.SubmitJob:input_type -> convergedcomputing.org.grpc.v1.SubmitJobRequest + 4, // 10: convergedcomputing.org.grpc.v1.Service.Serial:input_type -> convergedcomputing.org.grpc.v1.Request + 4, // 11: convergedcomputing.org.grpc.v1.Service.Stream:input_type -> convergedcomputing.org.grpc.v1.Request + 8, // 12: convergedcomputing.org.grpc.v1.Service.Register:output_type -> convergedcomputing.org.grpc.v1.RegisterResponse + 9, // 13: convergedcomputing.org.grpc.v1.Service.SubmitJob:output_type -> convergedcomputing.org.grpc.v1.SubmitJobResponse + 7, // 14: convergedcomputing.org.grpc.v1.Service.Serial:output_type -> convergedcomputing.org.grpc.v1.Response + 7, // 15: convergedcomputing.org.grpc.v1.Service.Stream:output_type -> convergedcomputing.org.grpc.v1.Response + 12, // [12:16] is the sub-list for method output_type + 8, // [8:12] is the sub-list for method input_type + 8, // [8:8] is the sub-list for extension type_name + 8, // [8:8] is the sub-list for extension extendee + 0, // [0:8] is the sub-list for field type_name } func init() { file_api_proto_init() } @@ -774,7 +898,7 @@ func file_api_proto_init() { } } file_api_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*Response); i { + switch v := v.(*SubmitJobRequest); i { case 0: return &v.state case 1: @@ -786,7 +910,7 @@ func file_api_proto_init() { } } file_api_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*RegisterResponse); i { + switch v := v.(*Response); i { case 0: return &v.state case 1: @@ -798,6 +922,18 @@ func file_api_proto_init() { } } file_api_proto_msgTypes[5].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*RegisterResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_api_proto_msgTypes[6].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*SubmitJobResponse); i { case 0: return &v.state @@ -816,7 +952,7 @@ func file_api_proto_init() { GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: file_api_proto_rawDesc, NumEnums: 3, - NumMessages: 7, + NumMessages: 8, NumExtensions: 0, NumServices: 1, }, diff --git a/pkg/api/v1/api_grpc.pb.go b/pkg/api/v1/api_grpc.pb.go index ddcfe54..def2091 100644 --- a/pkg/api/v1/api_grpc.pb.go +++ b/pkg/api/v1/api_grpc.pb.go @@ -25,7 +25,7 @@ type ServiceClient interface { // Register cluster - request to register a new cluster Register(ctx context.Context, in *RegisterRequest, opts ...grpc.CallOption) (*RegisterResponse, error) // Job Submission - request for submitting a job to a named cluster - SubmitJob(ctx context.Context, in *Request, opts ...grpc.CallOption) (*SubmitJobResponse, error) + SubmitJob(ctx context.Context, in *SubmitJobRequest, opts ...grpc.CallOption) (*SubmitJobResponse, error) // TESTING ENDPOINTS // Serial checks the connectivity and response time of the service. Serial(ctx context.Context, in *Request, opts ...grpc.CallOption) (*Response, error) @@ -51,7 +51,7 @@ func (c *serviceClient) Register(ctx context.Context, in *RegisterRequest, opts return out, nil } -func (c *serviceClient) SubmitJob(ctx context.Context, in *Request, opts ...grpc.CallOption) (*SubmitJobResponse, error) { +func (c *serviceClient) SubmitJob(ctx context.Context, in *SubmitJobRequest, opts ...grpc.CallOption) (*SubmitJobResponse, error) { out := new(SubmitJobResponse) err := c.cc.Invoke(ctx, "/convergedcomputing.org.grpc.v1.Service/SubmitJob", in, out, opts...) if err != nil { @@ -107,7 +107,7 @@ type ServiceServer interface { // Register cluster - request to register a new cluster Register(context.Context, *RegisterRequest) (*RegisterResponse, error) // Job Submission - request for submitting a job to a named cluster - SubmitJob(context.Context, *Request) (*SubmitJobResponse, error) + SubmitJob(context.Context, *SubmitJobRequest) (*SubmitJobResponse, error) // TESTING ENDPOINTS // Serial checks the connectivity and response time of the service. Serial(context.Context, *Request) (*Response, error) @@ -124,7 +124,7 @@ type UnimplementedServiceServer struct { func (UnimplementedServiceServer) Register(context.Context, *RegisterRequest) (*RegisterResponse, error) { return nil, status.Errorf(codes.Unimplemented, "method Register not implemented") } -func (UnimplementedServiceServer) SubmitJob(context.Context, *Request) (*SubmitJobResponse, error) { +func (UnimplementedServiceServer) SubmitJob(context.Context, *SubmitJobRequest) (*SubmitJobResponse, error) { return nil, status.Errorf(codes.Unimplemented, "method SubmitJob not implemented") } func (UnimplementedServiceServer) Serial(context.Context, *Request) (*Response, error) { @@ -165,7 +165,7 @@ func _Service_Register_Handler(srv interface{}, ctx context.Context, dec func(in } func _Service_SubmitJob_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { - in := new(Request) + in := new(SubmitJobRequest) if err := dec(in); err != nil { return nil, err } @@ -177,7 +177,7 @@ func _Service_SubmitJob_Handler(srv interface{}, ctx context.Context, dec func(i FullMethod: "/convergedcomputing.org.grpc.v1.Service/SubmitJob", } handler := func(ctx context.Context, req interface{}) (interface{}, error) { - return srv.(ServiceServer).SubmitJob(ctx, req.(*Request)) + return srv.(ServiceServer).SubmitJob(ctx, req.(*SubmitJobRequest)) } return interceptor(ctx, in, info, handler) } diff --git a/pkg/client/client.go b/pkg/client/client.go index f658a39..0e7a97a 100644 --- a/pkg/client/client.go +++ b/pkg/client/client.go @@ -5,7 +5,7 @@ import ( "log" pb "github.com/converged-computing/rainbow/pkg/api/v1" - "github.com/converged-computing/rainbow/pkg/provider" + "github.com/converged-computing/rainbow/pkg/types" "github.com/pkg/errors" "google.golang.org/grpc" "google.golang.org/grpc/connectivity" @@ -24,8 +24,9 @@ var _ Client = (*RainbowClient)(nil) // Client interface defines functions required for a valid client type Client interface { Serial(ctx context.Context, message string) (string, error) - Stream(ctx context.Context, it provider.MessageIterator) error + Stream(ctx context.Context, it types.MessageIterator) error Register(ctx context.Context, clusterName, secret string) (*pb.RegisterResponse, error) + SubmitJob(ctx context.Context, job types.JobSpec, cluster, token string) (*pb.SubmitJobResponse, error) } // NewClient creates a new RainbowClient diff --git a/pkg/client/endpoint.go b/pkg/client/endpoint.go index 6890077..d74aacf 100644 --- a/pkg/client/endpoint.go +++ b/pkg/client/endpoint.go @@ -2,9 +2,11 @@ package client import ( "context" + "fmt" "time" pb "github.com/converged-computing/rainbow/pkg/api/v1" + "github.com/converged-computing/rainbow/pkg/types" "github.com/pkg/errors" ts "google.golang.org/protobuf/types/known/timestamppb" ) @@ -14,18 +16,57 @@ type RegisterRequest struct { Secret string } +// SubmitJob submits a job to a named cluster. +// The token specific to the cluster is required +func (c *RainbowClient) SubmitJob( + ctx context.Context, + job types.JobSpec, + cluster string, + token string, +) (*pb.SubmitJobResponse, error) { + + response := &pb.SubmitJobResponse{} + + // First validate the job + if job.Nodes < 1 { + return response, fmt.Errorf("nodes must be greater than 1") + } + if !c.Connected() { + return response, errors.New("client is not connected") + } + if cluster == "" { + return response, errors.New("cluster name is required") + } + + // Contact the server... + ctx, cancel := context.WithTimeout(ctx, time.Second) + defer cancel() + + // Validate that the cluster exists, and we have the right token. + // The response is the same either way - not found does not reveal + // additional information to the client trying to find it + response, err := c.service.SubmitJob(ctx, &pb.SubmitJobRequest{ + Name: job.Name, + Token: token, + Nodes: job.Nodes, + Tasks: job.Tasks, + Cluster: cluster, + Command: job.Command, + Sent: ts.Now(), + }) + return response, err +} + // Register makes a request to register a new cluster func (c *RainbowClient) Register( ctx context.Context, - clusterName string, + cluster string, secret string, ) (*pb.RegisterResponse, error) { response := &pb.RegisterResponse{} - - // TODO add secret requirement when server has database - if clusterName == "" { - return response, errors.New("message is required") + if cluster == "" { + return response, errors.New("cluster is required") } if !c.Connected() { return response, errors.New("client is not connected") @@ -37,7 +78,7 @@ func (c *RainbowClient) Register( // Hit the register endpoint response, err := c.service.Register(ctx, &pb.RegisterRequest{ - Name: clusterName, + Name: cluster, Secret: secret, Sent: ts.Now(), }) diff --git a/pkg/client/stream.go b/pkg/client/stream.go index 8bd32c3..79a738b 100644 --- a/pkg/client/stream.go +++ b/pkg/client/stream.go @@ -5,16 +5,16 @@ import ( "log" pb "github.com/converged-computing/rainbow/pkg/api/v1" - "github.com/converged-computing/rainbow/pkg/provider" + "github.com/converged-computing/rainbow/pkg/types" "github.com/google/uuid" "github.com/pkg/errors" anypb "google.golang.org/protobuf/types/known/anypb" - tspb "google.golang.org/protobuf/types/known/timestamppb" - wrbp "google.golang.org/protobuf/types/known/wrapperspb" + ts "google.golang.org/protobuf/types/known/timestamppb" + wrapper "google.golang.org/protobuf/types/known/wrapperspb" ) // Stream sends a message to the server and receives the response. -func (c *RainbowClient) Stream(ctx context.Context, it provider.MessageIterator) error { +func (c *RainbowClient) Stream(ctx context.Context, it types.MessageIterator) error { if it == nil { return errors.New("message provider is required") } @@ -41,7 +41,7 @@ func (c *RainbowClient) Stream(ctx context.Context, it provider.MessageIterator) } // create message with wrapper - a, err := anypb.New(wrbp.String(it.Next())) + a, err := anypb.New(wrapper.String(it.Next())) if err != nil { return errors.Wrap(err, "unable to create message") } @@ -52,7 +52,7 @@ func (c *RainbowClient) Stream(ctx context.Context, it provider.MessageIterator) Id: uuid.New().String(), Data: a, }, - Sent: tspb.Now(), + Sent: ts.Now(), }); err != nil { return errors.Wrap(err, "failed to send a message") } diff --git a/pkg/provider/message.go b/pkg/provider/message.go index 930a336..09b733a 100644 --- a/pkg/provider/message.go +++ b/pkg/provider/message.go @@ -1,4 +1,4 @@ -package provider +package types import ( "fmt" diff --git a/pkg/server/database.go b/pkg/server/database.go index b815723..39814ea 100644 --- a/pkg/server/database.go +++ b/pkg/server/database.go @@ -4,6 +4,7 @@ import ( "fmt" pb "github.com/converged-computing/rainbow/pkg/api/v1" + "github.com/converged-computing/rainbow/pkg/utils" "github.com/google/uuid" _ "github.com/mattn/go-sqlite3" @@ -16,6 +17,21 @@ type Database struct { filepath string } +// Database types to serialize back into +type Cluster struct { + Name string + Secret string +} + +type Job struct { + Id int32 + Cluster string + Name string + Nodes int32 + Tasks int32 + Command string +} + // cleanup removes the filepath func (db *Database) cleanup() { // Delete a previous database that exists @@ -72,7 +88,7 @@ func (db *Database) RegisterCluster(name string) (pb.RegisterResponse_ResultType count, err := result.RowsAffected() // Debugging extra for now - fmt.Printf("%s: (%d)\n", query, count) + log.Printf("%s: (%d)\n", query, count) // Case 1: already exists if count > 0 { @@ -81,13 +97,13 @@ func (db *Database) RegisterCluster(name string) (pb.RegisterResponse_ResultType // Generate a "secret" token, lol token := uuid.New().String() - query = fmt.Sprintf("INSERT into clusters VALUES (\"%s\", \"%s\")", name, token) + query = fmt.Sprintf("INSERT into clusters (name, secret) VALUES (\"%s\", \"%s\")", name, token) result, err = conn.Exec(query) if err != nil { return 2, "", err } count, err = result.RowsAffected() - fmt.Printf("%s: (%d)\n", query, count) + log.Printf("%s: (%d)\n", query, count) // REGISTER_SUCCESS if count > 0 { @@ -98,6 +114,92 @@ func (db *Database) RegisterCluster(name string) (pb.RegisterResponse_ResultType return 2, "", err } +// SubmitJob adds the job to the database +// SUBMIT_UNSPECIFIED = 0; +// SUBMIT_SUCCESS = 1; +// SUBMIT_ERROR = 2; +// SUBMIT_DENIED = 3; +func (db *Database) SubmitJob(job *pb.SubmitJobRequest, cluster *Cluster) (pb.SubmitJobResponse_ResultType, int32, error) { + var jobid int32 + conn, err := db.connect() + if err != nil { + return 0, jobid, err + } + defer conn.Close() + + // Generate a "secret" token, lol + fields := "(cluster, name, nodes, tasks, command)" + values := fmt.Sprintf("(\"%s\", \"%s\",\"%d\",\"%d\",\"%s\")", cluster.Name, job.Name, job.Nodes, job.Tasks, job.Command) + + // Submit the query to get the global id (jobid, not submit yet) + query := fmt.Sprintf("INSERT into jobs %s VALUES %s", fields, values) + + // Since we want to get a result back, we use query + statement, err := conn.Prepare(query) + if err != nil { + return 2, jobid, err + } + + // We expect only one job + rows, err := statement.Query() + if err != nil { + return 2, jobid, err + } + + // Unwrap into job + j := Job{} + for rows.Next() { + err := rows.Scan(&j.Id, &j.Cluster, &j.Name, &j.Nodes, &j.Tasks, &j.Command) + if err != nil { + return 2, jobid, err + } + } + // Success + return 1, j.Id, nil +} + +// GetCluster gets a cluster if it exists AND the token for it is valid +func (db *Database) GetCluster(name, token string) (*Cluster, error) { + + // Connect! + conn, err := db.connect() + if err != nil { + return nil, err + } + defer conn.Close() + + // First determine if it exists + query := fmt.Sprintf("SELECT * from clusters WHERE name LIKE \"%s\" LIMIT 1", name) + // Since we want to get a result back, we use query + statement, err := conn.Prepare(query) + if err != nil { + return nil, err + } + + // Only allow one result, one cluster + rows, err := statement.Query() + if err != nil { + return nil, err + } + + // Unwrap result into cluster + cluster := Cluster{} + for rows.Next() { + err := rows.Scan(&cluster.Name, &cluster.Secret) + if err != nil { + return nil, err + } + } + + // Validate the name and token + if cluster.Name == "" || cluster.Secret != token { + return nil, fmt.Errorf("request denied") + } + // Debugging extra for now + log.Printf("%s: %s\n", query, cluster.Name) + return &cluster, nil +} + // create the database func (db *Database) createTables() error { @@ -113,13 +215,17 @@ func (db *Database) createTables() error { CREATE TABLE clusters ( name TEXT NOT NULL PRIMARY KEY, secret TEXT - );` + ); + ` createJobsTableSQL := ` CREATE TABLE jobs ( idJob integer NOT NULL PRIMARY KEY AUTOINCREMENT, - jobspec TEXT, cluster TEXT, + name TEXT, + nodes integer, + tasks integer, + command TEXT, FOREIGN KEY(cluster) REFERENCES clusters(name) );` @@ -148,15 +254,18 @@ func initDatabase(filepath string, cleanup bool) (*Database, error) { db.cleanup() } - // Create the database - err := db.create() + // If we haven't created yet or cleaned up + exists, err := utils.PathExists(db.filepath) if err != nil { return nil, err } - - if err != nil { - return nil, err + if !exists { + // Create the database + err := db.create() + if err != nil { + return nil, err + } + err = db.createTables() } - err = db.createTables() return &db, err } diff --git a/pkg/server/endpoint.go b/pkg/server/endpoint.go index cfc5471..4994fe3 100644 --- a/pkg/server/endpoint.go +++ b/pkg/server/endpoint.go @@ -31,6 +31,34 @@ func (s *Server) Register(_ context.Context, in *pb.RegisterRequest) (*pb.Regist }, err } +// SubmitJob submits a job to a specific cluster, or adds an entry to the database +func (s *Server) SubmitJob(_ context.Context, in *pb.SubmitJobRequest) (*pb.SubmitJobResponse, error) { + if in == nil { + return nil, errors.New("request is required") + } + + // Nogo without a token + if in.Token == "" { + return nil, errors.New("a cluster token is required") + } + + // Get the token for the cluster (if it exists, same response either way) + // woooomp wommmmp! + cluster, err := s.db.GetCluster(in.Cluster, in.Token) + if err != nil { + return nil, err + } + + // Convert data to string, should be the cluster name + // TODO make this better, I'm sure there is a better way + log.Printf("📝️ received job %s for cluster %s", in.Name, cluster.Name) + status, jobid, err := s.db.SubmitJob(in, cluster) + return &pb.SubmitJobResponse{ + Status: status, + Jobid: jobid, + }, err +} + // TEST ENDPOINTS ------------------------------------------------ // Stream implements the Stream method of the Service. func (s *Server) Stream(stream pb.Service_StreamServer) error { diff --git a/pkg/server/server.go b/pkg/server/server.go index db9c02d..b8dec3e 100644 --- a/pkg/server/server.go +++ b/pkg/server/server.go @@ -102,6 +102,7 @@ func (s *Server) Stop() { } } +// Start the server func (s *Server) Start(ctx context.Context, address string) error { // Create a listener on the specified address. lis, err := net.Listen(protocol, address) @@ -111,6 +112,7 @@ func (s *Server) Start(ctx context.Context, address string) error { return s.serve(ctx, lis) } +// serve is the main function to ensure the server is listening, etc. func (s *Server) serve(_ context.Context, lis net.Listener) error { if lis == nil { return errors.New("listener is required") diff --git a/pkg/types/job.go b/pkg/types/job.go new file mode 100644 index 0000000..7d741be --- /dev/null +++ b/pkg/types/job.go @@ -0,0 +1,9 @@ +package types + +// JobSpec holds basic metadata about a job +type JobSpec struct { + Name string + Command string + Nodes int32 + Tasks int32 +} diff --git a/pkg/types/message.go b/pkg/types/message.go new file mode 100644 index 0000000..09b733a --- /dev/null +++ b/pkg/types/message.go @@ -0,0 +1,31 @@ +package types + +import ( + "fmt" + "sync/atomic" +) + +var ( + _ MessageIterator = (*CountedMessageProvider)(nil) + MockedMessageProvider MessageIterator = &CountedMessageProvider{} +) + +// MessageIterator is an interface that defines the behavior of a stream iterator. +type MessageIterator interface { + Next() string + HasNext() bool +} + +// CountedMessageProvider is a simple message provider that generates a message with a counter. +type CountedMessageProvider struct { + counter atomic.Uint64 // counter for messages +} + +func (p *CountedMessageProvider) HasNext() bool { + return true +} + +func (p *CountedMessageProvider) Next() string { + p.counter.Add(1) + return fmt.Sprintf("message number %d", p.counter.Load()) +} diff --git a/pkg/types/version.go b/pkg/types/version.go new file mode 100644 index 0000000..cd34d7b --- /dev/null +++ b/pkg/types/version.go @@ -0,0 +1,20 @@ +package types + +import "fmt" + +const ( + // VersionMajor is for an API incompatible changes + VersionMajor = 0 + + // VersionMinor is for functionality in a backwards-compatible manner + VersionMinor = 1 + + // VersionPatch is for backwards-compatible bug fixes + VersionPatch = 0 + + // VersionDraft indicates development branch. Releases will be empty string. + VersionDraft = "-draft" +) + +// Version is the specification version that the package types support. +var Version = fmt.Sprintf("%d.%d.%d%s", VersionMajor, VersionMinor, VersionPatch, VersionDraft) diff --git a/pkg/utils/utils.go b/pkg/utils/utils.go new file mode 100644 index 0000000..367ed06 --- /dev/null +++ b/pkg/utils/utils.go @@ -0,0 +1,19 @@ +package utils + +import ( + "errors" + "fmt" + "os" +) + +// PathExists determines if a path exists +func PathExists(path string) (bool, error) { + _, err := os.Stat(path) + if err != nil { + if errors.Is(err, os.ErrNotExist) { + return false, nil + } + return true, fmt.Errorf("warning: exists but another error happened (debug): %s", err) + } + return true, nil +}