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:
Sybren A. Stüvel 2022-01-10 14:06:08 +01:00 committed by Sybren A. Stüvel
parent 7728c072ae
commit b605330c57
8 changed files with 414 additions and 64 deletions

View File

@ -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 {

View 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)
}

View 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: "",
})
}

View File

@ -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

View File

@ -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)

View File

@ -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)

View File

@ -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{
"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",
"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

View 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"`