From 1f3d0fb8044368780e8fb26cd6d2c97f4bc75a85 Mon Sep 17 00:00:00 2001 From: Tony Messias Date: Fri, 20 Sep 2024 19:00:11 -0300 Subject: [PATCH 01/12] Adds a shell {service} command --- app/Commands/ShellCommand.php | 29 ++++++++++++++++++++ app/Services/BaseService.php | 50 ++++++++++++++++++++++++++++++----- app/Services/Beanstalkd.php | 7 +++++ app/Services/Buggregator.php | 10 +++++++ app/Services/MailDev.php | 8 ++++++ app/Services/MailHog.php | 8 ++++++ app/Services/Mailpit.php | 8 ++++++ app/Services/MeiliSearch.php | 8 ++++++ app/Services/Soketi.php | 10 +++++++ app/Services/Traefik.php | 5 ++++ app/Shell/Docker.php | 36 +++++++++++++++++-------- 11 files changed, 161 insertions(+), 18 deletions(-) create mode 100644 app/Commands/ShellCommand.php diff --git a/app/Commands/ShellCommand.php b/app/Commands/ShellCommand.php new file mode 100644 index 00000000..65b5d690 --- /dev/null +++ b/app/Commands/ShellCommand.php @@ -0,0 +1,29 @@ +initializecommand(); + + $service = $services->get($this->argument('service')); + + resolve($service)->forwardShell(); + + return self::SUCCESS; + } +} diff --git a/app/Services/BaseService.php b/app/Services/BaseService.php index 9563994f..a878959f 100644 --- a/app/Services/BaseService.php +++ b/app/Services/BaseService.php @@ -7,6 +7,7 @@ use App\Shell\Environment; use App\Shell\Shell; use App\WritesToConsole; +use Exception; use Illuminate\Support\Str; use Throwable; @@ -15,14 +16,21 @@ abstract class BaseService use WritesToConsole; protected static $category; + protected static $displayName; protected $organization = 'library'; // Official repositories use `library` as the organization name. + protected $imageName; + protected $dockerTagsClass = DockerTags::class; + protected $tag; + protected $dockerRunTemplate; + protected $defaultPort; + protected $defaultPrompts = [ [ 'shortname' => 'port', @@ -35,11 +43,17 @@ abstract class BaseService 'default' => 'latest', ], ]; + protected $prompts = []; + protected $promptResponses = []; + protected $shell; + protected $environment; + protected $docker; + protected $useDefaults = false; public function __construct(Shell $shell, Environment $environment, Docker $docker) @@ -67,7 +81,7 @@ public static function name(): string return static::$displayName ?? Str::afterLast(static::class, '\\'); } - public function enable(bool $useDefaults = false, array $passthroughOptions = [], string $runOptions = null): void + public function enable(bool $useDefaults = false, array $passthroughOptions = [], ?string $runOptions = null): void { $this->useDefaults = $useDefaults; @@ -79,7 +93,7 @@ public function enable(bool $useDefaults = false, array $passthroughOptions = [] try { $this->docker->bootContainer( - join(' ', array_filter([ + implode(' ', array_filter([ $runOptions, $this->sanitizeDockerRunTemplate($this->dockerRunTemplate), $this->buildPassthroughOptionsString($passthroughOptions), @@ -89,8 +103,30 @@ public function enable(bool $useDefaults = false, array $passthroughOptions = [] $this->info("\nService enabled!"); } catch (Throwable $e) { - $this->error("\n" . $e->getMessage()); + $this->error("\n".$e->getMessage()); + } + } + + public function forwardShell(): void + { + if (! $this->docker->isDockerServiceRunning()) { + throw new Exception('Docker is not running.'); + } + + $service = $this->docker->takeoutContainers()->first(function ($container) { + return str_starts_with($container['names'], "TO--{$this->shortName()}--"); + }); + + if (! $service) { + throw new Exception(sprintf('Service %s is not enabled.', $this->shortName())); } + + $this->docker->forwardShell($service['container_id'], $this->shellCommand()); + } + + protected function shellCommand(): string + { + return 'bash'; } public function organization(): string @@ -200,13 +236,13 @@ protected function shortNameWithVersion(): string // Check if tag represents semantic version (v5.6.0, 5.7.4, or 8.0) and return major.minor // (eg mysql5.7) or return the actual tag prefixed by a dash (eg redis-buster) if (! preg_match('/v?(0|(?:[1-9]\d*))(?:\.(0|(?:[1-9]\d*))(?:\.(0|(?:[1-9]\d*)))?)/', $this->tag)) { - return $this->shortName() . "-{$this->tag}"; + return $this->shortName()."-{$this->tag}"; } $version = trim($this->tag, 'v'); [$major, $minor] = explode('.', $version); - return $this->shortName() . "{$major}.{$minor}"; + return $this->shortName()."{$major}.{$minor}"; } protected function containerName(): string @@ -218,7 +254,7 @@ protected function containerName(): string } } - return 'TO--' . $this->shortName() . '--' . $this->tag . $portTag; + return 'TO--'.$this->shortName().'--'.$this->tag.$portTag; } public function sanitizeDockerRunTemplate($dockerRunTemplate): string @@ -236,6 +272,6 @@ public function buildPassthroughOptionsString(array $passthroughOptions): string return ''; } - return join(' ', $passthroughOptions); + return implode(' ', $passthroughOptions); } } diff --git a/app/Services/Beanstalkd.php b/app/Services/Beanstalkd.php index 15ee4544..6156fbc7 100644 --- a/app/Services/Beanstalkd.php +++ b/app/Services/Beanstalkd.php @@ -7,9 +7,16 @@ class Beanstalkd extends BaseService protected static $category = Category::CACHE; protected $organization = 'schickling'; + protected $imageName = 'beanstalkd'; + protected $defaultPort = 11300; protected $dockerRunTemplate = '-p "${:port}":11300 \ "${:organization}"/"${:image_name}":"${:tag}"'; + + protected function shellCommand(): string + { + return 'sh'; + } } diff --git a/app/Services/Buggregator.php b/app/Services/Buggregator.php index be517996..6a9bcc20 100644 --- a/app/Services/Buggregator.php +++ b/app/Services/Buggregator.php @@ -9,10 +9,15 @@ class Buggregator extends BaseService protected static $category = Category::TOOLS; protected $dockerTagsClass = GitHubDockerTags::class; + protected $organization = 'ghcr.io'; + protected $imageName = 'buggregator/server'; + protected $tag = 'latest'; + protected $defaultPort = 8000; + protected $prompts = [ [ 'shortname' => 'smtp_port', @@ -42,4 +47,9 @@ class Buggregator extends BaseService -p "${:monolog_port}":9913 \ --network-alias "${:network_alias}" \ "${:organization}"/"${:image_name}":"${:tag}"'; + + protected function shellCommand(): string + { + return 'sh'; + } } diff --git a/app/Services/MailDev.php b/app/Services/MailDev.php index 3bd42753..7958d98f 100644 --- a/app/Services/MailDev.php +++ b/app/Services/MailDev.php @@ -7,8 +7,11 @@ class MailDev extends BaseService protected static $category = Category::MAIL; protected $organization = 'maildev'; + protected $imageName = 'maildev'; + protected $defaultPort = 1025; + protected $prompts = [ [ 'shortname' => 'web_port', @@ -20,4 +23,9 @@ class MailDev extends BaseService protected $dockerRunTemplate = '-p "${:port}":1025 \ -p "${:web_port}":1080 \ "${:organization}"/"${:image_name}":"${:tag}"'; + + protected function shellCommand(): string + { + return 'sh'; + } } diff --git a/app/Services/MailHog.php b/app/Services/MailHog.php index a1dd2576..a3268971 100644 --- a/app/Services/MailHog.php +++ b/app/Services/MailHog.php @@ -7,8 +7,11 @@ class MailHog extends BaseService protected static $category = Category::MAIL; protected $organization = 'mailhog'; + protected $imageName = 'mailhog'; + protected $defaultPort = 1025; + protected $prompts = [ [ 'shortname' => 'web_port', @@ -20,4 +23,9 @@ class MailHog extends BaseService protected $dockerRunTemplate = '-p "${:port}":1025 \ -p "${:web_port}":8025 \ "${:organization}"/"${:image_name}":"${:tag}"'; + + protected function shellCommand(): string + { + return 'sh'; + } } diff --git a/app/Services/Mailpit.php b/app/Services/Mailpit.php index effea528..609ba5e7 100644 --- a/app/Services/Mailpit.php +++ b/app/Services/Mailpit.php @@ -7,8 +7,11 @@ class Mailpit extends BaseService protected static $category = Category::MAIL; protected $organization = 'axllent'; + protected $imageName = 'mailpit'; + protected $defaultPort = 1025; + protected $prompts = [ [ 'shortname' => 'web_port', @@ -20,4 +23,9 @@ class Mailpit extends BaseService protected $dockerRunTemplate = '-p "${:port}":1025 \ -p "${:web_port}":8025 \ "${:organization}"/"${:image_name}":"${:tag}"'; + + protected function shellCommand(): string + { + return 'sh'; + } } diff --git a/app/Services/MeiliSearch.php b/app/Services/MeiliSearch.php index 441c8ebc..0c9ba902 100644 --- a/app/Services/MeiliSearch.php +++ b/app/Services/MeiliSearch.php @@ -7,8 +7,11 @@ class MeiliSearch extends BaseService protected static $category = Category::SEARCH; protected $organization = 'getmeili'; + protected $imageName = 'meilisearch'; + protected $defaultPort = 7700; + protected $prompts = [ [ 'shortname' => 'volume', @@ -20,4 +23,9 @@ class MeiliSearch extends BaseService protected $dockerRunTemplate = '-p "${:port}":7700 \ -v "${:volume}":/data.ms \ "${:organization}"/"${:image_name}":"${:tag}"'; + + protected function shellCommand(): string + { + return 'sh'; + } } diff --git a/app/Services/Soketi.php b/app/Services/Soketi.php index 342c2c88..f210783d 100644 --- a/app/Services/Soketi.php +++ b/app/Services/Soketi.php @@ -12,10 +12,15 @@ class Soketi extends BaseService protected static $category = Category::SOCKET; protected $dockerTagsClass = QuayDockerTags::class; + protected $organization = 'quay.io'; + protected $imageName = 'soketi/soketi'; + protected $tag = 'latest-16-alpine'; + protected $defaultPort = 6001; + protected $prompts = [ [ 'shortname' => 'metrics_port', @@ -41,4 +46,9 @@ public function __construct(Shell $shell, Environment $environment, Docker $dock return $prompt; }, $this->defaultPrompts); } + + protected function shellCommand(): string + { + return 'sh'; + } } diff --git a/app/Services/Traefik.php b/app/Services/Traefik.php index f2009cef..a32911e3 100644 --- a/app/Services/Traefik.php +++ b/app/Services/Traefik.php @@ -64,6 +64,11 @@ public function __construct(Shell $shell, Environment $environment, Docker $dock }, $this->prompts); } + protected function shellCommand(): string + { + return 'sh'; + } + protected function prompts(): void { parent::prompts(); diff --git a/app/Shell/Docker.php b/app/Shell/Docker.php index bca1ba73..8e2e7f45 100644 --- a/app/Shell/Docker.php +++ b/app/Shell/Docker.php @@ -3,7 +3,6 @@ namespace App\Shell; use App\Exceptions\DockerContainerMissingException; -use App\Shell\Environment; use Exception; use Illuminate\Support\Collection; use Illuminate\Support\Str; @@ -11,8 +10,11 @@ class Docker { protected $shell; + protected $formatter; + protected $networking; + protected $environment; public function __construct( @@ -35,10 +37,10 @@ public function removeContainer(string $containerId): void $this->stopContainer($containerId); } - $process = $this->shell->exec('docker rm ' . $containerId); + $process = $this->shell->exec('docker rm '.$containerId); if (! $process->isSuccessful()) { - throw new Exception('Failed removing container ' . $containerId); + throw new Exception('Failed removing container '.$containerId); } } @@ -50,10 +52,10 @@ public function stopContainer(string $containerId): void throw new DockerContainerMissingException($containerId); } - $process = $this->shell->exec('docker stop ' . $containerId); + $process = $this->shell->exec('docker stop '.$containerId); if (! $process->isSuccessful()) { - throw new Exception('Failed stopping container ' . $containerId); + throw new Exception('Failed stopping container '.$containerId); } } @@ -65,10 +67,10 @@ public function logContainer(string $containerId): void throw new DockerContainerMissingException($containerId); } - $process = $this->shell->exec('docker logs -f ' . $containerId); + $process = $this->shell->exec('docker logs -f '.$containerId); if (! $process->isSuccessful()) { - throw new Exception('Failed to log container ' . $containerId); + throw new Exception('Failed to log container '.$containerId); } } @@ -80,10 +82,10 @@ public function startContainer(string $containerId): void throw new DockerContainerMissingException($containerId); } - $process = $this->shell->exec('docker start ' . $containerId); + $process = $this->shell->exec('docker start '.$containerId); if (! $process->isSuccessful()) { - throw new Exception('Failed starting container ' . $containerId); + throw new Exception('Failed starting container '.$containerId); } } @@ -169,7 +171,7 @@ public function bootContainer(string $dockerRunTemplate, array $parameters): voi $process = $this->shell->exec($command, $parameters); if (! $process->isSuccessful()) { - throw new Exception('Failed installing ' . $parameters['image_name']); + throw new Exception('Failed installing '.$parameters['image_name']); } } @@ -196,10 +198,22 @@ public function stopDockerService(): void $this->shell->execQuietly('systemctl stop docker'); } else { // BSD, Solaris, Unknown - throw new Exception('Cannot stop Docker in PHP_OS_FAMILY ' . PHP_OS_FAMILY); + throw new Exception('Cannot stop Docker in PHP_OS_FAMILY '.PHP_OS_FAMILY); } } + public function forwardShell(string $containerId, string $shellCommand): void + { + $command = $this->shell->buildProcess(sprintf( + 'docker exec -it "%s" %s', + $containerId, $shellCommand, + )); + + $command->setTty(true); + $command->setTimeout(null); + $command->run(); + } + protected function runAndParseTable(string $command): Collection { return $this->formatter->rawTableOutputToCollection( From 16b4817e7386116d0f1182938889b6ee1524b752 Mon Sep 17 00:00:00 2001 From: Tony Messias Date: Fri, 20 Sep 2024 19:00:32 -0300 Subject: [PATCH 02/12] Fix CouchDB now seems to require user and password to run the image --- app/Services/CouchDB.php | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/app/Services/CouchDB.php b/app/Services/CouchDB.php index a8c92ead..269f05f5 100644 --- a/app/Services/CouchDB.php +++ b/app/Services/CouchDB.php @@ -7,17 +7,31 @@ class CouchDB extends BaseService protected static $category = Category::DATABASE; protected $imageName = 'couchdb'; + protected $defaultPort = 5984; + protected $prompts = [ [ 'shortname' => 'volume', 'prompt' => 'What is the Docker volume name?', 'default' => 'couchdb_data', ], + [ + 'shortname' => 'user', + 'prompt' => 'What is the CouchDB User?', + 'default' => 'couchdb', + ], + [ + 'shortname' => 'password', + 'prompt' => 'What is the CouchDB Password?', + 'default' => 'password', + ], ]; protected $dockerRunTemplate = '-p "${:port}":5984 \ -v "${:volume}":/opt/couchdb/data \ + -e COUCHDB_USER="${:user}" \ + -e COUCHDB_PASSWORD="${:password}" \ "${:organization}"/"${:image_name}":"${:tag}"'; protected static $displayName = 'CouchDB'; From 3c3f5ba894ecfca0889ff8a551ce9acd3c68c856 Mon Sep 17 00:00:00 2001 From: Tony Messias Date: Fri, 20 Sep 2024 19:00:56 -0300 Subject: [PATCH 03/12] Fix EventStoreDB no longer supports these flags --- app/Services/EventStoreDB.php | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/app/Services/EventStoreDB.php b/app/Services/EventStoreDB.php index 93f648bc..2e1f782d 100644 --- a/app/Services/EventStoreDB.php +++ b/app/Services/EventStoreDB.php @@ -7,8 +7,11 @@ class EventStoreDB extends BaseService protected static $category = Category::DATABASE; protected $organization = 'eventstore'; + protected $imageName = 'eventstore'; + protected $defaultPort = 1113; + protected $prompts = [ [ 'shortname' => 'web_port', @@ -25,7 +28,6 @@ class EventStoreDB extends BaseService protected $dockerRunTemplate = '-p "${:port}":1113 \ -p "${:web_port}":2113 \ -v "${:volume}":/var/lib/eventstore \ - "${:organization}"/"${:image_name}":"${:tag}" \ - --insecure --run-projections=All \ - --enable-external-tcp --enable-atom-pub-over-http'; + "${:organization}"/"${:image_name}":latest \ + --insecure --run-projections=All'; } From bfc7d7c77a27b7fd7aaddbb09690170d1f0c0b8f Mon Sep 17 00:00:00 2001 From: Tony Messias Date: Fri, 20 Sep 2024 19:01:15 -0300 Subject: [PATCH 04/12] Fix OpenSearch should disable security plugins by default --- app/Services/OpenSearch.php | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/app/Services/OpenSearch.php b/app/Services/OpenSearch.php index f47ea566..8b340199 100644 --- a/app/Services/OpenSearch.php +++ b/app/Services/OpenSearch.php @@ -7,8 +7,11 @@ class OpenSearch extends BaseService protected static $category = Category::SEARCH; protected $organization = 'opensearchproject'; + protected $imageName = 'opensearch'; + protected $defaultPort = 9200; + protected $prompts = [ [ 'shortname' => 'volume', @@ -23,7 +26,7 @@ class OpenSearch extends BaseService [ 'shortname' => 'disable_security', 'prompt' => 'Disable security plugin (true or false)?', - 'default' => 'false', + 'default' => 'true', ], ]; From abcd30ca320867c02c07aabf88e88197e0f2eb02 Mon Sep 17 00:00:00 2001 From: Tony Messias Date: Fri, 20 Sep 2024 19:04:36 -0300 Subject: [PATCH 05/12] Adds docs --- README.md | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/README.md b/README.md index 307c691b..3412e41e 100644 --- a/README.md +++ b/README.md @@ -169,6 +169,24 @@ takeout stop {container_id} takeout stop {container_id1} {container_id2} ``` +### Get a shell inside any Takeout container + +To get a shell inside any container that is started with Takeout, you may run: + +```bash +takeout shell {service} +``` + +Here are some examples: + +```bash +takeout shell mysql +takeout shell neo4j +takeotu shell pgvector +``` + +This will reuse the running container. Takeout will start either a `bash` or a `sh` process inside the container, depending on what the container supports (this is automatically handled by Takeout). + ## Running multiple versions of a dependency Another of Takeout's benefits is that it allows you to have multiple versions of a dependency installed and running at the same time. That means, for example, that you can run both MySQL 5.7 and 8.0 at the same time, on different ports. From f59b8944cd3485622b586be63100567d9ea7ea64 Mon Sep 17 00:00:00 2001 From: Tony Messias Date: Fri, 20 Sep 2024 19:06:29 -0300 Subject: [PATCH 06/12] Fix tests --- tests/Feature/DockerTagsTest.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/Feature/DockerTagsTest.php b/tests/Feature/DockerTagsTest.php index 796d4c4e..351cc57a 100644 --- a/tests/Feature/DockerTagsTest.php +++ b/tests/Feature/DockerTagsTest.php @@ -42,7 +42,7 @@ function it_sorts_the_versions_naturally() $tags = collect($dockerTags->getTags()); $this->assertEquals('latest', $tags->shift()); - $this->assertEquals('16.3', $tags->shift()); + $this->assertEquals('16.4', $tags->shift()); } /** @test */ From e5016820fc061d07d4ddbfcd1955dc8be4ac1f2f Mon Sep 17 00:00:00 2001 From: Tony Messias Date: Fri, 20 Sep 2024 19:07:12 -0300 Subject: [PATCH 07/12] Lint --- app/Services/BaseService.php | 8 ++++---- app/Shell/Docker.php | 23 ++++++++++++----------- 2 files changed, 16 insertions(+), 15 deletions(-) diff --git a/app/Services/BaseService.php b/app/Services/BaseService.php index a878959f..b75d3743 100644 --- a/app/Services/BaseService.php +++ b/app/Services/BaseService.php @@ -103,7 +103,7 @@ public function enable(bool $useDefaults = false, array $passthroughOptions = [] $this->info("\nService enabled!"); } catch (Throwable $e) { - $this->error("\n".$e->getMessage()); + $this->error("\n" . $e->getMessage()); } } @@ -236,13 +236,13 @@ protected function shortNameWithVersion(): string // Check if tag represents semantic version (v5.6.0, 5.7.4, or 8.0) and return major.minor // (eg mysql5.7) or return the actual tag prefixed by a dash (eg redis-buster) if (! preg_match('/v?(0|(?:[1-9]\d*))(?:\.(0|(?:[1-9]\d*))(?:\.(0|(?:[1-9]\d*)))?)/', $this->tag)) { - return $this->shortName()."-{$this->tag}"; + return $this->shortName() . "-{$this->tag}"; } $version = trim($this->tag, 'v'); [$major, $minor] = explode('.', $version); - return $this->shortName()."{$major}.{$minor}"; + return $this->shortName() . "{$major}.{$minor}"; } protected function containerName(): string @@ -254,7 +254,7 @@ protected function containerName(): string } } - return 'TO--'.$this->shortName().'--'.$this->tag.$portTag; + return 'TO--' . $this->shortName() . '--' . $this->tag . $portTag; } public function sanitizeDockerRunTemplate($dockerRunTemplate): string diff --git a/app/Shell/Docker.php b/app/Shell/Docker.php index 8e2e7f45..919aa2a4 100644 --- a/app/Shell/Docker.php +++ b/app/Shell/Docker.php @@ -37,10 +37,10 @@ public function removeContainer(string $containerId): void $this->stopContainer($containerId); } - $process = $this->shell->exec('docker rm '.$containerId); + $process = $this->shell->exec('docker rm ' . $containerId); if (! $process->isSuccessful()) { - throw new Exception('Failed removing container '.$containerId); + throw new Exception('Failed removing container ' . $containerId); } } @@ -52,10 +52,10 @@ public function stopContainer(string $containerId): void throw new DockerContainerMissingException($containerId); } - $process = $this->shell->exec('docker stop '.$containerId); + $process = $this->shell->exec('docker stop ' . $containerId); if (! $process->isSuccessful()) { - throw new Exception('Failed stopping container '.$containerId); + throw new Exception('Failed stopping container ' . $containerId); } } @@ -67,10 +67,10 @@ public function logContainer(string $containerId): void throw new DockerContainerMissingException($containerId); } - $process = $this->shell->exec('docker logs -f '.$containerId); + $process = $this->shell->exec('docker logs -f ' . $containerId); if (! $process->isSuccessful()) { - throw new Exception('Failed to log container '.$containerId); + throw new Exception('Failed to log container ' . $containerId); } } @@ -82,10 +82,10 @@ public function startContainer(string $containerId): void throw new DockerContainerMissingException($containerId); } - $process = $this->shell->exec('docker start '.$containerId); + $process = $this->shell->exec('docker start ' . $containerId); if (! $process->isSuccessful()) { - throw new Exception('Failed starting container '.$containerId); + throw new Exception('Failed starting container ' . $containerId); } } @@ -171,7 +171,7 @@ public function bootContainer(string $dockerRunTemplate, array $parameters): voi $process = $this->shell->exec($command, $parameters); if (! $process->isSuccessful()) { - throw new Exception('Failed installing '.$parameters['image_name']); + throw new Exception('Failed installing ' . $parameters['image_name']); } } @@ -198,7 +198,7 @@ public function stopDockerService(): void $this->shell->execQuietly('systemctl stop docker'); } else { // BSD, Solaris, Unknown - throw new Exception('Cannot stop Docker in PHP_OS_FAMILY '.PHP_OS_FAMILY); + throw new Exception('Cannot stop Docker in PHP_OS_FAMILY ' . PHP_OS_FAMILY); } } @@ -206,7 +206,8 @@ public function forwardShell(string $containerId, string $shellCommand): void { $command = $this->shell->buildProcess(sprintf( 'docker exec -it "%s" %s', - $containerId, $shellCommand, + $containerId, + $shellCommand, )); $command->setTty(true); From 0e1c0fe4c309ebbd470bfaa80fc6dc9e67480b39 Mon Sep 17 00:00:00 2001 From: Tony Messias Date: Fri, 4 Oct 2024 12:45:32 -0300 Subject: [PATCH 08/12] Apply suggestions from code review Co-authored-by: Matt Stauffer --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 3412e41e..bebba6f5 100644 --- a/README.md +++ b/README.md @@ -182,10 +182,10 @@ Here are some examples: ```bash takeout shell mysql takeout shell neo4j -takeotu shell pgvector +takeout shell pgvector ``` -This will reuse the running container. Takeout will start either a `bash` or a `sh` process inside the container, depending on what the container supports (this is automatically handled by Takeout). +This will open a shell inside the running container for the service you provide. Takeout will start either a `bash` or a `sh` process inside the container, depending on what the container supports. ## Running multiple versions of a dependency From b3e6cd7914f8efb82d4ab19ca3b2e1237d5c57b4 Mon Sep 17 00:00:00 2001 From: Tony Messias Date: Fri, 4 Oct 2024 13:03:47 -0300 Subject: [PATCH 09/12] Remove newline between properties --- app/Commands/ShellCommand.php | 1 - app/Services/BaseService.php | 14 -------------- app/Services/Beanstalkd.php | 4 ---- app/Services/Buggregator.php | 7 ------- app/Services/CouchDB.php | 5 ----- app/Services/EventStoreDB.php | 5 ----- app/Services/MailDev.php | 5 ----- app/Services/MailHog.php | 4 ---- app/Services/Mailpit.php | 4 ---- app/Services/MeiliSearch.php | 3 --- app/Services/OpenSearch.php | 3 --- app/Services/Soketi.php | 5 ----- app/Services/Traefik.php | 3 --- app/Shell/Docker.php | 3 --- 14 files changed, 66 deletions(-) diff --git a/app/Commands/ShellCommand.php b/app/Commands/ShellCommand.php index 65b5d690..cbafaac3 100644 --- a/app/Commands/ShellCommand.php +++ b/app/Commands/ShellCommand.php @@ -13,7 +13,6 @@ class ShellCommand extends Command const MENU_TITLE = 'Get a shell inside a running Takeout container.'; protected $signature = 'shell {service}'; - protected $description = 'Get a shell inside a running Takeout container.'; public function handle(Services $services): int diff --git a/app/Services/BaseService.php b/app/Services/BaseService.php index b75d3743..aa2ef819 100644 --- a/app/Services/BaseService.php +++ b/app/Services/BaseService.php @@ -16,21 +16,13 @@ abstract class BaseService use WritesToConsole; protected static $category; - protected static $displayName; - protected $organization = 'library'; // Official repositories use `library` as the organization name. - protected $imageName; - protected $dockerTagsClass = DockerTags::class; - protected $tag; - protected $dockerRunTemplate; - protected $defaultPort; - protected $defaultPrompts = [ [ 'shortname' => 'port', @@ -43,17 +35,11 @@ abstract class BaseService 'default' => 'latest', ], ]; - protected $prompts = []; - protected $promptResponses = []; - protected $shell; - protected $environment; - protected $docker; - protected $useDefaults = false; public function __construct(Shell $shell, Environment $environment, Docker $docker) diff --git a/app/Services/Beanstalkd.php b/app/Services/Beanstalkd.php index 6156fbc7..a4a967ae 100644 --- a/app/Services/Beanstalkd.php +++ b/app/Services/Beanstalkd.php @@ -5,13 +5,9 @@ class Beanstalkd extends BaseService { protected static $category = Category::CACHE; - protected $organization = 'schickling'; - protected $imageName = 'beanstalkd'; - protected $defaultPort = 11300; - protected $dockerRunTemplate = '-p "${:port}":11300 \ "${:organization}"/"${:image_name}":"${:tag}"'; diff --git a/app/Services/Buggregator.php b/app/Services/Buggregator.php index 6a9bcc20..e073a301 100644 --- a/app/Services/Buggregator.php +++ b/app/Services/Buggregator.php @@ -7,17 +7,11 @@ class Buggregator extends BaseService { protected static $category = Category::TOOLS; - protected $dockerTagsClass = GitHubDockerTags::class; - protected $organization = 'ghcr.io'; - protected $imageName = 'buggregator/server'; - protected $tag = 'latest'; - protected $defaultPort = 8000; - protected $prompts = [ [ 'shortname' => 'smtp_port', @@ -40,7 +34,6 @@ class Buggregator extends BaseService 'default' => 'buggregator', ], ]; - protected $dockerRunTemplate = '-p "${:port}":8000 \ -p "${:smtp_port}":1025 \ -p "${:var_dumper_port}":9912 \ diff --git a/app/Services/CouchDB.php b/app/Services/CouchDB.php index 269f05f5..927c0810 100644 --- a/app/Services/CouchDB.php +++ b/app/Services/CouchDB.php @@ -5,11 +5,8 @@ class CouchDB extends BaseService { protected static $category = Category::DATABASE; - protected $imageName = 'couchdb'; - protected $defaultPort = 5984; - protected $prompts = [ [ 'shortname' => 'volume', @@ -27,12 +24,10 @@ class CouchDB extends BaseService 'default' => 'password', ], ]; - protected $dockerRunTemplate = '-p "${:port}":5984 \ -v "${:volume}":/opt/couchdb/data \ -e COUCHDB_USER="${:user}" \ -e COUCHDB_PASSWORD="${:password}" \ "${:organization}"/"${:image_name}":"${:tag}"'; - protected static $displayName = 'CouchDB'; } diff --git a/app/Services/EventStoreDB.php b/app/Services/EventStoreDB.php index 2e1f782d..6fb680b7 100644 --- a/app/Services/EventStoreDB.php +++ b/app/Services/EventStoreDB.php @@ -5,13 +5,9 @@ class EventStoreDB extends BaseService { protected static $category = Category::DATABASE; - protected $organization = 'eventstore'; - protected $imageName = 'eventstore'; - protected $defaultPort = 1113; - protected $prompts = [ [ 'shortname' => 'web_port', @@ -24,7 +20,6 @@ class EventStoreDB extends BaseService 'default' => 'eventstore_data', ], ]; - protected $dockerRunTemplate = '-p "${:port}":1113 \ -p "${:web_port}":2113 \ -v "${:volume}":/var/lib/eventstore \ diff --git a/app/Services/MailDev.php b/app/Services/MailDev.php index 7958d98f..f4809aa9 100644 --- a/app/Services/MailDev.php +++ b/app/Services/MailDev.php @@ -5,13 +5,9 @@ class MailDev extends BaseService { protected static $category = Category::MAIL; - protected $organization = 'maildev'; - protected $imageName = 'maildev'; - protected $defaultPort = 1025; - protected $prompts = [ [ 'shortname' => 'web_port', @@ -19,7 +15,6 @@ class MailDev extends BaseService 'default' => '1080', ], ]; - protected $dockerRunTemplate = '-p "${:port}":1025 \ -p "${:web_port}":1080 \ "${:organization}"/"${:image_name}":"${:tag}"'; diff --git a/app/Services/MailHog.php b/app/Services/MailHog.php index a3268971..1b909e85 100644 --- a/app/Services/MailHog.php +++ b/app/Services/MailHog.php @@ -7,11 +7,8 @@ class MailHog extends BaseService protected static $category = Category::MAIL; protected $organization = 'mailhog'; - protected $imageName = 'mailhog'; - protected $defaultPort = 1025; - protected $prompts = [ [ 'shortname' => 'web_port', @@ -19,7 +16,6 @@ class MailHog extends BaseService 'default' => '8025', ], ]; - protected $dockerRunTemplate = '-p "${:port}":1025 \ -p "${:web_port}":8025 \ "${:organization}"/"${:image_name}":"${:tag}"'; diff --git a/app/Services/Mailpit.php b/app/Services/Mailpit.php index 609ba5e7..19ec8191 100644 --- a/app/Services/Mailpit.php +++ b/app/Services/Mailpit.php @@ -7,11 +7,8 @@ class Mailpit extends BaseService protected static $category = Category::MAIL; protected $organization = 'axllent'; - protected $imageName = 'mailpit'; - protected $defaultPort = 1025; - protected $prompts = [ [ 'shortname' => 'web_port', @@ -19,7 +16,6 @@ class Mailpit extends BaseService 'default' => '8025', ], ]; - protected $dockerRunTemplate = '-p "${:port}":1025 \ -p "${:web_port}":8025 \ "${:organization}"/"${:image_name}":"${:tag}"'; diff --git a/app/Services/MeiliSearch.php b/app/Services/MeiliSearch.php index 0c9ba902..26a50487 100644 --- a/app/Services/MeiliSearch.php +++ b/app/Services/MeiliSearch.php @@ -7,11 +7,8 @@ class MeiliSearch extends BaseService protected static $category = Category::SEARCH; protected $organization = 'getmeili'; - protected $imageName = 'meilisearch'; - protected $defaultPort = 7700; - protected $prompts = [ [ 'shortname' => 'volume', diff --git a/app/Services/OpenSearch.php b/app/Services/OpenSearch.php index 8b340199..62bcfe82 100644 --- a/app/Services/OpenSearch.php +++ b/app/Services/OpenSearch.php @@ -7,11 +7,8 @@ class OpenSearch extends BaseService protected static $category = Category::SEARCH; protected $organization = 'opensearchproject'; - protected $imageName = 'opensearch'; - protected $defaultPort = 9200; - protected $prompts = [ [ 'shortname' => 'volume', diff --git a/app/Services/Soketi.php b/app/Services/Soketi.php index f210783d..92507887 100644 --- a/app/Services/Soketi.php +++ b/app/Services/Soketi.php @@ -12,15 +12,10 @@ class Soketi extends BaseService protected static $category = Category::SOCKET; protected $dockerTagsClass = QuayDockerTags::class; - protected $organization = 'quay.io'; - protected $imageName = 'soketi/soketi'; - protected $tag = 'latest-16-alpine'; - protected $defaultPort = 6001; - protected $prompts = [ [ 'shortname' => 'metrics_port', diff --git a/app/Services/Traefik.php b/app/Services/Traefik.php index a32911e3..a623aa5e 100644 --- a/app/Services/Traefik.php +++ b/app/Services/Traefik.php @@ -12,11 +12,8 @@ class Traefik extends BaseService protected static $category = Category::TOOLS; protected $imageName = 'traefik'; - protected $defaultTag = 'v2.10'; - protected $defaultPort = 8080; - protected $prompts = [ [ 'shortname' => 'config_dir', diff --git a/app/Shell/Docker.php b/app/Shell/Docker.php index 919aa2a4..d183ad3e 100644 --- a/app/Shell/Docker.php +++ b/app/Shell/Docker.php @@ -10,11 +10,8 @@ class Docker { protected $shell; - protected $formatter; - protected $networking; - protected $environment; public function __construct( From 14b3a58c295ebd8d7de95a1377c5f0e17c483469 Mon Sep 17 00:00:00 2001 From: Tony Messias Date: Fri, 4 Oct 2024 13:05:47 -0300 Subject: [PATCH 10/12] Revert the join to implode and using nullable types --- app/Services/BaseService.php | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/app/Services/BaseService.php b/app/Services/BaseService.php index aa2ef819..62a68a6e 100644 --- a/app/Services/BaseService.php +++ b/app/Services/BaseService.php @@ -17,6 +17,7 @@ abstract class BaseService protected static $category; protected static $displayName; + protected $organization = 'library'; // Official repositories use `library` as the organization name. protected $imageName; protected $dockerTagsClass = DockerTags::class; @@ -67,7 +68,7 @@ public static function name(): string return static::$displayName ?? Str::afterLast(static::class, '\\'); } - public function enable(bool $useDefaults = false, array $passthroughOptions = [], ?string $runOptions = null): void + public function enable(bool $useDefaults = false, array $passthroughOptions = [], string $runOptions = null): void { $this->useDefaults = $useDefaults; @@ -79,7 +80,7 @@ public function enable(bool $useDefaults = false, array $passthroughOptions = [] try { $this->docker->bootContainer( - implode(' ', array_filter([ + join(' ', array_filter([ $runOptions, $this->sanitizeDockerRunTemplate($this->dockerRunTemplate), $this->buildPassthroughOptionsString($passthroughOptions), @@ -258,6 +259,6 @@ public function buildPassthroughOptionsString(array $passthroughOptions): string return ''; } - return implode(' ', $passthroughOptions); + return join(' ', $passthroughOptions); } } From bbb8275f34307eaa344fa7dcf593e21763249505 Mon Sep 17 00:00:00 2001 From: Tony Messias Date: Fri, 4 Oct 2024 13:08:17 -0300 Subject: [PATCH 11/12] Fix newline in some properties grouping --- app/Services/Beanstalkd.php | 2 ++ app/Services/Buggregator.php | 2 ++ app/Services/CouchDB.php | 3 +++ app/Services/EventStoreDB.php | 2 ++ app/Services/MailDev.php | 2 ++ app/Services/MailHog.php | 1 + app/Services/Mailpit.php | 1 + 7 files changed, 13 insertions(+) diff --git a/app/Services/Beanstalkd.php b/app/Services/Beanstalkd.php index a4a967ae..4a6afb78 100644 --- a/app/Services/Beanstalkd.php +++ b/app/Services/Beanstalkd.php @@ -5,9 +5,11 @@ class Beanstalkd extends BaseService { protected static $category = Category::CACHE; + protected $organization = 'schickling'; protected $imageName = 'beanstalkd'; protected $defaultPort = 11300; + protected $dockerRunTemplate = '-p "${:port}":11300 \ "${:organization}"/"${:image_name}":"${:tag}"'; diff --git a/app/Services/Buggregator.php b/app/Services/Buggregator.php index e073a301..d5290519 100644 --- a/app/Services/Buggregator.php +++ b/app/Services/Buggregator.php @@ -7,6 +7,7 @@ class Buggregator extends BaseService { protected static $category = Category::TOOLS; + protected $dockerTagsClass = GitHubDockerTags::class; protected $organization = 'ghcr.io'; protected $imageName = 'buggregator/server'; @@ -34,6 +35,7 @@ class Buggregator extends BaseService 'default' => 'buggregator', ], ]; + protected $dockerRunTemplate = '-p "${:port}":8000 \ -p "${:smtp_port}":1025 \ -p "${:var_dumper_port}":9912 \ diff --git a/app/Services/CouchDB.php b/app/Services/CouchDB.php index 927c0810..9c4f7974 100644 --- a/app/Services/CouchDB.php +++ b/app/Services/CouchDB.php @@ -5,6 +5,7 @@ class CouchDB extends BaseService { protected static $category = Category::DATABASE; + protected $imageName = 'couchdb'; protected $defaultPort = 5984; protected $prompts = [ @@ -24,10 +25,12 @@ class CouchDB extends BaseService 'default' => 'password', ], ]; + protected $dockerRunTemplate = '-p "${:port}":5984 \ -v "${:volume}":/opt/couchdb/data \ -e COUCHDB_USER="${:user}" \ -e COUCHDB_PASSWORD="${:password}" \ "${:organization}"/"${:image_name}":"${:tag}"'; + protected static $displayName = 'CouchDB'; } diff --git a/app/Services/EventStoreDB.php b/app/Services/EventStoreDB.php index 6fb680b7..5191c031 100644 --- a/app/Services/EventStoreDB.php +++ b/app/Services/EventStoreDB.php @@ -5,6 +5,7 @@ class EventStoreDB extends BaseService { protected static $category = Category::DATABASE; + protected $organization = 'eventstore'; protected $imageName = 'eventstore'; protected $defaultPort = 1113; @@ -20,6 +21,7 @@ class EventStoreDB extends BaseService 'default' => 'eventstore_data', ], ]; + protected $dockerRunTemplate = '-p "${:port}":1113 \ -p "${:web_port}":2113 \ -v "${:volume}":/var/lib/eventstore \ diff --git a/app/Services/MailDev.php b/app/Services/MailDev.php index f4809aa9..e0e8dcb0 100644 --- a/app/Services/MailDev.php +++ b/app/Services/MailDev.php @@ -5,6 +5,7 @@ class MailDev extends BaseService { protected static $category = Category::MAIL; + protected $organization = 'maildev'; protected $imageName = 'maildev'; protected $defaultPort = 1025; @@ -15,6 +16,7 @@ class MailDev extends BaseService 'default' => '1080', ], ]; + protected $dockerRunTemplate = '-p "${:port}":1025 \ -p "${:web_port}":1080 \ "${:organization}"/"${:image_name}":"${:tag}"'; diff --git a/app/Services/MailHog.php b/app/Services/MailHog.php index 1b909e85..b389a1ca 100644 --- a/app/Services/MailHog.php +++ b/app/Services/MailHog.php @@ -16,6 +16,7 @@ class MailHog extends BaseService 'default' => '8025', ], ]; + protected $dockerRunTemplate = '-p "${:port}":1025 \ -p "${:web_port}":8025 \ "${:organization}"/"${:image_name}":"${:tag}"'; diff --git a/app/Services/Mailpit.php b/app/Services/Mailpit.php index 19ec8191..4240ac38 100644 --- a/app/Services/Mailpit.php +++ b/app/Services/Mailpit.php @@ -16,6 +16,7 @@ class Mailpit extends BaseService 'default' => '8025', ], ]; + protected $dockerRunTemplate = '-p "${:port}":1025 \ -p "${:web_port}":8025 \ "${:organization}"/"${:image_name}":"${:tag}"'; From ca988dc0e5b4d930941a7f8cd4a0046da65d6ee4 Mon Sep 17 00:00:00 2001 From: Tony Messias Date: Fri, 4 Oct 2024 13:15:59 -0300 Subject: [PATCH 12/12] Fix tests --- tests/Feature/DockerTagsTest.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/Feature/DockerTagsTest.php b/tests/Feature/DockerTagsTest.php index 351cc57a..093c5004 100644 --- a/tests/Feature/DockerTagsTest.php +++ b/tests/Feature/DockerTagsTest.php @@ -42,7 +42,7 @@ function it_sorts_the_versions_naturally() $tags = collect($dockerTags->getTags()); $this->assertEquals('latest', $tags->shift()); - $this->assertEquals('16.4', $tags->shift()); + $this->assertEquals('17.0', $tags->shift()); } /** @test */