bug fix in automatic update
This commit is contained in:
parent
789618927d
commit
2f144c0d9d
|
@ -272,8 +272,88 @@ class UpdateSoftwareCommand extends Command
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper method to fix Git "dubious ownership" error
|
||||
*/
|
||||
private function fixGitOwnershipIssue(string $gitRoot): bool
|
||||
{
|
||||
try {
|
||||
// Check if the directory is a Git repository
|
||||
if (!is_dir($gitRoot . '/.git')) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Always add the directory to safe.directory when this method is called
|
||||
// This handles cases where Git detects dubious ownership for other reasons
|
||||
$safeDirProcess = new Process(['git', 'config', '--global', '--add', 'safe.directory', $gitRoot], $gitRoot);
|
||||
$safeDirProcess->setTimeout(300);
|
||||
$safeDirProcess->run();
|
||||
|
||||
if ($safeDirProcess->isSuccessful()) {
|
||||
$this->logger->info("Fixed Git ownership issue for directory: $gitRoot");
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
} catch (\Exception $e) {
|
||||
$this->logger->warning("Failed to fix Git ownership issue: " . $e->getMessage());
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper method to run Git command with ownership fix
|
||||
*/
|
||||
private function runGitCommand(array $command, string $workingDir, OutputInterface $output, int $retries = 3): void
|
||||
{
|
||||
$attempt = 0;
|
||||
while ($attempt < $retries) {
|
||||
try {
|
||||
$process = new Process($command, $workingDir);
|
||||
$process->setTimeout(3600);
|
||||
|
||||
if ($output->isVerbose()) {
|
||||
$process->mustRun(function ($type, $buffer) use ($output) {
|
||||
$this->writeOutput($output, $buffer);
|
||||
});
|
||||
} else {
|
||||
$process->mustRun();
|
||||
$this->writeOutput($output, $process->getOutput());
|
||||
}
|
||||
|
||||
$this->logger->info('Git command executed successfully: ' . implode(' ', $command));
|
||||
return;
|
||||
} catch (ProcessFailedException $e) {
|
||||
$attempt++;
|
||||
$errorMessage = $e->getProcess()->getErrorOutput() ?: $e->getMessage();
|
||||
$this->logger->warning("Attempt $attempt failed for " . implode(' ', $command) . ": $errorMessage");
|
||||
$this->writeOutput($output, "<comment>Attempt $attempt failed: $errorMessage</comment>");
|
||||
|
||||
// If the command failed with "dubious ownership" error, try to fix it
|
||||
if (str_contains($errorMessage, 'dubious ownership')) {
|
||||
$this->writeOutput($output, "<comment>Detected Git ownership issue, attempting to fix...</comment>");
|
||||
if ($this->fixGitOwnershipIssue($workingDir)) {
|
||||
$this->writeOutput($output, "<info>Git ownership issue fixed, retrying command...</info>");
|
||||
continue; // Retry the command without incrementing attempt
|
||||
}
|
||||
}
|
||||
|
||||
if ($attempt === $retries) {
|
||||
throw new \RuntimeException('Command "' . implode(' ', $command) . '" failed after ' . $retries . ' attempts: ' . $errorMessage);
|
||||
}
|
||||
sleep(5);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private function runProcess(array $command, string $workingDir, OutputInterface $output, int $retries = 3, bool $isComposer = false): void
|
||||
{
|
||||
// If this is a Git command, use the specialized Git command runner
|
||||
if (in_array($command[0], ['git'])) {
|
||||
$this->runGitCommand($command, $workingDir, $output, $retries);
|
||||
return;
|
||||
}
|
||||
|
||||
$attempt = 0;
|
||||
while ($attempt < $retries) {
|
||||
try {
|
||||
|
@ -318,13 +398,28 @@ class UpdateSoftwareCommand extends Command
|
|||
|
||||
private function getCurrentGitHead(): string
|
||||
{
|
||||
try {
|
||||
$process = new Process(['git', 'rev-parse', 'HEAD'], $this->rootDir);
|
||||
$process->run();
|
||||
|
||||
// If the command failed with "dubious ownership" error, try to fix it
|
||||
if (!$process->isSuccessful() && str_contains($process->getErrorOutput(), 'dubious ownership')) {
|
||||
if ($this->fixGitOwnershipIssue($this->rootDir)) {
|
||||
// Retry the command after fixing ownership
|
||||
$process = new Process(['git', 'rev-parse', 'HEAD'], $this->rootDir);
|
||||
$process->run();
|
||||
}
|
||||
}
|
||||
|
||||
if (!$process->isSuccessful()) {
|
||||
$this->logger->warning('Failed to get current Git HEAD: ' . $process->getErrorOutput());
|
||||
return 'unknown';
|
||||
}
|
||||
return trim($process->getOutput());
|
||||
} catch (\Exception $e) {
|
||||
$this->logger->warning('Failed to get current Git HEAD: ' . $e->getMessage());
|
||||
return 'unknown';
|
||||
}
|
||||
}
|
||||
|
||||
private function isUpToDate(): bool
|
||||
|
@ -333,6 +428,16 @@ class UpdateSoftwareCommand extends Command
|
|||
$this->runProcess(['git', 'fetch', 'origin'], $this->rootDir, new \Symfony\Component\Console\Output\NullOutput());
|
||||
$process = new Process(['git', 'status', '-uno'], $this->rootDir);
|
||||
$process->run();
|
||||
|
||||
// If the command failed with "dubious ownership" error, try to fix it
|
||||
if (!$process->isSuccessful() && str_contains($process->getErrorOutput(), 'dubious ownership')) {
|
||||
if ($this->fixGitOwnershipIssue($this->rootDir)) {
|
||||
// Retry the command after fixing ownership
|
||||
$process = new Process(['git', 'status', '-uno'], $this->rootDir);
|
||||
$process->run();
|
||||
}
|
||||
}
|
||||
|
||||
$status = $process->getOutput();
|
||||
return strpos($status, 'Your branch is up to date') !== false;
|
||||
} catch (\Exception $e) {
|
||||
|
@ -558,6 +663,16 @@ class UpdateSoftwareCommand extends Command
|
|||
$this->logger->warning('Command executed as root user.');
|
||||
}
|
||||
|
||||
// Check and fix Git ownership issues proactively
|
||||
if (is_dir($this->rootDir . '/.git')) {
|
||||
$this->writeOutput($output, 'Checking Git repository ownership...');
|
||||
if ($this->fixGitOwnershipIssue($this->rootDir)) {
|
||||
$this->writeOutput($output, '<info>Git ownership issue detected and fixed.</info>');
|
||||
} else {
|
||||
$this->writeOutput($output, '<info>Git repository ownership is correct.</info>');
|
||||
}
|
||||
}
|
||||
|
||||
$this->writeOutput($output, 'Pre-update checks completed successfully.');
|
||||
}
|
||||
|
||||
|
|
|
@ -19,6 +19,55 @@ final class UpdateCoreController extends AbstractController
|
|||
$this->connection = $connection;
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper method to fix Git "dubious ownership" error
|
||||
*/
|
||||
private function fixGitOwnershipIssue(string $gitRoot): bool
|
||||
{
|
||||
try {
|
||||
// Check if the directory is a Git repository
|
||||
if (!is_dir($gitRoot . '/.git')) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Always add the directory to safe.directory when this method is called
|
||||
// This handles cases where Git detects dubious ownership for other reasons
|
||||
$safeDirProcess = new Process(['git', 'config', '--global', '--add', 'safe.directory', $gitRoot], $gitRoot);
|
||||
$safeDirProcess->setTimeout(300);
|
||||
$safeDirProcess->run();
|
||||
|
||||
if ($safeDirProcess->isSuccessful()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
} catch (\Exception $e) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper method to run Git command with ownership fix
|
||||
*/
|
||||
private function runGitCommand(array $command, string $gitRoot, int $timeout = 7200): Process
|
||||
{
|
||||
$process = new Process($command, $gitRoot);
|
||||
$process->setTimeout($timeout);
|
||||
$process->run();
|
||||
|
||||
// If the command failed with "dubious ownership" error, try to fix it
|
||||
if (!$process->isSuccessful() && str_contains($process->getErrorOutput(), 'dubious ownership')) {
|
||||
if ($this->fixGitOwnershipIssue($gitRoot)) {
|
||||
// Retry the command after fixing ownership
|
||||
$process = new Process($command, $gitRoot);
|
||||
$process->setTimeout($timeout);
|
||||
$process->run();
|
||||
}
|
||||
}
|
||||
|
||||
return $process;
|
||||
}
|
||||
|
||||
#[Route('/api/admin/updatecore/run', name: 'api_admin_updatecore_run', methods: ['POST'])]
|
||||
public function api_admin_updatecore_run(): JsonResponse
|
||||
{
|
||||
|
@ -42,20 +91,39 @@ final class UpdateCoreController extends AbstractController
|
|||
'COMPOSER_HOME' => '/var/www/.composer',
|
||||
]);
|
||||
|
||||
// اجرای command به صورت synchronous برای اطمینان از اجرا
|
||||
$process = new Process(['php', 'hesabixCore/bin/console', 'hesabix:update', $stateFile], $gitRoot, $env);
|
||||
$process->setTimeout(7200); // افزایش تایماوت به 2 ساعت
|
||||
$process->start(function ($type, $buffer) use ($stateFile) {
|
||||
|
||||
// اجرای command و دریافت خروجی
|
||||
$process->run(function ($type, $buffer) use ($stateFile) {
|
||||
$state = json_decode(file_get_contents($stateFile), true) ?? ['uuid' => uniqid(), 'log' => ''];
|
||||
$state['log'] .= $buffer;
|
||||
file_put_contents($stateFile, json_encode($state));
|
||||
});
|
||||
|
||||
// بررسی نتیجه اجرا
|
||||
if (!$process->isSuccessful()) {
|
||||
$state = json_decode(file_get_contents($stateFile), true) ?? ['uuid' => $uuid, 'log' => ''];
|
||||
$state['error'] = $process->getErrorOutput();
|
||||
$state['log'] .= "\nError: " . $process->getErrorOutput();
|
||||
file_put_contents($stateFile, json_encode($state));
|
||||
|
||||
return new JsonResponse([
|
||||
'status' => 'error',
|
||||
'message' => 'Update process failed: ' . $process->getErrorOutput(),
|
||||
'uuid' => $uuid,
|
||||
], 500);
|
||||
}
|
||||
|
||||
// خواندن وضعیت نهایی
|
||||
$state = json_decode(file_get_contents($stateFile), true) ?? ['uuid' => $uuid, 'log' => ''];
|
||||
|
||||
return new JsonResponse([
|
||||
'status' => 'started',
|
||||
'message' => 'Update process started',
|
||||
'message' => 'Update process completed',
|
||||
'uuid' => $uuid,
|
||||
'output' => $state['log'] ?? '',
|
||||
]);
|
||||
}
|
||||
|
||||
|
@ -124,7 +192,7 @@ final class UpdateCoreController extends AbstractController
|
|||
}
|
||||
|
||||
#[Route('/api/admin/updatecore/stream', name: 'api_admin_updatecore_stream', methods: ['GET'])]
|
||||
public function api_admin_updatecore_stream(Request $request): StreamedResponse|JsonResponse
|
||||
public function api_admin_updatecore_stream(Request $request): JsonResponse
|
||||
{
|
||||
$uuid = $request->query->get('uuid');
|
||||
if (!$uuid) {
|
||||
|
@ -135,37 +203,27 @@ final class UpdateCoreController extends AbstractController
|
|||
$gitRoot = dirname($projectDir);
|
||||
$stateFile = $gitRoot . '/hesabixBackup/update_state_' . $uuid . '.json';
|
||||
|
||||
return new StreamedResponse(function () use ($stateFile) {
|
||||
header('Content-Type: text/event-stream');
|
||||
header('Cache-Control: no-cache');
|
||||
header('Connection: keep-alive');
|
||||
|
||||
while (true) {
|
||||
if (!file_exists($stateFile)) {
|
||||
echo "data: " . json_encode(['status' => 'idle', 'output' => '']) . "\n\n";
|
||||
ob_flush();
|
||||
flush();
|
||||
break;
|
||||
return new JsonResponse(['status' => 'idle', 'output' => '']);
|
||||
}
|
||||
|
||||
$state = json_decode(file_get_contents($stateFile), true) ?? ['log' => ''];
|
||||
$output = $state['log'] ?? '';
|
||||
|
||||
$isRunning = !isset($state['error']) &&
|
||||
!in_array('post_update_test', $state['completedSteps'] ?? []);
|
||||
!in_array('post_update_test', $state['completedSteps'] ?? []) &&
|
||||
!str_contains($output, 'No update needed') &&
|
||||
!str_contains($output, 'Software update completed successfully');
|
||||
|
||||
$status = isset($state['error']) ? 'error' : ($isRunning ? 'running' : 'success');
|
||||
echo "data: " . json_encode(['status' => $status, 'output' => $output]) . "\n\n";
|
||||
ob_flush();
|
||||
flush();
|
||||
|
||||
if (!$isRunning) {
|
||||
break;
|
||||
}
|
||||
|
||||
sleep(1);
|
||||
}
|
||||
});
|
||||
return new JsonResponse([
|
||||
'status' => $status,
|
||||
'output' => $output,
|
||||
'completedSteps' => $state['completedSteps'] ?? [],
|
||||
'error' => $state['error'] ?? null,
|
||||
'commit_hash' => $state['commit_hash'] ?? null
|
||||
]);
|
||||
}
|
||||
|
||||
#[Route('/api/admin/updatecore/commits', name: 'api_admin_updatecore_commits', methods: ['GET'])]
|
||||
|
@ -174,14 +232,10 @@ final class UpdateCoreController extends AbstractController
|
|||
$projectDir = $this->getParameter('kernel.project_dir');
|
||||
$gitRoot = dirname($projectDir); // رفتن به ریشه پروژه
|
||||
|
||||
$currentProcess = new Process(['git', 'rev-parse', 'HEAD'], $gitRoot);
|
||||
$currentProcess->setTimeout(7200); // افزایش تایماوت
|
||||
$currentProcess->run();
|
||||
$currentProcess = $this->runGitCommand(['git', 'rev-parse', 'HEAD'], $gitRoot);
|
||||
$currentCommit = $currentProcess->isSuccessful() ? trim($currentProcess->getOutput()) : 'unknown';
|
||||
|
||||
$targetProcess = new Process(['git', 'ls-remote', 'origin', 'HEAD'], $gitRoot);
|
||||
$targetProcess->setTimeout(7200); // افزایش تایماوت
|
||||
$targetProcess->run();
|
||||
$targetProcess = $this->runGitCommand(['git', 'ls-remote', 'origin', 'HEAD'], $gitRoot);
|
||||
$targetOutput = $targetProcess->isSuccessful() ? explode("\t", trim($targetProcess->getOutput()))[0] : 'unknown';
|
||||
|
||||
return new JsonResponse([
|
||||
|
@ -453,9 +507,7 @@ final class UpdateCoreController extends AbstractController
|
|||
}
|
||||
|
||||
// دریافت آدرس مخزن origin فعلی
|
||||
$process = new Process(['git', 'remote', 'get-url', 'origin'], $gitRoot);
|
||||
$process->setTimeout(7200); // افزایش تایماوت
|
||||
$process->run();
|
||||
$process = $this->runGitCommand(['git', 'remote', 'get-url', 'origin'], $gitRoot);
|
||||
|
||||
if (!$process->isSuccessful()) {
|
||||
return new JsonResponse([
|
||||
|
@ -483,6 +535,76 @@ final class UpdateCoreController extends AbstractController
|
|||
}
|
||||
}
|
||||
|
||||
#[Route('/api/admin/updatecore/run-manual', name: 'api_admin_updatecore_run_manual', methods: ['POST'])]
|
||||
public function api_admin_updatecore_run_manual(Request $request): JsonResponse
|
||||
{
|
||||
$uuid = $request->getPayload()->get('uuid');
|
||||
if (!$uuid) {
|
||||
return new JsonResponse([
|
||||
'status' => 'error',
|
||||
'message' => 'UUID is required',
|
||||
'output' => '',
|
||||
], 400);
|
||||
}
|
||||
|
||||
$projectDir = $this->getParameter('kernel.project_dir');
|
||||
$gitRoot = dirname($projectDir);
|
||||
$stateFile = $gitRoot . '/hesabixBackup/update_state_' . $uuid . '.json';
|
||||
|
||||
if (!file_exists($stateFile)) {
|
||||
return new JsonResponse([
|
||||
'status' => 'error',
|
||||
'message' => 'State file not found',
|
||||
'output' => '',
|
||||
], 404);
|
||||
}
|
||||
|
||||
$output = '';
|
||||
try {
|
||||
$output .= "شروع اجرای دستی بهروزرسانی...\n";
|
||||
|
||||
// اجرای command hesabix:update
|
||||
$env = array_merge($_SERVER, [
|
||||
'HOME' => '/var/www',
|
||||
'COMPOSER_HOME' => '/var/www/.composer',
|
||||
]);
|
||||
|
||||
$process = new Process(['php', 'hesabixCore/bin/console', 'hesabix:update', $stateFile], $gitRoot, $env);
|
||||
$process->setTimeout(7200);
|
||||
$process->run();
|
||||
|
||||
$output .= $process->getOutput();
|
||||
|
||||
if (!$process->isSuccessful()) {
|
||||
$output .= "\nخطا: " . $process->getErrorOutput();
|
||||
return new JsonResponse([
|
||||
'status' => 'error',
|
||||
'message' => 'خطا در اجرای بهروزرسانی',
|
||||
'output' => $output,
|
||||
], 500);
|
||||
}
|
||||
|
||||
// بررسی فایل state بعد از اجرا
|
||||
if (file_exists($stateFile)) {
|
||||
$state = json_decode(file_get_contents($stateFile), true) ?? [];
|
||||
$output .= "\nوضعیت نهایی: " . json_encode($state, JSON_PRETTY_PRINT);
|
||||
}
|
||||
|
||||
return new JsonResponse([
|
||||
'status' => 'success',
|
||||
'message' => 'بهروزرسانی با موفقیت انجام شد',
|
||||
'output' => $output,
|
||||
]);
|
||||
|
||||
} catch (\Exception $e) {
|
||||
return new JsonResponse([
|
||||
'status' => 'error',
|
||||
'message' => 'خطا در اجرای دستی: ' . $e->getMessage(),
|
||||
'output' => $output,
|
||||
], 500);
|
||||
}
|
||||
}
|
||||
|
||||
#[Route('/api/admin/updatecore/change-source', name: 'api_admin_updatecore_change_source', methods: ['POST'])]
|
||||
public function api_admin_updatecore_change_source(Request $request): JsonResponse
|
||||
{
|
||||
|
@ -513,9 +635,7 @@ final class UpdateCoreController extends AbstractController
|
|||
$output .= "شروع تغییر آدرس مخزن...\n";
|
||||
|
||||
// دریافت آدرس مخزن فعلی
|
||||
$currentProcess = new Process(['git', 'remote', 'get-url', 'origin'], $gitRoot);
|
||||
$currentProcess->setTimeout(7200);
|
||||
$currentProcess->run();
|
||||
$currentProcess = $this->runGitCommand(['git', 'remote', 'get-url', 'origin'], $gitRoot);
|
||||
$currentUrl = $currentProcess->isSuccessful() ? trim($currentProcess->getOutput()) : '';
|
||||
|
||||
if ($currentUrl) {
|
||||
|
@ -523,9 +643,7 @@ final class UpdateCoreController extends AbstractController
|
|||
}
|
||||
|
||||
// تغییر آدرس مخزن origin
|
||||
$changeProcess = new Process(['git', 'remote', 'set-url', 'origin', $sourceUrl], $gitRoot);
|
||||
$changeProcess->setTimeout(7200);
|
||||
$changeProcess->run();
|
||||
$changeProcess = $this->runGitCommand(['git', 'remote', 'set-url', 'origin', $sourceUrl], $gitRoot);
|
||||
|
||||
if (!$changeProcess->isSuccessful()) {
|
||||
return new JsonResponse([
|
||||
|
@ -538,9 +656,7 @@ final class UpdateCoreController extends AbstractController
|
|||
$output .= "آدرس مخزن به $sourceUrl تغییر یافت\n";
|
||||
|
||||
// بررسی اتصال به مخزن جدید
|
||||
$testProcess = new Process(['git', 'remote', 'show', 'origin'], $gitRoot);
|
||||
$testProcess->setTimeout(7200);
|
||||
$testProcess->run();
|
||||
$testProcess = $this->runGitCommand(['git', 'remote', 'show', 'origin'], $gitRoot);
|
||||
|
||||
if (!$testProcess->isSuccessful()) {
|
||||
return new JsonResponse([
|
||||
|
@ -553,9 +669,7 @@ final class UpdateCoreController extends AbstractController
|
|||
$output .= "اتصال به مخزن جدید با موفقیت برقرار شد\n";
|
||||
|
||||
// دریافت اطلاعات مخزن جدید
|
||||
$fetchProcess = new Process(['git', 'fetch', 'origin'], $gitRoot);
|
||||
$fetchProcess->setTimeout(7200);
|
||||
$fetchProcess->run();
|
||||
$fetchProcess = $this->runGitCommand(['git', 'fetch', 'origin'], $gitRoot);
|
||||
|
||||
if (!$fetchProcess->isSuccessful()) {
|
||||
$output .= "هشدار: خطا در دریافت اطلاعات از مخزن جدید: " . $fetchProcess->getErrorOutput() . "\n";
|
||||
|
@ -564,9 +678,7 @@ final class UpdateCoreController extends AbstractController
|
|||
}
|
||||
|
||||
// بررسی branch های موجود
|
||||
$branchProcess = new Process(['git', 'branch', '-r'], $gitRoot);
|
||||
$branchProcess->setTimeout(7200);
|
||||
$branchProcess->run();
|
||||
$branchProcess = $this->runGitCommand(['git', 'branch', '-r'], $gitRoot);
|
||||
|
||||
if ($branchProcess->isSuccessful()) {
|
||||
$branches = trim($branchProcess->getOutput());
|
||||
|
@ -578,9 +690,7 @@ final class UpdateCoreController extends AbstractController
|
|||
}
|
||||
|
||||
// پاک کردن کش Git
|
||||
$cleanProcess = new Process(['git', 'gc', '--prune=now'], $gitRoot);
|
||||
$cleanProcess->setTimeout(7200);
|
||||
$cleanProcess->run();
|
||||
$cleanProcess = $this->runGitCommand(['git', 'gc', '--prune=now'], $gitRoot);
|
||||
|
||||
if ($cleanProcess->isSuccessful()) {
|
||||
$output .= "کش Git پاک شد\n";
|
||||
|
|
|
@ -112,17 +112,17 @@
|
|||
<v-row justify="end" class="mb-4">
|
||||
<v-col cols="auto">
|
||||
<v-btn-group size="small">
|
||||
<v-btn :color="buttonColor" :loading="isUpdating"
|
||||
:disabled="isUpdating || status === 'running'"
|
||||
<v-btn :color="buttonColor" :loading="isUpdating || isStreaming"
|
||||
:disabled="isUpdating || isStreaming || status === 'running'"
|
||||
@click="startUpdate">
|
||||
{{ buttonText }}
|
||||
</v-btn>
|
||||
<v-btn color="warning" :loading="isClearingCache"
|
||||
:disabled="isUpdating || isClearingCache"
|
||||
:disabled="isUpdating || isStreaming || isClearingCache"
|
||||
@click="clearCache">
|
||||
{{ $t('updateSoftware.clearCacheButton') }}
|
||||
</v-btn>
|
||||
<v-btn color="info" :disabled="isUpdating || isChangingEnv"
|
||||
<v-btn color="info" :loading="isChangingEnv" :disabled="isUpdating || isStreaming || isChangingEnv"
|
||||
@click="openEnvDialog">
|
||||
{{ $t('updateSoftware.changeEnvButton') }}
|
||||
</v-btn>
|
||||
|
@ -134,11 +134,28 @@
|
|||
<v-toolbar flat color="white" density="compact">
|
||||
<v-toolbar-title>{{ $t('updateSoftware.progressTitle') }}</v-toolbar-title>
|
||||
<v-spacer></v-spacer>
|
||||
<v-chip v-if="isStreaming" color="primary" size="small" class="mr-2">
|
||||
<v-icon left size="small">mdi-sync</v-icon>
|
||||
در حال بهروزرسانی...
|
||||
</v-chip>
|
||||
<v-btn icon size="small" @click="checkStatusManually" class="mr-1" :loading="isCheckingStatus">
|
||||
<v-icon>mdi-refresh</v-icon>
|
||||
</v-btn>
|
||||
<v-btn icon size="small" @click="refreshPage" class="mr-1" title="Refresh صفحه">
|
||||
<v-icon>mdi-reload</v-icon>
|
||||
</v-btn>
|
||||
<v-btn icon size="small" @click="runUpdateManually" class="mr-1" title="اجرای دستی بهروزرسانی" :loading="isRunningManually">
|
||||
<v-icon>mdi-play</v-icon>
|
||||
</v-btn>
|
||||
<v-btn icon size="small" @click="copyToClipboard">
|
||||
<v-icon>mdi-content-copy</v-icon>
|
||||
</v-btn>
|
||||
</v-toolbar>
|
||||
<v-card-text>
|
||||
<v-alert v-if="isStreaming && !isPolling" type="info" dense class="mb-2">
|
||||
<v-icon left size="small">mdi-information</v-icon>
|
||||
اگر وضعیت بهروزرسانی نمایش داده نمیشود، روی دکمه refresh کلیک کنید
|
||||
</v-alert>
|
||||
<pre class="output-pre" ref="outputPre" v-html="formattedOutput"></pre>
|
||||
</v-card-text>
|
||||
</v-card>
|
||||
|
@ -191,8 +208,8 @@
|
|||
import { ref, onMounted, onUnmounted, nextTick } from 'vue';
|
||||
import axios from 'axios';
|
||||
|
||||
// تنظیم تایماوت Axios به 2 ساعت (7200000 میلیثانیه)
|
||||
axios.defaults.timeout = 7200000;
|
||||
// تنظیم تایماوت Axios به 5 دقیقه (300000 میلیثانیه)
|
||||
axios.defaults.timeout = 300000;
|
||||
|
||||
export default {
|
||||
name: 'UpdateSoftware',
|
||||
|
@ -234,6 +251,9 @@ export default {
|
|||
const isLoadingLogs = ref(false);
|
||||
const isClearingLogs = ref(false);
|
||||
const isPolling = ref(false);
|
||||
const isStreaming = ref(false);
|
||||
const isCheckingStatus = ref(false);
|
||||
const isRunningManually = ref(false);
|
||||
const updateSourceUrl = ref('');
|
||||
const isChangingSource = ref(false);
|
||||
|
||||
|
@ -264,6 +284,9 @@ export default {
|
|||
isLoadingLogs,
|
||||
isClearingLogs,
|
||||
isPolling,
|
||||
isStreaming,
|
||||
isCheckingStatus,
|
||||
isRunningManually,
|
||||
updateSourceUrl,
|
||||
isChangingSource,
|
||||
};
|
||||
|
@ -327,72 +350,164 @@ export default {
|
|||
async startUpdate() {
|
||||
if (this.isUpdating || this.status === 'running') return;
|
||||
|
||||
console.log('=== شروع فرآیند بهروزرسانی ===');
|
||||
console.log('وضعیت فعلی:', { isUpdating: this.isUpdating, status: this.status });
|
||||
|
||||
this.isUpdating = true;
|
||||
this.buttonText = this.$t('updateSoftware.updatingButton');
|
||||
this.isStreaming = false;
|
||||
this.buttonText = 'در حال اجرا...';
|
||||
this.buttonColor = 'primary';
|
||||
this.showOutput = true;
|
||||
this.output = this.$t('updateSoftware.startingMessage') + '\n';
|
||||
|
||||
console.log('درخواست شروع بهروزرسانی ارسال میشود...');
|
||||
|
||||
try {
|
||||
console.log('ارسال درخواست POST به /api/admin/updatecore/run');
|
||||
const response = await axios.post('/api/admin/updatecore/run', {}, {
|
||||
headers: { 'X-Requested-With': 'XMLHttpRequest' },
|
||||
timeout: 7200000 // تایماوت 2 ساعته برای درخواست اولیه
|
||||
timeout: 120000 // افزایش timeout به 2 دقیقه برای اجرای کامل
|
||||
});
|
||||
|
||||
console.log('پاسخ دریافتی:', response.data);
|
||||
|
||||
if (response.data.status === 'started') {
|
||||
this.updateUuid = response.data.uuid;
|
||||
console.log('UUID دریافت شد:', this.updateUuid);
|
||||
|
||||
// اگر خروجی در پاسخ وجود دارد، آن را نمایش بده
|
||||
if (response.data.output) {
|
||||
this.output = response.data.output;
|
||||
console.log('خروجی مستقیم دریافت شد:', response.data.output);
|
||||
} else {
|
||||
this.output += this.$t('updateSoftware.startedMessage') + '\n';
|
||||
console.log('شروع polling برای فرآیند طولانی...');
|
||||
this.startLogStream();
|
||||
}
|
||||
|
||||
// بررسی اینکه آیا فرآیند تکمیل شده
|
||||
if (response.data.output && (
|
||||
response.data.output.includes('Software is already up to date') ||
|
||||
response.data.output.includes('No update needed') ||
|
||||
response.data.output.includes('completed successfully')
|
||||
)) {
|
||||
console.log('فرآیند تکمیل شده - توقف polling');
|
||||
this.status = 'success';
|
||||
this.isPolling = false;
|
||||
this.isStreaming = false;
|
||||
this.isUpdating = false;
|
||||
this.buttonText = this.$t('updateSoftware.completedButton');
|
||||
this.buttonColor = 'success';
|
||||
|
||||
// نمایش پیام مناسب
|
||||
if (response.data.output.includes('Software is already up to date')) {
|
||||
this.showResultDialog = true;
|
||||
this.dialogTitle = 'اطلاعیه';
|
||||
this.dialogMessage = 'نرمافزار در حال حاضر بهروز است. هیچ بهروزرسانی جدیدی موجود نیست.';
|
||||
this.dialogColor = 'info';
|
||||
} else {
|
||||
this.showResultDialog = true;
|
||||
this.dialogTitle = this.$t('updateSoftware.dialogSuccessTitle');
|
||||
this.dialogMessage = 'بهروزرسانی با موفقیت انجام شد';
|
||||
this.dialogColor = 'success';
|
||||
}
|
||||
} else {
|
||||
// شروع polling برای فرآیندهای طولانی
|
||||
this.startLogStream();
|
||||
}
|
||||
} else if (response.data.status === 'error') {
|
||||
console.log('خطا در پاسخ:', response.data.message);
|
||||
this.output += '\n' + this.$t('updateSoftware.errorPrefix') + response.data.message;
|
||||
this.buttonColor = 'error';
|
||||
this.buttonText = this.$t('updateSoftware.failedButton');
|
||||
this.isUpdating = false;
|
||||
this.showResultDialog = true;
|
||||
this.dialogTitle = this.$t('updateSoftware.dialogErrorTitle');
|
||||
this.dialogMessage = this.$t('updateSoftware.dialogErrorSimpleMessage');
|
||||
this.dialogMessage = response.data.message || this.$t('updateSoftware.dialogErrorSimpleMessage');
|
||||
this.dialogColor = 'error';
|
||||
}
|
||||
} catch (error) {
|
||||
console.log('خطا در درخواست شروع:', error);
|
||||
console.log('جزئیات خطا:', {
|
||||
message: error.message,
|
||||
code: error.code,
|
||||
response: error.response?.data,
|
||||
status: error.response?.status
|
||||
});
|
||||
|
||||
this.output += '\n' + this.$t('updateSoftware.errorPrefix') + (error.response?.data?.message || error.message);
|
||||
this.buttonColor = 'error';
|
||||
this.buttonText = this.$t('updateSoftware.failedButton');
|
||||
this.isUpdating = false;
|
||||
this.showResultDialog = true;
|
||||
this.dialogTitle = this.$t('updateSoftware.dialogErrorTitle');
|
||||
this.dialogMessage = this.$t('updateSoftware.dialogErrorSimpleMessage');
|
||||
this.dialogMessage = error.response?.data?.message || error.message || this.$t('updateSoftware.dialogErrorSimpleMessage');
|
||||
this.dialogColor = 'error';
|
||||
}
|
||||
},
|
||||
async startLogStream() {
|
||||
const pollInterval = 2000; // افزایش فاصله polling به 2 ثانیه
|
||||
console.log('=== شروع polling ===');
|
||||
console.log('UUID برای polling:', this.updateUuid);
|
||||
|
||||
const pollInterval = 2000; // فاصله polling 2 ثانیه
|
||||
const maxPollingTime = 300000; // حداکثر 5 دقیقه polling
|
||||
const startTime = Date.now();
|
||||
|
||||
this.isPolling = true;
|
||||
this.isStreaming = true;
|
||||
this.isUpdating = true;
|
||||
let retryCount = 0;
|
||||
const maxRetries = 10;
|
||||
|
||||
const pollStream = async () => {
|
||||
if (!this.isPolling) return;
|
||||
if (!this.isPolling) {
|
||||
console.log('Polling متوقف شد');
|
||||
return;
|
||||
}
|
||||
|
||||
// بررسی timeout
|
||||
const elapsedTime = Date.now() - startTime;
|
||||
if (elapsedTime > maxPollingTime) {
|
||||
console.log('زمان polling تمام شد');
|
||||
this.output += '\nزمان انتظار تمام شد. فرآیند بهروزرسانی احتمالاً تکمیل شده است.\n';
|
||||
this.isPolling = false;
|
||||
this.isStreaming = false;
|
||||
this.isUpdating = false;
|
||||
this.buttonText = this.$t('updateSoftware.completedButton');
|
||||
this.buttonColor = 'success';
|
||||
|
||||
this.showResultDialog = true;
|
||||
this.dialogTitle = 'اطلاعیه';
|
||||
this.dialogMessage = 'زمان انتظار تمام شد. فرآیند بهروزرسانی احتمالاً تکمیل شده است.';
|
||||
this.dialogColor = 'info';
|
||||
return;
|
||||
}
|
||||
|
||||
console.log(`--- Polling attempt ${retryCount + 1} --- (${Math.round(elapsedTime/1000)}s elapsed)`);
|
||||
console.log('ارسال درخواست GET به /api/admin/updatecore/stream با UUID:', this.updateUuid);
|
||||
|
||||
try {
|
||||
const response = await axios.get(`/api/admin/updatecore/stream`, {
|
||||
params: { uuid: this.updateUuid },
|
||||
timeout: 7200000 // تایماوت 2 ساعته برای استریم
|
||||
timeout: 10000 // کاهش timeout برای polling
|
||||
});
|
||||
|
||||
console.log('پاسخ polling دریافتی:', response.data);
|
||||
const data = response.data;
|
||||
if (typeof data === 'string' && data.startsWith('data: ')) {
|
||||
try {
|
||||
const jsonStr = data.substring(data.indexOf('{'));
|
||||
const parsedData = JSON.parse(jsonStr);
|
||||
retryCount = 0; // reset retry count on success
|
||||
|
||||
if (parsedData.output && parsedData.output !== this.output) {
|
||||
this.output = parsedData.output;
|
||||
console.log('وضعیت دریافتی:', data.status);
|
||||
console.log('خروجی قبلی:', this.output);
|
||||
console.log('خروجی جدید:', data.output);
|
||||
|
||||
if (data.output && data.output !== this.output) {
|
||||
console.log('خروجی بهروزرسانی شد');
|
||||
this.output = data.output;
|
||||
} else {
|
||||
console.log('خروجی تغییری نکرده');
|
||||
}
|
||||
|
||||
this.status = parsedData.status;
|
||||
} catch (parseError) {
|
||||
console.error('خطا در پردازش پاسخ:', parseError);
|
||||
}
|
||||
}
|
||||
this.status = data.status;
|
||||
|
||||
await nextTick();
|
||||
if (this.$refs.outputPre) {
|
||||
|
@ -400,37 +515,249 @@ export default {
|
|||
}
|
||||
|
||||
if (this.status === 'success' || this.status === 'error') {
|
||||
console.log('فرآیند تکمیل شد. وضعیت:', this.status);
|
||||
this.isPolling = false;
|
||||
this.isStreaming = false;
|
||||
this.isUpdating = false;
|
||||
this.buttonText = this.status === 'success'
|
||||
? this.$t('updateSoftware.completedButton')
|
||||
: this.$t('updateSoftware.failedButton');
|
||||
this.buttonColor = this.status === 'success' ? 'success' : 'error';
|
||||
|
||||
this.showResultDialog = true;
|
||||
this.dialogTitle = this.status === 'success'
|
||||
? this.$t('updateSoftware.dialogSuccessTitle')
|
||||
: this.$t('updateSoftware.dialogErrorTitle');
|
||||
this.dialogMessage = this.status === 'success'
|
||||
? this.$t('updateSoftware.successMessage')
|
||||
: this.$t('updateSoftware.dialogErrorSimpleMessage');
|
||||
: (data.error || this.$t('updateSoftware.dialogErrorSimpleMessage'));
|
||||
this.dialogColor = this.status === 'success' ? 'success' : 'error';
|
||||
return;
|
||||
}
|
||||
|
||||
console.log(`انتظار ${pollInterval}ms برای polling بعدی...`);
|
||||
setTimeout(pollStream, pollInterval);
|
||||
|
||||
} catch (error) {
|
||||
console.error('خطا در دریافت جریان داده:', error);
|
||||
console.error('خطا در polling:', error);
|
||||
console.log('جزئیات خطای polling:', {
|
||||
message: error.message,
|
||||
code: error.code,
|
||||
response: error.response?.data,
|
||||
status: error.response?.status,
|
||||
retryCount: retryCount
|
||||
});
|
||||
|
||||
retryCount++;
|
||||
|
||||
// اگر خطای شبکه است و تعداد تلاشها کم است، دوباره تلاش کن
|
||||
if ((error.code === 'ECONNABORTED' || error.code === 'NETWORK_ERROR' || !error.response) && retryCount < maxRetries) {
|
||||
console.log(`تلاش مجدد ${retryCount}/${maxRetries}...`);
|
||||
this.output += `\nتلاش مجدد برای دریافت وضعیت... (${retryCount}/${maxRetries})\n`;
|
||||
setTimeout(pollStream, pollInterval * 2); // افزایش فاصله برای retry
|
||||
return;
|
||||
}
|
||||
|
||||
console.log('تعداد تلاشها تمام شد یا خطای غیرقابل حل');
|
||||
this.isPolling = false;
|
||||
this.isStreaming = false;
|
||||
this.output += '\n' + this.$t('updateSoftware.streamError');
|
||||
this.isUpdating = false;
|
||||
this.buttonColor = 'error';
|
||||
this.buttonText = this.$t('updateSoftware.failedButton');
|
||||
|
||||
// نمایش خطا به کاربر
|
||||
this.showResultDialog = true;
|
||||
this.dialogTitle = this.$t('updateSoftware.dialogErrorTitle');
|
||||
this.dialogMessage = error.response?.data?.message || error.message || this.$t('updateSoftware.dialogErrorSimpleMessage');
|
||||
this.dialogColor = 'error';
|
||||
}
|
||||
};
|
||||
|
||||
pollStream();
|
||||
},
|
||||
async checkStatusManually() {
|
||||
console.log('=== بررسی دستی وضعیت ===');
|
||||
console.log('UUID فعلی:', this.updateUuid);
|
||||
|
||||
if (!this.updateUuid) {
|
||||
console.log('هیچ UUID موجود نیست');
|
||||
this.showResultDialog = true;
|
||||
this.dialogTitle = this.$t('updateSoftware.dialogErrorTitle');
|
||||
this.dialogMessage = 'هیچ فرآیند بهروزرسانی فعال نیست';
|
||||
this.dialogColor = 'error';
|
||||
return;
|
||||
}
|
||||
|
||||
this.isCheckingStatus = true;
|
||||
console.log('ارسال درخواست بررسی وضعیت...');
|
||||
|
||||
try {
|
||||
const response = await axios.get(`/api/admin/updatecore/stream`, {
|
||||
params: { uuid: this.updateUuid },
|
||||
timeout: 10000
|
||||
});
|
||||
|
||||
console.log('پاسخ بررسی وضعیت:', response.data);
|
||||
const data = response.data;
|
||||
|
||||
console.log('وضعیت دریافتی:', data.status);
|
||||
console.log('خروجی دریافتی:', data.output);
|
||||
|
||||
if (data.output && data.output !== this.output) {
|
||||
console.log('خروجی بهروزرسانی شد');
|
||||
this.output = data.output;
|
||||
} else {
|
||||
console.log('خروجی تغییری نکرده');
|
||||
}
|
||||
|
||||
this.status = data.status;
|
||||
|
||||
await nextTick();
|
||||
if (this.$refs.outputPre) {
|
||||
this.$refs.outputPre.scrollTop = this.$refs.outputPre.scrollHeight;
|
||||
}
|
||||
|
||||
if (this.status === 'success' || this.status === 'error') {
|
||||
console.log('فرآیند تکمیل شد. وضعیت:', this.status);
|
||||
this.isPolling = false;
|
||||
this.isStreaming = false;
|
||||
this.isUpdating = false;
|
||||
this.buttonText = this.status === 'success'
|
||||
? this.$t('updateSoftware.completedButton')
|
||||
: this.$t('updateSoftware.failedButton');
|
||||
this.buttonColor = this.status === 'success' ? 'success' : 'error';
|
||||
|
||||
this.showResultDialog = true;
|
||||
this.dialogTitle = this.status === 'success'
|
||||
? this.$t('updateSoftware.dialogSuccessTitle')
|
||||
: this.$t('updateSoftware.dialogErrorTitle');
|
||||
this.dialogMessage = this.status === 'success'
|
||||
? this.$t('updateSoftware.successMessage')
|
||||
: (data.error || this.$t('updateSoftware.dialogErrorSimpleMessage'));
|
||||
this.dialogColor = this.status === 'success' ? 'success' : 'error';
|
||||
} else {
|
||||
console.log('فرآیند هنوز در حال اجرا است');
|
||||
this.showResultDialog = true;
|
||||
this.dialogTitle = 'وضعیت فعلی';
|
||||
this.dialogMessage = 'فرآیند بهروزرسانی هنوز در حال اجرا است';
|
||||
this.dialogColor = 'info';
|
||||
}
|
||||
|
||||
} catch (error) {
|
||||
console.error('خطا در بررسی دستی وضعیت:', error);
|
||||
console.log('جزئیات خطای بررسی دستی:', {
|
||||
message: error.message,
|
||||
code: error.code,
|
||||
response: error.response?.data,
|
||||
status: error.response?.status
|
||||
});
|
||||
|
||||
// اگر خطای شبکه است، وضعیت فایل state را نمایش بده
|
||||
if (!error.response) {
|
||||
console.log('خطای شبکه - نمایش وضعیت محلی');
|
||||
this.output += '\nخطا در اتصال به سرور. وضعیت فعلی:\n';
|
||||
this.output += `UUID: ${this.updateUuid}\n`;
|
||||
this.output += 'فرآیند بهروزرسانی احتمالاً تکمیل شده است.\n';
|
||||
this.output += 'لطفاً صفحه را refresh کنید.\n';
|
||||
|
||||
this.isPolling = false;
|
||||
this.isStreaming = false;
|
||||
this.isUpdating = false;
|
||||
this.buttonText = this.$t('updateSoftware.completedButton');
|
||||
this.buttonColor = 'success';
|
||||
|
||||
this.showResultDialog = true;
|
||||
this.dialogTitle = 'اطلاعیه';
|
||||
this.dialogMessage = 'فرآیند بهروزرسانی احتمالاً تکمیل شده است. لطفاً صفحه را refresh کنید.';
|
||||
this.dialogColor = 'info';
|
||||
} else {
|
||||
console.log('خطای HTTP - نمایش پیام خطا');
|
||||
this.showResultDialog = true;
|
||||
this.dialogTitle = this.$t('updateSoftware.dialogErrorTitle');
|
||||
this.dialogMessage = error.response?.data?.message || error.message || 'خطا در بررسی وضعیت';
|
||||
this.dialogColor = 'error';
|
||||
}
|
||||
} finally {
|
||||
this.isCheckingStatus = false;
|
||||
console.log('=== پایان بررسی دستی وضعیت ===');
|
||||
}
|
||||
},
|
||||
refreshPage() {
|
||||
console.log('=== Refresh page ===');
|
||||
console.log('وضعیت فعلی قبل از refresh:', {
|
||||
isUpdating: this.isUpdating,
|
||||
isStreaming: this.isStreaming,
|
||||
isPolling: this.isPolling,
|
||||
status: this.status,
|
||||
updateUuid: this.updateUuid
|
||||
});
|
||||
window.location.reload();
|
||||
},
|
||||
async runUpdateManually() {
|
||||
console.log('=== اجرای دستی بهروزرسانی ===');
|
||||
|
||||
if (!this.updateUuid) {
|
||||
this.showResultDialog = true;
|
||||
this.dialogTitle = this.$t('updateSoftware.dialogErrorTitle');
|
||||
this.dialogMessage = 'هیچ فرآیند بهروزرسانی فعال نیست';
|
||||
this.dialogColor = 'error';
|
||||
return;
|
||||
}
|
||||
|
||||
this.isRunningManually = true;
|
||||
this.output += '\n=== اجرای دستی بهروزرسانی ===\n';
|
||||
|
||||
try {
|
||||
// اجرای command به صورت دستی
|
||||
const response = await axios.post('/api/admin/updatecore/run-manual', {
|
||||
uuid: this.updateUuid
|
||||
}, {
|
||||
headers: { 'X-Requested-With': 'XMLHttpRequest' },
|
||||
timeout: 60000
|
||||
});
|
||||
|
||||
console.log('پاسخ اجرای دستی:', response.data);
|
||||
this.output += response.data.output || response.data.message + '\n';
|
||||
|
||||
if (response.data.status === 'success') {
|
||||
this.status = 'success';
|
||||
this.isPolling = false;
|
||||
this.isStreaming = false;
|
||||
this.isUpdating = false;
|
||||
this.buttonText = this.$t('updateSoftware.completedButton');
|
||||
this.buttonColor = 'success';
|
||||
|
||||
// بررسی اینکه آیا نرمافزار بهروز است
|
||||
if (response.data.output && response.data.output.includes('Software is already up to date')) {
|
||||
this.showResultDialog = true;
|
||||
this.dialogTitle = 'اطلاعیه';
|
||||
this.dialogMessage = 'نرمافزار در حال حاضر بهروز است. هیچ بهروزرسانی جدیدی موجود نیست.';
|
||||
this.dialogColor = 'info';
|
||||
} else {
|
||||
this.showResultDialog = true;
|
||||
this.dialogTitle = this.$t('updateSoftware.dialogSuccessTitle');
|
||||
this.dialogMessage = response.data.message || 'بهروزرسانی با موفقیت انجام شد';
|
||||
this.dialogColor = 'success';
|
||||
}
|
||||
} else {
|
||||
this.showResultDialog = true;
|
||||
this.dialogTitle = this.$t('updateSoftware.dialogErrorTitle');
|
||||
this.dialogMessage = response.data.message || 'خطا در اجرای دستی';
|
||||
this.dialogColor = 'error';
|
||||
}
|
||||
|
||||
} catch (error) {
|
||||
console.error('خطا در اجرای دستی:', error);
|
||||
this.output += 'خطا: ' + (error.response?.data?.message || error.message) + '\n';
|
||||
this.showResultDialog = true;
|
||||
this.dialogTitle = this.$t('updateSoftware.dialogErrorTitle');
|
||||
this.dialogMessage = error.response?.data?.message || error.message || 'خطا در اجرای دستی';
|
||||
this.dialogColor = 'error';
|
||||
} finally {
|
||||
this.isRunningManually = false;
|
||||
}
|
||||
},
|
||||
async clearCache() {
|
||||
this.isClearingCache = true;
|
||||
this.showOutput = true;
|
||||
|
@ -439,7 +766,7 @@ export default {
|
|||
try {
|
||||
const response = await axios.post('/api/admin/updatecore/clear-cache', {}, {
|
||||
headers: { 'X-Requested-With': 'XMLHttpRequest' },
|
||||
timeout: 7200000 // تایماوت 2 ساعته
|
||||
timeout: 60000 // کاهش timeout به 1 دقیقه
|
||||
});
|
||||
this.output += response.data.output || this.$t('updateSoftware.cacheClearedMessage') + '\n';
|
||||
this.showResultDialog = true;
|
||||
|
@ -478,7 +805,7 @@ export default {
|
|||
try {
|
||||
const response = await axios.post('/api/admin/updatecore/change-env', { env: this.tempSelectedEnv }, {
|
||||
headers: { 'X-Requested-With': 'XMLHttpRequest' },
|
||||
timeout: 7200000 // تایماوت 2 ساعته
|
||||
timeout: 300000 // کاهش timeout به 5 دقیقه
|
||||
});
|
||||
this.output += response.data.output || response.data.message + '\n';
|
||||
this.selectedEnv = this.tempSelectedEnv;
|
||||
|
@ -490,7 +817,7 @@ export default {
|
|||
this.output += 'خطا: ' + (error.response?.data?.message || error.message) + '\n';
|
||||
this.showResultDialog = true;
|
||||
this.dialogTitle = 'خطا';
|
||||
this.dialogMessage = 'خطایی در تغییر حالت رخ داد';
|
||||
this.dialogMessage = error.response?.data?.message || error.message || 'خطایی در تغییر حالت رخ داد';
|
||||
this.dialogColor = 'error';
|
||||
} finally {
|
||||
this.isChangingEnv = false;
|
||||
|
@ -501,7 +828,7 @@ export default {
|
|||
try {
|
||||
const response = await axios.get('/api/admin/updatecore/commits', {
|
||||
headers: { 'X-Requested-With': 'XMLHttpRequest' },
|
||||
timeout: 7200000 // تایماوت 2 ساعته
|
||||
timeout: 30000 // کاهش timeout به 30 ثانیه
|
||||
});
|
||||
this.currentCommit = response.data.currentCommit || 'unknown';
|
||||
this.targetCommit = response.data.targetCommit || 'unknown';
|
||||
|
@ -515,7 +842,7 @@ export default {
|
|||
try {
|
||||
const response = await axios.get('/api/admin/updatecore/system-info', {
|
||||
headers: { 'X-Requested-With': 'XMLHttpRequest' },
|
||||
timeout: 7200000 // تایماوت 2 ساعته
|
||||
timeout: 30000 // کاهش timeout به 30 ثانیه
|
||||
});
|
||||
this.systemInfo = {
|
||||
osName: response.data.osName || 'unknown',
|
||||
|
@ -549,7 +876,7 @@ export default {
|
|||
try {
|
||||
const response = await axios.get('/api/admin/updatecore/current-source', {
|
||||
headers: { 'X-Requested-With': 'XMLHttpRequest' },
|
||||
timeout: 7200000 // تایماوت 2 ساعته
|
||||
timeout: 30000 // کاهش timeout به 30 ثانیه
|
||||
});
|
||||
|
||||
if (response.data.status === 'success') {
|
||||
|
@ -575,7 +902,7 @@ export default {
|
|||
try {
|
||||
const response = await axios.get('/api/admin/updatecore/current-env', {
|
||||
headers: { 'X-Requested-With': 'XMLHttpRequest' },
|
||||
timeout: 7200000 // تایماوت 2 ساعته
|
||||
timeout: 30000 // کاهش timeout به 30 ثانیه
|
||||
});
|
||||
this.selectedEnv = response.data.env;
|
||||
this.tempSelectedEnv = response.data.env;
|
||||
|
@ -596,7 +923,7 @@ export default {
|
|||
try {
|
||||
const response = await axios.get('/api/admin/updatecore/system-logs', {
|
||||
headers: { 'X-Requested-With': 'XMLHttpRequest' },
|
||||
timeout: 7200000 // تایماوت 2 ساعته
|
||||
timeout: 30000 // کاهش timeout به 30 ثانیه
|
||||
});
|
||||
this.systemLogs = response.data.logs || response.data.message;
|
||||
} catch (error) {
|
||||
|
@ -611,7 +938,7 @@ export default {
|
|||
try {
|
||||
const response = await axios.post('/api/admin/updatecore/clear-logs', {}, {
|
||||
headers: { 'X-Requested-With': 'XMLHttpRequest' },
|
||||
timeout: 7200000 // تایماوت 2 ساعته
|
||||
timeout: 30000 // کاهش timeout به 30 ثانیه
|
||||
});
|
||||
if (response.data.status === 'success') {
|
||||
this.systemLogs = 'لاگها پاک شدند';
|
||||
|
@ -651,7 +978,7 @@ export default {
|
|||
sourceUrl: this.updateSourceUrl.trim()
|
||||
}, {
|
||||
headers: { 'X-Requested-With': 'XMLHttpRequest' },
|
||||
timeout: 7200000 // تایماوت 2 ساعته
|
||||
timeout: 120000 // کاهش timeout به 2 دقیقه
|
||||
});
|
||||
|
||||
this.output += response.data.output || response.data.message + '\n';
|
||||
|
@ -689,15 +1016,25 @@ export default {
|
|||
},
|
||||
},
|
||||
mounted() {
|
||||
console.log('=== Component mounted ===');
|
||||
console.log('شروع بارگذاری اطلاعات اولیه...');
|
||||
|
||||
this.fetchCommits();
|
||||
this.fetchSystemInfo();
|
||||
this.fetchCurrentEnv();
|
||||
this.fetchCurrentSource();
|
||||
this.buttonText = this.$t('updateSoftware.startButton');
|
||||
this.refreshLogs();
|
||||
|
||||
console.log('بارگذاری اطلاعات اولیه تکمیل شد');
|
||||
},
|
||||
beforeUnmount() {
|
||||
console.log('=== Component unmounting ===');
|
||||
console.log('متوقف کردن polling و streaming...');
|
||||
this.isPolling = false;
|
||||
this.isStreaming = false;
|
||||
this.isUpdating = false;
|
||||
console.log('Component cleanup completed');
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
|
Loading…
Reference in a new issue