From bf1cd328956de095a090f6d22e600ee8d1a79e0c Mon Sep 17 00:00:00 2001 From: inexcode Date: Sat, 20 Aug 2022 22:50:25 +0400 Subject: [PATCH] Change the ServiceStatus to match systemctl show --- .../graphql/common_types/service.py | 10 +++--- selfprivacy_api/rest/services.py | 36 ++++++++++--------- .../services/generic_service_mover.py | 7 ++-- .../services/generic_status_getter.py | 35 +++++++++--------- selfprivacy_api/services/service.py | 10 +++--- 5 files changed, 53 insertions(+), 45 deletions(-) diff --git a/selfprivacy_api/graphql/common_types/service.py b/selfprivacy_api/graphql/common_types/service.py index 99310f7..c1246ca 100644 --- a/selfprivacy_api/graphql/common_types/service.py +++ b/selfprivacy_api/graphql/common_types/service.py @@ -56,10 +56,12 @@ class ServiceStorageUsage(StorageUsageInterface): @strawberry.enum class ServiceStatusEnum(Enum): - RUNNING = "RUNNING" - DEGRADED = "DEGRADED" - ERROR = "ERROR" - STOPPED = "STOPPED" + ACTIVE = "ACTIVE" + RELOADING = "RELOADING" + INACTIVE = "INACTIVE" + FAILED = "FAILED" + ACTIVATING = "ACTIVATING" + DEACTIVATING = "DEACTIVATING" OFF = "OFF" diff --git a/selfprivacy_api/rest/services.py b/selfprivacy_api/rest/services.py index d374e7b..c9d5ff9 100644 --- a/selfprivacy_api/rest/services.py +++ b/selfprivacy_api/rest/services.py @@ -36,11 +36,13 @@ router = APIRouter( def service_status_to_return_code(status: ServiceStatus): - if status == ServiceStatus.RUNNING: + """Converts service status object to return code for + compatibility with legacy api""" + if status == ServiceStatus.ACTIVE: return 0 - elif status == ServiceStatus.ERROR: + elif status == ServiceStatus.FAILED: return 1 - elif status == ServiceStatus.STOPPED: + elif status == ServiceStatus.INACTIVE: return 3 elif status == ServiceStatus.OFF: return 4 @@ -317,13 +319,13 @@ async def rest_send_ssh_key(input: SshKeyInput): """Send the SSH key""" try: create_ssh_key("root", input.public_key) - except KeyAlreadyExists: - raise HTTPException(status_code=409, detail="Key already exists") - except InvalidPublicKey: + except KeyAlreadyExists as error: + raise HTTPException(status_code=409, detail="Key already exists") from error + except InvalidPublicKey as error: raise HTTPException( status_code=400, detail="Invalid key type. Only ssh-ed25519 and ssh-rsa are supported", - ) + ) from error return { "status": 0, @@ -345,15 +347,15 @@ async def rest_get_ssh_keys(username: str): async def rest_add_ssh_key(username: str, input: SshKeyInput): try: create_ssh_key(username, input.public_key) - except KeyAlreadyExists: - raise HTTPException(status_code=409, detail="Key already exists") - except InvalidPublicKey: + except KeyAlreadyExists as error: + raise HTTPException(status_code=409, detail="Key already exists") from error + except InvalidPublicKey as error: raise HTTPException( status_code=400, detail="Invalid key type. Only ssh-ed25519 and ssh-rsa are supported", - ) - except UserNotFound: - raise HTTPException(status_code=404, detail="User not found") + ) from error + except UserNotFound as error: + raise HTTPException(status_code=404, detail="User not found") from error return { "message": "New SSH key successfully written", @@ -364,8 +366,8 @@ async def rest_add_ssh_key(username: str, input: SshKeyInput): async def rest_delete_ssh_key(username: str, input: SshKeyInput): try: remove_ssh_key(username, input.public_key) - except KeyNotFound: - raise HTTPException(status_code=404, detail="Key not found") - except UserNotFound: - raise HTTPException(status_code=404, detail="User not found") + except KeyNotFound as error: + raise HTTPException(status_code=404, detail="Key not found") from error + except UserNotFound as error: + raise HTTPException(status_code=404, detail="User not found") from error return {"message": "SSH key deleted"} diff --git a/selfprivacy_api/services/generic_service_mover.py b/selfprivacy_api/services/generic_service_mover.py index a214830..c7d7c3b 100644 --- a/selfprivacy_api/services/generic_service_mover.py +++ b/selfprivacy_api/services/generic_service_mover.py @@ -103,10 +103,13 @@ def move_service( progress=5, ) service.stop() - # Wait for Nextcloud to stop, check every second + # Wait for the service to stop, check every second # If it does not stop in 30 seconds, abort for _ in range(30): - if service.get_status() != ServiceStatus.RUNNING: + if service.get_status() not in ( + ServiceStatus.ACTIVATING, + ServiceStatus.DEACTIVATING, + ): break time.sleep(1) else: diff --git a/selfprivacy_api/services/generic_status_getter.py b/selfprivacy_api/services/generic_status_getter.py index d53011e..c17f4d6 100644 --- a/selfprivacy_api/services/generic_status_getter.py +++ b/selfprivacy_api/services/generic_status_getter.py @@ -1,6 +1,5 @@ """Generic service status fetcher using systemctl""" import subprocess -import typing from selfprivacy_api.services.service import ServiceStatus @@ -8,22 +7,22 @@ from selfprivacy_api.services.service import ServiceStatus def get_service_status(service: str) -> ServiceStatus: """ Return service status from systemd. - Use command return code to determine status. - - Return code 0 means service is running. - Return code 1 or 2 means service is in error stat. - Return code 3 means service is stopped. - Return code 4 means service is off. + Use systemctl show to get the status of a service. + Get ActiveState from the output. """ - service_status = subprocess.Popen(["systemctl", "status", service]) - service_status.communicate()[0] - if service_status.returncode == 0: - return ServiceStatus.RUNNING - elif service_status.returncode == 1 or service_status.returncode == 2: - return ServiceStatus.ERROR - elif service_status.returncode == 3: - return ServiceStatus.STOPPED - elif service_status.returncode == 4: + service_status = subprocess.check_output(["systemctl", "show", service]) + if b"LoadState=not-found" in service_status: return ServiceStatus.OFF - else: - return ServiceStatus.DEGRADED + if b"ActiveState=active" in service_status: + return ServiceStatus.ACTIVE + if b"ActiveState=inactive" in service_status: + return ServiceStatus.INACTIVE + if b"ActiveState=activating" in service_status: + return ServiceStatus.ACTIVATING + if b"ActiveState=deactivating" in service_status: + return ServiceStatus.DEACTIVATING + if b"ActiveState=failed" in service_status: + return ServiceStatus.FAILED + if b"ActiveState=reloading" in service_status: + return ServiceStatus.RELOADING + return ServiceStatus.OFF diff --git a/selfprivacy_api/services/service.py b/selfprivacy_api/services/service.py index 0defcff..515e28f 100644 --- a/selfprivacy_api/services/service.py +++ b/selfprivacy_api/services/service.py @@ -12,10 +12,12 @@ from selfprivacy_api.utils.block_devices import BlockDevice class ServiceStatus(Enum): """Enum for service status""" - RUNNING = "RUNNING" - DEGRADED = "DEGRADED" - ERROR = "ERROR" - STOPPED = "STOPPED" + ACTIVE = "ACTIVE" + RELOADING = "RELOADING" + INACTIVE = "INACTIVE" + FAILED = "FAILED" + ACTIVATING = "ACTIVATING" + DEACTIVATING = "DEACTIVATING" OFF = "OFF"