syncra_addons/syncra_welcome/models/syncra_devops.py

80 lines
3.5 KiB
Python
Executable File

from odoo import models, fields, api, _
from odoo.exceptions import UserError
import os, zipfile, base64, io, subprocess
class SyncraDevOps(models.Model):
_inherit = 'syncra.welcome'
module_zip = fields.Binary(string="Upload Módulo (.zip)")
module_filename = fields.Char(string="Nome do Ficheiro")
def action_deploy_module(self):
"""Descompacta o ZIP na custom_addons2 e sincroniza com o Gitea do gelson.souto"""
if not self.module_zip:
raise UserError(_("Por favor, carregue um ficheiro .zip primeiro."))
addons_path = '/root/odoo-18.0+e.20251216/custom_addons2/'
# URL exato validado no terminal da HilariBD
git_url = "http://gelson.souto:Luanda244@173.208.243.178:3000/gelson.souto/syncra_addons.git"
try:
# 1. Descompactar os ficheiros
zip_data = base64.b64decode(self.module_zip)
with zipfile.ZipFile(io.BytesIO(zip_data)) as z:
z.extractall(addons_path)
# 2. Operações Git
os.chdir(addons_path)
# Configurações de identidade local
subprocess.run(['git', 'config', 'user.email', 'gelson.souto@syncra.com'], check=True)
subprocess.run(['git', 'config', 'user.name', 'Gelson do Souto'], check=True)
# Adicionar e Commit (com verificação para não falhar se não houver mudanças)
subprocess.run(['git', 'add', '.'], check=True)
# O status verifica se há algo novo antes de tentar o commit
status = subprocess.run(['git', 'status', '--porcelain'], capture_output=True, text=True)
if status.stdout:
subprocess.run(['git', 'commit', '-m', f"Auto-deploy SYNCRA: {self.module_filename}"], check=True)
# 3. Push Direto e Seguro
# Usamos -c credential.helper= para garantir que ele ignore senhas antigas e use o git_url
subprocess.run(['git', '-c', 'credential.helper=', 'push', git_url, 'HEAD:main'], check=True)
# 4. Atualizar lista de módulos no Odoo
self.env['ir.module.module'].update_list()
self.module_zip = False
return {
'effect': {
'fadeout': 'slow',
'message': 'Sucesso! Módulo em custom_addons2 e Gitea atualizado.',
'type': 'rainbow_man'
}
}
except subprocess.CalledProcessError as e:
raise UserError(_("Erro no comando Git (Verifique o terminal): %s") % (e.stderr or str(e)))
except Exception as e:
raise UserError(_("Erro inesperado no Deploy: %s") % str(e))
def action_restart_odoo(self):
"""Reinicia o serviço sem causar erro de SIGTERM no ecrã"""
try:
# O comando 'sleep 1' dá tempo ao Odoo para enviar o Rainbow Man antes de cair
restart_command = "sleep 1 && sudo systemctl restart odoo"
# Executa de forma desvinculada (nohup ou fork)
subprocess.Popen(['/bin/bash', '-c', restart_command])
return {
'effect': {
'fadeout': 'slow',
'message': 'Sinal de reinício enviado! O sistema voltará em instantes.',
'type': 'rainbow_man',
}
}
except Exception as e:
raise UserError(_("Falha ao agendar reinício: %s") % str(e))