More Shaman integration work
- Addon switches between filesystem-packing and Shaman-packing automatically, depending on whether the Manager has Shaman enabled. - Actually using BAT for Shaman packing. It doesn't work though, some error occurs when receiving Shaman response from the Manager in the Addon.
This commit is contained in:
parent
f9b7510c42
commit
21227c8046
@ -197,7 +197,7 @@ def copy( # type: ignore
|
|||||||
*,
|
*,
|
||||||
relative_only: bool,
|
relative_only: bool,
|
||||||
packer_class=pack.Packer,
|
packer_class=pack.Packer,
|
||||||
**packer_args: dict[Any, Any],
|
packer_kwargs: Optional[dict[Any, Any]] = None,
|
||||||
) -> PackThread:
|
) -> PackThread:
|
||||||
"""Use BAT to copy the given file and dependencies to the target location.
|
"""Use BAT to copy the given file and dependencies to the target location.
|
||||||
|
|
||||||
@ -210,13 +210,18 @@ def copy( # type: ignore
|
|||||||
if _running_packthread is not None:
|
if _running_packthread is not None:
|
||||||
raise RuntimeError("other packing operation already in progress")
|
raise RuntimeError("other packing operation already in progress")
|
||||||
|
|
||||||
|
print(f"packer_class: {packer_class}")
|
||||||
|
if packer_kwargs is None:
|
||||||
|
packer_kwargs = {}
|
||||||
|
packer_kwargs.setdefault("compress", True)
|
||||||
|
packer_kwargs.setdefault("relative_only", relative_only)
|
||||||
|
print(f"packer_kwargs: {packer_kwargs}")
|
||||||
|
|
||||||
packer = packer_class(
|
packer = packer_class(
|
||||||
base_blendfile,
|
base_blendfile,
|
||||||
project,
|
project,
|
||||||
target,
|
target,
|
||||||
compress=True,
|
**packer_kwargs,
|
||||||
relative_only=relative_only,
|
|
||||||
**packer_args,
|
|
||||||
)
|
)
|
||||||
if exclusion_filter:
|
if exclusion_filter:
|
||||||
filter_parts = exclusion_filter.strip().split(" ")
|
filter_parts = exclusion_filter.strip().split(" ")
|
||||||
|
@ -44,6 +44,7 @@ class Packer(bat_pack.Packer): # type: ignore
|
|||||||
blendfile: Path,
|
blendfile: Path,
|
||||||
project_root: Path,
|
project_root: Path,
|
||||||
target: str,
|
target: str,
|
||||||
|
*,
|
||||||
api_client: _ApiClient,
|
api_client: _ApiClient,
|
||||||
checkout_path: str,
|
checkout_path: str,
|
||||||
**kwargs: dict[Any, Any],
|
**kwargs: dict[Any, Any],
|
||||||
@ -201,7 +202,7 @@ class Transferrer(bat_transfer.FileTransferer): # type: ignore
|
|||||||
try:
|
try:
|
||||||
checksum = cache.compute_cached_checksum(src)
|
checksum = cache.compute_cached_checksum(src)
|
||||||
filesize = src.stat().st_size
|
filesize = src.stat().st_size
|
||||||
relpath: str = bat_bpathlib.strip_root(dst)
|
relpath = str(bat_bpathlib.strip_root(dst))
|
||||||
|
|
||||||
filespec = ShamanFileSpec(
|
filespec = ShamanFileSpec(
|
||||||
sha=checksum,
|
sha=checksum,
|
||||||
@ -253,6 +254,7 @@ class Transferrer(bat_transfer.FileTransferer): # type: ignore
|
|||||||
|
|
||||||
to_upload: deque[_ShamanFileSpec] = deque()
|
to_upload: deque[_ShamanFileSpec] = deque()
|
||||||
for file_spec in resp.files:
|
for file_spec in resp.files:
|
||||||
|
print(file_spec)
|
||||||
if file_spec.path not in self._rel_to_local_path:
|
if file_spec.path not in self._rel_to_local_path:
|
||||||
msg = (
|
msg = (
|
||||||
"Shaman requested path we did not intend to upload: %r" % file_spec
|
"Shaman requested path we did not intend to upload: %r" % file_spec
|
||||||
@ -261,7 +263,7 @@ class Transferrer(bat_transfer.FileTransferer): # type: ignore
|
|||||||
self.error_set(msg)
|
self.error_set(msg)
|
||||||
return None
|
return None
|
||||||
|
|
||||||
self.log.debug(" %s: %s", file_spec.status, file_spec.path)
|
self.log.debug(" %s: %s", file_spec.status.value, file_spec.path)
|
||||||
match file_spec.status.value:
|
match file_spec.status.value:
|
||||||
case "unknown":
|
case "unknown":
|
||||||
to_upload.appendleft(file_spec)
|
to_upload.appendleft(file_spec)
|
||||||
|
@ -3,8 +3,8 @@
|
|||||||
|
|
||||||
from typing import Optional, TYPE_CHECKING
|
from typing import Optional, TYPE_CHECKING
|
||||||
|
|
||||||
from flamenco import job_submission
|
from . import preferences
|
||||||
from flamenco.job_types_propgroup import JobTypePropertyGroup
|
from .job_types_propgroup import JobTypePropertyGroup
|
||||||
|
|
||||||
import bpy
|
import bpy
|
||||||
|
|
||||||
@ -31,6 +31,8 @@ class FLAMENCO_PT_job_submission(bpy.types.Panel):
|
|||||||
def draw(self, context: bpy.types.Context) -> None:
|
def draw(self, context: bpy.types.Context) -> None:
|
||||||
from . import job_types
|
from . import job_types
|
||||||
|
|
||||||
|
prefs = preferences.get(context)
|
||||||
|
|
||||||
layout = self.layout
|
layout = self.layout
|
||||||
layout.use_property_decorate = False
|
layout.use_property_decorate = False
|
||||||
layout.use_property_split = True
|
layout.use_property_split = True
|
||||||
@ -39,7 +41,14 @@ class FLAMENCO_PT_job_submission(bpy.types.Panel):
|
|||||||
|
|
||||||
col = layout.column(align=True)
|
col = layout.column(align=True)
|
||||||
col.prop(context.scene, "flamenco_job_name", text="Job Name")
|
col.prop(context.scene, "flamenco_job_name", text="Job Name")
|
||||||
row = col.row(align=True)
|
|
||||||
|
job_storage_col = col.column(align=True)
|
||||||
|
job_storage_col.enabled = not prefs.is_shaman_enabled
|
||||||
|
if prefs.is_shaman_enabled:
|
||||||
|
job_storage_col.label(
|
||||||
|
text="Shaman API will be used for job submission, so job storage location is ignored:"
|
||||||
|
)
|
||||||
|
row = job_storage_col.row(align=True)
|
||||||
row.prop(context.scene, "flamenco_job_storage", text="Job Storage")
|
row.prop(context.scene, "flamenco_job_storage", text="Job Storage")
|
||||||
prop = row.operator("flamenco3.explore_file_path", text="", icon="WINDOW")
|
prop = row.operator("flamenco3.explore_file_path", text="", icon="WINDOW")
|
||||||
prop.path = context.scene.flamenco_job_storage
|
prop.path = context.scene.flamenco_job_storage
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
# SPDX-License-Identifier: GPL-3.0-or-later
|
# SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
from pathlib import Path
|
from pathlib import Path, PurePosixPath
|
||||||
from typing import TYPE_CHECKING, Optional, Union
|
from typing import TYPE_CHECKING, Optional, Union
|
||||||
|
|
||||||
import bpy
|
import bpy
|
||||||
@ -47,7 +47,9 @@ def job_for_scene(scene: bpy.types.Scene) -> Optional[_SubmittedJob]:
|
|||||||
|
|
||||||
|
|
||||||
def set_blend_file(
|
def set_blend_file(
|
||||||
job_type: _AvailableJobType, job: _SubmittedJob, blendfile: Union[str, Path]
|
job_type: _AvailableJobType,
|
||||||
|
job: _SubmittedJob,
|
||||||
|
blendfile: Union[str, Path, PurePosixPath],
|
||||||
) -> None:
|
) -> None:
|
||||||
"""Update the job's 'blendfile' setting, if available.
|
"""Update the job's 'blendfile' setting, if available.
|
||||||
|
|
||||||
|
@ -10,7 +10,7 @@
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
||||||
__version__ = "63793f42-dirty"
|
__version__ = "8a43c69f-dirty"
|
||||||
|
|
||||||
# import ApiClient
|
# import ApiClient
|
||||||
from flamenco.manager.api_client import ApiClient
|
from flamenco.manager.api_client import ApiClient
|
||||||
|
@ -22,6 +22,7 @@ from flamenco.manager.model_utils import ( # noqa: F401
|
|||||||
validate_and_convert_types
|
validate_and_convert_types
|
||||||
)
|
)
|
||||||
from flamenco.manager.model.flamenco_version import FlamencoVersion
|
from flamenco.manager.model.flamenco_version import FlamencoVersion
|
||||||
|
from flamenco.manager.model.manager_configuration import ManagerConfiguration
|
||||||
|
|
||||||
|
|
||||||
class MetaApi(object):
|
class MetaApi(object):
|
||||||
@ -35,6 +36,48 @@ class MetaApi(object):
|
|||||||
if api_client is None:
|
if api_client is None:
|
||||||
api_client = ApiClient()
|
api_client = ApiClient()
|
||||||
self.api_client = api_client
|
self.api_client = api_client
|
||||||
|
self.get_configuration_endpoint = _Endpoint(
|
||||||
|
settings={
|
||||||
|
'response_type': (ManagerConfiguration,),
|
||||||
|
'auth': [],
|
||||||
|
'endpoint_path': '/api/configuration',
|
||||||
|
'operation_id': 'get_configuration',
|
||||||
|
'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.get_version_endpoint = _Endpoint(
|
self.get_version_endpoint = _Endpoint(
|
||||||
settings={
|
settings={
|
||||||
'response_type': (FlamencoVersion,),
|
'response_type': (FlamencoVersion,),
|
||||||
@ -78,6 +121,78 @@ class MetaApi(object):
|
|||||||
api_client=api_client
|
api_client=api_client
|
||||||
)
|
)
|
||||||
|
|
||||||
|
def get_configuration(
|
||||||
|
self,
|
||||||
|
**kwargs
|
||||||
|
):
|
||||||
|
"""Get the configuration of this Manager. # noqa: E501
|
||||||
|
|
||||||
|
This method makes a synchronous HTTP request by default. To make an
|
||||||
|
asynchronous HTTP request, please pass async_req=True
|
||||||
|
|
||||||
|
>>> thread = api.get_configuration(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:
|
||||||
|
ManagerConfiguration
|
||||||
|
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.get_configuration_endpoint.call_with_http_info(**kwargs)
|
||||||
|
|
||||||
def get_version(
|
def get_version(
|
||||||
self,
|
self,
|
||||||
**kwargs
|
**kwargs
|
||||||
|
@ -76,7 +76,7 @@ class ApiClient(object):
|
|||||||
self.default_headers[header_name] = header_value
|
self.default_headers[header_name] = header_value
|
||||||
self.cookie = cookie
|
self.cookie = cookie
|
||||||
# Set default User-Agent.
|
# Set default User-Agent.
|
||||||
self.user_agent = 'Flamenco/63793f42-dirty (Blender add-on)'
|
self.user_agent = 'Flamenco/8a43c69f-dirty (Blender add-on)'
|
||||||
|
|
||||||
def __enter__(self):
|
def __enter__(self):
|
||||||
return self
|
return self
|
||||||
|
@ -404,7 +404,7 @@ conf = flamenco.manager.Configuration(
|
|||||||
"OS: {env}\n"\
|
"OS: {env}\n"\
|
||||||
"Python Version: {pyversion}\n"\
|
"Python Version: {pyversion}\n"\
|
||||||
"Version of the API: 1.0.0\n"\
|
"Version of the API: 1.0.0\n"\
|
||||||
"SDK Package Version: 63793f42-dirty".\
|
"SDK Package Version: 8a43c69f-dirty".\
|
||||||
format(env=sys.platform, pyversion=sys.version)
|
format(env=sys.platform, pyversion=sys.version)
|
||||||
|
|
||||||
def get_host_settings(self):
|
def get_host_settings(self):
|
||||||
|
12
addon/flamenco/manager/docs/ManagerConfiguration.md
Normal file
12
addon/flamenco/manager/docs/ManagerConfiguration.md
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
# ManagerConfiguration
|
||||||
|
|
||||||
|
|
||||||
|
## Properties
|
||||||
|
Name | Type | Description | Notes
|
||||||
|
------------ | ------------- | ------------- | -------------
|
||||||
|
**shaman_enabled** | **bool** | Whether the Shaman file transfer API is available. |
|
||||||
|
**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)
|
||||||
|
|
||||||
|
|
@ -4,9 +4,71 @@ All URIs are relative to *http://localhost*
|
|||||||
|
|
||||||
Method | HTTP request | Description
|
Method | HTTP request | Description
|
||||||
------------- | ------------- | -------------
|
------------- | ------------- | -------------
|
||||||
|
[**get_configuration**](MetaApi.md#get_configuration) | **GET** /api/configuration | Get the configuration of this Manager.
|
||||||
[**get_version**](MetaApi.md#get_version) | **GET** /api/version | Get the Flamenco version of this Manager
|
[**get_version**](MetaApi.md#get_version) | **GET** /api/version | Get the Flamenco version of this Manager
|
||||||
|
|
||||||
|
|
||||||
|
# **get_configuration**
|
||||||
|
> ManagerConfiguration get_configuration()
|
||||||
|
|
||||||
|
Get the configuration of this Manager.
|
||||||
|
|
||||||
|
### Example
|
||||||
|
|
||||||
|
|
||||||
|
```python
|
||||||
|
import time
|
||||||
|
import flamenco.manager
|
||||||
|
from flamenco.manager.api import meta_api
|
||||||
|
from flamenco.manager.model.manager_configuration import ManagerConfiguration
|
||||||
|
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 = meta_api.MetaApi(api_client)
|
||||||
|
|
||||||
|
# example, this endpoint has no required or optional parameters
|
||||||
|
try:
|
||||||
|
# Get the configuration of this Manager.
|
||||||
|
api_response = api_instance.get_configuration()
|
||||||
|
pprint(api_response)
|
||||||
|
except flamenco.manager.ApiException as e:
|
||||||
|
print("Exception when calling MetaApi->get_configuration: %s\n" % e)
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
### Parameters
|
||||||
|
This endpoint does not need any parameter.
|
||||||
|
|
||||||
|
### Return type
|
||||||
|
|
||||||
|
[**ManagerConfiguration**](ManagerConfiguration.md)
|
||||||
|
|
||||||
|
### Authorization
|
||||||
|
|
||||||
|
No authorization required
|
||||||
|
|
||||||
|
### HTTP request headers
|
||||||
|
|
||||||
|
- **Content-Type**: Not defined
|
||||||
|
- **Accept**: application/json
|
||||||
|
|
||||||
|
|
||||||
|
### HTTP response details
|
||||||
|
|
||||||
|
| Status code | Description | Response headers |
|
||||||
|
|-------------|-------------|------------------|
|
||||||
|
**200** | normal response | - |
|
||||||
|
|
||||||
|
[[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)
|
||||||
|
|
||||||
# **get_version**
|
# **get_version**
|
||||||
> FlamencoVersion get_version()
|
> FlamencoVersion get_version()
|
||||||
|
|
||||||
|
261
addon/flamenco/manager/model/manager_configuration.py
Normal file
261
addon/flamenco/manager/model/manager_configuration.py
Normal file
@ -0,0 +1,261 @@
|
|||||||
|
"""
|
||||||
|
Flamenco manager
|
||||||
|
|
||||||
|
Render Farm manager API # noqa: E501
|
||||||
|
|
||||||
|
The version of the OpenAPI document: 1.0.0
|
||||||
|
Generated by: https://openapi-generator.tech
|
||||||
|
"""
|
||||||
|
|
||||||
|
|
||||||
|
import re # noqa: F401
|
||||||
|
import sys # noqa: F401
|
||||||
|
|
||||||
|
from flamenco.manager.model_utils import ( # noqa: F401
|
||||||
|
ApiTypeError,
|
||||||
|
ModelComposed,
|
||||||
|
ModelNormal,
|
||||||
|
ModelSimple,
|
||||||
|
cached_property,
|
||||||
|
change_keys_js_to_python,
|
||||||
|
convert_js_args_to_python_args,
|
||||||
|
date,
|
||||||
|
datetime,
|
||||||
|
file_type,
|
||||||
|
none_type,
|
||||||
|
validate_get_composed_info,
|
||||||
|
OpenApiModel
|
||||||
|
)
|
||||||
|
from flamenco.manager.exceptions import ApiAttributeError
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
class ManagerConfiguration(ModelNormal):
|
||||||
|
"""NOTE: This class is auto generated by OpenAPI Generator.
|
||||||
|
Ref: https://openapi-generator.tech
|
||||||
|
|
||||||
|
Do not edit the class manually.
|
||||||
|
|
||||||
|
Attributes:
|
||||||
|
allowed_values (dict): The key is the tuple path to the attribute
|
||||||
|
and the for var_name this is (var_name,). The value is a dict
|
||||||
|
with a capitalized key describing the allowed value and an allowed
|
||||||
|
value. These dicts store the allowed enum values.
|
||||||
|
attribute_map (dict): The key is attribute name
|
||||||
|
and the value is json key in definition.
|
||||||
|
discriminator_value_class_map (dict): A dict to go from the discriminator
|
||||||
|
variable value to the discriminator class name.
|
||||||
|
validations (dict): The key is the tuple path to the attribute
|
||||||
|
and the for var_name this is (var_name,). The value is a dict
|
||||||
|
that stores validations for max_length, min_length, max_items,
|
||||||
|
min_items, exclusive_maximum, inclusive_maximum, exclusive_minimum,
|
||||||
|
inclusive_minimum, and regex.
|
||||||
|
additional_properties_type (tuple): A tuple of classes accepted
|
||||||
|
as additional properties values.
|
||||||
|
"""
|
||||||
|
|
||||||
|
allowed_values = {
|
||||||
|
}
|
||||||
|
|
||||||
|
validations = {
|
||||||
|
}
|
||||||
|
|
||||||
|
@cached_property
|
||||||
|
def additional_properties_type():
|
||||||
|
"""
|
||||||
|
This must be a method because a model may have properties that are
|
||||||
|
of type self, this must run after the class is loaded
|
||||||
|
"""
|
||||||
|
return (bool, date, datetime, dict, float, int, list, str, none_type,) # noqa: E501
|
||||||
|
|
||||||
|
_nullable = False
|
||||||
|
|
||||||
|
@cached_property
|
||||||
|
def openapi_types():
|
||||||
|
"""
|
||||||
|
This must be a method because a model may have properties that are
|
||||||
|
of type self, this must run after the class is loaded
|
||||||
|
|
||||||
|
Returns
|
||||||
|
openapi_types (dict): The key is attribute name
|
||||||
|
and the value is attribute type.
|
||||||
|
"""
|
||||||
|
return {
|
||||||
|
'shaman_enabled': (bool,), # noqa: E501
|
||||||
|
}
|
||||||
|
|
||||||
|
@cached_property
|
||||||
|
def discriminator():
|
||||||
|
return None
|
||||||
|
|
||||||
|
|
||||||
|
attribute_map = {
|
||||||
|
'shaman_enabled': 'shamanEnabled', # noqa: E501
|
||||||
|
}
|
||||||
|
|
||||||
|
read_only_vars = {
|
||||||
|
}
|
||||||
|
|
||||||
|
_composed_schemas = {}
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
@convert_js_args_to_python_args
|
||||||
|
def _from_openapi_data(cls, shaman_enabled, *args, **kwargs): # noqa: E501
|
||||||
|
"""ManagerConfiguration - a model defined in OpenAPI
|
||||||
|
|
||||||
|
Args:
|
||||||
|
shaman_enabled (bool): Whether the Shaman file transfer API is available.
|
||||||
|
|
||||||
|
Keyword Args:
|
||||||
|
_check_type (bool): if True, values for parameters in openapi_types
|
||||||
|
will be type checked and a TypeError will be
|
||||||
|
raised if the wrong type is input.
|
||||||
|
Defaults to True
|
||||||
|
_path_to_item (tuple/list): This is a list of keys or values to
|
||||||
|
drill down to the model in received_data
|
||||||
|
when deserializing a response
|
||||||
|
_spec_property_naming (bool): True if the variable names in the input data
|
||||||
|
are serialized names, as specified in the OpenAPI document.
|
||||||
|
False if the variable names in the input data
|
||||||
|
are pythonic names, e.g. snake case (default)
|
||||||
|
_configuration (Configuration): the instance to use when
|
||||||
|
deserializing a file_type parameter.
|
||||||
|
If passed, type conversion is attempted
|
||||||
|
If omitted no type conversion is done.
|
||||||
|
_visited_composed_classes (tuple): This stores a tuple of
|
||||||
|
classes that we have traveled through so that
|
||||||
|
if we see that class again we will not use its
|
||||||
|
discriminator again.
|
||||||
|
When traveling through a discriminator, the
|
||||||
|
composed schema that is
|
||||||
|
is traveled through is added to this set.
|
||||||
|
For example if Animal has a discriminator
|
||||||
|
petType and we pass in "Dog", and the class Dog
|
||||||
|
allOf includes Animal, we move through Animal
|
||||||
|
once using the discriminator, and pick Dog.
|
||||||
|
Then in Dog, we will make an instance of the
|
||||||
|
Animal class but this time we won't travel
|
||||||
|
through its discriminator because we passed in
|
||||||
|
_visited_composed_classes = (Animal,)
|
||||||
|
"""
|
||||||
|
|
||||||
|
_check_type = kwargs.pop('_check_type', True)
|
||||||
|
_spec_property_naming = kwargs.pop('_spec_property_naming', False)
|
||||||
|
_path_to_item = kwargs.pop('_path_to_item', ())
|
||||||
|
_configuration = kwargs.pop('_configuration', None)
|
||||||
|
_visited_composed_classes = kwargs.pop('_visited_composed_classes', ())
|
||||||
|
|
||||||
|
self = super(OpenApiModel, cls).__new__(cls)
|
||||||
|
|
||||||
|
if args:
|
||||||
|
raise ApiTypeError(
|
||||||
|
"Invalid positional arguments=%s passed to %s. Remove those invalid positional arguments." % (
|
||||||
|
args,
|
||||||
|
self.__class__.__name__,
|
||||||
|
),
|
||||||
|
path_to_item=_path_to_item,
|
||||||
|
valid_classes=(self.__class__,),
|
||||||
|
)
|
||||||
|
|
||||||
|
self._data_store = {}
|
||||||
|
self._check_type = _check_type
|
||||||
|
self._spec_property_naming = _spec_property_naming
|
||||||
|
self._path_to_item = _path_to_item
|
||||||
|
self._configuration = _configuration
|
||||||
|
self._visited_composed_classes = _visited_composed_classes + (self.__class__,)
|
||||||
|
|
||||||
|
self.shaman_enabled = shaman_enabled
|
||||||
|
for var_name, var_value in kwargs.items():
|
||||||
|
if var_name not in self.attribute_map and \
|
||||||
|
self._configuration is not None and \
|
||||||
|
self._configuration.discard_unknown_keys and \
|
||||||
|
self.additional_properties_type is None:
|
||||||
|
# discard variable.
|
||||||
|
continue
|
||||||
|
setattr(self, var_name, var_value)
|
||||||
|
return self
|
||||||
|
|
||||||
|
required_properties = set([
|
||||||
|
'_data_store',
|
||||||
|
'_check_type',
|
||||||
|
'_spec_property_naming',
|
||||||
|
'_path_to_item',
|
||||||
|
'_configuration',
|
||||||
|
'_visited_composed_classes',
|
||||||
|
])
|
||||||
|
|
||||||
|
@convert_js_args_to_python_args
|
||||||
|
def __init__(self, shaman_enabled, *args, **kwargs): # noqa: E501
|
||||||
|
"""ManagerConfiguration - a model defined in OpenAPI
|
||||||
|
|
||||||
|
Args:
|
||||||
|
shaman_enabled (bool): Whether the Shaman file transfer API is available.
|
||||||
|
|
||||||
|
Keyword Args:
|
||||||
|
_check_type (bool): if True, values for parameters in openapi_types
|
||||||
|
will be type checked and a TypeError will be
|
||||||
|
raised if the wrong type is input.
|
||||||
|
Defaults to True
|
||||||
|
_path_to_item (tuple/list): This is a list of keys or values to
|
||||||
|
drill down to the model in received_data
|
||||||
|
when deserializing a response
|
||||||
|
_spec_property_naming (bool): True if the variable names in the input data
|
||||||
|
are serialized names, as specified in the OpenAPI document.
|
||||||
|
False if the variable names in the input data
|
||||||
|
are pythonic names, e.g. snake case (default)
|
||||||
|
_configuration (Configuration): the instance to use when
|
||||||
|
deserializing a file_type parameter.
|
||||||
|
If passed, type conversion is attempted
|
||||||
|
If omitted no type conversion is done.
|
||||||
|
_visited_composed_classes (tuple): This stores a tuple of
|
||||||
|
classes that we have traveled through so that
|
||||||
|
if we see that class again we will not use its
|
||||||
|
discriminator again.
|
||||||
|
When traveling through a discriminator, the
|
||||||
|
composed schema that is
|
||||||
|
is traveled through is added to this set.
|
||||||
|
For example if Animal has a discriminator
|
||||||
|
petType and we pass in "Dog", and the class Dog
|
||||||
|
allOf includes Animal, we move through Animal
|
||||||
|
once using the discriminator, and pick Dog.
|
||||||
|
Then in Dog, we will make an instance of the
|
||||||
|
Animal class but this time we won't travel
|
||||||
|
through its discriminator because we passed in
|
||||||
|
_visited_composed_classes = (Animal,)
|
||||||
|
"""
|
||||||
|
|
||||||
|
_check_type = kwargs.pop('_check_type', True)
|
||||||
|
_spec_property_naming = kwargs.pop('_spec_property_naming', False)
|
||||||
|
_path_to_item = kwargs.pop('_path_to_item', ())
|
||||||
|
_configuration = kwargs.pop('_configuration', None)
|
||||||
|
_visited_composed_classes = kwargs.pop('_visited_composed_classes', ())
|
||||||
|
|
||||||
|
if args:
|
||||||
|
raise ApiTypeError(
|
||||||
|
"Invalid positional arguments=%s passed to %s. Remove those invalid positional arguments." % (
|
||||||
|
args,
|
||||||
|
self.__class__.__name__,
|
||||||
|
),
|
||||||
|
path_to_item=_path_to_item,
|
||||||
|
valid_classes=(self.__class__,),
|
||||||
|
)
|
||||||
|
|
||||||
|
self._data_store = {}
|
||||||
|
self._check_type = _check_type
|
||||||
|
self._spec_property_naming = _spec_property_naming
|
||||||
|
self._path_to_item = _path_to_item
|
||||||
|
self._configuration = _configuration
|
||||||
|
self._visited_composed_classes = _visited_composed_classes + (self.__class__,)
|
||||||
|
|
||||||
|
self.shaman_enabled = shaman_enabled
|
||||||
|
for var_name, var_value in kwargs.items():
|
||||||
|
if var_name not in self.attribute_map and \
|
||||||
|
self._configuration is not None and \
|
||||||
|
self._configuration.discard_unknown_keys and \
|
||||||
|
self.additional_properties_type is None:
|
||||||
|
# discard variable.
|
||||||
|
continue
|
||||||
|
setattr(self, var_name, var_value)
|
||||||
|
if var_name in self.read_only_vars:
|
||||||
|
raise ApiAttributeError(f"`{var_name}` is a read-only attribute. Use `from_openapi_data` to instantiate "
|
||||||
|
f"class with read only attributes.")
|
@ -23,6 +23,7 @@ from flamenco.manager.model.job_all_of import JobAllOf
|
|||||||
from flamenco.manager.model.job_metadata import JobMetadata
|
from flamenco.manager.model.job_metadata import JobMetadata
|
||||||
from flamenco.manager.model.job_settings import JobSettings
|
from flamenco.manager.model.job_settings import JobSettings
|
||||||
from flamenco.manager.model.job_status import JobStatus
|
from flamenco.manager.model.job_status import JobStatus
|
||||||
|
from flamenco.manager.model.manager_configuration import ManagerConfiguration
|
||||||
from flamenco.manager.model.registered_worker import RegisteredWorker
|
from flamenco.manager.model.registered_worker import RegisteredWorker
|
||||||
from flamenco.manager.model.security_error import SecurityError
|
from flamenco.manager.model.security_error import SecurityError
|
||||||
from flamenco.manager.model.shaman_checkout import ShamanCheckout
|
from flamenco.manager.model.shaman_checkout import ShamanCheckout
|
||||||
|
@ -4,7 +4,7 @@ Render Farm manager API
|
|||||||
The `flamenco.manager` package is automatically generated by the [OpenAPI Generator](https://openapi-generator.tech) project:
|
The `flamenco.manager` package is automatically generated by the [OpenAPI Generator](https://openapi-generator.tech) project:
|
||||||
|
|
||||||
- API version: 1.0.0
|
- API version: 1.0.0
|
||||||
- Package version: 63793f42-dirty
|
- Package version: 8a43c69f-dirty
|
||||||
- Build package: org.openapitools.codegen.languages.PythonClientCodegen
|
- Build package: org.openapitools.codegen.languages.PythonClientCodegen
|
||||||
For more information, please visit [https://flamenco.io/](https://flamenco.io/)
|
For more information, please visit [https://flamenco.io/](https://flamenco.io/)
|
||||||
|
|
||||||
@ -67,6 +67,7 @@ Class | Method | HTTP request | Description
|
|||||||
*JobsApi* | [**fetch_job**](flamenco/manager/docs/JobsApi.md#fetch_job) | **GET** /api/jobs/{job_id} | Fetch info about the job.
|
*JobsApi* | [**fetch_job**](flamenco/manager/docs/JobsApi.md#fetch_job) | **GET** /api/jobs/{job_id} | Fetch info about the job.
|
||||||
*JobsApi* | [**get_job_types**](flamenco/manager/docs/JobsApi.md#get_job_types) | **GET** /api/jobs/types | Get list of job types and their parameters.
|
*JobsApi* | [**get_job_types**](flamenco/manager/docs/JobsApi.md#get_job_types) | **GET** /api/jobs/types | Get list of job types and their parameters.
|
||||||
*JobsApi* | [**submit_job**](flamenco/manager/docs/JobsApi.md#submit_job) | **POST** /api/jobs | Submit a new job for Flamenco Manager to execute.
|
*JobsApi* | [**submit_job**](flamenco/manager/docs/JobsApi.md#submit_job) | **POST** /api/jobs | Submit a new job for Flamenco Manager to execute.
|
||||||
|
*MetaApi* | [**get_configuration**](flamenco/manager/docs/MetaApi.md#get_configuration) | **GET** /api/configuration | Get the configuration of this Manager.
|
||||||
*MetaApi* | [**get_version**](flamenco/manager/docs/MetaApi.md#get_version) | **GET** /api/version | Get the Flamenco version of this Manager
|
*MetaApi* | [**get_version**](flamenco/manager/docs/MetaApi.md#get_version) | **GET** /api/version | Get the Flamenco version of this Manager
|
||||||
*ShamanApi* | [**shaman_checkout**](flamenco/manager/docs/ShamanApi.md#shaman_checkout) | **POST** /shaman/checkout/create | Create a directory, and symlink the required files into it. The files must all have been uploaded to Shaman before calling this endpoint.
|
*ShamanApi* | [**shaman_checkout**](flamenco/manager/docs/ShamanApi.md#shaman_checkout) | **POST** /shaman/checkout/create | Create a directory, and symlink the required files into it. The files must all have been uploaded to Shaman before calling this endpoint.
|
||||||
*ShamanApi* | [**shaman_checkout_requirements**](flamenco/manager/docs/ShamanApi.md#shaman_checkout_requirements) | **POST** /shaman/checkout/requirements | Checks a Shaman Requirements file, and reports which files are unknown.
|
*ShamanApi* | [**shaman_checkout_requirements**](flamenco/manager/docs/ShamanApi.md#shaman_checkout_requirements) | **POST** /shaman/checkout/requirements | Checks a Shaman Requirements file, and reports which files are unknown.
|
||||||
@ -97,6 +98,7 @@ Class | Method | HTTP request | Description
|
|||||||
- [JobMetadata](flamenco/manager/docs/JobMetadata.md)
|
- [JobMetadata](flamenco/manager/docs/JobMetadata.md)
|
||||||
- [JobSettings](flamenco/manager/docs/JobSettings.md)
|
- [JobSettings](flamenco/manager/docs/JobSettings.md)
|
||||||
- [JobStatus](flamenco/manager/docs/JobStatus.md)
|
- [JobStatus](flamenco/manager/docs/JobStatus.md)
|
||||||
|
- [ManagerConfiguration](flamenco/manager/docs/ManagerConfiguration.md)
|
||||||
- [RegisteredWorker](flamenco/manager/docs/RegisteredWorker.md)
|
- [RegisteredWorker](flamenco/manager/docs/RegisteredWorker.md)
|
||||||
- [SecurityError](flamenco/manager/docs/SecurityError.md)
|
- [SecurityError](flamenco/manager/docs/SecurityError.md)
|
||||||
- [ShamanCheckout](flamenco/manager/docs/ShamanCheckout.md)
|
- [ShamanCheckout](flamenco/manager/docs/ShamanCheckout.md)
|
||||||
|
@ -2,18 +2,19 @@
|
|||||||
# <pep8 compliant>
|
# <pep8 compliant>
|
||||||
|
|
||||||
import datetime
|
import datetime
|
||||||
|
import functools
|
||||||
import logging
|
import logging
|
||||||
from pathlib import Path
|
from pathlib import Path, PurePosixPath
|
||||||
from typing import Optional, TYPE_CHECKING
|
from typing import Optional, TYPE_CHECKING
|
||||||
from urllib3.exceptions import HTTPError, MaxRetryError
|
from urllib3.exceptions import HTTPError, MaxRetryError
|
||||||
|
|
||||||
import bpy
|
import bpy
|
||||||
|
|
||||||
from . import job_types, job_submission
|
from . import job_types, job_submission, preferences
|
||||||
from .job_types_propgroup import JobTypePropertyGroup
|
from .job_types_propgroup import JobTypePropertyGroup
|
||||||
|
|
||||||
if TYPE_CHECKING:
|
if TYPE_CHECKING:
|
||||||
from .bat_interface import (
|
from .bat.interface import (
|
||||||
PackThread as _PackThread,
|
PackThread as _PackThread,
|
||||||
Message as _Message,
|
Message as _Message,
|
||||||
)
|
)
|
||||||
@ -50,7 +51,6 @@ class FLAMENCO_OT_fetch_job_types(FlamencoOpMixin, bpy.types.Operator):
|
|||||||
api_client = self.get_api_client(context)
|
api_client = self.get_api_client(context)
|
||||||
|
|
||||||
from flamenco.manager import ApiException
|
from flamenco.manager import ApiException
|
||||||
from . import job_types
|
|
||||||
|
|
||||||
scene = context.scene
|
scene = context.scene
|
||||||
old_job_type_name = getattr(scene, "flamenco_job_type", "")
|
old_job_type_name = getattr(scene, "flamenco_job_type", "")
|
||||||
@ -85,13 +85,14 @@ class FLAMENCO_OT_ping_manager(FlamencoOpMixin, bpy.types.Operator):
|
|||||||
|
|
||||||
from flamenco.manager import ApiException
|
from flamenco.manager import ApiException
|
||||||
from flamenco.manager.apis import MetaApi
|
from flamenco.manager.apis import MetaApi
|
||||||
from flamenco.manager.models import FlamencoVersion
|
from flamenco.manager.models import FlamencoVersion, ManagerConfiguration
|
||||||
|
|
||||||
context.window_manager.flamenco_status_ping = "..."
|
context.window_manager.flamenco_status_ping = "..."
|
||||||
|
|
||||||
meta_api = MetaApi(api_client)
|
meta_api = MetaApi(api_client)
|
||||||
try:
|
try:
|
||||||
response: FlamencoVersion = meta_api.get_version()
|
version: FlamencoVersion = meta_api.get_version()
|
||||||
|
config: ManagerConfiguration = meta_api.get_configuration()
|
||||||
except ApiException as ex:
|
except ApiException as ex:
|
||||||
report = "Manager cannot be reached: %s" % ex
|
report = "Manager cannot be reached: %s" % ex
|
||||||
level = "ERROR"
|
level = "ERROR"
|
||||||
@ -104,9 +105,13 @@ class FLAMENCO_OT_ping_manager(FlamencoOpMixin, bpy.types.Operator):
|
|||||||
report = "Manager cannot be reached: %s" % ex
|
report = "Manager cannot be reached: %s" % ex
|
||||||
level = "ERROR"
|
level = "ERROR"
|
||||||
else:
|
else:
|
||||||
report = "%s version %s found" % (response.name, response.version)
|
report = "%s version %s found" % (version.name, version.version)
|
||||||
level = "INFO"
|
level = "INFO"
|
||||||
|
|
||||||
|
# Store whether this Manager supports the Shaman API.
|
||||||
|
prefs = preferences.get(context)
|
||||||
|
prefs.is_shaman_enabled = config.shaman_enabled
|
||||||
|
|
||||||
self.report({level}, report)
|
self.report({level}, report)
|
||||||
context.window_manager.flamenco_status_ping = report
|
context.window_manager.flamenco_status_ping = report
|
||||||
return {"FINISHED"}
|
return {"FINISHED"}
|
||||||
@ -138,7 +143,7 @@ class FLAMENCO_OT_submit_job(FlamencoOpMixin, bpy.types.Operator):
|
|||||||
bl_description = "Pack the current blend file and send it to Flamenco"
|
bl_description = "Pack the current blend file and send it to Flamenco"
|
||||||
bl_options = {"REGISTER"} # No UNDO.
|
bl_options = {"REGISTER"} # No UNDO.
|
||||||
|
|
||||||
blendfile_on_farm: Optional[Path] = None
|
blendfile_on_farm: Optional[PurePosixPath] = None
|
||||||
job_name: bpy.props.StringProperty(name="Job Name") # type: ignore
|
job_name: bpy.props.StringProperty(name="Job Name") # type: ignore
|
||||||
job: Optional[_SubmittedJob] = None
|
job: Optional[_SubmittedJob] = None
|
||||||
|
|
||||||
@ -211,13 +216,36 @@ class FLAMENCO_OT_submit_job(FlamencoOpMixin, bpy.types.Operator):
|
|||||||
return filepath
|
return filepath
|
||||||
|
|
||||||
def _bat_pack(self, context: bpy.types.Context, blendfile: Path) -> set[str]:
|
def _bat_pack(self, context: bpy.types.Context, blendfile: Path) -> set[str]:
|
||||||
from . import bat_interface
|
from .bat import interface as bat_interface
|
||||||
|
|
||||||
if bat_interface.is_packing():
|
if bat_interface.is_packing():
|
||||||
self.report({"ERROR"}, "Another packing operation is running")
|
self.report({"ERROR"}, "Another packing operation is running")
|
||||||
self._quit(context)
|
self._quit(context)
|
||||||
return {"CANCELLED"}
|
return {"CANCELLED"}
|
||||||
|
|
||||||
|
prefs = preferences.get(context)
|
||||||
|
if prefs.is_shaman_enabled:
|
||||||
|
blendfile_on_farm = self._bat_pack_shaman(context, blendfile)
|
||||||
|
else:
|
||||||
|
blendfile_on_farm = self._bat_pack_filesystem(context, blendfile)
|
||||||
|
|
||||||
|
self.blendfile_on_farm = blendfile_on_farm
|
||||||
|
|
||||||
|
context.window_manager.modal_handler_add(self)
|
||||||
|
wm = context.window_manager
|
||||||
|
self.timer = wm.event_timer_add(0.25, window=context.window)
|
||||||
|
|
||||||
|
return {"RUNNING_MODAL"}
|
||||||
|
|
||||||
|
def _bat_pack_filesystem(
|
||||||
|
self, context: bpy.types.Context, blendfile: Path
|
||||||
|
) -> PurePosixPath:
|
||||||
|
"""Use BAT to store the pack on the filesystem.
|
||||||
|
|
||||||
|
:return: the path of the blend file, for use in the job definition.
|
||||||
|
"""
|
||||||
|
from .bat import interface as bat_interface
|
||||||
|
|
||||||
# TODO: get project path from addon preferences / project definition on Manager.
|
# TODO: get project path from addon preferences / project definition on Manager.
|
||||||
project_path = blendfile.parent
|
project_path = blendfile.parent
|
||||||
try:
|
try:
|
||||||
@ -225,7 +253,7 @@ class FLAMENCO_OT_submit_job(FlamencoOpMixin, bpy.types.Operator):
|
|||||||
except FileNotFoundError:
|
except FileNotFoundError:
|
||||||
# Path.resolve() will raise a FileNotFoundError if the project path doesn't exist.
|
# Path.resolve() will raise a FileNotFoundError if the project path doesn't exist.
|
||||||
self.report({"ERROR"}, "Project path %s does not exist" % project_path)
|
self.report({"ERROR"}, "Project path %s does not exist" % project_path)
|
||||||
return {"CANCELLED"}
|
raise # TODO: handle this properly.
|
||||||
|
|
||||||
# Determine where the blend file will be stored.
|
# Determine where the blend file will be stored.
|
||||||
unique_dir = "%s-%s" % (
|
unique_dir = "%s-%s" % (
|
||||||
@ -237,7 +265,6 @@ class FLAMENCO_OT_submit_job(FlamencoOpMixin, bpy.types.Operator):
|
|||||||
# TODO: this should take the blendfile location relative to the project path into account.
|
# TODO: this should take the blendfile location relative to the project path into account.
|
||||||
pack_target_file = pack_target_dir / blendfile.name
|
pack_target_file = pack_target_dir / blendfile.name
|
||||||
self.log.info("Will store blend file at %s", pack_target_file)
|
self.log.info("Will store blend file at %s", pack_target_file)
|
||||||
self.blendfile_on_farm = pack_target_file
|
|
||||||
|
|
||||||
self.packthread = bat_interface.copy(
|
self.packthread = bat_interface.copy(
|
||||||
base_blendfile=blendfile,
|
base_blendfile=blendfile,
|
||||||
@ -247,14 +274,44 @@ class FLAMENCO_OT_submit_job(FlamencoOpMixin, bpy.types.Operator):
|
|||||||
relative_only=True, # TODO: get from GUI.
|
relative_only=True, # TODO: get from GUI.
|
||||||
)
|
)
|
||||||
|
|
||||||
context.window_manager.modal_handler_add(self)
|
return PurePosixPath(pack_target_file.as_posix())
|
||||||
wm = context.window_manager
|
|
||||||
self.timer = wm.event_timer_add(0.25, window=context.window)
|
|
||||||
|
|
||||||
return {"RUNNING_MODAL"}
|
def _bat_pack_shaman(
|
||||||
|
self, context: bpy.types.Context, blendfile: Path
|
||||||
|
) -> PurePosixPath:
|
||||||
|
"""Use the Manager's Shaman API to submit the BAT pack.
|
||||||
|
|
||||||
|
:return: the filesystem path of the blend file, for in the render job definition.
|
||||||
|
"""
|
||||||
|
from .bat import (
|
||||||
|
interface as bat_interface,
|
||||||
|
shaman as bat_shaman,
|
||||||
|
)
|
||||||
|
|
||||||
|
assert self.job is not None
|
||||||
|
self.log.info("Sending BAT pack to Shaman")
|
||||||
|
|
||||||
|
# TODO: get project name from preferences/GUI.
|
||||||
|
# TODO: update Shaman API to ensure this is a unique location.
|
||||||
|
checkout_root = PurePosixPath(f"project/{self.job.name}")
|
||||||
|
|
||||||
|
self.packthread = bat_interface.copy(
|
||||||
|
base_blendfile=blendfile,
|
||||||
|
project=blendfile.parent, # TODO: get from preferences/GUI.
|
||||||
|
target="/", # Target directory irrelevant for Shaman transfers.
|
||||||
|
exclusion_filter="", # TODO: get from GUI.
|
||||||
|
relative_only=True, # TODO: get from GUI.
|
||||||
|
packer_class=functools.partial(
|
||||||
|
bat_shaman.Packer,
|
||||||
|
api_client=self.get_api_client(context),
|
||||||
|
checkout_path=checkout_root,
|
||||||
|
),
|
||||||
|
)
|
||||||
|
|
||||||
|
return checkout_root / blendfile.name # TODO: get relative to the checkout dir.
|
||||||
|
|
||||||
def _on_bat_pack_msg(self, context: bpy.types.Context, msg: _Message) -> set[str]:
|
def _on_bat_pack_msg(self, context: bpy.types.Context, msg: _Message) -> set[str]:
|
||||||
from . import bat_interface
|
from .bat import interface as bat_interface
|
||||||
|
|
||||||
if isinstance(msg, bat_interface.MsgDone):
|
if isinstance(msg, bat_interface.MsgDone):
|
||||||
self._submit_job(context)
|
self._submit_job(context)
|
||||||
|
@ -9,6 +9,7 @@ def discard_flamenco_client(prefs, context):
|
|||||||
from . import comms
|
from . import comms
|
||||||
|
|
||||||
comms.discard_flamenco_data()
|
comms.discard_flamenco_data()
|
||||||
|
context.window_manager.flamenco_status_ping = ""
|
||||||
|
|
||||||
|
|
||||||
def _update_default_job_storage(
|
def _update_default_job_storage(
|
||||||
@ -28,6 +29,12 @@ class FlamencoPreferences(bpy.types.AddonPreferences):
|
|||||||
update=discard_flamenco_client,
|
update=discard_flamenco_client,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
is_shaman_enabled: bpy.props.BoolProperty( # type: ignore
|
||||||
|
name="Shaman Enabled",
|
||||||
|
description="Whether this Manager has the Shaman protocol enabled",
|
||||||
|
default=False,
|
||||||
|
)
|
||||||
|
|
||||||
job_storage: bpy.props.StringProperty( # type: ignore
|
job_storage: bpy.props.StringProperty( # type: ignore
|
||||||
name="Job Storage Directory",
|
name="Job Storage Directory",
|
||||||
subtype="DIR_PATH",
|
subtype="DIR_PATH",
|
||||||
@ -48,6 +55,12 @@ class FlamencoPreferences(bpy.types.AddonPreferences):
|
|||||||
if context.window_manager.flamenco_status_ping:
|
if context.window_manager.flamenco_status_ping:
|
||||||
col.label(text=context.window_manager.flamenco_status_ping)
|
col.label(text=context.window_manager.flamenco_status_ping)
|
||||||
|
|
||||||
|
col = layout.column(align=True)
|
||||||
|
col.enabled = not self.is_shaman_enabled
|
||||||
|
if self.is_shaman_enabled:
|
||||||
|
col.label(
|
||||||
|
text="This Manager supports the Shaman API, so this setting will be ignored:"
|
||||||
|
)
|
||||||
col.prop(self, "job_storage")
|
col.prop(self, "job_storage")
|
||||||
|
|
||||||
|
|
||||||
@ -88,6 +101,7 @@ _register, _unregister = bpy.utils.register_classes_factory(classes)
|
|||||||
def register():
|
def register():
|
||||||
_register()
|
_register()
|
||||||
_register_rna_props(get(bpy.context))
|
_register_rna_props(get(bpy.context))
|
||||||
|
bpy.context.window_manager.flamenco_status_ping = ""
|
||||||
|
|
||||||
|
|
||||||
def unregister():
|
def unregister():
|
||||||
|
@ -7,9 +7,7 @@ import (
|
|||||||
"context"
|
"context"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
"net/http"
|
|
||||||
|
|
||||||
"git.blender.org/flamenco/internal/appinfo"
|
|
||||||
"git.blender.org/flamenco/internal/manager/job_compilers"
|
"git.blender.org/flamenco/internal/manager/job_compilers"
|
||||||
"git.blender.org/flamenco/internal/manager/persistence"
|
"git.blender.org/flamenco/internal/manager/persistence"
|
||||||
"git.blender.org/flamenco/internal/manager/task_state_machine"
|
"git.blender.org/flamenco/internal/manager/task_state_machine"
|
||||||
@ -136,10 +134,3 @@ func sendAPIError(e echo.Context, code int, message string, args ...interface{})
|
|||||||
}
|
}
|
||||||
return e.JSON(code, petErr)
|
return e.JSON(code, petErr)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (f *Flamenco) GetVersion(e echo.Context) error {
|
|
||||||
return e.JSON(http.StatusOK, api.FlamencoVersion{
|
|
||||||
Version: appinfo.ApplicationVersion,
|
|
||||||
Name: appinfo.ApplicationName,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
25
internal/manager/api_impl/meta.go
Normal file
25
internal/manager/api_impl/meta.go
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
// Package api_impl implements the OpenAPI API from pkg/api/flamenco-manager.yaml.
|
||||||
|
package api_impl
|
||||||
|
|
||||||
|
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
|
|
||||||
|
import (
|
||||||
|
"net/http"
|
||||||
|
|
||||||
|
"git.blender.org/flamenco/internal/appinfo"
|
||||||
|
"git.blender.org/flamenco/pkg/api"
|
||||||
|
"github.com/labstack/echo/v4"
|
||||||
|
)
|
||||||
|
|
||||||
|
func (f *Flamenco) GetVersion(e echo.Context) error {
|
||||||
|
return e.JSON(http.StatusOK, api.FlamencoVersion{
|
||||||
|
Version: appinfo.ApplicationVersion,
|
||||||
|
Name: appinfo.ApplicationName,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func (f *Flamenco) GetConfiguration(e echo.Context) error {
|
||||||
|
return e.JSON(http.StatusOK, api.ManagerConfiguration{
|
||||||
|
ShamanEnabled: f.isShamanEnabled(),
|
||||||
|
})
|
||||||
|
}
|
@ -56,6 +56,26 @@ func (mr *MockFlamencoClientMockRecorder) FetchJobWithResponse(arg0, arg1 interf
|
|||||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "FetchJobWithResponse", reflect.TypeOf((*MockFlamencoClient)(nil).FetchJobWithResponse), varargs...)
|
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "FetchJobWithResponse", reflect.TypeOf((*MockFlamencoClient)(nil).FetchJobWithResponse), varargs...)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// GetConfigurationWithResponse mocks base method.
|
||||||
|
func (m *MockFlamencoClient) GetConfigurationWithResponse(arg0 context.Context, arg1 ...api.RequestEditorFn) (*api.GetConfigurationResponse, error) {
|
||||||
|
m.ctrl.T.Helper()
|
||||||
|
varargs := []interface{}{arg0}
|
||||||
|
for _, a := range arg1 {
|
||||||
|
varargs = append(varargs, a)
|
||||||
|
}
|
||||||
|
ret := m.ctrl.Call(m, "GetConfigurationWithResponse", varargs...)
|
||||||
|
ret0, _ := ret[0].(*api.GetConfigurationResponse)
|
||||||
|
ret1, _ := ret[1].(error)
|
||||||
|
return ret0, ret1
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetConfigurationWithResponse indicates an expected call of GetConfigurationWithResponse.
|
||||||
|
func (mr *MockFlamencoClientMockRecorder) GetConfigurationWithResponse(arg0 interface{}, arg1 ...interface{}) *gomock.Call {
|
||||||
|
mr.mock.ctrl.T.Helper()
|
||||||
|
varargs := append([]interface{}{arg0}, arg1...)
|
||||||
|
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetConfigurationWithResponse", reflect.TypeOf((*MockFlamencoClient)(nil).GetConfigurationWithResponse), varargs...)
|
||||||
|
}
|
||||||
|
|
||||||
// GetJobTypesWithResponse mocks base method.
|
// GetJobTypesWithResponse mocks base method.
|
||||||
func (m *MockFlamencoClient) GetJobTypesWithResponse(arg0 context.Context, arg1 ...api.RequestEditorFn) (*api.GetJobTypesResponse, error) {
|
func (m *MockFlamencoClient) GetJobTypesWithResponse(arg0 context.Context, arg1 ...api.RequestEditorFn) (*api.GetJobTypesResponse, error) {
|
||||||
m.ctrl.T.Helper()
|
m.ctrl.T.Helper()
|
||||||
|
@ -13,7 +13,7 @@ servers:
|
|||||||
- url: /
|
- url: /
|
||||||
paths:
|
paths:
|
||||||
/api/version:
|
/api/version:
|
||||||
summary: Workers can use this to check this is actually a Flamenco server.
|
summary: Clients can use this to check this is actually a Flamenco server.
|
||||||
get:
|
get:
|
||||||
summary: Get the Flamenco version of this Manager
|
summary: Get the Flamenco version of this Manager
|
||||||
operationId: getVersion
|
operationId: getVersion
|
||||||
@ -26,6 +26,19 @@ paths:
|
|||||||
schema:
|
schema:
|
||||||
$ref: "#/components/schemas/FlamencoVersion"
|
$ref: "#/components/schemas/FlamencoVersion"
|
||||||
|
|
||||||
|
/api/configuration:
|
||||||
|
summary: Endpoint for getting configuration of Flamenco Manager.
|
||||||
|
get:
|
||||||
|
summary: Get the configuration of this Manager.
|
||||||
|
operationId: getConfiguration
|
||||||
|
tags: [meta]
|
||||||
|
responses:
|
||||||
|
"200":
|
||||||
|
description: normal response
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema: {$ref: "#/components/schemas/ManagerConfiguration"}
|
||||||
|
|
||||||
/api/worker/register-worker:
|
/api/worker/register-worker:
|
||||||
summary: Registration of new workers
|
summary: Registration of new workers
|
||||||
post:
|
post:
|
||||||
@ -437,6 +450,14 @@ components:
|
|||||||
version: { type: string }
|
version: { type: string }
|
||||||
name: { type: string }
|
name: { type: string }
|
||||||
|
|
||||||
|
ManagerConfiguration:
|
||||||
|
type: object
|
||||||
|
properties:
|
||||||
|
"shamanEnabled":
|
||||||
|
description: Whether the Shaman file transfer API is available.
|
||||||
|
type: boolean
|
||||||
|
required: [shamanEnabled]
|
||||||
|
|
||||||
WorkerRegistration:
|
WorkerRegistration:
|
||||||
type: object
|
type: object
|
||||||
required: [secret, platform, supported_task_types, nickname]
|
required: [secret, platform, supported_task_types, nickname]
|
||||||
|
@ -90,6 +90,9 @@ func WithRequestEditorFn(fn RequestEditorFn) ClientOption {
|
|||||||
|
|
||||||
// The interface specification for the client above.
|
// The interface specification for the client above.
|
||||||
type ClientInterface interface {
|
type ClientInterface interface {
|
||||||
|
// GetConfiguration request
|
||||||
|
GetConfiguration(ctx context.Context, reqEditors ...RequestEditorFn) (*http.Response, error)
|
||||||
|
|
||||||
// SubmitJob request with any body
|
// SubmitJob request with any body
|
||||||
SubmitJobWithBody(ctx context.Context, contentType string, body io.Reader, reqEditors ...RequestEditorFn) (*http.Response, error)
|
SubmitJobWithBody(ctx context.Context, contentType string, body io.Reader, reqEditors ...RequestEditorFn) (*http.Response, error)
|
||||||
|
|
||||||
@ -150,6 +153,18 @@ type ClientInterface interface {
|
|||||||
ShamanFileStoreWithBody(ctx context.Context, checksum string, filesize int, params *ShamanFileStoreParams, contentType string, body io.Reader, reqEditors ...RequestEditorFn) (*http.Response, error)
|
ShamanFileStoreWithBody(ctx context.Context, checksum string, filesize int, params *ShamanFileStoreParams, contentType string, body io.Reader, reqEditors ...RequestEditorFn) (*http.Response, error)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (c *Client) GetConfiguration(ctx context.Context, reqEditors ...RequestEditorFn) (*http.Response, error) {
|
||||||
|
req, err := NewGetConfigurationRequest(c.Server)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
req = req.WithContext(ctx)
|
||||||
|
if err := c.applyEditors(ctx, req, reqEditors); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return c.Client.Do(req)
|
||||||
|
}
|
||||||
|
|
||||||
func (c *Client) SubmitJobWithBody(ctx context.Context, contentType string, body io.Reader, reqEditors ...RequestEditorFn) (*http.Response, error) {
|
func (c *Client) SubmitJobWithBody(ctx context.Context, contentType string, body io.Reader, reqEditors ...RequestEditorFn) (*http.Response, error) {
|
||||||
req, err := NewSubmitJobRequestWithBody(c.Server, contentType, body)
|
req, err := NewSubmitJobRequestWithBody(c.Server, contentType, body)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -414,6 +429,33 @@ func (c *Client) ShamanFileStoreWithBody(ctx context.Context, checksum string, f
|
|||||||
return c.Client.Do(req)
|
return c.Client.Do(req)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// NewGetConfigurationRequest generates requests for GetConfiguration
|
||||||
|
func NewGetConfigurationRequest(server string) (*http.Request, error) {
|
||||||
|
var err error
|
||||||
|
|
||||||
|
serverURL, err := url.Parse(server)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
operationPath := fmt.Sprintf("/api/configuration")
|
||||||
|
if operationPath[0] == '/' {
|
||||||
|
operationPath = "." + operationPath
|
||||||
|
}
|
||||||
|
|
||||||
|
queryURL, err := serverURL.Parse(operationPath)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
req, err := http.NewRequest("GET", queryURL.String(), nil)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return req, nil
|
||||||
|
}
|
||||||
|
|
||||||
// NewSubmitJobRequest calls the generic SubmitJob builder with application/json body
|
// NewSubmitJobRequest calls the generic SubmitJob builder with application/json body
|
||||||
func NewSubmitJobRequest(server string, body SubmitJobJSONRequestBody) (*http.Request, error) {
|
func NewSubmitJobRequest(server string, body SubmitJobJSONRequestBody) (*http.Request, error) {
|
||||||
var bodyReader io.Reader
|
var bodyReader io.Reader
|
||||||
@ -1019,6 +1061,9 @@ func WithBaseURL(baseURL string) ClientOption {
|
|||||||
|
|
||||||
// ClientWithResponsesInterface is the interface specification for the client with responses above.
|
// ClientWithResponsesInterface is the interface specification for the client with responses above.
|
||||||
type ClientWithResponsesInterface interface {
|
type ClientWithResponsesInterface interface {
|
||||||
|
// GetConfiguration request
|
||||||
|
GetConfigurationWithResponse(ctx context.Context, reqEditors ...RequestEditorFn) (*GetConfigurationResponse, error)
|
||||||
|
|
||||||
// SubmitJob request with any body
|
// SubmitJob request with any body
|
||||||
SubmitJobWithBodyWithResponse(ctx context.Context, contentType string, body io.Reader, reqEditors ...RequestEditorFn) (*SubmitJobResponse, error)
|
SubmitJobWithBodyWithResponse(ctx context.Context, contentType string, body io.Reader, reqEditors ...RequestEditorFn) (*SubmitJobResponse, error)
|
||||||
|
|
||||||
@ -1079,6 +1124,28 @@ type ClientWithResponsesInterface interface {
|
|||||||
ShamanFileStoreWithBodyWithResponse(ctx context.Context, checksum string, filesize int, params *ShamanFileStoreParams, contentType string, body io.Reader, reqEditors ...RequestEditorFn) (*ShamanFileStoreResponse, error)
|
ShamanFileStoreWithBodyWithResponse(ctx context.Context, checksum string, filesize int, params *ShamanFileStoreParams, contentType string, body io.Reader, reqEditors ...RequestEditorFn) (*ShamanFileStoreResponse, error)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type GetConfigurationResponse struct {
|
||||||
|
Body []byte
|
||||||
|
HTTPResponse *http.Response
|
||||||
|
JSON200 *ManagerConfiguration
|
||||||
|
}
|
||||||
|
|
||||||
|
// Status returns HTTPResponse.Status
|
||||||
|
func (r GetConfigurationResponse) Status() string {
|
||||||
|
if r.HTTPResponse != nil {
|
||||||
|
return r.HTTPResponse.Status
|
||||||
|
}
|
||||||
|
return http.StatusText(0)
|
||||||
|
}
|
||||||
|
|
||||||
|
// StatusCode returns HTTPResponse.StatusCode
|
||||||
|
func (r GetConfigurationResponse) StatusCode() int {
|
||||||
|
if r.HTTPResponse != nil {
|
||||||
|
return r.HTTPResponse.StatusCode
|
||||||
|
}
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
type SubmitJobResponse struct {
|
type SubmitJobResponse struct {
|
||||||
Body []byte
|
Body []byte
|
||||||
HTTPResponse *http.Response
|
HTTPResponse *http.Response
|
||||||
@ -1419,6 +1486,15 @@ func (r ShamanFileStoreResponse) StatusCode() int {
|
|||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// GetConfigurationWithResponse request returning *GetConfigurationResponse
|
||||||
|
func (c *ClientWithResponses) GetConfigurationWithResponse(ctx context.Context, reqEditors ...RequestEditorFn) (*GetConfigurationResponse, error) {
|
||||||
|
rsp, err := c.GetConfiguration(ctx, reqEditors...)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return ParseGetConfigurationResponse(rsp)
|
||||||
|
}
|
||||||
|
|
||||||
// SubmitJobWithBodyWithResponse request with arbitrary body returning *SubmitJobResponse
|
// SubmitJobWithBodyWithResponse request with arbitrary body returning *SubmitJobResponse
|
||||||
func (c *ClientWithResponses) SubmitJobWithBodyWithResponse(ctx context.Context, contentType string, body io.Reader, reqEditors ...RequestEditorFn) (*SubmitJobResponse, error) {
|
func (c *ClientWithResponses) SubmitJobWithBodyWithResponse(ctx context.Context, contentType string, body io.Reader, reqEditors ...RequestEditorFn) (*SubmitJobResponse, error) {
|
||||||
rsp, err := c.SubmitJobWithBody(ctx, contentType, body, reqEditors...)
|
rsp, err := c.SubmitJobWithBody(ctx, contentType, body, reqEditors...)
|
||||||
@ -1610,6 +1686,32 @@ func (c *ClientWithResponses) ShamanFileStoreWithBodyWithResponse(ctx context.Co
|
|||||||
return ParseShamanFileStoreResponse(rsp)
|
return ParseShamanFileStoreResponse(rsp)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ParseGetConfigurationResponse parses an HTTP response from a GetConfigurationWithResponse call
|
||||||
|
func ParseGetConfigurationResponse(rsp *http.Response) (*GetConfigurationResponse, error) {
|
||||||
|
bodyBytes, err := ioutil.ReadAll(rsp.Body)
|
||||||
|
defer func() { _ = rsp.Body.Close() }()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
response := &GetConfigurationResponse{
|
||||||
|
Body: bodyBytes,
|
||||||
|
HTTPResponse: rsp,
|
||||||
|
}
|
||||||
|
|
||||||
|
switch {
|
||||||
|
case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 200:
|
||||||
|
var dest ManagerConfiguration
|
||||||
|
if err := json.Unmarshal(bodyBytes, &dest); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
response.JSON200 = &dest
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
return response, nil
|
||||||
|
}
|
||||||
|
|
||||||
// ParseSubmitJobResponse parses an HTTP response from a SubmitJobWithResponse call
|
// ParseSubmitJobResponse parses an HTTP response from a SubmitJobWithResponse call
|
||||||
func ParseSubmitJobResponse(rsp *http.Response) (*SubmitJobResponse, error) {
|
func ParseSubmitJobResponse(rsp *http.Response) (*SubmitJobResponse, error) {
|
||||||
bodyBytes, err := ioutil.ReadAll(rsp.Body)
|
bodyBytes, err := ioutil.ReadAll(rsp.Body)
|
||||||
|
@ -13,6 +13,9 @@ import (
|
|||||||
|
|
||||||
// ServerInterface represents all server handlers.
|
// ServerInterface represents all server handlers.
|
||||||
type ServerInterface interface {
|
type ServerInterface interface {
|
||||||
|
// Get the configuration of this Manager.
|
||||||
|
// (GET /api/configuration)
|
||||||
|
GetConfiguration(ctx echo.Context) error
|
||||||
// Submit a new job for Flamenco Manager to execute.
|
// Submit a new job for Flamenco Manager to execute.
|
||||||
// (POST /api/jobs)
|
// (POST /api/jobs)
|
||||||
SubmitJob(ctx echo.Context) error
|
SubmitJob(ctx echo.Context) error
|
||||||
@ -66,6 +69,15 @@ type ServerInterfaceWrapper struct {
|
|||||||
Handler ServerInterface
|
Handler ServerInterface
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// GetConfiguration converts echo context to params.
|
||||||
|
func (w *ServerInterfaceWrapper) GetConfiguration(ctx echo.Context) error {
|
||||||
|
var err error
|
||||||
|
|
||||||
|
// Invoke the callback with all the unmarshalled arguments
|
||||||
|
err = w.Handler.GetConfiguration(ctx)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
// SubmitJob converts echo context to params.
|
// SubmitJob converts echo context to params.
|
||||||
func (w *ServerInterfaceWrapper) SubmitJob(ctx echo.Context) error {
|
func (w *ServerInterfaceWrapper) SubmitJob(ctx echo.Context) error {
|
||||||
var err error
|
var err error
|
||||||
@ -320,6 +332,7 @@ func RegisterHandlersWithBaseURL(router EchoRouter, si ServerInterface, baseURL
|
|||||||
Handler: si,
|
Handler: si,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
router.GET(baseURL+"/api/configuration", wrapper.GetConfiguration)
|
||||||
router.POST(baseURL+"/api/jobs", wrapper.SubmitJob)
|
router.POST(baseURL+"/api/jobs", wrapper.SubmitJob)
|
||||||
router.GET(baseURL+"/api/jobs/types", wrapper.GetJobTypes)
|
router.GET(baseURL+"/api/jobs/types", wrapper.GetJobTypes)
|
||||||
router.GET(baseURL+"/api/jobs/:job_id", wrapper.FetchJob)
|
router.GET(baseURL+"/api/jobs/:job_id", wrapper.FetchJob)
|
||||||
|
@ -18,92 +18,93 @@ import (
|
|||||||
// Base64 encoded, gzipped, json marshaled Swagger object
|
// Base64 encoded, gzipped, json marshaled Swagger object
|
||||||
var swaggerSpec = []string{
|
var swaggerSpec = []string{
|
||||||
|
|
||||||
"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",
|
||||||
"3by5+Z8AAAD//+uKmtshVAAA",
|
"Jp09c8M2Q9P7UqZN39QVcH6pQTHQo2DUbrQ2uTTpzXfpCNCjk+P+sF/YNpNlWQt/g8Oa9OGsaAve158i",
|
||||||
|
"vh7pd3RyPHIbOZHrmO8P5Eos9u9LmbaJrA7ge37dvL35vwAAAP//hZ9HEDhWAAA=",
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetSwagger returns the content of the embedded swagger specification file
|
// GetSwagger returns the content of the embedded swagger specification file
|
||||||
|
@ -225,6 +225,12 @@ type JobSettings struct {
|
|||||||
// JobStatus defines model for JobStatus.
|
// JobStatus defines model for JobStatus.
|
||||||
type JobStatus string
|
type JobStatus string
|
||||||
|
|
||||||
|
// ManagerConfiguration defines model for ManagerConfiguration.
|
||||||
|
type ManagerConfiguration struct {
|
||||||
|
// Whether the Shaman file transfer API is available.
|
||||||
|
ShamanEnabled bool `json:"shamanEnabled"`
|
||||||
|
}
|
||||||
|
|
||||||
// RegisteredWorker defines model for RegisteredWorker.
|
// RegisteredWorker defines model for RegisteredWorker.
|
||||||
type RegisteredWorker struct {
|
type RegisteredWorker struct {
|
||||||
Address string `json:"address"`
|
Address string `json:"address"`
|
||||||
|
Loading…
x
Reference in New Issue
Block a user