修改了Gunicorn标签内容
This commit is contained in:
259
gunicorn_tab.py
259
gunicorn_tab.py
@@ -2,19 +2,52 @@ import os
|
||||
from loguru import logger
|
||||
from PySide6.QtWidgets import (QWidget, QVBoxLayout, QHBoxLayout, QLabel, QLineEdit,
|
||||
QPushButton, QComboBox, QMessageBox, QTextEdit,
|
||||
QGroupBox, QGridLayout, QProgressBar)
|
||||
QGroupBox, QGridLayout, QProgressBar, QDialog,
|
||||
QDialogButtonBox)
|
||||
from PySide6.QtCore import Qt
|
||||
|
||||
from threads import (GunicornInstallThread, GunicornTestThread,
|
||||
UploadGunicornServiceThread, ManageGunicornServiceThread)
|
||||
|
||||
|
||||
class PasswordDialog(QDialog):
|
||||
def __init__(self, parent=None):
|
||||
super().__init__(parent)
|
||||
self.setWindowTitle("输入密码")
|
||||
self.setMinimumWidth(300)
|
||||
|
||||
layout = QVBoxLayout()
|
||||
|
||||
# 密码输入
|
||||
password_layout = QHBoxLayout()
|
||||
password_layout.addWidget(QLabel("密码:"))
|
||||
self.password_input = QLineEdit()
|
||||
self.password_input.setEchoMode(QLineEdit.Password)
|
||||
password_layout.addWidget(self.password_input)
|
||||
layout.addLayout(password_layout)
|
||||
|
||||
# 按钮
|
||||
button_box = QDialogButtonBox(QDialogButtonBox.Ok | QDialogButtonBox.Cancel)
|
||||
button_box.accepted.connect(self.accept)
|
||||
button_box.rejected.connect(self.reject)
|
||||
layout.addWidget(button_box)
|
||||
|
||||
self.setLayout(layout)
|
||||
|
||||
def get_password(self):
|
||||
return self.password_input.text()
|
||||
|
||||
|
||||
class GunicornTab(QWidget):
|
||||
def __init__(self, parent=None):
|
||||
super().__init__(parent)
|
||||
self.parent = parent
|
||||
self.init_ui()
|
||||
|
||||
# 连接服务器切换信号
|
||||
if self.parent and hasattr(self.parent, 'server_changed'):
|
||||
self.parent.server_changed.connect(self.on_server_changed)
|
||||
logger.info("Gunicorn标签已连接到服务器切换信号")
|
||||
def init_ui(self):
|
||||
layout = QVBoxLayout()
|
||||
|
||||
@@ -120,32 +153,130 @@ class GunicornTab(QWidget):
|
||||
self.load_gunicorn_config()
|
||||
|
||||
def load_gunicorn_config(self):
|
||||
if self.parent and hasattr(self.parent, 'server_connection_tab'):
|
||||
django_path = self.parent.server_connection_tab.django_path_input.text()
|
||||
self.django_path_input.setText(django_path)
|
||||
|
||||
# 生成默认的服务文件内容
|
||||
service_name = self.service_name_input.text()
|
||||
port = self.port_input.text()
|
||||
workers = self.workers_input.text()
|
||||
|
||||
service_content = self.generate_service_file(service_name, django_path, port, workers)
|
||||
self.service_editor.setText(service_content)
|
||||
"""加载Gunicorn配置,使用config.json中的值"""
|
||||
try:
|
||||
if self.parent and hasattr(self.parent, 'get_current_config'):
|
||||
config = self.parent.get_current_config()
|
||||
if config:
|
||||
django_path = config.get('django_path', '')
|
||||
project_name = config.get('project_name', 'myproject')
|
||||
username = config.get('username', 'www-data')
|
||||
|
||||
# 设置Django项目路径
|
||||
self.django_path_input.setText(django_path)
|
||||
|
||||
# 设置服务名称为项目名
|
||||
self.service_name_input.setText(project_name)
|
||||
|
||||
# 生成服务文件内容
|
||||
service_content = self.generate_service_file_from_config(config)
|
||||
self.service_editor.setText(service_content)
|
||||
|
||||
logger.info(f"从当前服务器配置加载Gunicorn配置: django_path={django_path}, project_name={project_name}")
|
||||
else:
|
||||
logger.warning("未找到当前服务器配置")
|
||||
else:
|
||||
# 兼容旧的加载方式
|
||||
config_path = os.path.join(os.path.dirname(__file__), 'config.json')
|
||||
with open(config_path, 'r', encoding='utf-8') as f:
|
||||
config = json.load(f)
|
||||
|
||||
if config and 'servers' in config and len(config['servers']) > 0:
|
||||
server_config = config['servers'][0]
|
||||
django_path = server_config.get('remote_directory', '')
|
||||
project_name = server_config.get('project_name', 'myproject')
|
||||
username = server_config.get('username', 'www-data')
|
||||
|
||||
# 设置Django项目路径
|
||||
self.django_path_input.setText(django_path)
|
||||
|
||||
# 设置服务名称为项目名
|
||||
self.service_name_input.setText(project_name)
|
||||
|
||||
# 生成服务文件内容
|
||||
service_content = self.generate_service_file_from_config(server_config)
|
||||
self.service_editor.setText(service_content)
|
||||
|
||||
logger.info(f"从配置文件加载Gunicorn配置: django_path={django_path}, project_name={project_name}")
|
||||
except Exception as e:
|
||||
logger.error(f"加载Gunicorn配置失败: {str(e)}")
|
||||
# 不显示警告,避免影响用户体验
|
||||
|
||||
def generate_service_file(self, service_name, django_path, port, workers):
|
||||
def generate_service_file_from_config(self, config):
|
||||
"""根据config.json配置生成服务文件内容"""
|
||||
username = config.get('username', 'www-data')
|
||||
project_name = config.get('project_name', 'myproject')
|
||||
django_path = config.get('remote_directory', '/home/user')
|
||||
|
||||
# 构建完整的项目路径
|
||||
project_path = f"{django_path.rstrip('/')}/{project_name}"
|
||||
|
||||
return f"""[Unit]
|
||||
Description={service_name} daemon
|
||||
Description=Gunicorn daemon for {project_name}
|
||||
After=network.target
|
||||
|
||||
[Service]
|
||||
User=www-data
|
||||
Group=www-data
|
||||
WorkingDirectory={django_path}
|
||||
ExecStart=/usr/local/bin/gunicorn --workers {workers} --bind 0.0.0.0:{port} {os.path.basename(django_path)}.wsgi:application
|
||||
User={username}
|
||||
Group={username}
|
||||
WorkingDirectory={project_path}
|
||||
# 所有Gunicorn参数直接在这里配置
|
||||
ExecStart=/usr/local/bin/gunicorn \\
|
||||
--bind 127.0.0.1:8000 \\
|
||||
--workers $(nproc --all * 2 + 1) \\
|
||||
--worker-class sync \\
|
||||
--timeout 60 \\
|
||||
--name {project_name} \\
|
||||
--access-logfile {project_path}/logs/gunicorn_access.log \\
|
||||
--error-logfile {project_path}/logs/gunicorn_error.log \\
|
||||
--log-level info \\
|
||||
{project_name}.wsgi:application
|
||||
Restart=on-failure
|
||||
RestartSec=5s
|
||||
PrivateTmp=true
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
"""
|
||||
WantedBy=multi-user.target"""
|
||||
|
||||
def generate_service_file(self, service_name, django_path, port, workers):
|
||||
"""保持向后兼容的方法"""
|
||||
# 获取config.json中的配置信息
|
||||
config = None
|
||||
if self.parent and hasattr(self.parent, 'server_connection_tab'):
|
||||
config = self.parent.server_connection_tab.get_current_config()
|
||||
|
||||
if config:
|
||||
return self.generate_service_file_from_config(config)
|
||||
else:
|
||||
# 如果没有config,使用默认值
|
||||
username = 'www-data'
|
||||
project_name = service_name
|
||||
project_path = f"{django_path.rstrip('/')}/{project_name}"
|
||||
|
||||
return f"""[Unit]
|
||||
Description=Gunicorn daemon for {project_name}
|
||||
After=network.target
|
||||
|
||||
[Service]
|
||||
User={username}
|
||||
Group={username}
|
||||
WorkingDirectory={project_path}
|
||||
# 所有Gunicorn参数直接在这里配置
|
||||
ExecStart=/usr/local/bin/gunicorn \\
|
||||
--bind 127.0.0.1:{port} \\
|
||||
--workers $(nproc --all * 2 + 1) \\
|
||||
--worker-class sync \\
|
||||
--timeout 60 \\
|
||||
--name {project_name} \\
|
||||
--access-logfile {project_path}/logs/gunicorn_access.log \\
|
||||
--error-logfile {project_path}/logs/gunicorn_error.log \\
|
||||
--log-level info \\
|
||||
{project_name}.wsgi:application
|
||||
Restart=on-failure
|
||||
RestartSec=5s
|
||||
PrivateTmp=true
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target"""
|
||||
|
||||
def check_ssh_connection(self):
|
||||
if not self.parent or not self.parent.ssh_client:
|
||||
@@ -153,6 +284,25 @@ WantedBy=multi-user.target
|
||||
return False
|
||||
return True
|
||||
|
||||
def get_password(self):
|
||||
# 获取密码
|
||||
password = None
|
||||
if self.parent and hasattr(self.parent, 'server_connection_tab'):
|
||||
password = self.parent.server_connection_tab.password_input.text()
|
||||
|
||||
# 如果密码为空,弹出密码输入对话框
|
||||
if not password:
|
||||
dialog = PasswordDialog(self)
|
||||
if dialog.exec_() == QDialog.Accepted:
|
||||
password = dialog.get_password()
|
||||
# 保存密码到服务器连接标签页
|
||||
if self.parent and hasattr(self.parent, 'server_connection_tab'):
|
||||
self.parent.server_connection_tab.password_input.setText(password)
|
||||
else:
|
||||
return None
|
||||
|
||||
return password
|
||||
|
||||
def install_gunicorn(self):
|
||||
if not self.check_ssh_connection():
|
||||
return
|
||||
@@ -163,9 +313,11 @@ WantedBy=multi-user.target
|
||||
self.progress_bar.setValue(0)
|
||||
|
||||
# 获取密码
|
||||
password = None
|
||||
if self.parent and hasattr(self.parent, 'server_connection_tab'):
|
||||
password = self.parent.server_connection_tab.password_input.text()
|
||||
password = self.get_password()
|
||||
if password is None:
|
||||
self.install_gunicorn_btn.setEnabled(True)
|
||||
self.progress_bar.setVisible(False)
|
||||
return
|
||||
|
||||
self.gunicorn_install_thread = GunicornInstallThread(self.parent.ssh_client, password)
|
||||
self.gunicorn_install_thread.progress_updated.connect(self.update_progress)
|
||||
@@ -218,20 +370,32 @@ WantedBy=multi-user.target
|
||||
if not self.check_ssh_connection():
|
||||
return
|
||||
|
||||
service_name = self.service_name_input.text().strip()
|
||||
# 获取config.json中的配置信息
|
||||
config = None
|
||||
if self.parent and hasattr(self.parent, 'server_connection_tab'):
|
||||
config = self.parent.server_connection_tab.get_current_config()
|
||||
|
||||
if config:
|
||||
project_name = config.get('project_name', 'django')
|
||||
else:
|
||||
project_name = 'django'
|
||||
|
||||
# 使用gunicorn_[project_name].service格式作为服务名称
|
||||
service_name = f"gunicorn_{project_name}"
|
||||
service_content = self.service_editor.toPlainText()
|
||||
|
||||
if not service_name or not service_content:
|
||||
QMessageBox.warning(self, "警告", "请输入服务名称并编辑服务文件内容")
|
||||
QMessageBox.warning(self, "警告", "请编辑服务文件内容")
|
||||
return
|
||||
|
||||
self.output_text.append(f"正在上传服务文件 {service_name}...")
|
||||
self.upload_service_btn.setEnabled(False)
|
||||
|
||||
# 获取密码
|
||||
password = None
|
||||
if self.parent and hasattr(self.parent, 'server_connection_tab'):
|
||||
password = self.parent.server_connection_tab.password_input.text()
|
||||
password = self.get_password()
|
||||
if password is None:
|
||||
self.upload_service_btn.setEnabled(True)
|
||||
return
|
||||
|
||||
self.upload_thread = UploadGunicornServiceThread(self.parent.ssh_client, service_name, service_content, password)
|
||||
self.upload_thread.result_ready.connect(self.on_upload_service_result)
|
||||
@@ -250,10 +414,18 @@ WantedBy=multi-user.target
|
||||
if not self.check_ssh_connection():
|
||||
return
|
||||
|
||||
service_name = self.service_name_input.text().strip()
|
||||
if not service_name:
|
||||
QMessageBox.warning(self, "警告", "请输入服务名称")
|
||||
return
|
||||
# 获取config.json中的配置信息
|
||||
config = None
|
||||
if self.parent and hasattr(self.parent, 'server_connection_tab'):
|
||||
config = self.parent.server_connection_tab.get_current_config()
|
||||
|
||||
if config:
|
||||
project_name = config.get('project_name', 'django')
|
||||
else:
|
||||
project_name = 'django'
|
||||
|
||||
# 使用gunicorn_[project_name].service格式作为服务名称
|
||||
service_name = f"gunicorn_{project_name}"
|
||||
|
||||
self.output_text.append(f"正在执行服务 {action} 操作...")
|
||||
|
||||
@@ -264,9 +436,11 @@ WantedBy=multi-user.target
|
||||
btn.setEnabled(False)
|
||||
|
||||
# 获取密码
|
||||
password = None
|
||||
if self.parent and hasattr(self.parent, 'server_connection_tab'):
|
||||
password = self.parent.server_connection_tab.password_input.text()
|
||||
password = self.get_password()
|
||||
if password is None:
|
||||
for btn in buttons:
|
||||
btn.setEnabled(True)
|
||||
return
|
||||
|
||||
self.manage_thread = ManageGunicornServiceThread(self.parent.ssh_client, service_name, action, password)
|
||||
self.manage_thread.result_ready.connect(lambda s, m: self.on_manage_service_result(s, m, buttons))
|
||||
@@ -291,8 +465,17 @@ WantedBy=multi-user.target
|
||||
if not self.check_ssh_connection():
|
||||
return
|
||||
|
||||
service_name = self.service_name_input.text().strip()
|
||||
if not service_name:
|
||||
return
|
||||
# 获取config.json中的配置信息
|
||||
config = None
|
||||
if self.parent and hasattr(self.parent, 'server_connection_tab'):
|
||||
config = self.parent.server_connection_tab.get_current_config()
|
||||
|
||||
if config:
|
||||
project_name = config.get('project_name', 'django')
|
||||
else:
|
||||
project_name = 'django'
|
||||
|
||||
# 使用gunicorn_[project_name].service格式作为服务名称
|
||||
service_name = f"gunicorn_{project_name}"
|
||||
|
||||
self.manage_service("status")
|
||||
Reference in New Issue
Block a user