mirror of
https://github.com/coollabsio/coolify.git
synced 2026-11-06 21:18:11 -04:00
fix(railpack): serialize builder bootstrap before builds
This commit is contained in:
@@ -268,11 +268,13 @@ it('stops the railpack builder after the build when no other build uses it', fun
|
||||
$command = invokeRailpackMethod($job, $reflection, 'railpack_build_command', ['coollabsio/coolify:test', collect([])]);
|
||||
|
||||
$sharedLock = strpos($command, 'flock -s 9');
|
||||
$bootstrap = strpos($command, railpackBuilderBootstrapScript());
|
||||
$build = strpos($command, 'docker buildx build --builder coolify-railpack');
|
||||
$stop = strpos($command, 'if flock -n -x 9; then DOCKER_CONFIG=/root/.docker docker buildx stop coolify-railpack');
|
||||
|
||||
expect($sharedLock)->not->toBeFalse()
|
||||
->and($build)->toBeGreaterThan($sharedLock)
|
||||
->and($bootstrap)->toBeGreaterThan($sharedLock)
|
||||
->and($build)->toBeGreaterThan($bootstrap)
|
||||
->and($stop)->toBeGreaterThan($build)
|
||||
->and($command)->toEndWith('exit $status');
|
||||
});
|
||||
|
||||
@@ -94,6 +94,7 @@ it('generates escaped railpack env args from resolved values and includes instal
|
||||
it('uses preview railpack environment variables for preview deployments', function () {
|
||||
$application = Mockery::mock(Application::class);
|
||||
$application->shouldReceive('getAttribute')->with('install_command')->andReturn(null);
|
||||
$application->shouldReceive('getAttribute')->with('settings')->andReturn((object) ['is_pr_deployments_public_enabled' => false]);
|
||||
|
||||
$previewValue = Mockery::mock(EnvironmentVariable::class)->makePartial();
|
||||
$previewValue->forceFill([
|
||||
@@ -104,12 +105,14 @@ it('uses preview railpack environment variables for preview deployments', functi
|
||||
$previewValue->shouldReceive('getResolvedValueWithServer')->once()->with(Mockery::type(Server::class))->andReturn('preview-value');
|
||||
|
||||
$previewQuery = Mockery::mock();
|
||||
$previewQuery->shouldReceive('whereNotIn')->with('id', [])->once()->andReturnSelf();
|
||||
$previewQuery->shouldReceive('withoutBuildpackControlVariables')->once()->andReturnSelf();
|
||||
$previewQuery->shouldReceive('where')->with('is_buildtime', true)->once()->andReturnSelf();
|
||||
$previewQuery->shouldReceive('get')->once()->andReturn(collect([]));
|
||||
$application->shouldReceive('environment_variables_preview')->once()->andReturn($previewQuery);
|
||||
|
||||
$railpackPreviewQuery = Mockery::mock();
|
||||
$railpackPreviewQuery->shouldReceive('whereNotIn')->with('id', [])->once()->andReturnSelf();
|
||||
$railpackPreviewQuery->shouldReceive('get')->once()->andReturn(collect([$previewValue]));
|
||||
$application->shouldReceive('railpack_environment_variables_preview')->once()->andReturn($railpackPreviewQuery);
|
||||
|
||||
|
||||
@@ -885,3 +885,14 @@ test('railpack builder helper command gets sudo only outside the helper script',
|
||||
." exit \$status' 2>/dev/null || sudo true"
|
||||
);
|
||||
});
|
||||
|
||||
test('railpack builder bootstrap script gets no sudo inside the helper script', function () {
|
||||
$command = railpackBuilderHelperCommand('$HOME/.docker/buildx', 'coolify-helper:1.0.0', railpackBuilderBootstrapScript().'; docker buildx prune --builder coolify-railpack -af');
|
||||
|
||||
$parsed = parseCommandsByLineForSudo(collect([$command]), $this->server)[0];
|
||||
|
||||
expect($parsed)
|
||||
->toStartWith('sudo docker run --rm ')
|
||||
->toContain(railpackBuilderBootstrapScript().'; docker buildx prune --builder coolify-railpack -af; status=$?;')
|
||||
->toEndWith("exit \$status' 2>/dev/null || sudo true");
|
||||
});
|
||||
|
||||
@@ -41,3 +41,32 @@ test('a held shared lock prevents stopping the builder', function () {
|
||||
expect($process->getExitCode())->toBe(0);
|
||||
expect($process->getOutput())->toBe('built');
|
||||
});
|
||||
|
||||
test('concurrent builds bootstrap the builder one at a time', function () {
|
||||
$directory = sys_get_temp_dir().'/railpack-bootstrap-'.bin2hex(random_bytes(8));
|
||||
mkdir($directory);
|
||||
|
||||
try {
|
||||
// The fake bootstrap takes time, like buildkitd that starts but does not listen yet.
|
||||
$setup = "docker() { if [ \"\$2\" = inspect ]; then echo start >> {$directory}/log; sleep 0.3; echo end >> {$directory}/log; fi; }; ";
|
||||
$script = str_replace(
|
||||
['/root/.docker/buildx/coolify-railpack.lock', '/root/.docker/buildx/coolify-railpack-bootstrap.lock'],
|
||||
[$directory.'/builder.lock', $directory.'/bootstrap.lock'],
|
||||
$setup.railpackBuilderLockedScript(railpackBuilderBootstrapScript().'; true'),
|
||||
);
|
||||
|
||||
$builds = [new Process(['bash', '-c', $script]), new Process(['bash', '-c', $script])];
|
||||
foreach ($builds as $build) {
|
||||
$build->start();
|
||||
}
|
||||
foreach ($builds as $build) {
|
||||
$build->wait();
|
||||
expect($build->getExitCode())->toBe(0);
|
||||
}
|
||||
|
||||
expect(file($directory.'/log', FILE_IGNORE_NEW_LINES))->toBe(['start', 'end', 'start', 'end']);
|
||||
} finally {
|
||||
array_map('unlink', glob($directory.'/*'));
|
||||
rmdir($directory);
|
||||
}
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user