mirror of
https://git.selfprivacy.org/SelfPrivacy/selfprivacy-rest-api.git
synced 2024-11-10 13:03:11 +00:00
feature(services): allow moving uninitialized services
This commit is contained in:
parent
6afaefbb41
commit
f57eda5237
|
@ -2,6 +2,7 @@
|
|||
|
||||
from abc import ABC, abstractmethod
|
||||
from typing import List, Optional
|
||||
from os.path import exists
|
||||
|
||||
from selfprivacy_api import utils
|
||||
from selfprivacy_api.services.config_item import ServiceConfigItem
|
||||
|
@ -237,6 +238,16 @@ class Service(ABC):
|
|||
storage_used += get_storage_usage(folder)
|
||||
return storage_used
|
||||
|
||||
@classmethod
|
||||
def has_folders(cls) -> int:
|
||||
"""
|
||||
If there are no folders on disk, moving is noop
|
||||
"""
|
||||
for folder in cls.get_folders():
|
||||
if exists(folder):
|
||||
return True
|
||||
return False
|
||||
|
||||
@classmethod
|
||||
def get_dns_records(cls, ip4: str, ip6: Optional[str]) -> List[ServiceDnsRecord]:
|
||||
subdomain = cls.get_subdomain()
|
||||
|
@ -358,6 +369,9 @@ class Service(ABC):
|
|||
binds = self.binds()
|
||||
if binds == []:
|
||||
raise MoveError("nothing to move")
|
||||
|
||||
# It is ok if service is uninitialized, we will just reregister it
|
||||
if self.has_folders():
|
||||
check_binds(current_volume_name, binds)
|
||||
|
||||
def do_move_to_volume(
|
||||
|
@ -401,7 +415,18 @@ class Service(ABC):
|
|||
service_name = self.get_display_name()
|
||||
|
||||
report_progress(0, job, "Performing pre-move checks...")
|
||||
|
||||
self.assert_can_move(volume)
|
||||
if not self.has_folders():
|
||||
self.set_location(volume)
|
||||
Jobs.update(
|
||||
job=job,
|
||||
status=JobStatus.FINISHED,
|
||||
result=f"{service_name} moved successfully(no folders).",
|
||||
status_text=f"NOT starting {service_name}",
|
||||
progress=100,
|
||||
)
|
||||
return job
|
||||
|
||||
report_progress(5, job, f"Stopping {service_name}...")
|
||||
assert self is not None
|
||||
|
|
|
@ -5,6 +5,7 @@ import subprocess
|
|||
|
||||
from typing import List
|
||||
from os import path
|
||||
from pathlib import Path
|
||||
|
||||
# from enum import Enum
|
||||
|
||||
|
@ -73,8 +74,11 @@ class DummyService(Service):
|
|||
@classmethod
|
||||
def status_file(cls) -> str:
|
||||
dir = cls.folders[0]
|
||||
# we do not REALLY want to store our state in our declared folders
|
||||
return path.join(dir, "..", "service_status")
|
||||
# We do not want to store our state in our declared folders
|
||||
# Because they are moved and tossed in tests wildly
|
||||
parent = Path(dir).parent
|
||||
|
||||
return path.join(parent, "service_status")
|
||||
|
||||
@classmethod
|
||||
def set_status(cls, status: ServiceStatus):
|
||||
|
|
|
@ -2,7 +2,7 @@ import pytest
|
|||
import shutil
|
||||
|
||||
from typing import Generator
|
||||
from os import mkdir
|
||||
from os import mkdir, rmdir
|
||||
|
||||
from selfprivacy_api.utils.block_devices import BlockDevices
|
||||
|
||||
|
@ -605,6 +605,11 @@ def test_graphql_move_service_without_folders_on_old_volume(
|
|||
mock_lsblk_devices,
|
||||
dummy_service: DummyService,
|
||||
):
|
||||
"""
|
||||
Situation when you have folders in the filetree but they are not mounted
|
||||
but just folders
|
||||
"""
|
||||
|
||||
target = "sda1"
|
||||
BlockDevices().update()
|
||||
assert BlockDevices().get_block_device(target) is not None
|
||||
|
@ -618,6 +623,59 @@ def test_graphql_move_service_without_folders_on_old_volume(
|
|||
assert "sda2/test_service is not found" in data["message"]
|
||||
|
||||
|
||||
def test_move_empty(
|
||||
authorized_client, generic_userdata, mock_check_volume, dummy_service, fp
|
||||
):
|
||||
"""
|
||||
A reregister of uninitialized service with no data.
|
||||
No binds in place yet, and no rebuilds should happen.
|
||||
"""
|
||||
|
||||
origin = "sda1"
|
||||
target = "sda2"
|
||||
assert BlockDevices().get_block_device(target) is not None
|
||||
assert BlockDevices().get_block_device(origin) is not None
|
||||
|
||||
dummy_service.set_drive(origin)
|
||||
dummy_service.set_simulated_moves(False)
|
||||
dummy_service.disable()
|
||||
|
||||
unit_name = "sp-nixos-rebuild.service"
|
||||
rebuild_command = ["systemctl", "start", unit_name]
|
||||
prepare_nixos_rebuild_calls(fp, unit_name)
|
||||
|
||||
# We will NOT be mounting and remounting folders
|
||||
mount_command = ["mount", fp.any()]
|
||||
unmount_command = ["umount", fp.any()]
|
||||
fp.pass_command(mount_command, 2)
|
||||
fp.pass_command(unmount_command, 2)
|
||||
|
||||
# We will NOT be changing ownership
|
||||
chown_command = ["chown", fp.any()]
|
||||
fp.pass_command(chown_command, 2)
|
||||
|
||||
# We have virtual binds encapsulating our understanding where this should go.
|
||||
assert len(dummy_service.binds()) == 2
|
||||
|
||||
# Remove all folders
|
||||
for folder in dummy_service.get_folders():
|
||||
shutil.rmtree(folder)
|
||||
|
||||
# They are virtual and unaffected by folder removal
|
||||
assert len(dummy_service.binds()) == 2
|
||||
|
||||
mutation_response = api_move(authorized_client, dummy_service, target)
|
||||
|
||||
data = get_data(mutation_response)["services"]["moveService"]
|
||||
assert_ok(data)
|
||||
assert data["service"] is not None
|
||||
|
||||
assert fp.call_count(rebuild_command) == 0
|
||||
assert fp.call_count(mount_command) == 0
|
||||
assert fp.call_count(unmount_command) == 0
|
||||
assert fp.call_count(chown_command) == 0
|
||||
|
||||
|
||||
def test_graphql_move_service(
|
||||
authorized_client, generic_userdata, mock_check_volume, dummy_service_with_binds, fp
|
||||
):
|
||||
|
|
Loading…
Reference in a new issue