fix: storages with preserved git repository

This commit is contained in:
Andras Bacsai
2024-08-21 14:31:17 +02:00
parent 3f9f197282
commit 7d7cdf41f7
6 changed files with 79 additions and 31 deletions

View File

@@ -204,7 +204,7 @@ class ApplicationDeploymentJob implements ShouldBeEncrypted, ShouldQueue
$this->container_name = "{$this->application->settings->custom_internal_name}-pr-{$this->pull_request_id}"; $this->container_name = "{$this->application->settings->custom_internal_name}-pr-{$this->pull_request_id}";
} }
} }
ray('New container name: ', $this->container_name); ray('New container name: ', $this->container_name)->green();
savePrivateKeyToFs($this->server); savePrivateKeyToFs($this->server);
$this->saved_outputs = collect(); $this->saved_outputs = collect();
@@ -419,6 +419,34 @@ class ApplicationDeploymentJob implements ShouldBeEncrypted, ShouldQueue
$this->prepare_builder_image(); $this->prepare_builder_image();
$this->check_git_if_build_needed(); $this->check_git_if_build_needed();
$this->clone_repository(); $this->clone_repository();
if ($this->preserveRepository) {
foreach ($this->application->fileStorages as $fileStorage) {
$path = $fileStorage->fs_path;
$saveName = 'file_stat_'.$fileStorage->id;
$realPathInGit = str($path)->replace($this->application->workdir(), $this->workdir)->value();
// check if the file is a directory or a file inside the repository
$this->execute_remote_command(
[executeInDocker($this->deployment_uuid, "stat -c '%F' {$realPathInGit}"), 'hidden' => true, 'ignore_errors' => true, 'save' => $saveName]
);
if ($this->saved_outputs->has($saveName)) {
$fileStat = $this->saved_outputs->get($saveName);
if ($fileStat->value() === 'directory' && ! $fileStorage->is_directory) {
$fileStorage->is_directory = true;
$fileStorage->content = null;
$fileStorage->save();
$fileStorage->deleteStorageOnServer();
$fileStorage->saveStorageOnServer();
} elseif ($fileStat->value() === 'regular file' && $fileStorage->is_directory) {
$fileStorage->is_directory = false;
$fileStorage->is_based_on_git = true;
$fileStorage->save();
$fileStorage->deleteStorageOnServer();
$fileStorage->saveStorageOnServer();
}
}
}
}
$this->generate_image_names(); $this->generate_image_names();
$this->cleanup_git(); $this->cleanup_git();
$this->application->loadComposeFile(isInit: false); $this->application->loadComposeFile(isInit: false);
@@ -626,20 +654,16 @@ class ApplicationDeploymentJob implements ShouldBeEncrypted, ShouldQueue
[ [
"mkdir -p $this->configuration_dir", "mkdir -p $this->configuration_dir",
], ],
// removing this now as we are using docker cp
// [
// "rm -rf $this->configuration_dir/{*,.*}",
// ],
[ [
"docker cp {$this->deployment_uuid}:{$this->workdir}/. {$this->configuration_dir}", "docker cp {$this->deployment_uuid}:{$this->workdir}/. {$this->configuration_dir}",
], ],
); );
} }
$this->application->fileStorages()->each(function ($fileStorage) { foreach ($this->application->fileStorages as $fileStorage) {
if (! $fileStorage->is_based_on_git && ! $fileStorage->is_directory) { if (! $fileStorage->is_based_on_git && ! $fileStorage->is_directory) {
$fileStorage->saveStorageOnServer(); $fileStorage->saveStorageOnServer();
} }
}); }
if ($this->use_build_server) { if ($this->use_build_server) {
$this->server = $this->build_server; $this->server = $this->build_server;
} }

View File

@@ -55,6 +55,7 @@ class FileStorage extends Component
$this->fileStorage->deleteStorageOnServer(); $this->fileStorage->deleteStorageOnServer();
$this->fileStorage->is_directory = true; $this->fileStorage->is_directory = true;
$this->fileStorage->content = null; $this->fileStorage->content = null;
$this->fileStorage->is_based_on_git = false;
$this->fileStorage->save(); $this->fileStorage->save();
$this->fileStorage->saveStorageOnServer(); $this->fileStorage->saveStorageOnServer();
} catch (\Throwable $e) { } catch (\Throwable $e) {

View File

@@ -52,6 +52,7 @@ class LocalFileVolume extends BaseModel
public function deleteStorageOnServer() public function deleteStorageOnServer()
{ {
$this->load(['service']);
$isService = data_get($this->resource, 'service'); $isService = data_get($this->resource, 'service');
if ($isService) { if ($isService) {
$workdir = $this->resource->service->workdir(); $workdir = $this->resource->service->workdir();

View File

@@ -91,7 +91,7 @@ function next_queuable(string $server_id, string $application_id): bool
$server = Server::find($server_id); $server = Server::find($server_id);
$concurrent_builds = $server->settings->concurrent_builds; $concurrent_builds = $server->settings->concurrent_builds;
ray("serverId:{$server->id}", "concurrentBuilds:{$concurrent_builds}", "deployments:{$deployments->count()}", "sameApplicationDeployments:{$same_application_deployments->count()}"); ray("serverId:{$server->id}", "concurrentBuilds:{$concurrent_builds}", "deployments:{$deployments->count()}", "sameApplicationDeployments:{$same_application_deployments->count()}")->green();
if ($deployments->count() > $concurrent_builds) { if ($deployments->count() > $concurrent_builds) {
return false; return false;

View File

@@ -53,7 +53,9 @@ function getFilesystemVolumesFromServer(ServiceApplication|ServiceDatabase|Appli
if ($isFile == 'OK') { if ($isFile == 'OK') {
// If its a file & exists // If its a file & exists
$filesystemContent = instant_remote_process(["cat $fileLocation"], $server); $filesystemContent = instant_remote_process(["cat $fileLocation"], $server);
$fileVolume->content = $filesystemContent; if ($fileVolume->is_based_on_git) {
$fileVolume->content = $filesystemContent;
}
$fileVolume->is_directory = false; $fileVolume->is_directory = false;
$fileVolume->save(); $fileVolume->save();
} elseif ($isDir == 'OK') { } elseif ($isDir == 'OK') {

View File

@@ -1955,6 +1955,12 @@ function parseDockerComposeFile(Service|Application $resource, bool $isNew = fal
$resource->docker_compose_raw = Yaml::dump($yaml, 10, 2); $resource->docker_compose_raw = Yaml::dump($yaml, 10, 2);
$resource->docker_compose = Yaml::dump($finalServices, 10, 2); $resource->docker_compose = Yaml::dump($finalServices, 10, 2);
} }
if ($resource->environment_variables()->count() === 0) {
data_forget($resource, 'environment_variables');
}
if ($resource->environment_variables_preview()->count() === 0) {
data_forget($resource, 'environment_variables_preview');
}
$resource->save(); $resource->save();
return collect($finalServices); return collect($finalServices);
@@ -2455,10 +2461,19 @@ function parseServiceVolumes($serviceVolumes, $resource, $topLevelVolumes, $pull
if (is_string($volume)) { if (is_string($volume)) {
$source = str($volume)->before(':'); $source = str($volume)->before(':');
$target = str($volume)->after(':')->beforeLast(':'); $target = str($volume)->after(':')->beforeLast(':');
$foundConfig = $resource->fileStorages()->whereMountPath($target)->first();
if ($source->startsWith('./') || $source->startsWith('/') || $source->startsWith('~')) { if ($source->startsWith('./') || $source->startsWith('/') || $source->startsWith('~')) {
$type = str('bind'); $type = str('bind');
// By default, we cannot determine if the bind is a directory or not, so we set it to directory if ($foundConfig) {
$isDirectory = true; $contentNotNull = data_get($foundConfig, 'content');
if ($contentNotNull) {
$content = $contentNotNull;
}
$isDirectory = data_get($foundConfig, 'is_directory');
} else {
// By default, we cannot determine if the bind is a directory or not, so we set it to directory
$isDirectory = true;
}
} else { } else {
$type = str('volume'); $type = str('volume');
} }
@@ -2474,13 +2489,16 @@ function parseServiceVolumes($serviceVolumes, $resource, $topLevelVolumes, $pull
if ($contentNotNull) { if ($contentNotNull) {
$content = $contentNotNull; $content = $contentNotNull;
} }
$isDirectory = data_get($foundConfig, 'is_directory');
} else {
$isDirectory = (bool) data_get($volume, 'isDirectory', null) || (bool) data_get($volume, 'is_directory', null); $isDirectory = (bool) data_get($volume, 'isDirectory', null) || (bool) data_get($volume, 'is_directory', null);
if ((is_null($isDirectory) || ! $isDirectory) && is_null($content)) {
// if isDirectory is not set (or false) & content is also not set, we assume it is a directory
ray('setting isDirectory to true');
$isDirectory = true;
}
} }
if ((is_null($isDirectory) || ! $isDirectory) && is_null($content)) {
// if isDirectory is not set (or false) & content is also not set, we assume it is a directory
ray('setting isDirectory to true');
$isDirectory = true;
}
} }
if ($type?->value() === 'bind') { if ($type?->value() === 'bind') {
if ($source->value() === '/var/run/docker.sock') { if ($source->value() === '/var/run/docker.sock') {
@@ -2504,21 +2522,23 @@ function parseServiceVolumes($serviceVolumes, $resource, $topLevelVolumes, $pull
if ($pull_request_id !== 0) { if ($pull_request_id !== 0) {
$source = $source."-pr-$pull_request_id"; $source = $source."-pr-$pull_request_id";
} }
LocalFileVolume::updateOrCreate( if (! $resource->settings->is_preserve_repository_enabled || $foundConfig->is_based_on_git) {
[ LocalFileVolume::updateOrCreate(
'mount_path' => $target, [
'resource_id' => $resource->id, 'mount_path' => $target,
'resource_type' => get_class($resource), 'resource_id' => $resource->id,
], 'resource_type' => get_class($resource),
[ ],
'fs_path' => $source, [
'mount_path' => $target, 'fs_path' => $source,
'content' => $content, 'mount_path' => $target,
'is_directory' => $isDirectory, 'content' => $content,
'resource_id' => $resource->id, 'is_directory' => $isDirectory,
'resource_type' => get_class($resource), 'resource_id' => $resource->id,
] 'resource_type' => get_class($resource),
); ]
);
}
} elseif ($type->value() === 'volume') { } elseif ($type->value() === 'volume') {
if ($topLevelVolumes->has($source->value())) { if ($topLevelVolumes->has($source->value())) {
$v = $topLevelVolumes->get($source->value()); $v = $topLevelVolumes->get($source->value());