diff --git a/addon/flamenco/manager/__init__.py b/addon/flamenco/manager/__init__.py index a4f5a3df..c9bdad84 100644 --- a/addon/flamenco/manager/__init__.py +++ b/addon/flamenco/manager/__init__.py @@ -10,7 +10,7 @@ """ -__version__ = "d8233363" +__version__ = "cfb17b17" # import ApiClient from flamenco.manager.api_client import ApiClient diff --git a/addon/flamenco/manager/api/worker_mgt_api.py b/addon/flamenco/manager/api/worker_mgt_api.py index 0e637d16..1db68c65 100644 --- a/addon/flamenco/manager/api/worker_mgt_api.py +++ b/addon/flamenco/manager/api/worker_mgt_api.py @@ -21,8 +21,10 @@ from flamenco.manager.model_utils import ( # noqa: F401 none_type, validate_and_convert_types ) +from flamenco.manager.model.error import Error from flamenco.manager.model.worker import Worker from flamenco.manager.model.worker_list import WorkerList +from flamenco.manager.model.worker_status_change_request import WorkerStatusChangeRequest class WorkerMgtApi(object): @@ -127,6 +129,62 @@ class WorkerMgtApi(object): }, api_client=api_client ) + self.request_worker_status_change_endpoint = _Endpoint( + settings={ + 'response_type': None, + 'auth': [], + 'endpoint_path': '/api/worker-mgt/workers/{worker_id}/setstatus', + 'operation_id': 'request_worker_status_change', + 'http_method': 'POST', + 'servers': None, + }, + params_map={ + 'all': [ + 'worker_id', + 'worker_status_change_request', + ], + 'required': [ + 'worker_id', + 'worker_status_change_request', + ], + 'nullable': [ + ], + 'enum': [ + ], + 'validation': [ + ] + }, + root_map={ + 'validations': { + }, + 'allowed_values': { + }, + 'openapi_types': { + 'worker_id': + (str,), + 'worker_status_change_request': + (WorkerStatusChangeRequest,), + }, + 'attribute_map': { + 'worker_id': 'worker_id', + }, + 'location_map': { + 'worker_id': 'path', + 'worker_status_change_request': 'body', + }, + 'collection_format_map': { + } + }, + headers_map={ + 'accept': [ + 'application/json' + ], + 'content_type': [ + 'application/json' + ] + }, + api_client=api_client + ) def fetch_worker( self, @@ -277,3 +335,84 @@ class WorkerMgtApi(object): kwargs['_host_index'] = kwargs.get('_host_index') return self.fetch_workers_endpoint.call_with_http_info(**kwargs) + def request_worker_status_change( + self, + worker_id, + worker_status_change_request, + **kwargs + ): + """request_worker_status_change # noqa: E501 + + This method makes a synchronous HTTP request by default. To make an + asynchronous HTTP request, please pass async_req=True + + >>> thread = api.request_worker_status_change(worker_id, worker_status_change_request, async_req=True) + >>> result = thread.get() + + Args: + worker_id (str): + worker_status_change_request (WorkerStatusChangeRequest): The status change to request. + + Keyword Args: + _return_http_data_only (bool): response data without head status + code and headers. Default is True. + _preload_content (bool): if False, the urllib3.HTTPResponse object + will be returned without reading/decoding response data. + Default is True. + _request_timeout (int/float/tuple): timeout setting for this request. If + one number provided, it will be total request timeout. It can also + be a pair (tuple) of (connection, read) timeouts. + Default is None. + _check_input_type (bool): specifies if type checking + should be done one the data sent to the server. + Default is True. + _check_return_type (bool): specifies if type checking + should be done one the data received from the server. + Default is True. + _spec_property_naming (bool): True if the variable names in the input data + are serialized names, as specified in the OpenAPI document. + False if the variable names in the input data + are pythonic names, e.g. snake case (default) + _content_type (str/None): force body content-type. + Default is None and content-type will be predicted by allowed + content-types and body. + _host_index (int/None): specifies the index of the server + that we want to use. + Default is read from the configuration. + async_req (bool): execute request asynchronously + + Returns: + None + If the method is called asynchronously, returns the request + thread. + """ + kwargs['async_req'] = kwargs.get( + 'async_req', False + ) + kwargs['_return_http_data_only'] = kwargs.get( + '_return_http_data_only', True + ) + kwargs['_preload_content'] = kwargs.get( + '_preload_content', True + ) + kwargs['_request_timeout'] = kwargs.get( + '_request_timeout', None + ) + kwargs['_check_input_type'] = kwargs.get( + '_check_input_type', True + ) + kwargs['_check_return_type'] = kwargs.get( + '_check_return_type', True + ) + kwargs['_spec_property_naming'] = kwargs.get( + '_spec_property_naming', False + ) + kwargs['_content_type'] = kwargs.get( + '_content_type') + kwargs['_host_index'] = kwargs.get('_host_index') + kwargs['worker_id'] = \ + worker_id + kwargs['worker_status_change_request'] = \ + worker_status_change_request + return self.request_worker_status_change_endpoint.call_with_http_info(**kwargs) + diff --git a/addon/flamenco/manager/api_client.py b/addon/flamenco/manager/api_client.py index 0e7bb07b..b09b804d 100644 --- a/addon/flamenco/manager/api_client.py +++ b/addon/flamenco/manager/api_client.py @@ -76,7 +76,7 @@ class ApiClient(object): self.default_headers[header_name] = header_value self.cookie = cookie # Set default User-Agent. - self.user_agent = 'Flamenco/d8233363 (Blender add-on)' + self.user_agent = 'Flamenco/cfb17b17 (Blender add-on)' def __enter__(self): return self diff --git a/addon/flamenco/manager/configuration.py b/addon/flamenco/manager/configuration.py index a2a0e35d..0a18e499 100644 --- a/addon/flamenco/manager/configuration.py +++ b/addon/flamenco/manager/configuration.py @@ -404,7 +404,7 @@ conf = flamenco.manager.Configuration( "OS: {env}\n"\ "Python Version: {pyversion}\n"\ "Version of the API: 1.0.0\n"\ - "SDK Package Version: d8233363".\ + "SDK Package Version: cfb17b17".\ format(env=sys.platform, pyversion=sys.version) def get_host_settings(self): diff --git a/addon/flamenco/manager/docs/SocketIOWorkerUpdate.md b/addon/flamenco/manager/docs/SocketIOWorkerUpdate.md index 4ba2da12..12e42e50 100644 --- a/addon/flamenco/manager/docs/SocketIOWorkerUpdate.md +++ b/addon/flamenco/manager/docs/SocketIOWorkerUpdate.md @@ -1,6 +1,6 @@ # SocketIOWorkerUpdate -Subset of a Worker, sent over SocketIO when a worker changes. For new workers, `previous_status` will be excluded. +Subset of a Worker, sent over SocketIO when a worker changes. ## Properties Name | Type | Description | Notes @@ -12,6 +12,7 @@ Name | Type | Description | Notes **version** | **str** | | **previous_status** | [**WorkerStatus**](WorkerStatus.md) | | [optional] **status_requested** | [**WorkerStatus**](WorkerStatus.md) | | [optional] +**lazy_status_request** | **bool** | Whether the worker is allowed to finish its current task before the status change is enforced. Mandatory when `status_requested` is set. | [optional] **any string name** | **bool, date, datetime, dict, float, int, list, str, none_type** | any string name can be used but the value must be the correct type | [optional] [[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) diff --git a/addon/flamenco/manager/docs/Worker.md b/addon/flamenco/manager/docs/Worker.md index def9d113..4b879265 100644 --- a/addon/flamenco/manager/docs/Worker.md +++ b/addon/flamenco/manager/docs/Worker.md @@ -13,6 +13,7 @@ Name | Type | Description | Notes **platform** | **str** | Operating system of the Worker | **supported_task_types** | **[str]** | | **status_requested** | [**WorkerStatus**](WorkerStatus.md) | | [optional] +**lazy_status_request** | **bool** | | [optional] **any string name** | **bool, date, datetime, dict, float, int, list, str, none_type** | any string name can be used but the value must be the correct type | [optional] [[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) diff --git a/addon/flamenco/manager/docs/WorkerMgtApi.md b/addon/flamenco/manager/docs/WorkerMgtApi.md index 293225a8..4bb6a0a9 100644 --- a/addon/flamenco/manager/docs/WorkerMgtApi.md +++ b/addon/flamenco/manager/docs/WorkerMgtApi.md @@ -6,6 +6,7 @@ Method | HTTP request | Description ------------- | ------------- | ------------- [**fetch_worker**](WorkerMgtApi.md#fetch_worker) | **GET** /api/worker-mgt/workers/{worker_id} | Fetch info about the worker. [**fetch_workers**](WorkerMgtApi.md#fetch_workers) | **GET** /api/worker-mgt/workers | Get list of workers. +[**request_worker_status_change**](WorkerMgtApi.md#request_worker_status_change) | **POST** /api/worker-mgt/workers/{worker_id}/setstatus | # **fetch_worker** @@ -134,3 +135,73 @@ No authorization required [[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md) +# **request_worker_status_change** +> request_worker_status_change(worker_id, worker_status_change_request) + + + +### Example + + +```python +import time +import flamenco.manager +from flamenco.manager.api import worker_mgt_api +from flamenco.manager.model.error import Error +from flamenco.manager.model.worker_status_change_request import WorkerStatusChangeRequest +from pprint import pprint +# Defining the host is optional and defaults to http://localhost +# See configuration.py for a list of all supported configuration parameters. +configuration = flamenco.manager.Configuration( + host = "http://localhost" +) + + +# Enter a context with an instance of the API client +with flamenco.manager.ApiClient() as api_client: + # Create an instance of the API class + api_instance = worker_mgt_api.WorkerMgtApi(api_client) + worker_id = "worker_id_example" # str | + worker_status_change_request = WorkerStatusChangeRequest( + status_requested=WorkerStatus("starting"), + is_lazy=True, + ) # WorkerStatusChangeRequest | The status change to request. + + # example passing only required values which don't have defaults set + try: + api_instance.request_worker_status_change(worker_id, worker_status_change_request) + except flamenco.manager.ApiException as e: + print("Exception when calling WorkerMgtApi->request_worker_status_change: %s\n" % e) +``` + + +### Parameters + +Name | Type | Description | Notes +------------- | ------------- | ------------- | ------------- + **worker_id** | **str**| | + **worker_status_change_request** | [**WorkerStatusChangeRequest**](WorkerStatusChangeRequest.md)| The status change to request. | + +### Return type + +void (empty response body) + +### Authorization + +No authorization required + +### HTTP request headers + + - **Content-Type**: application/json + - **Accept**: application/json + + +### HTTP response details + +| Status code | Description | Response headers | +|-------------|-------------|------------------| +**204** | Status change was accepted. | - | +**0** | Unexpected error. | - | + +[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md) + diff --git a/addon/flamenco/manager/docs/WorkerStatusChangeRequest.md b/addon/flamenco/manager/docs/WorkerStatusChangeRequest.md new file mode 100644 index 00000000..7439d3bc --- /dev/null +++ b/addon/flamenco/manager/docs/WorkerStatusChangeRequest.md @@ -0,0 +1,14 @@ +# WorkerStatusChangeRequest + +Request for a Worker to change its status. + +## Properties +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- +**status_requested** | [**WorkerStatus**](WorkerStatus.md) | | +**is_lazy** | **bool** | Whether the status change should happen immediately, or after the worker's current task is finished. | +**any string name** | **bool, date, datetime, dict, float, int, list, str, none_type** | any string name can be used but the value must be the correct type | [optional] + +[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) + + diff --git a/addon/flamenco/manager/docs/WorkerSummary.md b/addon/flamenco/manager/docs/WorkerSummary.md index f83826db..d09b7728 100644 --- a/addon/flamenco/manager/docs/WorkerSummary.md +++ b/addon/flamenco/manager/docs/WorkerSummary.md @@ -10,6 +10,7 @@ Name | Type | Description | Notes **status** | [**WorkerStatus**](WorkerStatus.md) | | **version** | **str** | Version of Flamenco this Worker is running | **status_requested** | [**WorkerStatus**](WorkerStatus.md) | | [optional] +**lazy_status_request** | **bool** | | [optional] **any string name** | **bool, date, datetime, dict, float, int, list, str, none_type** | any string name can be used but the value must be the correct type | [optional] [[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) diff --git a/addon/flamenco/manager/model/socket_io_worker_update.py b/addon/flamenco/manager/model/socket_io_worker_update.py index afa56452..a129f95e 100644 --- a/addon/flamenco/manager/model/socket_io_worker_update.py +++ b/addon/flamenco/manager/model/socket_io_worker_update.py @@ -94,6 +94,7 @@ class SocketIOWorkerUpdate(ModelNormal): 'version': (str,), # noqa: E501 'previous_status': (WorkerStatus,), # noqa: E501 'status_requested': (WorkerStatus,), # noqa: E501 + 'lazy_status_request': (bool,), # noqa: E501 } @cached_property @@ -109,6 +110,7 @@ class SocketIOWorkerUpdate(ModelNormal): 'version': 'version', # noqa: E501 'previous_status': 'previous_status', # noqa: E501 'status_requested': 'status_requested', # noqa: E501 + 'lazy_status_request': 'lazy_status_request', # noqa: E501 } read_only_vars = { @@ -161,6 +163,7 @@ class SocketIOWorkerUpdate(ModelNormal): _visited_composed_classes = (Animal,) previous_status (WorkerStatus): [optional] # noqa: E501 status_requested (WorkerStatus): [optional] # noqa: E501 + lazy_status_request (bool): Whether the worker is allowed to finish its current task before the status change is enforced. Mandatory when `status_requested` is set. . [optional] # noqa: E501 """ _check_type = kwargs.pop('_check_type', True) @@ -256,6 +259,7 @@ class SocketIOWorkerUpdate(ModelNormal): _visited_composed_classes = (Animal,) previous_status (WorkerStatus): [optional] # noqa: E501 status_requested (WorkerStatus): [optional] # noqa: E501 + lazy_status_request (bool): Whether the worker is allowed to finish its current task before the status change is enforced. Mandatory when `status_requested` is set. . [optional] # noqa: E501 """ _check_type = kwargs.pop('_check_type', True) diff --git a/addon/flamenco/manager/model/worker.py b/addon/flamenco/manager/model/worker.py index 392b772a..63ed3b74 100644 --- a/addon/flamenco/manager/model/worker.py +++ b/addon/flamenco/manager/model/worker.py @@ -99,6 +99,7 @@ class Worker(ModelComposed): 'platform': (str,), # noqa: E501 'supported_task_types': ([str],), # noqa: E501 'status_requested': (WorkerStatus,), # noqa: E501 + 'lazy_status_request': (bool,), # noqa: E501 } @cached_property @@ -115,6 +116,7 @@ class Worker(ModelComposed): 'platform': 'platform', # noqa: E501 'supported_task_types': 'supported_task_types', # noqa: E501 'status_requested': 'status_requested', # noqa: E501 + 'lazy_status_request': 'lazy_status_request', # noqa: E501 } read_only_vars = { @@ -164,6 +166,7 @@ class Worker(ModelComposed): through its discriminator because we passed in _visited_composed_classes = (Animal,) status_requested (WorkerStatus): [optional] # noqa: E501 + lazy_status_request (bool): [optional] # noqa: E501 """ _check_type = kwargs.pop('_check_type', True) @@ -271,6 +274,7 @@ class Worker(ModelComposed): through its discriminator because we passed in _visited_composed_classes = (Animal,) status_requested (WorkerStatus): [optional] # noqa: E501 + lazy_status_request (bool): [optional] # noqa: E501 """ _check_type = kwargs.pop('_check_type', True) diff --git a/addon/flamenco/manager/model/worker_status_change_request.py b/addon/flamenco/manager/model/worker_status_change_request.py new file mode 100644 index 00000000..d3495f0e --- /dev/null +++ b/addon/flamenco/manager/model/worker_status_change_request.py @@ -0,0 +1,273 @@ +""" + Flamenco manager + + Render Farm manager API # noqa: E501 + + The version of the OpenAPI document: 1.0.0 + Generated by: https://openapi-generator.tech +""" + + +import re # noqa: F401 +import sys # noqa: F401 + +from flamenco.manager.model_utils import ( # noqa: F401 + ApiTypeError, + ModelComposed, + ModelNormal, + ModelSimple, + cached_property, + change_keys_js_to_python, + convert_js_args_to_python_args, + date, + datetime, + file_type, + none_type, + validate_get_composed_info, + OpenApiModel +) +from flamenco.manager.exceptions import ApiAttributeError + + +def lazy_import(): + from flamenco.manager.model.worker_status import WorkerStatus + globals()['WorkerStatus'] = WorkerStatus + + +class WorkerStatusChangeRequest(ModelNormal): + """NOTE: This class is auto generated by OpenAPI Generator. + Ref: https://openapi-generator.tech + + Do not edit the class manually. + + Attributes: + allowed_values (dict): The key is the tuple path to the attribute + and the for var_name this is (var_name,). The value is a dict + with a capitalized key describing the allowed value and an allowed + value. These dicts store the allowed enum values. + attribute_map (dict): The key is attribute name + and the value is json key in definition. + discriminator_value_class_map (dict): A dict to go from the discriminator + variable value to the discriminator class name. + validations (dict): The key is the tuple path to the attribute + and the for var_name this is (var_name,). The value is a dict + that stores validations for max_length, min_length, max_items, + min_items, exclusive_maximum, inclusive_maximum, exclusive_minimum, + inclusive_minimum, and regex. + additional_properties_type (tuple): A tuple of classes accepted + as additional properties values. + """ + + allowed_values = { + } + + validations = { + } + + @cached_property + def additional_properties_type(): + """ + This must be a method because a model may have properties that are + of type self, this must run after the class is loaded + """ + lazy_import() + return (bool, date, datetime, dict, float, int, list, str, none_type,) # noqa: E501 + + _nullable = False + + @cached_property + def openapi_types(): + """ + This must be a method because a model may have properties that are + of type self, this must run after the class is loaded + + Returns + openapi_types (dict): The key is attribute name + and the value is attribute type. + """ + lazy_import() + return { + 'status_requested': (WorkerStatus,), # noqa: E501 + 'is_lazy': (bool,), # noqa: E501 + } + + @cached_property + def discriminator(): + return None + + + attribute_map = { + 'status_requested': 'status_requested', # noqa: E501 + 'is_lazy': 'is_lazy', # noqa: E501 + } + + read_only_vars = { + } + + _composed_schemas = {} + + @classmethod + @convert_js_args_to_python_args + def _from_openapi_data(cls, status_requested, is_lazy, *args, **kwargs): # noqa: E501 + """WorkerStatusChangeRequest - a model defined in OpenAPI + + Args: + status_requested (WorkerStatus): + is_lazy (bool): Whether the status change should happen immediately, or after the worker's current task is finished. + + Keyword Args: + _check_type (bool): if True, values for parameters in openapi_types + will be type checked and a TypeError will be + raised if the wrong type is input. + Defaults to True + _path_to_item (tuple/list): This is a list of keys or values to + drill down to the model in received_data + when deserializing a response + _spec_property_naming (bool): True if the variable names in the input data + are serialized names, as specified in the OpenAPI document. + False if the variable names in the input data + are pythonic names, e.g. snake case (default) + _configuration (Configuration): the instance to use when + deserializing a file_type parameter. + If passed, type conversion is attempted + If omitted no type conversion is done. + _visited_composed_classes (tuple): This stores a tuple of + classes that we have traveled through so that + if we see that class again we will not use its + discriminator again. + When traveling through a discriminator, the + composed schema that is + is traveled through is added to this set. + For example if Animal has a discriminator + petType and we pass in "Dog", and the class Dog + allOf includes Animal, we move through Animal + once using the discriminator, and pick Dog. + Then in Dog, we will make an instance of the + Animal class but this time we won't travel + through its discriminator because we passed in + _visited_composed_classes = (Animal,) + """ + + _check_type = kwargs.pop('_check_type', True) + _spec_property_naming = kwargs.pop('_spec_property_naming', False) + _path_to_item = kwargs.pop('_path_to_item', ()) + _configuration = kwargs.pop('_configuration', None) + _visited_composed_classes = kwargs.pop('_visited_composed_classes', ()) + + self = super(OpenApiModel, cls).__new__(cls) + + if args: + raise ApiTypeError( + "Invalid positional arguments=%s passed to %s. Remove those invalid positional arguments." % ( + args, + self.__class__.__name__, + ), + path_to_item=_path_to_item, + valid_classes=(self.__class__,), + ) + + self._data_store = {} + self._check_type = _check_type + self._spec_property_naming = _spec_property_naming + self._path_to_item = _path_to_item + self._configuration = _configuration + self._visited_composed_classes = _visited_composed_classes + (self.__class__,) + + self.status_requested = status_requested + self.is_lazy = is_lazy + for var_name, var_value in kwargs.items(): + if var_name not in self.attribute_map and \ + self._configuration is not None and \ + self._configuration.discard_unknown_keys and \ + self.additional_properties_type is None: + # discard variable. + continue + setattr(self, var_name, var_value) + return self + + required_properties = set([ + '_data_store', + '_check_type', + '_spec_property_naming', + '_path_to_item', + '_configuration', + '_visited_composed_classes', + ]) + + @convert_js_args_to_python_args + def __init__(self, status_requested, is_lazy, *args, **kwargs): # noqa: E501 + """WorkerStatusChangeRequest - a model defined in OpenAPI + + Args: + status_requested (WorkerStatus): + is_lazy (bool): Whether the status change should happen immediately, or after the worker's current task is finished. + + Keyword Args: + _check_type (bool): if True, values for parameters in openapi_types + will be type checked and a TypeError will be + raised if the wrong type is input. + Defaults to True + _path_to_item (tuple/list): This is a list of keys or values to + drill down to the model in received_data + when deserializing a response + _spec_property_naming (bool): True if the variable names in the input data + are serialized names, as specified in the OpenAPI document. + False if the variable names in the input data + are pythonic names, e.g. snake case (default) + _configuration (Configuration): the instance to use when + deserializing a file_type parameter. + If passed, type conversion is attempted + If omitted no type conversion is done. + _visited_composed_classes (tuple): This stores a tuple of + classes that we have traveled through so that + if we see that class again we will not use its + discriminator again. + When traveling through a discriminator, the + composed schema that is + is traveled through is added to this set. + For example if Animal has a discriminator + petType and we pass in "Dog", and the class Dog + allOf includes Animal, we move through Animal + once using the discriminator, and pick Dog. + Then in Dog, we will make an instance of the + Animal class but this time we won't travel + through its discriminator because we passed in + _visited_composed_classes = (Animal,) + """ + + _check_type = kwargs.pop('_check_type', True) + _spec_property_naming = kwargs.pop('_spec_property_naming', False) + _path_to_item = kwargs.pop('_path_to_item', ()) + _configuration = kwargs.pop('_configuration', None) + _visited_composed_classes = kwargs.pop('_visited_composed_classes', ()) + + if args: + raise ApiTypeError( + "Invalid positional arguments=%s passed to %s. Remove those invalid positional arguments." % ( + args, + self.__class__.__name__, + ), + path_to_item=_path_to_item, + valid_classes=(self.__class__,), + ) + + self._data_store = {} + self._check_type = _check_type + self._spec_property_naming = _spec_property_naming + self._path_to_item = _path_to_item + self._configuration = _configuration + self._visited_composed_classes = _visited_composed_classes + (self.__class__,) + + self.status_requested = status_requested + self.is_lazy = is_lazy + for var_name, var_value in kwargs.items(): + if var_name not in self.attribute_map and \ + self._configuration is not None and \ + self._configuration.discard_unknown_keys and \ + self.additional_properties_type is None: + # discard variable. + continue + setattr(self, var_name, var_value) + if var_name in self.read_only_vars: + raise ApiAttributeError(f"`{var_name}` is a read-only attribute. Use `from_openapi_data` to instantiate " + f"class with read only attributes.") diff --git a/addon/flamenco/manager/model/worker_summary.py b/addon/flamenco/manager/model/worker_summary.py index 5783e134..e97cf5cd 100644 --- a/addon/flamenco/manager/model/worker_summary.py +++ b/addon/flamenco/manager/model/worker_summary.py @@ -92,6 +92,7 @@ class WorkerSummary(ModelNormal): 'status': (WorkerStatus,), # noqa: E501 'version': (str,), # noqa: E501 'status_requested': (WorkerStatus,), # noqa: E501 + 'lazy_status_request': (bool,), # noqa: E501 } @cached_property @@ -105,6 +106,7 @@ class WorkerSummary(ModelNormal): 'status': 'status', # noqa: E501 'version': 'version', # noqa: E501 'status_requested': 'status_requested', # noqa: E501 + 'lazy_status_request': 'lazy_status_request', # noqa: E501 } read_only_vars = { @@ -155,6 +157,7 @@ class WorkerSummary(ModelNormal): through its discriminator because we passed in _visited_composed_classes = (Animal,) status_requested (WorkerStatus): [optional] # noqa: E501 + lazy_status_request (bool): [optional] # noqa: E501 """ _check_type = kwargs.pop('_check_type', True) @@ -247,6 +250,7 @@ class WorkerSummary(ModelNormal): through its discriminator because we passed in _visited_composed_classes = (Animal,) status_requested (WorkerStatus): [optional] # noqa: E501 + lazy_status_request (bool): [optional] # noqa: E501 """ _check_type = kwargs.pop('_check_type', True) diff --git a/addon/flamenco/manager/models/__init__.py b/addon/flamenco/manager/models/__init__.py index 14e808dc..a62ee6cf 100644 --- a/addon/flamenco/manager/models/__init__.py +++ b/addon/flamenco/manager/models/__init__.py @@ -62,4 +62,5 @@ from flamenco.manager.model.worker_sign_on import WorkerSignOn from flamenco.manager.model.worker_state_change import WorkerStateChange from flamenco.manager.model.worker_state_changed import WorkerStateChanged from flamenco.manager.model.worker_status import WorkerStatus +from flamenco.manager.model.worker_status_change_request import WorkerStatusChangeRequest from flamenco.manager.model.worker_summary import WorkerSummary diff --git a/addon/flamenco/manager_README.md b/addon/flamenco/manager_README.md index 534d058f..bd8873eb 100644 --- a/addon/flamenco/manager_README.md +++ b/addon/flamenco/manager_README.md @@ -4,7 +4,7 @@ Render Farm manager API The `flamenco.manager` package is automatically generated by the [OpenAPI Generator](https://openapi-generator.tech) project: - API version: 1.0.0 -- Package version: d8233363 +- Package version: cfb17b17 - Build package: org.openapitools.codegen.languages.PythonClientCodegen For more information, please visit [https://flamenco.io/](https://flamenco.io/) @@ -97,6 +97,7 @@ Class | Method | HTTP request | Description *WorkerApi* | [**worker_state_changed**](flamenco/manager/docs/WorkerApi.md#worker_state_changed) | **POST** /api/worker/state-changed | Worker changed state. This could be as acknowledgement of a Manager-requested state change, or in response to worker-local signals. *WorkerMgtApi* | [**fetch_worker**](flamenco/manager/docs/WorkerMgtApi.md#fetch_worker) | **GET** /api/worker-mgt/workers/{worker_id} | Fetch info about the worker. *WorkerMgtApi* | [**fetch_workers**](flamenco/manager/docs/WorkerMgtApi.md#fetch_workers) | **GET** /api/worker-mgt/workers | Get list of workers. +*WorkerMgtApi* | [**request_worker_status_change**](flamenco/manager/docs/WorkerMgtApi.md#request_worker_status_change) | **POST** /api/worker-mgt/workers/{worker_id}/setstatus | ## Documentation For Models @@ -154,6 +155,7 @@ Class | Method | HTTP request | Description - [WorkerStateChange](flamenco/manager/docs/WorkerStateChange.md) - [WorkerStateChanged](flamenco/manager/docs/WorkerStateChanged.md) - [WorkerStatus](flamenco/manager/docs/WorkerStatus.md) + - [WorkerStatusChangeRequest](flamenco/manager/docs/WorkerStatusChangeRequest.md) - [WorkerSummary](flamenco/manager/docs/WorkerSummary.md) diff --git a/internal/worker/mocks/client.gen.go b/internal/worker/mocks/client.gen.go index da25b3ff..0529138d 100644 --- a/internal/worker/mocks/client.gen.go +++ b/internal/worker/mocks/client.gen.go @@ -336,6 +336,46 @@ func (mr *MockFlamencoClientMockRecorder) RegisterWorkerWithResponse(arg0, arg1 return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "RegisterWorkerWithResponse", reflect.TypeOf((*MockFlamencoClient)(nil).RegisterWorkerWithResponse), varargs...) } +// RequestWorkerStatusChangeWithBodyWithResponse mocks base method. +func (m *MockFlamencoClient) RequestWorkerStatusChangeWithBodyWithResponse(arg0 context.Context, arg1, arg2 string, arg3 io.Reader, arg4 ...api.RequestEditorFn) (*api.RequestWorkerStatusChangeResponse, error) { + m.ctrl.T.Helper() + varargs := []interface{}{arg0, arg1, arg2, arg3} + for _, a := range arg4 { + varargs = append(varargs, a) + } + ret := m.ctrl.Call(m, "RequestWorkerStatusChangeWithBodyWithResponse", varargs...) + ret0, _ := ret[0].(*api.RequestWorkerStatusChangeResponse) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// RequestWorkerStatusChangeWithBodyWithResponse indicates an expected call of RequestWorkerStatusChangeWithBodyWithResponse. +func (mr *MockFlamencoClientMockRecorder) RequestWorkerStatusChangeWithBodyWithResponse(arg0, arg1, arg2, arg3 interface{}, arg4 ...interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + varargs := append([]interface{}{arg0, arg1, arg2, arg3}, arg4...) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "RequestWorkerStatusChangeWithBodyWithResponse", reflect.TypeOf((*MockFlamencoClient)(nil).RequestWorkerStatusChangeWithBodyWithResponse), varargs...) +} + +// RequestWorkerStatusChangeWithResponse mocks base method. +func (m *MockFlamencoClient) RequestWorkerStatusChangeWithResponse(arg0 context.Context, arg1 string, arg2 api.RequestWorkerStatusChangeJSONRequestBody, arg3 ...api.RequestEditorFn) (*api.RequestWorkerStatusChangeResponse, error) { + m.ctrl.T.Helper() + varargs := []interface{}{arg0, arg1, arg2} + for _, a := range arg3 { + varargs = append(varargs, a) + } + ret := m.ctrl.Call(m, "RequestWorkerStatusChangeWithResponse", varargs...) + ret0, _ := ret[0].(*api.RequestWorkerStatusChangeResponse) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// RequestWorkerStatusChangeWithResponse indicates an expected call of RequestWorkerStatusChangeWithResponse. +func (mr *MockFlamencoClientMockRecorder) RequestWorkerStatusChangeWithResponse(arg0, arg1, arg2 interface{}, arg3 ...interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + varargs := append([]interface{}{arg0, arg1, arg2}, arg3...) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "RequestWorkerStatusChangeWithResponse", reflect.TypeOf((*MockFlamencoClient)(nil).RequestWorkerStatusChangeWithResponse), varargs...) +} + // ScheduleTaskWithResponse mocks base method. func (m *MockFlamencoClient) ScheduleTaskWithResponse(arg0 context.Context, arg1 ...api.RequestEditorFn) (*api.ScheduleTaskResponse, error) { m.ctrl.T.Helper() diff --git a/pkg/api/openapi_client.gen.go b/pkg/api/openapi_client.gen.go index b8438c95..58d0942f 100644 --- a/pkg/api/openapi_client.gen.go +++ b/pkg/api/openapi_client.gen.go @@ -140,6 +140,11 @@ type ClientInterface interface { // FetchWorker request FetchWorker(ctx context.Context, workerId string, reqEditors ...RequestEditorFn) (*http.Response, error) + // RequestWorkerStatusChange request with any body + RequestWorkerStatusChangeWithBody(ctx context.Context, workerId string, contentType string, body io.Reader, reqEditors ...RequestEditorFn) (*http.Response, error) + + RequestWorkerStatusChange(ctx context.Context, workerId string, body RequestWorkerStatusChangeJSONRequestBody, reqEditors ...RequestEditorFn) (*http.Response, error) + // RegisterWorker request with any body RegisterWorkerWithBody(ctx context.Context, contentType string, body io.Reader, reqEditors ...RequestEditorFn) (*http.Response, error) @@ -405,6 +410,30 @@ func (c *Client) FetchWorker(ctx context.Context, workerId string, reqEditors .. return c.Client.Do(req) } +func (c *Client) RequestWorkerStatusChangeWithBody(ctx context.Context, workerId string, contentType string, body io.Reader, reqEditors ...RequestEditorFn) (*http.Response, error) { + req, err := NewRequestWorkerStatusChangeRequestWithBody(c.Server, workerId, contentType, body) + 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) RequestWorkerStatusChange(ctx context.Context, workerId string, body RequestWorkerStatusChangeJSONRequestBody, reqEditors ...RequestEditorFn) (*http.Response, error) { + req, err := NewRequestWorkerStatusChangeRequest(c.Server, workerId, body) + 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 { @@ -1107,6 +1136,53 @@ func NewFetchWorkerRequest(server string, workerId string) (*http.Request, error return req, nil } +// NewRequestWorkerStatusChangeRequest calls the generic RequestWorkerStatusChange builder with application/json body +func NewRequestWorkerStatusChangeRequest(server string, workerId string, body RequestWorkerStatusChangeJSONRequestBody) (*http.Request, error) { + var bodyReader io.Reader + buf, err := json.Marshal(body) + if err != nil { + return nil, err + } + bodyReader = bytes.NewReader(buf) + return NewRequestWorkerStatusChangeRequestWithBody(server, workerId, "application/json", bodyReader) +} + +// NewRequestWorkerStatusChangeRequestWithBody generates requests for RequestWorkerStatusChange with any type of body +func NewRequestWorkerStatusChangeRequestWithBody(server string, workerId string, contentType string, body io.Reader) (*http.Request, error) { + var err error + + var pathParam0 string + + pathParam0, err = runtime.StyleParamWithLocation("simple", false, "worker_id", runtime.ParamLocationPath, workerId) + if err != nil { + return nil, err + } + + serverURL, err := url.Parse(server) + if err != nil { + return nil, err + } + + operationPath := fmt.Sprintf("/api/worker-mgt/workers/%s/setstatus", pathParam0) + if operationPath[0] == '/' { + operationPath = "." + operationPath + } + + queryURL, err := serverURL.Parse(operationPath) + if err != nil { + return nil, err + } + + req, err := http.NewRequest("POST", queryURL.String(), body) + if err != nil { + return nil, err + } + + req.Header.Add("Content-Type", contentType) + + 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 @@ -1668,6 +1744,11 @@ type ClientWithResponsesInterface interface { // FetchWorker request FetchWorkerWithResponse(ctx context.Context, workerId string, reqEditors ...RequestEditorFn) (*FetchWorkerResponse, error) + // RequestWorkerStatusChange request with any body + RequestWorkerStatusChangeWithBodyWithResponse(ctx context.Context, workerId string, contentType string, body io.Reader, reqEditors ...RequestEditorFn) (*RequestWorkerStatusChangeResponse, error) + + RequestWorkerStatusChangeWithResponse(ctx context.Context, workerId string, body RequestWorkerStatusChangeJSONRequestBody, reqEditors ...RequestEditorFn) (*RequestWorkerStatusChangeResponse, error) + // RegisterWorker request with any body RegisterWorkerWithBodyWithResponse(ctx context.Context, contentType string, body io.Reader, reqEditors ...RequestEditorFn) (*RegisterWorkerResponse, error) @@ -2029,6 +2110,28 @@ func (r FetchWorkerResponse) StatusCode() int { return 0 } +type RequestWorkerStatusChangeResponse struct { + Body []byte + HTTPResponse *http.Response + JSONDefault *Error +} + +// Status returns HTTPResponse.Status +func (r RequestWorkerStatusChangeResponse) Status() string { + if r.HTTPResponse != nil { + return r.HTTPResponse.Status + } + return http.StatusText(0) +} + +// StatusCode returns HTTPResponse.StatusCode +func (r RequestWorkerStatusChangeResponse) StatusCode() int { + if r.HTTPResponse != nil { + return r.HTTPResponse.StatusCode + } + return 0 +} + type RegisterWorkerResponse struct { Body []byte HTTPResponse *http.Response @@ -2462,6 +2565,23 @@ func (c *ClientWithResponses) FetchWorkerWithResponse(ctx context.Context, worke return ParseFetchWorkerResponse(rsp) } +// RequestWorkerStatusChangeWithBodyWithResponse request with arbitrary body returning *RequestWorkerStatusChangeResponse +func (c *ClientWithResponses) RequestWorkerStatusChangeWithBodyWithResponse(ctx context.Context, workerId string, contentType string, body io.Reader, reqEditors ...RequestEditorFn) (*RequestWorkerStatusChangeResponse, error) { + rsp, err := c.RequestWorkerStatusChangeWithBody(ctx, workerId, contentType, body, reqEditors...) + if err != nil { + return nil, err + } + return ParseRequestWorkerStatusChangeResponse(rsp) +} + +func (c *ClientWithResponses) RequestWorkerStatusChangeWithResponse(ctx context.Context, workerId string, body RequestWorkerStatusChangeJSONRequestBody, reqEditors ...RequestEditorFn) (*RequestWorkerStatusChangeResponse, error) { + rsp, err := c.RequestWorkerStatusChange(ctx, workerId, body, reqEditors...) + if err != nil { + return nil, err + } + return ParseRequestWorkerStatusChangeResponse(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...) @@ -3010,6 +3130,32 @@ func ParseFetchWorkerResponse(rsp *http.Response) (*FetchWorkerResponse, error) return response, nil } +// ParseRequestWorkerStatusChangeResponse parses an HTTP response from a RequestWorkerStatusChangeWithResponse call +func ParseRequestWorkerStatusChangeResponse(rsp *http.Response) (*RequestWorkerStatusChangeResponse, error) { + bodyBytes, err := ioutil.ReadAll(rsp.Body) + defer func() { _ = rsp.Body.Close() }() + if err != nil { + return nil, err + } + + response := &RequestWorkerStatusChangeResponse{ + Body: bodyBytes, + HTTPResponse: rsp, + } + + switch { + case strings.Contains(rsp.Header.Get("Content-Type"), "json") && true: + var dest Error + if err := json.Unmarshal(bodyBytes, &dest); err != nil { + return nil, err + } + response.JSONDefault = &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 c53ec28d..f0bd5102 100644 --- a/pkg/api/openapi_server.gen.go +++ b/pkg/api/openapi_server.gen.go @@ -55,6 +55,9 @@ type ServerInterface interface { // Fetch info about the worker. // (GET /api/worker-mgt/workers/{worker_id}) FetchWorker(ctx echo.Context, workerId string) error + + // (POST /api/worker-mgt/workers/{worker_id}/setstatus) + RequestWorkerStatusChange(ctx echo.Context, workerId string) error // Register a new worker // (POST /api/worker/register-worker) RegisterWorker(ctx echo.Context) error @@ -281,6 +284,22 @@ func (w *ServerInterfaceWrapper) FetchWorker(ctx echo.Context) error { return err } +// RequestWorkerStatusChange converts echo context to params. +func (w *ServerInterfaceWrapper) RequestWorkerStatusChange(ctx echo.Context) error { + var err error + // ------------- Path parameter "worker_id" ------------- + var workerId string + + err = runtime.BindStyledParameterWithLocation("simple", false, "worker_id", runtime.ParamLocationPath, ctx.Param("worker_id"), &workerId) + if err != nil { + return echo.NewHTTPError(http.StatusBadRequest, fmt.Sprintf("Invalid format for parameter worker_id: %s", err)) + } + + // Invoke the callback with all the unmarshalled arguments + err = w.Handler.RequestWorkerStatusChange(ctx, workerId) + return err +} + // RegisterWorker converts echo context to params. func (w *ServerInterfaceWrapper) RegisterWorker(ctx echo.Context) error { var err error @@ -524,6 +543,7 @@ func RegisterHandlersWithBaseURL(router EchoRouter, si ServerInterface, baseURL router.GET(baseURL+"/api/version", wrapper.GetVersion) router.GET(baseURL+"/api/worker-mgt/workers", wrapper.FetchWorkers) router.GET(baseURL+"/api/worker-mgt/workers/:worker_id", wrapper.FetchWorker) + router.POST(baseURL+"/api/worker-mgt/workers/:worker_id/setstatus", wrapper.RequestWorkerStatusChange) router.POST(baseURL+"/api/worker/register-worker", wrapper.RegisterWorker) router.POST(baseURL+"/api/worker/sign-off", wrapper.SignOff) router.POST(baseURL+"/api/worker/sign-on", wrapper.SignOn) diff --git a/pkg/api/openapi_spec.gen.go b/pkg/api/openapi_spec.gen.go index 20e75e34..c9a27eaf 100644 --- a/pkg/api/openapi_spec.gen.go +++ b/pkg/api/openapi_spec.gen.go @@ -18,137 +18,139 @@ import ( // Base64 encoded, gzipped, json marshaled Swagger object var swaggerSpec = []string{ - "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", - "AP//3aXGoJmTAAA=", + "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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 09793361..be08a133 100644 --- a/pkg/api/openapi_types.gen.go +++ b/pkg/api/openapi_types.gen.go @@ -451,11 +451,14 @@ type SocketIOTaskUpdate struct { Updated time.Time `json:"updated"` } -// Subset of a Worker, sent over SocketIO when a worker changes. For new workers, `previous_status` will be excluded. +// Subset of a Worker, sent over SocketIO when a worker changes. type SocketIOWorkerUpdate struct { // UUID of the Worker Id string `json:"id"` + // Whether the worker is allowed to finish its current task before the status change is enforced. Mandatory when `status_requested` is set. + LazyStatusRequest *bool `json:"lazy_status_request,omitempty"` + // Name of the worker Nickname string `json:"nickname"` PreviousStatus *WorkerStatus `json:"previous_status,omitempty"` @@ -579,12 +582,20 @@ type WorkerStateChanged struct { // WorkerStatus defines model for WorkerStatus. type WorkerStatus string +// Request for a Worker to change its status. +type WorkerStatusChangeRequest struct { + // Whether the status change should happen immediately, or after the worker's current task is finished. + IsLazy bool `json:"is_lazy"` + StatusRequested WorkerStatus `json:"status_requested"` +} + // Basic information about a Worker. type WorkerSummary struct { - Id string `json:"id"` - Nickname string `json:"nickname"` - Status WorkerStatus `json:"status"` - StatusRequested *WorkerStatus `json:"status_requested,omitempty"` + Id string `json:"id"` + LazyStatusRequest *bool `json:"lazy_status_request,omitempty"` + Nickname string `json:"nickname"` + Status WorkerStatus `json:"status"` + StatusRequested *WorkerStatus `json:"status_requested,omitempty"` // Version of Flamenco this Worker is running Version string `json:"version"` @@ -602,6 +613,9 @@ type SetJobStatusJSONBody JobStatusChange // SetTaskStatusJSONBody defines parameters for SetTaskStatus. type SetTaskStatusJSONBody TaskStatusChange +// RequestWorkerStatusChangeJSONBody defines parameters for RequestWorkerStatusChange. +type RequestWorkerStatusChangeJSONBody WorkerStatusChangeRequest + // RegisterWorkerJSONBody defines parameters for RegisterWorker. type RegisterWorkerJSONBody WorkerRegistration @@ -641,6 +655,9 @@ type SetJobStatusJSONRequestBody SetJobStatusJSONBody // SetTaskStatusJSONRequestBody defines body for SetTaskStatus for application/json ContentType. type SetTaskStatusJSONRequestBody SetTaskStatusJSONBody +// RequestWorkerStatusChangeJSONRequestBody defines body for RequestWorkerStatusChange for application/json ContentType. +type RequestWorkerStatusChangeJSONRequestBody RequestWorkerStatusChangeJSONBody + // RegisterWorkerJSONRequestBody defines body for RegisterWorker for application/json ContentType. type RegisterWorkerJSONRequestBody RegisterWorkerJSONBody diff --git a/web/app/src/manager-api/ApiClient.js b/web/app/src/manager-api/ApiClient.js index 5b758f0e..3f2e30f1 100644 --- a/web/app/src/manager-api/ApiClient.js +++ b/web/app/src/manager-api/ApiClient.js @@ -55,7 +55,7 @@ class ApiClient { * @default {} */ this.defaultHeaders = { - 'User-Agent': 'Flamenco/d8233363 / webbrowser' + 'User-Agent': 'Flamenco/cfb17b17 / webbrowser' }; /** diff --git a/web/app/src/manager-api/index.js b/web/app/src/manager-api/index.js index 1a625f5d..bfd1b457 100644 --- a/web/app/src/manager-api/index.js +++ b/web/app/src/manager-api/index.js @@ -64,6 +64,7 @@ import WorkerSignOn from './model/WorkerSignOn'; import WorkerStateChange from './model/WorkerStateChange'; import WorkerStateChanged from './model/WorkerStateChanged'; import WorkerStatus from './model/WorkerStatus'; +import WorkerStatusChangeRequest from './model/WorkerStatusChangeRequest'; import WorkerSummary from './model/WorkerSummary'; import JobsApi from './manager/JobsApi'; import MetaApi from './manager/MetaApi'; @@ -416,6 +417,12 @@ export { */ WorkerStatus, + /** + * The WorkerStatusChangeRequest model constructor. + * @property {module:model/WorkerStatusChangeRequest} + */ + WorkerStatusChangeRequest, + /** * The WorkerSummary model constructor. * @property {module:model/WorkerSummary} diff --git a/web/app/src/manager-api/manager/WorkerMgtApi.js b/web/app/src/manager-api/manager/WorkerMgtApi.js index de8e346d..506f54f2 100644 --- a/web/app/src/manager-api/manager/WorkerMgtApi.js +++ b/web/app/src/manager-api/manager/WorkerMgtApi.js @@ -13,8 +13,10 @@ import ApiClient from "../ApiClient"; +import Error from '../model/Error'; import Worker from '../model/Worker'; import WorkerList from '../model/WorkerList'; +import WorkerStatusChangeRequest from '../model/WorkerStatusChangeRequest'; /** * WorkerMgt service. @@ -121,4 +123,54 @@ export default class WorkerMgtApi { } + /** + * @param {String} workerId + * @param {module:model/WorkerStatusChangeRequest} workerStatusChangeRequest The status change to request. + * @return {Promise} a {@link https://www.promisejs.org/|Promise}, with an object containing HTTP response + */ + requestWorkerStatusChangeWithHttpInfo(workerId, workerStatusChangeRequest) { + let postBody = workerStatusChangeRequest; + // verify the required parameter 'workerId' is set + if (workerId === undefined || workerId === null) { + throw new Error("Missing the required parameter 'workerId' when calling requestWorkerStatusChange"); + } + // verify the required parameter 'workerStatusChangeRequest' is set + if (workerStatusChangeRequest === undefined || workerStatusChangeRequest === null) { + throw new Error("Missing the required parameter 'workerStatusChangeRequest' when calling requestWorkerStatusChange"); + } + + let pathParams = { + 'worker_id': workerId + }; + let queryParams = { + }; + let headerParams = { + }; + let formParams = { + }; + + let authNames = []; + let contentTypes = ['application/json']; + let accepts = ['application/json']; + let returnType = null; + return this.apiClient.callApi( + '/api/worker-mgt/workers/{worker_id}/setstatus', 'POST', + pathParams, queryParams, headerParams, formParams, postBody, + authNames, contentTypes, accepts, returnType, null + ); + } + + /** + * @param {String} workerId + * @param {module:model/WorkerStatusChangeRequest} workerStatusChangeRequest The status change to request. + * @return {Promise} a {@link https://www.promisejs.org/|Promise} + */ + requestWorkerStatusChange(workerId, workerStatusChangeRequest) { + return this.requestWorkerStatusChangeWithHttpInfo(workerId, workerStatusChangeRequest) + .then(function(response_and_data) { + return response_and_data.data; + }); + } + + } diff --git a/web/app/src/manager-api/model/SocketIOWorkerUpdate.js b/web/app/src/manager-api/model/SocketIOWorkerUpdate.js index 350e7936..93c8b9fb 100644 --- a/web/app/src/manager-api/model/SocketIOWorkerUpdate.js +++ b/web/app/src/manager-api/model/SocketIOWorkerUpdate.js @@ -22,7 +22,7 @@ import WorkerStatus from './WorkerStatus'; class SocketIOWorkerUpdate { /** * Constructs a new SocketIOWorkerUpdate. - * Subset of a Worker, sent over SocketIO when a worker changes. For new workers, `previous_status` will be excluded. + * Subset of a Worker, sent over SocketIO when a worker changes. * @alias module:model/SocketIOWorkerUpdate * @param id {String} UUID of the Worker * @param nickname {String} Name of the worker @@ -77,6 +77,9 @@ class SocketIOWorkerUpdate { if (data.hasOwnProperty('status_requested')) { obj['status_requested'] = WorkerStatus.constructFromObject(data['status_requested']); } + if (data.hasOwnProperty('lazy_status_request')) { + obj['lazy_status_request'] = ApiClient.convertToType(data['lazy_status_request'], 'Boolean'); + } if (data.hasOwnProperty('version')) { obj['version'] = ApiClient.convertToType(data['version'], 'String'); } @@ -120,6 +123,12 @@ SocketIOWorkerUpdate.prototype['previous_status'] = undefined; */ SocketIOWorkerUpdate.prototype['status_requested'] = undefined; +/** + * Whether the worker is allowed to finish its current task before the status change is enforced. Mandatory when `status_requested` is set. + * @member {Boolean} lazy_status_request + */ +SocketIOWorkerUpdate.prototype['lazy_status_request'] = undefined; + /** * @member {String} version */ diff --git a/web/app/src/manager-api/model/Worker.js b/web/app/src/manager-api/model/Worker.js index 7a8118e7..960fafd0 100644 --- a/web/app/src/manager-api/model/Worker.js +++ b/web/app/src/manager-api/model/Worker.js @@ -81,6 +81,9 @@ class Worker { if (data.hasOwnProperty('status_requested')) { obj['status_requested'] = WorkerStatus.constructFromObject(data['status_requested']); } + if (data.hasOwnProperty('lazy_status_request')) { + obj['lazy_status_request'] = ApiClient.convertToType(data['lazy_status_request'], 'Boolean'); + } if (data.hasOwnProperty('version')) { obj['version'] = ApiClient.convertToType(data['version'], 'String'); } @@ -120,6 +123,11 @@ Worker.prototype['status'] = undefined; */ Worker.prototype['status_requested'] = undefined; +/** + * @member {Boolean} lazy_status_request + */ +Worker.prototype['lazy_status_request'] = undefined; + /** * Version of Flamenco this Worker is running * @member {String} version @@ -161,6 +169,10 @@ WorkerSummary.prototype['status'] = undefined; * @member {module:model/WorkerStatus} status_requested */ WorkerSummary.prototype['status_requested'] = undefined; +/** + * @member {Boolean} lazy_status_request + */ +WorkerSummary.prototype['lazy_status_request'] = undefined; /** * Version of Flamenco this Worker is running * @member {String} version diff --git a/web/app/src/manager-api/model/WorkerStatusChangeRequest.js b/web/app/src/manager-api/model/WorkerStatusChangeRequest.js new file mode 100644 index 00000000..673abdca --- /dev/null +++ b/web/app/src/manager-api/model/WorkerStatusChangeRequest.js @@ -0,0 +1,86 @@ +/** + * Flamenco manager + * Render Farm manager API + * + * The version of the OpenAPI document: 1.0.0 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + * + */ + +import ApiClient from '../ApiClient'; +import WorkerStatus from './WorkerStatus'; + +/** + * The WorkerStatusChangeRequest model module. + * @module model/WorkerStatusChangeRequest + * @version 0.0.0 + */ +class WorkerStatusChangeRequest { + /** + * Constructs a new WorkerStatusChangeRequest. + * Request for a Worker to change its status. + * @alias module:model/WorkerStatusChangeRequest + * @param statusRequested {module:model/WorkerStatus} + * @param isLazy {Boolean} Whether the status change should happen immediately, or after the worker's current task is finished. + */ + constructor(statusRequested, isLazy) { + + WorkerStatusChangeRequest.initialize(this, statusRequested, isLazy); + } + + /** + * Initializes the fields of this object. + * This method is used by the constructors of any subclasses, in order to implement multiple inheritance (mix-ins). + * Only for internal use. + */ + static initialize(obj, statusRequested, isLazy) { + obj['status_requested'] = statusRequested; + obj['is_lazy'] = isLazy; + } + + /** + * Constructs a WorkerStatusChangeRequest from a plain JavaScript object, optionally creating a new instance. + * Copies all relevant properties from data to obj if supplied or a new instance if not. + * @param {Object} data The plain JavaScript object bearing properties of interest. + * @param {module:model/WorkerStatusChangeRequest} obj Optional instance to populate. + * @return {module:model/WorkerStatusChangeRequest} The populated WorkerStatusChangeRequest instance. + */ + static constructFromObject(data, obj) { + if (data) { + obj = obj || new WorkerStatusChangeRequest(); + + if (data.hasOwnProperty('status_requested')) { + obj['status_requested'] = WorkerStatus.constructFromObject(data['status_requested']); + } + if (data.hasOwnProperty('is_lazy')) { + obj['is_lazy'] = ApiClient.convertToType(data['is_lazy'], 'Boolean'); + } + } + return obj; + } + + +} + +/** + * @member {module:model/WorkerStatus} status_requested + */ +WorkerStatusChangeRequest.prototype['status_requested'] = undefined; + +/** + * Whether the status change should happen immediately, or after the worker's current task is finished. + * @member {Boolean} is_lazy + */ +WorkerStatusChangeRequest.prototype['is_lazy'] = undefined; + + + + + + +export default WorkerStatusChangeRequest; + diff --git a/web/app/src/manager-api/model/WorkerSummary.js b/web/app/src/manager-api/model/WorkerSummary.js index 0d5bfd49..4afa8fab 100644 --- a/web/app/src/manager-api/model/WorkerSummary.js +++ b/web/app/src/manager-api/model/WorkerSummary.js @@ -69,6 +69,9 @@ class WorkerSummary { if (data.hasOwnProperty('status_requested')) { obj['status_requested'] = WorkerStatus.constructFromObject(data['status_requested']); } + if (data.hasOwnProperty('lazy_status_request')) { + obj['lazy_status_request'] = ApiClient.convertToType(data['lazy_status_request'], 'Boolean'); + } if (data.hasOwnProperty('version')) { obj['version'] = ApiClient.convertToType(data['version'], 'String'); } @@ -99,6 +102,11 @@ WorkerSummary.prototype['status'] = undefined; */ WorkerSummary.prototype['status_requested'] = undefined; +/** + * @member {Boolean} lazy_status_request + */ +WorkerSummary.prototype['lazy_status_request'] = undefined; + /** * Version of Flamenco this Worker is running * @member {String} version