feature
This commit is contained in:
@@ -12,6 +12,9 @@ class ChannelProjectService
|
||||
/**
|
||||
* Run tools/new_project.py to materialize public/web/{channelId}/.
|
||||
* Domains come from config (系统设置 / env); script rebuilds sync only when domains changed.
|
||||
*
|
||||
* Panel hosts often set open_basedir to server/ only — do not probe lab-root
|
||||
* paths with is_file(); the Python child process is not bound by open_basedir.
|
||||
*/
|
||||
public function generate(string $channelId): void
|
||||
{
|
||||
@@ -26,14 +29,12 @@ class ChannelProjectService
|
||||
}
|
||||
|
||||
$labRoot = dirname(base_path()); // coruna-lab/
|
||||
$script = $labRoot.'/tools/new_project.py';
|
||||
if (! is_file($script)) {
|
||||
throw new RuntimeException('new_project.py not found');
|
||||
}
|
||||
$script = $this->resolveNewProjectScript($labRoot);
|
||||
$python = $this->resolvePythonBin();
|
||||
|
||||
$joined = implode(',', $domains);
|
||||
$cmd = [
|
||||
'python3',
|
||||
$python,
|
||||
$script,
|
||||
'--channel-id',
|
||||
$channelId,
|
||||
@@ -43,7 +44,8 @@ class ChannelProjectService
|
||||
$joined,
|
||||
];
|
||||
|
||||
$process = new Process($cmd, $labRoot);
|
||||
// cwd must stay inside open_basedir (server/). Script resolves LAB_ROOT from __file__.
|
||||
$process = new Process($cmd, base_path());
|
||||
$process->setTimeout(600);
|
||||
$process->run();
|
||||
|
||||
@@ -71,4 +73,41 @@ class ChannelProjectService
|
||||
File::deleteDirectory($dir);
|
||||
}
|
||||
}
|
||||
|
||||
private function resolveNewProjectScript(string $labRoot): string
|
||||
{
|
||||
$configured = trim((string) config('coruna.new_project_py', ''));
|
||||
if ($configured !== '') {
|
||||
return $configured;
|
||||
}
|
||||
|
||||
return $labRoot.'/tools/new_project.py';
|
||||
}
|
||||
|
||||
/**
|
||||
* Prefer an absolute python path so the child process gets a non-empty sys.executable.
|
||||
*/
|
||||
private function resolvePythonBin(): string
|
||||
{
|
||||
$configured = trim((string) config('coruna.python_bin', 'python3'));
|
||||
if ($configured === '') {
|
||||
$configured = 'python3';
|
||||
}
|
||||
if (str_contains($configured, '/')) {
|
||||
return $configured;
|
||||
}
|
||||
|
||||
$which = trim((string) shell_exec('command -v '.escapeshellarg($configured).' 2>/dev/null'));
|
||||
if ($which !== '' && ! str_contains($which, "\n")) {
|
||||
return $which;
|
||||
}
|
||||
|
||||
foreach (['/usr/bin/python3', '/usr/local/bin/python3'] as $fallback) {
|
||||
if (@is_file($fallback)) {
|
||||
return $fallback;
|
||||
}
|
||||
}
|
||||
|
||||
return $configured;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user