This repository was archived by the owner on Apr 27, 2026. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 128
Expand file tree
/
Copy pathEnvironmentSshCommand.php
More file actions
127 lines (110 loc) · 5.59 KB
/
EnvironmentSshCommand.php
File metadata and controls
127 lines (110 loc) · 5.59 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
<?php
namespace Platformsh\Cli\Command\Environment;
use Platformsh\Cli\Command\CommandBase;
use Platformsh\Cli\Service\Ssh;
use Platformsh\Cli\Util\OsUtil;
use Platformsh\Client\Exception\EnvironmentStateException;
use Symfony\Component\Console\Exception\InvalidArgumentException;
use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Output\OutputInterface;
class EnvironmentSshCommand extends CommandBase
{
/**
* {@inheritdoc}
*/
protected function configure()
{
$this
->setName('environment:ssh')
->setAliases(['ssh'])
->addArgument('cmd', InputArgument::OPTIONAL | InputArgument::IS_ARRAY, 'A command to run on the environment.')
->addOption('pipe', null, InputOption::VALUE_NONE, 'Output the SSH URL only.')
->addOption('all', null, InputOption::VALUE_NONE, 'Output all SSH URLs (for every app).')
->addOption('option', 'o', InputOption::VALUE_REQUIRED | InputOption::VALUE_IS_ARRAY, 'Pass an extra option to SSH')
->setDescription('SSH to the current environment');
$this->addProjectOption()
->addEnvironmentOption()
->addRemoteContainerOptions();
Ssh::configureInput($this->getDefinition());
$this->addExample('Open a shell over SSH');
$this->addExample('Pass an extra option to SSH', "-o 'RequestTTY force'");
$this->addExample('List files', 'ls');
$this->addExample("Monitor the app log (use '--' before flags)", 'tail /var/log/app.log -- -n50 -f');
$envPrefix = $this->config()->get('service.env_prefix');
$this->addExample('Display relationships (use quotes for complex syntax)', "'echo \${$envPrefix}RELATIONSHIPS | base64 --decode'");
}
protected function execute(InputInterface $input, OutputInterface $output)
{
$this->chooseEnvFilter = $this->filterEnvsMaybeActive();
$this->validateInput($input);
$environment = $this->getSelectedEnvironment();
if ($input->getOption('all')) {
$output->writeln(array_values($environment->getSshUrls()));
return 0;
}
try {
$container = $this->selectRemoteContainer($input);
$sshUrl = $container->getSshUrl($input->getOption('instance'));
} catch (EnvironmentStateException $e) {
if ($e->getEnvironment()->id !== $environment->id) {
throw $e;
}
switch ($e->getEnvironment()->status) {
case 'inactive':
$this->stdErr->writeln(sprintf('The environment %s is inactive, so an SSH connection is not possible.', $this->api()->getEnvironmentLabel($e->getEnvironment(), 'error')));
if (!$e->getEnvironment()->has_code) {
$this->stdErr->writeln('');
$this->stdErr->writeln('Push code to the environment to activate it.');
}
return 1;
case 'paused':
$this->stdErr->writeln(sprintf('The environment %s is paused, so an SSH connection is not possible.', $this->api()->getEnvironmentLabel($e->getEnvironment(), 'error')));
if ($this->config()->isCommandEnabled('environment:resume')) {
$this->stdErr->writeln('');
$this->stdErr->writeln(sprintf('Resume the environment by running: <info>%s environment:resume -e %s</info>', $this->config()->get('application.executable'), OsUtil::escapeShellArg($environment->id)));
}
return 1;
}
throw $e;
} catch (\InvalidArgumentException $e) {
// Use Symfony's exception to print usage information.
throw $e instanceof InvalidArgumentException ? $e : new InvalidArgumentException($e->getMessage());
}
if ($input->getOption('pipe')) {
$output->write($sshUrl);
return 0;
}
$remoteCommand = $input->getArgument('cmd');
if (empty($remoteCommand) && $this->runningViaMulti) {
throw new InvalidArgumentException('The cmd argument is required when running via "multi"');
}
$options = $input->getOption('option');
// Send the TERM environment variable by default, when it has a
// supported value and when opening a shell (i.e. when no command is
// specified).
$validTermInfo = ['xterm', 'xterm-color', 'xterm-256color'];
if (empty($remoteCommand) && in_array(getenv('TERM'), $validTermInfo, true)) {
$options = array_merge(['SendEnv TERM'], $options);
}
/** @var \Platformsh\Cli\Service\Ssh $ssh */
$ssh = $this->getService('ssh');
$command = $ssh->getSshCommand($sshUrl, $options, $remoteCommand);
/** @var \Platformsh\Cli\Service\Shell $shell */
$shell = $this->getService('shell');
$start = \time();
$exitCode = $shell->executeSimple($command, null, $ssh->getEnv());
if ($exitCode !== 0) {
if ($this->getSelectedProject()->isSuspended()) {
$this->stdErr->writeln('');
$this->warnIfSuspended($this->getSelectedProject());
return $exitCode;
}
/** @var \Platformsh\Cli\Service\SshDiagnostics $diagnostics */
$diagnostics = $this->getService('ssh_diagnostics');
$diagnostics->diagnoseFailureWithTest($sshUrl, $start, $exitCode);
}
return $exitCode;
}
}