API for getting supported job types from the Manager
Not yet hooked up to the job compiler, only reports one hard-coded job type.
This commit is contained in:
parent
7728c072ae
commit
b605330c57
@ -1,3 +1,4 @@
|
|||||||
|
// Package api_impl implements the OpenAPI API from pkg/api/flamenco-manager.yaml.
|
||||||
package api_impl
|
package api_impl
|
||||||
|
|
||||||
/* ***** BEGIN GPL LICENSE BLOCK *****
|
/* ***** BEGIN GPL LICENSE BLOCK *****
|
||||||
@ -21,11 +22,7 @@ package api_impl
|
|||||||
* ***** END GPL LICENSE BLOCK ***** */
|
* ***** END GPL LICENSE BLOCK ***** */
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"net/http"
|
|
||||||
|
|
||||||
"github.com/google/uuid"
|
|
||||||
"github.com/labstack/echo/v4"
|
"github.com/labstack/echo/v4"
|
||||||
"github.com/rs/zerolog/log"
|
|
||||||
"gitlab.com/blender/flamenco-goja-test/pkg/api"
|
"gitlab.com/blender/flamenco-goja-test/pkg/api"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -38,47 +35,6 @@ func NewFlamenco() *Flamenco {
|
|||||||
return &Flamenco{}
|
return &Flamenco{}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (f *Flamenco) RegisterWorker(e echo.Context) error {
|
|
||||||
remoteIP := e.RealIP()
|
|
||||||
|
|
||||||
logger := log.With().
|
|
||||||
Str("ip", remoteIP).
|
|
||||||
Logger()
|
|
||||||
|
|
||||||
var req api.RegisterWorkerJSONBody
|
|
||||||
err := e.Bind(&req)
|
|
||||||
if err != nil {
|
|
||||||
logger.Warn().Err(err).Msg("bad request received")
|
|
||||||
return sendAPIError(e, http.StatusBadRequest, "invalid format")
|
|
||||||
}
|
|
||||||
|
|
||||||
logger.Info().Str("nickname", req.Nickname).Msg("registering new worker")
|
|
||||||
|
|
||||||
return e.JSON(http.StatusOK, &api.RegisteredWorker{
|
|
||||||
Id: uuid.New().String(),
|
|
||||||
Nickname: req.Nickname,
|
|
||||||
Platform: req.Platform,
|
|
||||||
Address: remoteIP,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
func (f *Flamenco) ScheduleTask(e echo.Context) error {
|
|
||||||
return e.JSON(http.StatusOK, &api.AssignedTask{
|
|
||||||
Id: uuid.New().String(),
|
|
||||||
Commands: []api.Command{
|
|
||||||
{"echo", echo.Map{"payload": "Simon says \"Shaders!\""}},
|
|
||||||
{"blender", echo.Map{"blender_cmd": "/shared/bin/blender"}},
|
|
||||||
},
|
|
||||||
Job: uuid.New().String(),
|
|
||||||
JobPriority: 50,
|
|
||||||
JobType: "blender-render",
|
|
||||||
Name: "A1032",
|
|
||||||
Priority: 50,
|
|
||||||
Status: "active",
|
|
||||||
TaskType: "blender-render",
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
// sendPetstoreError wraps sending of an error in the Error format, and
|
// sendPetstoreError wraps sending of an error in the Error format, and
|
||||||
// handling the failure to marshal that.
|
// handling the failure to marshal that.
|
||||||
func sendAPIError(e echo.Context, code int, message string) error {
|
func sendAPIError(e echo.Context, code int, message string) error {
|
||||||
|
78
internal/manager/api_impl/job_compiler.go
Normal file
78
internal/manager/api_impl/job_compiler.go
Normal file
@ -0,0 +1,78 @@
|
|||||||
|
package api_impl
|
||||||
|
|
||||||
|
/* ***** BEGIN GPL LICENSE BLOCK *****
|
||||||
|
*
|
||||||
|
* Original Code Copyright (C) 2022 Blender Foundation.
|
||||||
|
*
|
||||||
|
* This file is part of Flamenco.
|
||||||
|
*
|
||||||
|
* Flamenco is free software: you can redistribute it and/or modify it under
|
||||||
|
* the terms of the GNU General Public License as published by the Free Software
|
||||||
|
* Foundation, either version 3 of the License, or (at your option) any later
|
||||||
|
* version.
|
||||||
|
*
|
||||||
|
* Flamenco is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||||
|
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
|
||||||
|
* A PARTICULAR PURPOSE. See the GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License along with
|
||||||
|
* Flamenco. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*
|
||||||
|
* ***** END GPL LICENSE BLOCK ***** */
|
||||||
|
|
||||||
|
import (
|
||||||
|
"net/http"
|
||||||
|
|
||||||
|
"github.com/labstack/echo/v4"
|
||||||
|
"gitlab.com/blender/flamenco-goja-test/pkg/api"
|
||||||
|
)
|
||||||
|
|
||||||
|
func (f *Flamenco) GetJobTypes(e echo.Context) error {
|
||||||
|
// Some helper functions because Go doesn't allow taking the address of a literal.
|
||||||
|
defaultString := func(s string) *interface{} {
|
||||||
|
var iValue interface{}
|
||||||
|
iValue = s
|
||||||
|
return &iValue
|
||||||
|
}
|
||||||
|
defaultInt32 := func(i int32) *interface{} {
|
||||||
|
var iValue interface{}
|
||||||
|
iValue = i
|
||||||
|
return &iValue
|
||||||
|
}
|
||||||
|
defaultBool := func(b bool) *interface{} {
|
||||||
|
var iValue interface{}
|
||||||
|
iValue = b
|
||||||
|
return &iValue
|
||||||
|
}
|
||||||
|
boolPtr := func(b bool) *bool {
|
||||||
|
return &b
|
||||||
|
}
|
||||||
|
choicesStr := func(choices ...string) *[]string {
|
||||||
|
return &choices
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: dynamically build based on the actually registered job types.
|
||||||
|
types := api.AvailableJobTypes{
|
||||||
|
JobTypes: []api.AvailableJobType{{
|
||||||
|
Name: "simple-blender-render",
|
||||||
|
Settings: []api.AvailableJobSetting{
|
||||||
|
{Key: "blender_cmd", Type: "string", Default: defaultString("{blender}")},
|
||||||
|
{Key: "chunk_size", Type: "int32", Default: defaultInt32(1)},
|
||||||
|
{Key: "frames", Type: "string", Required: boolPtr(true)},
|
||||||
|
{Key: "render_output", Type: "string", Required: boolPtr(true)},
|
||||||
|
{Key: "fps", Type: "int32"},
|
||||||
|
{Key: "extract_audio", Type: "bool", Default: defaultBool(true)},
|
||||||
|
{Key: "images_or_video",
|
||||||
|
Type: "string",
|
||||||
|
Required: boolPtr(true),
|
||||||
|
Choices: choicesStr("images", "video"),
|
||||||
|
Visible: boolPtr(false),
|
||||||
|
},
|
||||||
|
{Key: "format", Type: "string", Required: boolPtr(true)},
|
||||||
|
{Key: "output_file_extension", Type: "string", Required: boolPtr(true)},
|
||||||
|
},
|
||||||
|
}},
|
||||||
|
}
|
||||||
|
|
||||||
|
return e.JSON(http.StatusOK, &types)
|
||||||
|
}
|
73
internal/manager/api_impl/workers.go
Normal file
73
internal/manager/api_impl/workers.go
Normal file
@ -0,0 +1,73 @@
|
|||||||
|
package api_impl
|
||||||
|
|
||||||
|
/* ***** BEGIN GPL LICENSE BLOCK *****
|
||||||
|
*
|
||||||
|
* Original Code Copyright (C) 2022 Blender Foundation.
|
||||||
|
*
|
||||||
|
* This file is part of Flamenco.
|
||||||
|
*
|
||||||
|
* Flamenco is free software: you can redistribute it and/or modify it under
|
||||||
|
* the terms of the GNU General Public License as published by the Free Software
|
||||||
|
* Foundation, either version 3 of the License, or (at your option) any later
|
||||||
|
* version.
|
||||||
|
*
|
||||||
|
* Flamenco is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||||
|
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
|
||||||
|
* A PARTICULAR PURPOSE. See the GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License along with
|
||||||
|
* Flamenco. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*
|
||||||
|
* ***** END GPL LICENSE BLOCK ***** */
|
||||||
|
|
||||||
|
import (
|
||||||
|
"net/http"
|
||||||
|
|
||||||
|
"github.com/google/uuid"
|
||||||
|
"github.com/labstack/echo/v4"
|
||||||
|
"github.com/rs/zerolog/log"
|
||||||
|
|
||||||
|
"gitlab.com/blender/flamenco-goja-test/pkg/api"
|
||||||
|
)
|
||||||
|
|
||||||
|
func (f *Flamenco) RegisterWorker(e echo.Context) error {
|
||||||
|
remoteIP := e.RealIP()
|
||||||
|
|
||||||
|
logger := log.With().
|
||||||
|
Str("ip", remoteIP).
|
||||||
|
Logger()
|
||||||
|
|
||||||
|
var req api.RegisterWorkerJSONBody
|
||||||
|
err := e.Bind(&req)
|
||||||
|
if err != nil {
|
||||||
|
logger.Warn().Err(err).Msg("bad request received")
|
||||||
|
return sendAPIError(e, http.StatusBadRequest, "invalid format")
|
||||||
|
}
|
||||||
|
|
||||||
|
logger.Info().Str("nickname", req.Nickname).Msg("registering new worker")
|
||||||
|
|
||||||
|
return e.JSON(http.StatusOK, &api.RegisteredWorker{
|
||||||
|
Id: uuid.New().String(),
|
||||||
|
Nickname: req.Nickname,
|
||||||
|
Platform: req.Platform,
|
||||||
|
Address: remoteIP,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func (f *Flamenco) ScheduleTask(e echo.Context) error {
|
||||||
|
return e.JSON(http.StatusOK, &api.AssignedTask{
|
||||||
|
Id: uuid.New().String(),
|
||||||
|
Commands: []api.Command{
|
||||||
|
{"echo", echo.Map{"payload": "Simon says \"Shaders!\""}},
|
||||||
|
{"blender", echo.Map{"blender_cmd": "/shared/bin/blender"}},
|
||||||
|
},
|
||||||
|
Job: uuid.New().String(),
|
||||||
|
JobPriority: 50,
|
||||||
|
JobType: "blender-render",
|
||||||
|
Name: "A1032",
|
||||||
|
Priority: 50,
|
||||||
|
Status: "active",
|
||||||
|
TaskType: "blender-render",
|
||||||
|
User: "",
|
||||||
|
})
|
||||||
|
}
|
@ -60,6 +60,20 @@ paths:
|
|||||||
application/json:
|
application/json:
|
||||||
schema: {$ref: "#/components/schemas/SecurityError"}
|
schema: {$ref: "#/components/schemas/SecurityError"}
|
||||||
|
|
||||||
|
/api/jobs/types:
|
||||||
|
summary: Available Flamenco job types.
|
||||||
|
get:
|
||||||
|
operationId: getJobTypes
|
||||||
|
summary: Get list of job types and their parameters.
|
||||||
|
tags: [jobs]
|
||||||
|
responses:
|
||||||
|
"200":
|
||||||
|
description: Available job types
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema: {$ref: "#/components/schemas/AvailableJobTypes"}
|
||||||
|
|
||||||
|
|
||||||
tags:
|
tags:
|
||||||
- name: worker
|
- name: worker
|
||||||
description: API for Flamenco Workers to communicate with Flamenco Manager.
|
description: API for Flamenco Workers to communicate with Flamenco Manager.
|
||||||
@ -126,6 +140,57 @@ components:
|
|||||||
settings: {type: object}
|
settings: {type: object}
|
||||||
required: [name, settings]
|
required: [name, settings]
|
||||||
|
|
||||||
|
AvailableJobTypes:
|
||||||
|
type: object
|
||||||
|
description: List of job types supported by this Manager.
|
||||||
|
properties:
|
||||||
|
"job_types":
|
||||||
|
type: array
|
||||||
|
items: {$ref: "#/components/schemas/AvailableJobType"}
|
||||||
|
required: [job_types]
|
||||||
|
|
||||||
|
AvailableJobType:
|
||||||
|
type: object
|
||||||
|
description: Job type supported by this Manager, and its parameters.
|
||||||
|
properties:
|
||||||
|
"name": {type: string}
|
||||||
|
"settings":
|
||||||
|
type: array
|
||||||
|
items: {$ref: "#/components/schemas/AvailableJobSetting"}
|
||||||
|
required: [name, settings]
|
||||||
|
|
||||||
|
AvailableJobSetting:
|
||||||
|
type: object
|
||||||
|
description: Single setting of a Job types.
|
||||||
|
properties:
|
||||||
|
"key":
|
||||||
|
type: string
|
||||||
|
description: Identifier for the setting, must be unique within the job type.
|
||||||
|
"type": {$ref: "#/components/schemas/AvailableJobSettingType"}
|
||||||
|
"choices":
|
||||||
|
description: When given, limit the valid values to these choices. Only usable with string type.
|
||||||
|
type: array
|
||||||
|
items: {type: string}
|
||||||
|
"default":
|
||||||
|
description: The default value shown to the user when determining this setting.
|
||||||
|
"visible":
|
||||||
|
type: boolean
|
||||||
|
description: >
|
||||||
|
Whether to show this setting in the UI of a job submitter (like a
|
||||||
|
Blender add-on). Set to `false` when it is an internal setting that
|
||||||
|
shouldn't be shown to end users.
|
||||||
|
default: true
|
||||||
|
"required":
|
||||||
|
type: boolean
|
||||||
|
description: Whether to immediately reject a job definition, of this type, without this particular setting.
|
||||||
|
default: false
|
||||||
|
required: [key, type]
|
||||||
|
|
||||||
|
AvailableJobSettingType:
|
||||||
|
type: string
|
||||||
|
description: Type of job setting, must be usable as IDProperty type in Blender. No nested structures (arrays, dictionaries) are supported.
|
||||||
|
enum: [string, int32, float, bool]
|
||||||
|
|
||||||
Error:
|
Error:
|
||||||
type: object
|
type: object
|
||||||
required: [code, message]
|
required: [code, message]
|
||||||
@ -139,8 +204,15 @@ components:
|
|||||||
properties:
|
properties:
|
||||||
message: {type: string}
|
message: {type: string}
|
||||||
|
|
||||||
|
|
||||||
securitySchemes:
|
securitySchemes:
|
||||||
worker_auth:
|
worker_auth:
|
||||||
description: Username is the worker ID, password is the secret given at worker registration.
|
description: Username is the worker ID, password is the secret given at worker registration.
|
||||||
type: http
|
type: http
|
||||||
scheme: basic
|
scheme: basic
|
||||||
|
user_auth:
|
||||||
|
description: >
|
||||||
|
OAuth2 authentication flow for authenticating users. Currently not
|
||||||
|
implemented, so now more used as a "todo" than actual authentication.
|
||||||
|
type: http
|
||||||
|
scheme: basic
|
||||||
|
@ -88,6 +88,9 @@ func WithRequestEditorFn(fn RequestEditorFn) ClientOption {
|
|||||||
|
|
||||||
// The interface specification for the client above.
|
// The interface specification for the client above.
|
||||||
type ClientInterface interface {
|
type ClientInterface interface {
|
||||||
|
// GetJobTypes request
|
||||||
|
GetJobTypes(ctx context.Context, reqEditors ...RequestEditorFn) (*http.Response, error)
|
||||||
|
|
||||||
// RegisterWorker request with any body
|
// RegisterWorker request with any body
|
||||||
RegisterWorkerWithBody(ctx context.Context, contentType string, body io.Reader, reqEditors ...RequestEditorFn) (*http.Response, error)
|
RegisterWorkerWithBody(ctx context.Context, contentType string, body io.Reader, reqEditors ...RequestEditorFn) (*http.Response, error)
|
||||||
|
|
||||||
@ -97,6 +100,18 @@ type ClientInterface interface {
|
|||||||
ScheduleTask(ctx context.Context, reqEditors ...RequestEditorFn) (*http.Response, error)
|
ScheduleTask(ctx context.Context, reqEditors ...RequestEditorFn) (*http.Response, error)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (c *Client) GetJobTypes(ctx context.Context, reqEditors ...RequestEditorFn) (*http.Response, error) {
|
||||||
|
req, err := NewGetJobTypesRequest(c.Server)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
req = req.WithContext(ctx)
|
||||||
|
if err := c.applyEditors(ctx, req, reqEditors); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return c.Client.Do(req)
|
||||||
|
}
|
||||||
|
|
||||||
func (c *Client) RegisterWorkerWithBody(ctx context.Context, contentType string, body io.Reader, reqEditors ...RequestEditorFn) (*http.Response, error) {
|
func (c *Client) RegisterWorkerWithBody(ctx context.Context, contentType string, body io.Reader, reqEditors ...RequestEditorFn) (*http.Response, error) {
|
||||||
req, err := NewRegisterWorkerRequestWithBody(c.Server, contentType, body)
|
req, err := NewRegisterWorkerRequestWithBody(c.Server, contentType, body)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -133,6 +148,33 @@ func (c *Client) ScheduleTask(ctx context.Context, reqEditors ...RequestEditorFn
|
|||||||
return c.Client.Do(req)
|
return c.Client.Do(req)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// NewGetJobTypesRequest generates requests for GetJobTypes
|
||||||
|
func NewGetJobTypesRequest(server string) (*http.Request, error) {
|
||||||
|
var err error
|
||||||
|
|
||||||
|
serverURL, err := url.Parse(server)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
operationPath := fmt.Sprintf("/api/jobs/types")
|
||||||
|
if operationPath[0] == '/' {
|
||||||
|
operationPath = "." + operationPath
|
||||||
|
}
|
||||||
|
|
||||||
|
queryURL, err := serverURL.Parse(operationPath)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
req, err := http.NewRequest("GET", queryURL.String(), nil)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return req, nil
|
||||||
|
}
|
||||||
|
|
||||||
// NewRegisterWorkerRequest calls the generic RegisterWorker builder with application/json body
|
// NewRegisterWorkerRequest calls the generic RegisterWorker builder with application/json body
|
||||||
func NewRegisterWorkerRequest(server string, body RegisterWorkerJSONRequestBody) (*http.Request, error) {
|
func NewRegisterWorkerRequest(server string, body RegisterWorkerJSONRequestBody) (*http.Request, error) {
|
||||||
var bodyReader io.Reader
|
var bodyReader io.Reader
|
||||||
@ -243,6 +285,9 @@ func WithBaseURL(baseURL string) ClientOption {
|
|||||||
|
|
||||||
// ClientWithResponsesInterface is the interface specification for the client with responses above.
|
// ClientWithResponsesInterface is the interface specification for the client with responses above.
|
||||||
type ClientWithResponsesInterface interface {
|
type ClientWithResponsesInterface interface {
|
||||||
|
// GetJobTypes request
|
||||||
|
GetJobTypesWithResponse(ctx context.Context, reqEditors ...RequestEditorFn) (*GetJobTypesResponse, error)
|
||||||
|
|
||||||
// RegisterWorker request with any body
|
// RegisterWorker request with any body
|
||||||
RegisterWorkerWithBodyWithResponse(ctx context.Context, contentType string, body io.Reader, reqEditors ...RequestEditorFn) (*RegisterWorkerResponse, error)
|
RegisterWorkerWithBodyWithResponse(ctx context.Context, contentType string, body io.Reader, reqEditors ...RequestEditorFn) (*RegisterWorkerResponse, error)
|
||||||
|
|
||||||
@ -252,6 +297,28 @@ type ClientWithResponsesInterface interface {
|
|||||||
ScheduleTaskWithResponse(ctx context.Context, reqEditors ...RequestEditorFn) (*ScheduleTaskResponse, error)
|
ScheduleTaskWithResponse(ctx context.Context, reqEditors ...RequestEditorFn) (*ScheduleTaskResponse, error)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type GetJobTypesResponse struct {
|
||||||
|
Body []byte
|
||||||
|
HTTPResponse *http.Response
|
||||||
|
JSON200 *AvailableJobTypes
|
||||||
|
}
|
||||||
|
|
||||||
|
// Status returns HTTPResponse.Status
|
||||||
|
func (r GetJobTypesResponse) Status() string {
|
||||||
|
if r.HTTPResponse != nil {
|
||||||
|
return r.HTTPResponse.Status
|
||||||
|
}
|
||||||
|
return http.StatusText(0)
|
||||||
|
}
|
||||||
|
|
||||||
|
// StatusCode returns HTTPResponse.StatusCode
|
||||||
|
func (r GetJobTypesResponse) StatusCode() int {
|
||||||
|
if r.HTTPResponse != nil {
|
||||||
|
return r.HTTPResponse.StatusCode
|
||||||
|
}
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
type RegisterWorkerResponse struct {
|
type RegisterWorkerResponse struct {
|
||||||
Body []byte
|
Body []byte
|
||||||
HTTPResponse *http.Response
|
HTTPResponse *http.Response
|
||||||
@ -298,6 +365,15 @@ func (r ScheduleTaskResponse) StatusCode() int {
|
|||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// GetJobTypesWithResponse request returning *GetJobTypesResponse
|
||||||
|
func (c *ClientWithResponses) GetJobTypesWithResponse(ctx context.Context, reqEditors ...RequestEditorFn) (*GetJobTypesResponse, error) {
|
||||||
|
rsp, err := c.GetJobTypes(ctx, reqEditors...)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return ParseGetJobTypesResponse(rsp)
|
||||||
|
}
|
||||||
|
|
||||||
// RegisterWorkerWithBodyWithResponse request with arbitrary body returning *RegisterWorkerResponse
|
// RegisterWorkerWithBodyWithResponse request with arbitrary body returning *RegisterWorkerResponse
|
||||||
func (c *ClientWithResponses) RegisterWorkerWithBodyWithResponse(ctx context.Context, contentType string, body io.Reader, reqEditors ...RequestEditorFn) (*RegisterWorkerResponse, error) {
|
func (c *ClientWithResponses) RegisterWorkerWithBodyWithResponse(ctx context.Context, contentType string, body io.Reader, reqEditors ...RequestEditorFn) (*RegisterWorkerResponse, error) {
|
||||||
rsp, err := c.RegisterWorkerWithBody(ctx, contentType, body, reqEditors...)
|
rsp, err := c.RegisterWorkerWithBody(ctx, contentType, body, reqEditors...)
|
||||||
@ -324,6 +400,32 @@ func (c *ClientWithResponses) ScheduleTaskWithResponse(ctx context.Context, reqE
|
|||||||
return ParseScheduleTaskResponse(rsp)
|
return ParseScheduleTaskResponse(rsp)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ParseGetJobTypesResponse parses an HTTP response from a GetJobTypesWithResponse call
|
||||||
|
func ParseGetJobTypesResponse(rsp *http.Response) (*GetJobTypesResponse, error) {
|
||||||
|
bodyBytes, err := ioutil.ReadAll(rsp.Body)
|
||||||
|
defer func() { _ = rsp.Body.Close() }()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
response := &GetJobTypesResponse{
|
||||||
|
Body: bodyBytes,
|
||||||
|
HTTPResponse: rsp,
|
||||||
|
}
|
||||||
|
|
||||||
|
switch {
|
||||||
|
case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 200:
|
||||||
|
var dest AvailableJobTypes
|
||||||
|
if err := json.Unmarshal(bodyBytes, &dest); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
response.JSON200 = &dest
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
return response, nil
|
||||||
|
}
|
||||||
|
|
||||||
// ParseRegisterWorkerResponse parses an HTTP response from a RegisterWorkerWithResponse call
|
// ParseRegisterWorkerResponse parses an HTTP response from a RegisterWorkerWithResponse call
|
||||||
func ParseRegisterWorkerResponse(rsp *http.Response) (*RegisterWorkerResponse, error) {
|
func ParseRegisterWorkerResponse(rsp *http.Response) (*RegisterWorkerResponse, error) {
|
||||||
bodyBytes, err := ioutil.ReadAll(rsp.Body)
|
bodyBytes, err := ioutil.ReadAll(rsp.Body)
|
||||||
|
@ -9,6 +9,9 @@ import (
|
|||||||
|
|
||||||
// ServerInterface represents all server handlers.
|
// ServerInterface represents all server handlers.
|
||||||
type ServerInterface interface {
|
type ServerInterface interface {
|
||||||
|
// Get list of job types and their parameters.
|
||||||
|
// (GET /api/jobs/types)
|
||||||
|
GetJobTypes(ctx echo.Context) error
|
||||||
// Register a new worker
|
// Register a new worker
|
||||||
// (POST /api/worker/register-worker)
|
// (POST /api/worker/register-worker)
|
||||||
RegisterWorker(ctx echo.Context) error
|
RegisterWorker(ctx echo.Context) error
|
||||||
@ -22,6 +25,15 @@ type ServerInterfaceWrapper struct {
|
|||||||
Handler ServerInterface
|
Handler ServerInterface
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// GetJobTypes converts echo context to params.
|
||||||
|
func (w *ServerInterfaceWrapper) GetJobTypes(ctx echo.Context) error {
|
||||||
|
var err error
|
||||||
|
|
||||||
|
// Invoke the callback with all the unmarshalled arguments
|
||||||
|
err = w.Handler.GetJobTypes(ctx)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
// RegisterWorker converts echo context to params.
|
// RegisterWorker converts echo context to params.
|
||||||
func (w *ServerInterfaceWrapper) RegisterWorker(ctx echo.Context) error {
|
func (w *ServerInterfaceWrapper) RegisterWorker(ctx echo.Context) error {
|
||||||
var err error
|
var err error
|
||||||
@ -70,6 +82,7 @@ func RegisterHandlersWithBaseURL(router EchoRouter, si ServerInterface, baseURL
|
|||||||
Handler: si,
|
Handler: si,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
router.GET(baseURL+"/api/jobs/types", wrapper.GetJobTypes)
|
||||||
router.POST(baseURL+"/api/worker/register-worker", wrapper.RegisterWorker)
|
router.POST(baseURL+"/api/worker/register-worker", wrapper.RegisterWorker)
|
||||||
router.POST(baseURL+"/api/worker/task", wrapper.ScheduleTask)
|
router.POST(baseURL+"/api/worker/task", wrapper.ScheduleTask)
|
||||||
|
|
||||||
|
@ -18,25 +18,35 @@ import (
|
|||||||
// Base64 encoded, gzipped, json marshaled Swagger object
|
// Base64 encoded, gzipped, json marshaled Swagger object
|
||||||
var swaggerSpec = []string{
|
var swaggerSpec = []string{
|
||||||
|
|
||||||
"H4sIAAAAAAAC/7xX32/jNgz+VwRtj6mdXe8pb7fdbiiwH8W1wx6KolBsxlFrSzqSTi4o8r8PlOzEbpzr",
|
"H4sIAAAAAAAC/7xY32/jNhL+Vwa6A64FFDu36ZPftt3rIUWvGzQp+rAbpLQ4tplQpJYc2jUC/++HIakf",
|
||||||
"gHV7imOR4sePHyn5WRe+Cd6BY9KLZ03FGhoTHz8Q2cpBeWvoSf6XQAXawNY7vRitKkvKKJYnQ8qy/Eco",
|
"tuRkr7ftSyJLJGfmm29mPum5qGzdWIOGfLF4Lny1wVrEy7feq7VBeSf8E/+W6CunGlLWFIujp6A8CCC+",
|
||||||
"wG6gVMud4jWovzw+AWZ6pgP6AMgWYpQHW8oP7wLohSZG6yq9nwmsxrgy2liGJj58j7DSC/1dfgSdd4jz",
|
"Eh4U8W+HFaotSljugTYIv1r3hG5WlEXjbIOOFEYrD0ryP9o3WCwKT06ZdXEo2a1aGBnXKMI6Xvzd4apY",
|
||||||
"n5KD+HabGUSzk/+PfjkZ49EvHwJaj5Z3AwPrGCrA3iK9nXB3pple+PaexIbbV9MRXm+SpWRk6Ok8kJYA",
|
"FH+b907Ps8fz79IG3psPE86JPf9+tMtJG492+dA4ZZ2i/WCBMoRrdO2KdHdiuxH19IOXz/QkKLwaDuN6",
|
||||||
"Jxb2M43wpbUIpV7cRaYTF51Hl8EB0QD4C24GRAyxDKp0f2DdLx+hYIHVV+REO92CQggIJGkro8i6qgbV",
|
"m1ZyRMI/nXckeHQTDw5l4fBTUA5lsfgQkU5Y5B05gs6jgeMn2AyAGPoyyNJ9h7pdPmJF7NbbrVBaLDX+",
|
||||||
"7ajYK/gKRcvwmoLOloGA2bqKBos9uBfU9Dz0DlPZ/IzoI8vj6IUvY/SVx8ZwqvTlOz2bKHwDRKaC1ysV",
|
"YJe3SMROjXh0q8xaI/j0HOwKBPxgl8Cn+TFdqo1VVbo8PufXDRpYqy2aErSqFUXWbYVWkv8G9ECW73mE",
|
||||||
"9zzaT6H5DJUlBoQy0XIK7FxjmbJEIJpcqw3xgynYbsbqHWjeFk/ndV8bFh6mq+FXvDV4plSHnjhdakPw",
|
"fMgM3hu9h+DZR9gp2kCCLhpn2x3xRpCfUkziSgRNY7/uNgj5YfID/MbuTHYGOBGwY98lErpamWh/o3wL",
|
||||||
"yFA+HIQ3HgonHuP2n+yCQxpHPoZt0Ocx00WLCI5jbP2SoEFSZ3BOle4Gila66oyg/rFKviWPwfRYPGtw",
|
"yYyPf8L9+OhriYbUSqGDlXXxuLynhDp4giVCMOpTSMEpE5c8ZnA5vlFYPV+e+5BWQnssx3jTBh3Hoeoa",
|
||||||
"bSMeEXhsW+MKqKFMHRxq4Pi8Mja9/NJCGx8kv4vD6+R2ISCAji6jF8G0lB7QF0DS1QOExyIl2SYZo0mD",
|
"pRKEeg8OOfsgohmJK2UUbyg5sTEqNllGf2ygdKsRjlQVtHB9zJ1vS2s1CtNj/nLZTHDujrcdymKrvFpq",
|
||||||
"4SUV/0JsUCDw/6GnLtJINJMhBqI7rViCHGVxIwdAgrSNHD2YltenQ/RPApTd5LCV8ZiM1dXHmQqGaOux",
|
"PAqNXHgpMk7VUTIgg/jLdWIqR+nDslZE6OArrZ4QBHyr0Uh0IKS8sObrGdwi8XG/RSR/S/lObVIY4Nbg",
|
||||||
"7JcSRlXZDThluDfFAfkyVuPRI6iWhmxxHGFr5qD3gtG6lU9Dz7Ep+Dh99afaNOAKr27BCAUt1p0nLfJ8",
|
"jNCdDdoIYtNBS/OPmMWOMmhkpIyffTQTGJ1UPLMmL/rM+rzLEJ9weN8gxxujHTEslY/wcP3uJtXqPmaZ",
|
||||||
"1a1m1ufC6DiTz+BKQPXJYKMa40wFqD5cX0m72QIcwSDOL9e/bi5P9t9ut1nl2sxjlXc+lFehvrjM5hm4",
|
"scpIzOAnCwY9oeQSCxUFhx6+iuXjS5CqYlPCKfRfg3AIPjSNdYSSqYAm1BxP5mnJ3fTqTVEWK20FFWUE",
|
||||||
"bM1NHStpuR6h7cLpmd4AUoLzQzbP5mLtAzgTrF7oy/hKxM3rWJncBJsnGnPsRvHF9jiJPUVyRMyR3qsy",
|
"YBBiz+dhiNOxtb2mt5gmlvLwH2HEGl0JwkhQFIkqai7TicZ0dhhkwD5/kE21zVHHOcl028hbW6+lm7GY",
|
||||||
"5pkMu4mddATEP/py17MKLjqaEGpbRNf8kVJvpJvBa/eGib6KpRtTnqzkkO3R66GsGVuIOqfghUsJ+m4+",
|
"aKI/Kk9tomMDPo/KGIF2RPyxSNsqfTHM3sRUgK0CGIWVH4DDxqFnF0CAT4MnT7BYXL9jFQhfUyyflekT",
|
||||||
"fzOQJ6fXBEQnB2qtegxJNivT1vxmMNIEnojdOvgaoGAoFXQ20tVNY3A3KKQyysG2a6d4M5LLxl3Xt/p+",
|
"5/5Auv7lnI1T/WQAWhmtr6yrBSVlEWthLDRq9F6s8XVlEM/s10958zOulSd0KBMsY8fOCTkhpUM/PUW1",
|
||||||
"wimVRPnVwDPe8IaK4u7GPS0jGRBlW8NtOpL+syKN7v8TJMWb//GalkkW7+bvTyfV7z5+G5AyG2Nrs6xB",
|
"8PQgKlLbY7U00Fiqejqvs7QgxmE6G3ZFO+HOpKrTYONHLeMfOqFzzOhXtMCk6urC6PEYyq42jrKognNo",
|
||||||
"rTwqXls6XOr2M/1+fvlm2Mdn7AT4a8DGknS8+gjOQjmawXpx92L63t3v74fV/GPJxrpOADxm4jUlROKo",
|
"KNouTgEaBHXGz6nU3WIVWMWdIdRns+QlegzU6uK569fR8SgThalQo0yKsdFI8XolVLr5KWCIFxzfRXc7",
|
||||||
"qyIqcGXw1nHWQUAZRRFBGnK5ltDdjiefYddXkczDREuEksCRq3TrhEBQW8vro9Fvaexl/SfAoge6v9//",
|
"bbtgJ+LsyFuObjQi+HThbIWeq3pyEiTaJho7kRrDKRT/B9mwckh/BZ+ypSPSTJoYkG6cseRypMUtN+Pk",
|
||||||
"HQAA//+F23YLEg4AAA==",
|
"EiuLBxFoM26h798G2rwBfsiis4oIwkrbXdSew/tmnSUKfJfIrPdgLIHixNdoCGUJ3oKxO6itixpYsn4Q",
|
||||||
|
"8LEgK+3HgiWQAVFREPrEZhI+cYJE6SO8qvrutyFqGMJdzPaZWH7xrLdqZP3FjT4thut3JTTC+511sn2U",
|
||||||
|
"0E7vFSCoXeoGNJq96g6jrczKpvZtSFTUz5Hiey1qNJWFOxSczOB03ukX8/kqP50pO0/vGcNIfk4683vh",
|
||||||
|
"aqjTXIa3N9fcOFSFxuPAzr9vftxejc7f7XaztQkz69bzvMfP142+uJpdztDMNlTryElF+sjbbK4oiy06",
|
||||||
|
"n9z55+xydsmrbYNGNKpYFFfxFpcpbSLH5qJR80e79POuEtapcrgSI6LXkt1F6nQKV4BvLPvGC99cXrZQ",
|
||||||
|
"oolbRdPozI/5o0+lnUTG/ypBfErXybeOdlEvjFIJhboWbp+8BT0ST1FXbFC5E+VIgkVClDO+uD86qDfV",
|
||||||
|
"If3Yvw0fyoRfouHc5aF8setnsvUTYLbTO8/u1FHQ07dW7r8YlBMddgLLtIrlVut9MWxw/EJ2+BPzPdIx",
|
||||||
|
"Ey4allYaWh9OXu+/iBtpFk/YDgZ/b7BiwY15zZAerfsgwOAut6MBo/KN+4lNKSVM0H6nP2UU5W990zTi",
|
||||||
|
"USGDxrskTv68ohx+eZwAKX5z7AV7rIs3l9+MO/1PNn6V9CC6skpfSpTv5P2hLL65vPpivh+rrQnnb9DV",
|
||||||
|
"ynPHhHdoFMqjaVwsPjwfT68P94f7YTbfL0kokwlAx0i8xoQInM9ZdIBGNlYZmmUXHLfy6EEaEvOCTecT",
|
||||||
|
"Rx+Ab64jmF2fSoDGz2z8UhUMA5i/q3WLBm+PeS5lRw/3h/8GAAD//4xnB3uMFgAA",
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetSwagger returns the content of the embedded swagger specification file
|
// GetSwagger returns the content of the embedded swagger specification file
|
||||||
|
@ -7,6 +7,17 @@ const (
|
|||||||
Worker_authScopes = "worker_auth.Scopes"
|
Worker_authScopes = "worker_auth.Scopes"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// Defines values for AvailableJobSettingType.
|
||||||
|
const (
|
||||||
|
AvailableJobSettingTypeBool AvailableJobSettingType = "bool"
|
||||||
|
|
||||||
|
AvailableJobSettingTypeFloat AvailableJobSettingType = "float"
|
||||||
|
|
||||||
|
AvailableJobSettingTypeInt32 AvailableJobSettingType = "int32"
|
||||||
|
|
||||||
|
AvailableJobSettingTypeString AvailableJobSettingType = "string"
|
||||||
|
)
|
||||||
|
|
||||||
// Defines values for TaskStatus.
|
// Defines values for TaskStatus.
|
||||||
const (
|
const (
|
||||||
TaskStatusActive TaskStatus = "active"
|
TaskStatusActive TaskStatus = "active"
|
||||||
@ -44,6 +55,41 @@ type AssignedTask struct {
|
|||||||
User string `json:"user"`
|
User string `json:"user"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Single setting of a Job types.
|
||||||
|
type AvailableJobSetting struct {
|
||||||
|
// When given, limit the valid values to these choices. Only usable with string type.
|
||||||
|
Choices *[]string `json:"choices,omitempty"`
|
||||||
|
|
||||||
|
// The default value shown to the user when determining this setting.
|
||||||
|
Default *interface{} `json:"default,omitempty"`
|
||||||
|
|
||||||
|
// Identifier for the setting, must be unique within the job type.
|
||||||
|
Key string `json:"key"`
|
||||||
|
|
||||||
|
// Whether to immediately reject a job definition, of this type, without this particular setting.
|
||||||
|
Required *bool `json:"required,omitempty"`
|
||||||
|
|
||||||
|
// Type of job setting, must be usable as IDProperty type in Blender. No nested structures (arrays, dictionaries) are supported.
|
||||||
|
Type AvailableJobSettingType `json:"type"`
|
||||||
|
|
||||||
|
// Whether to show this setting in the UI of a job submitter (like a Blender add-on). Set to `false` when it is an internal setting that shouldn't be shown to end users.
|
||||||
|
Visible *bool `json:"visible,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// Type of job setting, must be usable as IDProperty type in Blender. No nested structures (arrays, dictionaries) are supported.
|
||||||
|
type AvailableJobSettingType string
|
||||||
|
|
||||||
|
// Job type supported by this Manager, and its parameters.
|
||||||
|
type AvailableJobType struct {
|
||||||
|
Name string `json:"name"`
|
||||||
|
Settings []AvailableJobSetting `json:"settings"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// List of job types supported by this Manager.
|
||||||
|
type AvailableJobTypes struct {
|
||||||
|
JobTypes []AvailableJobType `json:"job_types"`
|
||||||
|
}
|
||||||
|
|
||||||
// Command represents a single command to execute by the Worker.
|
// Command represents a single command to execute by the Worker.
|
||||||
type Command struct {
|
type Command struct {
|
||||||
Name string `json:"name"`
|
Name string `json:"name"`
|
||||||
|
Loading…
x
Reference in New Issue
Block a user