-
Notifications
You must be signed in to change notification settings - Fork 6
Expand file tree
/
Copy pathShell_Command.php
More file actions
149 lines (131 loc) · 4.05 KB
/
Shell_Command.php
File metadata and controls
149 lines (131 loc) · 4.05 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
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
<?php
use EE\Model\Site;
use EE\Site\Utils as Site_Utils;
use EE\Utils as EE_Utils;
/**
* Brings up a shell to run wp-cli, composer etc.
*
* ## EXAMPLES
*
* # Open shell of example.com
* $ ee shell example.com
*
* @package ee-cli
*/
class Shell_Command extends EE_Command {
/**
* Brings up a shell to run wp-cli, composer etc.
*
* ## OPTIONS
*
* [<site-name>]
* : Name of website to run shell on.
*
* [--user=<user>]
* : Set the user to exec into shell.
*
* [--service=<service>]
* : Set the service whose shell you want.
* ---
* default: php
* ---
*
* [--command=<command>]
* : Command to non-interactively run in the shell.
*
* ## EXAMPLES
*
* # Open shell for site
* $ ee shell example.com
*
* # Open shell with root user
* $ ee shell example.com --user=root
*
* # Open shell for some other service
* $ ee shell example.com --service=nginx
*
* # Run command non-interactively
* $ ee shell example.com --service=nginx --command='nginx -t && nginx -s reload'
*
*/
public function __invoke( $args, $assoc_args ) {
EE_Utils\delem_log( 'ee shell start' );
$args = Site_Utils\auto_site_name( $args, 'shell', '' );
$site_name = EE_Utils\remove_trailing_slash( $args[0] );
$site = Site::find( $site_name );
if ( ! $site || ! $site->site_enabled ) {
EE::error( "Site $site_name does not exist or is not enabled." );
}
chdir( $site->site_fs_path );
$service = EE_Utils\get_flag_value( $assoc_args, 'service' );
$this->check_shell_available( $service, $site );
$user = EE_Utils\get_flag_value( $assoc_args, 'user' );
$user_string = '';
if ( $user ) {
$user_string = $this->check_user_available( $user, $service ) ? "--user='$user'" : '';
}
$shell = ( 'mailhog' === $service ) ? 'sh' : 'bash';
$command = EE_Utils\get_flag_value( $assoc_args, 'command' );
if ( $command ) {
EE::exec( "docker-compose exec $user_string $service $shell -c \"$command\"", true, true );
} else {
$this->run( "docker-compose exec $user_string $service $shell" );
}
EE_Utils\delem_log( 'ee shell end' );
}
/**
* Run the command to open shell.
*
* @param string $cmd Command to be executed to open shell.
* @param null|array $descriptors File descriptors for proc.
*/
private function run( $cmd, $descriptors = null ) {
EE_Utils\check_proc_available( 'ee_shell' );
if ( ! $descriptors ) {
$descriptors = array( STDIN, STDOUT, STDERR );
}
$final_cmd = EE_Utils\force_env_on_nix_systems( $cmd );
$proc = EE_Utils\proc_open_compat( $final_cmd, $descriptors, $pipes );
if ( ! $proc ) {
exit( 1 );
}
$r = proc_close( $proc );
if ( $r ) {
exit( $r );
}
}
/**
* Function to check if container supporting shell is present in docker-compose.yml or not.
*
* @param string $shell_container Container to be checked.
* @param EE\Model\Site $site Contains relevant site info.
*
* @throws \EE\ExitException
*/
private function check_shell_available( $shell_container, $site ) {
$launch = EE::launch( 'docker-compose config --services' );
$services = explode( PHP_EOL, trim( $launch->stdout ) );
if ( in_array( $shell_container, $services, true ) ) {
return;
}
EE::debug( 'Site type: ' . $site->site_type );
EE::debug( 'Site command: ' . $site->app_sub_type );
EE::error( sprintf( '%s site does not have support to launch %s shell.', $site->site_url, $shell_container ) );
}
/**
* Function to check if a user is present or not in the given container.
*
* @param string $user User to be checked in the shell.
* @param string $shell_container Container in which the user is to be checked.
*
* @return bool Success.
*/
private function check_user_available( $user, $shell_container ) {
$check_command = sprintf( "docker-compose exec --user='%s' %s bash -c 'exit'", $user, $shell_container );
if ( EE::exec( $check_command ) ) {
return true;
}
EE::warning( "$user is not available in $shell_container, falling back to default user." );
return false;
}
}