mirror of
https://github.com/coollabsio/coolify.git
synced 2026-11-06 21:18:11 -04:00
fix: enforce webhook lockouts and stop cancelled runner provisioning
- Manual webhooks (GitHub, GitLab, Gitea, Bitbucket) now reject all deliveries for a locked-out scope before reading secrets or verifying signatures, including correctly signed ones, until the window expires. - ProvisionGithubRunnerJob checks whether the execution has already finished before and after each provisioning step, and only sets ready_at or Failed while it is still occupying/provisioning. A runner that is cancelled, timed out or completed mid-provisioning is no longer started, retried or overwritten. - VolumeCloneJob creates bind-volume clones as plain local volumes without the source driver options, so the clone never mounts the source host directory. - Image pulls for additional servers no longer ignore docker pull errors. - Add tests for each change.
This commit is contained in:
@@ -340,10 +340,16 @@ class MultiServerRecordingDeploymentJob extends ApplicationDeploymentJob
|
||||
/** Output that `docker images -q` returns; empty means the image is missing. */
|
||||
public string $localImageOutput = 'sha256:0123456789ab';
|
||||
|
||||
public bool $failImagePull = false;
|
||||
|
||||
public function execute_remote_command(...$commands): void
|
||||
{
|
||||
foreach ($commands as $command) {
|
||||
$this->recordedCommands[] = $command['command'] ?? $command[0];
|
||||
$remoteCommand = $command['command'] ?? $command[0];
|
||||
$this->recordedCommands[] = $remoteCommand;
|
||||
if ($this->failImagePull && str_starts_with($remoteCommand, 'docker pull ') && ! ($command['ignore_errors'] ?? false)) {
|
||||
throw new RuntimeException('Registry image pull failed.');
|
||||
}
|
||||
if (isset($command['save'])) {
|
||||
(new ReflectionProperty(ApplicationDeploymentJob::class, 'saved_outputs'))->getValue($this)->put($command['save'], $this->localImageOutput);
|
||||
}
|
||||
@@ -390,6 +396,18 @@ describe('inline Dockerfile image on additional servers', function () {
|
||||
]);
|
||||
});
|
||||
|
||||
test('an additional server fails when pulling the image fails even if an old image is cached', function () {
|
||||
[$job, $reflection] = makeInlineDockerfileJob($this->application->fresh(), true);
|
||||
$job->failImagePull = true;
|
||||
$job->localImageOutput = 'sha256:stale-cached-image';
|
||||
|
||||
expect(fn () => $reflection->getMethod('pull_image_for_additional_server')->invoke($job))
|
||||
->toThrow(RuntimeException::class, 'Registry image pull failed.');
|
||||
expect($job->recordedCommands)->toBe([
|
||||
"docker pull 'registry.example.com/nginx-multi:latest'",
|
||||
]);
|
||||
});
|
||||
|
||||
test('a deployments only server explains that the main server must push a missing image', function () {
|
||||
$this->extraServer->settings->update(['server_role' => 'deployment']);
|
||||
[$job, $reflection] = makeInlineDockerfileJob($this->application->fresh(), true, $this->extraServer->fresh());
|
||||
|
||||
Reference in New Issue
Block a user