Improved Singbox Setup Error handling for edge cases
This commit is contained in:
parent
01bd5f8d3f
commit
951802fe5c
3 changed files with 29 additions and 22 deletions
|
|
@ -34,6 +34,7 @@ class ResultError(Enum):
|
||||||
@dataclass
|
@dataclass
|
||||||
class Result():
|
class Result():
|
||||||
valid: bool
|
valid: bool
|
||||||
|
goal_result: Optional[bool] = None
|
||||||
error_type: ResultError = ResultError.SUCCESS
|
error_type: ResultError = ResultError.SUCCESS
|
||||||
data: Optional[Any] = None
|
data: Optional[Any] = None
|
||||||
message: Optional[str] = None
|
message: Optional[str] = None
|
||||||
|
|
|
||||||
|
|
@ -6,8 +6,6 @@ from core.Constants import Constants
|
||||||
from core.errors.logger import logger
|
from core.errors.logger import logger
|
||||||
from core.utils.run_commands import run_generic_command
|
from core.utils.run_commands import run_generic_command
|
||||||
from core.observers.ApplicationVersionObserver import ApplicationVersionObserver
|
from core.observers.ApplicationVersionObserver import ApplicationVersionObserver
|
||||||
from core.Errors import FileIntegrityError
|
|
||||||
from core.services.networking.api_requests.subtools.extract_domain import extract_domain
|
|
||||||
from core.models.orm_models.Dependency import Dependency
|
from core.models.orm_models.Dependency import Dependency
|
||||||
from core.models.orm_calls.dependency_calls import get_dependency_version
|
from core.models.orm_calls.dependency_calls import get_dependency_version
|
||||||
from core.controllers.ConfigurationController import ConfigurationController
|
from core.controllers.ConfigurationController import ConfigurationController
|
||||||
|
|
@ -17,13 +15,12 @@ import httpx
|
||||||
from io import BytesIO
|
from io import BytesIO
|
||||||
from typing import Optional
|
from typing import Optional
|
||||||
import hashlib
|
import hashlib
|
||||||
import shutil
|
|
||||||
import tarfile
|
import tarfile
|
||||||
import os
|
import os
|
||||||
|
|
||||||
SUDO_SINGBOX_LOCATION = f"{Constants.SUDO_TARGET_FOLDER}/sing-box"
|
SUDO_SINGBOX_LOCATION = f"{Constants.SUDO_TARGET_FOLDER}/sing-box"
|
||||||
|
|
||||||
def singbox_setup(application_version_observer: Optional[ApplicationVersionObserver]) -> Result:
|
def setup_singbox_binary(application_version_observer: Optional[ApplicationVersionObserver]) -> Result:
|
||||||
"""
|
"""
|
||||||
Rank:
|
Rank:
|
||||||
Module's Main Orchestrator
|
Module's Main Orchestrator
|
||||||
|
|
@ -58,13 +55,18 @@ def singbox_setup(application_version_observer: Optional[ApplicationVersionObser
|
||||||
logger.info("Sync is required. We could not access the information on the most current version locally.")
|
logger.info("Sync is required. We could not access the information on the most current version locally.")
|
||||||
return update_result # (user MUST sync)
|
return update_result # (user MUST sync)
|
||||||
|
|
||||||
# this is blank if the checks worked, but nothing is required,
|
if already_in_sudo_folder and update_result.goal_result:
|
||||||
|
# no update required:
|
||||||
|
no_update = "No update for singbox is required."
|
||||||
|
logger.info(no_update)
|
||||||
|
return Result(valid=True, message=no_update)
|
||||||
|
|
||||||
required_update = update_result.data
|
required_update = update_result.data
|
||||||
|
|
||||||
# no update required:
|
if required_update is None or not isinstance(required_update, Dependency):
|
||||||
if required_update is None and already_in_sudo_folder:
|
error_msg = "You need to Sync, because you lack the dependency data for singbox."
|
||||||
logger.info("No update for singbox is required.")
|
logger.error(error_msg)
|
||||||
return update_result
|
return Result(valid=False, error_type=ResultError.NEED_SYNC, message=error_msg)
|
||||||
|
|
||||||
# UPDATE FROM HERE ON
|
# UPDATE FROM HERE ON
|
||||||
logger.info("Updating Singbox..")
|
logger.info("Updating Singbox..")
|
||||||
|
|
@ -168,13 +170,9 @@ def update_needed() -> Result:
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
Always a Result Object.
|
Always a Result Object.
|
||||||
|
No update needed = goal_result=True
|
||||||
** IMPORTANT**
|
Update needed = goal_result=False
|
||||||
If an update is NOT needed, but it can complete the check, it returns valid=True, but None for Data.
|
Can't complete the checks, valid=False
|
||||||
|
|
||||||
If an update IS needed, it returns data with the new version.
|
|
||||||
|
|
||||||
If it can't complete the checks, it returns False for valid.
|
|
||||||
"""
|
"""
|
||||||
app_name = "singbox"
|
app_name = "singbox"
|
||||||
rejected_values = [None, False, ""]
|
rejected_values = [None, False, ""]
|
||||||
|
|
@ -200,7 +198,7 @@ def update_needed() -> Result:
|
||||||
logger.info(f"While the version of {app_name} we installed in our configuration is {version_installed}")
|
logger.info(f"While the version of {app_name} we installed in our configuration is {version_installed}")
|
||||||
if version_installed in rejected_values:
|
if version_installed in rejected_values:
|
||||||
logger.info(f"We need to update to the new {new_version}")
|
logger.info(f"We need to update to the new {new_version}")
|
||||||
return Result(valid=True, data=version_sql_query)
|
return Result(valid=True, goal_result=False, data=version_sql_query)
|
||||||
|
|
||||||
################################################
|
################################################
|
||||||
# EVALUATE
|
# EVALUATE
|
||||||
|
|
@ -218,6 +216,8 @@ def update_needed() -> Result:
|
||||||
logger.error(f"The version_installed is in the wrong format: {str(e)}. But we can still update to the new version..")
|
logger.error(f"The version_installed is in the wrong format: {str(e)}. But we can still update to the new version..")
|
||||||
# wipe config:
|
# wipe config:
|
||||||
changed_config = ConfigurationController.update_singbox_version(None) # can make this dynamic if more apps are added.
|
changed_config = ConfigurationController.update_singbox_version(None) # can make this dynamic if more apps are added.
|
||||||
|
if not changed_config:
|
||||||
|
logger.error("Critical Issue with wiping the config version")
|
||||||
need_update = True # the version_sql_query data is still valid.
|
need_update = True # the version_sql_query data is still valid.
|
||||||
else:
|
else:
|
||||||
error_msg = f"Corrupt data, corrupt filesystem, or outright developer bug. Please contact customer support with new_version: {new_version} and version_installed {version_installed} tried to see if it should update but {str(e)}"
|
error_msg = f"Corrupt data, corrupt filesystem, or outright developer bug. Please contact customer support with new_version: {new_version} and version_installed {version_installed} tried to see if it should update but {str(e)}"
|
||||||
|
|
@ -225,9 +225,9 @@ def update_needed() -> Result:
|
||||||
return Result(valid=False, error_type=ResultError.INVALID_INPUT, message=error_msg)
|
return Result(valid=False, error_type=ResultError.INVALID_INPUT, message=error_msg)
|
||||||
|
|
||||||
if need_update:
|
if need_update:
|
||||||
return Result(valid=True, data=version_sql_query, message="update")
|
return Result(valid=True, goal_result=True, data=version_sql_query, message="update")
|
||||||
else:
|
else:
|
||||||
return Result(valid=True, data=None, message="Not needed.") # BLANK DATA, BUT TRUE
|
return Result(valid=True, goal_result=False, data=version_sql_query, message="Not needed.")
|
||||||
|
|
||||||
|
|
||||||
def already_downloaded(which_version: str) -> bool:
|
def already_downloaded(which_version: str) -> bool:
|
||||||
|
|
@ -292,9 +292,10 @@ def download_and_verify(
|
||||||
else:
|
else:
|
||||||
error_msg = f"Could not download {target_app_name} because of a Connection Error."
|
error_msg = f"Could not download {target_app_name} because of a Connection Error."
|
||||||
logger.error(error_msg)
|
logger.error(error_msg)
|
||||||
return Return(valid=False, error_type=ResultError.CONNECTION, message=error_msg)
|
return Result(valid=False, error_type=ResultError.CONNECTION, message=error_msg)
|
||||||
|
|
||||||
application_version_observer.notify('downloaded', f"Downloaded {target_app_name}")
|
if application_version_observer is not None:
|
||||||
|
application_version_observer.notify('downloaded', f"Downloaded {target_app_name}")
|
||||||
response_buffer.seek(0)
|
response_buffer.seek(0)
|
||||||
|
|
||||||
################################################
|
################################################
|
||||||
|
|
@ -305,7 +306,7 @@ def download_and_verify(
|
||||||
if real_file_hash != target_file_hash:
|
if real_file_hash != target_file_hash:
|
||||||
error_msg = f'Application version file integrity could not be verified. We are targeting {target_file_hash}, but got {real_file_hash}'
|
error_msg = f'Application version file integrity could not be verified. We are targeting {target_file_hash}, but got {real_file_hash}'
|
||||||
logger.error(error_msg)
|
logger.error(error_msg)
|
||||||
return Return(valid=False, error_type=ResultError.INVALID_INPUT, message=error_msg)
|
return Result(valid=False, error_type=ResultError.INVALID_INPUT, message=error_msg)
|
||||||
|
|
||||||
################################################
|
################################################
|
||||||
# SAVE IT IN CORRECT STRUCTURE
|
# SAVE IT IN CORRECT STRUCTURE
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,6 @@
|
||||||
from core.services.helpers.manage_assets import sudo_assets_folder_setup
|
from core.services.helpers.manage_assets import sudo_assets_folder_setup
|
||||||
from core.utils.basic_operations.confirm_files_exist import confirm_files_and_folders_exist
|
from core.utils.basic_operations.confirm_files_exist import confirm_files_and_folders_exist
|
||||||
|
from core.utils.basic_operations.does_file_exist import does_file_exist
|
||||||
from core.models.Result import Result, ResultError
|
from core.models.Result import Result, ResultError
|
||||||
from core.Constants import Constants
|
from core.Constants import Constants
|
||||||
from core.errors.logger import logger
|
from core.errors.logger import logger
|
||||||
|
|
@ -68,3 +69,7 @@ def test_if_in_sudo_folder() -> Result:
|
||||||
logger.error(error_msg)
|
logger.error(error_msg)
|
||||||
return Result(valid=False, message=error_msg)
|
return Result(valid=False, message=error_msg)
|
||||||
|
|
||||||
|
|
||||||
|
def is_singbox_wrapper_ready() -> bool:
|
||||||
|
wrapper_location = f"{Constants.SUDO_TARGET_FOLDER}/singbox_wrapper"
|
||||||
|
return does_file_exist(wrapper_location)
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue