80 lines
3.5 KiB
Python
Executable File
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))
|