mirror of
https://github.com/iio612/DEFENDER.git
synced 2026-02-13 11:14:23 +00:00
Adding 'make update' to update from git repository. remove previous installation.py file, the update of packages is done via install.py file.
This commit is contained in:
7
Makefile
7
Makefile
@@ -53,3 +53,10 @@ ifeq ($(OS), Linux)
|
||||
fi
|
||||
@export echo $DBUS_SESSION_BUS_ADDRESS && systemctl --user daemon-reload && echo "Systemd Daemon reloaded!"
|
||||
endif
|
||||
|
||||
update:
|
||||
ifeq ($(OS), Linux)
|
||||
$(info Starting update from the main repository...)
|
||||
@. .pyenv/bin/activate && python core/install.py --git-update
|
||||
$(info Update done!)
|
||||
endif
|
||||
|
||||
139
README.md
139
README.md
@@ -34,10 +34,11 @@ Il permet aux opérateurs de gérer efficacement un canal, tout en offrant aux u
|
||||
- Python version 3.10 ou supérieure
|
||||
```bash
|
||||
# Bash
|
||||
$ git clone https://github.com/adator85/IRC_DEFENDER_MODULES.git
|
||||
$ git clone https://github.com/adator85/DEFENDER.git defender
|
||||
$ cd defender/
|
||||
# Renommer le fichier exemple_configuration.json en configuration.json
|
||||
# Configurer le fichier configuration.json
|
||||
$ python3 main.py
|
||||
$ make install
|
||||
```
|
||||
Si votre configuration est bonne, votre service est censé etre connecté a votre réseau IRC
|
||||
Pour Les prochains lancement de defender vous devez utiliser la commande suivante:
|
||||
@@ -49,11 +50,11 @@ Pour Les prochains lancement de defender vous devez utiliser la commande suivant
|
||||
# Installation manuelle:
|
||||
```bash
|
||||
# Bash
|
||||
$ git clone https://github.com/adator85/IRC_DEFENDER_MODULES.git
|
||||
$ cd IRC_DEFENDER_MODULES
|
||||
$ git clone https://github.com/adator85/DEFENDER.git defender
|
||||
$ cd defender/
|
||||
$ python3 -m venv .pyenv
|
||||
$ source .pyenv/bin/activate
|
||||
(pyenv)$ pip install sqlalchemy, psutil, requests, faker, unrealircd_rpc_py, pyyaml
|
||||
(pyenv)$ pip install -r requirements.txt
|
||||
|
||||
# Créer un service nommé "defender.service"
|
||||
# pour votre service et placer le dans "/PATH/TO/USER/.config/systemd/user/"
|
||||
@@ -104,87 +105,91 @@ Pour Les prochains lancement de defender vous devez utiliser la commande suivant
|
||||
GLINE_DURATION: Durée de bannissement temporaire d'un utilisateur en minutes. (default : "30")
|
||||
|
||||
DEBUG (Debug)
|
||||
DEBUG_LEVEL: Niveau de verbosité des messages de debug (plus grand est le nombre, plus il y a d'informations). (default : 20) Pour une production
|
||||
DEBUG_LEVEL: Niveau de verbosité des messages de debug (plus petit est le nombre, plus il y a d'informations). (default : 20) Pour une production
|
||||
DEBUG_HARD: Généralement utiliser pour les developpeurs.
|
||||
|
||||
```
|
||||
Modification de la configuration
|
||||
|
||||
Vous devez modifier le fichier configuration.json en remplaçant les valeurs par défaut avec vos propres informations. Assurez-vous de bien lire la description de chaque paramètre pour une configuration optimale du service.
|
||||
Vous devez modifier le fichier configuration.yaml en remplaçant les valeurs par défaut avec vos propres informations. Assurez-vous de bien lire la description de chaque paramètre pour une configuration optimale du service.
|
||||
|
||||
## Exemple de configuration de base
|
||||
```json
|
||||
{
|
||||
"SERVEUR_IP": "IP.DE.TON.SERVER",
|
||||
"SERVEUR_HOSTNAME": "HOST.DE.TON.SERVER",
|
||||
"SERVEUR_LINK": "LINK.DE.TON.SERVER",
|
||||
"SERVEUR_PORT": 6901,
|
||||
"SERVEUR_PASSWORD": "MOT_DE_PASS_DE_TON_LINK",
|
||||
"SERVEUR_ID": "10Z",
|
||||
"SERVEUR_SSL": true,
|
||||
```yaml
|
||||
configuration:
|
||||
SERVEUR_IP: "YOUR.SERVER.IP"
|
||||
SERVEUR_HOSTNAME: "YOUR.SERVER.HOST"
|
||||
SERVEUR_LINK: "LINK.DE.TON.SERVER"
|
||||
SERVEUR_PORT: 7002
|
||||
SERVEUR_PASSWORD: "YOUR_LINK_PASSWORD"
|
||||
SERVEUR_ID: "006"
|
||||
SERVEUR_SSL: true
|
||||
|
||||
"SERVICE_NAME": "defender",
|
||||
"SERVICE_NICKNAME": "PyDefender",
|
||||
"SERVICE_REALNAME": "Python Defender Security",
|
||||
"SERVICE_USERNAME": "PyDefender",
|
||||
"SERVICE_HOST": "HOST.DE.TON.DEFENDER",
|
||||
SERVICE_NAME: "defender"
|
||||
SERVICE_NICKNAME: "PyDefender"
|
||||
SERVICE_REALNAME: "Python Defender Security"
|
||||
SERVICE_USERNAME: "PyDefender"
|
||||
SERVICE_HOST: "HOST.DE.TON.DEFENDER"
|
||||
SERVICE_INFO: "Network IRC Service"
|
||||
SERVICE_CHANLOG: "#services"
|
||||
SERVICE_SMODES: "+ioqBS"
|
||||
SERVICE_CMODES: "ntsOP"
|
||||
SERVICE_UMODES: "o"
|
||||
SERVICE_PREFIX: "!"
|
||||
|
||||
"OWNER": "TON_NICK_NAME",
|
||||
"PASSWORD": "TON_PASSWORD"
|
||||
|
||||
}
|
||||
OWNER: "TON_NICK_NAME"
|
||||
PASSWORD: "TON_PASSWORD"
|
||||
|
||||
```
|
||||
|
||||
## Exemple complet de configuration
|
||||
```json
|
||||
{
|
||||
"SERVEUR_IP": "YOUR.SERVER.IP",
|
||||
"SERVEUR_HOSTNAME": "YOUR.SERVER.HOST",
|
||||
"SERVEUR_LINK": "LINK.DE.TON.SERVER",
|
||||
"SERVEUR_PORT": 6901,
|
||||
"SERVEUR_PASSWORD": "YOUR_LINK_PASSWORD",
|
||||
"SERVEUR_ID": "10Z",
|
||||
"SERVEUR_SSL": true,
|
||||
```yaml
|
||||
configuration:
|
||||
SERVEUR_IP: "YOUR.SERVER.IP"
|
||||
SERVEUR_HOSTNAME: "YOUR.SERVER.HOST"
|
||||
SERVEUR_LINK: "LINK.DE.TON.SERVER"
|
||||
SERVEUR_PORT: 7002
|
||||
SERVEUR_PASSWORD: "YOUR_LINK_PASSWORD"
|
||||
SERVEUR_ID: "006"
|
||||
SERVEUR_SSL: true
|
||||
|
||||
"SERVICE_NAME": "defender",
|
||||
"SERVICE_NICKNAME": "PyDefender",
|
||||
"SERVICE_REALNAME": "Python Defender Security",
|
||||
"SERVICE_USERNAME": "PyDefender",
|
||||
"SERVICE_HOST": "HOST.DE.TON.DEFENDER",
|
||||
"SERVICE_INFO": "Network IRC Service",
|
||||
"SERVICE_CHANLOG": "#services",
|
||||
"SERVICE_SMODES": "+ioqBS",
|
||||
"SERVICE_CMODES": "ntsOP",
|
||||
"SERVICE_UMODES": "o",
|
||||
"SERVICE_PREFIX": "!",
|
||||
SERVICE_NAME: "defender"
|
||||
SERVICE_NICKNAME: "PyDefender"
|
||||
SERVICE_REALNAME: "Python Defender Security"
|
||||
SERVICE_USERNAME: "PyDefender"
|
||||
SERVICE_HOST: "HOST.DE.TON.DEFENDER"
|
||||
SERVICE_INFO: "Network IRC Service"
|
||||
SERVICE_CHANLOG: "#services"
|
||||
SERVICE_SMODES: "+ioqBS"
|
||||
SERVICE_CMODES: "ntsOP"
|
||||
SERVICE_UMODES: "o"
|
||||
SERVICE_PREFIX: "!"
|
||||
|
||||
"OWNER": "TON_NICK_NAME",
|
||||
"PASSWORD": "TON_PASSWORD",
|
||||
OWNER: "TON_NICK_NAME"
|
||||
PASSWORD: "TON_PASSWORD"
|
||||
|
||||
"JSONRPC_URL": "https://your.domaine.com:8600/api",
|
||||
"JSONRPC_PATH_TO_SOCKET_FILE": "/PATH/TO/YOUR/IRCD/data/rpc.socket",
|
||||
"JSONRPC_METHOD": "socket",
|
||||
"JSONRPC_USER": "YOUR_RPC_USER",
|
||||
"JSONRPC_PASSWORD": "YOUR_RPC_PASSWORD",
|
||||
JSONRPC_URL: "https://your.domaine.com:8600/api"
|
||||
JSONRPC_PATH_TO_SOCKET_FILE: "/PATH/TO/YOUR/IRCD/data/rpc.socket"
|
||||
JSONRPC_METHOD: "unixsocket"
|
||||
JSONRPC_USER: "YOUR_RPC_USER"
|
||||
JSONRPC_PASSWORD: "YOUR_RPC_PASSWORD"
|
||||
|
||||
"SALON_JAIL": "#jail",
|
||||
"SALON_JAIL_MODES": "sS",
|
||||
"SALON_LIBERER": "#welcome",
|
||||
SALON_JAIL: "#jail"
|
||||
SALON_JAIL_MODES: "sS"
|
||||
SALON_LIBERER: "#welcome"
|
||||
|
||||
"CLONE_CHANNEL": "#clones",
|
||||
"CLONE_CMODES": "+nts",
|
||||
"CLONE_LOG_HOST_EXEMPT": ["HOST.TO.SKIP"],
|
||||
"CLONE_CHANNEL_PASSWORD": "YOUR_CHANNEL_PASSWORD",
|
||||
CLONE_CHANNEL: "#clones"
|
||||
CLONE_CMODES: "+nts"
|
||||
CLONE_LOG_HOST_EXEMPT: ["HOST.TO.SKIP"]
|
||||
CLONE_CHANNEL_PASSWORD: "YOUR_CHANNEL_PASSWORD"
|
||||
|
||||
"API_TIMEOUT": 2,
|
||||
API_TIMEOUT: 2
|
||||
|
||||
"PORTS_TO_SCAN": [3028, 8080, 1080, 1085, 4145, 9050],
|
||||
"WHITELISTED_IP": ["127.0.0.1"],
|
||||
"GLINE_DURATION": "30",
|
||||
PORTS_TO_SCAN: [3028 8080 1080 1085 4145 9050]
|
||||
WHITELISTED_IP: ["127.0.0.1"]
|
||||
GLINE_DURATION: "30"
|
||||
|
||||
"DEBUG_LEVEL": 20
|
||||
|
||||
}
|
||||
DEBUG_LEVEL: 20
|
||||
DEBUG_HARD: true
|
||||
```
|
||||
|
||||
# \\!/ Attention \\!/
|
||||
@@ -192,7 +197,7 @@ Le mot de passe de l'administrateur et le mot de passe du service doivent être
|
||||
Ne partagez pas vos informations de connexion au serveur IRC avec des tiers.
|
||||
a votre premiere connexion vous devez tapez
|
||||
```
|
||||
/msg [NomDuService] auth [nickname] [password]
|
||||
/msg [NomDuService] firstauth [nickname] [password]
|
||||
-- Une fois identifié tapez la commande suivante
|
||||
/msg [NomDuService] editaccess [nickname] [Nouveau-Password] 5
|
||||
```
|
||||
|
||||
@@ -24,7 +24,7 @@ configuration:
|
||||
|
||||
JSONRPC_URL: "https://your.domaine.com:8600/api"
|
||||
JSONRPC_PATH_TO_SOCKET_FILE: "/PATH/TO/YOUR/IRCD/data/rpc.socket"
|
||||
JSONRPC_METHOD: "socket"
|
||||
JSONRPC_METHOD: "unixsocket"
|
||||
JSONRPC_USER: "YOUR_RPC_USER"
|
||||
JSONRPC_PASSWORD: "YOUR_RPC_PASSWORD"
|
||||
|
||||
|
||||
@@ -1,23 +1,99 @@
|
||||
import argparse
|
||||
import os
|
||||
import sys
|
||||
import json
|
||||
from dataclasses import dataclass
|
||||
from subprocess import check_call, CalledProcessError, check_output
|
||||
from pathlib import Path
|
||||
from platform import python_version_tuple
|
||||
import traceback
|
||||
|
||||
parser = argparse.ArgumentParser(description="Python Installation Code")
|
||||
parser.add_argument('--check-version', action='store_true', help='Check if the python version is ok!')
|
||||
parser.add_argument('--install', action='store_true', help='Run the installation')
|
||||
parser.add_argument('--git-update', action='store_true', help='Update from git (main repository)')
|
||||
args = parser.parse_args()
|
||||
|
||||
PYTHON_REQUIRED_VERSION = (3, 10, 0)
|
||||
PYTHON_SYSTEM_VERSION = tuple(map(int, python_version_tuple()))
|
||||
ROOT_PATH = os.getcwd()
|
||||
PYENV = Path(f'{ROOT_PATH}/.pyenv/bin/python')
|
||||
PYENV = Path(ROOT_PATH).joinpath('.pyenv/bin/python') if os.name != 'nt' else Path(ROOT_PATH).joinpath('.pyenv/Scripts/python.exe')
|
||||
PIPENV = Path(f'{ROOT_PATH}/.pyenv/bin/pip') if os.name != 'nt' else Path(f'{ROOT_PATH}/.pyenv/Scripts/pip.exe')
|
||||
USER_HOME_DIRECTORY = Path.home()
|
||||
SYSTEMD_PATH = Path(USER_HOME_DIRECTORY).joinpath('.config', 'systemd', 'user')
|
||||
PY_EXEC = 'defender.py'
|
||||
SERVICE_FILE_NAME = 'defender.service'
|
||||
|
||||
@dataclass
|
||||
class Package:
|
||||
name: str = None
|
||||
version: str = None
|
||||
|
||||
def __load_required_package_versions() -> list[Package]:
|
||||
"""This will create Package model with package names and required version
|
||||
"""
|
||||
try:
|
||||
DB_PACKAGES: list[Package] = []
|
||||
version_filename = Path(ROOT_PATH).joinpath('version.json') # f'.{os.sep}version.json'
|
||||
with open(version_filename, 'r') as version_data:
|
||||
package_info:dict[str, str] = json.load(version_data)
|
||||
|
||||
for name, version in package_info.items():
|
||||
if name == 'version':
|
||||
continue
|
||||
DB_PACKAGES.append(
|
||||
Package(name=name, version=version)
|
||||
)
|
||||
|
||||
return DB_PACKAGES
|
||||
|
||||
except FileNotFoundError as fe:
|
||||
print(f"File not found: {fe}")
|
||||
except Exception as err:
|
||||
print(f"General Error: {err}")
|
||||
|
||||
def update_packages() -> None:
|
||||
try:
|
||||
newVersion = False
|
||||
db_packages = __load_required_package_versions()
|
||||
print(ROOT_PATH)
|
||||
if sys.prefix not in PYENV.__str__():
|
||||
print(f"You are probably running a new installation or you are not using your virtual env {PYENV}")
|
||||
return newVersion
|
||||
|
||||
print(f"> Checking for dependencies versions ==> WAIT")
|
||||
for package in db_packages:
|
||||
newVersion = False
|
||||
_required_version = package.version
|
||||
_installed_version: str = None
|
||||
output = check_output([PIPENV, 'show', package.name])
|
||||
for line in output.decode().splitlines():
|
||||
if line.startswith('Version:'):
|
||||
_installed_version = line.split(':')[1].strip()
|
||||
break
|
||||
|
||||
required_version = tuple(map(int, _required_version.split('.')))
|
||||
installed_version = tuple(map(int, _installed_version.split('.')))
|
||||
|
||||
if required_version > installed_version:
|
||||
print(f'> New version of {package.name} is available {installed_version} ==> {required_version}')
|
||||
newVersion = True
|
||||
|
||||
if newVersion:
|
||||
check_call([PIPENV, 'install', '--upgrade', package.name])
|
||||
|
||||
print(f"> Dependencies versions ==> OK")
|
||||
return newVersion
|
||||
|
||||
except CalledProcessError:
|
||||
print(f"[!] Package {package.name} not installed [!]")
|
||||
except Exception as err:
|
||||
print(f"UpdatePackage Error: {err}")
|
||||
traceback.print_exc()
|
||||
|
||||
def run_git_update() -> None:
|
||||
check_call(['git', 'pull', 'origin', 'main'])
|
||||
|
||||
def check_python_requirement():
|
||||
if PYTHON_SYSTEM_VERSION < PYTHON_REQUIRED_VERSION:
|
||||
raise RuntimeError(f"Your Python Version is not meeting the requirement, System Version: {PYTHON_SYSTEM_VERSION} < Required Version {PYTHON_REQUIRED_VERSION}")
|
||||
@@ -65,6 +141,10 @@ def main():
|
||||
create_service_file()
|
||||
sys.exit(0)
|
||||
|
||||
if args.git_update:
|
||||
run_git_update()
|
||||
sys.exit(0)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
|
||||
@@ -1,314 +0,0 @@
|
||||
import os
|
||||
import json
|
||||
from sys import exit, prefix
|
||||
from dataclasses import dataclass
|
||||
from subprocess import check_call, run, CalledProcessError, PIPE, check_output
|
||||
from platform import python_version, python_version_tuple
|
||||
|
||||
class Install:
|
||||
|
||||
@dataclass
|
||||
class CoreConfig:
|
||||
install_log_file: str
|
||||
unix_systemd_folder: str
|
||||
service_file_name: str
|
||||
service_cmd_executable: list
|
||||
service_cmd_daemon_reload: list
|
||||
defender_main_executable: str
|
||||
python_min_version: str
|
||||
python_current_version_tuple: tuple[int, int, int]
|
||||
python_current_version: tuple[int, int, int]
|
||||
defender_install_folder: str
|
||||
venv_folder: str
|
||||
venv_cmd_installation: list
|
||||
venv_cmd_requirements: list[str]
|
||||
venv_pip_executable: str
|
||||
venv_python_executable: str
|
||||
|
||||
@dataclass
|
||||
class Package:
|
||||
name: str = None
|
||||
version: str = None
|
||||
|
||||
DB_PACKAGES: list[Package] = []
|
||||
|
||||
def __init__(self) -> None:
|
||||
|
||||
self.set_configuration()
|
||||
|
||||
if self.skip_install:
|
||||
self.install_dependencies()
|
||||
self.check_packages_version()
|
||||
return None
|
||||
|
||||
self.check_packages_version()
|
||||
|
||||
# Sinon tester les dependances python et les installer avec pip
|
||||
if self.do_install():
|
||||
|
||||
self.install_dependencies()
|
||||
|
||||
self.create_service_file()
|
||||
|
||||
self.print_final_message()
|
||||
|
||||
return None
|
||||
|
||||
def set_configuration(self):
|
||||
|
||||
self.skip_install = False
|
||||
defender_install_folder = os.getcwd()
|
||||
venv_folder = '.pyenv'
|
||||
unix_user_home_directory = os.path.expanduser("~")
|
||||
unix_systemd_folder = os.path.join(unix_user_home_directory, '.config', 'systemd', 'user')
|
||||
defender_main_executable = os.path.join(defender_install_folder, 'defender.py')
|
||||
|
||||
self.config = self.CoreConfig(
|
||||
install_log_file='install.log',
|
||||
unix_systemd_folder=unix_systemd_folder,
|
||||
service_file_name='defender.service',
|
||||
service_cmd_executable=['systemctl', '--user', 'start', 'defender'],
|
||||
service_cmd_daemon_reload=['systemctl', '--user', 'daemon-reload'],
|
||||
defender_main_executable=defender_main_executable,
|
||||
python_min_version=(3, 10, 0),
|
||||
python_current_version_tuple=tuple(map(int, python_version_tuple())),
|
||||
python_current_version=python_version(),
|
||||
defender_install_folder=defender_install_folder,
|
||||
venv_folder=venv_folder,
|
||||
venv_cmd_installation=['python3', '-m', 'venv', venv_folder],
|
||||
venv_cmd_requirements=['sqlalchemy','psutil','requests','faker','pyyaml','unrealircd_rpc_py'],
|
||||
venv_pip_executable=f'{os.path.join(defender_install_folder, venv_folder, "bin")}{os.sep}pip',
|
||||
venv_python_executable=f'{os.path.join(defender_install_folder, venv_folder, "bin")}{os.sep}python'
|
||||
)
|
||||
|
||||
if not self.check_python_version():
|
||||
# If the Python version is not good then Exit
|
||||
exit("[!] Python version error [!]")
|
||||
|
||||
if not os.path.exists(os.path.join(self.config.defender_install_folder, 'config', 'configuration.yaml')):
|
||||
# If configuration file do not exist
|
||||
exit("[!] Configuration file (core/configuration.yaml) doesn't exist! please create it [!]")
|
||||
|
||||
# Exclude Windows OS from the installation
|
||||
if os.name == 'nt':
|
||||
# If windows, modify pip and python virtual environment executable
|
||||
self.config.venv_pip_executable = f'{os.path.join(defender_install_folder, venv_folder, "Scripts")}{os.sep}pip.exe'
|
||||
self.config.venv_python_executable = f'{os.path.join(defender_install_folder, venv_folder, "Scripts")}{os.sep}python.exe'
|
||||
self.skip_install = True
|
||||
return False
|
||||
|
||||
if self.is_root():
|
||||
exit(f'[!] I highly not recommend running Defender as root [!]')
|
||||
self.skip_install = True
|
||||
return False
|
||||
|
||||
def is_root(self) -> bool:
|
||||
|
||||
if os.geteuid() != 0:
|
||||
print('> User without privileges ==> OK')
|
||||
return False
|
||||
elif os.geteuid() == 0:
|
||||
print('[!] Do not use root to install Defender [!]')
|
||||
exit("Do not use root to install Defender")
|
||||
return True
|
||||
|
||||
def do_install(self) -> bool:
|
||||
|
||||
full_service_file_path = os.path.join(self.config.unix_systemd_folder, self.config.service_file_name)
|
||||
|
||||
if not os.path.exists(full_service_file_path):
|
||||
print(f'[!] Service file does not exist [!]')
|
||||
return True
|
||||
|
||||
# Check if virtual env exist
|
||||
if not os.path.exists(f'{os.path.join(self.config.defender_install_folder, self.config.venv_folder)}'):
|
||||
self.run_subprocess(self.config.venv_cmd_installation)
|
||||
print(f'[!] Virtual env does not exist run the install [!]')
|
||||
return True
|
||||
|
||||
def run_subprocess(self, command:list) -> None:
|
||||
|
||||
print(f'> {command}')
|
||||
try:
|
||||
check_call(command)
|
||||
print("The command completed successfully.")
|
||||
except CalledProcessError as e:
|
||||
print(f"The command failed with the return code: {e.returncode}")
|
||||
print(f"Try to install dependencies ...")
|
||||
exit(5)
|
||||
|
||||
def get_packages_version_from_json(self) -> None:
|
||||
"""This will create Package model with package names and required version
|
||||
"""
|
||||
try:
|
||||
|
||||
version_filename = f'.{os.sep}version.json'
|
||||
with open(version_filename, 'r') as version_data:
|
||||
package_info:dict[str, str] = json.load(version_data)
|
||||
|
||||
for name, version in package_info.items():
|
||||
if name == 'version':
|
||||
continue
|
||||
|
||||
self.DB_PACKAGES.append(
|
||||
self.Package(name=name, version=version)
|
||||
)
|
||||
|
||||
return None
|
||||
except FileNotFoundError as fe:
|
||||
print(f"File not found: {fe}")
|
||||
except Exception as err:
|
||||
print(f"General Error: {err}")
|
||||
|
||||
def check_packages_version(self) -> bool:
|
||||
|
||||
try:
|
||||
newVersion = False
|
||||
self.get_packages_version_from_json()
|
||||
|
||||
if not self.config.venv_folder in prefix:
|
||||
print(f"You are probably running a new installation or you are not using your virtual env {self.config.venv_folder}")
|
||||
return newVersion
|
||||
|
||||
print(f"> Checking for dependencies versions ==> WAIT")
|
||||
for package in self.DB_PACKAGES:
|
||||
newVersion = False
|
||||
_required_version = package.version
|
||||
_installed_version: str = None
|
||||
|
||||
output = check_output([self.config.venv_pip_executable, 'show', package.name])
|
||||
for line in output.decode().splitlines():
|
||||
if line.startswith('Version:'):
|
||||
_installed_version = line.split(':')[1].strip()
|
||||
break
|
||||
|
||||
required_version = tuple(map(int, _required_version.split('.')))
|
||||
installed_version = tuple(map(int, _installed_version.split('.')))
|
||||
|
||||
if required_version > installed_version:
|
||||
print(f'> New version of {package.name} is available {installed_version} ==> {required_version}')
|
||||
newVersion = True
|
||||
|
||||
if newVersion:
|
||||
self.run_subprocess([self.config.venv_pip_executable, 'install', '--upgrade', package.name])
|
||||
|
||||
print(f"> Dependencies versions ==> OK")
|
||||
return newVersion
|
||||
|
||||
except CalledProcessError:
|
||||
print(f"[!] Package {package.name} not installed [!]")
|
||||
except Exception as err:
|
||||
print(f"General Error: {err}")
|
||||
|
||||
def check_python_version(self) -> bool:
|
||||
"""Test si la version de python est autorisée ou non
|
||||
|
||||
Returns:
|
||||
bool: True si la version de python est autorisé sinon False
|
||||
"""
|
||||
if self.config.python_current_version_tuple < self.config.python_min_version:
|
||||
print(f"## Your python version must be greather than or equal to {self.config.python_min_version} ##")
|
||||
return False
|
||||
|
||||
print(f"> Version of python : {self.config.python_current_version} ==> OK")
|
||||
return True
|
||||
|
||||
def check_package(self, package_name) -> bool:
|
||||
|
||||
try:
|
||||
# Run a command in the virtual environment's Python to check if the package is installed
|
||||
run([self.config.venv_python_executable, '-c', f'import {package_name}'], check=True, stdout=PIPE, stderr=PIPE)
|
||||
return True
|
||||
except CalledProcessError as cpe:
|
||||
print(cpe)
|
||||
return False
|
||||
|
||||
def install_dependencies(self) -> None:
|
||||
"""### Verifie les dépendances si elles sont installées
|
||||
- Test si les modules sont installés
|
||||
- Met a jour pip
|
||||
- Install les modules manquants
|
||||
"""
|
||||
do_install = False
|
||||
|
||||
# Check if virtual env exist
|
||||
if not os.path.exists(f'{os.path.join(self.config.defender_install_folder, self.config.venv_folder)}'):
|
||||
self.run_subprocess(self.config.venv_cmd_installation)
|
||||
do_install = True
|
||||
|
||||
for module in self.config.venv_cmd_requirements:
|
||||
module = module.replace('pyyaml', 'yaml')
|
||||
if not self.check_package(module):
|
||||
do_install = True
|
||||
|
||||
if not do_install:
|
||||
return None
|
||||
|
||||
print("===> Clean pip cache")
|
||||
self.run_subprocess([self.config.venv_pip_executable, 'cache', 'purge'])
|
||||
|
||||
print("===> Check if pip is up to date")
|
||||
self.run_subprocess([self.config.venv_python_executable, '-m', 'pip', 'install', '--upgrade', 'pip'])
|
||||
|
||||
if not self.check_package('greenlet'):
|
||||
self.run_subprocess([self.config.venv_pip_executable, 'install', '--only-binary', ':all:', 'greenlet'])
|
||||
print('====> Greenlet installed')
|
||||
|
||||
for module in self.config.venv_cmd_requirements:
|
||||
if not self.check_package(module):
|
||||
print("### Trying to install missing python packages ###")
|
||||
self.run_subprocess([self.config.venv_pip_executable, 'install', module])
|
||||
print(f"====> Module {module} installed!")
|
||||
else:
|
||||
print(f"==> {module} already installed")
|
||||
|
||||
def create_service_file(self) -> None:
|
||||
|
||||
full_service_file_path = os.path.join(self.config.unix_systemd_folder, self.config.service_file_name)
|
||||
|
||||
if os.path.exists(full_service_file_path):
|
||||
print(f'[!] Service file already exist [!]')
|
||||
self.run_subprocess(self.config.service_cmd_executable)
|
||||
return None
|
||||
|
||||
contain = f'''[Unit]
|
||||
Description=Defender IRC Service
|
||||
|
||||
[Service]
|
||||
ExecStart={self.config.venv_python_executable} {self.config.defender_main_executable}
|
||||
WorkingDirectory={self.config.defender_install_folder}
|
||||
SyslogIdentifier=Defender
|
||||
Restart=on-failure
|
||||
|
||||
[Install]
|
||||
WantedBy=default.target
|
||||
'''
|
||||
# Check if user systemd is available (.config/systemd/user/)
|
||||
if not os.path.exists(self.config.unix_systemd_folder):
|
||||
self.run_subprocess(['mkdir', '-p', self.config.unix_systemd_folder])
|
||||
|
||||
with open(full_service_file_path, 'w+') as servicefile:
|
||||
servicefile.write(contain)
|
||||
servicefile.close()
|
||||
print('Service file generated with current configuration')
|
||||
print('Running IRC Service ...')
|
||||
self.run_subprocess(self.config.service_cmd_daemon_reload)
|
||||
self.run_subprocess(self.config.service_cmd_executable)
|
||||
|
||||
else:
|
||||
with open(full_service_file_path, 'w+') as servicefile:
|
||||
servicefile.write(contain)
|
||||
servicefile.close()
|
||||
print('Service file generated with current configuration')
|
||||
print('Running IRC Service ...')
|
||||
self.run_subprocess(self.config.service_cmd_daemon_reload)
|
||||
self.run_subprocess(self.config.service_cmd_executable)
|
||||
|
||||
def print_final_message(self) -> None:
|
||||
|
||||
print(f"#"*24)
|
||||
print("Installation complete ...")
|
||||
print("If the configuration is correct, then you must see your service connected to your irc server")
|
||||
print(f"If any issue, you can see the log file for debug {self.config.defender_install_folder}{os.sep}logs{os.sep}defender.log")
|
||||
print(f"#"*24)
|
||||
exit(1)
|
||||
@@ -1,4 +1,4 @@
|
||||
from core import installation
|
||||
from core import install
|
||||
|
||||
#############################################
|
||||
# @Version : 6.3 #
|
||||
@@ -10,7 +10,7 @@ from core import installation
|
||||
#############################################
|
||||
|
||||
try:
|
||||
installation.Install()
|
||||
install.update_packages()
|
||||
from core.loader import Loader
|
||||
loader = Loader()
|
||||
loader.Irc.init_irc()
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
Faker==33.1.2
|
||||
psutil==6.1.1
|
||||
PyYAML==6.0.2
|
||||
requests==2.32.3
|
||||
SQLAlchemy==2.0.36
|
||||
Faker==37.12.0
|
||||
psutil==7.1.2
|
||||
PyYAML==6.0.3
|
||||
requests==2.32.5
|
||||
SQLAlchemy==2.0.44
|
||||
unrealircd_rpc_py==3.0.2
|
||||
10
version.json
10
version.json
@@ -1,10 +1,10 @@
|
||||
{
|
||||
"version": "6.3.2",
|
||||
|
||||
"requests": "2.32.3",
|
||||
"psutil": "6.0.0",
|
||||
"requests": "2.32.5",
|
||||
"psutil": "7.1.2",
|
||||
"unrealircd_rpc_py": "3.0.1",
|
||||
"sqlalchemy": "2.0.35",
|
||||
"faker": "30.1.0",
|
||||
"pyyaml": "6.0.2"
|
||||
"sqlalchemy": "2.0.44",
|
||||
"faker": "37.12.0",
|
||||
"pyyaml": "6.0.3"
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user