diff --git a/CHANGELOG.md b/CHANGELOG.md index 241b1d80..c9d8bc6f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,7 +8,7 @@ bugs in actually-released versions. - Improve speed of queueing up >100 simultaneous job deletions. - Improve logging of job deletion. -- Add Worker Cluster support. Workers can be members of any number of clusters. Workers will only work on jobs that are assigned to that cluster. Jobs that do not have a cluster will be available to all workers, regardless of their cluster assignment. As a result, clusterless workers will only work on clusterless jobs. +- Add Worker Tag support. Workers can be members of any number of tags. Workers will only work on jobs that are assigned to that tag. Jobs that do not have a tag will be available to all workers, regardless of their tag assignment. As a result, tagless workers will only work on tagless jobs. - Fix limitation where a job could have no more than 1000 tasks ([#104201](https://projects.blender.org/studio/flamenco/issues/104201)) - Add support for finding the top-level 'project' directory. When submitting files to Flamenco, the add-on will try to retain the directory structure of your Blender project as precisely as possible. This new feature allows the add-on to find the top-level directory of your project by finding a `.blender_project`, `.git`, or `.subversion` directory. This can be configured in the add-on preferences. - Worker status is remembered when they sign off, so that workers when they come back online do so to the same state ([#99549](https://projects.blender.org/studio/flamenco/issues/99549)). diff --git a/addon/flamenco/__init__.py b/addon/flamenco/__init__.py index 10de1bc9..7dca8fc3 100644 --- a/addon/flamenco/__init__.py +++ b/addon/flamenco/__init__.py @@ -26,7 +26,7 @@ if __is_first_load: comms, preferences, projects, - worker_clusters, + worker_tags, ) else: import importlib @@ -37,7 +37,7 @@ else: comms = importlib.reload(comms) preferences = importlib.reload(preferences) projects = importlib.reload(projects) - worker_clusters = importlib.reload(worker_clusters) + worker_tags = importlib.reload(worker_tags) import bpy @@ -155,7 +155,7 @@ def register() -> None: ) preferences.register() - worker_clusters.register() + worker_tags.register() operators.register() gui.register() job_types.register() @@ -173,5 +173,5 @@ def unregister() -> None: job_types.unregister() gui.unregister() operators.unregister() - worker_clusters.unregister() + worker_tags.unregister() preferences.unregister() diff --git a/addon/flamenco/gui.py b/addon/flamenco/gui.py index 9ff7d427..d9697f75 100644 --- a/addon/flamenco/gui.py +++ b/addon/flamenco/gui.py @@ -43,10 +43,10 @@ class FLAMENCO_PT_job_submission(bpy.types.Panel): col.prop(context.scene, "flamenco_job_name", text="Job Name") col.prop(context.scene, "flamenco_job_priority", text="Priority") - # Worker cluster: + # Worker tag: row = col.row(align=True) - row.prop(context.scene, "flamenco_worker_cluster", text="Cluster") - row.operator("flamenco.fetch_worker_clusters", text="", icon="FILE_REFRESH") + row.prop(context.scene, "flamenco_worker_tag", text="Tag") + row.operator("flamenco.fetch_worker_tags", text="", icon="FILE_REFRESH") layout.separator() diff --git a/addon/flamenco/job_submission.py b/addon/flamenco/job_submission.py index 95344474..cb40a5c2 100644 --- a/addon/flamenco/job_submission.py +++ b/addon/flamenco/job_submission.py @@ -54,9 +54,9 @@ def job_for_scene(scene: bpy.types.Scene) -> Optional[_SubmittedJob]: type_etag=propgroup.job_type.etag, ) - worker_cluster: str = getattr(scene, "flamenco_worker_cluster", "") - if worker_cluster and worker_cluster != "-": - job.worker_cluster = worker_cluster + worker_tag: str = getattr(scene, "flamenco_worker_tag", "") + if worker_tag and worker_tag != "-": + job.worker_tag = worker_tag return job diff --git a/addon/flamenco/manager/api/worker_mgt_api.py b/addon/flamenco/manager/api/worker_mgt_api.py index bea95e86..ad626625 100644 --- a/addon/flamenco/manager/api/worker_mgt_api.py +++ b/addon/flamenco/manager/api/worker_mgt_api.py @@ -23,12 +23,12 @@ from flamenco.manager.model_utils import ( # noqa: F401 ) from flamenco.manager.model.error import Error from flamenco.manager.model.worker import Worker -from flamenco.manager.model.worker_cluster import WorkerCluster -from flamenco.manager.model.worker_cluster_change_request import WorkerClusterChangeRequest -from flamenco.manager.model.worker_cluster_list import WorkerClusterList from flamenco.manager.model.worker_list import WorkerList from flamenco.manager.model.worker_sleep_schedule import WorkerSleepSchedule from flamenco.manager.model.worker_status_change_request import WorkerStatusChangeRequest +from flamenco.manager.model.worker_tag import WorkerTag +from flamenco.manager.model.worker_tag_change_request import WorkerTagChangeRequest +from flamenco.manager.model.worker_tag_list import WorkerTagList class WorkerMgtApi(object): @@ -42,21 +42,21 @@ class WorkerMgtApi(object): if api_client is None: api_client = ApiClient() self.api_client = api_client - self.create_worker_cluster_endpoint = _Endpoint( + self.create_worker_tag_endpoint = _Endpoint( settings={ - 'response_type': (WorkerCluster,), + 'response_type': (WorkerTag,), 'auth': [], - 'endpoint_path': '/api/v3/worker-mgt/clusters', - 'operation_id': 'create_worker_cluster', + 'endpoint_path': '/api/v3/worker-mgt/tags', + 'operation_id': 'create_worker_tag', 'http_method': 'POST', 'servers': None, }, params_map={ 'all': [ - 'worker_cluster', + 'worker_tag', ], 'required': [ - 'worker_cluster', + 'worker_tag', ], 'nullable': [ ], @@ -71,13 +71,13 @@ class WorkerMgtApi(object): 'allowed_values': { }, 'openapi_types': { - 'worker_cluster': - (WorkerCluster,), + 'worker_tag': + (WorkerTag,), }, 'attribute_map': { }, 'location_map': { - 'worker_cluster': 'body', + 'worker_tag': 'body', }, 'collection_format_map': { } @@ -141,21 +141,21 @@ class WorkerMgtApi(object): }, api_client=api_client ) - self.delete_worker_cluster_endpoint = _Endpoint( + self.delete_worker_tag_endpoint = _Endpoint( settings={ 'response_type': None, 'auth': [], - 'endpoint_path': '/api/v3/worker-mgt/cluster/{cluster_id}', - 'operation_id': 'delete_worker_cluster', + 'endpoint_path': '/api/v3/worker-mgt/tag/{tag_id}', + 'operation_id': 'delete_worker_tag', 'http_method': 'DELETE', 'servers': None, }, params_map={ 'all': [ - 'cluster_id', + 'tag_id', ], 'required': [ - 'cluster_id', + 'tag_id', ], 'nullable': [ ], @@ -170,14 +170,14 @@ class WorkerMgtApi(object): 'allowed_values': { }, 'openapi_types': { - 'cluster_id': + 'tag_id': (str,), }, 'attribute_map': { - 'cluster_id': 'cluster_id', + 'tag_id': 'tag_id', }, 'location_map': { - 'cluster_id': 'path', + 'tag_id': 'path', }, 'collection_format_map': { } @@ -239,97 +239,6 @@ class WorkerMgtApi(object): }, api_client=api_client ) - self.fetch_worker_cluster_endpoint = _Endpoint( - settings={ - 'response_type': (WorkerCluster,), - 'auth': [], - 'endpoint_path': '/api/v3/worker-mgt/cluster/{cluster_id}', - 'operation_id': 'fetch_worker_cluster', - 'http_method': 'GET', - 'servers': None, - }, - params_map={ - 'all': [ - 'cluster_id', - ], - 'required': [ - 'cluster_id', - ], - 'nullable': [ - ], - 'enum': [ - ], - 'validation': [ - ] - }, - root_map={ - 'validations': { - }, - 'allowed_values': { - }, - 'openapi_types': { - 'cluster_id': - (str,), - }, - 'attribute_map': { - 'cluster_id': 'cluster_id', - }, - 'location_map': { - 'cluster_id': 'path', - }, - 'collection_format_map': { - } - }, - headers_map={ - 'accept': [ - 'application/json' - ], - 'content_type': [], - }, - api_client=api_client - ) - self.fetch_worker_clusters_endpoint = _Endpoint( - settings={ - 'response_type': (WorkerClusterList,), - 'auth': [], - 'endpoint_path': '/api/v3/worker-mgt/clusters', - 'operation_id': 'fetch_worker_clusters', - 'http_method': 'GET', - 'servers': None, - }, - params_map={ - 'all': [ - ], - 'required': [], - 'nullable': [ - ], - 'enum': [ - ], - 'validation': [ - ] - }, - root_map={ - 'validations': { - }, - 'allowed_values': { - }, - 'openapi_types': { - }, - 'attribute_map': { - }, - 'location_map': { - }, - 'collection_format_map': { - } - }, - headers_map={ - 'accept': [ - 'application/json' - ], - 'content_type': [], - }, - api_client=api_client - ) self.fetch_worker_sleep_schedule_endpoint = _Endpoint( settings={ 'response_type': (WorkerSleepSchedule,), @@ -379,6 +288,97 @@ class WorkerMgtApi(object): }, api_client=api_client ) + self.fetch_worker_tag_endpoint = _Endpoint( + settings={ + 'response_type': (WorkerTag,), + 'auth': [], + 'endpoint_path': '/api/v3/worker-mgt/tag/{tag_id}', + 'operation_id': 'fetch_worker_tag', + 'http_method': 'GET', + 'servers': None, + }, + params_map={ + 'all': [ + 'tag_id', + ], + 'required': [ + 'tag_id', + ], + 'nullable': [ + ], + 'enum': [ + ], + 'validation': [ + ] + }, + root_map={ + 'validations': { + }, + 'allowed_values': { + }, + 'openapi_types': { + 'tag_id': + (str,), + }, + 'attribute_map': { + 'tag_id': 'tag_id', + }, + 'location_map': { + 'tag_id': 'path', + }, + 'collection_format_map': { + } + }, + headers_map={ + 'accept': [ + 'application/json' + ], + 'content_type': [], + }, + api_client=api_client + ) + self.fetch_worker_tags_endpoint = _Endpoint( + settings={ + 'response_type': (WorkerTagList,), + 'auth': [], + 'endpoint_path': '/api/v3/worker-mgt/tags', + 'operation_id': 'fetch_worker_tags', + 'http_method': 'GET', + 'servers': None, + }, + params_map={ + 'all': [ + ], + 'required': [], + 'nullable': [ + ], + 'enum': [ + ], + 'validation': [ + ] + }, + root_map={ + 'validations': { + }, + 'allowed_values': { + }, + 'openapi_types': { + }, + 'attribute_map': { + }, + 'location_map': { + }, + 'collection_format_map': { + } + }, + headers_map={ + 'accept': [ + 'application/json' + ], + 'content_type': [], + }, + api_client=api_client + ) self.fetch_workers_endpoint = _Endpoint( settings={ 'response_type': (WorkerList,), @@ -477,62 +477,6 @@ class WorkerMgtApi(object): }, api_client=api_client ) - self.set_worker_clusters_endpoint = _Endpoint( - settings={ - 'response_type': None, - 'auth': [], - 'endpoint_path': '/api/v3/worker-mgt/workers/{worker_id}/setclusters', - 'operation_id': 'set_worker_clusters', - 'http_method': 'POST', - 'servers': None, - }, - params_map={ - 'all': [ - 'worker_id', - 'worker_cluster_change_request', - ], - 'required': [ - 'worker_id', - 'worker_cluster_change_request', - ], - 'nullable': [ - ], - 'enum': [ - ], - 'validation': [ - ] - }, - root_map={ - 'validations': { - }, - 'allowed_values': { - }, - 'openapi_types': { - 'worker_id': - (str,), - 'worker_cluster_change_request': - (WorkerClusterChangeRequest,), - }, - 'attribute_map': { - 'worker_id': 'worker_id', - }, - 'location_map': { - 'worker_id': 'path', - 'worker_cluster_change_request': 'body', - }, - 'collection_format_map': { - } - }, - headers_map={ - 'accept': [ - 'application/json' - ], - 'content_type': [ - 'application/json' - ] - }, - api_client=api_client - ) self.set_worker_sleep_schedule_endpoint = _Endpoint( settings={ 'response_type': None, @@ -589,23 +533,23 @@ class WorkerMgtApi(object): }, api_client=api_client ) - self.update_worker_cluster_endpoint = _Endpoint( + self.set_worker_tags_endpoint = _Endpoint( settings={ 'response_type': None, 'auth': [], - 'endpoint_path': '/api/v3/worker-mgt/cluster/{cluster_id}', - 'operation_id': 'update_worker_cluster', - 'http_method': 'PUT', + 'endpoint_path': '/api/v3/worker-mgt/workers/{worker_id}/settags', + 'operation_id': 'set_worker_tags', + 'http_method': 'POST', 'servers': None, }, params_map={ 'all': [ - 'cluster_id', - 'worker_cluster', + 'worker_id', + 'worker_tag_change_request', ], 'required': [ - 'cluster_id', - 'worker_cluster', + 'worker_id', + 'worker_tag_change_request', ], 'nullable': [ ], @@ -620,17 +564,73 @@ class WorkerMgtApi(object): 'allowed_values': { }, 'openapi_types': { - 'cluster_id': + 'worker_id': (str,), - 'worker_cluster': - (WorkerCluster,), + 'worker_tag_change_request': + (WorkerTagChangeRequest,), }, 'attribute_map': { - 'cluster_id': 'cluster_id', + 'worker_id': 'worker_id', }, 'location_map': { - 'cluster_id': 'path', - 'worker_cluster': 'body', + 'worker_id': 'path', + 'worker_tag_change_request': 'body', + }, + 'collection_format_map': { + } + }, + headers_map={ + 'accept': [ + 'application/json' + ], + 'content_type': [ + 'application/json' + ] + }, + api_client=api_client + ) + self.update_worker_tag_endpoint = _Endpoint( + settings={ + 'response_type': None, + 'auth': [], + 'endpoint_path': '/api/v3/worker-mgt/tag/{tag_id}', + 'operation_id': 'update_worker_tag', + 'http_method': 'PUT', + 'servers': None, + }, + params_map={ + 'all': [ + 'tag_id', + 'worker_tag', + ], + 'required': [ + 'tag_id', + 'worker_tag', + ], + 'nullable': [ + ], + 'enum': [ + ], + 'validation': [ + ] + }, + root_map={ + 'validations': { + }, + 'allowed_values': { + }, + 'openapi_types': { + 'tag_id': + (str,), + 'worker_tag': + (WorkerTag,), + }, + 'attribute_map': { + 'tag_id': 'tag_id', + }, + 'location_map': { + 'tag_id': 'path', + 'worker_tag': 'body', }, 'collection_format_map': { } @@ -646,21 +646,21 @@ class WorkerMgtApi(object): api_client=api_client ) - def create_worker_cluster( + def create_worker_tag( self, - worker_cluster, + worker_tag, **kwargs ): - """Create a new worker cluster. # noqa: E501 + """Create a new worker tag. # noqa: E501 This method makes a synchronous HTTP request by default. To make an asynchronous HTTP request, please pass async_req=True - >>> thread = api.create_worker_cluster(worker_cluster, async_req=True) + >>> thread = api.create_worker_tag(worker_tag, async_req=True) >>> result = thread.get() Args: - worker_cluster (WorkerCluster): The worker cluster. + worker_tag (WorkerTag): The worker tag. Keyword Args: _return_http_data_only (bool): response data without head status @@ -691,7 +691,7 @@ class WorkerMgtApi(object): async_req (bool): execute request asynchronously Returns: - WorkerCluster + WorkerTag If the method is called asynchronously, returns the request thread. """ @@ -719,9 +719,9 @@ class WorkerMgtApi(object): kwargs['_content_type'] = kwargs.get( '_content_type') kwargs['_host_index'] = kwargs.get('_host_index') - kwargs['worker_cluster'] = \ - worker_cluster - return self.create_worker_cluster_endpoint.call_with_http_info(**kwargs) + kwargs['worker_tag'] = \ + worker_tag + return self.create_worker_tag_endpoint.call_with_http_info(**kwargs) def delete_worker( self, @@ -800,21 +800,21 @@ class WorkerMgtApi(object): worker_id return self.delete_worker_endpoint.call_with_http_info(**kwargs) - def delete_worker_cluster( + def delete_worker_tag( self, - cluster_id, + tag_id, **kwargs ): - """Remove this worker cluster. This unassigns all workers from the cluster and removes it. # noqa: E501 + """Remove this worker tag. This unassigns all workers from the tag and removes it. # noqa: E501 This method makes a synchronous HTTP request by default. To make an asynchronous HTTP request, please pass async_req=True - >>> thread = api.delete_worker_cluster(cluster_id, async_req=True) + >>> thread = api.delete_worker_tag(tag_id, async_req=True) >>> result = thread.get() Args: - cluster_id (str): + tag_id (str): Keyword Args: _return_http_data_only (bool): response data without head status @@ -873,9 +873,9 @@ class WorkerMgtApi(object): kwargs['_content_type'] = kwargs.get( '_content_type') kwargs['_host_index'] = kwargs.get('_host_index') - kwargs['cluster_id'] = \ - cluster_id - return self.delete_worker_cluster_endpoint.call_with_http_info(**kwargs) + kwargs['tag_id'] = \ + tag_id + return self.delete_worker_tag_endpoint.call_with_http_info(**kwargs) def fetch_worker( self, @@ -954,155 +954,6 @@ class WorkerMgtApi(object): worker_id return self.fetch_worker_endpoint.call_with_http_info(**kwargs) - def fetch_worker_cluster( - self, - cluster_id, - **kwargs - ): - """Get a single worker cluster. # noqa: E501 - - This method makes a synchronous HTTP request by default. To make an - asynchronous HTTP request, please pass async_req=True - - >>> thread = api.fetch_worker_cluster(cluster_id, async_req=True) - >>> result = thread.get() - - Args: - cluster_id (str): - - 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: - WorkerCluster - 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['cluster_id'] = \ - cluster_id - return self.fetch_worker_cluster_endpoint.call_with_http_info(**kwargs) - - def fetch_worker_clusters( - self, - **kwargs - ): - """Get list of worker clusters. # noqa: E501 - - This method makes a synchronous HTTP request by default. To make an - asynchronous HTTP request, please pass async_req=True - - >>> thread = api.fetch_worker_clusters(async_req=True) - >>> result = thread.get() - - - 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: - WorkerClusterList - 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') - return self.fetch_worker_clusters_endpoint.call_with_http_info(**kwargs) - def fetch_worker_sleep_schedule( self, worker_id, @@ -1180,6 +1031,155 @@ class WorkerMgtApi(object): worker_id return self.fetch_worker_sleep_schedule_endpoint.call_with_http_info(**kwargs) + def fetch_worker_tag( + self, + tag_id, + **kwargs + ): + """Get a single worker tag. # noqa: E501 + + This method makes a synchronous HTTP request by default. To make an + asynchronous HTTP request, please pass async_req=True + + >>> thread = api.fetch_worker_tag(tag_id, async_req=True) + >>> result = thread.get() + + Args: + tag_id (str): + + 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: + WorkerTag + 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['tag_id'] = \ + tag_id + return self.fetch_worker_tag_endpoint.call_with_http_info(**kwargs) + + def fetch_worker_tags( + self, + **kwargs + ): + """Get list of worker tags. # noqa: E501 + + This method makes a synchronous HTTP request by default. To make an + asynchronous HTTP request, please pass async_req=True + + >>> thread = api.fetch_worker_tags(async_req=True) + >>> result = thread.get() + + + 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: + WorkerTagList + 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') + return self.fetch_worker_tags_endpoint.call_with_http_info(**kwargs) + def fetch_workers( self, **kwargs @@ -1333,87 +1333,6 @@ class WorkerMgtApi(object): worker_status_change_request return self.request_worker_status_change_endpoint.call_with_http_info(**kwargs) - def set_worker_clusters( - self, - worker_id, - worker_cluster_change_request, - **kwargs - ): - """set_worker_clusters # noqa: E501 - - This method makes a synchronous HTTP request by default. To make an - asynchronous HTTP request, please pass async_req=True - - >>> thread = api.set_worker_clusters(worker_id, worker_cluster_change_request, async_req=True) - >>> result = thread.get() - - Args: - worker_id (str): - worker_cluster_change_request (WorkerClusterChangeRequest): The list of cluster IDs this worker should be a member of. - - 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_cluster_change_request'] = \ - worker_cluster_change_request - return self.set_worker_clusters_endpoint.call_with_http_info(**kwargs) - def set_worker_sleep_schedule( self, worker_id, @@ -1495,23 +1414,23 @@ class WorkerMgtApi(object): worker_sleep_schedule return self.set_worker_sleep_schedule_endpoint.call_with_http_info(**kwargs) - def update_worker_cluster( + def set_worker_tags( self, - cluster_id, - worker_cluster, + worker_id, + worker_tag_change_request, **kwargs ): - """Update an existing worker cluster. # noqa: E501 + """set_worker_tags # noqa: E501 This method makes a synchronous HTTP request by default. To make an asynchronous HTTP request, please pass async_req=True - >>> thread = api.update_worker_cluster(cluster_id, worker_cluster, async_req=True) + >>> thread = api.set_worker_tags(worker_id, worker_tag_change_request, async_req=True) >>> result = thread.get() Args: - cluster_id (str): - worker_cluster (WorkerCluster): The updated worker cluster. + worker_id (str): + worker_tag_change_request (WorkerTagChangeRequest): The list of worker tag IDs this worker should be a member of. Keyword Args: _return_http_data_only (bool): response data without head status @@ -1570,9 +1489,90 @@ class WorkerMgtApi(object): kwargs['_content_type'] = kwargs.get( '_content_type') kwargs['_host_index'] = kwargs.get('_host_index') - kwargs['cluster_id'] = \ - cluster_id - kwargs['worker_cluster'] = \ - worker_cluster - return self.update_worker_cluster_endpoint.call_with_http_info(**kwargs) + kwargs['worker_id'] = \ + worker_id + kwargs['worker_tag_change_request'] = \ + worker_tag_change_request + return self.set_worker_tags_endpoint.call_with_http_info(**kwargs) + + def update_worker_tag( + self, + tag_id, + worker_tag, + **kwargs + ): + """Update an existing worker tag. # noqa: E501 + + This method makes a synchronous HTTP request by default. To make an + asynchronous HTTP request, please pass async_req=True + + >>> thread = api.update_worker_tag(tag_id, worker_tag, async_req=True) + >>> result = thread.get() + + Args: + tag_id (str): + worker_tag (WorkerTag): The updated worker tag. + + 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['tag_id'] = \ + tag_id + kwargs['worker_tag'] = \ + worker_tag + return self.update_worker_tag_endpoint.call_with_http_info(**kwargs) diff --git a/addon/flamenco/manager/docs/Job.md b/addon/flamenco/manager/docs/Job.md index c2021b90..cc3a8eb5 100644 --- a/addon/flamenco/manager/docs/Job.md +++ b/addon/flamenco/manager/docs/Job.md @@ -17,7 +17,7 @@ Name | Type | Description | Notes **settings** | [**JobSettings**](JobSettings.md) | | [optional] **metadata** | [**JobMetadata**](JobMetadata.md) | | [optional] **storage** | [**JobStorageInfo**](JobStorageInfo.md) | | [optional] -**worker_cluster** | **str** | Worker Cluster that should execute this job. When a cluster ID is given, only Workers in that cluster will be scheduled to work on it. If empty or ommitted, all workers can work on this job. | [optional] +**worker_tag** | **str** | Worker tag that should execute this job. When a tag ID is given, only Workers in that tag will be scheduled to work on it. If empty or ommitted, all workers can work on this job. | [optional] **delete_requested_at** | **datetime** | If job deletion was requested, this is the timestamp at which that request was stored on Flamenco Manager. | [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] diff --git a/addon/flamenco/manager/docs/JobsApi.md b/addon/flamenco/manager/docs/JobsApi.md index ef7a169e..6554b71b 100644 --- a/addon/flamenco/manager/docs/JobsApi.md +++ b/addon/flamenco/manager/docs/JobsApi.md @@ -1225,7 +1225,7 @@ with flamenco.manager.ApiClient() as api_client: storage=JobStorageInfo( shaman_checkout_id="shaman_checkout_id_example", ), - worker_cluster="worker_cluster_example", + worker_tag="worker_tag_example", ) # SubmittedJob | Job to submit # example passing only required values which don't have defaults set @@ -1307,7 +1307,7 @@ with flamenco.manager.ApiClient() as api_client: storage=JobStorageInfo( shaman_checkout_id="shaman_checkout_id_example", ), - worker_cluster="worker_cluster_example", + worker_tag="worker_tag_example", ) # SubmittedJob | Job to check # example passing only required values which don't have defaults set diff --git a/addon/flamenco/manager/docs/SubmittedJob.md b/addon/flamenco/manager/docs/SubmittedJob.md index cdb5ac95..e3b22b0d 100644 --- a/addon/flamenco/manager/docs/SubmittedJob.md +++ b/addon/flamenco/manager/docs/SubmittedJob.md @@ -13,7 +13,7 @@ Name | Type | Description | Notes **settings** | [**JobSettings**](JobSettings.md) | | [optional] **metadata** | [**JobMetadata**](JobMetadata.md) | | [optional] **storage** | [**JobStorageInfo**](JobStorageInfo.md) | | [optional] -**worker_cluster** | **str** | Worker Cluster that should execute this job. When a cluster ID is given, only Workers in that cluster will be scheduled to work on it. If empty or ommitted, all workers can work on this job. | [optional] +**worker_tag** | **str** | Worker tag that should execute this job. When a tag ID is given, only Workers in that tag will be scheduled to work on it. If empty or ommitted, all workers can work on this job. | [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 d514ec65..ade74dde 100644 --- a/addon/flamenco/manager/docs/Worker.md +++ b/addon/flamenco/manager/docs/Worker.md @@ -15,7 +15,7 @@ Name | Type | Description | Notes **status_change** | [**WorkerStatusChangeRequest**](WorkerStatusChangeRequest.md) | | [optional] **last_seen** | **datetime** | Last time this worker was seen by the Manager. | [optional] **task** | [**WorkerTask**](WorkerTask.md) | | [optional] -**clusters** | [**[WorkerCluster]**](WorkerCluster.md) | Clusters of which this Worker is a member. | [optional] +**tags** | [**[WorkerTag]**](WorkerTag.md) | Tags of which this Worker is a member. | [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/WorkerAllOf.md b/addon/flamenco/manager/docs/WorkerAllOf.md index 3aa9fb71..8f954366 100644 --- a/addon/flamenco/manager/docs/WorkerAllOf.md +++ b/addon/flamenco/manager/docs/WorkerAllOf.md @@ -8,7 +8,7 @@ Name | Type | Description | Notes **platform** | **str** | Operating system of the Worker | **supported_task_types** | **[str]** | | **task** | [**WorkerTask**](WorkerTask.md) | | [optional] -**clusters** | [**[WorkerCluster]**](WorkerCluster.md) | Clusters of which this Worker is a member. | [optional] +**tags** | [**[WorkerTag]**](WorkerTag.md) | Tags of which this Worker is a member. | [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 a6111337..cb6bdc0e 100644 --- a/addon/flamenco/manager/docs/WorkerMgtApi.md +++ b/addon/flamenco/manager/docs/WorkerMgtApi.md @@ -4,24 +4,24 @@ All URIs are relative to *http://localhost* Method | HTTP request | Description ------------- | ------------- | ------------- -[**create_worker_cluster**](WorkerMgtApi.md#create_worker_cluster) | **POST** /api/v3/worker-mgt/clusters | Create a new worker cluster. +[**create_worker_tag**](WorkerMgtApi.md#create_worker_tag) | **POST** /api/v3/worker-mgt/tags | Create a new worker tag. [**delete_worker**](WorkerMgtApi.md#delete_worker) | **DELETE** /api/v3/worker-mgt/workers/{worker_id} | Remove the given worker. It is recommended to only call this function when the worker is in `offline` state. If the worker is still running, stop it first. Any task still assigned to the worker will be requeued. -[**delete_worker_cluster**](WorkerMgtApi.md#delete_worker_cluster) | **DELETE** /api/v3/worker-mgt/cluster/{cluster_id} | Remove this worker cluster. This unassigns all workers from the cluster and removes it. +[**delete_worker_tag**](WorkerMgtApi.md#delete_worker_tag) | **DELETE** /api/v3/worker-mgt/tag/{tag_id} | Remove this worker tag. This unassigns all workers from the tag and removes it. [**fetch_worker**](WorkerMgtApi.md#fetch_worker) | **GET** /api/v3/worker-mgt/workers/{worker_id} | Fetch info about the worker. -[**fetch_worker_cluster**](WorkerMgtApi.md#fetch_worker_cluster) | **GET** /api/v3/worker-mgt/cluster/{cluster_id} | Get a single worker cluster. -[**fetch_worker_clusters**](WorkerMgtApi.md#fetch_worker_clusters) | **GET** /api/v3/worker-mgt/clusters | Get list of worker clusters. [**fetch_worker_sleep_schedule**](WorkerMgtApi.md#fetch_worker_sleep_schedule) | **GET** /api/v3/worker-mgt/workers/{worker_id}/sleep-schedule | +[**fetch_worker_tag**](WorkerMgtApi.md#fetch_worker_tag) | **GET** /api/v3/worker-mgt/tag/{tag_id} | Get a single worker tag. +[**fetch_worker_tags**](WorkerMgtApi.md#fetch_worker_tags) | **GET** /api/v3/worker-mgt/tags | Get list of worker tags. [**fetch_workers**](WorkerMgtApi.md#fetch_workers) | **GET** /api/v3/worker-mgt/workers | Get list of workers. [**request_worker_status_change**](WorkerMgtApi.md#request_worker_status_change) | **POST** /api/v3/worker-mgt/workers/{worker_id}/setstatus | -[**set_worker_clusters**](WorkerMgtApi.md#set_worker_clusters) | **POST** /api/v3/worker-mgt/workers/{worker_id}/setclusters | [**set_worker_sleep_schedule**](WorkerMgtApi.md#set_worker_sleep_schedule) | **POST** /api/v3/worker-mgt/workers/{worker_id}/sleep-schedule | -[**update_worker_cluster**](WorkerMgtApi.md#update_worker_cluster) | **PUT** /api/v3/worker-mgt/cluster/{cluster_id} | Update an existing worker cluster. +[**set_worker_tags**](WorkerMgtApi.md#set_worker_tags) | **POST** /api/v3/worker-mgt/workers/{worker_id}/settags | +[**update_worker_tag**](WorkerMgtApi.md#update_worker_tag) | **PUT** /api/v3/worker-mgt/tag/{tag_id} | Update an existing worker tag. -# **create_worker_cluster** -> WorkerCluster create_worker_cluster(worker_cluster) +# **create_worker_tag** +> WorkerTag create_worker_tag(worker_tag) -Create a new worker cluster. +Create a new worker tag. ### Example @@ -31,7 +31,7 @@ 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_cluster import WorkerCluster +from flamenco.manager.model.worker_tag import WorkerTag 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. @@ -44,19 +44,19 @@ configuration = flamenco.manager.Configuration( with flamenco.manager.ApiClient() as api_client: # Create an instance of the API class api_instance = worker_mgt_api.WorkerMgtApi(api_client) - worker_cluster = WorkerCluster( + worker_tag = WorkerTag( id="id_example", name="name_example", description="description_example", - ) # WorkerCluster | The worker cluster. + ) # WorkerTag | The worker tag. # example passing only required values which don't have defaults set try: - # Create a new worker cluster. - api_response = api_instance.create_worker_cluster(worker_cluster) + # Create a new worker tag. + api_response = api_instance.create_worker_tag(worker_tag) pprint(api_response) except flamenco.manager.ApiException as e: - print("Exception when calling WorkerMgtApi->create_worker_cluster: %s\n" % e) + print("Exception when calling WorkerMgtApi->create_worker_tag: %s\n" % e) ``` @@ -64,11 +64,11 @@ with flamenco.manager.ApiClient() as api_client: Name | Type | Description | Notes ------------- | ------------- | ------------- | ------------- - **worker_cluster** | [**WorkerCluster**](WorkerCluster.md)| The worker cluster. | + **worker_tag** | [**WorkerTag**](WorkerTag.md)| The worker tag. | ### Return type -[**WorkerCluster**](WorkerCluster.md) +[**WorkerTag**](WorkerTag.md) ### Authorization @@ -84,7 +84,7 @@ No authorization required | Status code | Description | Response headers | |-------------|-------------|------------------| -**200** | The cluster was created. The created cluster is returned, so that the caller can know its UUID. | - | +**200** | The tag was created. The created tag is returned, so that the caller can know its UUID. | - | **0** | Error message | - | [[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) @@ -154,10 +154,10 @@ 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) -# **delete_worker_cluster** -> delete_worker_cluster(cluster_id) +# **delete_worker_tag** +> delete_worker_tag(tag_id) -Remove this worker cluster. This unassigns all workers from the cluster and removes it. +Remove this worker tag. This unassigns all workers from the tag and removes it. ### Example @@ -179,14 +179,14 @@ configuration = flamenco.manager.Configuration( with flamenco.manager.ApiClient() as api_client: # Create an instance of the API class api_instance = worker_mgt_api.WorkerMgtApi(api_client) - cluster_id = "cluster_id_example" # str | + tag_id = "tag_id_example" # str | # example passing only required values which don't have defaults set try: - # Remove this worker cluster. This unassigns all workers from the cluster and removes it. - api_instance.delete_worker_cluster(cluster_id) + # Remove this worker tag. This unassigns all workers from the tag and removes it. + api_instance.delete_worker_tag(tag_id) except flamenco.manager.ApiException as e: - print("Exception when calling WorkerMgtApi->delete_worker_cluster: %s\n" % e) + print("Exception when calling WorkerMgtApi->delete_worker_tag: %s\n" % e) ``` @@ -194,7 +194,7 @@ with flamenco.manager.ApiClient() as api_client: Name | Type | Description | Notes ------------- | ------------- | ------------- | ------------- - **cluster_id** | **str**| | + **tag_id** | **str**| | ### Return type @@ -214,7 +214,7 @@ No authorization required | Status code | Description | Response headers | |-------------|-------------|------------------| -**204** | The cluster has been removed. | - | +**204** | The tag has been removed. | - | **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) @@ -284,132 +284,6 @@ 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) -# **fetch_worker_cluster** -> WorkerCluster fetch_worker_cluster(cluster_id) - -Get a single worker cluster. - -### Example - - -```python -import time -import flamenco.manager -from flamenco.manager.api import worker_mgt_api -from flamenco.manager.model.worker_cluster import WorkerCluster -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) - cluster_id = "cluster_id_example" # str | - - # example passing only required values which don't have defaults set - try: - # Get a single worker cluster. - api_response = api_instance.fetch_worker_cluster(cluster_id) - pprint(api_response) - except flamenco.manager.ApiException as e: - print("Exception when calling WorkerMgtApi->fetch_worker_cluster: %s\n" % e) -``` - - -### Parameters - -Name | Type | Description | Notes -------------- | ------------- | ------------- | ------------- - **cluster_id** | **str**| | - -### Return type - -[**WorkerCluster**](WorkerCluster.md) - -### Authorization - -No authorization required - -### HTTP request headers - - - **Content-Type**: Not defined - - **Accept**: application/json - - -### HTTP response details - -| Status code | Description | Response headers | -|-------------|-------------|------------------| -**200** | The worker cluster. | - | - -[[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) - -# **fetch_worker_clusters** -> WorkerClusterList fetch_worker_clusters() - -Get list of worker clusters. - -### Example - - -```python -import time -import flamenco.manager -from flamenco.manager.api import worker_mgt_api -from flamenco.manager.model.worker_cluster_list import WorkerClusterList -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) - - # example, this endpoint has no required or optional parameters - try: - # Get list of worker clusters. - api_response = api_instance.fetch_worker_clusters() - pprint(api_response) - except flamenco.manager.ApiException as e: - print("Exception when calling WorkerMgtApi->fetch_worker_clusters: %s\n" % e) -``` - - -### Parameters -This endpoint does not need any parameter. - -### Return type - -[**WorkerClusterList**](WorkerClusterList.md) - -### Authorization - -No authorization required - -### HTTP request headers - - - **Content-Type**: Not defined - - **Accept**: application/json - - -### HTTP response details - -| Status code | Description | Response headers | -|-------------|-------------|------------------| -**200** | Worker clusters. | - | - -[[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) - # **fetch_worker_sleep_schedule** > WorkerSleepSchedule fetch_worker_sleep_schedule(worker_id) @@ -477,6 +351,132 @@ 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) +# **fetch_worker_tag** +> WorkerTag fetch_worker_tag(tag_id) + +Get a single worker tag. + +### Example + + +```python +import time +import flamenco.manager +from flamenco.manager.api import worker_mgt_api +from flamenco.manager.model.worker_tag import WorkerTag +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) + tag_id = "tag_id_example" # str | + + # example passing only required values which don't have defaults set + try: + # Get a single worker tag. + api_response = api_instance.fetch_worker_tag(tag_id) + pprint(api_response) + except flamenco.manager.ApiException as e: + print("Exception when calling WorkerMgtApi->fetch_worker_tag: %s\n" % e) +``` + + +### Parameters + +Name | Type | Description | Notes +------------- | ------------- | ------------- | ------------- + **tag_id** | **str**| | + +### Return type + +[**WorkerTag**](WorkerTag.md) + +### Authorization + +No authorization required + +### HTTP request headers + + - **Content-Type**: Not defined + - **Accept**: application/json + + +### HTTP response details + +| Status code | Description | Response headers | +|-------------|-------------|------------------| +**200** | The worker tag. | - | + +[[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) + +# **fetch_worker_tags** +> WorkerTagList fetch_worker_tags() + +Get list of worker tags. + +### Example + + +```python +import time +import flamenco.manager +from flamenco.manager.api import worker_mgt_api +from flamenco.manager.model.worker_tag_list import WorkerTagList +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) + + # example, this endpoint has no required or optional parameters + try: + # Get list of worker tags. + api_response = api_instance.fetch_worker_tags() + pprint(api_response) + except flamenco.manager.ApiException as e: + print("Exception when calling WorkerMgtApi->fetch_worker_tags: %s\n" % e) +``` + + +### Parameters +This endpoint does not need any parameter. + +### Return type + +[**WorkerTagList**](WorkerTagList.md) + +### Authorization + +No authorization required + +### HTTP request headers + + - **Content-Type**: Not defined + - **Accept**: application/json + + +### HTTP response details + +| Status code | Description | Response headers | +|-------------|-------------|------------------| +**200** | Worker tags. | - | + +[[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) + # **fetch_workers** > WorkerList fetch_workers() @@ -599,77 +599,6 @@ No authorization required - **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) - -# **set_worker_clusters** -> set_worker_clusters(worker_id, worker_cluster_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_cluster_change_request import WorkerClusterChangeRequest -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_cluster_change_request = WorkerClusterChangeRequest( - cluster_ids=[ - "cluster_ids_example", - ], - ) # WorkerClusterChangeRequest | The list of cluster IDs this worker should be a member of. - - # example passing only required values which don't have defaults set - try: - api_instance.set_worker_clusters(worker_id, worker_cluster_change_request) - except flamenco.manager.ApiException as e: - print("Exception when calling WorkerMgtApi->set_worker_clusters: %s\n" % e) -``` - - -### Parameters - -Name | Type | Description | Notes -------------- | ------------- | ------------- | ------------- - **worker_id** | **str**| | - **worker_cluster_change_request** | [**WorkerClusterChangeRequest**](WorkerClusterChangeRequest.md)| The list of cluster IDs this worker should be a member of. | - -### 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 | @@ -751,10 +680,10 @@ 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) -# **update_worker_cluster** -> update_worker_cluster(cluster_id, worker_cluster) +# **set_worker_tags** +> set_worker_tags(worker_id, worker_tag_change_request) + -Update an existing worker cluster. ### Example @@ -764,7 +693,7 @@ 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_cluster import WorkerCluster +from flamenco.manager.model.worker_tag_change_request import WorkerTagChangeRequest 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. @@ -777,19 +706,18 @@ configuration = flamenco.manager.Configuration( with flamenco.manager.ApiClient() as api_client: # Create an instance of the API class api_instance = worker_mgt_api.WorkerMgtApi(api_client) - cluster_id = "cluster_id_example" # str | - worker_cluster = WorkerCluster( - id="id_example", - name="name_example", - description="description_example", - ) # WorkerCluster | The updated worker cluster. + worker_id = "worker_id_example" # str | + worker_tag_change_request = WorkerTagChangeRequest( + tag_ids=[ + "tag_ids_example", + ], + ) # WorkerTagChangeRequest | The list of worker tag IDs this worker should be a member of. # example passing only required values which don't have defaults set try: - # Update an existing worker cluster. - api_instance.update_worker_cluster(cluster_id, worker_cluster) + api_instance.set_worker_tags(worker_id, worker_tag_change_request) except flamenco.manager.ApiException as e: - print("Exception when calling WorkerMgtApi->update_worker_cluster: %s\n" % e) + print("Exception when calling WorkerMgtApi->set_worker_tags: %s\n" % e) ``` @@ -797,8 +725,8 @@ with flamenco.manager.ApiClient() as api_client: Name | Type | Description | Notes ------------- | ------------- | ------------- | ------------- - **cluster_id** | **str**| | - **worker_cluster** | [**WorkerCluster**](WorkerCluster.md)| The updated worker cluster. | + **worker_id** | **str**| | + **worker_tag_change_request** | [**WorkerTagChangeRequest**](WorkerTagChangeRequest.md)| The list of worker tag IDs this worker should be a member of. | ### Return type @@ -818,7 +746,79 @@ No authorization required | Status code | Description | Response headers | |-------------|-------------|------------------| -**204** | The cluster update has been stored. | - | +**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) + +# **update_worker_tag** +> update_worker_tag(tag_id, worker_tag) + +Update an existing worker tag. + +### 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_tag import WorkerTag +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) + tag_id = "tag_id_example" # str | + worker_tag = WorkerTag( + id="id_example", + name="name_example", + description="description_example", + ) # WorkerTag | The updated worker tag. + + # example passing only required values which don't have defaults set + try: + # Update an existing worker tag. + api_instance.update_worker_tag(tag_id, worker_tag) + except flamenco.manager.ApiException as e: + print("Exception when calling WorkerMgtApi->update_worker_tag: %s\n" % e) +``` + + +### Parameters + +Name | Type | Description | Notes +------------- | ------------- | ------------- | ------------- + **tag_id** | **str**| | + **worker_tag** | [**WorkerTag**](WorkerTag.md)| The updated worker tag. | + +### 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** | The tag update has been stored. | - | **0** | Error message | - | [[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/WorkerCluster.md b/addon/flamenco/manager/docs/WorkerTag.md similarity index 62% rename from addon/flamenco/manager/docs/WorkerCluster.md rename to addon/flamenco/manager/docs/WorkerTag.md index 37e89092..a245b1ab 100644 --- a/addon/flamenco/manager/docs/WorkerCluster.md +++ b/addon/flamenco/manager/docs/WorkerTag.md @@ -1,12 +1,12 @@ -# WorkerCluster +# WorkerTag -Cluster of workers. A job can optionally specify which cluster it should be limited to. Workers can be part of multiple clusters simultaneously. +Tag of workers. A job can optionally specify which tag it should be limited to. Workers can be part of multiple tags simultaneously. ## Properties Name | Type | Description | Notes ------------ | ------------- | ------------- | ------------- **name** | **str** | | -**id** | **str** | UUID of the cluster. Can be ommitted when creating a new cluster, in which case a random UUID will be assigned. | [optional] +**id** | **str** | UUID of the tag. Can be ommitted when creating a new tag, in which case a random UUID will be assigned. | [optional] **description** | **str** | | [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] diff --git a/addon/flamenco/manager/docs/WorkerClusterChangeRequest.md b/addon/flamenco/manager/docs/WorkerTagChangeRequest.md similarity index 78% rename from addon/flamenco/manager/docs/WorkerClusterChangeRequest.md rename to addon/flamenco/manager/docs/WorkerTagChangeRequest.md index 4aecc43c..54eb5872 100644 --- a/addon/flamenco/manager/docs/WorkerClusterChangeRequest.md +++ b/addon/flamenco/manager/docs/WorkerTagChangeRequest.md @@ -1,11 +1,11 @@ -# WorkerClusterChangeRequest +# WorkerTagChangeRequest -Request to change which clusters this Worker is assigned to. +Request to change which tags this Worker is assigned to. ## Properties Name | Type | Description | Notes ------------ | ------------- | ------------- | ------------- -**cluster_ids** | **[str]** | | +**tag_ids** | **[str]** | | **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/WorkerClusterList.md b/addon/flamenco/manager/docs/WorkerTagList.md similarity index 82% rename from addon/flamenco/manager/docs/WorkerClusterList.md rename to addon/flamenco/manager/docs/WorkerTagList.md index 530ce72b..3733dea7 100644 --- a/addon/flamenco/manager/docs/WorkerClusterList.md +++ b/addon/flamenco/manager/docs/WorkerTagList.md @@ -1,10 +1,10 @@ -# WorkerClusterList +# WorkerTagList ## Properties Name | Type | Description | Notes ------------ | ------------- | ------------- | ------------- -**clusters** | [**[WorkerCluster]**](WorkerCluster.md) | | [optional] +**tags** | [**[WorkerTag]**](WorkerTag.md) | | [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/job.py b/addon/flamenco/manager/model/job.py index 98939894..6918b169 100644 --- a/addon/flamenco/manager/model/job.py +++ b/addon/flamenco/manager/model/job.py @@ -110,7 +110,7 @@ class Job(ModelComposed): 'settings': (JobSettings,), # noqa: E501 'metadata': (JobMetadata,), # noqa: E501 'storage': (JobStorageInfo,), # noqa: E501 - 'worker_cluster': (str,), # noqa: E501 + 'worker_tag': (str,), # noqa: E501 'delete_requested_at': (datetime,), # noqa: E501 } @@ -133,7 +133,7 @@ class Job(ModelComposed): 'settings': 'settings', # noqa: E501 'metadata': 'metadata', # noqa: E501 'storage': 'storage', # noqa: E501 - 'worker_cluster': 'worker_cluster', # noqa: E501 + 'worker_tag': 'worker_tag', # noqa: E501 'delete_requested_at': 'delete_requested_at', # noqa: E501 } @@ -189,7 +189,7 @@ class Job(ModelComposed): settings (JobSettings): [optional] # noqa: E501 metadata (JobMetadata): [optional] # noqa: E501 storage (JobStorageInfo): [optional] # noqa: E501 - worker_cluster (str): Worker Cluster that should execute this job. When a cluster ID is given, only Workers in that cluster will be scheduled to work on it. If empty or ommitted, all workers can work on this job. . [optional] # noqa: E501 + worker_tag (str): Worker tag that should execute this job. When a tag ID is given, only Workers in that tag will be scheduled to work on it. If empty or ommitted, all workers can work on this job. . [optional] # noqa: E501 delete_requested_at (datetime): If job deletion was requested, this is the timestamp at which that request was stored on Flamenco Manager. . [optional] # noqa: E501 """ @@ -304,7 +304,7 @@ class Job(ModelComposed): settings (JobSettings): [optional] # noqa: E501 metadata (JobMetadata): [optional] # noqa: E501 storage (JobStorageInfo): [optional] # noqa: E501 - worker_cluster (str): Worker Cluster that should execute this job. When a cluster ID is given, only Workers in that cluster will be scheduled to work on it. If empty or ommitted, all workers can work on this job. . [optional] # noqa: E501 + worker_tag (str): Worker tag that should execute this job. When a tag ID is given, only Workers in that tag will be scheduled to work on it. If empty or ommitted, all workers can work on this job. . [optional] # noqa: E501 delete_requested_at (datetime): If job deletion was requested, this is the timestamp at which that request was stored on Flamenco Manager. . [optional] # noqa: E501 """ diff --git a/addon/flamenco/manager/model/submitted_job.py b/addon/flamenco/manager/model/submitted_job.py index 6cdf0417..ce91ed25 100644 --- a/addon/flamenco/manager/model/submitted_job.py +++ b/addon/flamenco/manager/model/submitted_job.py @@ -99,7 +99,7 @@ class SubmittedJob(ModelNormal): 'settings': (JobSettings,), # noqa: E501 'metadata': (JobMetadata,), # noqa: E501 'storage': (JobStorageInfo,), # noqa: E501 - 'worker_cluster': (str,), # noqa: E501 + 'worker_tag': (str,), # noqa: E501 } @cached_property @@ -116,7 +116,7 @@ class SubmittedJob(ModelNormal): 'settings': 'settings', # noqa: E501 'metadata': 'metadata', # noqa: E501 'storage': 'storage', # noqa: E501 - 'worker_cluster': 'worker_cluster', # noqa: E501 + 'worker_tag': 'worker_tag', # noqa: E501 } read_only_vars = { @@ -170,7 +170,7 @@ class SubmittedJob(ModelNormal): settings (JobSettings): [optional] # noqa: E501 metadata (JobMetadata): [optional] # noqa: E501 storage (JobStorageInfo): [optional] # noqa: E501 - worker_cluster (str): Worker Cluster that should execute this job. When a cluster ID is given, only Workers in that cluster will be scheduled to work on it. If empty or ommitted, all workers can work on this job. . [optional] # noqa: E501 + worker_tag (str): Worker tag that should execute this job. When a tag ID is given, only Workers in that tag will be scheduled to work on it. If empty or ommitted, all workers can work on this job. . [optional] # noqa: E501 """ priority = kwargs.get('priority', 50) @@ -267,7 +267,7 @@ class SubmittedJob(ModelNormal): settings (JobSettings): [optional] # noqa: E501 metadata (JobMetadata): [optional] # noqa: E501 storage (JobStorageInfo): [optional] # noqa: E501 - worker_cluster (str): Worker Cluster that should execute this job. When a cluster ID is given, only Workers in that cluster will be scheduled to work on it. If empty or ommitted, all workers can work on this job. . [optional] # noqa: E501 + worker_tag (str): Worker tag that should execute this job. When a tag ID is given, only Workers in that tag will be scheduled to work on it. If empty or ommitted, all workers can work on this job. . [optional] # noqa: E501 """ priority = kwargs.get('priority', 50) diff --git a/addon/flamenco/manager/model/worker.py b/addon/flamenco/manager/model/worker.py index 2f35c7d4..4d48dd85 100644 --- a/addon/flamenco/manager/model/worker.py +++ b/addon/flamenco/manager/model/worker.py @@ -31,16 +31,16 @@ from flamenco.manager.exceptions import ApiAttributeError def lazy_import(): from flamenco.manager.model.worker_all_of import WorkerAllOf - from flamenco.manager.model.worker_cluster import WorkerCluster 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 + from flamenco.manager.model.worker_tag import WorkerTag from flamenco.manager.model.worker_task import WorkerTask globals()['WorkerAllOf'] = WorkerAllOf - globals()['WorkerCluster'] = WorkerCluster globals()['WorkerStatus'] = WorkerStatus globals()['WorkerStatusChangeRequest'] = WorkerStatusChangeRequest globals()['WorkerSummary'] = WorkerSummary + globals()['WorkerTag'] = WorkerTag globals()['WorkerTask'] = WorkerTask @@ -107,7 +107,7 @@ class Worker(ModelComposed): 'status_change': (WorkerStatusChangeRequest,), # noqa: E501 'last_seen': (datetime,), # noqa: E501 'task': (WorkerTask,), # noqa: E501 - 'clusters': ([WorkerCluster],), # noqa: E501 + 'tags': ([WorkerTag],), # noqa: E501 } @cached_property @@ -126,7 +126,7 @@ class Worker(ModelComposed): 'status_change': 'status_change', # noqa: E501 'last_seen': 'last_seen', # noqa: E501 'task': 'task', # noqa: E501 - 'clusters': 'clusters', # noqa: E501 + 'tags': 'tags', # noqa: E501 } read_only_vars = { @@ -178,7 +178,7 @@ class Worker(ModelComposed): status_change (WorkerStatusChangeRequest): [optional] # noqa: E501 last_seen (datetime): Last time this worker was seen by the Manager.. [optional] # noqa: E501 task (WorkerTask): [optional] # noqa: E501 - clusters ([WorkerCluster]): Clusters of which this Worker is a member.. [optional] # noqa: E501 + tags ([WorkerTag]): Tags of which this Worker is a member.. [optional] # noqa: E501 """ _check_type = kwargs.pop('_check_type', True) @@ -288,7 +288,7 @@ class Worker(ModelComposed): status_change (WorkerStatusChangeRequest): [optional] # noqa: E501 last_seen (datetime): Last time this worker was seen by the Manager.. [optional] # noqa: E501 task (WorkerTask): [optional] # noqa: E501 - clusters ([WorkerCluster]): Clusters of which this Worker is a member.. [optional] # noqa: E501 + tags ([WorkerTag]): Tags of which this Worker is a member.. [optional] # noqa: E501 """ _check_type = kwargs.pop('_check_type', True) diff --git a/addon/flamenco/manager/model/worker_all_of.py b/addon/flamenco/manager/model/worker_all_of.py index 0cab4910..7196901b 100644 --- a/addon/flamenco/manager/model/worker_all_of.py +++ b/addon/flamenco/manager/model/worker_all_of.py @@ -30,9 +30,9 @@ from flamenco.manager.exceptions import ApiAttributeError def lazy_import(): - from flamenco.manager.model.worker_cluster import WorkerCluster + from flamenco.manager.model.worker_tag import WorkerTag from flamenco.manager.model.worker_task import WorkerTask - globals()['WorkerCluster'] = WorkerCluster + globals()['WorkerTag'] = WorkerTag globals()['WorkerTask'] = WorkerTask @@ -93,7 +93,7 @@ class WorkerAllOf(ModelNormal): 'platform': (str,), # noqa: E501 'supported_task_types': ([str],), # noqa: E501 'task': (WorkerTask,), # noqa: E501 - 'clusters': ([WorkerCluster],), # noqa: E501 + 'tags': ([WorkerTag],), # noqa: E501 } @cached_property @@ -106,7 +106,7 @@ class WorkerAllOf(ModelNormal): 'platform': 'platform', # noqa: E501 'supported_task_types': 'supported_task_types', # noqa: E501 'task': 'task', # noqa: E501 - 'clusters': 'clusters', # noqa: E501 + 'tags': 'tags', # noqa: E501 } read_only_vars = { @@ -156,7 +156,7 @@ class WorkerAllOf(ModelNormal): through its discriminator because we passed in _visited_composed_classes = (Animal,) task (WorkerTask): [optional] # noqa: E501 - clusters ([WorkerCluster]): Clusters of which this Worker is a member.. [optional] # noqa: E501 + tags ([WorkerTag]): Tags of which this Worker is a member.. [optional] # noqa: E501 """ _check_type = kwargs.pop('_check_type', True) @@ -247,7 +247,7 @@ class WorkerAllOf(ModelNormal): through its discriminator because we passed in _visited_composed_classes = (Animal,) task (WorkerTask): [optional] # noqa: E501 - clusters ([WorkerCluster]): Clusters of which this Worker is a member.. [optional] # noqa: E501 + tags ([WorkerTag]): Tags of which this Worker is a member.. [optional] # noqa: E501 """ _check_type = kwargs.pop('_check_type', True) diff --git a/addon/flamenco/manager/model/worker_cluster.py b/addon/flamenco/manager/model/worker_tag.py similarity index 96% rename from addon/flamenco/manager/model/worker_cluster.py rename to addon/flamenco/manager/model/worker_tag.py index d8637c2f..3d91bab8 100644 --- a/addon/flamenco/manager/model/worker_cluster.py +++ b/addon/flamenco/manager/model/worker_tag.py @@ -30,7 +30,7 @@ from flamenco.manager.exceptions import ApiAttributeError -class WorkerCluster(ModelNormal): +class WorkerTag(ModelNormal): """NOTE: This class is auto generated by OpenAPI Generator. Ref: https://openapi-generator.tech @@ -105,7 +105,7 @@ class WorkerCluster(ModelNormal): @classmethod @convert_js_args_to_python_args def _from_openapi_data(cls, name, *args, **kwargs): # noqa: E501 - """WorkerCluster - a model defined in OpenAPI + """WorkerTag - a model defined in OpenAPI Args: name (str): @@ -141,7 +141,7 @@ class WorkerCluster(ModelNormal): Animal class but this time we won't travel through its discriminator because we passed in _visited_composed_classes = (Animal,) - id (str): UUID of the cluster. Can be ommitted when creating a new cluster, in which case a random UUID will be assigned. . [optional] # noqa: E501 + id (str): UUID of the tag. Can be ommitted when creating a new tag, in which case a random UUID will be assigned. . [optional] # noqa: E501 description (str): [optional] # noqa: E501 """ @@ -192,7 +192,7 @@ class WorkerCluster(ModelNormal): @convert_js_args_to_python_args def __init__(self, name, *args, **kwargs): # noqa: E501 - """WorkerCluster - a model defined in OpenAPI + """WorkerTag - a model defined in OpenAPI Args: name (str): @@ -228,7 +228,7 @@ class WorkerCluster(ModelNormal): Animal class but this time we won't travel through its discriminator because we passed in _visited_composed_classes = (Animal,) - id (str): UUID of the cluster. Can be ommitted when creating a new cluster, in which case a random UUID will be assigned. . [optional] # noqa: E501 + id (str): UUID of the tag. Can be ommitted when creating a new tag, in which case a random UUID will be assigned. . [optional] # noqa: E501 description (str): [optional] # noqa: E501 """ diff --git a/addon/flamenco/manager/model/worker_cluster_change_request.py b/addon/flamenco/manager/model/worker_tag_change_request.py similarity index 94% rename from addon/flamenco/manager/model/worker_cluster_change_request.py rename to addon/flamenco/manager/model/worker_tag_change_request.py index 9a2b609d..656972f6 100644 --- a/addon/flamenco/manager/model/worker_cluster_change_request.py +++ b/addon/flamenco/manager/model/worker_tag_change_request.py @@ -30,7 +30,7 @@ from flamenco.manager.exceptions import ApiAttributeError -class WorkerClusterChangeRequest(ModelNormal): +class WorkerTagChangeRequest(ModelNormal): """NOTE: This class is auto generated by OpenAPI Generator. Ref: https://openapi-generator.tech @@ -81,7 +81,7 @@ class WorkerClusterChangeRequest(ModelNormal): and the value is attribute type. """ return { - 'cluster_ids': ([str],), # noqa: E501 + 'tag_ids': ([str],), # noqa: E501 } @cached_property @@ -90,7 +90,7 @@ class WorkerClusterChangeRequest(ModelNormal): attribute_map = { - 'cluster_ids': 'cluster_ids', # noqa: E501 + 'tag_ids': 'tag_ids', # noqa: E501 } read_only_vars = { @@ -100,11 +100,11 @@ class WorkerClusterChangeRequest(ModelNormal): @classmethod @convert_js_args_to_python_args - def _from_openapi_data(cls, cluster_ids, *args, **kwargs): # noqa: E501 - """WorkerClusterChangeRequest - a model defined in OpenAPI + def _from_openapi_data(cls, tag_ids, *args, **kwargs): # noqa: E501 + """WorkerTagChangeRequest - a model defined in OpenAPI Args: - cluster_ids ([str]): + tag_ids ([str]): Keyword Args: _check_type (bool): if True, values for parameters in openapi_types @@ -164,7 +164,7 @@ class WorkerClusterChangeRequest(ModelNormal): self._configuration = _configuration self._visited_composed_classes = _visited_composed_classes + (self.__class__,) - self.cluster_ids = cluster_ids + self.tag_ids = tag_ids for var_name, var_value in kwargs.items(): if var_name not in self.attribute_map and \ self._configuration is not None and \ @@ -185,11 +185,11 @@ class WorkerClusterChangeRequest(ModelNormal): ]) @convert_js_args_to_python_args - def __init__(self, cluster_ids, *args, **kwargs): # noqa: E501 - """WorkerClusterChangeRequest - a model defined in OpenAPI + def __init__(self, tag_ids, *args, **kwargs): # noqa: E501 + """WorkerTagChangeRequest - a model defined in OpenAPI Args: - cluster_ids ([str]): + tag_ids ([str]): Keyword Args: _check_type (bool): if True, values for parameters in openapi_types @@ -247,7 +247,7 @@ class WorkerClusterChangeRequest(ModelNormal): self._configuration = _configuration self._visited_composed_classes = _visited_composed_classes + (self.__class__,) - self.cluster_ids = cluster_ids + self.tag_ids = tag_ids for var_name, var_value in kwargs.items(): if var_name not in self.attribute_map and \ self._configuration is not None and \ diff --git a/addon/flamenco/manager/model/worker_cluster_list.py b/addon/flamenco/manager/model/worker_tag_list.py similarity index 95% rename from addon/flamenco/manager/model/worker_cluster_list.py rename to addon/flamenco/manager/model/worker_tag_list.py index 4b87d13d..7eb304e0 100644 --- a/addon/flamenco/manager/model/worker_cluster_list.py +++ b/addon/flamenco/manager/model/worker_tag_list.py @@ -30,11 +30,11 @@ from flamenco.manager.exceptions import ApiAttributeError def lazy_import(): - from flamenco.manager.model.worker_cluster import WorkerCluster - globals()['WorkerCluster'] = WorkerCluster + from flamenco.manager.model.worker_tag import WorkerTag + globals()['WorkerTag'] = WorkerTag -class WorkerClusterList(ModelNormal): +class WorkerTagList(ModelNormal): """NOTE: This class is auto generated by OpenAPI Generator. Ref: https://openapi-generator.tech @@ -87,7 +87,7 @@ class WorkerClusterList(ModelNormal): """ lazy_import() return { - 'clusters': ([WorkerCluster],), # noqa: E501 + 'tags': ([WorkerTag],), # noqa: E501 } @cached_property @@ -96,7 +96,7 @@ class WorkerClusterList(ModelNormal): attribute_map = { - 'clusters': 'clusters', # noqa: E501 + 'tags': 'tags', # noqa: E501 } read_only_vars = { @@ -107,7 +107,7 @@ class WorkerClusterList(ModelNormal): @classmethod @convert_js_args_to_python_args def _from_openapi_data(cls, *args, **kwargs): # noqa: E501 - """WorkerClusterList - a model defined in OpenAPI + """WorkerTagList - a model defined in OpenAPI Keyword Args: _check_type (bool): if True, values for parameters in openapi_types @@ -140,7 +140,7 @@ class WorkerClusterList(ModelNormal): Animal class but this time we won't travel through its discriminator because we passed in _visited_composed_classes = (Animal,) - clusters ([WorkerCluster]): [optional] # noqa: E501 + tags ([WorkerTag]): [optional] # noqa: E501 """ _check_type = kwargs.pop('_check_type', True) @@ -189,7 +189,7 @@ class WorkerClusterList(ModelNormal): @convert_js_args_to_python_args def __init__(self, *args, **kwargs): # noqa: E501 - """WorkerClusterList - a model defined in OpenAPI + """WorkerTagList - a model defined in OpenAPI Keyword Args: _check_type (bool): if True, values for parameters in openapi_types @@ -222,7 +222,7 @@ class WorkerClusterList(ModelNormal): Animal class but this time we won't travel through its discriminator because we passed in _visited_composed_classes = (Animal,) - clusters ([WorkerCluster]): [optional] # noqa: E501 + tags ([WorkerTag]): [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 e4fe3a14..e8dbfbce 100644 --- a/addon/flamenco/manager/models/__init__.py +++ b/addon/flamenco/manager/models/__init__.py @@ -74,9 +74,6 @@ from flamenco.manager.model.task_update import TaskUpdate from flamenco.manager.model.task_worker import TaskWorker from flamenco.manager.model.worker import Worker from flamenco.manager.model.worker_all_of import WorkerAllOf -from flamenco.manager.model.worker_cluster import WorkerCluster -from flamenco.manager.model.worker_cluster_change_request import WorkerClusterChangeRequest -from flamenco.manager.model.worker_cluster_list import WorkerClusterList from flamenco.manager.model.worker_list import WorkerList from flamenco.manager.model.worker_registration import WorkerRegistration from flamenco.manager.model.worker_sign_on import WorkerSignOn @@ -86,5 +83,8 @@ 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 +from flamenco.manager.model.worker_tag import WorkerTag +from flamenco.manager.model.worker_tag_change_request import WorkerTagChangeRequest +from flamenco.manager.model.worker_tag_list import WorkerTagList from flamenco.manager.model.worker_task import WorkerTask from flamenco.manager.model.worker_task_all_of import WorkerTaskAllOf diff --git a/addon/flamenco/manager_README.md b/addon/flamenco/manager_README.md index b8086d84..f3d38ce5 100644 --- a/addon/flamenco/manager_README.md +++ b/addon/flamenco/manager_README.md @@ -116,18 +116,18 @@ Class | Method | HTTP request | Description *WorkerApi* | [**task_update**](flamenco/manager/docs/WorkerApi.md#task_update) | **POST** /api/v3/worker/task/{task_id} | Update the task, typically to indicate progress, completion, or failure. *WorkerApi* | [**worker_state**](flamenco/manager/docs/WorkerApi.md#worker_state) | **GET** /api/v3/worker/state | *WorkerApi* | [**worker_state_changed**](flamenco/manager/docs/WorkerApi.md#worker_state_changed) | **POST** /api/v3/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* | [**create_worker_cluster**](flamenco/manager/docs/WorkerMgtApi.md#create_worker_cluster) | **POST** /api/v3/worker-mgt/clusters | Create a new worker cluster. +*WorkerMgtApi* | [**create_worker_tag**](flamenco/manager/docs/WorkerMgtApi.md#create_worker_tag) | **POST** /api/v3/worker-mgt/tags | Create a new worker tag. *WorkerMgtApi* | [**delete_worker**](flamenco/manager/docs/WorkerMgtApi.md#delete_worker) | **DELETE** /api/v3/worker-mgt/workers/{worker_id} | Remove the given worker. It is recommended to only call this function when the worker is in `offline` state. If the worker is still running, stop it first. Any task still assigned to the worker will be requeued. -*WorkerMgtApi* | [**delete_worker_cluster**](flamenco/manager/docs/WorkerMgtApi.md#delete_worker_cluster) | **DELETE** /api/v3/worker-mgt/cluster/{cluster_id} | Remove this worker cluster. This unassigns all workers from the cluster and removes it. +*WorkerMgtApi* | [**delete_worker_tag**](flamenco/manager/docs/WorkerMgtApi.md#delete_worker_tag) | **DELETE** /api/v3/worker-mgt/tag/{tag_id} | Remove this worker tag. This unassigns all workers from the tag and removes it. *WorkerMgtApi* | [**fetch_worker**](flamenco/manager/docs/WorkerMgtApi.md#fetch_worker) | **GET** /api/v3/worker-mgt/workers/{worker_id} | Fetch info about the worker. -*WorkerMgtApi* | [**fetch_worker_cluster**](flamenco/manager/docs/WorkerMgtApi.md#fetch_worker_cluster) | **GET** /api/v3/worker-mgt/cluster/{cluster_id} | Get a single worker cluster. -*WorkerMgtApi* | [**fetch_worker_clusters**](flamenco/manager/docs/WorkerMgtApi.md#fetch_worker_clusters) | **GET** /api/v3/worker-mgt/clusters | Get list of worker clusters. *WorkerMgtApi* | [**fetch_worker_sleep_schedule**](flamenco/manager/docs/WorkerMgtApi.md#fetch_worker_sleep_schedule) | **GET** /api/v3/worker-mgt/workers/{worker_id}/sleep-schedule | +*WorkerMgtApi* | [**fetch_worker_tag**](flamenco/manager/docs/WorkerMgtApi.md#fetch_worker_tag) | **GET** /api/v3/worker-mgt/tag/{tag_id} | Get a single worker tag. +*WorkerMgtApi* | [**fetch_worker_tags**](flamenco/manager/docs/WorkerMgtApi.md#fetch_worker_tags) | **GET** /api/v3/worker-mgt/tags | Get list of worker tags. *WorkerMgtApi* | [**fetch_workers**](flamenco/manager/docs/WorkerMgtApi.md#fetch_workers) | **GET** /api/v3/worker-mgt/workers | Get list of workers. *WorkerMgtApi* | [**request_worker_status_change**](flamenco/manager/docs/WorkerMgtApi.md#request_worker_status_change) | **POST** /api/v3/worker-mgt/workers/{worker_id}/setstatus | -*WorkerMgtApi* | [**set_worker_clusters**](flamenco/manager/docs/WorkerMgtApi.md#set_worker_clusters) | **POST** /api/v3/worker-mgt/workers/{worker_id}/setclusters | *WorkerMgtApi* | [**set_worker_sleep_schedule**](flamenco/manager/docs/WorkerMgtApi.md#set_worker_sleep_schedule) | **POST** /api/v3/worker-mgt/workers/{worker_id}/sleep-schedule | -*WorkerMgtApi* | [**update_worker_cluster**](flamenco/manager/docs/WorkerMgtApi.md#update_worker_cluster) | **PUT** /api/v3/worker-mgt/cluster/{cluster_id} | Update an existing worker cluster. +*WorkerMgtApi* | [**set_worker_tags**](flamenco/manager/docs/WorkerMgtApi.md#set_worker_tags) | **POST** /api/v3/worker-mgt/workers/{worker_id}/settags | +*WorkerMgtApi* | [**update_worker_tag**](flamenco/manager/docs/WorkerMgtApi.md#update_worker_tag) | **PUT** /api/v3/worker-mgt/tag/{tag_id} | Update an existing worker tag. ## Documentation For Models @@ -197,9 +197,6 @@ Class | Method | HTTP request | Description - [TaskWorker](flamenco/manager/docs/TaskWorker.md) - [Worker](flamenco/manager/docs/Worker.md) - [WorkerAllOf](flamenco/manager/docs/WorkerAllOf.md) - - [WorkerCluster](flamenco/manager/docs/WorkerCluster.md) - - [WorkerClusterChangeRequest](flamenco/manager/docs/WorkerClusterChangeRequest.md) - - [WorkerClusterList](flamenco/manager/docs/WorkerClusterList.md) - [WorkerList](flamenco/manager/docs/WorkerList.md) - [WorkerRegistration](flamenco/manager/docs/WorkerRegistration.md) - [WorkerSignOn](flamenco/manager/docs/WorkerSignOn.md) @@ -209,6 +206,9 @@ Class | Method | HTTP request | Description - [WorkerStatus](flamenco/manager/docs/WorkerStatus.md) - [WorkerStatusChangeRequest](flamenco/manager/docs/WorkerStatusChangeRequest.md) - [WorkerSummary](flamenco/manager/docs/WorkerSummary.md) + - [WorkerTag](flamenco/manager/docs/WorkerTag.md) + - [WorkerTagChangeRequest](flamenco/manager/docs/WorkerTagChangeRequest.md) + - [WorkerTagList](flamenco/manager/docs/WorkerTagList.md) - [WorkerTask](flamenco/manager/docs/WorkerTask.md) - [WorkerTaskAllOf](flamenco/manager/docs/WorkerTaskAllOf.md) diff --git a/addon/flamenco/operators.py b/addon/flamenco/operators.py index 5ee0a0e3..0b6c883b 100644 --- a/addon/flamenco/operators.py +++ b/addon/flamenco/operators.py @@ -10,7 +10,7 @@ from urllib3.exceptions import HTTPError, MaxRetryError import bpy -from . import job_types, job_submission, preferences, worker_clusters +from . import job_types, job_submission, preferences, worker_tags from .job_types_propgroup import JobTypePropertyGroup from .bat.submodules import bpathlib @@ -83,10 +83,10 @@ class FLAMENCO_OT_fetch_job_types(FlamencoOpMixin, bpy.types.Operator): return {"FINISHED"} -class FLAMENCO_OT_fetch_worker_clusters(FlamencoOpMixin, bpy.types.Operator): - bl_idname = "flamenco.fetch_worker_clusters" - bl_label = "Fetch Worker Clusters" - bl_description = "Query Flamenco Manager to obtain the available worker clusters" +class FLAMENCO_OT_fetch_worker_tags(FlamencoOpMixin, bpy.types.Operator): + bl_idname = "flamenco.fetch_worker_tags" + bl_label = "Fetch Worker Tags" + bl_description = "Query Flamenco Manager to obtain the available worker tags" def execute(self, context: bpy.types.Context) -> set[str]: api_client = self.get_api_client(context) @@ -94,10 +94,10 @@ class FLAMENCO_OT_fetch_worker_clusters(FlamencoOpMixin, bpy.types.Operator): from flamenco.manager import ApiException scene = context.scene - old_cluster = getattr(scene, "flamenco_worker_cluster", "") + old_tag = getattr(scene, "flamenco_worker_tag", "") try: - worker_clusters.refresh(context, api_client) + worker_tags.refresh(context, api_client) except ApiException as ex: self.report({"ERROR"}, "Error getting job types: %s" % ex) return {"CANCELLED"} @@ -107,9 +107,9 @@ class FLAMENCO_OT_fetch_worker_clusters(FlamencoOpMixin, bpy.types.Operator): self.report({"ERROR"}, "Unable to reach Manager") return {"CANCELLED"} - if old_cluster: - # TODO: handle cases where the old cluster no longer exists. - scene.flamenco_worker_cluster = old_cluster + if old_tag: + # TODO: handle cases where the old tag no longer exists. + scene.flamenco_worker_tag = old_tag return {"FINISHED"} @@ -669,7 +669,7 @@ class FLAMENCO3_OT_explore_file_path(bpy.types.Operator): classes = ( FLAMENCO_OT_fetch_job_types, - FLAMENCO_OT_fetch_worker_clusters, + FLAMENCO_OT_fetch_worker_tags, FLAMENCO_OT_ping_manager, FLAMENCO_OT_eval_setting, FLAMENCO_OT_submit_job, diff --git a/addon/flamenco/preferences.py b/addon/flamenco/preferences.py index 31bc231c..2b5daa27 100644 --- a/addon/flamenco/preferences.py +++ b/addon/flamenco/preferences.py @@ -43,7 +43,7 @@ _project_finder_enum_items = [ ] -class WorkerCluster(bpy.types.PropertyGroup): +class WorkerTag(bpy.types.PropertyGroup): id: bpy.props.StringProperty(name="id") # type: ignore name: bpy.props.StringProperty(name="Name") # type: ignore description: bpy.props.StringProperty(name="Description") # type: ignore @@ -93,10 +93,10 @@ class FlamencoPreferences(bpy.types.AddonPreferences): get=lambda prefs: prefs.job_storage, ) - worker_clusters: bpy.props.CollectionProperty( # type: ignore - type=WorkerCluster, - name="Worker Clusters", - description="Cache for the worker clusters available on the configured Manager", + worker_tags: bpy.props.CollectionProperty( # type: ignore + type=WorkerTag, + name="Worker Tags", + description="Cache for the worker tags available on the configured Manager", options={"HIDDEN"}, ) @@ -169,7 +169,7 @@ def manager_url(context: bpy.types.Context) -> str: classes = ( - WorkerCluster, + WorkerTag, FlamencoPreferences, ) _register, _unregister = bpy.utils.register_classes_factory(classes) diff --git a/addon/flamenco/worker_clusters.py b/addon/flamenco/worker_tags.py similarity index 62% rename from addon/flamenco/worker_clusters.py rename to addon/flamenco/worker_tags.py index 2604f488..2ed75cbb 100644 --- a/addon/flamenco/worker_clusters.py +++ b/addon/flamenco/worker_tags.py @@ -16,25 +16,25 @@ _enum_items: list[Union[tuple[str, str, str], tuple[str, str, str, int, int]]] = def refresh(context: bpy.types.Context, api_client: _ApiClient) -> None: - """Fetch the available worker clusters from the Manager.""" + """Fetch the available worker tags from the Manager.""" from flamenco.manager import ApiClient from flamenco.manager.api import worker_mgt_api - from flamenco.manager.model.worker_cluster_list import WorkerClusterList + from flamenco.manager.model.worker_tag_list import WorkerTagList assert isinstance(api_client, ApiClient) api = worker_mgt_api.WorkerMgtApi(api_client) - response: WorkerClusterList = api.fetch_worker_clusters() + response: WorkerTagList = api.fetch_worker_tags() # Store on the preferences, so a cached version persists until the next refresh. prefs = preferences.get(context) - prefs.worker_clusters.clear() + prefs.worker_tags.clear() - for cluster in response.clusters: - rna_cluster = prefs.worker_clusters.add() - rna_cluster.id = cluster.id - rna_cluster.name = cluster.name - rna_cluster.description = getattr(cluster, "description", "") + for tag in response.tags: + rna_tag = prefs.worker_tags.add() + rna_tag.id = tag.id + rna_tag.name = tag.name + rna_tag.description = getattr(tag, "description", "") # Preferences have changed, so make sure that Blender saves them (assuming # auto-save here). @@ -46,25 +46,25 @@ def _get_enum_items(self, context): prefs = preferences.get(context) _enum_items = [ - ("-", "All", "No specific cluster assigned, any worker can handle this job"), + ("-", "All", "No specific tag assigned, any worker can handle this job"), ] _enum_items.extend( - (cluster.id, cluster.name, cluster.description) - for cluster in prefs.worker_clusters + (tag.id, tag.name, tag.description) + for tag in prefs.worker_tags ) return _enum_items def register() -> None: - bpy.types.Scene.flamenco_worker_cluster = bpy.props.EnumProperty( - name="Worker Cluster", + bpy.types.Scene.flamenco_worker_tag = bpy.props.EnumProperty( + name="Worker Tag", items=_get_enum_items, description="The set of Workers that can handle tasks of this job", ) def unregister() -> None: - to_del = ((bpy.types.Scene, "flamenco_worker_cluster"),) + to_del = ((bpy.types.Scene, "flamenco_worker_tag"),) for ob, attr in to_del: try: delattr(ob, attr) diff --git a/internal/manager/api_impl/interfaces.go b/internal/manager/api_impl/interfaces.go index 17fd7c91..7b0c5c31 100644 --- a/internal/manager/api_impl/interfaces.go +++ b/internal/manager/api_impl/interfaces.go @@ -65,13 +65,13 @@ type PersistenceService interface { RemoveFromJobBlocklist(ctx context.Context, jobUUID, workerUUID, taskType string) error ClearJobBlocklist(ctx context.Context, job *persistence.Job) error - // Worker cluster management. - WorkerSetClusters(ctx context.Context, worker *persistence.Worker, clusterUUIDs []string) error - CreateWorkerCluster(ctx context.Context, cluster *persistence.WorkerCluster) error - FetchWorkerCluster(ctx context.Context, uuid string) (*persistence.WorkerCluster, error) - FetchWorkerClusters(ctx context.Context) ([]*persistence.WorkerCluster, error) - DeleteWorkerCluster(ctx context.Context, uuid string) error - SaveWorkerCluster(ctx context.Context, cluster *persistence.WorkerCluster) error + // Worker tag management. + WorkerSetTags(ctx context.Context, worker *persistence.Worker, tagUUIDs []string) error + CreateWorkerTag(ctx context.Context, tag *persistence.WorkerTag) error + FetchWorkerTag(ctx context.Context, uuid string) (*persistence.WorkerTag, error) + FetchWorkerTags(ctx context.Context) ([]*persistence.WorkerTag, error) + DeleteWorkerTag(ctx context.Context, uuid string) error + SaveWorkerTag(ctx context.Context, tag *persistence.WorkerTag) error // WorkersLeftToRun returns a set of worker UUIDs that can run tasks of the given type on the given job. WorkersLeftToRun(ctx context.Context, job *persistence.Job, taskType string) (map[string]bool, error) diff --git a/internal/manager/api_impl/jobs.go b/internal/manager/api_impl/jobs.go index fcd84a7e..aca62069 100644 --- a/internal/manager/api_impl/jobs.go +++ b/internal/manager/api_impl/jobs.go @@ -618,8 +618,8 @@ func jobDBtoAPI(dbJob *persistence.Job) api.Job { if dbJob.DeleteRequestedAt.Valid { apiJob.DeleteRequestedAt = &dbJob.DeleteRequestedAt.Time } - if dbJob.WorkerCluster != nil { - apiJob.WorkerCluster = &dbJob.WorkerCluster.UUID + if dbJob.WorkerTag != nil { + apiJob.WorkerTag = &dbJob.WorkerTag.UUID } return apiJob diff --git a/internal/manager/api_impl/jobs_test.go b/internal/manager/api_impl/jobs_test.go index 5c64babf..fa666fe8 100644 --- a/internal/manager/api_impl/jobs_test.go +++ b/internal/manager/api_impl/jobs_test.go @@ -320,19 +320,19 @@ func TestSubmitJobWithShamanCheckoutID(t *testing.T) { assert.NoError(t, err) } -func TestSubmitJobWithWorkerCluster(t *testing.T) { +func TestSubmitJobWithWorkerTag(t *testing.T) { mockCtrl := gomock.NewController(t) defer mockCtrl.Finish() mf := newMockedFlamenco(mockCtrl) worker := testWorker() - workerClusterUUID := "04435762-9dc8-4f13-80b7-643a6fa5b6fd" - cluster := persistence.WorkerCluster{ + workerTagUUID := "04435762-9dc8-4f13-80b7-643a6fa5b6fd" + tag := persistence.WorkerTag{ Model: persistence.Model{ID: 47}, - UUID: workerClusterUUID, - Name: "first cluster", - Description: "my first cluster", + UUID: workerTagUUID, + Name: "first tag", + Description: "my first tag", } submittedJob := api.SubmittedJob{ @@ -340,7 +340,7 @@ func TestSubmitJobWithWorkerCluster(t *testing.T) { Type: "test", Priority: 50, SubmitterPlatform: worker.Platform, - WorkerCluster: &workerClusterUUID, + WorkerTag: &workerTagUUID, } mf.expectConvertTwoWayVariables(t, @@ -351,8 +351,8 @@ func TestSubmitJobWithWorkerCluster(t *testing.T) { // Expect the job compiler to be called. authoredJob := job_compilers.AuthoredJob{ - JobID: "afc47568-bd9d-4368-8016-e91d945db36d", - WorkerClusterUUID: workerClusterUUID, + JobID: "afc47568-bd9d-4368-8016-e91d945db36d", + WorkerTagUUID: workerTagUUID, Name: submittedJob.Name, JobType: submittedJob.Type, @@ -382,8 +382,8 @@ func TestSubmitJobWithWorkerCluster(t *testing.T) { Settings: persistence.StringInterfaceMap{}, Metadata: persistence.StringStringMap{}, - WorkerClusterID: &cluster.ID, - WorkerCluster: &cluster, + WorkerTagID: &tag.ID, + WorkerTag: &tag, } mf.persistence.EXPECT().FetchJob(gomock.Any(), queuedJob.JobID).Return(&dbJob, nil) diff --git a/internal/manager/api_impl/mocks/api_impl_mock.gen.go b/internal/manager/api_impl/mocks/api_impl_mock.gen.go index 31a8aafa..6817cfce 100644 --- a/internal/manager/api_impl/mocks/api_impl_mock.gen.go +++ b/internal/manager/api_impl/mocks/api_impl_mock.gen.go @@ -141,18 +141,18 @@ func (mr *MockPersistenceServiceMockRecorder) CreateWorker(arg0, arg1 interface{ return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CreateWorker", reflect.TypeOf((*MockPersistenceService)(nil).CreateWorker), arg0, arg1) } -// CreateWorkerCluster mocks base method. -func (m *MockPersistenceService) CreateWorkerCluster(arg0 context.Context, arg1 *persistence.WorkerCluster) error { +// CreateWorkerTag mocks base method. +func (m *MockPersistenceService) CreateWorkerTag(arg0 context.Context, arg1 *persistence.WorkerTag) error { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "CreateWorkerCluster", arg0, arg1) + ret := m.ctrl.Call(m, "CreateWorkerTag", arg0, arg1) ret0, _ := ret[0].(error) return ret0 } -// CreateWorkerCluster indicates an expected call of CreateWorkerCluster. -func (mr *MockPersistenceServiceMockRecorder) CreateWorkerCluster(arg0, arg1 interface{}) *gomock.Call { +// CreateWorkerTag indicates an expected call of CreateWorkerTag. +func (mr *MockPersistenceServiceMockRecorder) CreateWorkerTag(arg0, arg1 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CreateWorkerCluster", reflect.TypeOf((*MockPersistenceService)(nil).CreateWorkerCluster), arg0, arg1) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CreateWorkerTag", reflect.TypeOf((*MockPersistenceService)(nil).CreateWorkerTag), arg0, arg1) } // DeleteWorker mocks base method. @@ -169,18 +169,18 @@ func (mr *MockPersistenceServiceMockRecorder) DeleteWorker(arg0, arg1 interface{ return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DeleteWorker", reflect.TypeOf((*MockPersistenceService)(nil).DeleteWorker), arg0, arg1) } -// DeleteWorkerCluster mocks base method. -func (m *MockPersistenceService) DeleteWorkerCluster(arg0 context.Context, arg1 string) error { +// DeleteWorkerTag mocks base method. +func (m *MockPersistenceService) DeleteWorkerTag(arg0 context.Context, arg1 string) error { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "DeleteWorkerCluster", arg0, arg1) + ret := m.ctrl.Call(m, "DeleteWorkerTag", arg0, arg1) ret0, _ := ret[0].(error) return ret0 } -// DeleteWorkerCluster indicates an expected call of DeleteWorkerCluster. -func (mr *MockPersistenceServiceMockRecorder) DeleteWorkerCluster(arg0, arg1 interface{}) *gomock.Call { +// DeleteWorkerTag indicates an expected call of DeleteWorkerTag. +func (mr *MockPersistenceServiceMockRecorder) DeleteWorkerTag(arg0, arg1 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DeleteWorkerCluster", reflect.TypeOf((*MockPersistenceService)(nil).DeleteWorkerCluster), arg0, arg1) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DeleteWorkerTag", reflect.TypeOf((*MockPersistenceService)(nil).DeleteWorkerTag), arg0, arg1) } // FetchJob mocks base method. @@ -258,34 +258,34 @@ func (mr *MockPersistenceServiceMockRecorder) FetchWorker(arg0, arg1 interface{} return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "FetchWorker", reflect.TypeOf((*MockPersistenceService)(nil).FetchWorker), arg0, arg1) } -// FetchWorkerCluster mocks base method. -func (m *MockPersistenceService) FetchWorkerCluster(arg0 context.Context, arg1 string) (*persistence.WorkerCluster, error) { +// FetchWorkerTag mocks base method. +func (m *MockPersistenceService) FetchWorkerTag(arg0 context.Context, arg1 string) (*persistence.WorkerTag, error) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "FetchWorkerCluster", arg0, arg1) - ret0, _ := ret[0].(*persistence.WorkerCluster) + ret := m.ctrl.Call(m, "FetchWorkerTag", arg0, arg1) + ret0, _ := ret[0].(*persistence.WorkerTag) ret1, _ := ret[1].(error) return ret0, ret1 } -// FetchWorkerCluster indicates an expected call of FetchWorkerCluster. -func (mr *MockPersistenceServiceMockRecorder) FetchWorkerCluster(arg0, arg1 interface{}) *gomock.Call { +// FetchWorkerTag indicates an expected call of FetchWorkerTag. +func (mr *MockPersistenceServiceMockRecorder) FetchWorkerTag(arg0, arg1 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "FetchWorkerCluster", reflect.TypeOf((*MockPersistenceService)(nil).FetchWorkerCluster), arg0, arg1) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "FetchWorkerTag", reflect.TypeOf((*MockPersistenceService)(nil).FetchWorkerTag), arg0, arg1) } -// FetchWorkerClusters mocks base method. -func (m *MockPersistenceService) FetchWorkerClusters(arg0 context.Context) ([]*persistence.WorkerCluster, error) { +// FetchWorkerTags mocks base method. +func (m *MockPersistenceService) FetchWorkerTags(arg0 context.Context) ([]*persistence.WorkerTag, error) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "FetchWorkerClusters", arg0) - ret0, _ := ret[0].([]*persistence.WorkerCluster) + ret := m.ctrl.Call(m, "FetchWorkerTags", arg0) + ret0, _ := ret[0].([]*persistence.WorkerTag) ret1, _ := ret[1].(error) return ret0, ret1 } -// FetchWorkerClusters indicates an expected call of FetchWorkerClusters. -func (mr *MockPersistenceServiceMockRecorder) FetchWorkerClusters(arg0 interface{}) *gomock.Call { +// FetchWorkerTags indicates an expected call of FetchWorkerTags. +func (mr *MockPersistenceServiceMockRecorder) FetchWorkerTags(arg0 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "FetchWorkerClusters", reflect.TypeOf((*MockPersistenceService)(nil).FetchWorkerClusters), arg0) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "FetchWorkerTags", reflect.TypeOf((*MockPersistenceService)(nil).FetchWorkerTags), arg0) } // FetchWorkerTask mocks base method. @@ -433,20 +433,6 @@ func (mr *MockPersistenceServiceMockRecorder) SaveWorker(arg0, arg1 interface{}) return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SaveWorker", reflect.TypeOf((*MockPersistenceService)(nil).SaveWorker), arg0, arg1) } -// SaveWorkerCluster mocks base method. -func (m *MockPersistenceService) SaveWorkerCluster(arg0 context.Context, arg1 *persistence.WorkerCluster) error { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "SaveWorkerCluster", arg0, arg1) - ret0, _ := ret[0].(error) - return ret0 -} - -// SaveWorkerCluster indicates an expected call of SaveWorkerCluster. -func (mr *MockPersistenceServiceMockRecorder) SaveWorkerCluster(arg0, arg1 interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SaveWorkerCluster", reflect.TypeOf((*MockPersistenceService)(nil).SaveWorkerCluster), arg0, arg1) -} - // SaveWorkerStatus mocks base method. func (m *MockPersistenceService) SaveWorkerStatus(arg0 context.Context, arg1 *persistence.Worker) error { m.ctrl.T.Helper() @@ -461,6 +447,20 @@ func (mr *MockPersistenceServiceMockRecorder) SaveWorkerStatus(arg0, arg1 interf return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SaveWorkerStatus", reflect.TypeOf((*MockPersistenceService)(nil).SaveWorkerStatus), arg0, arg1) } +// SaveWorkerTag mocks base method. +func (m *MockPersistenceService) SaveWorkerTag(arg0 context.Context, arg1 *persistence.WorkerTag) error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "SaveWorkerTag", arg0, arg1) + ret0, _ := ret[0].(error) + return ret0 +} + +// SaveWorkerTag indicates an expected call of SaveWorkerTag. +func (mr *MockPersistenceServiceMockRecorder) SaveWorkerTag(arg0, arg1 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SaveWorkerTag", reflect.TypeOf((*MockPersistenceService)(nil).SaveWorkerTag), arg0, arg1) +} + // ScheduleTask mocks base method. func (m *MockPersistenceService) ScheduleTask(arg0 context.Context, arg1 *persistence.Worker) (*persistence.Task, error) { m.ctrl.T.Helper() @@ -532,18 +532,18 @@ func (mr *MockPersistenceServiceMockRecorder) WorkerSeen(arg0, arg1 interface{}) return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "WorkerSeen", reflect.TypeOf((*MockPersistenceService)(nil).WorkerSeen), arg0, arg1) } -// WorkerSetClusters mocks base method. -func (m *MockPersistenceService) WorkerSetClusters(arg0 context.Context, arg1 *persistence.Worker, arg2 []string) error { +// WorkerSetTags mocks base method. +func (m *MockPersistenceService) WorkerSetTags(arg0 context.Context, arg1 *persistence.Worker, arg2 []string) error { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "WorkerSetClusters", arg0, arg1, arg2) + ret := m.ctrl.Call(m, "WorkerSetTags", arg0, arg1, arg2) ret0, _ := ret[0].(error) return ret0 } -// WorkerSetClusters indicates an expected call of WorkerSetClusters. -func (mr *MockPersistenceServiceMockRecorder) WorkerSetClusters(arg0, arg1, arg2 interface{}) *gomock.Call { +// WorkerSetTags indicates an expected call of WorkerSetTags. +func (mr *MockPersistenceServiceMockRecorder) WorkerSetTags(arg0, arg1, arg2 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "WorkerSetClusters", reflect.TypeOf((*MockPersistenceService)(nil).WorkerSetClusters), arg0, arg1, arg2) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "WorkerSetTags", reflect.TypeOf((*MockPersistenceService)(nil).WorkerSetTags), arg0, arg1, arg2) } // WorkersLeftToRun mocks base method. diff --git a/internal/manager/api_impl/worker_mgt.go b/internal/manager/api_impl/worker_mgt.go index c1f8ab30..509f525f 100644 --- a/internal/manager/api_impl/worker_mgt.go +++ b/internal/manager/api_impl/worker_mgt.go @@ -182,7 +182,7 @@ func (f *Flamenco) RequestWorkerStatusChange(e echo.Context, workerUUID string) return e.NoContent(http.StatusNoContent) } -func (f *Flamenco) SetWorkerClusters(e echo.Context, workerUUID string) error { +func (f *Flamenco) SetWorkerTags(e echo.Context, workerUUID string) error { ctx := e.Request().Context() logger := requestLogger(e) logger = logger.With().Str("worker", workerUUID).Logger() @@ -192,7 +192,7 @@ func (f *Flamenco) SetWorkerClusters(e echo.Context, workerUUID string) error { } // Decode the request body. - var change api.WorkerClusterChangeRequest + var change api.WorkerTagChangeRequest if err := e.Bind(&change); err != nil { logger.Warn().Err(err).Msg("bad request received") return sendAPIError(e, http.StatusBadRequest, "invalid format") @@ -210,13 +210,13 @@ func (f *Flamenco) SetWorkerClusters(e echo.Context, workerUUID string) error { } logger = logger.With(). - Strs("clusters", change.ClusterIds). + Strs("tags", change.TagIds). Logger() - logger.Info().Msg("worker cluster change requested") + logger.Info().Msg("worker tag change requested") - // Store the new cluster assignment. - if err := f.persist.WorkerSetClusters(ctx, dbWorker, change.ClusterIds); err != nil { - logger.Error().Err(err).Msg("saving worker after cluster change request") + // Store the new tag assignment. + if err := f.persist.WorkerSetTags(ctx, dbWorker, change.TagIds); err != nil { + logger.Error().Err(err).Msg("saving worker after tag change request") return sendAPIError(e, http.StatusInternalServerError, "error saving worker: %v", err) } @@ -227,155 +227,155 @@ func (f *Flamenco) SetWorkerClusters(e echo.Context, workerUUID string) error { return e.NoContent(http.StatusNoContent) } -func (f *Flamenco) DeleteWorkerCluster(e echo.Context, clusterUUID string) error { +func (f *Flamenco) DeleteWorkerTag(e echo.Context, tagUUID string) error { ctx := e.Request().Context() logger := requestLogger(e) - logger = logger.With().Str("cluster", clusterUUID).Logger() + logger = logger.With().Str("tag", tagUUID).Logger() - if !uuid.IsValid(clusterUUID) { + if !uuid.IsValid(tagUUID) { return sendAPIError(e, http.StatusBadRequest, "not a valid UUID") } - err := f.persist.DeleteWorkerCluster(ctx, clusterUUID) + err := f.persist.DeleteWorkerTag(ctx, tagUUID) switch { - case errors.Is(err, persistence.ErrWorkerClusterNotFound): - logger.Debug().Msg("non-existent worker cluster requested") - return sendAPIError(e, http.StatusNotFound, "worker cluster %q not found", clusterUUID) + case errors.Is(err, persistence.ErrWorkerTagNotFound): + logger.Debug().Msg("non-existent worker tag requested") + return sendAPIError(e, http.StatusNotFound, "worker tag %q not found", tagUUID) case err != nil: - logger.Error().Err(err).Msg("deleting worker cluster") - return sendAPIError(e, http.StatusInternalServerError, "error deleting worker cluster: %v", err) + logger.Error().Err(err).Msg("deleting worker tag") + return sendAPIError(e, http.StatusInternalServerError, "error deleting worker tag: %v", err) } - // TODO: SocketIO broadcast of cluster deletion. + // TODO: SocketIO broadcast of tag deletion. - logger.Info().Msg("worker cluster deleted") + logger.Info().Msg("worker tag deleted") return e.NoContent(http.StatusNoContent) } -func (f *Flamenco) FetchWorkerCluster(e echo.Context, clusterUUID string) error { +func (f *Flamenco) FetchWorkerTag(e echo.Context, tagUUID string) error { ctx := e.Request().Context() logger := requestLogger(e) - logger = logger.With().Str("cluster", clusterUUID).Logger() + logger = logger.With().Str("tag", tagUUID).Logger() - if !uuid.IsValid(clusterUUID) { + if !uuid.IsValid(tagUUID) { return sendAPIError(e, http.StatusBadRequest, "not a valid UUID") } - cluster, err := f.persist.FetchWorkerCluster(ctx, clusterUUID) + tag, err := f.persist.FetchWorkerTag(ctx, tagUUID) switch { - case errors.Is(err, persistence.ErrWorkerClusterNotFound): - logger.Debug().Msg("non-existent worker cluster requested") - return sendAPIError(e, http.StatusNotFound, "worker cluster %q not found", clusterUUID) + case errors.Is(err, persistence.ErrWorkerTagNotFound): + logger.Debug().Msg("non-existent worker tag requested") + return sendAPIError(e, http.StatusNotFound, "worker tag %q not found", tagUUID) case err != nil: - logger.Error().Err(err).Msg("fetching worker cluster") - return sendAPIError(e, http.StatusInternalServerError, "error fetching worker cluster: %v", err) + logger.Error().Err(err).Msg("fetching worker tag") + return sendAPIError(e, http.StatusInternalServerError, "error fetching worker tag: %v", err) } - return e.JSON(http.StatusOK, workerClusterDBtoAPI(*cluster)) + return e.JSON(http.StatusOK, workerTagDBtoAPI(*tag)) } -func (f *Flamenco) UpdateWorkerCluster(e echo.Context, clusterUUID string) error { +func (f *Flamenco) UpdateWorkerTag(e echo.Context, tagUUID string) error { ctx := e.Request().Context() logger := requestLogger(e) - logger = logger.With().Str("cluster", clusterUUID).Logger() + logger = logger.With().Str("tag", tagUUID).Logger() - if !uuid.IsValid(clusterUUID) { + if !uuid.IsValid(tagUUID) { return sendAPIError(e, http.StatusBadRequest, "not a valid UUID") } // Decode the request body. - var update api.UpdateWorkerClusterJSONBody + var update api.UpdateWorkerTagJSONBody if err := e.Bind(&update); err != nil { logger.Warn().Err(err).Msg("bad request received") return sendAPIError(e, http.StatusBadRequest, "invalid format") } - dbCluster, err := f.persist.FetchWorkerCluster(ctx, clusterUUID) + dbTag, err := f.persist.FetchWorkerTag(ctx, tagUUID) switch { - case errors.Is(err, persistence.ErrWorkerClusterNotFound): - logger.Debug().Msg("non-existent worker cluster requested") - return sendAPIError(e, http.StatusNotFound, "worker cluster %q not found", clusterUUID) + case errors.Is(err, persistence.ErrWorkerTagNotFound): + logger.Debug().Msg("non-existent worker tag requested") + return sendAPIError(e, http.StatusNotFound, "worker tag %q not found", tagUUID) case err != nil: - logger.Error().Err(err).Msg("fetching worker cluster") - return sendAPIError(e, http.StatusInternalServerError, "error fetching worker cluster: %v", err) + logger.Error().Err(err).Msg("fetching worker tag") + return sendAPIError(e, http.StatusInternalServerError, "error fetching worker tag: %v", err) } - // Update the cluster. - dbCluster.Name = update.Name + // Update the tag. + dbTag.Name = update.Name if update.Description == nil { - dbCluster.Description = "" + dbTag.Description = "" } else { - dbCluster.Description = *update.Description + dbTag.Description = *update.Description } - if err := f.persist.SaveWorkerCluster(ctx, dbCluster); err != nil { - logger.Error().Err(err).Msg("saving worker cluster") - return sendAPIError(e, http.StatusInternalServerError, "error saving worker cluster") + if err := f.persist.SaveWorkerTag(ctx, dbTag); err != nil { + logger.Error().Err(err).Msg("saving worker tag") + return sendAPIError(e, http.StatusInternalServerError, "error saving worker tag") } - // TODO: SocketIO broadcast of cluster update. + // TODO: SocketIO broadcast of tag update. return e.NoContent(http.StatusNoContent) } -func (f *Flamenco) FetchWorkerClusters(e echo.Context) error { +func (f *Flamenco) FetchWorkerTags(e echo.Context) error { ctx := e.Request().Context() logger := requestLogger(e) - dbClusters, err := f.persist.FetchWorkerClusters(ctx) + dbTags, err := f.persist.FetchWorkerTags(ctx) if err != nil { - logger.Error().Err(err).Msg("fetching worker clusters") - return sendAPIError(e, http.StatusInternalServerError, "error saving worker cluster") + logger.Error().Err(err).Msg("fetching worker tags") + return sendAPIError(e, http.StatusInternalServerError, "error saving worker tag") } - apiClusters := []api.WorkerCluster{} - for _, dbCluster := range dbClusters { - apiCluster := workerClusterDBtoAPI(*dbCluster) - apiClusters = append(apiClusters, apiCluster) + apiTags := []api.WorkerTag{} + for _, dbTag := range dbTags { + apiTag := workerTagDBtoAPI(*dbTag) + apiTags = append(apiTags, apiTag) } - clusterList := api.WorkerClusterList{ - Clusters: &apiClusters, + tagList := api.WorkerTagList{ + Tags: &apiTags, } - return e.JSON(http.StatusOK, &clusterList) + return e.JSON(http.StatusOK, &tagList) } -func (f *Flamenco) CreateWorkerCluster(e echo.Context) error { +func (f *Flamenco) CreateWorkerTag(e echo.Context) error { ctx := e.Request().Context() logger := requestLogger(e) // Decode the request body. - var apiCluster api.CreateWorkerClusterJSONBody - if err := e.Bind(&apiCluster); err != nil { + var apiTag api.CreateWorkerTagJSONBody + if err := e.Bind(&apiTag); err != nil { logger.Warn().Err(err).Msg("bad request received") return sendAPIError(e, http.StatusBadRequest, "invalid format") } // Convert to persistence layer model. - var clusterUUID string - if apiCluster.Id != nil && *apiCluster.Id != "" { - clusterUUID = *apiCluster.Id + var tagUUID string + if apiTag.Id != nil && *apiTag.Id != "" { + tagUUID = *apiTag.Id } else { - clusterUUID = uuid.New() + tagUUID = uuid.New() } - dbCluster := persistence.WorkerCluster{ - UUID: clusterUUID, - Name: apiCluster.Name, + dbTag := persistence.WorkerTag{ + UUID: tagUUID, + Name: apiTag.Name, } - if apiCluster.Description != nil { - dbCluster.Description = *apiCluster.Description + if apiTag.Description != nil { + dbTag.Description = *apiTag.Description } // Store in the database. - if err := f.persist.CreateWorkerCluster(ctx, &dbCluster); err != nil { - logger.Error().Err(err).Msg("creating worker cluster") - return sendAPIError(e, http.StatusInternalServerError, "error creating worker cluster") + if err := f.persist.CreateWorkerTag(ctx, &dbTag); err != nil { + logger.Error().Err(err).Msg("creating worker tag") + return sendAPIError(e, http.StatusInternalServerError, "error creating worker tag") } - // TODO: SocketIO broadcast of cluster creation. + // TODO: SocketIO broadcast of tag creation. - return e.JSON(http.StatusOK, workerClusterDBtoAPI(dbCluster)) + return e.JSON(http.StatusOK, workerTagDBtoAPI(dbTag)) } func workerSummary(w persistence.Worker) api.WorkerSummary { @@ -407,26 +407,26 @@ func workerDBtoAPI(w persistence.Worker) api.Worker { SupportedTaskTypes: w.TaskTypes(), } - if len(w.Clusters) > 0 { - clusters := []api.WorkerCluster{} - for i := range w.Clusters { - clusters = append(clusters, workerClusterDBtoAPI(*w.Clusters[i])) + if len(w.Tags) > 0 { + tags := []api.WorkerTag{} + for i := range w.Tags { + tags = append(tags, workerTagDBtoAPI(*w.Tags[i])) } - apiWorker.Clusters = &clusters + apiWorker.Tags = &tags } return apiWorker } -func workerClusterDBtoAPI(wc persistence.WorkerCluster) api.WorkerCluster { +func workerTagDBtoAPI(wc persistence.WorkerTag) api.WorkerTag { uuid := wc.UUID // Take a copy for safety. - apiCluster := api.WorkerCluster{ + apiTag := api.WorkerTag{ Id: &uuid, Name: wc.Name, } if len(wc.Description) > 0 { - apiCluster.Description = &wc.Description + apiTag.Description = &wc.Description } - return apiCluster + return apiTag } diff --git a/internal/manager/api_impl/worker_mgt_test.go b/internal/manager/api_impl/worker_mgt_test.go index f914121d..352125c3 100644 --- a/internal/manager/api_impl/worker_mgt_test.go +++ b/internal/manager/api_impl/worker_mgt_test.go @@ -262,58 +262,58 @@ func TestRequestWorkerStatusChangeRevert(t *testing.T) { assertResponseNoContent(t, echo) } -func TestWorkerClusterCRUDHappyFlow(t *testing.T) { +func TestWorkerTagCRUDHappyFlow(t *testing.T) { mockCtrl := gomock.NewController(t) defer mockCtrl.Finish() mf := newMockedFlamenco(mockCtrl) - // Create a cluster. + // Create a tag. UUID := "18d9234e-5135-458f-a1ba-a350c3d4e837" - apiCluster := api.WorkerCluster{ + apiTag := api.WorkerTag{ Id: &UUID, Name: "ʻO nā manu ʻino", Description: ptr("Ke aloha"), } - expectDBCluster := persistence.WorkerCluster{ + expectDBTag := persistence.WorkerTag{ UUID: UUID, - Name: apiCluster.Name, - Description: *apiCluster.Description, + Name: apiTag.Name, + Description: *apiTag.Description, } - mf.persistence.EXPECT().CreateWorkerCluster(gomock.Any(), &expectDBCluster) - // TODO: expect SocketIO broadcast of the cluster creation. - echo := mf.prepareMockedJSONRequest(apiCluster) - require.NoError(t, mf.flamenco.CreateWorkerCluster(echo)) - assertResponseJSON(t, echo, http.StatusOK, &apiCluster) + mf.persistence.EXPECT().CreateWorkerTag(gomock.Any(), &expectDBTag) + // TODO: expect SocketIO broadcast of the tag creation. + echo := mf.prepareMockedJSONRequest(apiTag) + require.NoError(t, mf.flamenco.CreateWorkerTag(echo)) + assertResponseJSON(t, echo, http.StatusOK, &apiTag) - // Fetch the cluster - mf.persistence.EXPECT().FetchWorkerCluster(gomock.Any(), UUID).Return(&expectDBCluster, nil) + // Fetch the tag + mf.persistence.EXPECT().FetchWorkerTag(gomock.Any(), UUID).Return(&expectDBTag, nil) echo = mf.prepareMockedRequest(nil) - require.NoError(t, mf.flamenco.FetchWorkerCluster(echo, UUID)) - assertResponseJSON(t, echo, http.StatusOK, &apiCluster) + require.NoError(t, mf.flamenco.FetchWorkerTag(echo, UUID)) + assertResponseJSON(t, echo, http.StatusOK, &apiTag) // Update & save. newUUID := "60442762-83d3-4fc3-bf75-6ab5799cdbaa" - newAPICluster := api.WorkerCluster{ + newAPITag := api.WorkerTag{ Id: &newUUID, // Intentionally change the UUID. This should just be ignored. Name: "updated name", } - expectNewDBCluster := persistence.WorkerCluster{ + expectNewDBTag := persistence.WorkerTag{ UUID: UUID, - Name: newAPICluster.Name, + Name: newAPITag.Name, Description: "", } - // TODO: expect SocketIO broadcast of the cluster update. - mf.persistence.EXPECT().FetchWorkerCluster(gomock.Any(), UUID).Return(&expectDBCluster, nil) - mf.persistence.EXPECT().SaveWorkerCluster(gomock.Any(), &expectNewDBCluster) - echo = mf.prepareMockedJSONRequest(newAPICluster) - require.NoError(t, mf.flamenco.UpdateWorkerCluster(echo, UUID)) + // TODO: expect SocketIO broadcast of the tag update. + mf.persistence.EXPECT().FetchWorkerTag(gomock.Any(), UUID).Return(&expectDBTag, nil) + mf.persistence.EXPECT().SaveWorkerTag(gomock.Any(), &expectNewDBTag) + echo = mf.prepareMockedJSONRequest(newAPITag) + require.NoError(t, mf.flamenco.UpdateWorkerTag(echo, UUID)) assertResponseNoContent(t, echo) // Delete. - mf.persistence.EXPECT().DeleteWorkerCluster(gomock.Any(), UUID) - // TODO: expect SocketIO broadcast of the cluster deletion. - echo = mf.prepareMockedJSONRequest(newAPICluster) - require.NoError(t, mf.flamenco.DeleteWorkerCluster(echo, UUID)) + mf.persistence.EXPECT().DeleteWorkerTag(gomock.Any(), UUID) + // TODO: expect SocketIO broadcast of the tag deletion. + echo = mf.prepareMockedJSONRequest(newAPITag) + require.NoError(t, mf.flamenco.DeleteWorkerTag(echo, UUID)) assertResponseNoContent(t, echo) } diff --git a/internal/manager/job_compilers/author.go b/internal/manager/job_compilers/author.go index 7a457feb..c1d5dd3a 100644 --- a/internal/manager/job_compilers/author.go +++ b/internal/manager/job_compilers/author.go @@ -20,8 +20,8 @@ type Author struct { } type AuthoredJob struct { - JobID string - WorkerClusterUUID string + JobID string + WorkerTagUUID string Name string JobType string diff --git a/internal/manager/job_compilers/job_compilers.go b/internal/manager/job_compilers/job_compilers.go index 3b4cae4c..41228d0f 100644 --- a/internal/manager/job_compilers/job_compilers.go +++ b/internal/manager/job_compilers/job_compilers.go @@ -127,8 +127,8 @@ func (s *Service) Compile(ctx context.Context, sj api.SubmittedJob) (*AuthoredJo aj.Storage.ShamanCheckoutID = *sj.Storage.ShamanCheckoutId } - if sj.WorkerCluster != nil { - aj.WorkerClusterUUID = *sj.WorkerCluster + if sj.WorkerTag != nil { + aj.WorkerTagUUID = *sj.WorkerTag } compiler, err := vm.getCompileJob() diff --git a/internal/manager/job_compilers/job_compilers_test.go b/internal/manager/job_compilers/job_compilers_test.go index ad746b51..3fcccfaa 100644 --- a/internal/manager/job_compilers/job_compilers_test.go +++ b/internal/manager/job_compilers/job_compilers_test.go @@ -45,12 +45,12 @@ func exampleSubmittedJob() api.SubmittedJob { "user.name": "Sybren Stüvel", }} sj := api.SubmittedJob{ - Name: "3Д рендеринг", - Priority: 50, - Type: "simple-blender-render", - Settings: &settings, - Metadata: &metadata, - WorkerCluster: ptr("acce9983-e663-4210-b3cc-f7bfa629cb21"), + Name: "3Д рендеринг", + Priority: 50, + Type: "simple-blender-render", + Settings: &settings, + Metadata: &metadata, + WorkerTag: ptr("acce9983-e663-4210-b3cc-f7bfa629cb21"), } return sj } @@ -80,7 +80,7 @@ func TestSimpleBlenderRenderHappy(t *testing.T) { // Properties should be copied as-is. assert.Equal(t, sj.Name, aj.Name) - assert.Equal(t, *sj.WorkerCluster, aj.WorkerClusterUUID) + assert.Equal(t, *sj.WorkerTag, aj.WorkerTagUUID) assert.Equal(t, sj.Type, aj.JobType) assert.Equal(t, sj.Priority, aj.Priority) assert.EqualValues(t, sj.Settings.AdditionalProperties, aj.Settings) @@ -139,7 +139,7 @@ func TestSimpleBlenderRenderHappy(t *testing.T) { assert.Equal(t, expectDeps, tVideo.Dependencies) } -func TestJobWithoutCluster(t *testing.T) { +func TestJobWithoutTag(t *testing.T) { c := mockedClock(t) s, err := Load(c) @@ -151,20 +151,20 @@ func TestJobWithoutCluster(t *testing.T) { sj := exampleSubmittedJob() - // Try with nil WorkerCluster. + // Try with nil WorkerTag. { - sj.WorkerCluster = nil + sj.WorkerTag = nil aj, err := s.Compile(ctx, sj) require.NoError(t, err) - assert.Zero(t, aj.WorkerClusterUUID) + assert.Zero(t, aj.WorkerTagUUID) } - // Try with empty WorkerCluster. + // Try with empty WorkerTag. { - sj.WorkerCluster = ptr("") + sj.WorkerTag = ptr("") aj, err := s.Compile(ctx, sj) require.NoError(t, err) - assert.Zero(t, aj.WorkerClusterUUID) + assert.Zero(t, aj.WorkerTagUUID) } } diff --git a/internal/manager/persistence/db_migration.go b/internal/manager/persistence/db_migration.go index b60d9230..6c8bc570 100644 --- a/internal/manager/persistence/db_migration.go +++ b/internal/manager/persistence/db_migration.go @@ -16,7 +16,7 @@ func (db *DB) migrate() error { &Task{}, &TaskFailure{}, &Worker{}, - &WorkerCluster{}, + &WorkerTag{}, ) if err != nil { return fmt.Errorf("failed to automigrate database: %v", err) diff --git a/internal/manager/persistence/errors.go b/internal/manager/persistence/errors.go index 1316f481..0b7ebd6f 100644 --- a/internal/manager/persistence/errors.go +++ b/internal/manager/persistence/errors.go @@ -9,10 +9,10 @@ import ( ) var ( - ErrJobNotFound = PersistenceError{Message: "job not found", Err: gorm.ErrRecordNotFound} - ErrTaskNotFound = PersistenceError{Message: "task not found", Err: gorm.ErrRecordNotFound} - ErrWorkerNotFound = PersistenceError{Message: "worker not found", Err: gorm.ErrRecordNotFound} - ErrWorkerClusterNotFound = PersistenceError{Message: "worker cluster not found", Err: gorm.ErrRecordNotFound} + ErrJobNotFound = PersistenceError{Message: "job not found", Err: gorm.ErrRecordNotFound} + ErrTaskNotFound = PersistenceError{Message: "task not found", Err: gorm.ErrRecordNotFound} + ErrWorkerNotFound = PersistenceError{Message: "worker not found", Err: gorm.ErrRecordNotFound} + ErrWorkerTagNotFound = PersistenceError{Message: "worker tag not found", Err: gorm.ErrRecordNotFound} ) type PersistenceError struct { @@ -40,8 +40,8 @@ func workerError(errorToWrap error, message string, msgArgs ...interface{}) erro return wrapError(translateGormWorkerError(errorToWrap), message, msgArgs...) } -func workerClusterError(errorToWrap error, message string, msgArgs ...interface{}) error { - return wrapError(translateGormWorkerClusterError(errorToWrap), message, msgArgs...) +func workerTagError(errorToWrap error, message string, msgArgs ...interface{}) error { + return wrapError(translateGormWorkerTagError(errorToWrap), message, msgArgs...) } func wrapError(errorToWrap error, message string, format ...interface{}) error { @@ -86,11 +86,11 @@ func translateGormWorkerError(gormError error) error { return gormError } -// translateGormWorkerClusterError translates a Gorm error to a persistence layer error. +// translateGormWorkerTagError translates a Gorm error to a persistence layer error. // This helps to keep Gorm as "implementation detail" of the persistence layer. -func translateGormWorkerClusterError(gormError error) error { +func translateGormWorkerTagError(gormError error) error { if errors.Is(gormError, gorm.ErrRecordNotFound) { - return ErrWorkerClusterNotFound + return ErrWorkerTagNotFound } return gormError } diff --git a/internal/manager/persistence/jobs.go b/internal/manager/persistence/jobs.go index 66b9e0fa..8f6329d9 100644 --- a/internal/manager/persistence/jobs.go +++ b/internal/manager/persistence/jobs.go @@ -36,8 +36,8 @@ type Job struct { Storage JobStorageInfo `gorm:"embedded;embeddedPrefix:storage_"` - WorkerClusterID *uint - WorkerCluster *WorkerCluster `gorm:"foreignkey:WorkerClusterID;references:ID;constraint:OnDelete:SET NULL"` + WorkerTagID *uint + WorkerTag *WorkerTag `gorm:"foreignkey:WorkerTagID;references:ID;constraint:OnDelete:SET NULL"` } type StringInterfaceMap map[string]interface{} @@ -148,14 +148,14 @@ func (db *DB) StoreAuthoredJob(ctx context.Context, authoredJob job_compilers.Au }, } - // Find and assign the worker cluster. - if authoredJob.WorkerClusterUUID != "" { - dbCluster, err := fetchWorkerCluster(tx, authoredJob.WorkerClusterUUID) + // Find and assign the worker tag. + if authoredJob.WorkerTagUUID != "" { + dbTag, err := fetchWorkerTag(tx, authoredJob.WorkerTagUUID) if err != nil { return err } - dbJob.WorkerClusterID = &dbCluster.ID - dbJob.WorkerCluster = dbCluster + dbJob.WorkerTagID = &dbTag.ID + dbJob.WorkerTag = dbTag } if err := tx.Create(&dbJob).Error; err != nil { @@ -233,7 +233,7 @@ func (db *DB) FetchJob(ctx context.Context, jobUUID string) (*Job, error) { dbJob := Job{} findResult := db.gormDB.WithContext(ctx). Limit(1). - Preload("WorkerCluster"). + Preload("WorkerTag"). Find(&dbJob, "uuid = ?", jobUUID) if findResult.Error != nil { return nil, jobError(findResult.Error, "fetching job") diff --git a/internal/manager/persistence/jobs_blocklist.go b/internal/manager/persistence/jobs_blocklist.go index c12b09b7..da041ecf 100644 --- a/internal/manager/persistence/jobs_blocklist.go +++ b/internal/manager/persistence/jobs_blocklist.go @@ -108,16 +108,16 @@ func (db *DB) WorkersLeftToRun(ctx context.Context, job *Job, taskType string) ( Select("uuid"). Where("id not in (?)", blockedWorkers) - if job.WorkerClusterID == nil { + if job.WorkerTagID == nil { // Count all workers, so no extra restrictions are necessary. } else { - // Only count workers in the job's cluster. - jobCluster := db.gormDB. - Table("worker_cluster_membership"). + // Only count workers in the job's tag. + jobTag := db.gormDB. + Table("worker_tag_membership"). Select("worker_id"). - Where("worker_cluster_id = ?", *job.WorkerClusterID) + Where("worker_tag_id = ?", *job.WorkerTagID) query = query. - Where("id in (?)", jobCluster) + Where("id in (?)", jobTag) } // Find the workers NOT blocked. diff --git a/internal/manager/persistence/jobs_blocklist_test.go b/internal/manager/persistence/jobs_blocklist_test.go index 97e3503d..d82a4092 100644 --- a/internal/manager/persistence/jobs_blocklist_test.go +++ b/internal/manager/persistence/jobs_blocklist_test.go @@ -126,14 +126,14 @@ func TestWorkersLeftToRun(t *testing.T) { worker1 := createWorker(ctx, t, db) worker2 := createWorkerFrom(ctx, t, db, *worker1) - // Create one worker cluster. It will not be used by this job, but one of the + // Create one worker tag. It will not be used by this job, but one of the // workers will be assigned to it. It can get this job's tasks, though. - // Because the job is clusterless, it can be run by all. - cluster1 := WorkerCluster{UUID: "11157623-4b14-4801-bee2-271dddab6309", Name: "Cluster 1"} - require.NoError(t, db.CreateWorkerCluster(ctx, &cluster1)) + // Because the job is tagless, it can be run by all. + tag1 := WorkerTag{UUID: "11157623-4b14-4801-bee2-271dddab6309", Name: "Tag 1"} + require.NoError(t, db.CreateWorkerTag(ctx, &tag1)) workerC1 := createWorker(ctx, t, db, func(w *Worker) { w.UUID = "c1c1c1c1-0000-1111-2222-333333333333" - w.Clusters = []*WorkerCluster{&cluster1} + w.Tags = []*WorkerTag{&tag1} }) uuidMap := func(workers ...*Worker) map[string]bool { @@ -172,43 +172,43 @@ func TestWorkersLeftToRun(t *testing.T) { } } -func TestWorkersLeftToRunWithClusters(t *testing.T) { +func TestWorkersLeftToRunWithTags(t *testing.T) { ctx, cancel, db := persistenceTestFixtures(t, schedulerTestTimeout) defer cancel() - // Create clusters. - cluster1 := WorkerCluster{UUID: "11157623-4b14-4801-bee2-271dddab6309", Name: "Cluster 1"} - cluster2 := WorkerCluster{UUID: "22257623-4b14-4801-bee2-271dddab6309", Name: "Cluster 2"} - cluster3 := WorkerCluster{UUID: "33357623-4b14-4801-bee2-271dddab6309", Name: "Cluster 3"} - require.NoError(t, db.CreateWorkerCluster(ctx, &cluster1)) - require.NoError(t, db.CreateWorkerCluster(ctx, &cluster2)) - require.NoError(t, db.CreateWorkerCluster(ctx, &cluster3)) + // Create tags. + tag1 := WorkerTag{UUID: "11157623-4b14-4801-bee2-271dddab6309", Name: "Tag 1"} + tag2 := WorkerTag{UUID: "22257623-4b14-4801-bee2-271dddab6309", Name: "Tag 2"} + tag3 := WorkerTag{UUID: "33357623-4b14-4801-bee2-271dddab6309", Name: "Tag 3"} + require.NoError(t, db.CreateWorkerTag(ctx, &tag1)) + require.NoError(t, db.CreateWorkerTag(ctx, &tag2)) + require.NoError(t, db.CreateWorkerTag(ctx, &tag3)) - // Create a job in cluster1. + // Create a job in tag1. authoredJob := createTestAuthoredJobWithTasks() - authoredJob.WorkerClusterUUID = cluster1.UUID + authoredJob.WorkerTagUUID = tag1.UUID job := persistAuthoredJob(t, ctx, db, authoredJob) - // Clusters 1 + 3 + // Tags 1 + 3 workerC13 := createWorker(ctx, t, db, func(w *Worker) { w.UUID = "c13c1313-0000-1111-2222-333333333333" - w.Clusters = []*WorkerCluster{&cluster1, &cluster3} + w.Tags = []*WorkerTag{&tag1, &tag3} }) - // Cluster 1 + // Tag 1 workerC1 := createWorker(ctx, t, db, func(w *Worker) { w.UUID = "c1c1c1c1-0000-1111-2222-333333333333" - w.Clusters = []*WorkerCluster{&cluster1} + w.Tags = []*WorkerTag{&tag1} }) - // Cluster 2 worker, this one should never appear. + // Tag 2 worker, this one should never appear. createWorker(ctx, t, db, func(w *Worker) { w.UUID = "c2c2c2c2-0000-1111-2222-333333333333" - w.Clusters = []*WorkerCluster{&cluster2} + w.Tags = []*WorkerTag{&tag2} }) - // No clusters, so should be able to run only clusterless jobs. Which is none + // No tags, so should be able to run only tagless jobs. Which is none // in this test. createWorker(ctx, t, db, func(w *Worker) { w.UUID = "00000000-0000-1111-2222-333333333333" - w.Clusters = nil + w.Tags = nil }) uuidMap := func(workers ...*Worker) map[string]bool { @@ -219,7 +219,7 @@ func TestWorkersLeftToRunWithClusters(t *testing.T) { return theMap } - // All Cluster 1 workers, no blocklist. + // All Tag 1 workers, no blocklist. left, err := db.WorkersLeftToRun(ctx, job, "blender") require.NoError(t, err) assert.Equal(t, uuidMap(workerC13, workerC1), left) @@ -230,7 +230,7 @@ func TestWorkersLeftToRunWithClusters(t *testing.T) { require.NoError(t, err) assert.Equal(t, uuidMap(workerC13), left) - // All clustered workers blocked. + // All taged workers blocked. _ = db.AddWorkerToJobBlocklist(ctx, job, workerC13, "blender") left, err = db.WorkersLeftToRun(ctx, job, "blender") assert.NoError(t, err) diff --git a/internal/manager/persistence/jobs_query.go b/internal/manager/persistence/jobs_query.go index 63773b4a..77f295b8 100644 --- a/internal/manager/persistence/jobs_query.go +++ b/internal/manager/persistence/jobs_query.go @@ -64,7 +64,7 @@ func (db *DB) QueryJobs(ctx context.Context, apiQ api.JobsQuery) ([]*Job, error) } } - q.Preload("Cluster") + q.Preload("Tag") result := []*Job{} tx := q.Scan(&result) diff --git a/internal/manager/persistence/jobs_test.go b/internal/manager/persistence/jobs_test.go index 6fd36f66..f9623a4c 100644 --- a/internal/manager/persistence/jobs_test.go +++ b/internal/manager/persistence/jobs_test.go @@ -757,7 +757,7 @@ func createWorker(ctx context.Context, t *testing.T, db *DB, updaters ...func(*W Software: "3.0", Status: api.WorkerStatusAwake, SupportedTaskTypes: "blender,ffmpeg,file-management", - Clusters: nil, + Tags: nil, } for _, updater := range updaters { diff --git a/internal/manager/persistence/task_scheduler.go b/internal/manager/persistence/task_scheduler.go index 08f135f9..47560e5d 100644 --- a/internal/manager/persistence/task_scheduler.go +++ b/internal/manager/persistence/task_scheduler.go @@ -26,7 +26,7 @@ func (db *DB) ScheduleTask(ctx context.Context, w *Worker) (*Task, error) { logger := log.With().Str("worker", w.UUID).Logger() logger.Trace().Msg("finding task for worker") - hasWorkerClusters, err := db.HasWorkerClusters(ctx) + hasWorkerTags, err := db.HasWorkerTags(ctx) if err != nil { return nil, err } @@ -37,7 +37,7 @@ func (db *DB) ScheduleTask(ctx context.Context, w *Worker) (*Task, error) { var task *Task txErr := db.gormDB.WithContext(ctx).Transaction(func(tx *gorm.DB) error { var err error - task, err = findTaskForWorker(tx, w, hasWorkerClusters) + task, err = findTaskForWorker(tx, w, hasWorkerTags) if err != nil { if isDatabaseBusyError(err) { logger.Trace().Err(err).Msg("database busy while finding task for worker") @@ -84,7 +84,7 @@ func (db *DB) ScheduleTask(ctx context.Context, w *Worker) (*Task, error) { return task, nil } -func findTaskForWorker(tx *gorm.DB, w *Worker, checkWorkerClusters bool) (*Task, error) { +func findTaskForWorker(tx *gorm.DB, w *Worker, checkWorkerTags bool) (*Task, error) { task := Task{} // If a task is alreay active & assigned to this worker, return just that. @@ -129,21 +129,21 @@ func findTaskForWorker(tx *gorm.DB, w *Worker, checkWorkerClusters bool) (*Task, Where("TF.worker_id is NULL"). // Not failed before Where("tasks.type not in (?)", blockedTaskTypesQuery) // Non-blocklisted - if checkWorkerClusters { - // The system has one or more clusters, so limit the available jobs to those - // that have no cluster, or overlap with the Worker's clusters. - if len(w.Clusters) == 0 { - // Clusterless workers only get clusterless jobs. + if checkWorkerTags { + // The system has one or more tags, so limit the available jobs to those + // that have no tag, or overlap with the Worker's tags. + if len(w.Tags) == 0 { + // Tagless workers only get tagless jobs. findTaskQuery = findTaskQuery. - Where("jobs.worker_cluster_id is NULL") + Where("jobs.worker_tag_id is NULL") } else { - // Clustered workers get clusterless jobs AND jobs of their own clusters. - clusterIDs := []uint{} - for _, cluster := range w.Clusters { - clusterIDs = append(clusterIDs, cluster.ID) + // Taged workers get tagless jobs AND jobs of their own tags. + tagIDs := []uint{} + for _, tag := range w.Tags { + tagIDs = append(tagIDs, tag.ID) } findTaskQuery = findTaskQuery. - Where("jobs.worker_cluster_id is NULL or worker_cluster_id in ?", clusterIDs) + Where("jobs.worker_tag_id is NULL or worker_tag_id in ?", tagIDs) } } diff --git a/internal/manager/persistence/task_scheduler_test.go b/internal/manager/persistence/task_scheduler_test.go index 90fe0b8f..0005bdfc 100644 --- a/internal/manager/persistence/task_scheduler_test.go +++ b/internal/manager/persistence/task_scheduler_test.go @@ -291,87 +291,87 @@ func TestPreviouslyFailed(t *testing.T) { assert.Equal(t, att2.Name, task.Name, "the second task should have been chosen") } -func TestWorkerClusterJobWithCluster(t *testing.T) { +func TestWorkerTagJobWithTag(t *testing.T) { ctx, cancel, db := persistenceTestFixtures(t, schedulerTestTimeout) defer cancel() - // Create worker clusters: - cluster1 := WorkerCluster{UUID: "f0157623-4b14-4801-bee2-271dddab6309", Name: "Cluster 1"} - cluster2 := WorkerCluster{UUID: "2f71dba1-cf92-4752-8386-f5926affabd5", Name: "Cluster 2"} - require.NoError(t, db.CreateWorkerCluster(ctx, &cluster1)) - require.NoError(t, db.CreateWorkerCluster(ctx, &cluster2)) + // Create worker tags: + tag1 := WorkerTag{UUID: "f0157623-4b14-4801-bee2-271dddab6309", Name: "Tag 1"} + tag2 := WorkerTag{UUID: "2f71dba1-cf92-4752-8386-f5926affabd5", Name: "Tag 2"} + require.NoError(t, db.CreateWorkerTag(ctx, &tag1)) + require.NoError(t, db.CreateWorkerTag(ctx, &tag2)) - // Create a worker in cluster1: + // Create a worker in tag1: workerC := linuxWorker(t, db, func(w *Worker) { - w.Clusters = []*WorkerCluster{&cluster1} + w.Tags = []*WorkerTag{&tag1} }) - // Create a worker without cluster: + // Create a worker without tag: workerNC := linuxWorker(t, db, func(w *Worker) { w.UUID = "c53f8f68-4149-4790-991c-ba73a326551e" - w.Clusters = nil + w.Tags = nil }) - { // Test job with different cluster: + { // Test job with different tag: authTask := authorTestTask("the task", "blender") job := authorTestJob("499cf0f8-e83d-4cb1-837a-df94789d07db", "simple-blender-render", authTask) - job.WorkerClusterUUID = cluster2.UUID + job.WorkerTagUUID = tag2.UUID constructTestJob(ctx, t, db, job) task, err := db.ScheduleTask(ctx, &workerC) require.NoError(t, err) - assert.Nil(t, task, "job with different cluster should not be scheduled") + assert.Nil(t, task, "job with different tag should not be scheduled") } - { // Test job with matching cluster: + { // Test job with matching tag: authTask := authorTestTask("the task", "blender") job := authorTestJob("5d4c2321-0bb7-4c13-a9dd-32a2c0cd156e", "simple-blender-render", authTask) - job.WorkerClusterUUID = cluster1.UUID + job.WorkerTagUUID = tag1.UUID constructTestJob(ctx, t, db, job) task, err := db.ScheduleTask(ctx, &workerC) require.NoError(t, err) - require.NotNil(t, task, "job with matching cluster should be scheduled") + require.NotNil(t, task, "job with matching tag should be scheduled") assert.Equal(t, authTask.UUID, task.UUID) task, err = db.ScheduleTask(ctx, &workerNC) require.NoError(t, err) - assert.Nil(t, task, "job with cluster should not be scheduled for worker without cluster") + assert.Nil(t, task, "job with tag should not be scheduled for worker without tag") } } -func TestWorkerClusterJobWithoutCluster(t *testing.T) { +func TestWorkerTagJobWithoutTag(t *testing.T) { ctx, cancel, db := persistenceTestFixtures(t, schedulerTestTimeout) defer cancel() - // Create worker cluster: - cluster1 := WorkerCluster{UUID: "f0157623-4b14-4801-bee2-271dddab6309", Name: "Cluster 1"} - require.NoError(t, db.CreateWorkerCluster(ctx, &cluster1)) + // Create worker tag: + tag1 := WorkerTag{UUID: "f0157623-4b14-4801-bee2-271dddab6309", Name: "Tag 1"} + require.NoError(t, db.CreateWorkerTag(ctx, &tag1)) - // Create a worker in cluster1: + // Create a worker in tag1: workerC := linuxWorker(t, db, func(w *Worker) { - w.Clusters = []*WorkerCluster{&cluster1} + w.Tags = []*WorkerTag{&tag1} }) - // Create a worker without cluster: + // Create a worker without tag: workerNC := linuxWorker(t, db, func(w *Worker) { w.UUID = "c53f8f68-4149-4790-991c-ba73a326551e" - w.Clusters = nil + w.Tags = nil }) - // Test cluster-less job: + // Test tag-less job: authTask := authorTestTask("the task", "blender") job := authorTestJob("b6a1d859-122f-4791-8b78-b943329a9989", "simple-blender-render", authTask) constructTestJob(ctx, t, db, job) task, err := db.ScheduleTask(ctx, &workerC) require.NoError(t, err) - require.NotNil(t, task, "job without cluster should always be scheduled to worker in some cluster") + require.NotNil(t, task, "job without tag should always be scheduled to worker in some tag") assert.Equal(t, authTask.UUID, task.UUID) task, err = db.ScheduleTask(ctx, &workerNC) require.NoError(t, err) - require.NotNil(t, task, "job without cluster should always be scheduled to worker without cluster") + require.NotNil(t, task, "job without tag should always be scheduled to worker without tag") assert.Equal(t, authTask.UUID, task.UUID) } diff --git a/internal/manager/persistence/test_support.go b/internal/manager/persistence/test_support.go index 80832819..2b1351c4 100644 --- a/internal/manager/persistence/test_support.go +++ b/internal/manager/persistence/test_support.go @@ -96,8 +96,8 @@ type WorkerTestFixture struct { ctx context.Context done func() - worker *Worker - cluster *WorkerCluster + worker *Worker + tag *WorkerTag } func workerTestFixtures(t *testing.T, testContextTimeout time.Duration) WorkerTestFixture { @@ -113,21 +113,21 @@ func workerTestFixtures(t *testing.T, testContextTimeout time.Duration) WorkerTe SupportedTaskTypes: "blender,ffmpeg,file-management", } - wc := WorkerCluster{ + wc := WorkerTag{ UUID: uuid.New(), Name: "arbejdsklynge", - Description: "Worker cluster in Danish", + Description: "Worker tag in Danish", } require.NoError(t, db.CreateWorker(ctx, &w)) - require.NoError(t, db.CreateWorkerCluster(ctx, &wc)) + require.NoError(t, db.CreateWorkerTag(ctx, &wc)) return WorkerTestFixture{ db: db, ctx: ctx, done: cancel, - worker: &w, - cluster: &wc, + worker: &w, + tag: &wc, } } diff --git a/internal/manager/persistence/worker_cluster.go b/internal/manager/persistence/worker_cluster.go deleted file mode 100644 index 60974e6d..00000000 --- a/internal/manager/persistence/worker_cluster.go +++ /dev/null @@ -1,112 +0,0 @@ -package persistence - -// SPDX-License-Identifier: GPL-3.0-or-later - -import ( - "context" - "fmt" - - "gorm.io/gorm" -) - -type WorkerCluster struct { - Model - - UUID string `gorm:"type:char(36);default:'';unique;index"` - Name string `gorm:"type:varchar(64);default:'';unique"` - Description string `gorm:"type:varchar(255);default:''"` - - Workers []*Worker `gorm:"many2many:worker_cluster_membership;constraint:OnDelete:CASCADE"` -} - -func (db *DB) CreateWorkerCluster(ctx context.Context, wc *WorkerCluster) error { - if err := db.gormDB.WithContext(ctx).Create(wc).Error; err != nil { - return fmt.Errorf("creating new worker cluster: %w", err) - } - return nil -} - -// HasWorkerClusters returns whether there are any clusters defined at all. -func (db *DB) HasWorkerClusters(ctx context.Context) (bool, error) { - var count int64 - tx := db.gormDB.WithContext(ctx). - Model(&WorkerCluster{}). - Count(&count) - if err := tx.Error; err != nil { - return false, workerClusterError(err, "counting worker clusters") - } - return count > 0, nil -} - -func (db *DB) FetchWorkerCluster(ctx context.Context, uuid string) (*WorkerCluster, error) { - tx := db.gormDB.WithContext(ctx) - return fetchWorkerCluster(tx, uuid) -} - -// fetchWorkerCluster fetches the worker cluster using the given database instance. -func fetchWorkerCluster(gormDB *gorm.DB, uuid string) (*WorkerCluster, error) { - w := WorkerCluster{} - tx := gormDB.First(&w, "uuid = ?", uuid) - if tx.Error != nil { - return nil, workerClusterError(tx.Error, "fetching worker cluster") - } - return &w, nil -} - -func (db *DB) SaveWorkerCluster(ctx context.Context, cluster *WorkerCluster) error { - if err := db.gormDB.WithContext(ctx).Save(cluster).Error; err != nil { - return workerClusterError(err, "saving worker cluster") - } - return nil -} - -// DeleteWorkerCluster deletes the given cluster, after unassigning all workers from it. -func (db *DB) DeleteWorkerCluster(ctx context.Context, uuid string) error { - tx := db.gormDB.WithContext(ctx). - Where("uuid = ?", uuid). - Delete(&WorkerCluster{}) - if tx.Error != nil { - return workerClusterError(tx.Error, "deleting worker cluster") - } - if tx.RowsAffected == 0 { - return ErrWorkerClusterNotFound - } - return nil -} - -func (db *DB) FetchWorkerClusters(ctx context.Context) ([]*WorkerCluster, error) { - clusters := make([]*WorkerCluster, 0) - tx := db.gormDB.WithContext(ctx).Model(&WorkerCluster{}).Scan(&clusters) - if tx.Error != nil { - return nil, workerClusterError(tx.Error, "fetching all worker clusters") - } - return clusters, nil -} - -func (db *DB) fetchWorkerClustersWithUUID(ctx context.Context, clusterUUIDs []string) ([]*WorkerCluster, error) { - clusters := make([]*WorkerCluster, 0) - tx := db.gormDB.WithContext(ctx). - Model(&WorkerCluster{}). - Where("uuid in ?", clusterUUIDs). - Scan(&clusters) - if tx.Error != nil { - return nil, workerClusterError(tx.Error, "fetching all worker clusters") - } - return clusters, nil -} - -func (db *DB) WorkerSetClusters(ctx context.Context, worker *Worker, clusterUUIDs []string) error { - clusters, err := db.fetchWorkerClustersWithUUID(ctx, clusterUUIDs) - if err != nil { - return workerClusterError(err, "fetching worker clusters") - } - - err = db.gormDB.WithContext(ctx). - Model(worker). - Association("Clusters"). - Replace(clusters) - if err != nil { - return workerClusterError(err, "updating worker clusters") - } - return nil -} diff --git a/internal/manager/persistence/worker_cluster_test.go b/internal/manager/persistence/worker_cluster_test.go deleted file mode 100644 index ed054c6b..00000000 --- a/internal/manager/persistence/worker_cluster_test.go +++ /dev/null @@ -1,165 +0,0 @@ -package persistence - -// SPDX-License-Identifier: GPL-3.0-or-later - -import ( - "testing" - "time" - - "git.blender.org/flamenco/internal/uuid" - "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/require" -) - -func TestCreateFetchCluster(t *testing.T) { - f := workerTestFixtures(t, 1*time.Second) - defer f.done() - - // Test fetching non-existent cluster - fetchedCluster, err := f.db.FetchWorkerCluster(f.ctx, "7ee21bc8-ff1a-42d2-a6b6-cc4b529b189f") - assert.ErrorIs(t, err, ErrWorkerClusterNotFound) - assert.Nil(t, fetchedCluster) - - // New cluster creation is already done in the workerTestFixtures() call. - assert.NotNil(t, f.cluster) - - fetchedCluster, err = f.db.FetchWorkerCluster(f.ctx, f.cluster.UUID) - require.NoError(t, err) - assert.NotNil(t, fetchedCluster) - - // Test contents of fetched cluster. - assert.Equal(t, f.cluster.UUID, fetchedCluster.UUID) - assert.Equal(t, f.cluster.Name, fetchedCluster.Name) - assert.Equal(t, f.cluster.Description, fetchedCluster.Description) - assert.Zero(t, fetchedCluster.Workers) -} - -func TestFetchDeleteClusters(t *testing.T) { - f := workerTestFixtures(t, 1*time.Second) - defer f.done() - - // Single cluster was created by fixture. - has, err := f.db.HasWorkerClusters(f.ctx) - require.NoError(t, err) - assert.True(t, has, "expecting HasWorkerClusters to return true") - - secondCluster := WorkerCluster{ - UUID: uuid.New(), - Name: "arbeiderscluster", - Description: "Worker cluster in Dutch", - } - - require.NoError(t, f.db.CreateWorkerCluster(f.ctx, &secondCluster)) - - allClusters, err := f.db.FetchWorkerClusters(f.ctx) - require.NoError(t, err) - - require.Len(t, allClusters, 2) - var allClusterIDs [2]string - for idx := range allClusters { - allClusterIDs[idx] = allClusters[idx].UUID - } - assert.Contains(t, allClusterIDs, f.cluster.UUID) - assert.Contains(t, allClusterIDs, secondCluster.UUID) - - has, err = f.db.HasWorkerClusters(f.ctx) - require.NoError(t, err) - assert.True(t, has, "expecting HasWorkerClusters to return true") - - // Test deleting the 2nd cluster. - require.NoError(t, f.db.DeleteWorkerCluster(f.ctx, secondCluster.UUID)) - - allClusters, err = f.db.FetchWorkerClusters(f.ctx) - require.NoError(t, err) - require.Len(t, allClusters, 1) - assert.Equal(t, f.cluster.UUID, allClusters[0].UUID) - - // Test deleting the 1st cluster. - require.NoError(t, f.db.DeleteWorkerCluster(f.ctx, f.cluster.UUID)) - has, err = f.db.HasWorkerClusters(f.ctx) - require.NoError(t, err) - assert.False(t, has, "expecting HasWorkerClusters to return false") -} - -func TestAssignUnassignWorkerClusters(t *testing.T) { - f := workerTestFixtures(t, 1*time.Second) - defer f.done() - - assertClusters := func(msgLabel string, clusterUUIDs ...string) { - w, err := f.db.FetchWorker(f.ctx, f.worker.UUID) - require.NoError(t, err) - - // Catch doubly-reported clusters, as the maps below would hide those cases. - assert.Len(t, w.Clusters, len(clusterUUIDs), msgLabel) - - expectClusters := make(map[string]bool) - for _, cid := range clusterUUIDs { - expectClusters[cid] = true - } - - actualClusters := make(map[string]bool) - for _, c := range w.Clusters { - actualClusters[c.UUID] = true - } - - assert.Equal(t, expectClusters, actualClusters, msgLabel) - } - - secondCluster := WorkerCluster{ - UUID: uuid.New(), - Name: "arbeiderscluster", - Description: "Worker cluster in Dutch", - } - - require.NoError(t, f.db.CreateWorkerCluster(f.ctx, &secondCluster)) - - // By default the Worker should not be part of a cluster. - assertClusters("default cluster assignment") - - require.NoError(t, f.db.WorkerSetClusters(f.ctx, f.worker, []string{f.cluster.UUID})) - assertClusters("setting one cluster", f.cluster.UUID) - - // Double assignments should also just work. - require.NoError(t, f.db.WorkerSetClusters(f.ctx, f.worker, []string{f.cluster.UUID, f.cluster.UUID})) - assertClusters("setting twice the same cluster", f.cluster.UUID) - - // Multiple cluster memberships. - require.NoError(t, f.db.WorkerSetClusters(f.ctx, f.worker, []string{f.cluster.UUID, secondCluster.UUID})) - assertClusters("setting two different clusters", f.cluster.UUID, secondCluster.UUID) - - // Remove memberships. - require.NoError(t, f.db.WorkerSetClusters(f.ctx, f.worker, []string{secondCluster.UUID})) - assertClusters("unassigning from first cluster", secondCluster.UUID) - require.NoError(t, f.db.WorkerSetClusters(f.ctx, f.worker, []string{})) - assertClusters("unassigning from second cluster") -} - -func TestSaveWorkerCluster(t *testing.T) { - f := workerTestFixtures(t, 1*time.Second) - defer f.done() - - f.cluster.Name = "übercluster" - f.cluster.Description = "ʻO kēlā hui ma laila" - require.NoError(t, f.db.SaveWorkerCluster(f.ctx, f.cluster)) - - fetched, err := f.db.FetchWorkerCluster(f.ctx, f.cluster.UUID) - require.NoError(t, err) - assert.Equal(t, f.cluster.Name, fetched.Name) - assert.Equal(t, f.cluster.Description, fetched.Description) -} - -func TestDeleteWorkerClusterWithWorkersAssigned(t *testing.T) { - f := workerTestFixtures(t, 1*time.Second) - defer f.done() - - // Assign the worker. - require.NoError(t, f.db.WorkerSetClusters(f.ctx, f.worker, []string{f.cluster.UUID})) - - // Delete the cluster. - require.NoError(t, f.db.DeleteWorkerCluster(f.ctx, f.cluster.UUID)) - - // Check the Worker has been unassigned from the cluster. - w, err := f.db.FetchWorker(f.ctx, f.worker.UUID) - require.NoError(t, err) - assert.Empty(t, w.Clusters) -} diff --git a/internal/manager/persistence/worker_tag.go b/internal/manager/persistence/worker_tag.go new file mode 100644 index 00000000..6e0c1506 --- /dev/null +++ b/internal/manager/persistence/worker_tag.go @@ -0,0 +1,112 @@ +package persistence + +// SPDX-License-Identifier: GPL-3.0-or-later + +import ( + "context" + "fmt" + + "gorm.io/gorm" +) + +type WorkerTag struct { + Model + + UUID string `gorm:"type:char(36);default:'';unique;index"` + Name string `gorm:"type:varchar(64);default:'';unique"` + Description string `gorm:"type:varchar(255);default:''"` + + Workers []*Worker `gorm:"many2many:worker_tag_membership;constraint:OnDelete:CASCADE"` +} + +func (db *DB) CreateWorkerTag(ctx context.Context, wc *WorkerTag) error { + if err := db.gormDB.WithContext(ctx).Create(wc).Error; err != nil { + return fmt.Errorf("creating new worker tag: %w", err) + } + return nil +} + +// HasWorkerTags returns whether there are any tags defined at all. +func (db *DB) HasWorkerTags(ctx context.Context) (bool, error) { + var count int64 + tx := db.gormDB.WithContext(ctx). + Model(&WorkerTag{}). + Count(&count) + if err := tx.Error; err != nil { + return false, workerTagError(err, "counting worker tags") + } + return count > 0, nil +} + +func (db *DB) FetchWorkerTag(ctx context.Context, uuid string) (*WorkerTag, error) { + tx := db.gormDB.WithContext(ctx) + return fetchWorkerTag(tx, uuid) +} + +// fetchWorkerTag fetches the worker tag using the given database instance. +func fetchWorkerTag(gormDB *gorm.DB, uuid string) (*WorkerTag, error) { + w := WorkerTag{} + tx := gormDB.First(&w, "uuid = ?", uuid) + if tx.Error != nil { + return nil, workerTagError(tx.Error, "fetching worker tag") + } + return &w, nil +} + +func (db *DB) SaveWorkerTag(ctx context.Context, tag *WorkerTag) error { + if err := db.gormDB.WithContext(ctx).Save(tag).Error; err != nil { + return workerTagError(err, "saving worker tag") + } + return nil +} + +// DeleteWorkerTag deletes the given tag, after unassigning all workers from it. +func (db *DB) DeleteWorkerTag(ctx context.Context, uuid string) error { + tx := db.gormDB.WithContext(ctx). + Where("uuid = ?", uuid). + Delete(&WorkerTag{}) + if tx.Error != nil { + return workerTagError(tx.Error, "deleting worker tag") + } + if tx.RowsAffected == 0 { + return ErrWorkerTagNotFound + } + return nil +} + +func (db *DB) FetchWorkerTags(ctx context.Context) ([]*WorkerTag, error) { + tags := make([]*WorkerTag, 0) + tx := db.gormDB.WithContext(ctx).Model(&WorkerTag{}).Scan(&tags) + if tx.Error != nil { + return nil, workerTagError(tx.Error, "fetching all worker tags") + } + return tags, nil +} + +func (db *DB) fetchWorkerTagsWithUUID(ctx context.Context, tagUUIDs []string) ([]*WorkerTag, error) { + tags := make([]*WorkerTag, 0) + tx := db.gormDB.WithContext(ctx). + Model(&WorkerTag{}). + Where("uuid in ?", tagUUIDs). + Scan(&tags) + if tx.Error != nil { + return nil, workerTagError(tx.Error, "fetching all worker tags") + } + return tags, nil +} + +func (db *DB) WorkerSetTags(ctx context.Context, worker *Worker, tagUUIDs []string) error { + tags, err := db.fetchWorkerTagsWithUUID(ctx, tagUUIDs) + if err != nil { + return workerTagError(err, "fetching worker tags") + } + + err = db.gormDB.WithContext(ctx). + Model(worker). + Association("Tags"). + Replace(tags) + if err != nil { + return workerTagError(err, "updating worker tags") + } + return nil +} diff --git a/internal/manager/persistence/worker_tag_test.go b/internal/manager/persistence/worker_tag_test.go new file mode 100644 index 00000000..372332fd --- /dev/null +++ b/internal/manager/persistence/worker_tag_test.go @@ -0,0 +1,165 @@ +package persistence + +// SPDX-License-Identifier: GPL-3.0-or-later + +import ( + "testing" + "time" + + "git.blender.org/flamenco/internal/uuid" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" +) + +func TestCreateFetchTag(t *testing.T) { + f := workerTestFixtures(t, 1*time.Second) + defer f.done() + + // Test fetching non-existent tag + fetchedTag, err := f.db.FetchWorkerTag(f.ctx, "7ee21bc8-ff1a-42d2-a6b6-cc4b529b189f") + assert.ErrorIs(t, err, ErrWorkerTagNotFound) + assert.Nil(t, fetchedTag) + + // New tag creation is already done in the workerTestFixtures() call. + assert.NotNil(t, f.tag) + + fetchedTag, err = f.db.FetchWorkerTag(f.ctx, f.tag.UUID) + require.NoError(t, err) + assert.NotNil(t, fetchedTag) + + // Test contents of fetched tag. + assert.Equal(t, f.tag.UUID, fetchedTag.UUID) + assert.Equal(t, f.tag.Name, fetchedTag.Name) + assert.Equal(t, f.tag.Description, fetchedTag.Description) + assert.Zero(t, fetchedTag.Workers) +} + +func TestFetchDeleteTags(t *testing.T) { + f := workerTestFixtures(t, 1*time.Second) + defer f.done() + + // Single tag was created by fixture. + has, err := f.db.HasWorkerTags(f.ctx) + require.NoError(t, err) + assert.True(t, has, "expecting HasWorkerTags to return true") + + secondTag := WorkerTag{ + UUID: uuid.New(), + Name: "arbeiderstag", + Description: "Worker tag in Dutch", + } + + require.NoError(t, f.db.CreateWorkerTag(f.ctx, &secondTag)) + + allTags, err := f.db.FetchWorkerTags(f.ctx) + require.NoError(t, err) + + require.Len(t, allTags, 2) + var allTagIDs [2]string + for idx := range allTags { + allTagIDs[idx] = allTags[idx].UUID + } + assert.Contains(t, allTagIDs, f.tag.UUID) + assert.Contains(t, allTagIDs, secondTag.UUID) + + has, err = f.db.HasWorkerTags(f.ctx) + require.NoError(t, err) + assert.True(t, has, "expecting HasWorkerTags to return true") + + // Test deleting the 2nd tag. + require.NoError(t, f.db.DeleteWorkerTag(f.ctx, secondTag.UUID)) + + allTags, err = f.db.FetchWorkerTags(f.ctx) + require.NoError(t, err) + require.Len(t, allTags, 1) + assert.Equal(t, f.tag.UUID, allTags[0].UUID) + + // Test deleting the 1st tag. + require.NoError(t, f.db.DeleteWorkerTag(f.ctx, f.tag.UUID)) + has, err = f.db.HasWorkerTags(f.ctx) + require.NoError(t, err) + assert.False(t, has, "expecting HasWorkerTags to return false") +} + +func TestAssignUnassignWorkerTags(t *testing.T) { + f := workerTestFixtures(t, 1*time.Second) + defer f.done() + + assertTags := func(msgLabel string, tagUUIDs ...string) { + w, err := f.db.FetchWorker(f.ctx, f.worker.UUID) + require.NoError(t, err) + + // Catch doubly-reported tags, as the maps below would hide those cases. + assert.Len(t, w.Tags, len(tagUUIDs), msgLabel) + + expectTags := make(map[string]bool) + for _, cid := range tagUUIDs { + expectTags[cid] = true + } + + actualTags := make(map[string]bool) + for _, c := range w.Tags { + actualTags[c.UUID] = true + } + + assert.Equal(t, expectTags, actualTags, msgLabel) + } + + secondTag := WorkerTag{ + UUID: uuid.New(), + Name: "arbeiderstag", + Description: "Worker tag in Dutch", + } + + require.NoError(t, f.db.CreateWorkerTag(f.ctx, &secondTag)) + + // By default the Worker should not be part of a tag. + assertTags("default tag assignment") + + require.NoError(t, f.db.WorkerSetTags(f.ctx, f.worker, []string{f.tag.UUID})) + assertTags("setting one tag", f.tag.UUID) + + // Double assignments should also just work. + require.NoError(t, f.db.WorkerSetTags(f.ctx, f.worker, []string{f.tag.UUID, f.tag.UUID})) + assertTags("setting twice the same tag", f.tag.UUID) + + // Multiple tag memberships. + require.NoError(t, f.db.WorkerSetTags(f.ctx, f.worker, []string{f.tag.UUID, secondTag.UUID})) + assertTags("setting two different tags", f.tag.UUID, secondTag.UUID) + + // Remove memberships. + require.NoError(t, f.db.WorkerSetTags(f.ctx, f.worker, []string{secondTag.UUID})) + assertTags("unassigning from first tag", secondTag.UUID) + require.NoError(t, f.db.WorkerSetTags(f.ctx, f.worker, []string{})) + assertTags("unassigning from second tag") +} + +func TestSaveWorkerTag(t *testing.T) { + f := workerTestFixtures(t, 1*time.Second) + defer f.done() + + f.tag.Name = "übertag" + f.tag.Description = "ʻO kēlā hui ma laila" + require.NoError(t, f.db.SaveWorkerTag(f.ctx, f.tag)) + + fetched, err := f.db.FetchWorkerTag(f.ctx, f.tag.UUID) + require.NoError(t, err) + assert.Equal(t, f.tag.Name, fetched.Name) + assert.Equal(t, f.tag.Description, fetched.Description) +} + +func TestDeleteWorkerTagWithWorkersAssigned(t *testing.T) { + f := workerTestFixtures(t, 1*time.Second) + defer f.done() + + // Assign the worker. + require.NoError(t, f.db.WorkerSetTags(f.ctx, f.worker, []string{f.tag.UUID})) + + // Delete the tag. + require.NoError(t, f.db.DeleteWorkerTag(f.ctx, f.tag.UUID)) + + // Check the Worker has been unassigned from the tag. + w, err := f.db.FetchWorker(f.ctx, f.worker.UUID) + require.NoError(t, err) + assert.Empty(t, w.Tags) +} diff --git a/internal/manager/persistence/workers.go b/internal/manager/persistence/workers.go index b71996ab..4fe25431 100644 --- a/internal/manager/persistence/workers.go +++ b/internal/manager/persistence/workers.go @@ -31,7 +31,7 @@ type Worker struct { SupportedTaskTypes string `gorm:"type:varchar(255);default:''"` // comma-separated list of task types. - Clusters []*WorkerCluster `gorm:"many2many:worker_cluster_membership;constraint:OnDelete:CASCADE"` + Tags []*WorkerTag `gorm:"many2many:worker_tag_membership;constraint:OnDelete:CASCADE"` } func (w *Worker) Identifier() string { @@ -73,7 +73,7 @@ func (db *DB) CreateWorker(ctx context.Context, w *Worker) error { func (db *DB) FetchWorker(ctx context.Context, uuid string) (*Worker, error) { w := Worker{} tx := db.gormDB.WithContext(ctx). - Preload("Clusters"). + Preload("Tags"). First(&w, "uuid = ?", uuid) if tx.Error != nil { return nil, workerError(tx.Error, "fetching worker") diff --git a/internal/manager/persistence/workers_test.go b/internal/manager/persistence/workers_test.go index 38417f01..a92bf705 100644 --- a/internal/manager/persistence/workers_test.go +++ b/internal/manager/persistence/workers_test.go @@ -319,18 +319,18 @@ func TestDeleteWorker(t *testing.T) { } } -func TestDeleteWorkerWithClusterAssigned(t *testing.T) { +func TestDeleteWorkerWithTagAssigned(t *testing.T) { f := workerTestFixtures(t, 1*time.Second) defer f.done() // Assign the worker. - require.NoError(t, f.db.WorkerSetClusters(f.ctx, f.worker, []string{f.cluster.UUID})) + require.NoError(t, f.db.WorkerSetTags(f.ctx, f.worker, []string{f.tag.UUID})) // Delete the Worker. require.NoError(t, f.db.DeleteWorker(f.ctx, f.worker.UUID)) - // Check the Worker has been unassigned from the cluster. - cluster, err := f.db.FetchWorkerCluster(f.ctx, f.cluster.UUID) + // Check the Worker has been unassigned from the tag. + tag, err := f.db.FetchWorkerTag(f.ctx, f.tag.UUID) require.NoError(t, err) - assert.Empty(t, cluster.Workers) + assert.Empty(t, tag.Workers) } diff --git a/internal/manager/webupdates/worker_updates.go b/internal/manager/webupdates/worker_updates.go index a088cdb3..a60f40d8 100644 --- a/internal/manager/webupdates/worker_updates.go +++ b/internal/manager/webupdates/worker_updates.go @@ -32,7 +32,7 @@ func NewWorkerUpdate(worker *persistence.Worker) api.SocketIOWorkerUpdate { workerUpdate.LastSeen = &worker.LastSeenAt } - // TODO: add cluster IDs. + // TODO: add tag IDs. return workerUpdate } diff --git a/internal/worker/mocks/client.gen.go b/internal/worker/mocks/client.gen.go index 7ef5594e..3d4b19fa 100644 --- a/internal/worker/mocks/client.gen.go +++ b/internal/worker/mocks/client.gen.go @@ -116,44 +116,44 @@ func (mr *MockFlamencoClientMockRecorder) CheckSharedStoragePathWithResponse(arg return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CheckSharedStoragePathWithResponse", reflect.TypeOf((*MockFlamencoClient)(nil).CheckSharedStoragePathWithResponse), varargs...) } -// CreateWorkerClusterWithBodyWithResponse mocks base method. -func (m *MockFlamencoClient) CreateWorkerClusterWithBodyWithResponse(arg0 context.Context, arg1 string, arg2 io.Reader, arg3 ...api.RequestEditorFn) (*api.CreateWorkerClusterResponse, error) { +// CreateWorkerTagWithBodyWithResponse mocks base method. +func (m *MockFlamencoClient) CreateWorkerTagWithBodyWithResponse(arg0 context.Context, arg1 string, arg2 io.Reader, arg3 ...api.RequestEditorFn) (*api.CreateWorkerTagResponse, error) { m.ctrl.T.Helper() varargs := []interface{}{arg0, arg1, arg2} for _, a := range arg3 { varargs = append(varargs, a) } - ret := m.ctrl.Call(m, "CreateWorkerClusterWithBodyWithResponse", varargs...) - ret0, _ := ret[0].(*api.CreateWorkerClusterResponse) + ret := m.ctrl.Call(m, "CreateWorkerTagWithBodyWithResponse", varargs...) + ret0, _ := ret[0].(*api.CreateWorkerTagResponse) ret1, _ := ret[1].(error) return ret0, ret1 } -// CreateWorkerClusterWithBodyWithResponse indicates an expected call of CreateWorkerClusterWithBodyWithResponse. -func (mr *MockFlamencoClientMockRecorder) CreateWorkerClusterWithBodyWithResponse(arg0, arg1, arg2 interface{}, arg3 ...interface{}) *gomock.Call { +// CreateWorkerTagWithBodyWithResponse indicates an expected call of CreateWorkerTagWithBodyWithResponse. +func (mr *MockFlamencoClientMockRecorder) CreateWorkerTagWithBodyWithResponse(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, "CreateWorkerClusterWithBodyWithResponse", reflect.TypeOf((*MockFlamencoClient)(nil).CreateWorkerClusterWithBodyWithResponse), varargs...) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CreateWorkerTagWithBodyWithResponse", reflect.TypeOf((*MockFlamencoClient)(nil).CreateWorkerTagWithBodyWithResponse), varargs...) } -// CreateWorkerClusterWithResponse mocks base method. -func (m *MockFlamencoClient) CreateWorkerClusterWithResponse(arg0 context.Context, arg1 api.CreateWorkerClusterJSONRequestBody, arg2 ...api.RequestEditorFn) (*api.CreateWorkerClusterResponse, error) { +// CreateWorkerTagWithResponse mocks base method. +func (m *MockFlamencoClient) CreateWorkerTagWithResponse(arg0 context.Context, arg1 api.CreateWorkerTagJSONRequestBody, arg2 ...api.RequestEditorFn) (*api.CreateWorkerTagResponse, error) { m.ctrl.T.Helper() varargs := []interface{}{arg0, arg1} for _, a := range arg2 { varargs = append(varargs, a) } - ret := m.ctrl.Call(m, "CreateWorkerClusterWithResponse", varargs...) - ret0, _ := ret[0].(*api.CreateWorkerClusterResponse) + ret := m.ctrl.Call(m, "CreateWorkerTagWithResponse", varargs...) + ret0, _ := ret[0].(*api.CreateWorkerTagResponse) ret1, _ := ret[1].(error) return ret0, ret1 } -// CreateWorkerClusterWithResponse indicates an expected call of CreateWorkerClusterWithResponse. -func (mr *MockFlamencoClientMockRecorder) CreateWorkerClusterWithResponse(arg0, arg1 interface{}, arg2 ...interface{}) *gomock.Call { +// CreateWorkerTagWithResponse indicates an expected call of CreateWorkerTagWithResponse. +func (mr *MockFlamencoClientMockRecorder) CreateWorkerTagWithResponse(arg0, arg1 interface{}, arg2 ...interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() varargs := append([]interface{}{arg0, arg1}, arg2...) - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CreateWorkerClusterWithResponse", reflect.TypeOf((*MockFlamencoClient)(nil).CreateWorkerClusterWithResponse), varargs...) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CreateWorkerTagWithResponse", reflect.TypeOf((*MockFlamencoClient)(nil).CreateWorkerTagWithResponse), varargs...) } // DeleteJobWhatWouldItDoWithResponse mocks base method. @@ -196,24 +196,24 @@ func (mr *MockFlamencoClientMockRecorder) DeleteJobWithResponse(arg0, arg1 inter return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DeleteJobWithResponse", reflect.TypeOf((*MockFlamencoClient)(nil).DeleteJobWithResponse), varargs...) } -// DeleteWorkerClusterWithResponse mocks base method. -func (m *MockFlamencoClient) DeleteWorkerClusterWithResponse(arg0 context.Context, arg1 string, arg2 ...api.RequestEditorFn) (*api.DeleteWorkerClusterResponse, error) { +// DeleteWorkerTagWithResponse mocks base method. +func (m *MockFlamencoClient) DeleteWorkerTagWithResponse(arg0 context.Context, arg1 string, arg2 ...api.RequestEditorFn) (*api.DeleteWorkerTagResponse, error) { m.ctrl.T.Helper() varargs := []interface{}{arg0, arg1} for _, a := range arg2 { varargs = append(varargs, a) } - ret := m.ctrl.Call(m, "DeleteWorkerClusterWithResponse", varargs...) - ret0, _ := ret[0].(*api.DeleteWorkerClusterResponse) + ret := m.ctrl.Call(m, "DeleteWorkerTagWithResponse", varargs...) + ret0, _ := ret[0].(*api.DeleteWorkerTagResponse) ret1, _ := ret[1].(error) return ret0, ret1 } -// DeleteWorkerClusterWithResponse indicates an expected call of DeleteWorkerClusterWithResponse. -func (mr *MockFlamencoClientMockRecorder) DeleteWorkerClusterWithResponse(arg0, arg1 interface{}, arg2 ...interface{}) *gomock.Call { +// DeleteWorkerTagWithResponse indicates an expected call of DeleteWorkerTagWithResponse. +func (mr *MockFlamencoClientMockRecorder) DeleteWorkerTagWithResponse(arg0, arg1 interface{}, arg2 ...interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() varargs := append([]interface{}{arg0, arg1}, arg2...) - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DeleteWorkerClusterWithResponse", reflect.TypeOf((*MockFlamencoClient)(nil).DeleteWorkerClusterWithResponse), varargs...) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DeleteWorkerTagWithResponse", reflect.TypeOf((*MockFlamencoClient)(nil).DeleteWorkerTagWithResponse), varargs...) } // DeleteWorkerWithResponse mocks base method. @@ -396,46 +396,6 @@ func (mr *MockFlamencoClientMockRecorder) FetchTaskWithResponse(arg0, arg1 inter return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "FetchTaskWithResponse", reflect.TypeOf((*MockFlamencoClient)(nil).FetchTaskWithResponse), varargs...) } -// FetchWorkerClusterWithResponse mocks base method. -func (m *MockFlamencoClient) FetchWorkerClusterWithResponse(arg0 context.Context, arg1 string, arg2 ...api.RequestEditorFn) (*api.FetchWorkerClusterResponse, error) { - m.ctrl.T.Helper() - varargs := []interface{}{arg0, arg1} - for _, a := range arg2 { - varargs = append(varargs, a) - } - ret := m.ctrl.Call(m, "FetchWorkerClusterWithResponse", varargs...) - ret0, _ := ret[0].(*api.FetchWorkerClusterResponse) - ret1, _ := ret[1].(error) - return ret0, ret1 -} - -// FetchWorkerClusterWithResponse indicates an expected call of FetchWorkerClusterWithResponse. -func (mr *MockFlamencoClientMockRecorder) FetchWorkerClusterWithResponse(arg0, arg1 interface{}, arg2 ...interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - varargs := append([]interface{}{arg0, arg1}, arg2...) - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "FetchWorkerClusterWithResponse", reflect.TypeOf((*MockFlamencoClient)(nil).FetchWorkerClusterWithResponse), varargs...) -} - -// FetchWorkerClustersWithResponse mocks base method. -func (m *MockFlamencoClient) FetchWorkerClustersWithResponse(arg0 context.Context, arg1 ...api.RequestEditorFn) (*api.FetchWorkerClustersResponse, error) { - m.ctrl.T.Helper() - varargs := []interface{}{arg0} - for _, a := range arg1 { - varargs = append(varargs, a) - } - ret := m.ctrl.Call(m, "FetchWorkerClustersWithResponse", varargs...) - ret0, _ := ret[0].(*api.FetchWorkerClustersResponse) - ret1, _ := ret[1].(error) - return ret0, ret1 -} - -// FetchWorkerClustersWithResponse indicates an expected call of FetchWorkerClustersWithResponse. -func (mr *MockFlamencoClientMockRecorder) FetchWorkerClustersWithResponse(arg0 interface{}, arg1 ...interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - varargs := append([]interface{}{arg0}, arg1...) - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "FetchWorkerClustersWithResponse", reflect.TypeOf((*MockFlamencoClient)(nil).FetchWorkerClustersWithResponse), varargs...) -} - // FetchWorkerSleepScheduleWithResponse mocks base method. func (m *MockFlamencoClient) FetchWorkerSleepScheduleWithResponse(arg0 context.Context, arg1 string, arg2 ...api.RequestEditorFn) (*api.FetchWorkerSleepScheduleResponse, error) { m.ctrl.T.Helper() @@ -456,6 +416,46 @@ func (mr *MockFlamencoClientMockRecorder) FetchWorkerSleepScheduleWithResponse(a return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "FetchWorkerSleepScheduleWithResponse", reflect.TypeOf((*MockFlamencoClient)(nil).FetchWorkerSleepScheduleWithResponse), varargs...) } +// FetchWorkerTagWithResponse mocks base method. +func (m *MockFlamencoClient) FetchWorkerTagWithResponse(arg0 context.Context, arg1 string, arg2 ...api.RequestEditorFn) (*api.FetchWorkerTagResponse, error) { + m.ctrl.T.Helper() + varargs := []interface{}{arg0, arg1} + for _, a := range arg2 { + varargs = append(varargs, a) + } + ret := m.ctrl.Call(m, "FetchWorkerTagWithResponse", varargs...) + ret0, _ := ret[0].(*api.FetchWorkerTagResponse) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// FetchWorkerTagWithResponse indicates an expected call of FetchWorkerTagWithResponse. +func (mr *MockFlamencoClientMockRecorder) FetchWorkerTagWithResponse(arg0, arg1 interface{}, arg2 ...interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + varargs := append([]interface{}{arg0, arg1}, arg2...) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "FetchWorkerTagWithResponse", reflect.TypeOf((*MockFlamencoClient)(nil).FetchWorkerTagWithResponse), varargs...) +} + +// FetchWorkerTagsWithResponse mocks base method. +func (m *MockFlamencoClient) FetchWorkerTagsWithResponse(arg0 context.Context, arg1 ...api.RequestEditorFn) (*api.FetchWorkerTagsResponse, error) { + m.ctrl.T.Helper() + varargs := []interface{}{arg0} + for _, a := range arg1 { + varargs = append(varargs, a) + } + ret := m.ctrl.Call(m, "FetchWorkerTagsWithResponse", varargs...) + ret0, _ := ret[0].(*api.FetchWorkerTagsResponse) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// FetchWorkerTagsWithResponse indicates an expected call of FetchWorkerTagsWithResponse. +func (mr *MockFlamencoClientMockRecorder) FetchWorkerTagsWithResponse(arg0 interface{}, arg1 ...interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + varargs := append([]interface{}{arg0}, arg1...) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "FetchWorkerTagsWithResponse", reflect.TypeOf((*MockFlamencoClient)(nil).FetchWorkerTagsWithResponse), varargs...) +} + // FetchWorkerWithResponse mocks base method. func (m *MockFlamencoClient) FetchWorkerWithResponse(arg0 context.Context, arg1 string, arg2 ...api.RequestEditorFn) (*api.FetchWorkerResponse, error) { m.ctrl.T.Helper() @@ -1016,46 +1016,6 @@ func (mr *MockFlamencoClientMockRecorder) SetTaskStatusWithResponse(arg0, arg1, return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetTaskStatusWithResponse", reflect.TypeOf((*MockFlamencoClient)(nil).SetTaskStatusWithResponse), varargs...) } -// SetWorkerClustersWithBodyWithResponse mocks base method. -func (m *MockFlamencoClient) SetWorkerClustersWithBodyWithResponse(arg0 context.Context, arg1, arg2 string, arg3 io.Reader, arg4 ...api.RequestEditorFn) (*api.SetWorkerClustersResponse, error) { - m.ctrl.T.Helper() - varargs := []interface{}{arg0, arg1, arg2, arg3} - for _, a := range arg4 { - varargs = append(varargs, a) - } - ret := m.ctrl.Call(m, "SetWorkerClustersWithBodyWithResponse", varargs...) - ret0, _ := ret[0].(*api.SetWorkerClustersResponse) - ret1, _ := ret[1].(error) - return ret0, ret1 -} - -// SetWorkerClustersWithBodyWithResponse indicates an expected call of SetWorkerClustersWithBodyWithResponse. -func (mr *MockFlamencoClientMockRecorder) SetWorkerClustersWithBodyWithResponse(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, "SetWorkerClustersWithBodyWithResponse", reflect.TypeOf((*MockFlamencoClient)(nil).SetWorkerClustersWithBodyWithResponse), varargs...) -} - -// SetWorkerClustersWithResponse mocks base method. -func (m *MockFlamencoClient) SetWorkerClustersWithResponse(arg0 context.Context, arg1 string, arg2 api.SetWorkerClustersJSONRequestBody, arg3 ...api.RequestEditorFn) (*api.SetWorkerClustersResponse, error) { - m.ctrl.T.Helper() - varargs := []interface{}{arg0, arg1, arg2} - for _, a := range arg3 { - varargs = append(varargs, a) - } - ret := m.ctrl.Call(m, "SetWorkerClustersWithResponse", varargs...) - ret0, _ := ret[0].(*api.SetWorkerClustersResponse) - ret1, _ := ret[1].(error) - return ret0, ret1 -} - -// SetWorkerClustersWithResponse indicates an expected call of SetWorkerClustersWithResponse. -func (mr *MockFlamencoClientMockRecorder) SetWorkerClustersWithResponse(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, "SetWorkerClustersWithResponse", reflect.TypeOf((*MockFlamencoClient)(nil).SetWorkerClustersWithResponse), varargs...) -} - // SetWorkerSleepScheduleWithBodyWithResponse mocks base method. func (m *MockFlamencoClient) SetWorkerSleepScheduleWithBodyWithResponse(arg0 context.Context, arg1, arg2 string, arg3 io.Reader, arg4 ...api.RequestEditorFn) (*api.SetWorkerSleepScheduleResponse, error) { m.ctrl.T.Helper() @@ -1096,6 +1056,46 @@ func (mr *MockFlamencoClientMockRecorder) SetWorkerSleepScheduleWithResponse(arg return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetWorkerSleepScheduleWithResponse", reflect.TypeOf((*MockFlamencoClient)(nil).SetWorkerSleepScheduleWithResponse), varargs...) } +// SetWorkerTagsWithBodyWithResponse mocks base method. +func (m *MockFlamencoClient) SetWorkerTagsWithBodyWithResponse(arg0 context.Context, arg1, arg2 string, arg3 io.Reader, arg4 ...api.RequestEditorFn) (*api.SetWorkerTagsResponse, error) { + m.ctrl.T.Helper() + varargs := []interface{}{arg0, arg1, arg2, arg3} + for _, a := range arg4 { + varargs = append(varargs, a) + } + ret := m.ctrl.Call(m, "SetWorkerTagsWithBodyWithResponse", varargs...) + ret0, _ := ret[0].(*api.SetWorkerTagsResponse) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// SetWorkerTagsWithBodyWithResponse indicates an expected call of SetWorkerTagsWithBodyWithResponse. +func (mr *MockFlamencoClientMockRecorder) SetWorkerTagsWithBodyWithResponse(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, "SetWorkerTagsWithBodyWithResponse", reflect.TypeOf((*MockFlamencoClient)(nil).SetWorkerTagsWithBodyWithResponse), varargs...) +} + +// SetWorkerTagsWithResponse mocks base method. +func (m *MockFlamencoClient) SetWorkerTagsWithResponse(arg0 context.Context, arg1 string, arg2 api.SetWorkerTagsJSONRequestBody, arg3 ...api.RequestEditorFn) (*api.SetWorkerTagsResponse, error) { + m.ctrl.T.Helper() + varargs := []interface{}{arg0, arg1, arg2} + for _, a := range arg3 { + varargs = append(varargs, a) + } + ret := m.ctrl.Call(m, "SetWorkerTagsWithResponse", varargs...) + ret0, _ := ret[0].(*api.SetWorkerTagsResponse) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// SetWorkerTagsWithResponse indicates an expected call of SetWorkerTagsWithResponse. +func (mr *MockFlamencoClientMockRecorder) SetWorkerTagsWithResponse(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, "SetWorkerTagsWithResponse", reflect.TypeOf((*MockFlamencoClient)(nil).SetWorkerTagsWithResponse), varargs...) +} + // ShamanCheckoutRequirementsWithBodyWithResponse mocks base method. func (m *MockFlamencoClient) ShamanCheckoutRequirementsWithBodyWithResponse(arg0 context.Context, arg1 string, arg2 io.Reader, arg3 ...api.RequestEditorFn) (*api.ShamanCheckoutRequirementsResponse, error) { m.ctrl.T.Helper() @@ -1416,44 +1416,44 @@ func (mr *MockFlamencoClientMockRecorder) TaskUpdateWithResponse(arg0, arg1, arg return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "TaskUpdateWithResponse", reflect.TypeOf((*MockFlamencoClient)(nil).TaskUpdateWithResponse), varargs...) } -// UpdateWorkerClusterWithBodyWithResponse mocks base method. -func (m *MockFlamencoClient) UpdateWorkerClusterWithBodyWithResponse(arg0 context.Context, arg1, arg2 string, arg3 io.Reader, arg4 ...api.RequestEditorFn) (*api.UpdateWorkerClusterResponse, error) { +// UpdateWorkerTagWithBodyWithResponse mocks base method. +func (m *MockFlamencoClient) UpdateWorkerTagWithBodyWithResponse(arg0 context.Context, arg1, arg2 string, arg3 io.Reader, arg4 ...api.RequestEditorFn) (*api.UpdateWorkerTagResponse, error) { m.ctrl.T.Helper() varargs := []interface{}{arg0, arg1, arg2, arg3} for _, a := range arg4 { varargs = append(varargs, a) } - ret := m.ctrl.Call(m, "UpdateWorkerClusterWithBodyWithResponse", varargs...) - ret0, _ := ret[0].(*api.UpdateWorkerClusterResponse) + ret := m.ctrl.Call(m, "UpdateWorkerTagWithBodyWithResponse", varargs...) + ret0, _ := ret[0].(*api.UpdateWorkerTagResponse) ret1, _ := ret[1].(error) return ret0, ret1 } -// UpdateWorkerClusterWithBodyWithResponse indicates an expected call of UpdateWorkerClusterWithBodyWithResponse. -func (mr *MockFlamencoClientMockRecorder) UpdateWorkerClusterWithBodyWithResponse(arg0, arg1, arg2, arg3 interface{}, arg4 ...interface{}) *gomock.Call { +// UpdateWorkerTagWithBodyWithResponse indicates an expected call of UpdateWorkerTagWithBodyWithResponse. +func (mr *MockFlamencoClientMockRecorder) UpdateWorkerTagWithBodyWithResponse(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, "UpdateWorkerClusterWithBodyWithResponse", reflect.TypeOf((*MockFlamencoClient)(nil).UpdateWorkerClusterWithBodyWithResponse), varargs...) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "UpdateWorkerTagWithBodyWithResponse", reflect.TypeOf((*MockFlamencoClient)(nil).UpdateWorkerTagWithBodyWithResponse), varargs...) } -// UpdateWorkerClusterWithResponse mocks base method. -func (m *MockFlamencoClient) UpdateWorkerClusterWithResponse(arg0 context.Context, arg1 string, arg2 api.UpdateWorkerClusterJSONRequestBody, arg3 ...api.RequestEditorFn) (*api.UpdateWorkerClusterResponse, error) { +// UpdateWorkerTagWithResponse mocks base method. +func (m *MockFlamencoClient) UpdateWorkerTagWithResponse(arg0 context.Context, arg1 string, arg2 api.UpdateWorkerTagJSONRequestBody, arg3 ...api.RequestEditorFn) (*api.UpdateWorkerTagResponse, error) { m.ctrl.T.Helper() varargs := []interface{}{arg0, arg1, arg2} for _, a := range arg3 { varargs = append(varargs, a) } - ret := m.ctrl.Call(m, "UpdateWorkerClusterWithResponse", varargs...) - ret0, _ := ret[0].(*api.UpdateWorkerClusterResponse) + ret := m.ctrl.Call(m, "UpdateWorkerTagWithResponse", varargs...) + ret0, _ := ret[0].(*api.UpdateWorkerTagResponse) ret1, _ := ret[1].(error) return ret0, ret1 } -// UpdateWorkerClusterWithResponse indicates an expected call of UpdateWorkerClusterWithResponse. -func (mr *MockFlamencoClientMockRecorder) UpdateWorkerClusterWithResponse(arg0, arg1, arg2 interface{}, arg3 ...interface{}) *gomock.Call { +// UpdateWorkerTagWithResponse indicates an expected call of UpdateWorkerTagWithResponse. +func (mr *MockFlamencoClientMockRecorder) UpdateWorkerTagWithResponse(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, "UpdateWorkerClusterWithResponse", reflect.TypeOf((*MockFlamencoClient)(nil).UpdateWorkerClusterWithResponse), varargs...) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "UpdateWorkerTagWithResponse", reflect.TypeOf((*MockFlamencoClient)(nil).UpdateWorkerTagWithResponse), varargs...) } // WorkerStateChangedWithBodyWithResponse mocks base method. diff --git a/pkg/api/flamenco-openapi.yaml b/pkg/api/flamenco-openapi.yaml index 5363fbf1..e796ed19 100644 --- a/pkg/api/flamenco-openapi.yaml +++ b/pkg/api/flamenco-openapi.yaml @@ -534,10 +534,10 @@ paths: schema: $ref: "#/components/schemas/Error" - /api/v3/worker-mgt/workers/{worker_id}/setclusters: - summary: Update the cluster membership of this Worker. + /api/v3/worker-mgt/workers/{worker_id}/settags: + summary: Update the tag membership of this Worker. post: - operationId: setWorkerClusters + operationId: setWorkerTags tags: [worker-mgt] parameters: - name: worker_id @@ -545,12 +545,12 @@ paths: required: true schema: { type: string, format: uuid } requestBody: - description: The list of cluster IDs this worker should be a member of. + description: The list of worker tag IDs this worker should be a member of. required: true content: application/json: schema: - $ref: "#/components/schemas/WorkerClusterChangeRequest" + $ref: "#/components/schemas/WorkerTagChangeRequest" responses: "204": description: Status change was accepted. @@ -611,84 +611,84 @@ paths: schema: $ref: "#/components/schemas/Error" - /api/v3/worker-mgt/clusters: - summary: Manage worker clusters. + /api/v3/worker-mgt/tags: + summary: Manage worker tags. get: - operationId: fetchWorkerClusters - summary: Get list of worker clusters. + operationId: fetchWorkerTags + summary: Get list of worker tags. tags: [worker-mgt] responses: "200": - description: Worker clusters. + description: Worker tags. content: application/json: - schema: { $ref: "#/components/schemas/WorkerClusterList" } + schema: { $ref: "#/components/schemas/WorkerTagList" } post: - operationId: createWorkerCluster - summary: Create a new worker cluster. + operationId: createWorkerTag + summary: Create a new worker tag. tags: [worker-mgt] requestBody: - description: The worker cluster. + description: The worker tag. required: true content: application/json: schema: - $ref: "#/components/schemas/WorkerCluster" + $ref: "#/components/schemas/WorkerTag" responses: "200": - description: The cluster was created. The created cluster is returned, so that the caller can know its UUID. + description: The tag was created. The created tag is returned, so that the caller can know its UUID. content: application/json: - schema: { $ref: "#/components/schemas/WorkerCluster" } + schema: { $ref: "#/components/schemas/WorkerTag" } default: description: Error message content: application/json: schema: { $ref: "#/components/schemas/Error" } - /api/v3/worker-mgt/cluster/{cluster_id}: - summary: Get, update, or delete a worker cluster. + /api/v3/worker-mgt/tag/{tag_id}: + summary: Get, update, or delete a worker tag. parameters: - - name: cluster_id + - name: tag_id in: path required: true schema: { type: string, format: uuid } get: - operationId: fetchWorkerCluster - summary: Get a single worker cluster. + operationId: fetchWorkerTag + summary: Get a single worker tag. tags: [worker-mgt] responses: "200": - description: The worker cluster. + description: The worker tag. content: application/json: - schema: { $ref: "#/components/schemas/WorkerCluster" } + schema: { $ref: "#/components/schemas/WorkerTag" } put: - operationId: updateWorkerCluster - summary: Update an existing worker cluster. + operationId: updateWorkerTag + summary: Update an existing worker tag. tags: [worker-mgt] requestBody: - description: The updated worker cluster. + description: The updated worker tag. required: true content: application/json: schema: - $ref: "#/components/schemas/WorkerCluster" + $ref: "#/components/schemas/WorkerTag" responses: "204": - description: The cluster update has been stored. + description: The tag update has been stored. default: description: Error message content: application/json: schema: { $ref: "#/components/schemas/Error" } delete: - operationId: deleteWorkerCluster - summary: Remove this worker cluster. This unassigns all workers from the cluster and removes it. + operationId: deleteWorkerTag + summary: Remove this worker tag. This unassigns all workers from the tag and removes it. tags: [worker-mgt] responses: "204": - description: The cluster has been removed. + description: The tag has been removed. default: description: Unexpected error. content: @@ -1758,12 +1758,12 @@ components: test/debug scripts easier, as they can use a static document on all platforms. "storage": { $ref: "#/components/schemas/JobStorageInfo" } - "worker_cluster": + "worker_tag": type: string format: uuid description: > - Worker Cluster that should execute this job. When a cluster ID is - given, only Workers in that cluster will be scheduled to work on it. + Worker tag that should execute this job. When a tag ID is + given, only Workers in that tag will be scheduled to work on it. If empty or ommitted, all workers can work on this job. required: [name, type, priority, submitter_platform] example: @@ -2364,10 +2364,10 @@ components: type: array items: { type: string } "task": { $ref: "#/components/schemas/WorkerTask" } - "clusters": + "tags": type: array - items: { $ref: "#/components/schemas/WorkerCluster" } - description: Clusters of which this Worker is a member. + items: { $ref: "#/components/schemas/WorkerTag" } + description: Tags of which this Worker is a member. required: - id - name @@ -2421,17 +2421,17 @@ components: start_time: "09:00" end_time: "18:00" - WorkerCluster: + WorkerTag: type: object description: > - Cluster of workers. A job can optionally specify which cluster it should - be limited to. Workers can be part of multiple clusters simultaneously. + Tag of workers. A job can optionally specify which tag it should + be limited to. Workers can be part of multiple tags simultaneously. properties: "id": type: string format: uuid description: > - UUID of the cluster. Can be ommitted when creating a new cluster, in + UUID of the tag. Can be ommitted when creating a new tag, in which case a random UUID will be assigned. "name": type: string @@ -2442,25 +2442,25 @@ components: name: GPU-EEVEE description: All workers that can do GPU rendering with EEVEE. - WorkerClusterList: + WorkerTagList: type: object properties: - "clusters": + "tags": type: array - items: { $ref: "#/components/schemas/WorkerCluster" } + items: { $ref: "#/components/schemas/WorkerTag" } - WorkerClusterChangeRequest: + WorkerTagChangeRequest: type: object - description: Request to change which clusters this Worker is assigned to. + description: Request to change which tags this Worker is assigned to. properties: - "cluster_ids": + "tag_ids": type: array items: type: string format: uuid - required: [cluster_ids] + required: [tag_ids] example: - "cluster_ids": ["4312d68c-ea6d-4566-9bf6-e9f09be48ceb"] + "tag_ids": ["4312d68c-ea6d-4566-9bf6-e9f09be48ceb"] securitySchemes: worker_auth: diff --git a/pkg/api/openapi_client.gen.go b/pkg/api/openapi_client.gen.go index e085dda2..5e707507 100644 --- a/pkg/api/openapi_client.gen.go +++ b/pkg/api/openapi_client.gen.go @@ -212,24 +212,24 @@ type ClientInterface interface { // GetVersion request GetVersion(ctx context.Context, reqEditors ...RequestEditorFn) (*http.Response, error) - // DeleteWorkerCluster request - DeleteWorkerCluster(ctx context.Context, clusterId string, reqEditors ...RequestEditorFn) (*http.Response, error) + // DeleteWorkerTag request + DeleteWorkerTag(ctx context.Context, tagId string, reqEditors ...RequestEditorFn) (*http.Response, error) - // FetchWorkerCluster request - FetchWorkerCluster(ctx context.Context, clusterId string, reqEditors ...RequestEditorFn) (*http.Response, error) + // FetchWorkerTag request + FetchWorkerTag(ctx context.Context, tagId string, reqEditors ...RequestEditorFn) (*http.Response, error) - // UpdateWorkerCluster request with any body - UpdateWorkerClusterWithBody(ctx context.Context, clusterId string, contentType string, body io.Reader, reqEditors ...RequestEditorFn) (*http.Response, error) + // UpdateWorkerTag request with any body + UpdateWorkerTagWithBody(ctx context.Context, tagId string, contentType string, body io.Reader, reqEditors ...RequestEditorFn) (*http.Response, error) - UpdateWorkerCluster(ctx context.Context, clusterId string, body UpdateWorkerClusterJSONRequestBody, reqEditors ...RequestEditorFn) (*http.Response, error) + UpdateWorkerTag(ctx context.Context, tagId string, body UpdateWorkerTagJSONRequestBody, reqEditors ...RequestEditorFn) (*http.Response, error) - // FetchWorkerClusters request - FetchWorkerClusters(ctx context.Context, reqEditors ...RequestEditorFn) (*http.Response, error) + // FetchWorkerTags request + FetchWorkerTags(ctx context.Context, reqEditors ...RequestEditorFn) (*http.Response, error) - // CreateWorkerCluster request with any body - CreateWorkerClusterWithBody(ctx context.Context, contentType string, body io.Reader, reqEditors ...RequestEditorFn) (*http.Response, error) + // CreateWorkerTag request with any body + CreateWorkerTagWithBody(ctx context.Context, contentType string, body io.Reader, reqEditors ...RequestEditorFn) (*http.Response, error) - CreateWorkerCluster(ctx context.Context, body CreateWorkerClusterJSONRequestBody, reqEditors ...RequestEditorFn) (*http.Response, error) + CreateWorkerTag(ctx context.Context, body CreateWorkerTagJSONRequestBody, reqEditors ...RequestEditorFn) (*http.Response, error) // FetchWorkers request FetchWorkers(ctx context.Context, reqEditors ...RequestEditorFn) (*http.Response, error) @@ -240,16 +240,16 @@ type ClientInterface interface { // FetchWorker request FetchWorker(ctx context.Context, workerId string, reqEditors ...RequestEditorFn) (*http.Response, error) - // SetWorkerClusters request with any body - SetWorkerClustersWithBody(ctx context.Context, workerId string, contentType string, body io.Reader, reqEditors ...RequestEditorFn) (*http.Response, error) - - SetWorkerClusters(ctx context.Context, workerId string, body SetWorkerClustersJSONRequestBody, 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) + // SetWorkerTags request with any body + SetWorkerTagsWithBody(ctx context.Context, workerId string, contentType string, body io.Reader, reqEditors ...RequestEditorFn) (*http.Response, error) + + SetWorkerTags(ctx context.Context, workerId string, body SetWorkerTagsJSONRequestBody, reqEditors ...RequestEditorFn) (*http.Response, error) + // FetchWorkerSleepSchedule request FetchWorkerSleepSchedule(ctx context.Context, workerId string, reqEditors ...RequestEditorFn) (*http.Response, error) @@ -822,8 +822,8 @@ func (c *Client) GetVersion(ctx context.Context, reqEditors ...RequestEditorFn) return c.Client.Do(req) } -func (c *Client) DeleteWorkerCluster(ctx context.Context, clusterId string, reqEditors ...RequestEditorFn) (*http.Response, error) { - req, err := NewDeleteWorkerClusterRequest(c.Server, clusterId) +func (c *Client) DeleteWorkerTag(ctx context.Context, tagId string, reqEditors ...RequestEditorFn) (*http.Response, error) { + req, err := NewDeleteWorkerTagRequest(c.Server, tagId) if err != nil { return nil, err } @@ -834,8 +834,8 @@ func (c *Client) DeleteWorkerCluster(ctx context.Context, clusterId string, reqE return c.Client.Do(req) } -func (c *Client) FetchWorkerCluster(ctx context.Context, clusterId string, reqEditors ...RequestEditorFn) (*http.Response, error) { - req, err := NewFetchWorkerClusterRequest(c.Server, clusterId) +func (c *Client) FetchWorkerTag(ctx context.Context, tagId string, reqEditors ...RequestEditorFn) (*http.Response, error) { + req, err := NewFetchWorkerTagRequest(c.Server, tagId) if err != nil { return nil, err } @@ -846,8 +846,8 @@ func (c *Client) FetchWorkerCluster(ctx context.Context, clusterId string, reqEd return c.Client.Do(req) } -func (c *Client) UpdateWorkerClusterWithBody(ctx context.Context, clusterId string, contentType string, body io.Reader, reqEditors ...RequestEditorFn) (*http.Response, error) { - req, err := NewUpdateWorkerClusterRequestWithBody(c.Server, clusterId, contentType, body) +func (c *Client) UpdateWorkerTagWithBody(ctx context.Context, tagId string, contentType string, body io.Reader, reqEditors ...RequestEditorFn) (*http.Response, error) { + req, err := NewUpdateWorkerTagRequestWithBody(c.Server, tagId, contentType, body) if err != nil { return nil, err } @@ -858,8 +858,8 @@ func (c *Client) UpdateWorkerClusterWithBody(ctx context.Context, clusterId stri return c.Client.Do(req) } -func (c *Client) UpdateWorkerCluster(ctx context.Context, clusterId string, body UpdateWorkerClusterJSONRequestBody, reqEditors ...RequestEditorFn) (*http.Response, error) { - req, err := NewUpdateWorkerClusterRequest(c.Server, clusterId, body) +func (c *Client) UpdateWorkerTag(ctx context.Context, tagId string, body UpdateWorkerTagJSONRequestBody, reqEditors ...RequestEditorFn) (*http.Response, error) { + req, err := NewUpdateWorkerTagRequest(c.Server, tagId, body) if err != nil { return nil, err } @@ -870,8 +870,8 @@ func (c *Client) UpdateWorkerCluster(ctx context.Context, clusterId string, body return c.Client.Do(req) } -func (c *Client) FetchWorkerClusters(ctx context.Context, reqEditors ...RequestEditorFn) (*http.Response, error) { - req, err := NewFetchWorkerClustersRequest(c.Server) +func (c *Client) FetchWorkerTags(ctx context.Context, reqEditors ...RequestEditorFn) (*http.Response, error) { + req, err := NewFetchWorkerTagsRequest(c.Server) if err != nil { return nil, err } @@ -882,8 +882,8 @@ func (c *Client) FetchWorkerClusters(ctx context.Context, reqEditors ...RequestE return c.Client.Do(req) } -func (c *Client) CreateWorkerClusterWithBody(ctx context.Context, contentType string, body io.Reader, reqEditors ...RequestEditorFn) (*http.Response, error) { - req, err := NewCreateWorkerClusterRequestWithBody(c.Server, contentType, body) +func (c *Client) CreateWorkerTagWithBody(ctx context.Context, contentType string, body io.Reader, reqEditors ...RequestEditorFn) (*http.Response, error) { + req, err := NewCreateWorkerTagRequestWithBody(c.Server, contentType, body) if err != nil { return nil, err } @@ -894,8 +894,8 @@ func (c *Client) CreateWorkerClusterWithBody(ctx context.Context, contentType st return c.Client.Do(req) } -func (c *Client) CreateWorkerCluster(ctx context.Context, body CreateWorkerClusterJSONRequestBody, reqEditors ...RequestEditorFn) (*http.Response, error) { - req, err := NewCreateWorkerClusterRequest(c.Server, body) +func (c *Client) CreateWorkerTag(ctx context.Context, body CreateWorkerTagJSONRequestBody, reqEditors ...RequestEditorFn) (*http.Response, error) { + req, err := NewCreateWorkerTagRequest(c.Server, body) if err != nil { return nil, err } @@ -942,30 +942,6 @@ func (c *Client) FetchWorker(ctx context.Context, workerId string, reqEditors .. return c.Client.Do(req) } -func (c *Client) SetWorkerClustersWithBody(ctx context.Context, workerId string, contentType string, body io.Reader, reqEditors ...RequestEditorFn) (*http.Response, error) { - req, err := NewSetWorkerClustersRequestWithBody(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) SetWorkerClusters(ctx context.Context, workerId string, body SetWorkerClustersJSONRequestBody, reqEditors ...RequestEditorFn) (*http.Response, error) { - req, err := NewSetWorkerClustersRequest(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) 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 { @@ -990,6 +966,30 @@ func (c *Client) RequestWorkerStatusChange(ctx context.Context, workerId string, return c.Client.Do(req) } +func (c *Client) SetWorkerTagsWithBody(ctx context.Context, workerId string, contentType string, body io.Reader, reqEditors ...RequestEditorFn) (*http.Response, error) { + req, err := NewSetWorkerTagsRequestWithBody(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) SetWorkerTags(ctx context.Context, workerId string, body SetWorkerTagsJSONRequestBody, reqEditors ...RequestEditorFn) (*http.Response, error) { + req, err := NewSetWorkerTagsRequest(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) FetchWorkerSleepSchedule(ctx context.Context, workerId string, reqEditors ...RequestEditorFn) (*http.Response, error) { req, err := NewFetchWorkerSleepScheduleRequest(c.Server, workerId) if err != nil { @@ -2380,13 +2380,13 @@ func NewGetVersionRequest(server string) (*http.Request, error) { return req, nil } -// NewDeleteWorkerClusterRequest generates requests for DeleteWorkerCluster -func NewDeleteWorkerClusterRequest(server string, clusterId string) (*http.Request, error) { +// NewDeleteWorkerTagRequest generates requests for DeleteWorkerTag +func NewDeleteWorkerTagRequest(server string, tagId string) (*http.Request, error) { var err error var pathParam0 string - pathParam0, err = runtime.StyleParamWithLocation("simple", false, "cluster_id", runtime.ParamLocationPath, clusterId) + pathParam0, err = runtime.StyleParamWithLocation("simple", false, "tag_id", runtime.ParamLocationPath, tagId) if err != nil { return nil, err } @@ -2396,7 +2396,7 @@ func NewDeleteWorkerClusterRequest(server string, clusterId string) (*http.Reque return nil, err } - operationPath := fmt.Sprintf("/api/v3/worker-mgt/cluster/%s", pathParam0) + operationPath := fmt.Sprintf("/api/v3/worker-mgt/tag/%s", pathParam0) if operationPath[0] == '/' { operationPath = "." + operationPath } @@ -2414,13 +2414,13 @@ func NewDeleteWorkerClusterRequest(server string, clusterId string) (*http.Reque return req, nil } -// NewFetchWorkerClusterRequest generates requests for FetchWorkerCluster -func NewFetchWorkerClusterRequest(server string, clusterId string) (*http.Request, error) { +// NewFetchWorkerTagRequest generates requests for FetchWorkerTag +func NewFetchWorkerTagRequest(server string, tagId string) (*http.Request, error) { var err error var pathParam0 string - pathParam0, err = runtime.StyleParamWithLocation("simple", false, "cluster_id", runtime.ParamLocationPath, clusterId) + pathParam0, err = runtime.StyleParamWithLocation("simple", false, "tag_id", runtime.ParamLocationPath, tagId) if err != nil { return nil, err } @@ -2430,7 +2430,7 @@ func NewFetchWorkerClusterRequest(server string, clusterId string) (*http.Reques return nil, err } - operationPath := fmt.Sprintf("/api/v3/worker-mgt/cluster/%s", pathParam0) + operationPath := fmt.Sprintf("/api/v3/worker-mgt/tag/%s", pathParam0) if operationPath[0] == '/' { operationPath = "." + operationPath } @@ -2448,24 +2448,24 @@ func NewFetchWorkerClusterRequest(server string, clusterId string) (*http.Reques return req, nil } -// NewUpdateWorkerClusterRequest calls the generic UpdateWorkerCluster builder with application/json body -func NewUpdateWorkerClusterRequest(server string, clusterId string, body UpdateWorkerClusterJSONRequestBody) (*http.Request, error) { +// NewUpdateWorkerTagRequest calls the generic UpdateWorkerTag builder with application/json body +func NewUpdateWorkerTagRequest(server string, tagId string, body UpdateWorkerTagJSONRequestBody) (*http.Request, error) { var bodyReader io.Reader buf, err := json.Marshal(body) if err != nil { return nil, err } bodyReader = bytes.NewReader(buf) - return NewUpdateWorkerClusterRequestWithBody(server, clusterId, "application/json", bodyReader) + return NewUpdateWorkerTagRequestWithBody(server, tagId, "application/json", bodyReader) } -// NewUpdateWorkerClusterRequestWithBody generates requests for UpdateWorkerCluster with any type of body -func NewUpdateWorkerClusterRequestWithBody(server string, clusterId string, contentType string, body io.Reader) (*http.Request, error) { +// NewUpdateWorkerTagRequestWithBody generates requests for UpdateWorkerTag with any type of body +func NewUpdateWorkerTagRequestWithBody(server string, tagId string, contentType string, body io.Reader) (*http.Request, error) { var err error var pathParam0 string - pathParam0, err = runtime.StyleParamWithLocation("simple", false, "cluster_id", runtime.ParamLocationPath, clusterId) + pathParam0, err = runtime.StyleParamWithLocation("simple", false, "tag_id", runtime.ParamLocationPath, tagId) if err != nil { return nil, err } @@ -2475,7 +2475,7 @@ func NewUpdateWorkerClusterRequestWithBody(server string, clusterId string, cont return nil, err } - operationPath := fmt.Sprintf("/api/v3/worker-mgt/cluster/%s", pathParam0) + operationPath := fmt.Sprintf("/api/v3/worker-mgt/tag/%s", pathParam0) if operationPath[0] == '/' { operationPath = "." + operationPath } @@ -2495,8 +2495,8 @@ func NewUpdateWorkerClusterRequestWithBody(server string, clusterId string, cont return req, nil } -// NewFetchWorkerClustersRequest generates requests for FetchWorkerClusters -func NewFetchWorkerClustersRequest(server string) (*http.Request, error) { +// NewFetchWorkerTagsRequest generates requests for FetchWorkerTags +func NewFetchWorkerTagsRequest(server string) (*http.Request, error) { var err error serverURL, err := url.Parse(server) @@ -2504,7 +2504,7 @@ func NewFetchWorkerClustersRequest(server string) (*http.Request, error) { return nil, err } - operationPath := fmt.Sprintf("/api/v3/worker-mgt/clusters") + operationPath := fmt.Sprintf("/api/v3/worker-mgt/tags") if operationPath[0] == '/' { operationPath = "." + operationPath } @@ -2522,19 +2522,19 @@ func NewFetchWorkerClustersRequest(server string) (*http.Request, error) { return req, nil } -// NewCreateWorkerClusterRequest calls the generic CreateWorkerCluster builder with application/json body -func NewCreateWorkerClusterRequest(server string, body CreateWorkerClusterJSONRequestBody) (*http.Request, error) { +// NewCreateWorkerTagRequest calls the generic CreateWorkerTag builder with application/json body +func NewCreateWorkerTagRequest(server string, body CreateWorkerTagJSONRequestBody) (*http.Request, error) { var bodyReader io.Reader buf, err := json.Marshal(body) if err != nil { return nil, err } bodyReader = bytes.NewReader(buf) - return NewCreateWorkerClusterRequestWithBody(server, "application/json", bodyReader) + return NewCreateWorkerTagRequestWithBody(server, "application/json", bodyReader) } -// NewCreateWorkerClusterRequestWithBody generates requests for CreateWorkerCluster with any type of body -func NewCreateWorkerClusterRequestWithBody(server string, contentType string, body io.Reader) (*http.Request, error) { +// NewCreateWorkerTagRequestWithBody generates requests for CreateWorkerTag with any type of body +func NewCreateWorkerTagRequestWithBody(server string, contentType string, body io.Reader) (*http.Request, error) { var err error serverURL, err := url.Parse(server) @@ -2542,7 +2542,7 @@ func NewCreateWorkerClusterRequestWithBody(server string, contentType string, bo return nil, err } - operationPath := fmt.Sprintf("/api/v3/worker-mgt/clusters") + operationPath := fmt.Sprintf("/api/v3/worker-mgt/tags") if operationPath[0] == '/' { operationPath = "." + operationPath } @@ -2657,53 +2657,6 @@ func NewFetchWorkerRequest(server string, workerId string) (*http.Request, error return req, nil } -// NewSetWorkerClustersRequest calls the generic SetWorkerClusters builder with application/json body -func NewSetWorkerClustersRequest(server string, workerId string, body SetWorkerClustersJSONRequestBody) (*http.Request, error) { - var bodyReader io.Reader - buf, err := json.Marshal(body) - if err != nil { - return nil, err - } - bodyReader = bytes.NewReader(buf) - return NewSetWorkerClustersRequestWithBody(server, workerId, "application/json", bodyReader) -} - -// NewSetWorkerClustersRequestWithBody generates requests for SetWorkerClusters with any type of body -func NewSetWorkerClustersRequestWithBody(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/v3/worker-mgt/workers/%s/setclusters", 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 -} - // 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 @@ -2751,6 +2704,53 @@ func NewRequestWorkerStatusChangeRequestWithBody(server string, workerId string, return req, nil } +// NewSetWorkerTagsRequest calls the generic SetWorkerTags builder with application/json body +func NewSetWorkerTagsRequest(server string, workerId string, body SetWorkerTagsJSONRequestBody) (*http.Request, error) { + var bodyReader io.Reader + buf, err := json.Marshal(body) + if err != nil { + return nil, err + } + bodyReader = bytes.NewReader(buf) + return NewSetWorkerTagsRequestWithBody(server, workerId, "application/json", bodyReader) +} + +// NewSetWorkerTagsRequestWithBody generates requests for SetWorkerTags with any type of body +func NewSetWorkerTagsRequestWithBody(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/v3/worker-mgt/workers/%s/settags", 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 +} + // NewFetchWorkerSleepScheduleRequest generates requests for FetchWorkerSleepSchedule func NewFetchWorkerSleepScheduleRequest(server string, workerId string) (*http.Request, error) { var err error @@ -3313,24 +3313,24 @@ type ClientWithResponsesInterface interface { // GetVersion request GetVersionWithResponse(ctx context.Context, reqEditors ...RequestEditorFn) (*GetVersionResponse, error) - // DeleteWorkerCluster request - DeleteWorkerClusterWithResponse(ctx context.Context, clusterId string, reqEditors ...RequestEditorFn) (*DeleteWorkerClusterResponse, error) + // DeleteWorkerTag request + DeleteWorkerTagWithResponse(ctx context.Context, tagId string, reqEditors ...RequestEditorFn) (*DeleteWorkerTagResponse, error) - // FetchWorkerCluster request - FetchWorkerClusterWithResponse(ctx context.Context, clusterId string, reqEditors ...RequestEditorFn) (*FetchWorkerClusterResponse, error) + // FetchWorkerTag request + FetchWorkerTagWithResponse(ctx context.Context, tagId string, reqEditors ...RequestEditorFn) (*FetchWorkerTagResponse, error) - // UpdateWorkerCluster request with any body - UpdateWorkerClusterWithBodyWithResponse(ctx context.Context, clusterId string, contentType string, body io.Reader, reqEditors ...RequestEditorFn) (*UpdateWorkerClusterResponse, error) + // UpdateWorkerTag request with any body + UpdateWorkerTagWithBodyWithResponse(ctx context.Context, tagId string, contentType string, body io.Reader, reqEditors ...RequestEditorFn) (*UpdateWorkerTagResponse, error) - UpdateWorkerClusterWithResponse(ctx context.Context, clusterId string, body UpdateWorkerClusterJSONRequestBody, reqEditors ...RequestEditorFn) (*UpdateWorkerClusterResponse, error) + UpdateWorkerTagWithResponse(ctx context.Context, tagId string, body UpdateWorkerTagJSONRequestBody, reqEditors ...RequestEditorFn) (*UpdateWorkerTagResponse, error) - // FetchWorkerClusters request - FetchWorkerClustersWithResponse(ctx context.Context, reqEditors ...RequestEditorFn) (*FetchWorkerClustersResponse, error) + // FetchWorkerTags request + FetchWorkerTagsWithResponse(ctx context.Context, reqEditors ...RequestEditorFn) (*FetchWorkerTagsResponse, error) - // CreateWorkerCluster request with any body - CreateWorkerClusterWithBodyWithResponse(ctx context.Context, contentType string, body io.Reader, reqEditors ...RequestEditorFn) (*CreateWorkerClusterResponse, error) + // CreateWorkerTag request with any body + CreateWorkerTagWithBodyWithResponse(ctx context.Context, contentType string, body io.Reader, reqEditors ...RequestEditorFn) (*CreateWorkerTagResponse, error) - CreateWorkerClusterWithResponse(ctx context.Context, body CreateWorkerClusterJSONRequestBody, reqEditors ...RequestEditorFn) (*CreateWorkerClusterResponse, error) + CreateWorkerTagWithResponse(ctx context.Context, body CreateWorkerTagJSONRequestBody, reqEditors ...RequestEditorFn) (*CreateWorkerTagResponse, error) // FetchWorkers request FetchWorkersWithResponse(ctx context.Context, reqEditors ...RequestEditorFn) (*FetchWorkersResponse, error) @@ -3341,16 +3341,16 @@ type ClientWithResponsesInterface interface { // FetchWorker request FetchWorkerWithResponse(ctx context.Context, workerId string, reqEditors ...RequestEditorFn) (*FetchWorkerResponse, error) - // SetWorkerClusters request with any body - SetWorkerClustersWithBodyWithResponse(ctx context.Context, workerId string, contentType string, body io.Reader, reqEditors ...RequestEditorFn) (*SetWorkerClustersResponse, error) - - SetWorkerClustersWithResponse(ctx context.Context, workerId string, body SetWorkerClustersJSONRequestBody, reqEditors ...RequestEditorFn) (*SetWorkerClustersResponse, 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) + // SetWorkerTags request with any body + SetWorkerTagsWithBodyWithResponse(ctx context.Context, workerId string, contentType string, body io.Reader, reqEditors ...RequestEditorFn) (*SetWorkerTagsResponse, error) + + SetWorkerTagsWithResponse(ctx context.Context, workerId string, body SetWorkerTagsJSONRequestBody, reqEditors ...RequestEditorFn) (*SetWorkerTagsResponse, error) + // FetchWorkerSleepSchedule request FetchWorkerSleepScheduleWithResponse(ctx context.Context, workerId string, reqEditors ...RequestEditorFn) (*FetchWorkerSleepScheduleResponse, error) @@ -4118,14 +4118,14 @@ func (r GetVersionResponse) StatusCode() int { return 0 } -type DeleteWorkerClusterResponse struct { +type DeleteWorkerTagResponse struct { Body []byte HTTPResponse *http.Response JSONDefault *Error } // Status returns HTTPResponse.Status -func (r DeleteWorkerClusterResponse) Status() string { +func (r DeleteWorkerTagResponse) Status() string { if r.HTTPResponse != nil { return r.HTTPResponse.Status } @@ -4133,21 +4133,21 @@ func (r DeleteWorkerClusterResponse) Status() string { } // StatusCode returns HTTPResponse.StatusCode -func (r DeleteWorkerClusterResponse) StatusCode() int { +func (r DeleteWorkerTagResponse) StatusCode() int { if r.HTTPResponse != nil { return r.HTTPResponse.StatusCode } return 0 } -type FetchWorkerClusterResponse struct { +type FetchWorkerTagResponse struct { Body []byte HTTPResponse *http.Response - JSON200 *WorkerCluster + JSON200 *WorkerTag } // Status returns HTTPResponse.Status -func (r FetchWorkerClusterResponse) Status() string { +func (r FetchWorkerTagResponse) Status() string { if r.HTTPResponse != nil { return r.HTTPResponse.Status } @@ -4155,21 +4155,21 @@ func (r FetchWorkerClusterResponse) Status() string { } // StatusCode returns HTTPResponse.StatusCode -func (r FetchWorkerClusterResponse) StatusCode() int { +func (r FetchWorkerTagResponse) StatusCode() int { if r.HTTPResponse != nil { return r.HTTPResponse.StatusCode } return 0 } -type UpdateWorkerClusterResponse struct { +type UpdateWorkerTagResponse struct { Body []byte HTTPResponse *http.Response JSONDefault *Error } // Status returns HTTPResponse.Status -func (r UpdateWorkerClusterResponse) Status() string { +func (r UpdateWorkerTagResponse) Status() string { if r.HTTPResponse != nil { return r.HTTPResponse.Status } @@ -4177,21 +4177,21 @@ func (r UpdateWorkerClusterResponse) Status() string { } // StatusCode returns HTTPResponse.StatusCode -func (r UpdateWorkerClusterResponse) StatusCode() int { +func (r UpdateWorkerTagResponse) StatusCode() int { if r.HTTPResponse != nil { return r.HTTPResponse.StatusCode } return 0 } -type FetchWorkerClustersResponse struct { +type FetchWorkerTagsResponse struct { Body []byte HTTPResponse *http.Response - JSON200 *WorkerClusterList + JSON200 *WorkerTagList } // Status returns HTTPResponse.Status -func (r FetchWorkerClustersResponse) Status() string { +func (r FetchWorkerTagsResponse) Status() string { if r.HTTPResponse != nil { return r.HTTPResponse.Status } @@ -4199,22 +4199,22 @@ func (r FetchWorkerClustersResponse) Status() string { } // StatusCode returns HTTPResponse.StatusCode -func (r FetchWorkerClustersResponse) StatusCode() int { +func (r FetchWorkerTagsResponse) StatusCode() int { if r.HTTPResponse != nil { return r.HTTPResponse.StatusCode } return 0 } -type CreateWorkerClusterResponse struct { +type CreateWorkerTagResponse struct { Body []byte HTTPResponse *http.Response - JSON200 *WorkerCluster + JSON200 *WorkerTag JSONDefault *Error } // Status returns HTTPResponse.Status -func (r CreateWorkerClusterResponse) Status() string { +func (r CreateWorkerTagResponse) Status() string { if r.HTTPResponse != nil { return r.HTTPResponse.Status } @@ -4222,7 +4222,7 @@ func (r CreateWorkerClusterResponse) Status() string { } // StatusCode returns HTTPResponse.StatusCode -func (r CreateWorkerClusterResponse) StatusCode() int { +func (r CreateWorkerTagResponse) StatusCode() int { if r.HTTPResponse != nil { return r.HTTPResponse.StatusCode } @@ -4295,28 +4295,6 @@ func (r FetchWorkerResponse) StatusCode() int { return 0 } -type SetWorkerClustersResponse struct { - Body []byte - HTTPResponse *http.Response - JSONDefault *Error -} - -// Status returns HTTPResponse.Status -func (r SetWorkerClustersResponse) Status() string { - if r.HTTPResponse != nil { - return r.HTTPResponse.Status - } - return http.StatusText(0) -} - -// StatusCode returns HTTPResponse.StatusCode -func (r SetWorkerClustersResponse) StatusCode() int { - if r.HTTPResponse != nil { - return r.HTTPResponse.StatusCode - } - return 0 -} - type RequestWorkerStatusChangeResponse struct { Body []byte HTTPResponse *http.Response @@ -4339,6 +4317,28 @@ func (r RequestWorkerStatusChangeResponse) StatusCode() int { return 0 } +type SetWorkerTagsResponse struct { + Body []byte + HTTPResponse *http.Response + JSONDefault *Error +} + +// Status returns HTTPResponse.Status +func (r SetWorkerTagsResponse) Status() string { + if r.HTTPResponse != nil { + return r.HTTPResponse.Status + } + return http.StatusText(0) +} + +// StatusCode returns HTTPResponse.StatusCode +func (r SetWorkerTagsResponse) StatusCode() int { + if r.HTTPResponse != nil { + return r.HTTPResponse.StatusCode + } + return 0 +} + type FetchWorkerSleepScheduleResponse struct { Body []byte HTTPResponse *http.Response @@ -4976,65 +4976,65 @@ func (c *ClientWithResponses) GetVersionWithResponse(ctx context.Context, reqEdi return ParseGetVersionResponse(rsp) } -// DeleteWorkerClusterWithResponse request returning *DeleteWorkerClusterResponse -func (c *ClientWithResponses) DeleteWorkerClusterWithResponse(ctx context.Context, clusterId string, reqEditors ...RequestEditorFn) (*DeleteWorkerClusterResponse, error) { - rsp, err := c.DeleteWorkerCluster(ctx, clusterId, reqEditors...) +// DeleteWorkerTagWithResponse request returning *DeleteWorkerTagResponse +func (c *ClientWithResponses) DeleteWorkerTagWithResponse(ctx context.Context, tagId string, reqEditors ...RequestEditorFn) (*DeleteWorkerTagResponse, error) { + rsp, err := c.DeleteWorkerTag(ctx, tagId, reqEditors...) if err != nil { return nil, err } - return ParseDeleteWorkerClusterResponse(rsp) + return ParseDeleteWorkerTagResponse(rsp) } -// FetchWorkerClusterWithResponse request returning *FetchWorkerClusterResponse -func (c *ClientWithResponses) FetchWorkerClusterWithResponse(ctx context.Context, clusterId string, reqEditors ...RequestEditorFn) (*FetchWorkerClusterResponse, error) { - rsp, err := c.FetchWorkerCluster(ctx, clusterId, reqEditors...) +// FetchWorkerTagWithResponse request returning *FetchWorkerTagResponse +func (c *ClientWithResponses) FetchWorkerTagWithResponse(ctx context.Context, tagId string, reqEditors ...RequestEditorFn) (*FetchWorkerTagResponse, error) { + rsp, err := c.FetchWorkerTag(ctx, tagId, reqEditors...) if err != nil { return nil, err } - return ParseFetchWorkerClusterResponse(rsp) + return ParseFetchWorkerTagResponse(rsp) } -// UpdateWorkerClusterWithBodyWithResponse request with arbitrary body returning *UpdateWorkerClusterResponse -func (c *ClientWithResponses) UpdateWorkerClusterWithBodyWithResponse(ctx context.Context, clusterId string, contentType string, body io.Reader, reqEditors ...RequestEditorFn) (*UpdateWorkerClusterResponse, error) { - rsp, err := c.UpdateWorkerClusterWithBody(ctx, clusterId, contentType, body, reqEditors...) +// UpdateWorkerTagWithBodyWithResponse request with arbitrary body returning *UpdateWorkerTagResponse +func (c *ClientWithResponses) UpdateWorkerTagWithBodyWithResponse(ctx context.Context, tagId string, contentType string, body io.Reader, reqEditors ...RequestEditorFn) (*UpdateWorkerTagResponse, error) { + rsp, err := c.UpdateWorkerTagWithBody(ctx, tagId, contentType, body, reqEditors...) if err != nil { return nil, err } - return ParseUpdateWorkerClusterResponse(rsp) + return ParseUpdateWorkerTagResponse(rsp) } -func (c *ClientWithResponses) UpdateWorkerClusterWithResponse(ctx context.Context, clusterId string, body UpdateWorkerClusterJSONRequestBody, reqEditors ...RequestEditorFn) (*UpdateWorkerClusterResponse, error) { - rsp, err := c.UpdateWorkerCluster(ctx, clusterId, body, reqEditors...) +func (c *ClientWithResponses) UpdateWorkerTagWithResponse(ctx context.Context, tagId string, body UpdateWorkerTagJSONRequestBody, reqEditors ...RequestEditorFn) (*UpdateWorkerTagResponse, error) { + rsp, err := c.UpdateWorkerTag(ctx, tagId, body, reqEditors...) if err != nil { return nil, err } - return ParseUpdateWorkerClusterResponse(rsp) + return ParseUpdateWorkerTagResponse(rsp) } -// FetchWorkerClustersWithResponse request returning *FetchWorkerClustersResponse -func (c *ClientWithResponses) FetchWorkerClustersWithResponse(ctx context.Context, reqEditors ...RequestEditorFn) (*FetchWorkerClustersResponse, error) { - rsp, err := c.FetchWorkerClusters(ctx, reqEditors...) +// FetchWorkerTagsWithResponse request returning *FetchWorkerTagsResponse +func (c *ClientWithResponses) FetchWorkerTagsWithResponse(ctx context.Context, reqEditors ...RequestEditorFn) (*FetchWorkerTagsResponse, error) { + rsp, err := c.FetchWorkerTags(ctx, reqEditors...) if err != nil { return nil, err } - return ParseFetchWorkerClustersResponse(rsp) + return ParseFetchWorkerTagsResponse(rsp) } -// CreateWorkerClusterWithBodyWithResponse request with arbitrary body returning *CreateWorkerClusterResponse -func (c *ClientWithResponses) CreateWorkerClusterWithBodyWithResponse(ctx context.Context, contentType string, body io.Reader, reqEditors ...RequestEditorFn) (*CreateWorkerClusterResponse, error) { - rsp, err := c.CreateWorkerClusterWithBody(ctx, contentType, body, reqEditors...) +// CreateWorkerTagWithBodyWithResponse request with arbitrary body returning *CreateWorkerTagResponse +func (c *ClientWithResponses) CreateWorkerTagWithBodyWithResponse(ctx context.Context, contentType string, body io.Reader, reqEditors ...RequestEditorFn) (*CreateWorkerTagResponse, error) { + rsp, err := c.CreateWorkerTagWithBody(ctx, contentType, body, reqEditors...) if err != nil { return nil, err } - return ParseCreateWorkerClusterResponse(rsp) + return ParseCreateWorkerTagResponse(rsp) } -func (c *ClientWithResponses) CreateWorkerClusterWithResponse(ctx context.Context, body CreateWorkerClusterJSONRequestBody, reqEditors ...RequestEditorFn) (*CreateWorkerClusterResponse, error) { - rsp, err := c.CreateWorkerCluster(ctx, body, reqEditors...) +func (c *ClientWithResponses) CreateWorkerTagWithResponse(ctx context.Context, body CreateWorkerTagJSONRequestBody, reqEditors ...RequestEditorFn) (*CreateWorkerTagResponse, error) { + rsp, err := c.CreateWorkerTag(ctx, body, reqEditors...) if err != nil { return nil, err } - return ParseCreateWorkerClusterResponse(rsp) + return ParseCreateWorkerTagResponse(rsp) } // FetchWorkersWithResponse request returning *FetchWorkersResponse @@ -5064,23 +5064,6 @@ func (c *ClientWithResponses) FetchWorkerWithResponse(ctx context.Context, worke return ParseFetchWorkerResponse(rsp) } -// SetWorkerClustersWithBodyWithResponse request with arbitrary body returning *SetWorkerClustersResponse -func (c *ClientWithResponses) SetWorkerClustersWithBodyWithResponse(ctx context.Context, workerId string, contentType string, body io.Reader, reqEditors ...RequestEditorFn) (*SetWorkerClustersResponse, error) { - rsp, err := c.SetWorkerClustersWithBody(ctx, workerId, contentType, body, reqEditors...) - if err != nil { - return nil, err - } - return ParseSetWorkerClustersResponse(rsp) -} - -func (c *ClientWithResponses) SetWorkerClustersWithResponse(ctx context.Context, workerId string, body SetWorkerClustersJSONRequestBody, reqEditors ...RequestEditorFn) (*SetWorkerClustersResponse, error) { - rsp, err := c.SetWorkerClusters(ctx, workerId, body, reqEditors...) - if err != nil { - return nil, err - } - return ParseSetWorkerClustersResponse(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...) @@ -5098,6 +5081,23 @@ func (c *ClientWithResponses) RequestWorkerStatusChangeWithResponse(ctx context. return ParseRequestWorkerStatusChangeResponse(rsp) } +// SetWorkerTagsWithBodyWithResponse request with arbitrary body returning *SetWorkerTagsResponse +func (c *ClientWithResponses) SetWorkerTagsWithBodyWithResponse(ctx context.Context, workerId string, contentType string, body io.Reader, reqEditors ...RequestEditorFn) (*SetWorkerTagsResponse, error) { + rsp, err := c.SetWorkerTagsWithBody(ctx, workerId, contentType, body, reqEditors...) + if err != nil { + return nil, err + } + return ParseSetWorkerTagsResponse(rsp) +} + +func (c *ClientWithResponses) SetWorkerTagsWithResponse(ctx context.Context, workerId string, body SetWorkerTagsJSONRequestBody, reqEditors ...RequestEditorFn) (*SetWorkerTagsResponse, error) { + rsp, err := c.SetWorkerTags(ctx, workerId, body, reqEditors...) + if err != nil { + return nil, err + } + return ParseSetWorkerTagsResponse(rsp) +} + // FetchWorkerSleepScheduleWithResponse request returning *FetchWorkerSleepScheduleResponse func (c *ClientWithResponses) FetchWorkerSleepScheduleWithResponse(ctx context.Context, workerId string, reqEditors ...RequestEditorFn) (*FetchWorkerSleepScheduleResponse, error) { rsp, err := c.FetchWorkerSleepSchedule(ctx, workerId, reqEditors...) @@ -6190,15 +6190,15 @@ func ParseGetVersionResponse(rsp *http.Response) (*GetVersionResponse, error) { return response, nil } -// ParseDeleteWorkerClusterResponse parses an HTTP response from a DeleteWorkerClusterWithResponse call -func ParseDeleteWorkerClusterResponse(rsp *http.Response) (*DeleteWorkerClusterResponse, error) { +// ParseDeleteWorkerTagResponse parses an HTTP response from a DeleteWorkerTagWithResponse call +func ParseDeleteWorkerTagResponse(rsp *http.Response) (*DeleteWorkerTagResponse, error) { bodyBytes, err := ioutil.ReadAll(rsp.Body) defer func() { _ = rsp.Body.Close() }() if err != nil { return nil, err } - response := &DeleteWorkerClusterResponse{ + response := &DeleteWorkerTagResponse{ Body: bodyBytes, HTTPResponse: rsp, } @@ -6216,22 +6216,22 @@ func ParseDeleteWorkerClusterResponse(rsp *http.Response) (*DeleteWorkerClusterR return response, nil } -// ParseFetchWorkerClusterResponse parses an HTTP response from a FetchWorkerClusterWithResponse call -func ParseFetchWorkerClusterResponse(rsp *http.Response) (*FetchWorkerClusterResponse, error) { +// ParseFetchWorkerTagResponse parses an HTTP response from a FetchWorkerTagWithResponse call +func ParseFetchWorkerTagResponse(rsp *http.Response) (*FetchWorkerTagResponse, error) { bodyBytes, err := ioutil.ReadAll(rsp.Body) defer func() { _ = rsp.Body.Close() }() if err != nil { return nil, err } - response := &FetchWorkerClusterResponse{ + response := &FetchWorkerTagResponse{ Body: bodyBytes, HTTPResponse: rsp, } switch { case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 200: - var dest WorkerCluster + var dest WorkerTag if err := json.Unmarshal(bodyBytes, &dest); err != nil { return nil, err } @@ -6242,15 +6242,15 @@ func ParseFetchWorkerClusterResponse(rsp *http.Response) (*FetchWorkerClusterRes return response, nil } -// ParseUpdateWorkerClusterResponse parses an HTTP response from a UpdateWorkerClusterWithResponse call -func ParseUpdateWorkerClusterResponse(rsp *http.Response) (*UpdateWorkerClusterResponse, error) { +// ParseUpdateWorkerTagResponse parses an HTTP response from a UpdateWorkerTagWithResponse call +func ParseUpdateWorkerTagResponse(rsp *http.Response) (*UpdateWorkerTagResponse, error) { bodyBytes, err := ioutil.ReadAll(rsp.Body) defer func() { _ = rsp.Body.Close() }() if err != nil { return nil, err } - response := &UpdateWorkerClusterResponse{ + response := &UpdateWorkerTagResponse{ Body: bodyBytes, HTTPResponse: rsp, } @@ -6268,22 +6268,22 @@ func ParseUpdateWorkerClusterResponse(rsp *http.Response) (*UpdateWorkerClusterR return response, nil } -// ParseFetchWorkerClustersResponse parses an HTTP response from a FetchWorkerClustersWithResponse call -func ParseFetchWorkerClustersResponse(rsp *http.Response) (*FetchWorkerClustersResponse, error) { +// ParseFetchWorkerTagsResponse parses an HTTP response from a FetchWorkerTagsWithResponse call +func ParseFetchWorkerTagsResponse(rsp *http.Response) (*FetchWorkerTagsResponse, error) { bodyBytes, err := ioutil.ReadAll(rsp.Body) defer func() { _ = rsp.Body.Close() }() if err != nil { return nil, err } - response := &FetchWorkerClustersResponse{ + response := &FetchWorkerTagsResponse{ Body: bodyBytes, HTTPResponse: rsp, } switch { case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 200: - var dest WorkerClusterList + var dest WorkerTagList if err := json.Unmarshal(bodyBytes, &dest); err != nil { return nil, err } @@ -6294,22 +6294,22 @@ func ParseFetchWorkerClustersResponse(rsp *http.Response) (*FetchWorkerClustersR return response, nil } -// ParseCreateWorkerClusterResponse parses an HTTP response from a CreateWorkerClusterWithResponse call -func ParseCreateWorkerClusterResponse(rsp *http.Response) (*CreateWorkerClusterResponse, error) { +// ParseCreateWorkerTagResponse parses an HTTP response from a CreateWorkerTagWithResponse call +func ParseCreateWorkerTagResponse(rsp *http.Response) (*CreateWorkerTagResponse, error) { bodyBytes, err := ioutil.ReadAll(rsp.Body) defer func() { _ = rsp.Body.Close() }() if err != nil { return nil, err } - response := &CreateWorkerClusterResponse{ + response := &CreateWorkerTagResponse{ Body: bodyBytes, HTTPResponse: rsp, } switch { case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 200: - var dest WorkerCluster + var dest WorkerTag if err := json.Unmarshal(bodyBytes, &dest); err != nil { return nil, err } @@ -6405,15 +6405,15 @@ func ParseFetchWorkerResponse(rsp *http.Response) (*FetchWorkerResponse, error) return response, nil } -// ParseSetWorkerClustersResponse parses an HTTP response from a SetWorkerClustersWithResponse call -func ParseSetWorkerClustersResponse(rsp *http.Response) (*SetWorkerClustersResponse, error) { +// 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 := &SetWorkerClustersResponse{ + response := &RequestWorkerStatusChangeResponse{ Body: bodyBytes, HTTPResponse: rsp, } @@ -6431,15 +6431,15 @@ func ParseSetWorkerClustersResponse(rsp *http.Response) (*SetWorkerClustersRespo return response, nil } -// ParseRequestWorkerStatusChangeResponse parses an HTTP response from a RequestWorkerStatusChangeWithResponse call -func ParseRequestWorkerStatusChangeResponse(rsp *http.Response) (*RequestWorkerStatusChangeResponse, error) { +// ParseSetWorkerTagsResponse parses an HTTP response from a SetWorkerTagsWithResponse call +func ParseSetWorkerTagsResponse(rsp *http.Response) (*SetWorkerTagsResponse, error) { bodyBytes, err := ioutil.ReadAll(rsp.Body) defer func() { _ = rsp.Body.Close() }() if err != nil { return nil, err } - response := &RequestWorkerStatusChangeResponse{ + response := &SetWorkerTagsResponse{ Body: bodyBytes, HTTPResponse: rsp, } diff --git a/pkg/api/openapi_server.gen.go b/pkg/api/openapi_server.gen.go index d314ecbf..c7d168d4 100644 --- a/pkg/api/openapi_server.gen.go +++ b/pkg/api/openapi_server.gen.go @@ -110,21 +110,21 @@ type ServerInterface interface { // Get the Flamenco version of this Manager // (GET /api/v3/version) GetVersion(ctx echo.Context) error - // Remove this worker cluster. This unassigns all workers from the cluster and removes it. - // (DELETE /api/v3/worker-mgt/cluster/{cluster_id}) - DeleteWorkerCluster(ctx echo.Context, clusterId string) error - // Get a single worker cluster. - // (GET /api/v3/worker-mgt/cluster/{cluster_id}) - FetchWorkerCluster(ctx echo.Context, clusterId string) error - // Update an existing worker cluster. - // (PUT /api/v3/worker-mgt/cluster/{cluster_id}) - UpdateWorkerCluster(ctx echo.Context, clusterId string) error - // Get list of worker clusters. - // (GET /api/v3/worker-mgt/clusters) - FetchWorkerClusters(ctx echo.Context) error - // Create a new worker cluster. - // (POST /api/v3/worker-mgt/clusters) - CreateWorkerCluster(ctx echo.Context) error + // Remove this worker tag. This unassigns all workers from the tag and removes it. + // (DELETE /api/v3/worker-mgt/tag/{tag_id}) + DeleteWorkerTag(ctx echo.Context, tagId string) error + // Get a single worker tag. + // (GET /api/v3/worker-mgt/tag/{tag_id}) + FetchWorkerTag(ctx echo.Context, tagId string) error + // Update an existing worker tag. + // (PUT /api/v3/worker-mgt/tag/{tag_id}) + UpdateWorkerTag(ctx echo.Context, tagId string) error + // Get list of worker tags. + // (GET /api/v3/worker-mgt/tags) + FetchWorkerTags(ctx echo.Context) error + // Create a new worker tag. + // (POST /api/v3/worker-mgt/tags) + CreateWorkerTag(ctx echo.Context) error // Get list of workers. // (GET /api/v3/worker-mgt/workers) FetchWorkers(ctx echo.Context) error @@ -135,12 +135,12 @@ type ServerInterface interface { // (GET /api/v3/worker-mgt/workers/{worker_id}) FetchWorker(ctx echo.Context, workerId string) error - // (POST /api/v3/worker-mgt/workers/{worker_id}/setclusters) - SetWorkerClusters(ctx echo.Context, workerId string) error - // (POST /api/v3/worker-mgt/workers/{worker_id}/setstatus) RequestWorkerStatusChange(ctx echo.Context, workerId string) error + // (POST /api/v3/worker-mgt/workers/{worker_id}/settags) + SetWorkerTags(ctx echo.Context, workerId string) error + // (GET /api/v3/worker-mgt/workers/{worker_id}/sleep-schedule) FetchWorkerSleepSchedule(ctx echo.Context, workerId string) error @@ -661,69 +661,69 @@ func (w *ServerInterfaceWrapper) GetVersion(ctx echo.Context) error { return err } -// DeleteWorkerCluster converts echo context to params. -func (w *ServerInterfaceWrapper) DeleteWorkerCluster(ctx echo.Context) error { +// DeleteWorkerTag converts echo context to params. +func (w *ServerInterfaceWrapper) DeleteWorkerTag(ctx echo.Context) error { var err error - // ------------- Path parameter "cluster_id" ------------- - var clusterId string + // ------------- Path parameter "tag_id" ------------- + var tagId string - err = runtime.BindStyledParameterWithLocation("simple", false, "cluster_id", runtime.ParamLocationPath, ctx.Param("cluster_id"), &clusterId) + err = runtime.BindStyledParameterWithLocation("simple", false, "tag_id", runtime.ParamLocationPath, ctx.Param("tag_id"), &tagId) if err != nil { - return echo.NewHTTPError(http.StatusBadRequest, fmt.Sprintf("Invalid format for parameter cluster_id: %s", err)) + return echo.NewHTTPError(http.StatusBadRequest, fmt.Sprintf("Invalid format for parameter tag_id: %s", err)) } // Invoke the callback with all the unmarshalled arguments - err = w.Handler.DeleteWorkerCluster(ctx, clusterId) + err = w.Handler.DeleteWorkerTag(ctx, tagId) return err } -// FetchWorkerCluster converts echo context to params. -func (w *ServerInterfaceWrapper) FetchWorkerCluster(ctx echo.Context) error { +// FetchWorkerTag converts echo context to params. +func (w *ServerInterfaceWrapper) FetchWorkerTag(ctx echo.Context) error { var err error - // ------------- Path parameter "cluster_id" ------------- - var clusterId string + // ------------- Path parameter "tag_id" ------------- + var tagId string - err = runtime.BindStyledParameterWithLocation("simple", false, "cluster_id", runtime.ParamLocationPath, ctx.Param("cluster_id"), &clusterId) + err = runtime.BindStyledParameterWithLocation("simple", false, "tag_id", runtime.ParamLocationPath, ctx.Param("tag_id"), &tagId) if err != nil { - return echo.NewHTTPError(http.StatusBadRequest, fmt.Sprintf("Invalid format for parameter cluster_id: %s", err)) + return echo.NewHTTPError(http.StatusBadRequest, fmt.Sprintf("Invalid format for parameter tag_id: %s", err)) } // Invoke the callback with all the unmarshalled arguments - err = w.Handler.FetchWorkerCluster(ctx, clusterId) + err = w.Handler.FetchWorkerTag(ctx, tagId) return err } -// UpdateWorkerCluster converts echo context to params. -func (w *ServerInterfaceWrapper) UpdateWorkerCluster(ctx echo.Context) error { +// UpdateWorkerTag converts echo context to params. +func (w *ServerInterfaceWrapper) UpdateWorkerTag(ctx echo.Context) error { var err error - // ------------- Path parameter "cluster_id" ------------- - var clusterId string + // ------------- Path parameter "tag_id" ------------- + var tagId string - err = runtime.BindStyledParameterWithLocation("simple", false, "cluster_id", runtime.ParamLocationPath, ctx.Param("cluster_id"), &clusterId) + err = runtime.BindStyledParameterWithLocation("simple", false, "tag_id", runtime.ParamLocationPath, ctx.Param("tag_id"), &tagId) if err != nil { - return echo.NewHTTPError(http.StatusBadRequest, fmt.Sprintf("Invalid format for parameter cluster_id: %s", err)) + return echo.NewHTTPError(http.StatusBadRequest, fmt.Sprintf("Invalid format for parameter tag_id: %s", err)) } // Invoke the callback with all the unmarshalled arguments - err = w.Handler.UpdateWorkerCluster(ctx, clusterId) + err = w.Handler.UpdateWorkerTag(ctx, tagId) return err } -// FetchWorkerClusters converts echo context to params. -func (w *ServerInterfaceWrapper) FetchWorkerClusters(ctx echo.Context) error { +// FetchWorkerTags converts echo context to params. +func (w *ServerInterfaceWrapper) FetchWorkerTags(ctx echo.Context) error { var err error // Invoke the callback with all the unmarshalled arguments - err = w.Handler.FetchWorkerClusters(ctx) + err = w.Handler.FetchWorkerTags(ctx) return err } -// CreateWorkerCluster converts echo context to params. -func (w *ServerInterfaceWrapper) CreateWorkerCluster(ctx echo.Context) error { +// CreateWorkerTag converts echo context to params. +func (w *ServerInterfaceWrapper) CreateWorkerTag(ctx echo.Context) error { var err error // Invoke the callback with all the unmarshalled arguments - err = w.Handler.CreateWorkerCluster(ctx) + err = w.Handler.CreateWorkerTag(ctx) return err } @@ -768,22 +768,6 @@ func (w *ServerInterfaceWrapper) FetchWorker(ctx echo.Context) error { return err } -// SetWorkerClusters converts echo context to params. -func (w *ServerInterfaceWrapper) SetWorkerClusters(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.SetWorkerClusters(ctx, workerId) - return err -} - // RequestWorkerStatusChange converts echo context to params. func (w *ServerInterfaceWrapper) RequestWorkerStatusChange(ctx echo.Context) error { var err error @@ -800,6 +784,22 @@ func (w *ServerInterfaceWrapper) RequestWorkerStatusChange(ctx echo.Context) err return err } +// SetWorkerTags converts echo context to params. +func (w *ServerInterfaceWrapper) SetWorkerTags(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.SetWorkerTags(ctx, workerId) + return err +} + // FetchWorkerSleepSchedule converts echo context to params. func (w *ServerInterfaceWrapper) FetchWorkerSleepSchedule(ctx echo.Context) error { var err error @@ -1010,16 +1010,16 @@ func RegisterHandlersWithBaseURL(router EchoRouter, si ServerInterface, baseURL router.GET(baseURL+"/api/v3/tasks/:task_id/logtail", wrapper.FetchTaskLogTail) router.POST(baseURL+"/api/v3/tasks/:task_id/setstatus", wrapper.SetTaskStatus) router.GET(baseURL+"/api/v3/version", wrapper.GetVersion) - router.DELETE(baseURL+"/api/v3/worker-mgt/cluster/:cluster_id", wrapper.DeleteWorkerCluster) - router.GET(baseURL+"/api/v3/worker-mgt/cluster/:cluster_id", wrapper.FetchWorkerCluster) - router.PUT(baseURL+"/api/v3/worker-mgt/cluster/:cluster_id", wrapper.UpdateWorkerCluster) - router.GET(baseURL+"/api/v3/worker-mgt/clusters", wrapper.FetchWorkerClusters) - router.POST(baseURL+"/api/v3/worker-mgt/clusters", wrapper.CreateWorkerCluster) + router.DELETE(baseURL+"/api/v3/worker-mgt/tag/:tag_id", wrapper.DeleteWorkerTag) + router.GET(baseURL+"/api/v3/worker-mgt/tag/:tag_id", wrapper.FetchWorkerTag) + router.PUT(baseURL+"/api/v3/worker-mgt/tag/:tag_id", wrapper.UpdateWorkerTag) + router.GET(baseURL+"/api/v3/worker-mgt/tags", wrapper.FetchWorkerTags) + router.POST(baseURL+"/api/v3/worker-mgt/tags", wrapper.CreateWorkerTag) router.GET(baseURL+"/api/v3/worker-mgt/workers", wrapper.FetchWorkers) router.DELETE(baseURL+"/api/v3/worker-mgt/workers/:worker_id", wrapper.DeleteWorker) router.GET(baseURL+"/api/v3/worker-mgt/workers/:worker_id", wrapper.FetchWorker) - router.POST(baseURL+"/api/v3/worker-mgt/workers/:worker_id/setclusters", wrapper.SetWorkerClusters) router.POST(baseURL+"/api/v3/worker-mgt/workers/:worker_id/setstatus", wrapper.RequestWorkerStatusChange) + router.POST(baseURL+"/api/v3/worker-mgt/workers/:worker_id/settags", wrapper.SetWorkerTags) router.GET(baseURL+"/api/v3/worker-mgt/workers/:worker_id/sleep-schedule", wrapper.FetchWorkerSleepSchedule) router.POST(baseURL+"/api/v3/worker-mgt/workers/:worker_id/sleep-schedule", wrapper.SetWorkerSleepSchedule) router.POST(baseURL+"/api/v3/worker/register-worker", wrapper.RegisterWorker) diff --git a/pkg/api/openapi_spec.gen.go b/pkg/api/openapi_spec.gen.go index 44add218..71af703a 100644 --- a/pkg/api/openapi_spec.gen.go +++ b/pkg/api/openapi_spec.gen.go @@ -18,218 +18,218 @@ import ( // Base64 encoded, gzipped, json marshaled Swagger object var swaggerSpec = []string{ - "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", + "XwAAAP//X9irkUUBAQA=", } // 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 cc38c11f..def95f89 100644 --- a/pkg/api/openapi_types.gen.go +++ b/pkg/api/openapi_types.gen.go @@ -636,8 +636,8 @@ type SubmittedJob struct { // If this field is ommitted, the check is bypassed. TypeEtag *string `json:"type_etag,omitempty"` - // Worker Cluster that should execute this job. When a cluster ID is given, only Workers in that cluster will be scheduled to work on it. If empty or ommitted, all workers can work on this job. - WorkerCluster *string `json:"worker_cluster,omitempty"` + // Worker tag that should execute this job. When a tag ID is given, only Workers in that tag will be scheduled to work on it. If empty or ommitted, all workers can work on this job. + WorkerTag *string `json:"worker_tag,omitempty"` } // The task as it exists in the Manager database, i.e. before variable replacement. @@ -719,9 +719,6 @@ type Worker struct { // Embedded struct due to allOf(#/components/schemas/WorkerSummary) WorkerSummary `yaml:",inline"` // Embedded fields due to inline allOf schema - // Clusters of which this Worker is a member. - Clusters *[]WorkerCluster `json:"clusters,omitempty"` - // IP address of the Worker IpAddress string `json:"ip_address"` @@ -729,29 +726,13 @@ type Worker struct { Platform string `json:"platform"` SupportedTaskTypes []string `json:"supported_task_types"` + // Tags of which this Worker is a member. + Tags *[]WorkerTag `json:"tags,omitempty"` + // Task assigned to a Worker. Task *WorkerTask `json:"task,omitempty"` } -// Cluster of workers. A job can optionally specify which cluster it should be limited to. Workers can be part of multiple clusters simultaneously. -type WorkerCluster struct { - Description *string `json:"description,omitempty"` - - // UUID of the cluster. Can be ommitted when creating a new cluster, in which case a random UUID will be assigned. - Id *string `json:"id,omitempty"` - Name string `json:"name"` -} - -// Request to change which clusters this Worker is assigned to. -type WorkerClusterChangeRequest struct { - ClusterIds []string `json:"cluster_ids"` -} - -// WorkerClusterList defines model for WorkerClusterList. -type WorkerClusterList struct { - Clusters *[]WorkerCluster `json:"clusters,omitempty"` -} - // List of workers. type WorkerList struct { Workers []WorkerSummary `json:"workers"` @@ -818,6 +799,25 @@ type WorkerSummary struct { Version string `json:"version"` } +// Tag of workers. A job can optionally specify which tag it should be limited to. Workers can be part of multiple tags simultaneously. +type WorkerTag struct { + Description *string `json:"description,omitempty"` + + // UUID of the tag. Can be ommitted when creating a new tag, in which case a random UUID will be assigned. + Id *string `json:"id,omitempty"` + Name string `json:"name"` +} + +// Request to change which tags this Worker is assigned to. +type WorkerTagChangeRequest struct { + TagIds []string `json:"tag_ids"` +} + +// WorkerTagList defines model for WorkerTagList. +type WorkerTagList struct { + Tags *[]WorkerTag `json:"tags,omitempty"` +} + // WorkerTask defines model for WorkerTask. type WorkerTask struct { // Embedded struct due to allOf(#/components/schemas/TaskSummary) @@ -871,18 +871,18 @@ type ShamanFileStoreParams struct { // SetTaskStatusJSONBody defines parameters for SetTaskStatus. type SetTaskStatusJSONBody TaskStatusChange -// UpdateWorkerClusterJSONBody defines parameters for UpdateWorkerCluster. -type UpdateWorkerClusterJSONBody WorkerCluster +// UpdateWorkerTagJSONBody defines parameters for UpdateWorkerTag. +type UpdateWorkerTagJSONBody WorkerTag -// CreateWorkerClusterJSONBody defines parameters for CreateWorkerCluster. -type CreateWorkerClusterJSONBody WorkerCluster - -// SetWorkerClustersJSONBody defines parameters for SetWorkerClusters. -type SetWorkerClustersJSONBody WorkerClusterChangeRequest +// CreateWorkerTagJSONBody defines parameters for CreateWorkerTag. +type CreateWorkerTagJSONBody WorkerTag // RequestWorkerStatusChangeJSONBody defines parameters for RequestWorkerStatusChange. type RequestWorkerStatusChangeJSONBody WorkerStatusChangeRequest +// SetWorkerTagsJSONBody defines parameters for SetWorkerTags. +type SetWorkerTagsJSONBody WorkerTagChangeRequest + // SetWorkerSleepScheduleJSONBody defines parameters for SetWorkerSleepSchedule. type SetWorkerSleepScheduleJSONBody WorkerSleepSchedule @@ -934,18 +934,18 @@ type ShamanCheckoutRequirementsJSONRequestBody ShamanCheckoutRequirementsJSONBod // SetTaskStatusJSONRequestBody defines body for SetTaskStatus for application/json ContentType. type SetTaskStatusJSONRequestBody SetTaskStatusJSONBody -// UpdateWorkerClusterJSONRequestBody defines body for UpdateWorkerCluster for application/json ContentType. -type UpdateWorkerClusterJSONRequestBody UpdateWorkerClusterJSONBody +// UpdateWorkerTagJSONRequestBody defines body for UpdateWorkerTag for application/json ContentType. +type UpdateWorkerTagJSONRequestBody UpdateWorkerTagJSONBody -// CreateWorkerClusterJSONRequestBody defines body for CreateWorkerCluster for application/json ContentType. -type CreateWorkerClusterJSONRequestBody CreateWorkerClusterJSONBody - -// SetWorkerClustersJSONRequestBody defines body for SetWorkerClusters for application/json ContentType. -type SetWorkerClustersJSONRequestBody SetWorkerClustersJSONBody +// CreateWorkerTagJSONRequestBody defines body for CreateWorkerTag for application/json ContentType. +type CreateWorkerTagJSONRequestBody CreateWorkerTagJSONBody // RequestWorkerStatusChangeJSONRequestBody defines body for RequestWorkerStatusChange for application/json ContentType. type RequestWorkerStatusChangeJSONRequestBody RequestWorkerStatusChangeJSONBody +// SetWorkerTagsJSONRequestBody defines body for SetWorkerTags for application/json ContentType. +type SetWorkerTagsJSONRequestBody SetWorkerTagsJSONBody + // SetWorkerSleepScheduleJSONRequestBody defines body for SetWorkerSleepSchedule for application/json ContentType. type SetWorkerSleepScheduleJSONRequestBody SetWorkerSleepScheduleJSONBody diff --git a/web/app/src/components/jobs/JobDetails.vue b/web/app/src/components/jobs/JobDetails.vue index 6198b7ee..55ca5d08 100644 --- a/web/app/src/components/jobs/JobDetails.vue +++ b/web/app/src/components/jobs/JobDetails.vue @@ -32,12 +32,17 @@
ID
{{ jobData.id }}
-