feat: implement project management and service orchestration architecture
This commit is contained in:
+118
-6
@@ -7,6 +7,7 @@ import { projectService } from '../services/ProjectService'
|
||||
import { phpManagerService } from '../services/PhpManagerService'
|
||||
import { mariaDbManagerService } from '../services/MariaDbManagerService'
|
||||
import { nginxManagerService } from '../services/NginxManagerService'
|
||||
import { apacheManagerService } from '../services/ApacheManagerService'
|
||||
import { phpMyAdminService } from '../services/PhpMyAdminService'
|
||||
import { portMappingService } from '../services/PortMappingService'
|
||||
import path from 'path'
|
||||
@@ -55,7 +56,8 @@ async function rebuildNginxConfig(forceProjects: boolean = false): Promise<{ bin
|
||||
}
|
||||
|
||||
// Generate project configs
|
||||
const projects = await projectService.getProjects()
|
||||
const allProjects = await projectService.getProjects()
|
||||
const projects = allProjects.filter(p => !p.serverType || p.serverType === 'nginx')
|
||||
for (const p of projects) {
|
||||
const projectConfPath = path.join(projectsConfDir, `${p.host}.conf`)
|
||||
let shouldGenerate = forceProjects || !fs.existsSync(projectConfPath)
|
||||
@@ -142,12 +144,88 @@ async function reloadNginx(): Promise<{ success: boolean; message: string }> {
|
||||
return { success: false, message: `Reload hatası: ${error.message}` }
|
||||
}
|
||||
}
|
||||
async function rebuildApacheConfig(forceProjects: boolean = false): Promise<{ binPath: string; apacheDir: string; configPath: string }> {
|
||||
const settings = configService.getSettings()
|
||||
const binDir = path.join(configService.getBasePath(), 'bin')
|
||||
const apacheDir = path.join(binDir, 'apache')
|
||||
|
||||
const isWindows = process.platform === 'win32';
|
||||
const binPath = findExecutable(apacheDir, isWindows ? 'httpd.exe' : 'httpd')
|
||||
if (!binPath) throw new Error('Apache executable bulunamadı.')
|
||||
|
||||
const apacheRoot = path.dirname(path.dirname(binPath)) // bin'in üstü
|
||||
const logDir = path.join(configService.getBasePath(), 'logs')
|
||||
const rootPath = path.join(app.getAppPath(), 'www')
|
||||
|
||||
// Ensure directories exist
|
||||
const projectsConfDir = path.join(configService.getBasePath(), 'generated_configs', 'projects_apache')
|
||||
if (!fs.existsSync(projectsConfDir)) fs.mkdirSync(projectsConfDir, { recursive: true })
|
||||
|
||||
// Generate project configs
|
||||
const allProjects = await projectService.getProjects()
|
||||
const projects = allProjects.filter(p => p.serverType === 'apache')
|
||||
for (const p of projects) {
|
||||
const projectConfPath = path.join(projectsConfDir, `${p.host}.conf`)
|
||||
let shouldGenerate = forceProjects || !fs.existsSync(projectConfPath)
|
||||
|
||||
if (shouldGenerate) {
|
||||
const phpPort = portMappingService.getPhpPort(p.phpVersion)
|
||||
let normalizedPath = p.path.replace(/\\/g, '/')
|
||||
if (!normalizedPath.endsWith('/')) normalizedPath += '/'
|
||||
|
||||
await configService.generateConfig('apache_project.conf.template', `projects_apache/${p.host}.conf`, {
|
||||
HOST: p.host,
|
||||
PATH: normalizedPath,
|
||||
PHP_PORT: phpPort.toString()
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
const projectsInclusion = projects.length > 0
|
||||
? `Include "${projectsConfDir.replace(/\\/g, '/')}/*.conf"`
|
||||
: ''
|
||||
|
||||
const configPath = await configService.generateConfig('httpd.conf.template', 'httpd.conf', {
|
||||
PORT: settings.apachePort || '8080',
|
||||
LISTEN_ADDRESS: settings.allowRemoteAccess ? '0.0.0.0' : '127.0.0.1',
|
||||
PHP_PORT: settings.phpPort,
|
||||
ROOT: rootPath.replace(/\\/g, '/'),
|
||||
SRVROOT: apacheRoot.replace(/\\/g, '/'),
|
||||
LOG_DIR: logDir.replace(/\\/g, '/'),
|
||||
PHPMYADMIN_DIR: phpMyAdminService.getPath().replace(/\\/g, '/'),
|
||||
PROJECTS: projectsInclusion
|
||||
})
|
||||
|
||||
return { binPath, apacheDir, configPath }
|
||||
}
|
||||
|
||||
async function restartApache(): Promise<{ success: boolean; message: string }> {
|
||||
try {
|
||||
const { binPath, configPath } = await rebuildApacheConfig(false)
|
||||
|
||||
await processManager.forceKillAll('apache')
|
||||
await processManager.stopService('apache')
|
||||
await new Promise(resolve => setTimeout(resolve, 1000))
|
||||
|
||||
const success = await processManager.startService('apache', binPath, ['-f', configPath], false)
|
||||
|
||||
if (success) {
|
||||
return { success: true, message: 'Apache restart successful' }
|
||||
} else {
|
||||
const errorLogs = await processManager.getLastErrorLogs('apache')
|
||||
return { success: false, message: `Apache restart failed:\n${errorLogs.join('\n')}` }
|
||||
}
|
||||
} catch (error: any) {
|
||||
return { success: false, message: `Restart hatası: ${error.message}` }
|
||||
}
|
||||
}
|
||||
|
||||
export function registerIpcHandlers(): void {
|
||||
// Service management
|
||||
ipcMain.handle('services:reload', async (_event, serviceName: string) => {
|
||||
if (serviceName !== 'nginx') return { success: false, message: 'Yalnızca Nginx için reload desteklenmektedir.' }
|
||||
return await reloadNginx()
|
||||
if (serviceName === 'nginx') return await reloadNginx()
|
||||
if (serviceName === 'apache') return await restartApache() // Apache doesn't have a simple reload here
|
||||
return { success: false, message: 'Bu servis için reload desteklenmiyor.' }
|
||||
})
|
||||
|
||||
ipcMain.handle('services:start', async (_event, serviceName: string) => {
|
||||
@@ -157,17 +235,24 @@ export function registerIpcHandlers(): void {
|
||||
|
||||
if (serviceName === 'nginx') {
|
||||
const { binPath, nginxPrefix, configPath } = await rebuildNginxConfig(false)
|
||||
|
||||
const success = await processManager.startService('nginx', binPath, ['-p', nginxPrefix, '-c', configPath], false)
|
||||
|
||||
if (!success) {
|
||||
const errorLogs = await processManager.getLastErrorLogs('nginx')
|
||||
return { success: false, message: `Nginx başlatılamadı.\n\n${errorLogs.join('\n')}` }
|
||||
}
|
||||
|
||||
return { success, message: success ? 'Nginx başlatıldı.' : 'Nginx devreye alınamadı.' }
|
||||
}
|
||||
|
||||
if (serviceName === 'apache') {
|
||||
const { binPath, configPath } = await rebuildApacheConfig(false)
|
||||
const success = await processManager.startService('apache', binPath, ['-f', configPath], false)
|
||||
if (!success) {
|
||||
const errorLogs = await processManager.getLastErrorLogs('apache')
|
||||
return { success: false, message: `Apache başlatılamadı.\n\n${errorLogs.join('\n')}` }
|
||||
}
|
||||
return { success, message: success ? 'Apache başlatıldı.' : 'Apache devreye alınamadı.' }
|
||||
}
|
||||
|
||||
if (serviceName.startsWith('php')) {
|
||||
const versionMatch = serviceName.match(/^php:(.+)$/)
|
||||
const phpVersion = versionMatch ? versionMatch[1] : null
|
||||
@@ -451,6 +536,33 @@ export function registerIpcHandlers(): void {
|
||||
}
|
||||
})
|
||||
|
||||
// Apache Versions
|
||||
ipcMain.handle('apache:versions', async () => {
|
||||
return await apacheManagerService.getVersions()
|
||||
})
|
||||
|
||||
ipcMain.handle('apache:download', async (event, id: string) => {
|
||||
const versions = await apacheManagerService.getVersions()
|
||||
const version = versions.find(v => v.id === id)
|
||||
if (!version) return { success: false, message: 'Geçersiz Apache sürümü.' }
|
||||
|
||||
try {
|
||||
apacheManagerService.updateProgress(id, 0, 'downloading')
|
||||
event.sender.send('apache:progress', { id, progress: 0 })
|
||||
|
||||
await downloadService.downloadAndExtract(version.url, id, (p) => {
|
||||
apacheManagerService.updateProgress(id, p)
|
||||
event.sender.send('apache:progress', { id, progress: p })
|
||||
})
|
||||
|
||||
apacheManagerService.updateProgress(id, 100, 'installed')
|
||||
return { success: true, message: 'Apache indirme tamamlandı.' }
|
||||
} catch (error: any) {
|
||||
apacheManagerService.updateProgress(id, 0, 'available')
|
||||
return { success: false, message: `Apache hatası: ${error.message}` }
|
||||
}
|
||||
})
|
||||
|
||||
// Nginx Versions
|
||||
ipcMain.handle('nginx:versions', async () => {
|
||||
return await nginxManagerService.getVersions()
|
||||
|
||||
Reference in New Issue
Block a user