Surf icon indicating copy to clipboard operation
Surf copied to clipboard

[Feature] Option to control task execution per node

Open chrosey opened this issue 6 years ago • 12 comments
trafficstars

Expected Behavior

Add an option to control whether a task is executed on a node.

Actual Behavior

Unless defined, every Task is run on every node the Application ist hosted on. This is not necessary for Tasks that need to run once only.

chrosey avatar Oct 11 '19 10:10 chrosey

@chrosey Can you give me a usecase for this?

simonschaufi avatar Feb 16 '20 12:02 simonschaufi

Database migration, upgrade wizards,...

t3easy avatar Feb 16 '20 12:02 t3easy

I may have an addition: Can I adjust task options per node? (Example: Customizing the host header for the WebOpCache ResetExecutionTask)

chrosey avatar Apr 21 '20 09:04 chrosey

@chrosey currently this is not possible. Everything is bound to an Application but you can of course write you own Tasks and since you get the node as parameter, you can do everything you want.

simonschaufi avatar Apr 21 '20 09:04 simonschaufi

@simonschaufi Sorry, but this is not true.

@chrosey You can add options to a node which are merged with other options: https://github.com/TYPO3/Surf/blob/6f532c809cafb46e045687bf974ab6ede1951565/src/Domain/Service/TaskManager.php#L91

Then you must not configure the same option at the deployment, globalTaskOptions ($application->setOption('TYPO3\\Surf\\Task\\Package\\GitTask[hardClean]', true);), or at the task itselve.

Maybe we should write the order with examples to the documentation.

t3easy avatar Apr 21 '20 13:04 t3easy

Ok. I was really not aware of this. But is it true that you cannot bind a task only to a defined Node meaning all tasks will run on all nodes.

simonschaufi avatar Apr 21 '20 15:04 simonschaufi

@t3easy I tried that with opcache-reset.

foreach ($targets1 as $t) {
    $node = new Node($t);
    $node->setHostname($t);
    $node->setOption('username', $deploymentUser);
    $node->setOption(
        \TYPO3\Surf\Task\Php\WebOpcacheResetExecuteTask::class,
        [
            'scriptIdentifier' => 'erase-all-humans',
            'baseUrl' => 'https://'.$node->getHostname(),
            'stream_context' => [
                'http' => [
                    'header' => 'Host: example.com',
                ],
                'ssl' => [
                    'verify_peer' => false,
                    'verify_peer_name' => false,
                ],
            ],
        ]
    );
    $application->addNode($node);
}

but there is an Error while deploying.

Node1 (CraftCMS) TYPO3\Surf\Task\Php\WebOpcacheResetExecuteTask
 Got exception "The required option "scriptIdentifier" is missing." rolling back.
 Rolling back TYPO3\Surf\Task\Php\WebOpcacheResetExecuteTask
 In Task.php line 79:
                                                         
   [TYPO3\Surf\Exception\InvalidConfigurationException]  
   The required option "scriptIdentifier" is missing.    
                                                         
 Exception trace:
   at /tmp/vendor/typo3/surf/src/Domain/Model/Task.php:79
  TYPO3\Surf\Domain\Model\Task->configureOptions() at /tmp/vendor/typo3/surf/src/Domain/Model/Task.php:48
  TYPO3\Surf\Domain\Model\Task->rollback() at /tmp/vendor/typo3/surf/src/Domain/Service/TaskManager.php:72
  TYPO3\Surf\Domain\Service\TaskManager->rollback() at /tmp/vendor/typo3/surf/src/Domain/Model/SimpleWorkflow.php:107
  TYPO3\Surf\Domain\Model\SimpleWorkflow->run() at /tmp/vendor/typo3/surf/src/Domain/Model/Deployment.php:184
  TYPO3\Surf\Domain\Model\Deployment->deploy() at /tmp/vendor/typo3/surf/src/Command/DeployCommand.php:66
  TYPO3\Surf\Command\DeployCommand->execute() at /tmp/vendor/symfony/console/Command/Command.php:255
  Symfony\Component\Console\Command\Command->run() at /tmp/vendor/symfony/console/Application.php:1012
  Symfony\Component\Console\Application->doRunCommand() at /tmp/vendor/typo3/surf/src/Cli/Symfony/ConsoleApplication.php:64
  TYPO3\Surf\Cli\Symfony\ConsoleApplication->doRunCommand() at /tmp/vendor/symfony/console/Application.php:272
  Symfony\Component\Console\Application->doRun() at /tmp/vendor/symfony/console/Application.php:148
  Symfony\Component\Console\Application->run() at /tmp/vendor/typo3/surf/src/Cli/Symfony/ConsoleApplication.php:49
  TYPO3\Surf\Cli\Symfony\ConsoleApplication->run() at /tmp/vendor/typo3/surf/surf:14

How should the Syntax to set these options be to let it work?

chrosey avatar Apr 21 '20 15:04 chrosey

@simonschaufi thats why I would suggest maybe an boolean meta-option for abstract class Task which can be set like any other options to disable or enable Tasks for some Nodes.

chrosey avatar Apr 21 '20 15:04 chrosey

@chrosey You set the option wrong. setOption only accepts one option with one value. So it would be:

$node->setOption(
    \TYPO3\Surf\Task\Php\WebOpcacheResetExecuteTask::class . '[scriptIdentifier]',
    'erase-all-humans'
);

t3easy avatar Apr 21 '20 18:04 t3easy

The option key for a global task option is always fullQualifiedClassName[optionName]

t3easy avatar Apr 21 '20 18:04 t3easy

@t3easy: worked like a charm.

Did I miss this in the documentation?

chrosey avatar Apr 22 '20 08:04 chrosey

No, I guess there is no dokumentation how options can be set and how they are merged/overridden to the final result.

t3easy avatar Apr 22 '20 09:04 t3easy