Skip to content

Commit

Permalink
Merge pull request #349 from tighten/tm/shell-cmd
Browse files Browse the repository at this point in the history
Add a `takeout shell` command
  • Loading branch information
tonysm authored Dec 6, 2024
2 parents a39e947 + ca988dc commit fbc9a3d
Show file tree
Hide file tree
Showing 16 changed files with 138 additions and 9 deletions.
18 changes: 18 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
takeout shell pgvector
```

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

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.
Expand Down
28 changes: 28 additions & 0 deletions app/Commands/ShellCommand.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
<?php

namespace App\Commands;

use App\InitializesCommands;
use App\Services;
use Illuminate\Console\Command;

class ShellCommand extends Command
{
use InitializesCommands;

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
{
$this->initializecommand();

$service = $services->get($this->argument('service'));

resolve($service)->forwardShell();

return self::SUCCESS;
}
}
23 changes: 23 additions & 0 deletions app/Services/BaseService.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
use App\Shell\Environment;
use App\Shell\Shell;
use App\WritesToConsole;
use Exception;
use Illuminate\Support\Str;
use Throwable;

Expand Down Expand Up @@ -93,6 +94,28 @@ public function enable(bool $useDefaults = false, array $passthroughOptions = []
}
}

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
{
return $this->organization;
Expand Down
5 changes: 5 additions & 0 deletions app/Services/Beanstalkd.php
Original file line number Diff line number Diff line change
Expand Up @@ -12,4 +12,9 @@ class Beanstalkd extends BaseService

protected $dockerRunTemplate = '-p "${:port}":11300 \
"${:organization}"/"${:image_name}":"${:tag}"';

protected function shellCommand(): string
{
return 'sh';
}
}
5 changes: 5 additions & 0 deletions app/Services/Buggregator.php
Original file line number Diff line number Diff line change
Expand Up @@ -42,4 +42,9 @@ class Buggregator extends BaseService
-p "${:monolog_port}":9913 \
--network-alias "${:network_alias}" \
"${:organization}"/"${:image_name}":"${:tag}"';

protected function shellCommand(): string
{
return 'sh';
}
}
12 changes: 12 additions & 0 deletions app/Services/CouchDB.php
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,22 @@ class CouchDB extends BaseService
'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';
Expand Down
5 changes: 2 additions & 3 deletions app/Services/EventStoreDB.php
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,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';
}
5 changes: 5 additions & 0 deletions app/Services/MailDev.php
Original file line number Diff line number Diff line change
Expand Up @@ -20,4 +20,9 @@ class MailDev extends BaseService
protected $dockerRunTemplate = '-p "${:port}":1025 \
-p "${:web_port}":1080 \
"${:organization}"/"${:image_name}":"${:tag}"';

protected function shellCommand(): string
{
return 'sh';
}
}
5 changes: 5 additions & 0 deletions app/Services/MailHog.php
Original file line number Diff line number Diff line change
Expand Up @@ -20,4 +20,9 @@ class MailHog extends BaseService
protected $dockerRunTemplate = '-p "${:port}":1025 \
-p "${:web_port}":8025 \
"${:organization}"/"${:image_name}":"${:tag}"';

protected function shellCommand(): string
{
return 'sh';
}
}
5 changes: 5 additions & 0 deletions app/Services/Mailpit.php
Original file line number Diff line number Diff line change
Expand Up @@ -20,4 +20,9 @@ class Mailpit extends BaseService
protected $dockerRunTemplate = '-p "${:port}":1025 \
-p "${:web_port}":8025 \
"${:organization}"/"${:image_name}":"${:tag}"';

protected function shellCommand(): string
{
return 'sh';
}
}
5 changes: 5 additions & 0 deletions app/Services/MeiliSearch.php
Original file line number Diff line number Diff line change
Expand Up @@ -20,4 +20,9 @@ class MeiliSearch extends BaseService
protected $dockerRunTemplate = '-p "${:port}":7700 \
-v "${:volume}":/data.ms \
"${:organization}"/"${:image_name}":"${:tag}"';

protected function shellCommand(): string
{
return 'sh';
}
}
2 changes: 1 addition & 1 deletion app/Services/OpenSearch.php
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ class OpenSearch extends BaseService
[
'shortname' => 'disable_security',
'prompt' => 'Disable security plugin (true or false)?',
'default' => 'false',
'default' => 'true',
],
];

Expand Down
5 changes: 5 additions & 0 deletions app/Services/Soketi.php
Original file line number Diff line number Diff line change
Expand Up @@ -41,4 +41,9 @@ public function __construct(Shell $shell, Environment $environment, Docker $dock
return $prompt;
}, $this->defaultPrompts);
}

protected function shellCommand(): string
{
return 'sh';
}
}
8 changes: 5 additions & 3 deletions app/Services/Traefik.php
Original file line number Diff line number Diff line change
Expand Up @@ -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',
Expand Down Expand Up @@ -64,6 +61,11 @@ public function __construct(Shell $shell, Environment $environment, Docker $dock
}, $this->prompts);
}

protected function shellCommand(): string
{
return 'sh';
}

protected function prompts(): void
{
parent::prompts();
Expand Down
14 changes: 13 additions & 1 deletion app/Shell/Docker.php
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -200,6 +199,19 @@ public function stopDockerService(): void
}
}

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(
Expand Down
2 changes: 1 addition & 1 deletion tests/Feature/DockerTagsTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -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('17.0', $tags->shift());
}

/** @test */
Expand Down

0 comments on commit fbc9a3d

Please sign in to comment.