diff --git a/app/Jobs/ApplicationDeploymentJob.php b/app/Jobs/ApplicationDeploymentJob.php index e480a6fc7..957817813 100644 --- a/app/Jobs/ApplicationDeploymentJob.php +++ b/app/Jobs/ApplicationDeploymentJob.php @@ -9,6 +9,7 @@ use App\Events\ApplicationStatusChanged; use App\Models\Application; use App\Models\ApplicationDeploymentQueue; use App\Models\ApplicationPreview; +use App\Models\DockerRegistry; use App\Models\EnvironmentVariable; use App\Models\GithubApp; use App\Models\GitlabApp; @@ -383,6 +384,7 @@ class ApplicationDeploymentJob implements ShouldBeEncrypted, ShouldQueue private function deploy_dockerimage_buildpack() { + $useCustomRegistry = $this->application->docker_use_custom_registry; try { // setup $this->dockerImage = $this->application->docker_registry_image_name; @@ -394,7 +396,7 @@ class ApplicationDeploymentJob implements ShouldBeEncrypted, ShouldQueue $this->application_deployment_queue->addLogEntry("Starting deployment of {$this->dockerImage}:{$this->dockerImageTag} to {$this->server->name}."); // login if use custom registry - if ($this->application->docker_use_custom_registry) { + if ($useCustomRegistry) { $this->handleRegistryAuth(); } @@ -402,25 +404,16 @@ class ApplicationDeploymentJob implements ShouldBeEncrypted, ShouldQueue $this->prepare_builder_image(); $this->generate_compose_file(); $this->rolling_update(); - - // Logout if use custom registry - if ($this->application->docker_use_custom_registry) { + } catch (Exception $e) { + throw $e; + } finally { + if ($useCustomRegistry) { $this->application_deployment_queue->addLogEntry('Logging out from registry...'); $this->execute_remote_command([ 'docker logout', 'hidden' => true ]); } - } catch (Exception $e) { - // Make sure to logout even if build/pull fails - if ($this->application->docker_use_custom_registry) { - $this->execute_remote_command([ - 'docker logout', - 'hidden' => true - ]); - } - //$this->application_deployment_queue->addLogEntry('Deployment error: ' . $e->getMessage(), 'stderr'); - throw $e; } } @@ -2477,13 +2470,27 @@ COPY ./nginx.conf /etc/nginx/conf.d/default.conf"); private function handleRegistryAuth() { - //$registry = $this->$application->registry; ?? - //$token = escapeshellarg($registry->token); ... - $token = escapeshellarg('test'); - $url = escapeshellarg('test'); - $username = escapeshellarg('test'); + $registry = DockerRegistry::find($this->application->docker_registry_id); + if (!$registry) { + throw new Exception('Registry not found.'); + } + + $token = escapeshellarg($registry->token); + $username = escapeshellarg($registry->username); + + // Handle different registry types + $url = match ($registry->type) { + 'docker_hub' => '', // Docker Hub doesn't need URL specified + 'custom' => escapeshellarg($registry->url), + default => escapeshellarg($registry->url) + }; + $this->application_deployment_queue->addLogEntry('Attempting to log into registry...'); - $command = "echo {{secrets.token}} | docker login {$url} -u {$username} --password-stdin"; + + // Build login command based on registry type + $command = $registry->type === 'docker_hub' + ? "echo {{secrets.token}} | docker login -u {$username} --password-stdin" + : "echo {{secrets.token}} | docker login {$url} -u {$username} --password-stdin"; $this->execute_remote_command( [ diff --git a/app/Livewire/Images/Images/Create.php b/app/Livewire/Images/Images/Create.php new file mode 100644 index 000000000..e69de29bb diff --git a/app/Livewire/Images/Images/Index.php b/app/Livewire/Images/Images/Index.php new file mode 100644 index 000000000..4126ebddf --- /dev/null +++ b/app/Livewire/Images/Images/Index.php @@ -0,0 +1,13 @@ + 'required|string|max:255', + 'type' => 'required|string', + 'url' => 'nullable|string|max:255', + 'username' => 'nullable|string|max:255', + 'token' => 'nullable|string', + ]; + + public function getRegistryTypesProperty() + { + return DockerRegistry::getTypes(); + } + + public function submit() + { + $this->validate(); + + DockerRegistry::create([ + 'name' => $this->name, + 'type' => $this->type, + 'url' => $this->type === 'custom' ? $this->url : 'docker.io', + 'username' => $this->username, + 'token' => $this->token, + ]); + + $this->dispatch('registry-added'); + $this->dispatch('success', 'Registry added successfully.'); + $this->dispatch('close-modal'); + } + + public function render() + { + return view('livewire.images.registry.create'); + } +} diff --git a/app/Livewire/Images/Registry/Index.php b/app/Livewire/Images/Registry/Index.php new file mode 100644 index 000000000..f612ebee2 --- /dev/null +++ b/app/Livewire/Images/Registry/Index.php @@ -0,0 +1,18 @@ + '$refresh']; + + public function render() + { + return view('livewire.images.registry.index', [ + 'registries' => DockerRegistry::all() + ]); + } +} diff --git a/app/Livewire/Images/Registry/Show.php b/app/Livewire/Images/Registry/Show.php new file mode 100644 index 000000000..90069f571 --- /dev/null +++ b/app/Livewire/Images/Registry/Show.php @@ -0,0 +1,82 @@ + 'required|string|max:255', + 'type' => 'required|string', + 'url' => 'nullable|string|max:255', + 'username' => 'nullable|string|max:255', + 'token' => 'nullable|string', + ]; + + public function mount(DockerRegistry $registry) + { + $this->registry = $registry; + $this->name = $registry->name; + $this->type = $registry->type; + $this->url = $registry->url; + $this->username = $registry->username; + $this->token = $registry->token; + } + + public function getRegistryTypesProperty() + { + return DockerRegistry::getTypes(); + } + + public function updateRegistry() + { + $this->validate(); + + $this->registry->update([ + 'name' => $this->name, + 'type' => $this->type, + 'url' => $this->type === 'custom' ? $this->url : 'docker.io', + 'username' => $this->username, + 'token' => $this->token, + ]); + + $this->dispatch('success', 'Registry updated successfully.'); + } + + public function delete() + { + // Update all applications using this registry + $this->registry->applications() + ->update([ + 'docker_registry_id' => null, + 'docker_use_custom_registry' => false + ]); + + $this->registry->delete(); + $this->dispatch('registry-added'); + $this->dispatch('success', 'Registry deleted successfully.'); + } + + public function render() + { + return view('livewire.images.registry.show'); + } + + public function getIsFormDirtyProperty(): bool + { + return $this->name !== $this->registry->name + || $this->type !== $this->registry->type + || $this->url !== $this->registry->url + || $this->username !== $this->registry->username + || $this->token !== $this->registry->token; + } +} diff --git a/app/Livewire/Project/Application/General.php b/app/Livewire/Project/Application/General.php index d1e905dd9..72829c8de 100644 --- a/app/Livewire/Project/Application/General.php +++ b/app/Livewire/Project/Application/General.php @@ -4,7 +4,7 @@ namespace App\Livewire\Project\Application; use App\Actions\Application\GenerateConfig; use App\Models\Application; -use App\Models\Registry; +use App\Models\DockerRegistry; use Illuminate\Support\Collection; use Livewire\Component; use Spatie\Url\Url; @@ -444,7 +444,7 @@ class General extends Component public function render() { return view('livewire.project.application.general', [ - 'registries' => Registry::all(), + 'registries' => DockerRegistry::all(), ]); } } diff --git a/app/Livewire/Project/New/DockerImage.php b/app/Livewire/Project/New/DockerImage.php index 936e22b5e..7833a11b9 100644 --- a/app/Livewire/Project/New/DockerImage.php +++ b/app/Livewire/Project/New/DockerImage.php @@ -3,7 +3,7 @@ namespace App\Livewire\Project\New; use App\Models\Application; -use App\Models\Registry; +use App\Models\DockerRegistry; use App\Models\Project; use App\Models\StandaloneDocker; use App\Models\SwarmDocker; @@ -20,8 +20,7 @@ class DockerImage extends Component protected $rules = [ 'dockerImage' => 'required|string', - 'selectedRegistry' => 'nullable|required_if:useCustomRegistry,true', - 'useCustomRegistry' => 'boolean' + 'selectedRegistry' => 'required_if:useCustomRegistry,true|nullable|exists:docker_registries,id' ]; public function mount() @@ -62,7 +61,7 @@ class DockerImage extends Component 'docker_registry_image_name' => $image, 'docker_registry_image_tag' => $tag, 'docker_use_custom_registry' => $this->useCustomRegistry, - 'docker_registry_id' => $this->selectedRegistry, + 'docker_registry_id' => $this->selectedRegistry ?? null, 'environment_id' => $environment->id, 'destination_id' => $destination->id, 'destination_type' => $destination_class, @@ -85,7 +84,7 @@ class DockerImage extends Component public function render() { return view('livewire.project.new.docker-image', [ - 'registries' => Registry::all() + 'registries' => DockerRegistry::all() ]); } } diff --git a/app/Models/Application.php b/app/Models/Application.php index 5cd1eb99b..6ecc5f202 100644 --- a/app/Models/Application.php +++ b/app/Models/Application.php @@ -1536,6 +1536,6 @@ class Application extends BaseModel public function registry() { - return $this->belongsTo(Registry::class); + return $this->belongsTo(DockerRegistry::class); } } diff --git a/app/Models/Registry.php b/app/Models/DockerRegistry.php similarity index 72% rename from app/Models/Registry.php rename to app/Models/DockerRegistry.php index 8793815a2..c3638d0ad 100644 --- a/app/Models/Registry.php +++ b/app/Models/DockerRegistry.php @@ -5,16 +5,10 @@ namespace App\Models; use Illuminate\Database\Eloquent\Model; use Illuminate\Database\Eloquent\Relations\HasMany; -class Registry extends Model +// #[OA\Schema( +class DockerRegistry extends Model { - protected $fillable = [ - 'name', - 'type', - 'url', - 'username', - 'token', - 'is_default' - ]; + protected $guarded = []; protected $casts = [ 'is_default' => 'boolean', @@ -34,6 +28,6 @@ class Registry extends Model public function applications(): HasMany { - return $this->hasMany(Application::class); + return $this->hasMany(Application::class, 'docker_registry_id', 'id'); } } diff --git a/database/migrations/2024_11_10_203115_create_registries_table.php b/database/migrations/2024_11_10_203115_create_registries_table.php index 01cb3e654..cc71abc06 100644 --- a/database/migrations/2024_11_10_203115_create_registries_table.php +++ b/database/migrations/2024_11_10_203115_create_registries_table.php @@ -14,7 +14,6 @@ return new class extends Migration { $table->string('url')->nullable(); $table->string('username')->nullable(); $table->text('token')->nullable(); - $table->boolean('is_default')->default(false); $table->timestamps(); }); diff --git a/resources/views/components/images/navbar.blade.php b/resources/views/components/images/navbar.blade.php new file mode 100644 index 000000000..c13b94c95 --- /dev/null +++ b/resources/views/components/images/navbar.blade.php @@ -0,0 +1,14 @@ +