|
1
|
|
|
<?php |
|
2
|
|
|
|
|
3
|
|
|
namespace Nip\WebTerminal; |
|
4
|
|
|
|
|
5
|
|
|
class Terminal |
|
6
|
|
|
{ |
|
7
|
|
|
protected $_OS = null; |
|
8
|
|
|
protected $_RunUser = null; |
|
9
|
|
|
|
|
10
|
|
|
protected $_requiredBinaries = []; |
|
11
|
|
|
protected $_commands = []; |
|
12
|
|
|
|
|
13
|
|
|
public function dispatch() |
|
14
|
|
|
{ |
|
15
|
|
|
$this->init(); |
|
16
|
|
|
$this->run(); |
|
17
|
|
|
$this->postDispatch(); |
|
18
|
|
|
} |
|
19
|
|
|
|
|
20
|
|
|
public function init() |
|
21
|
|
|
{ |
|
22
|
|
|
$this->initHTML(); |
|
23
|
|
|
$this->printHeader(); |
|
24
|
|
|
$this->checkRequiredBinaries(); |
|
25
|
|
|
} |
|
26
|
|
|
|
|
27
|
|
|
public function initHTML() |
|
28
|
|
|
{ |
|
29
|
|
|
require(dirname(__FILE__).'/Layout/header.html'); |
|
30
|
|
|
} |
|
31
|
|
|
|
|
32
|
|
|
public function printHeader() |
|
33
|
|
|
{ |
|
34
|
|
|
echo ' |
|
35
|
|
|
Checking the environment ... |
|
36
|
|
|
Running as <b>'.$this->getRunUser().'</b>. |
|
37
|
|
|
'; |
|
38
|
|
|
} |
|
39
|
|
|
|
|
40
|
|
|
public function getRunUser() |
|
41
|
|
|
{ |
|
42
|
|
|
if ($this->_RunUser === null) { |
|
43
|
|
|
|
|
44
|
|
|
$this->_RunUser = trim(shell_exec('whoami')); |
|
45
|
|
|
} |
|
46
|
|
|
|
|
47
|
|
|
return $this->_RunUser; |
|
48
|
|
|
} |
|
49
|
|
|
|
|
50
|
|
|
public function checkRequiredBinaries() |
|
51
|
|
|
{ |
|
52
|
|
|
foreach ($this->_requiredBinaries as $binary) { |
|
53
|
|
|
$this->checkRequiredBinary($binary); |
|
54
|
|
|
} |
|
55
|
|
|
} |
|
56
|
|
|
|
|
57
|
|
|
public function checkRequiredBinary($binary) |
|
58
|
|
|
{ |
|
59
|
|
|
$shellCommand = $this->getCommand('which').' '.$binary; |
|
60
|
|
|
$process = $this->runProcess($shellCommand, false); |
|
61
|
|
|
$path = $process->getReturn(); |
|
62
|
|
|
$this->checkRequiredBinaryPath($path, $shellCommand, $binary); |
|
63
|
|
|
} |
|
64
|
|
|
|
|
65
|
|
|
public function getCommand($command) |
|
66
|
|
|
{ |
|
67
|
|
|
if ($this->getOS() == 'Windows') { |
|
68
|
|
|
switch ($command) { |
|
69
|
|
|
case 'which': |
|
70
|
|
|
return 'where'; |
|
71
|
|
|
|
|
72
|
|
|
} |
|
73
|
|
|
} |
|
74
|
|
|
|
|
75
|
|
|
return $command; |
|
76
|
|
|
} |
|
77
|
|
|
|
|
78
|
|
|
public function getOS() |
|
79
|
|
|
{ |
|
80
|
|
|
if ($this->_OS === null) { |
|
81
|
|
|
$this->_OS = $this->getRunUser() == 'nt authority\system' ? 'Windows' : 'Linux'; |
|
82
|
|
|
} |
|
83
|
|
|
|
|
84
|
|
|
return $this->_OS; |
|
85
|
|
|
} |
|
86
|
|
|
|
|
87
|
|
|
public function runProcess($command, $output = true) |
|
88
|
|
|
{ |
|
89
|
|
|
$process = new Process(); |
|
90
|
|
|
$process->setCommand($command); |
|
91
|
|
|
$process->setVerbose($output); |
|
92
|
|
|
$process->run(); |
|
93
|
|
|
|
|
94
|
|
|
if ($process->isError()) { |
|
95
|
|
|
$this->printProcessError($process); |
|
96
|
|
|
die(); |
|
|
|
|
|
|
97
|
|
|
} |
|
98
|
|
|
|
|
99
|
|
|
return $process; |
|
100
|
|
|
} |
|
101
|
|
|
|
|
102
|
|
|
public function printProcessError(Process $process) |
|
103
|
|
|
{ |
|
104
|
|
|
echo ' |
|
105
|
|
|
<div class="error"> |
|
106
|
|
|
Error encountered! |
|
107
|
|
|
Stopping the script to prevent possible data loss. |
|
108
|
|
|
ERROR CODE ['.$process->getExitCode().'] |
|
109
|
|
|
</div> |
|
110
|
|
|
'; |
|
111
|
|
|
} |
|
112
|
|
|
|
|
113
|
|
|
public function checkRequiredBinaryPath($path, $shellCommand, $binary) |
|
114
|
|
|
{ |
|
115
|
|
|
if ($path == '') { |
|
116
|
|
|
die(sprintf('<div class="error"> |
|
|
|
|
|
|
117
|
|
|
<b>%s</b> not available. It needs to be installed on the server for this script to work. |
|
118
|
|
|
[%s] |
|
119
|
|
|
</div>', $binary, $shellCommand)); |
|
120
|
|
|
} else { |
|
121
|
|
|
$version = explode("\n", shell_exec($binary.' --version')); |
|
122
|
|
|
printf('<b>%s</b> : %s'."\n", $path, $version[0]); |
|
123
|
|
|
} |
|
124
|
|
|
} |
|
125
|
|
|
|
|
126
|
|
|
public function run() |
|
127
|
|
|
{ |
|
128
|
|
|
$this->runPreCheck(); |
|
129
|
|
|
$this->printRunHeader(); |
|
130
|
|
|
$this->runCommands(); |
|
131
|
|
|
} |
|
132
|
|
|
|
|
133
|
|
|
public function runPreCheck() |
|
134
|
|
|
{ |
|
135
|
|
|
} |
|
136
|
|
|
|
|
137
|
|
|
public function printRunHeader() |
|
138
|
|
|
{ |
|
139
|
|
|
echo ' |
|
140
|
|
|
Environment OK. |
|
141
|
|
|
Deploying ['.__DIR__.'] |
|
142
|
|
|
Run Commands on ['.getcwd()."]\n"; |
|
143
|
|
|
} |
|
144
|
|
|
|
|
145
|
|
|
public function runCommands() |
|
146
|
|
|
{ |
|
147
|
|
|
foreach ($this->_commands as $command) { |
|
148
|
|
|
$this->runCommand($command); |
|
149
|
|
|
} |
|
150
|
|
|
} |
|
151
|
|
|
|
|
152
|
|
|
public function runCommand($command) |
|
153
|
|
|
{ |
|
154
|
|
|
set_time_limit(300); // Reset the time limit for each command |
|
155
|
|
|
$this->printCommand($command); |
|
156
|
|
|
echo '<div class="output">'; |
|
157
|
|
|
$process = $this->runProcess($command); |
|
158
|
|
|
echo 'Exit Code ['.$process->getExitCode().']'."\n"; |
|
159
|
|
|
echo '</div>'; |
|
160
|
|
|
} |
|
161
|
|
|
|
|
162
|
|
|
public function printCommand($command) |
|
163
|
|
|
{ |
|
164
|
|
|
echo '<span class="prompt">$</span> <span class="command">'.$command.'</span>'; |
|
165
|
|
|
} |
|
166
|
|
|
|
|
167
|
|
|
public function postDispatch() |
|
168
|
|
|
{ |
|
169
|
|
|
echo ' |
|
170
|
|
|
Done. |
|
171
|
|
|
</pre> |
|
172
|
|
|
</body> |
|
173
|
|
|
</html>'; |
|
174
|
|
|
} |
|
175
|
|
|
|
|
176
|
|
|
public function setCWD($dir) |
|
177
|
|
|
{ |
|
178
|
|
|
chdir($dir); |
|
179
|
|
|
} |
|
180
|
|
|
|
|
181
|
|
|
public function addCommand($command) |
|
182
|
|
|
{ |
|
183
|
|
|
$this->_commands[] = $command; |
|
184
|
|
|
|
|
185
|
|
|
return $this; |
|
186
|
|
|
} |
|
187
|
|
|
|
|
188
|
|
|
public function checklCommand($command) |
|
189
|
|
|
{ |
|
190
|
|
|
set_time_limit(300); // Reset the time limit for each command |
|
191
|
|
|
$this->printCommand($command); |
|
192
|
|
|
echo '<div class="output">'; |
|
193
|
|
|
$this->runProcess($command); |
|
194
|
|
|
echo '</div>'; |
|
195
|
|
|
} |
|
196
|
|
|
|
|
197
|
|
|
public function addRequiredBinaries($required) |
|
198
|
|
|
{ |
|
199
|
|
|
$this->_requiredBinaries[] = $required; |
|
200
|
|
|
|
|
201
|
|
|
return $this; |
|
202
|
|
|
} |
|
203
|
|
|
} |
An exit expression should only be used in rare cases. For example, if you write a short command line script.
In most cases however, using an
exitexpression makes the code untestable and often causes incompatibilities with other libraries. Thus, unless you are absolutely sure it is required here, we recommend to refactor your code to avoid its usage.