WIP: 103268-job-task-progress #104185
@ -4,7 +4,7 @@ This file contains the history of changes to Flamenco. Only changes that might
|
||||
be interesting for users are listed here, such as new features and fixes for
|
||||
bugs in actually-released versions.
|
||||
|
||||
## 3.2 - in development
|
||||
## 3.2 - released 2023-02-21
|
||||
|
||||
- When rendering EXR files, use Blender's preview JPEG files to generate the preview video ([43bc22f10fae](https://developer.blender.org/rF43bc22f10fae0fcaed6a4a3b3ace1be617193e21)).
|
||||
- Fix issue where workers would switch immediately on a state change request, even if it was of the "after task is finished" kind.
|
||||
@ -16,7 +16,10 @@ bugs in actually-released versions.
|
||||
- Increase preview image file size from 10 MB to 25 MB. Even though the Worker can down-scale render output before sending to the Manager as preview, they could still be larger than the limit of 10 MB.
|
||||
- Fix a crash of the Manager when using an invalid frame range (`1 10` for example, instead of `1-10` or `1,10`)
|
||||
- Make it possible to delete jobs. The job and its tasks are removed from Flamenco, including last-rendered images and logs. The input files (i.e. the to-be-rendered blend files and their dependencies) will only be removed if [the Shaman system](https://flamenco.blender.org/usage/shared-storage/shaman/) was used AND if the job was submitted with Flamenco 3.2 or newer.
|
||||
|
||||
- Security updates of some dependencies:
|
||||
- https://pkg.go.dev/vuln/GO-2022-1031
|
||||
- https://pkg.go.dev/vuln/GO-2023-1571
|
||||
- https://pkg.go.dev/vuln/GO-2023-1572
|
||||
|
||||
|
||||
## 3.1 - released 2022-10-18
|
||||
|
4
Makefile
@ -2,8 +2,8 @@ PKG := git.blender.org/flamenco
|
||||
|
||||
# To update the version number in all the relevant places, update the VERSION
|
||||
# variable below and run `make update-version`.
|
||||
VERSION := 3.2-beta
|
||||
RELEASE_CYCLE := beta
|
||||
VERSION := 3.2
|
||||
RELEASE_CYCLE := release
|
||||
|
||||
# _GIT_DESCRIPTION_OR_TAG is either something like '16-123abc' (when we're 16
|
||||
# commits since the last tag) or it's something like `v3.0-beta2` (when exactly
|
||||
|
@ -12,7 +12,7 @@ bl_info = {
|
||||
"doc_url": "https://flamenco.blender.org/",
|
||||
"category": "System",
|
||||
"support": "COMMUNITY",
|
||||
"warning": "This is version 3.2-beta of the add-on, which is not a stable release",
|
||||
"warning": "",
|
||||
}
|
||||
|
||||
from pathlib import Path
|
||||
|
2
addon/flamenco/manager/__init__.py
generated
@ -10,7 +10,7 @@
|
||||
"""
|
||||
|
||||
|
||||
__version__ = "3.2-beta"
|
||||
__version__ = "3.2"
|
||||
|
||||
# import ApiClient
|
||||
from flamenco.manager.api_client import ApiClient
|
||||
|
2
addon/flamenco/manager/api_client.py
generated
@ -76,7 +76,7 @@ class ApiClient(object):
|
||||
self.default_headers[header_name] = header_value
|
||||
self.cookie = cookie
|
||||
# Set default User-Agent.
|
||||
self.user_agent = 'Flamenco/3.2-beta (Blender add-on)'
|
||||
self.user_agent = 'Flamenco/3.2 (Blender add-on)'
|
||||
|
||||
def __enter__(self):
|
||||
return self
|
||||
|
2
addon/flamenco/manager/configuration.py
generated
@ -404,7 +404,7 @@ conf = flamenco.manager.Configuration(
|
||||
"OS: {env}\n"\
|
||||
"Python Version: {pyversion}\n"\
|
||||
"Version of the API: 1.0.0\n"\
|
||||
"SDK Package Version: 3.2-beta".\
|
||||
"SDK Package Version: 3.2".\
|
||||
format(env=sys.platform, pyversion=sys.version)
|
||||
|
||||
def get_host_settings(self):
|
||||
|
2
addon/flamenco/manager_README.md
generated
@ -4,7 +4,7 @@ Render Farm manager API
|
||||
The `flamenco.manager` package is automatically generated by the [OpenAPI Generator](https://openapi-generator.tech) project:
|
||||
|
||||
- API version: 1.0.0
|
||||
- Package version: 3.2-beta
|
||||
- Package version: 3.2
|
||||
- Build package: org.openapitools.codegen.languages.PythonClientCodegen
|
||||
For more information, please visit [https://flamenco.io/](https://flamenco.io/)
|
||||
|
||||
|
8
go.mod
@ -25,8 +25,8 @@ require (
|
||||
github.com/stretchr/testify v1.7.0
|
||||
github.com/ziflex/lecho/v3 v3.1.0
|
||||
golang.org/x/crypto v0.0.0-20211215165025-cf75a172585e
|
||||
golang.org/x/image v0.0.0-20191009234506-e7c1f5e7dbb8
|
||||
golang.org/x/net v0.5.0
|
||||
golang.org/x/image v0.5.0
|
||||
golang.org/x/net v0.7.0
|
||||
gopkg.in/yaml.v2 v2.4.0
|
||||
gorm.io/gorm v1.23.8
|
||||
modernc.org/sqlite v1.17.3
|
||||
@ -52,8 +52,8 @@ require (
|
||||
github.com/valyala/bytebufferpool v1.0.0 // indirect
|
||||
github.com/valyala/fasttemplate v1.2.1 // indirect
|
||||
golang.org/x/mod v0.7.0 // indirect
|
||||
golang.org/x/sys v0.4.0 // indirect
|
||||
golang.org/x/text v0.6.0 // indirect
|
||||
golang.org/x/sys v0.5.0 // indirect
|
||||
golang.org/x/text v0.7.0 // indirect
|
||||
golang.org/x/time v0.0.0-20210220033141-f8bda1e9f3ba // indirect
|
||||
golang.org/x/tools v0.5.1-0.20230117180257-8aba49bb5ea2 // indirect
|
||||
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b // indirect
|
||||
|
23
go.sum
@ -163,6 +163,7 @@ github.com/valyala/fasttemplate v1.2.1/go.mod h1:KHLXt3tVN2HBp8eijSv/kGJopbvo7S+
|
||||
github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
||||
github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k=
|
||||
github.com/yuin/goldmark v1.4.0/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k=
|
||||
github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
|
||||
github.com/ziflex/lecho/v3 v3.1.0 h1:65bSzSc0yw7EEhi44lMnkOI877ZzbE7tGDWfYCQXZwI=
|
||||
github.com/ziflex/lecho/v3 v3.1.0/go.mod h1:dwQ6xCAKmSBHhwZ6XmiAiDptD7iklVkW7xQYGUncX0Q=
|
||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||
@ -175,11 +176,13 @@ golang.org/x/crypto v0.0.0-20210817164053-32db794688a5/go.mod h1:GvvjBRRGRdwPK5y
|
||||
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
|
||||
golang.org/x/crypto v0.0.0-20211215165025-cf75a172585e h1:1SzTfNOXwIS2oWiMF+6qu0OUDKb0dauo6MoDUQyu+yU=
|
||||
golang.org/x/crypto v0.0.0-20211215165025-cf75a172585e/go.mod h1:P+XmwS30IXTQdn5tA2iutPOUgjI07+tq3H3K9MVA1s8=
|
||||
golang.org/x/image v0.0.0-20191009234506-e7c1f5e7dbb8 h1:hVwzHzIUGRjiF7EcUjqNxk3NCfkPxbDKRdnNE1Rpg0U=
|
||||
golang.org/x/image v0.0.0-20191009234506-e7c1f5e7dbb8/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=
|
||||
golang.org/x/image v0.5.0 h1:5JMiNunQeQw++mMOz48/ISeNu3Iweh/JaZU8ZLqHRrI=
|
||||
golang.org/x/image v0.5.0/go.mod h1:FVC7BI/5Ym8R25iw5OLsgshdUBbT1h5jZTpA+mvAdZ4=
|
||||
golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||
golang.org/x/mod v0.4.1/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||
golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
|
||||
golang.org/x/mod v0.7.0 h1:LapD9S96VoQRhi/GrNTqeBJFrUjs5UHCAtTlgwA5oZA=
|
||||
golang.org/x/mod v0.7.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
|
||||
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||
@ -190,12 +193,14 @@ golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v
|
||||
golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM=
|
||||
golang.org/x/net v0.0.0-20210805182204-aaa1db679c0d/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
||||
golang.org/x/net v0.0.0-20210913180222-943fd674d43e/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
||||
golang.org/x/net v0.5.0 h1:GyT4nK/YDHSqa1c4753ouYCDajOYKTja9Xb/OHtgvSw=
|
||||
golang.org/x/net v0.5.0/go.mod h1:DivGGAXEgPSlEBzxGzZI+ZLohi+xUj054jfeKui00ws=
|
||||
golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
|
||||
golang.org/x/net v0.7.0 h1:rJrUqqhjsgNp7KqAIc25s9pZnjU7TUcSY7HcVZjdn1g=
|
||||
golang.org/x/net v0.7.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
|
||||
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
@ -222,17 +227,20 @@ golang.org/x/sys v0.0.0-20211025201205-69cdffdb9359/go.mod h1:oPkhp1MJrh7nUepCBc
|
||||
golang.org/x/sys v0.0.0-20211031064116-611d5d643895/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20211103235746-7861aae1554b/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220405052023-b1e9470b6e64/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.4.0 h1:Zr2JFtRQNX3BCZ8YtxRE9hNJYC8J6I1MVbMg6owUp18=
|
||||
golang.org/x/sys v0.4.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.5.0 h1:MUK/U/4lj1t1oPg0HfuXDN/Z1wv31ZJ/YcPiGccS4DU=
|
||||
golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw=
|
||||
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
|
||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
|
||||
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
|
||||
golang.org/x/text v0.6.0 h1:3XmdazWV+ubf7QgHSTWeykHOci5oeekaGJBLkrkaw4k=
|
||||
golang.org/x/text v0.6.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
|
||||
golang.org/x/text v0.7.0 h1:4BRB4x83lYWy72KwLD/qYDuTu7q9PjSagHvijDw7cLo=
|
||||
golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
|
||||
golang.org/x/time v0.0.0-20201208040808-7e3f01d25324/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||
golang.org/x/time v0.0.0-20210220033141-f8bda1e9f3ba h1:O8mE0/t419eoIwhTFpKVkHiTs/Igowgfkj25AcZrtiE=
|
||||
golang.org/x/time v0.0.0-20210220033141-f8bda1e9f3ba/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||
@ -243,6 +251,7 @@ golang.org/x/tools v0.0.0-20201124115921-2c860bdd6e78/go.mod h1:emZCQorbCU4vsT4f
|
||||
golang.org/x/tools v0.0.0-20210114065538-d78b04bdf963/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
|
||||
golang.org/x/tools v0.1.1/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
|
||||
golang.org/x/tools v0.1.7/go.mod h1:LGqMHiF4EqQNHR1JncWGqT5BVaXmza+X+BDGol+dOxo=
|
||||
golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
|
||||
golang.org/x/tools v0.5.1-0.20230117180257-8aba49bb5ea2 h1:v0FhRDmSCNH/0EurAT6T8KRY4aNuUhz6/WwBMxG+gvQ=
|
||||
golang.org/x/tools v0.5.1-0.20230117180257-8aba49bb5ea2/go.mod h1:N+Kgy78s5I24c24dU8OfWNEotWjutIs8SnJvn5IDq+k=
|
||||
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
|
@ -24,6 +24,7 @@ var ApplicationGitHash = "set-during-build"
|
||||
// that only supports strings.
|
||||
var ReleaseCycle string = "set-during-build"
|
||||
|
||||
const releaseCycleReleaseCandidate = "rc"
|
||||
const releaseCycleRelease = "release"
|
||||
|
||||
// FormattedApplicationInfo returns the application name & version as single string.
|
||||
@ -39,9 +40,10 @@ func UserAgent() string {
|
||||
// ExtendedVersion returns the application version, and includes the Git hash if
|
||||
// this is not a release version. See `IsReleaseVersion`.
|
||||
func ExtendedVersion() string {
|
||||
if ReleaseCycle == releaseCycleRelease {
|
||||
switch ReleaseCycle {
|
||||
case releaseCycleRelease, releaseCycleReleaseCandidate:
|
||||
return ApplicationVersion
|
||||
default:
|
||||
return fmt.Sprintf("%s-%s", ApplicationVersion, ApplicationGitHash)
|
||||
}
|
||||
|
||||
return fmt.Sprintf("%s-%s", ApplicationVersion, ApplicationGitHash)
|
||||
}
|
||||
|
Before Width: | Height: | Size: 9.3 KiB After Width: | Height: | Size: 9.3 KiB |
Before Width: | Height: | Size: 34 KiB After Width: | Height: | Size: 34 KiB |
Before Width: | Height: | Size: 9.4 KiB After Width: | Height: | Size: 9.4 KiB |
Before Width: | Height: | Size: 513 B After Width: | Height: | Size: 513 B |
Before Width: | Height: | Size: 1.1 KiB After Width: | Height: | Size: 1.1 KiB |
Before Width: | Height: | Size: 12 KiB After Width: | Height: | Size: 12 KiB |
Before Width: | Height: | Size: 34 KiB After Width: | Height: | Size: 34 KiB |
8
web/app/public/mkico.sh
Executable file
@ -0,0 +1,8 @@
|
||||
#!/bin/bash
|
||||
|
||||
convert flamenco.png -bordercolor '#00000000' -border 0 \
|
||||
\( -clone 0 -resize 16x16 \) \
|
||||
\( -clone 0 -resize 32x32 \) \
|
||||
\( -clone 0 -resize 48x48 \) \
|
||||
\( -clone 0 -resize 64x64 \) \
|
||||
-delete 0 -colors 256 favicon.ico
|
@ -26,7 +26,7 @@
|
||||
|
||||
<script>
|
||||
import * as API from '@/manager-api';
|
||||
import { apiClient } from '@/stores/api-query-count';
|
||||
import { getAPIClient } from "@/api-client";
|
||||
import { backendURL } from '@/urls';
|
||||
|
||||
import ApiSpinner from '@/components/ApiSpinner.vue'
|
||||
@ -51,7 +51,7 @@ export default {
|
||||
methods: {
|
||||
// TODO: also call this when SocketIO reconnects.
|
||||
fetchManagerInfo() {
|
||||
const metaAPI = new API.MetaApi(apiClient);
|
||||
const metaAPI = new API.MetaApi(getAPIClient());
|
||||
metaAPI.getVersion().then((version) => {
|
||||
this.flamencoName = version.name;
|
||||
this.flamencoVersion = version.version;
|
||||
|
@ -17,7 +17,7 @@ const DEFAULT_FLAMENCO_NAME = "Flamenco";
|
||||
const DEFAULT_FLAMENCO_VERSION = "unknown";
|
||||
import ApiSpinner from '@/components/ApiSpinner.vue'
|
||||
import { MetaApi } from "@/manager-api";
|
||||
import { apiClient } from '@/stores/api-query-count';
|
||||
import { getAPIClient } from "@/api-client";
|
||||
|
||||
export default {
|
||||
name: 'SetupAssistant',
|
||||
@ -35,7 +35,7 @@ export default {
|
||||
methods: {
|
||||
// TODO: also call this when SocketIO reconnects.
|
||||
fetchManagerInfo() {
|
||||
const metaAPI = new MetaApi(apiClient);
|
||||
const metaAPI = new MetaApi(getAPIClient());
|
||||
metaAPI.getVersion().then((version) => {
|
||||
this.flamencoName = version.name;
|
||||
this.flamencoVersion = version.version;
|
||||
|
39
web/app/src/api-client.js
Normal file
@ -0,0 +1,39 @@
|
||||
import { ApiClient } from "@/manager-api";
|
||||
import { CountingApiClient } from "@/stores/api-query-count";
|
||||
import { api as apiURL } from '@/urls'
|
||||
|
||||
/**
|
||||
* Scrub the custom User-Agent header from the API client, for those webbrowsers
|
||||
* who do not want to have it set.
|
||||
*
|
||||
* It's actually scrubbed for all webbrowsers, as those privacy-first
|
||||
* webbrowsers also make it hard to fingerprint which browser you're using (for
|
||||
* good reason).
|
||||
*
|
||||
* @param {ApiClient} apiClient
|
||||
*/
|
||||
export function scrubAPIClient(apiClient) {
|
||||
delete apiClient.defaultHeaders['User-Agent'];
|
||||
}
|
||||
|
||||
/**
|
||||
* @returns {ApiClient} Bare API client that is not connected to the UI in any way.
|
||||
*/
|
||||
export function newBareAPIClient() {
|
||||
const apiClient = new ApiClient(apiURL());
|
||||
scrubAPIClient(apiClient);
|
||||
return apiClient;
|
||||
}
|
||||
|
||||
let apiClient = null;
|
||||
|
||||
/**
|
||||
* @returns {ApiClient} API client that updates the UI to show long-running queries.
|
||||
*/
|
||||
export function getAPIClient() {
|
||||
if (apiClient == null) {
|
||||
apiClient = new CountingApiClient(apiURL());
|
||||
scrubAPIClient(apiClient);
|
||||
}
|
||||
return apiClient;
|
||||
}
|
@ -26,7 +26,7 @@
|
||||
import { ref } from 'vue';
|
||||
|
||||
import { useNotifs } from '@/stores/notifications';
|
||||
import { apiClient } from '@/stores/api-query-count';
|
||||
import { getAPIClient } from "@/api-client";
|
||||
import { JobsApi, JobPriorityChange } from '@/manager-api';
|
||||
|
||||
const props = defineProps({
|
||||
@ -45,7 +45,7 @@ const errorMessage = ref('');
|
||||
// Methods
|
||||
function updateJobPriority() {
|
||||
const jobPriorityChange = new JobPriorityChange(priorityState.value);
|
||||
const jobsAPI = new JobsApi(apiClient);
|
||||
const jobsAPI = new JobsApi(getAPIClient());
|
||||
return jobsAPI.setJobPriority(props.jobId, jobPriorityChange)
|
||||
.then(() => {
|
||||
notifs.add(`Updated job priority to ${priorityState.value}`)
|
||||
|
@ -3,7 +3,7 @@ import { onMounted, onUnmounted } from 'vue'
|
||||
import { TabulatorFull as Tabulator } from 'tabulator-tables';
|
||||
import { useTaskLog } from '@/stores/tasklog'
|
||||
import { useTasks } from '@/stores/tasks'
|
||||
import { apiClient } from '@/stores/api-query-count';
|
||||
import { getAPIClient } from "@/api-client";
|
||||
import { JobsApi } from '@/manager-api';
|
||||
|
||||
const taskLog = useTaskLog();
|
||||
@ -59,7 +59,7 @@ function _fetchLogTail(taskID) {
|
||||
|
||||
if (!taskID) return;
|
||||
|
||||
const jobsAPI = new JobsApi(apiClient);
|
||||
const jobsAPI = new JobsApi(getAPIClient());
|
||||
return jobsAPI.fetchTaskLogTail(taskID)
|
||||
.then((logTail) => {
|
||||
taskLog.addChunk(logTail);
|
||||
|
@ -26,7 +26,7 @@
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { apiClient } from '@/stores/api-query-count';
|
||||
import { getAPIClient } from "@/api-client";
|
||||
import { JobsApi } from '@/manager-api';
|
||||
import LinkWorker from '@/components/LinkWorker.vue';
|
||||
import { watch, onMounted, inject, ref, nextTick } from 'vue'
|
||||
@ -35,7 +35,7 @@ import { watch, onMounted, inject, ref, nextTick } from 'vue'
|
||||
const props = defineProps(['jobID']);
|
||||
const emit = defineEmits(['reshuffled'])
|
||||
|
||||
const jobsApi = new JobsApi(apiClient);
|
||||
const jobsApi = new JobsApi(getAPIClient());
|
||||
const isVisible = inject("isVisible");
|
||||
const isFetching = ref(false);
|
||||
const errorMsg = ref("");
|
||||
|
@ -18,7 +18,7 @@
|
||||
<script>
|
||||
import { useJobs } from '@/stores/jobs';
|
||||
import { useNotifs } from '@/stores/notifications';
|
||||
import { apiClient } from '@/stores/api-query-count';
|
||||
import { getAPIClient } from "@/api-client";
|
||||
import { JobsApi } from '@/manager-api';
|
||||
import { JobDeletionInfo } from '@/manager-api';
|
||||
|
||||
@ -31,7 +31,7 @@ export default {
|
||||
data: () => ({
|
||||
jobs: useJobs(),
|
||||
notifs: useNotifs(),
|
||||
jobsAPI: new JobsApi(apiClient),
|
||||
jobsAPI: new JobsApi(getAPIClient()),
|
||||
|
||||
deleteInfo: null,
|
||||
}),
|
||||
@ -98,7 +98,6 @@ export default {
|
||||
* @param { JobDeletionInfo } deleteInfo
|
||||
*/
|
||||
_showDeleteJobPopup(deleteInfo) {
|
||||
console.log("deleteInfo", deleteInfo);
|
||||
this.deleteInfo = deleteInfo;
|
||||
},
|
||||
|
||||
|
@ -39,7 +39,7 @@
|
||||
<dd class="field-status-label" :class="'status-' + jobData.status">{{ jobData.status }}</dd>
|
||||
|
||||
<dt class="field-type" title="Type">Type</dt>
|
||||
<dd>{{ jobType? jobType.label : jobData.type }}</dd>
|
||||
<dd>{{ jobType ? jobType.label : jobData.type }}</dd>
|
||||
|
||||
<dt class="field-priority" title="Priority">Priority</dt>
|
||||
<dd>
|
||||
@ -76,7 +76,7 @@
|
||||
<script>
|
||||
import * as datetime from "@/datetime";
|
||||
import * as API from '@/manager-api';
|
||||
import { apiClient } from '@/stores/api-query-count';
|
||||
import { getAPIClient } from "@/api-client";
|
||||
import LastRenderedImage from '@/components/jobs/LastRenderedImage.vue'
|
||||
import Blocklist from './Blocklist.vue'
|
||||
import TabItem from '@/components/TabItem.vue'
|
||||
@ -103,7 +103,7 @@ export default {
|
||||
datetime: datetime, // So that the template can access it.
|
||||
copyElementText: copyElementText,
|
||||
simpleSettings: null, // Object with filtered job settings, or null if there is no job.
|
||||
jobsApi: new API.JobsApi(apiClient),
|
||||
jobsApi: new API.JobsApi(getAPIClient()),
|
||||
jobType: null, // API.AvailableJobType object for the current job type.
|
||||
jobTypeSettings: null, // Mapping from setting key to its definition in the job type.
|
||||
showAllSettings: false,
|
||||
|
@ -17,7 +17,7 @@ import { TabulatorFull as Tabulator } from 'tabulator-tables';
|
||||
import * as datetime from "@/datetime";
|
||||
import * as API from '@/manager-api'
|
||||
import { indicator } from '@/statusindicator';
|
||||
import { apiClient } from '@/stores/api-query-count';
|
||||
import { getAPIClient } from "@/api-client";
|
||||
import { useJobs } from '@/stores/jobs';
|
||||
|
||||
import JobActionsBar from '@/components/jobs/JobActionsBar.vue'
|
||||
@ -130,7 +130,7 @@ export default {
|
||||
this.fetchAllJobs();
|
||||
},
|
||||
fetchAllJobs() {
|
||||
const jobsApi = new API.JobsApi(apiClient);
|
||||
const jobsApi = new API.JobsApi(getAPIClient());
|
||||
const jobsQuery = {};
|
||||
this.jobs.isJobless = false;
|
||||
jobsApi.queryJobs(jobsQuery).then(this.onJobsFetched, function (error) {
|
||||
|
@ -9,7 +9,7 @@
|
||||
import { reactive, ref, watch } from 'vue'
|
||||
import { api } from '@/urls';
|
||||
import { JobsApi, JobLastRenderedImageInfo, SocketIOLastRenderedUpdate } from '@/manager-api';
|
||||
import { apiClient } from '@/stores/api-query-count';
|
||||
import { getAPIClient } from "@/api-client";
|
||||
|
||||
const props = defineProps([
|
||||
/* The job UUID to show renders for, or some false-y value if renders from all
|
||||
@ -27,7 +27,7 @@ const cssClasses = reactive({
|
||||
'nothing-rendered-yet': true,
|
||||
})
|
||||
|
||||
const jobsApi = new JobsApi(apiClient);
|
||||
const jobsApi = new JobsApi(getAPIClient());
|
||||
|
||||
/**
|
||||
* Fetches the last-rendered info for the given job, then updates the <img> tag for it.
|
||||
|
@ -73,7 +73,7 @@
|
||||
import * as datetime from "@/datetime";
|
||||
import { JobsApi } from '@/manager-api';
|
||||
import { backendURL } from '@/urls';
|
||||
import { apiClient } from '@/stores/api-query-count';
|
||||
import { getAPIClient } from "@/api-client";
|
||||
import { useNotifs } from "@/stores/notifications";
|
||||
import LinkWorker from '@/components/LinkWorker.vue';
|
||||
import { copyElementText } from '@/clipboard';
|
||||
@ -90,7 +90,7 @@ export default {
|
||||
return {
|
||||
datetime: datetime, // So that the template can access it.
|
||||
copyElementText: copyElementText,
|
||||
jobsApi: new JobsApi(apiClient),
|
||||
jobsApi: new JobsApi(getAPIClient()),
|
||||
notifs: useNotifs(),
|
||||
};
|
||||
},
|
||||
|
@ -17,7 +17,7 @@ import { TabulatorFull as Tabulator } from 'tabulator-tables';
|
||||
import * as datetime from "@/datetime";
|
||||
import * as API from '@/manager-api'
|
||||
import { indicator } from '@/statusindicator';
|
||||
import { apiClient } from '@/stores/api-query-count';
|
||||
import { getAPIClient } from "@/api-client";
|
||||
import { useTasks } from '@/stores/tasks';
|
||||
|
||||
import TaskActionsBar from '@/components/jobs/TaskActionsBar.vue'
|
||||
@ -132,7 +132,7 @@ export default {
|
||||
return;
|
||||
}
|
||||
|
||||
const jobsApi = new API.JobsApi(apiClient);
|
||||
const jobsApi = new API.JobsApi(getAPIClient());
|
||||
jobsApi.fetchJobTasks(this.jobID)
|
||||
.then(this.onTasksFetched, function (error) {
|
||||
// TODO: error handling.
|
||||
|
@ -6,11 +6,7 @@
|
||||
</option>
|
||||
<option v-for="(action, key) in WORKER_ACTIONS" :value="key">{{ action.label }}</option>
|
||||
</select>
|
||||
<button
|
||||
:disabled="!canPerformAction"
|
||||
class="btn"
|
||||
@click.prevent="performWorkerAction"
|
||||
>Apply</button>
|
||||
<button :disabled="!canPerformAction" class="btn" @click.prevent="performWorkerAction">Apply</button>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
@ -18,46 +14,46 @@ import { computed, ref } from 'vue'
|
||||
import { useWorkers } from '@/stores/workers';
|
||||
import { useNotifs } from '@/stores/notifications';
|
||||
import { WorkerMgtApi, WorkerStatusChangeRequest } from '@/manager-api';
|
||||
import { apiClient } from '@/stores/api-query-count';
|
||||
import { getAPIClient } from "@/api-client";
|
||||
|
||||
/* Freeze to prevent Vue.js from creating getters & setters all over this object.
|
||||
* We don't need it to be tracked, as it won't be changed anyway. */
|
||||
const WORKER_ACTIONS = Object.freeze({
|
||||
offline_lazy: {
|
||||
label: 'Shut Down (after task is finished)',
|
||||
icon: '✝',
|
||||
title: 'Shut down the worker after the current task finishes. The worker may automatically restart.',
|
||||
target_status: 'offline',
|
||||
lazy: true,
|
||||
},
|
||||
offline_immediate: {
|
||||
label: 'Shut Down (immediately)',
|
||||
icon: '✝!',
|
||||
title: 'Immediately shut down the worker. It may automatically restart.',
|
||||
target_status: 'offline',
|
||||
lazy: false,
|
||||
},
|
||||
asleep_lazy: {
|
||||
label: 'Send to Sleep (after task is finished)',
|
||||
icon: '😴',
|
||||
title: 'Let the worker sleep after finishing this task.',
|
||||
target_status: 'asleep',
|
||||
lazy: true,
|
||||
},
|
||||
asleep_immediate: {
|
||||
label: 'Send to Sleep (immediately)',
|
||||
icon: '😴!',
|
||||
title: 'Let the worker sleep immediately.',
|
||||
target_status: 'asleep',
|
||||
lazy: false,
|
||||
},
|
||||
wakeup: {
|
||||
label: 'Wake Up',
|
||||
icon: '😃',
|
||||
title: 'Wake the worker up. A sleeping worker can take a minute to respond.',
|
||||
target_status: 'awake',
|
||||
lazy: false,
|
||||
},
|
||||
offline_lazy: {
|
||||
label: 'Shut Down (after task is finished)',
|
||||
icon: '✝',
|
||||
title: 'Shut down the worker after the current task finishes. The worker may automatically restart.',
|
||||
target_status: 'offline',
|
||||
lazy: true,
|
||||
},
|
||||
offline_immediate: {
|
||||
label: 'Shut Down (immediately)',
|
||||
icon: '✝!',
|
||||
title: 'Immediately shut down the worker. It may automatically restart.',
|
||||
target_status: 'offline',
|
||||
lazy: false,
|
||||
},
|
||||
asleep_lazy: {
|
||||
label: 'Send to Sleep (after task is finished)',
|
||||
icon: '😴',
|
||||
title: 'Let the worker sleep after finishing this task.',
|
||||
target_status: 'asleep',
|
||||
lazy: true,
|
||||
},
|
||||
asleep_immediate: {
|
||||
label: 'Send to Sleep (immediately)',
|
||||
icon: '😴!',
|
||||
title: 'Let the worker sleep immediately.',
|
||||
target_status: 'asleep',
|
||||
lazy: false,
|
||||
},
|
||||
wakeup: {
|
||||
label: 'Wake Up',
|
||||
icon: '😃',
|
||||
title: 'Wake the worker up. A sleeping worker can take a minute to respond.',
|
||||
target_status: 'awake',
|
||||
lazy: false,
|
||||
},
|
||||
});
|
||||
|
||||
const selectedAction = ref('');
|
||||
@ -73,7 +69,7 @@ function performWorkerAction() {
|
||||
return;
|
||||
}
|
||||
|
||||
const api = new WorkerMgtApi(apiClient);
|
||||
const api = new WorkerMgtApi(getAPIClient());
|
||||
const action = WORKER_ACTIONS[selectedAction.value];
|
||||
const statuschange = new WorkerStatusChangeRequest(action.target_status, action.lazy);
|
||||
console.log("Requesting worker status change", statuschange);
|
||||
|
@ -123,7 +123,7 @@ import { useNotifs } from '@/stores/notifications'
|
||||
|
||||
import * as datetime from "@/datetime";
|
||||
import { WorkerMgtApi, WorkerSleepSchedule } from '@/manager-api';
|
||||
import { apiClient } from '@/stores/api-query-count';
|
||||
import { getAPIClient } from "@/api-client";
|
||||
import { workerStatus } from "../../statusindicator";
|
||||
import LinkWorkerTask from '@/components/LinkWorkerTask.vue';
|
||||
import SwitchCheckbox from '@/components/SwitchCheckbox.vue';
|
||||
@ -140,7 +140,7 @@ export default {
|
||||
data() {
|
||||
return {
|
||||
datetime: datetime, // So that the template can access it.
|
||||
api: new WorkerMgtApi(apiClient),
|
||||
api: new WorkerMgtApi(getAPIClient()),
|
||||
workerStatusHTML: "",
|
||||
workerSleepSchedule: this.defaultWorkerSleepSchedule(),
|
||||
isScheduleEditing: false,
|
||||
|
@ -19,7 +19,7 @@
|
||||
import { TabulatorFull as Tabulator } from 'tabulator-tables';
|
||||
import { WorkerMgtApi } from '@/manager-api'
|
||||
import { indicator, workerStatus } from '@/statusindicator';
|
||||
import { apiClient } from '@/stores/api-query-count';
|
||||
import { getAPIClient } from "@/api-client";
|
||||
import { useWorkers } from '@/stores/workers';
|
||||
|
||||
import StatusFilterBar from '@/components/StatusFilterBar.vue'
|
||||
@ -117,7 +117,7 @@ export default {
|
||||
this.fetchAllWorkers();
|
||||
},
|
||||
fetchAllWorkers() {
|
||||
const api = new WorkerMgtApi(apiClient);
|
||||
const api = new WorkerMgtApi(getAPIClient());
|
||||
api.fetchWorkers().then(this.onWorkersFetched, function (error) {
|
||||
// TODO: error handling.
|
||||
console.error(error);
|
||||
|
@ -7,7 +7,8 @@ import SetupAssistant from '@/SetupAssistant.vue'
|
||||
import autoreload from '@/autoreloader'
|
||||
import router from '@/router/index'
|
||||
import setupAssistantRouter from '@/router/setup-assistant'
|
||||
import { ApiClient, MetaApi } from "@/manager-api";
|
||||
import { MetaApi } from "@/manager-api";
|
||||
import { newBareAPIClient } from "@/api-client";
|
||||
import * as urls from '@/urls'
|
||||
|
||||
// Ensure Tabulator can find `luxon`, which it needs for sorting by
|
||||
@ -24,7 +25,6 @@ autoreload();
|
||||
const pinia = createPinia()
|
||||
|
||||
function normalMode() {
|
||||
console.log("Flamenco is starting in normal operation mode");
|
||||
const app = createApp(App)
|
||||
app.use(pinia)
|
||||
app.use(router)
|
||||
@ -42,7 +42,7 @@ function setupAssistantMode() {
|
||||
/* This cannot use the client from '@/stores/api-query-count', as that would
|
||||
* require Pinia, which is unavailable until the app is actually started. And to
|
||||
* know which app to start, this API call needs to return data. */
|
||||
const apiClient = new ApiClient(urls.api());;
|
||||
const apiClient = newBareAPIClient();
|
||||
const metaAPI = new MetaApi(apiClient);
|
||||
metaAPI.getConfiguration()
|
||||
.then((config) => {
|
||||
|
2
web/app/src/manager-api/ApiClient.js
generated
@ -55,7 +55,7 @@ class ApiClient {
|
||||
* @default {}
|
||||
*/
|
||||
this.defaultHeaders = {
|
||||
'User-Agent': 'Flamenco/3.2-beta / webbrowser'
|
||||
'User-Agent': 'Flamenco/3.2 / webbrowser'
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -1,6 +1,5 @@
|
||||
import { defineStore } from "pinia";
|
||||
import { ApiClient } from "@/manager-api";
|
||||
import * as urls from '@/urls'
|
||||
|
||||
/**
|
||||
* Keep track of running API queries.
|
||||
@ -42,5 +41,3 @@ export class CountingApiClient extends ApiClient {
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
export const apiClient = new CountingApiClient(urls.api());;
|
||||
|
@ -1,10 +1,10 @@
|
||||
import { defineStore } from 'pinia'
|
||||
|
||||
import * as API from '@/manager-api';
|
||||
import { apiClient } from '@/stores/api-query-count';
|
||||
import { getAPIClient } from "@/api-client";
|
||||
|
||||
|
||||
const jobsAPI = new API.JobsApi(apiClient);
|
||||
const jobsAPI = new API.JobsApi(getAPIClient());
|
||||
|
||||
// 'use' prefix is idiomatic for Pinia stores.
|
||||
// See https://pinia.vuejs.org/core-concepts/
|
||||
|
@ -1,10 +1,10 @@
|
||||
import { defineStore } from 'pinia'
|
||||
|
||||
import * as API from '@/manager-api';
|
||||
import { apiClient } from '@/stores/api-query-count';
|
||||
import { getAPIClient } from "@/api-client";
|
||||
|
||||
|
||||
const jobsAPI = new API.JobsApi(apiClient);
|
||||
const jobsAPI = new API.JobsApi(getAPIClient());
|
||||
|
||||
// 'use' prefix is idiomatic for Pinia stores.
|
||||
// See https://pinia.vuejs.org/core-concepts/
|
||||
|
@ -39,7 +39,7 @@ import { useJobs } from '@/stores/jobs';
|
||||
import { useTasks } from '@/stores/tasks';
|
||||
import { useNotifs } from '@/stores/notifications'
|
||||
import { useTaskLog } from '@/stores/tasklog'
|
||||
import { apiClient } from '@/stores/api-query-count';
|
||||
import { getAPIClient } from "@/api-client";
|
||||
|
||||
import FooterPopup from '@/components/footer/FooterPopup.vue'
|
||||
import GetTheAddon from '@/components/GetTheAddon.vue'
|
||||
@ -127,7 +127,7 @@ export default {
|
||||
return;
|
||||
}
|
||||
|
||||
const jobsAPI = new API.JobsApi(apiClient);
|
||||
const jobsAPI = new API.JobsApi(getAPIClient());
|
||||
jobsAPI.fetchTask(taskSummary.id)
|
||||
.then((task) => {
|
||||
this.tasks.setActiveTask(task);
|
||||
@ -225,7 +225,7 @@ export default {
|
||||
return;
|
||||
}
|
||||
|
||||
const jobsAPI = new API.JobsApi(apiClient);
|
||||
const jobsAPI = new API.JobsApi(getAPIClient());
|
||||
return jobsAPI.fetchJob(jobID)
|
||||
.then((job) => {
|
||||
this.jobs.setActiveJob(job);
|
||||
@ -254,7 +254,7 @@ export default {
|
||||
return;
|
||||
}
|
||||
|
||||
const jobsAPI = new API.JobsApi(apiClient);
|
||||
const jobsAPI = new API.JobsApi(getAPIClient());
|
||||
return jobsAPI.fetchTask(taskID)
|
||||
.then((task) => {
|
||||
this.tasks.setActiveTask(task);
|
||||
|
@ -2,38 +2,28 @@
|
||||
<div class="setup-container">
|
||||
<h1>Flamenco Setup Assistant</h1>
|
||||
<ul class="progress">
|
||||
<li
|
||||
v-for="step in totalSetupSteps" :key="step"
|
||||
@click="jumpToStep(step)"
|
||||
:class="{
|
||||
current: step == currentSetupStep,
|
||||
done: step < overallSetupStep,
|
||||
done_previously: (step < overallSetupStep && currentSetupStep > step),
|
||||
done_and_current: step == currentSetupStep && (step < overallSetupStep || step == 1),
|
||||
disabled: step > overallSetupStep,
|
||||
}"
|
||||
>
|
||||
<li v-for="step in totalSetupSteps" :key="step" @click="jumpToStep(step)" :class="{
|
||||
current: step == currentSetupStep,
|
||||
done: step < overallSetupStep,
|
||||
done_previously: (step < overallSetupStep && currentSetupStep > step),
|
||||
done_and_current: step == currentSetupStep && (step < overallSetupStep || step == 1),
|
||||
disabled: step > overallSetupStep,
|
||||
}">
|
||||
<span></span>
|
||||
</li>
|
||||
<div class="progress-bar"></div>
|
||||
</ul>
|
||||
<div class="setup-step step-welcome">
|
||||
|
||||
<step-item
|
||||
v-show="currentSetupStep == 1"
|
||||
@next-clicked="nextStep"
|
||||
:is-next-clickable="true"
|
||||
:is-back-visible="false"
|
||||
title="Welcome!"
|
||||
next-label="Let's go"
|
||||
>
|
||||
<step-item v-show="currentSetupStep == 1" @next-clicked="nextStep" :is-next-clickable="true"
|
||||
:is-back-visible="false" title="Welcome!" next-label="Let's go">
|
||||
<p>
|
||||
This setup assistant will guide you through the initial configuration of Flamenco. You will be up
|
||||
and running in a few minutes!
|
||||
</p>
|
||||
<p>Before we start, here is a quick overview of the Flamenco architecture.</p>
|
||||
|
||||
<img src="@/assets/architecture.png" alt="Flamenco architecture"/>
|
||||
<img src="@/assets/architecture.png" alt="Flamenco architecture" />
|
||||
|
||||
<p>The illustration shows the key components and how they interact together:</p>
|
||||
<ul>
|
||||
@ -41,26 +31,24 @@
|
||||
<strong>Manager</strong>: This application. It coordinates all the activity.
|
||||
</li>
|
||||
<li>
|
||||
<strong>Worker</strong>: A workstation or dedicated rendering machine. It executes the tasks assigned by the Manager.
|
||||
<strong>Worker</strong>: A workstation or dedicated rendering machine. It executes the tasks assigned by the
|
||||
Manager.
|
||||
</li>
|
||||
<li>
|
||||
<strong>Shared Storage</strong>: A location accessible by the Manager and the Workers, where the files to be rendered should be saved.
|
||||
<strong>Shared Storage</strong>: A location accessible by the Manager and the Workers, where the files to be
|
||||
rendered should be saved.
|
||||
</li>
|
||||
<li>
|
||||
<strong>Blender Add-on</strong>: This is needed to connect to the Manager and submit a job from Blender.
|
||||
</li>
|
||||
</ul>
|
||||
<p>More information is available on the online documentation at
|
||||
<a href="https://flamenco.blender.org">flamenco.blender.org</a>.</p>
|
||||
<a href="https://flamenco.blender.org">flamenco.blender.org</a>.
|
||||
</p>
|
||||
</step-item>
|
||||
|
||||
<step-item
|
||||
v-show="currentSetupStep == 2"
|
||||
@next-clicked="nextStepAfterCheckSharedStoragePath"
|
||||
@back-clicked="prevStep"
|
||||
:is-next-clickable="sharedStoragePath.length > 0"
|
||||
title="Shared Storage"
|
||||
>
|
||||
<step-item v-show="currentSetupStep == 2" @next-clicked="nextStepAfterCheckSharedStoragePath"
|
||||
@back-clicked="prevStep" :is-next-clickable="sharedStoragePath.length > 0" title="Shared Storage">
|
||||
<p>Specify a path (or drive) where you want to store your Flamenco data.</p>
|
||||
<p>
|
||||
The location of the shared storage should be accessible by Flamenco Manager and by the Workers.
|
||||
@ -79,37 +67,26 @@
|
||||
<a href="https://flamenco.blender.org/usage/shared-storage/">Learn more</a>.
|
||||
</p>
|
||||
|
||||
<input
|
||||
v-model="sharedStoragePath"
|
||||
@keyup.enter="nextStepAfterCheckSharedStoragePath"
|
||||
type="text"
|
||||
placeholder="Path to shared storage"
|
||||
:class="{
|
||||
<input v-model="sharedStoragePath" @keyup.enter="nextStepAfterCheckSharedStoragePath" type="text"
|
||||
placeholder="Path to shared storage" :class="{
|
||||
'is-invalid': (sharedStorageCheckResult != null) && !sharedStorageCheckResult.is_usable
|
||||
}"
|
||||
>
|
||||
<p v-if="sharedStorageCheckResult != null"
|
||||
:class="{
|
||||
'check-ok': sharedStorageCheckResult.is_usable,
|
||||
'check-failed': !sharedStorageCheckResult.is_usable
|
||||
}">
|
||||
<p v-if="sharedStorageCheckResult != null" :class="{
|
||||
'check-ok': sharedStorageCheckResult.is_usable,
|
||||
'check-failed': !sharedStorageCheckResult.is_usable
|
||||
}">
|
||||
{{ sharedStorageCheckResult.cause }}
|
||||
</p>
|
||||
</step-item>
|
||||
|
||||
<step-item
|
||||
v-show="currentSetupStep == 3"
|
||||
@next-clicked="nextStepAfterCheckBlenderExePath"
|
||||
@back-clicked="prevStep"
|
||||
:is-next-clickable="selectedBlender != null || customBlenderExe != (null || '')"
|
||||
title="Blender"
|
||||
>
|
||||
<step-item v-show="currentSetupStep == 3" @next-clicked="nextStepAfterCheckBlenderExePath" @back-clicked="prevStep"
|
||||
:is-next-clickable="selectedBlender != null || customBlenderExe != (null || '')" title="Blender">
|
||||
|
||||
<div v-if="isBlenderExeFinding" class="is-in-progress">Looking for Blender installs...</div>
|
||||
|
||||
<p v-if="autoFoundBlenders.length === 0">
|
||||
Provide a path to a Blender executable accessible by all Workers.
|
||||
<br/><br/>
|
||||
<br /><br />
|
||||
If your rendering setup features operating systems different from the one you are currently using,
|
||||
you can manually set up the other paths later.
|
||||
</p>
|
||||
@ -119,23 +96,16 @@
|
||||
<fieldset v-if="autoFoundBlenders.length >= 1">
|
||||
<label v-if="autoFoundBlenderPathEnvvar" for="blender-path_envvar">
|
||||
<div>
|
||||
<input
|
||||
v-model="selectedBlender"
|
||||
:value="autoFoundBlenderPathEnvvar"
|
||||
id="blender-path_envvar"
|
||||
name="blender"
|
||||
<input v-model="selectedBlender" :value="autoFoundBlenderPathEnvvar" id="blender-path_envvar" name="blender"
|
||||
type="radio">
|
||||
{{ sourceLabels[autoFoundBlenderPathEnvvar.source] }}
|
||||
{{ sourceLabels[autoFoundBlenderPathEnvvar.source] }}
|
||||
</div>
|
||||
<div class="setup-path-command">
|
||||
<span class="path">
|
||||
{{autoFoundBlenderPathEnvvar.path}}
|
||||
{{ autoFoundBlenderPathEnvvar.path }}
|
||||
</span>
|
||||
<span
|
||||
aria-label="Console output when running with --version"
|
||||
class="command-preview"
|
||||
data-microtip-position="top"
|
||||
role="tooltip">
|
||||
<span aria-label="Console output when running with --version" class="command-preview"
|
||||
data-microtip-position="top" role="tooltip">
|
||||
{{ autoFoundBlenderPathEnvvar.cause }}
|
||||
</span>
|
||||
</div>
|
||||
@ -143,23 +113,16 @@
|
||||
|
||||
<label v-if="autoFoundBlenderFileAssociation" for="blender-file_association">
|
||||
<div>
|
||||
<input
|
||||
v-model="selectedBlender"
|
||||
:value="autoFoundBlenderFileAssociation"
|
||||
id="blender-file_association"
|
||||
name="blender"
|
||||
type="radio">
|
||||
{{ sourceLabels[autoFoundBlenderFileAssociation.source] }}
|
||||
<input v-model="selectedBlender" :value="autoFoundBlenderFileAssociation" id="blender-file_association"
|
||||
name="blender" type="radio">
|
||||
{{ sourceLabels[autoFoundBlenderFileAssociation.source] }}
|
||||
</div>
|
||||
<div class="setup-path-command">
|
||||
<span class="path">
|
||||
{{autoFoundBlenderFileAssociation.path}}
|
||||
{{ autoFoundBlenderFileAssociation.path }}
|
||||
</span>
|
||||
<span
|
||||
aria-label="Console output when running with --version"
|
||||
class="command-preview"
|
||||
data-microtip-position="top"
|
||||
role="tooltip">
|
||||
<span aria-label="Console output when running with --version" class="command-preview"
|
||||
data-microtip-position="top" role="tooltip">
|
||||
{{ autoFoundBlenderFileAssociation.cause }}
|
||||
</span>
|
||||
</div>
|
||||
@ -167,24 +130,15 @@
|
||||
|
||||
<label for="blender-input_path">
|
||||
<div>
|
||||
<input
|
||||
type="radio"
|
||||
v-model="selectedBlender"
|
||||
name="blender"
|
||||
:value="blenderFromInputPath"
|
||||
id="blender-input_path"
|
||||
>
|
||||
<input type="radio" v-model="selectedBlender" name="blender" :value="blenderFromInputPath"
|
||||
id="blender-input_path">
|
||||
{{ sourceLabels['input_path'] }}
|
||||
</div>
|
||||
<div>
|
||||
<input
|
||||
v-model="customBlenderExe"
|
||||
@keyup.enter="nextStepAfterCheckBlenderExePath"
|
||||
<input v-model="customBlenderExe" @keyup.enter="nextStepAfterCheckBlenderExePath"
|
||||
@focus="selectedBlender = null"
|
||||
:class="{'is-invalid': blenderExeCheckResult != null && !blenderExeCheckResult.is_usable}"
|
||||
type="text"
|
||||
placeholder="Path to Blender"
|
||||
>
|
||||
:class="{ 'is-invalid': blenderExeCheckResult != null && !blenderExeCheckResult.is_usable }" type="text"
|
||||
placeholder="Path to Blender">
|
||||
<p v-if="isBlenderExeChecking" class="is-in-progress">Checking...</p>
|
||||
<p v-if="blenderExeCheckResult != null && !blenderExeCheckResult.is_usable" class="check-failed">
|
||||
{{ blenderExeCheckResult.cause }}</p>
|
||||
@ -193,13 +147,9 @@
|
||||
</fieldset>
|
||||
|
||||
<div v-if="autoFoundBlenders.length === 0">
|
||||
<input
|
||||
v-model="customBlenderExe"
|
||||
@keyup.enter="nextStepAfterCheckBlenderExePath"
|
||||
:class="{'is-invalid': blenderExeCheckResult != null && !blenderExeCheckResult.is_usable}"
|
||||
type="text"
|
||||
placeholder="Path to Blender executable"
|
||||
>
|
||||
<input v-model="customBlenderExe" @keyup.enter="nextStepAfterCheckBlenderExePath"
|
||||
:class="{ 'is-invalid': blenderExeCheckResult != null && !blenderExeCheckResult.is_usable }" type="text"
|
||||
placeholder="Path to Blender executable">
|
||||
|
||||
<p v-if="isBlenderExeChecking" class="is-in-progress">Checking...</p>
|
||||
<p v-if="blenderExeCheckResult != null && !blenderExeCheckResult.is_usable" class="check-failed">
|
||||
@ -207,14 +157,8 @@
|
||||
</div>
|
||||
</step-item>
|
||||
|
||||
<step-item
|
||||
v-show="currentSetupStep == 4"
|
||||
@next-clicked="confirmSetupAssistant"
|
||||
@back-clicked="prevStep"
|
||||
next-label="Confirm"
|
||||
title="Review"
|
||||
:is-next-clickable="setupConfirmIsClickable"
|
||||
>
|
||||
<step-item v-show="currentSetupStep == 4" @next-clicked="confirmSetupAssistant" @back-clicked="prevStep"
|
||||
next-label="Confirm" title="Review" :is-next-clickable="setupConfirmIsClickable">
|
||||
<div v-if="isConfigComplete">
|
||||
<p>This is the configuration that will be used by Flamenco:</p>
|
||||
<dl>
|
||||
@ -253,7 +197,7 @@ import NotificationBar from '@/components/footer/NotificationBar.vue'
|
||||
import UpdateListener from '@/components/UpdateListener.vue'
|
||||
import StepItem from '@/components/steps/StepItem.vue';
|
||||
import { MetaApi, PathCheckInput, SetupAssistantConfig } from "@/manager-api";
|
||||
import { apiClient } from '@/stores/api-query-count';
|
||||
import { getAPIClient } from "@/api-client";
|
||||
|
||||
export default {
|
||||
name: 'SetupAssistantView',
|
||||
@ -265,7 +209,7 @@ export default {
|
||||
data: () => ({
|
||||
sharedStoragePath: "",
|
||||
sharedStorageCheckResult: null, // api.PathCheckResult
|
||||
metaAPI: new MetaApi(apiClient),
|
||||
metaAPI: new MetaApi(getAPIClient()),
|
||||
|
||||
allBlenders: [], // combination of autoFoundBlenders and blenderExeCheckResult.
|
||||
|
||||
@ -458,7 +402,6 @@ export default {
|
||||
}
|
||||
</script>
|
||||
<style>
|
||||
|
||||
.step-welcome ul {
|
||||
padding-left: var(--spacer-xl);
|
||||
margin-bottom: var(--spacer-xl);
|
||||
@ -517,7 +460,8 @@ export default {
|
||||
}
|
||||
|
||||
.progress-bar {
|
||||
--width-each-segment: calc(100% / calc(v-bind('totalSetupSteps') - 1)); /* Substract 1 because the first step has no progress. */
|
||||
--width-each-segment: calc(100% / calc(v-bind('totalSetupSteps') - 1));
|
||||
/* Substract 1 because the first step has no progress. */
|
||||
--progress-bar-width-at-current-step: calc(var(--width-each-segment) * calc(v-bind('currentSetupStep') - 1));
|
||||
|
||||
position: absolute;
|
||||
|
@ -7,8 +7,7 @@
|
||||
</div>
|
||||
<footer class="app-footer">
|
||||
<notification-bar />
|
||||
<update-listener ref="updateListener" mainSubscription="allWorkers"
|
||||
@workerUpdate="onSIOWorkerUpdate"
|
||||
<update-listener ref="updateListener" mainSubscription="allWorkers" @workerUpdate="onSIOWorkerUpdate"
|
||||
@sioReconnected="onSIOReconnected" @sioDisconnected="onSIODisconnected" />
|
||||
</footer>
|
||||
</template>
|
||||
@ -17,6 +16,7 @@
|
||||
.col-workers-list {
|
||||
grid-area: col-1;
|
||||
}
|
||||
|
||||
.col-workers-2 {
|
||||
grid-area: col-2;
|
||||
}
|
||||
@ -26,7 +26,7 @@
|
||||
import { WorkerMgtApi } from '@/manager-api';
|
||||
import { useNotifs } from '@/stores/notifications'
|
||||
import { useWorkers } from '@/stores/workers';
|
||||
import { apiClient } from '@/stores/api-query-count';
|
||||
import { getAPIClient } from "@/api-client";
|
||||
|
||||
import NotificationBar from '@/components/footer/NotificationBar.vue'
|
||||
import UpdateListener from '@/components/UpdateListener.vue'
|
||||
@ -45,7 +45,7 @@ export default {
|
||||
data: () => ({
|
||||
workers: useWorkers(),
|
||||
notifs: useNotifs(),
|
||||
api: new WorkerMgtApi(apiClient),
|
||||
api: new WorkerMgtApi(getAPIClient()),
|
||||
}),
|
||||
mounted() {
|
||||
window.workersView = this;
|
||||
|
@ -10,11 +10,16 @@ people.
|
||||
|
||||
## Steps to release a new version of Flamenco
|
||||
|
||||
Replace `${VERSION}` with the actual version number.
|
||||
|
||||
1. Update `CHANGELOG.md` and mark the to-be-released version as released today.
|
||||
2. Update `Makefile` and change the `VERSION` and `RELEASE_CYCLE` variables.
|
||||
3. Run `make update-version`
|
||||
4. Commit & tag with the commands shown in the 2nd step.
|
||||
5. Run `make release-package`
|
||||
6. Check that the files in `dist/` are there and have a non-zero size.
|
||||
7. Run `make publish-release-packages` to upload the packages to the website.
|
||||
8. Run `make project-website` to generate and publish the new website.
|
||||
2. Update `web/project-website/data/flamenco.yaml` for the new version.
|
||||
3. Update `Makefile` and change the `VERSION` and `RELEASE_CYCLE` variables.
|
||||
4. `make update-version`
|
||||
5. `git commit -m "Bump version to ${VERSION}"`
|
||||
6. `git tag v${VERSION}`
|
||||
7. `make release-package`
|
||||
8. Check that the files in `dist/` are there and have a non-zero size.
|
||||
9. `make publish-release-packages` to upload the packages to the website.
|
||||
10. `make project-website` to generate and publish the new website.
|
||||
11. `git push && git push --tags`
|
||||
|
@ -1 +1 @@
|
||||
latestVersion: "3.1"
|
||||
latestVersion: "3.2"
|
||||
|