fix: docker image parser

This commit is contained in:
Andras Bacsai
2025-01-20 13:57:12 +01:00
parent f35f45324b
commit 57f61d4589
3 changed files with 175 additions and 8 deletions

View File

@@ -6,6 +6,7 @@ use App\Models\Application;
use App\Models\Project;
use App\Models\StandaloneDocker;
use App\Models\SwarmDocker;
use App\Services\DockerImageParser;
use Livewire\Component;
use Visus\Cuid2\Cuid2;
@@ -28,12 +29,10 @@ class DockerImage extends Component
$this->validate([
'dockerImage' => 'required',
]);
$image = str($this->dockerImage)->before(':');
if (str($this->dockerImage)->contains(':')) {
$tag = str($this->dockerImage)->after(':');
} else {
$tag = 'latest';
}
$parser = new DockerImageParser;
$parser->parse($this->dockerImage);
$destination_uuid = $this->query['destination'];
$destination = StandaloneDocker::where('uuid', $destination_uuid)->first();
if (! $destination) {
@@ -53,8 +52,8 @@ class DockerImage extends Component
'git_branch' => 'main',
'build_pack' => 'dockerimage',
'ports_exposes' => 80,
'docker_registry_image_name' => $image,
'docker_registry_image_tag' => $tag,
'docker_registry_image_name' => $parser->getFullImageNameWithoutTag(),
'docker_registry_image_tag' => $parser->getTag(),
'environment_id' => $environment->id,
'destination_id' => $destination->id,
'destination_type' => $destination_class,

View File

@@ -0,0 +1,74 @@
<?php
namespace App\Services;
class DockerImageParser
{
private string $registryUrl = '';
private string $imageName = '';
private string $tag = 'latest';
public function parse(string $imageString): self
{
// First split by : to handle the tag, but be careful with registry ports
$lastColon = strrpos($imageString, ':');
$hasSlash = str_contains($imageString, '/');
// If the last colon appears after the last slash, it's a tag
// Otherwise it might be a port in the registry URL
if ($lastColon !== false && (! $hasSlash || $lastColon > strrpos($imageString, '/'))) {
$mainPart = substr($imageString, 0, $lastColon);
$this->tag = substr($imageString, $lastColon + 1);
} else {
$mainPart = $imageString;
$this->tag = 'latest';
}
// Split the main part by / to handle registry and image name
$pathParts = explode('/', $mainPart);
// If we have more than one part and the first part contains a dot or colon
// it's likely a registry URL
if (count($pathParts) > 1 && (str_contains($pathParts[0], '.') || str_contains($pathParts[0], ':'))) {
$this->registryUrl = array_shift($pathParts);
$this->imageName = implode('/', $pathParts);
} else {
$this->imageName = $mainPart;
}
return $this;
}
public function getFullImageNameWithoutTag(): string
{
return $this->registryUrl.'/'.$this->imageName;
}
public function getRegistryUrl(): string
{
return $this->registryUrl;
}
public function getImageName(): string
{
return $this->imageName;
}
public function getTag(): string
{
return $this->tag;
}
public function toString(): string
{
$parts = [];
if ($this->registryUrl) {
$parts[] = $this->registryUrl;
}
$parts[] = $this->imageName;
return implode('/', $parts).':'.$this->tag;
}
}