Manager: allow setup to finish without Blender
Add an option to the setup assistant to skip configuring the path to Blender. It will just use the `default` option, which causes the Workers to try and find Blender on their own. Fixes #104306 Reviewed-on: https://projects.blender.org/studio/flamenco/pulls/104306 Reviewed-by: Sybren A. Stüvel <sybren@blender.org>
This commit is contained in:
parent
0a98fd2b96
commit
6baa132c43
@ -21,6 +21,14 @@ import (
|
||||
"projects.blender.org/studio/flamenco/pkg/api"
|
||||
)
|
||||
|
||||
var (
|
||||
ErrSetupConfigUnusableSource = errors.New("sources should not have the 'is_usable' field set to false")
|
||||
ErrSetupConfigEmptyStorageLocation = errors.New("'storageLocation' field must not be empty")
|
||||
ErrSetupConfigEmptyPath = errors.New("'path' field must not be empty while using the 'file_association' source")
|
||||
ErrSetupConfigEmptyPathOrInput = errors.New("'path' or 'input' fields must not be empty while using the 'input_path' or 'path_envvar' sources")
|
||||
ErrSetupConfigEmptySource = errors.New("'source' field must not be empty")
|
||||
)
|
||||
|
||||
func (f *Flamenco) GetVersion(e echo.Context) error {
|
||||
return e.JSON(http.StatusOK, api.FlamencoVersion{
|
||||
Version: appinfo.ExtendedVersion(),
|
||||
@ -265,11 +273,9 @@ func (f *Flamenco) SaveSetupAssistantConfig(e echo.Context) error {
|
||||
|
||||
logger = logger.With().Interface("config", setupAssistantCfg).Logger()
|
||||
|
||||
if setupAssistantCfg.StorageLocation == "" ||
|
||||
!setupAssistantCfg.BlenderExecutable.IsUsable ||
|
||||
setupAssistantCfg.BlenderExecutable.Path == "" {
|
||||
logger.Warn().Msg("setup assistant: configuration is incomplete, unable to accept")
|
||||
return sendAPIError(e, http.StatusBadRequest, "configuration is incomplete")
|
||||
if err := checkSetupAssistantConfig(setupAssistantCfg); err != nil {
|
||||
logger.Error().AnErr("cause", err).Msg("setup assistant: configuration is incomplete")
|
||||
return sendAPIError(e, http.StatusBadRequest, "configuration is incomplete: %v", err)
|
||||
}
|
||||
|
||||
conf := f.config.Get()
|
||||
@ -277,7 +283,7 @@ func (f *Flamenco) SaveSetupAssistantConfig(e echo.Context) error {
|
||||
|
||||
var executable string
|
||||
switch setupAssistantCfg.BlenderExecutable.Source {
|
||||
case api.BlenderPathSourceFileAssociation:
|
||||
case api.BlenderPathSourceFileAssociation, api.BlenderPathSourceDefault:
|
||||
// The Worker will try to use the file association when the command is set
|
||||
// to the string "blender".
|
||||
executable = "blender"
|
||||
@ -336,3 +342,37 @@ func flamencoManagerDir() (string, error) {
|
||||
func commandNeedsQuoting(cmd string) bool {
|
||||
return strings.ContainsAny(cmd, "\n\t;()")
|
||||
}
|
||||
|
||||
func checkSetupAssistantConfig(config api.SetupAssistantConfig) error {
|
||||
if config.StorageLocation == "" {
|
||||
return ErrSetupConfigEmptyStorageLocation
|
||||
}
|
||||
|
||||
if !config.BlenderExecutable.IsUsable {
|
||||
return ErrSetupConfigUnusableSource
|
||||
}
|
||||
|
||||
switch config.BlenderExecutable.Source {
|
||||
case api.BlenderPathSourceDefault:
|
||||
return nil
|
||||
|
||||
case api.BlenderPathSourceFileAssociation:
|
||||
if config.BlenderExecutable.Path == "" {
|
||||
return ErrSetupConfigEmptyPath
|
||||
}
|
||||
|
||||
case api.BlenderPathSourceInputPath, api.BlenderPathSourcePathEnvvar:
|
||||
if config.BlenderExecutable.Path == "" ||
|
||||
config.BlenderExecutable.Input == "" {
|
||||
return ErrSetupConfigEmptyPathOrInput
|
||||
}
|
||||
|
||||
case "":
|
||||
return ErrSetupConfigEmptySource
|
||||
|
||||
default:
|
||||
return fmt.Errorf("unknown 'source' field value: %v", config.BlenderExecutable.Source)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
@ -363,6 +363,27 @@ func TestSaveSetupAssistantConfig(t *testing.T) {
|
||||
assert.Equal(t, expectBlenderVar, savedConfig.Variables["blender"])
|
||||
assert.Equal(t, defaultBlenderArgsVar, savedConfig.Variables["blenderArgs"])
|
||||
}
|
||||
|
||||
// Test situation where adding a blender executable was skipped.
|
||||
{
|
||||
savedConfig := doTest(api.SetupAssistantConfig{
|
||||
StorageLocation: mf.tempdir,
|
||||
BlenderExecutable: api.BlenderPathCheckResult{
|
||||
IsUsable: true,
|
||||
Source: api.BlenderPathSourceDefault,
|
||||
},
|
||||
})
|
||||
assert.Equal(t, mf.tempdir, savedConfig.SharedStoragePath)
|
||||
expectBlenderVar := config.Variable{
|
||||
Values: config.VariableValues{
|
||||
{Platform: "linux", Value: "blender"},
|
||||
{Platform: "windows", Value: "blender"},
|
||||
{Platform: "darwin", Value: "blender"},
|
||||
},
|
||||
}
|
||||
assert.Equal(t, expectBlenderVar, savedConfig.Variables["blender"])
|
||||
assert.Equal(t, defaultBlenderArgsVar, savedConfig.Variables["blenderArgs"])
|
||||
}
|
||||
}
|
||||
|
||||
func metaTestFixtures(t *testing.T) (mockedFlamenco, func()) {
|
||||
|
@ -114,7 +114,7 @@
|
||||
|
||||
<p v-else>Choose how a Worker should invoke the Blender command when performing a task:</p>
|
||||
|
||||
<fieldset v-if="autoFoundBlenders.length >= 1">
|
||||
<fieldset>
|
||||
<label v-if="autoFoundBlenderPathEnvvar" for="blender-path_envvar">
|
||||
<div>
|
||||
<input
|
||||
@ -191,25 +191,19 @@
|
||||
</p>
|
||||
</div>
|
||||
</label>
|
||||
|
||||
<label for="blender-default">
|
||||
<div>
|
||||
<input
|
||||
type="radio"
|
||||
v-model="selectedBlender"
|
||||
name="blender"
|
||||
:value="blenderFromDefaultSource"
|
||||
id="blender-default" />
|
||||
{{ sourceLabels['default'] }}
|
||||
</div>
|
||||
</label>
|
||||
</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" />
|
||||
|
||||
<p v-if="isBlenderExeChecking" class="is-in-progress">Checking...</p>
|
||||
<p
|
||||
v-if="blenderExeCheckResult != null && !blenderExeCheckResult.is_usable"
|
||||
class="check-failed">
|
||||
{{ blenderExeCheckResult.cause }}
|
||||
</p>
|
||||
</div>
|
||||
</step-item>
|
||||
|
||||
<step-item
|
||||
@ -240,6 +234,9 @@
|
||||
The command you provided: "<code>{{ selectedBlender.path }}</code
|
||||
>"
|
||||
</dd>
|
||||
<dd v-if="selectedBlender.source == 'default'">
|
||||
You have chosen to skip adding a blender path.
|
||||
</dd>
|
||||
</dl>
|
||||
</div>
|
||||
<p v-if="isConfirmed" class="check-ok">
|
||||
@ -291,7 +288,8 @@ export default {
|
||||
sourceLabels: {
|
||||
file_association: 'Blender that runs when you double-click a .blend file:',
|
||||
path_envvar: 'Blender found on the $PATH environment:',
|
||||
input_path: 'Another Blender executable:',
|
||||
input_path: 'Specify a Blender executable:',
|
||||
default: 'Skip, let the Workers use whatever Blender is available.',
|
||||
},
|
||||
isConfirming: false,
|
||||
isConfirmed: false,
|
||||
@ -324,6 +322,15 @@ export default {
|
||||
blenderFromInputPath() {
|
||||
return this.allBlenders.find((b) => b.source === 'input_path');
|
||||
},
|
||||
blenderFromDefaultSource() {
|
||||
return {
|
||||
input: '',
|
||||
path: '',
|
||||
source: 'default',
|
||||
is_usable: true,
|
||||
cause: '',
|
||||
};
|
||||
},
|
||||
setupConfirmIsClickable() {
|
||||
if (this.isConfirming || this.isConfirmed) {
|
||||
return false;
|
||||
|
Loading…
x
Reference in New Issue
Block a user