feat: implement Nginx and Apache configuration management and service control IPC handlers

This commit is contained in:
Ümit Tunç
2026-04-02 00:15:04 +03:00
parent 8c18c25ae9
commit 72b2d297fd
2 changed files with 64 additions and 4 deletions
+7
View File
@@ -232,9 +232,13 @@ async function rebuildApacheConfig(forceProjects: boolean = false): Promise<{ bi
async function restartApache(): Promise<{ success: boolean; message: string }> { async function restartApache(): Promise<{ success: boolean; message: string }> {
try { try {
const { binPath, configPath } = await rebuildApacheConfig(false) const { binPath, configPath } = await rebuildApacheConfig(false)
const settings = configService.getSettings()
await processManager.forceKillAll('apache') await processManager.forceKillAll('apache')
await processManager.stopService('apache') await processManager.stopService('apache')
// Force kill port to be absolutely sure
await processManager.killByPort('apache', settings.apachePort || '8080')
await new Promise(resolve => setTimeout(resolve, 1000)) await new Promise(resolve => setTimeout(resolve, 1000))
const success = await processManager.startService('apache', binPath, ['-f', configPath], false) const success = await processManager.startService('apache', binPath, ['-f', configPath], false)
@@ -275,6 +279,9 @@ export function registerIpcHandlers(): void {
if (serviceName === 'apache') { if (serviceName === 'apache') {
const { binPath, configPath } = await rebuildApacheConfig(false) const { binPath, configPath } = await rebuildApacheConfig(false)
const settings = configService.getSettings()
// Ensure port is free
await processManager.killByPort('apache', settings.apachePort || '8080')
const success = await processManager.startService('apache', binPath, ['-f', configPath], false) const success = await processManager.startService('apache', binPath, ['-f', configPath], false)
if (!success) { if (!success) {
const errorLogs = await processManager.getLastErrorLogs('apache') const errorLogs = await processManager.getLastErrorLogs('apache')
+57 -4
View File
@@ -517,7 +517,15 @@ function App(): JSX.Element {
if (window.api && window.api.invoke) { if (window.api && window.api.invoke) {
const result = await window.api.invoke('nginx:config:save', nginxConfig) const result = await window.api.invoke('nginx:config:save', nginxConfig)
if (result.success) { if (result.success) {
setNotification({ open: true, message: t('server.nginx.config_saved'), severity: 'success' }) Swal.fire({
title: t('common.success'),
text: t('server.nginx.config_saved'),
icon: 'success',
background: '#1e1e1e',
color: '#fff',
confirmButtonColor: '#153E5E',
customClass: { popup: 'swal2-dark-popup' }
})
setIsNginxConfigOpen(false) setIsNginxConfigOpen(false)
} }
} }
@@ -535,7 +543,15 @@ function App(): JSX.Element {
if (window.api && window.api.invoke) { if (window.api && window.api.invoke) {
const result = await window.api.invoke('apache:config:save', apacheConfig) const result = await window.api.invoke('apache:config:save', apacheConfig)
if (result.success) { if (result.success) {
setNotification({ open: true, message: t('server.apache.config_saved'), severity: 'success' }) Swal.fire({
title: t('common.success'),
text: t('server.apache.config_saved'),
icon: 'success',
background: '#1e1e1e',
color: '#fff',
confirmButtonColor: '#153E5E',
customClass: { popup: 'swal2-dark-popup' }
})
setIsApacheConfigOpen(false) setIsApacheConfigOpen(false)
} }
} }
@@ -616,7 +632,15 @@ function App(): JSX.Element {
if (window.api && window.api.invoke) { if (window.api && window.api.invoke) {
const result = await window.api.invoke('project:nginx:save', selectedProjectHost, projectNginxConfig) const result = await window.api.invoke('project:nginx:save', selectedProjectHost, projectNginxConfig)
if (result.success) { if (result.success) {
setNotification({ open: true, message: t('server.nginx.config_saved'), severity: 'success' }) Swal.fire({
title: t('common.success'),
text: t('server.nginx.config_saved'),
icon: 'success',
background: '#1e1e1e',
color: '#fff',
confirmButtonColor: '#153E5E',
customClass: { popup: 'swal2-dark-popup' }
})
setIsProjectNginxConfigOpen(false) setIsProjectNginxConfigOpen(false)
} }
} }
@@ -1099,7 +1123,15 @@ function App(): JSX.Element {
<IconButton <IconButton
onClick={() => { onClick={() => {
window.api.invoke('services:reload', 'nginx').then((res: any) => { window.api.invoke('services:reload', 'nginx').then((res: any) => {
setNotification({ open: true, message: res.message, severity: res.success ? 'success' : 'error' }) Swal.fire({
title: res.success ? t('common.success') : t('common.error'),
text: res.message,
icon: res.success ? 'success' : 'error',
background: '#1e1e1e',
color: '#fff',
confirmButtonColor: '#153E5E',
customClass: { popup: 'swal2-dark-popup' }
})
}) })
}} }}
title={t('server.nginx.save_reload')} title={t('server.nginx.save_reload')}
@@ -1150,6 +1182,27 @@ function App(): JSX.Element {
> >
<SettingsIcon fontSize="small" /> <SettingsIcon fontSize="small" />
</IconButton> </IconButton>
<IconButton
onClick={() => {
window.api.invoke('services:reload', 'apache').then((res: any) => {
Swal.fire({
title: res.success ? t('common.success') : t('common.error'),
text: res.message,
icon: res.success ? 'success' : 'error',
background: '#1e1e1e',
color: '#fff',
confirmButtonColor: '#153E5E',
customClass: { popup: 'swal2-dark-popup' }
})
})
}}
title={t('server.apache.save_reload')}
size="small"
disabled={status.apache !== 'running'}
sx={{ bgcolor: 'rgba(255,255,255,0.05)', '&:hover': { color: 'primary.main' } }}
>
<RefreshIcon fontSize="small" />
</IconButton>
</Box> </Box>
<Switch <Switch
checked={status.apache === 'running' || status.apache === 'starting'} checked={status.apache === 'running' || status.apache === 'starting'}