diff --git a/internal/manager/api_impl/api_impl.go b/internal/manager/api_impl/api_impl.go index e46cf934..254d0b9c 100644 --- a/internal/manager/api_impl/api_impl.go +++ b/internal/manager/api_impl/api_impl.go @@ -1,3 +1,4 @@ +// Package api_impl implements the OpenAPI API from pkg/api/flamenco-manager.yaml. package api_impl /* ***** BEGIN GPL LICENSE BLOCK ***** @@ -21,11 +22,7 @@ package api_impl * ***** 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" ) @@ -38,47 +35,6 @@ func NewFlamenco() *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 // handling the failure to marshal that. func sendAPIError(e echo.Context, code int, message string) error { diff --git a/internal/manager/api_impl/job_compiler.go b/internal/manager/api_impl/job_compiler.go new file mode 100644 index 00000000..ce4cb9c3 --- /dev/null +++ b/internal/manager/api_impl/job_compiler.go @@ -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 . + * + * ***** 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) +} diff --git a/internal/manager/api_impl/workers.go b/internal/manager/api_impl/workers.go new file mode 100644 index 00000000..2d1dbff7 --- /dev/null +++ b/internal/manager/api_impl/workers.go @@ -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 . + * + * ***** 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: "", + }) +} diff --git a/pkg/api/flamenco-manager.yaml b/pkg/api/flamenco-manager.yaml index 6b684439..32db81a3 100644 --- a/pkg/api/flamenco-manager.yaml +++ b/pkg/api/flamenco-manager.yaml @@ -60,6 +60,20 @@ paths: application/json: 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: - name: worker description: API for Flamenco Workers to communicate with Flamenco Manager. @@ -126,6 +140,57 @@ components: settings: {type: object} 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: type: object required: [code, message] @@ -139,8 +204,15 @@ components: properties: message: {type: string} + securitySchemes: worker_auth: description: Username is the worker ID, password is the secret given at worker registration. type: http 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 diff --git a/pkg/api/openapi_client.gen.go b/pkg/api/openapi_client.gen.go index 1581487c..eb465cac 100644 --- a/pkg/api/openapi_client.gen.go +++ b/pkg/api/openapi_client.gen.go @@ -88,6 +88,9 @@ func WithRequestEditorFn(fn RequestEditorFn) ClientOption { // The interface specification for the client above. type ClientInterface interface { + // GetJobTypes request + GetJobTypes(ctx context.Context, reqEditors ...RequestEditorFn) (*http.Response, error) + // RegisterWorker request with any body 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) } +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) { req, err := NewRegisterWorkerRequestWithBody(c.Server, contentType, body) if err != nil { @@ -133,6 +148,33 @@ func (c *Client) ScheduleTask(ctx context.Context, reqEditors ...RequestEditorFn 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 func NewRegisterWorkerRequest(server string, body RegisterWorkerJSONRequestBody) (*http.Request, error) { var bodyReader io.Reader @@ -243,6 +285,9 @@ func WithBaseURL(baseURL string) ClientOption { // ClientWithResponsesInterface is the interface specification for the client with responses above. type ClientWithResponsesInterface interface { + // GetJobTypes request + GetJobTypesWithResponse(ctx context.Context, reqEditors ...RequestEditorFn) (*GetJobTypesResponse, error) + // RegisterWorker request with any body 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) } +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 { Body []byte HTTPResponse *http.Response @@ -298,6 +365,15 @@ func (r ScheduleTaskResponse) StatusCode() int { 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 func (c *ClientWithResponses) RegisterWorkerWithBodyWithResponse(ctx context.Context, contentType string, body io.Reader, reqEditors ...RequestEditorFn) (*RegisterWorkerResponse, error) { rsp, err := c.RegisterWorkerWithBody(ctx, contentType, body, reqEditors...) @@ -324,6 +400,32 @@ func (c *ClientWithResponses) ScheduleTaskWithResponse(ctx context.Context, reqE 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 func ParseRegisterWorkerResponse(rsp *http.Response) (*RegisterWorkerResponse, error) { bodyBytes, err := ioutil.ReadAll(rsp.Body) diff --git a/pkg/api/openapi_server.gen.go b/pkg/api/openapi_server.gen.go index 520c5676..66a58be4 100644 --- a/pkg/api/openapi_server.gen.go +++ b/pkg/api/openapi_server.gen.go @@ -9,6 +9,9 @@ import ( // ServerInterface represents all server handlers. type ServerInterface interface { + // Get list of job types and their parameters. + // (GET /api/jobs/types) + GetJobTypes(ctx echo.Context) error // Register a new worker // (POST /api/worker/register-worker) RegisterWorker(ctx echo.Context) error @@ -22,6 +25,15 @@ type ServerInterfaceWrapper struct { 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. func (w *ServerInterfaceWrapper) RegisterWorker(ctx echo.Context) error { var err error @@ -70,6 +82,7 @@ func RegisterHandlersWithBaseURL(router EchoRouter, si ServerInterface, baseURL Handler: si, } + router.GET(baseURL+"/api/jobs/types", wrapper.GetJobTypes) router.POST(baseURL+"/api/worker/register-worker", wrapper.RegisterWorker) router.POST(baseURL+"/api/worker/task", wrapper.ScheduleTask) diff --git a/pkg/api/openapi_spec.gen.go b/pkg/api/openapi_spec.gen.go index bf3bb842..19c51425 100644 --- a/pkg/api/openapi_spec.gen.go +++ b/pkg/api/openapi_spec.gen.go @@ -18,25 +18,35 @@ import ( // Base64 encoded, gzipped, json marshaled Swagger object var swaggerSpec = []string{ - "H4sIAAAAAAAC/7xX32/jNgz+VwRtj6mdXe8pb7fdbiiwH8W1wx6KolBsxlFrSzqSTi4o8r8PlOzEbpzr", - "gHV7imOR4sePHyn5WRe+Cd6BY9KLZ03FGhoTHz8Q2cpBeWvoSf6XQAXawNY7vRitKkvKKJYnQ8qy/Eco", - "wG6gVMud4jWovzw+AWZ6pgP6AMgWYpQHW8oP7wLohSZG6yq9nwmsxrgy2liGJj58j7DSC/1dfgSdd4jz", - "n5KD+HabGUSzk/+PfjkZ49EvHwJaj5Z3AwPrGCrA3iK9nXB3pple+PaexIbbV9MRXm+SpWRk6Ok8kJYA", - "Jxb2M43wpbUIpV7cRaYTF51Hl8EB0QD4C24GRAyxDKp0f2DdLx+hYIHVV+REO92CQggIJGkro8i6qgbV", - "7ajYK/gKRcvwmoLOloGA2bqKBos9uBfU9Dz0DlPZ/IzoI8vj6IUvY/SVx8ZwqvTlOz2bKHwDRKaC1ysV", - "9zzaT6H5DJUlBoQy0XIK7FxjmbJEIJpcqw3xgynYbsbqHWjeFk/ndV8bFh6mq+FXvDV4plSHnjhdakPw", - "yFA+HIQ3HgonHuP2n+yCQxpHPoZt0Ocx00WLCI5jbP2SoEFSZ3BOle4Gila66oyg/rFKviWPwfRYPGtw", - "bSMeEXhsW+MKqKFMHRxq4Pi8Mja9/NJCGx8kv4vD6+R2ISCAji6jF8G0lB7QF0DS1QOExyIl2SYZo0mD", - "4SUV/0JsUCDw/6GnLtJINJMhBqI7rViCHGVxIwdAgrSNHD2YltenQ/RPApTd5LCV8ZiM1dXHmQqGaOux", - "7JcSRlXZDThluDfFAfkyVuPRI6iWhmxxHGFr5qD3gtG6lU9Dz7Ep+Dh99afaNOAKr27BCAUt1p0nLfJ8", - "1a1m1ufC6DiTz+BKQPXJYKMa40wFqD5cX0m72QIcwSDOL9e/bi5P9t9ut1nl2sxjlXc+lFehvrjM5hm4", - "bM1NHStpuR6h7cLpmd4AUoLzQzbP5mLtAzgTrF7oy/hKxM3rWJncBJsnGnPsRvHF9jiJPUVyRMyR3qsy", - "5pkMu4mddATEP/py17MKLjqaEGpbRNf8kVJvpJvBa/eGib6KpRtTnqzkkO3R66GsGVuIOqfghUsJ+m4+", - "fzOQJ6fXBEQnB2qtegxJNivT1vxmMNIEnojdOvgaoGAoFXQ20tVNY3A3KKQyysG2a6d4M5LLxl3Xt/p+", - "wimVRPnVwDPe8IaK4u7GPS0jGRBlW8NtOpL+syKN7v8TJMWb//GalkkW7+bvTyfV7z5+G5AyG2Nrs6xB", - "rTwqXls6XOr2M/1+fvlm2Mdn7AT4a8DGknS8+gjOQjmawXpx92L63t3v74fV/GPJxrpOADxm4jUlROKo", - "qyIqcGXw1nHWQUAZRRFBGnK5ltDdjiefYddXkczDREuEksCRq3TrhEBQW8vro9Fvaexl/SfAoge6v9//", - "HQAA//+F23YLEg4AAA==", + "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", } // GetSwagger returns the content of the embedded swagger specification file diff --git a/pkg/api/openapi_types.gen.go b/pkg/api/openapi_types.gen.go index 03628845..234dc8bf 100644 --- a/pkg/api/openapi_types.gen.go +++ b/pkg/api/openapi_types.gen.go @@ -7,6 +7,17 @@ const ( 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. const ( TaskStatusActive TaskStatus = "active" @@ -44,6 +55,41 @@ type AssignedTask struct { 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. type Command struct { Name string `json:"name"`