mirror of
https://git.selfprivacy.org/SelfPrivacy/selfprivacy-rest-api.git
synced 2024-11-17 08:02:36 +00:00
chore: Migrate to NixOS 24.05
This commit is contained in:
parent
9b93107b36
commit
659cfca8a3
|
@ -20,6 +20,7 @@ pythonPackages.buildPythonPackage rec {
|
|||
typing-extensions
|
||||
uvicorn
|
||||
websockets
|
||||
httpx
|
||||
];
|
||||
pythonImportsCheck = [ "selfprivacy_api" ];
|
||||
doCheck = false;
|
||||
|
|
|
@ -2,11 +2,11 @@
|
|||
"nodes": {
|
||||
"nixpkgs": {
|
||||
"locked": {
|
||||
"lastModified": 1719957072,
|
||||
"narHash": "sha256-gvFhEf5nszouwLAkT9nWsDzocUTqLWHuL++dvNjMp9I=",
|
||||
"lastModified": 1721949857,
|
||||
"narHash": "sha256-DID446r8KsmJhbCzx4el8d9SnPiE8qa6+eEQOJ40vR0=",
|
||||
"owner": "nixos",
|
||||
"repo": "nixpkgs",
|
||||
"rev": "7144d6241f02d171d25fba3edeaf15e0f2592105",
|
||||
"rev": "a1cc729dcbc31d9b0d11d86dc7436163548a9665",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
system = "x86_64-linux";
|
||||
pkgs = nixpkgs.legacyPackages.${system};
|
||||
selfprivacy-graphql-api = pkgs.callPackage ./default.nix {
|
||||
pythonPackages = pkgs.python310Packages;
|
||||
pythonPackages = pkgs.python312Packages;
|
||||
rev = self.shortRev or self.dirtyShortRev or "dirty";
|
||||
};
|
||||
python = self.packages.${system}.default.pythonModule;
|
||||
|
@ -85,7 +85,7 @@
|
|||
packages = with pkgs; [
|
||||
nixpkgs-fmt
|
||||
rclone
|
||||
redis
|
||||
valkey
|
||||
restic
|
||||
self.packages.${system}.pytest-vm
|
||||
# FIXME consider loading this explicitly only after ArchLinux issue is solved
|
||||
|
@ -134,6 +134,7 @@
|
|||
boot.consoleLogLevel = lib.mkForce 3;
|
||||
documentation.enable = false;
|
||||
services.journald.extraConfig = lib.mkForce "";
|
||||
services.redis.package = pkgs.valkey;
|
||||
services.redis.servers.sp-api = {
|
||||
enable = true;
|
||||
save = [ ];
|
||||
|
|
|
@ -61,7 +61,7 @@ in
|
|||
HOME = "/root";
|
||||
PYTHONUNBUFFERED = "1";
|
||||
PYTHONPATH =
|
||||
pkgs.python310Packages.makePythonPath [ selfprivacy-graphql-api ];
|
||||
pkgs.python312Packages.makePythonPath [ selfprivacy-graphql-api ];
|
||||
} // config.networking.proxy.envVars;
|
||||
path = [
|
||||
"/var/"
|
||||
|
@ -82,7 +82,7 @@ in
|
|||
wantedBy = [ "network-online.target" ];
|
||||
serviceConfig = {
|
||||
User = "root";
|
||||
ExecStart = "${pkgs.python310Packages.huey}/bin/huey_consumer.py selfprivacy_api.task_registry.huey";
|
||||
ExecStart = "${pkgs.python312Packages.huey}/bin/huey_consumer.py selfprivacy_api.task_registry.huey";
|
||||
Restart = "always";
|
||||
RestartSec = "5";
|
||||
};
|
||||
|
|
|
@ -78,7 +78,7 @@ def do_autobackup() -> None:
|
|||
For some reason, we cannot launch periodic huey tasks
|
||||
inside tests
|
||||
"""
|
||||
time = datetime.utcnow().replace(tzinfo=timezone.utc)
|
||||
time = datetime.now(timezone.utc)
|
||||
services_to_back_up = Backups.services_to_back_up(time)
|
||||
if not services_to_back_up:
|
||||
return
|
||||
|
|
|
@ -50,6 +50,7 @@ def tombstone_service(service_id: str) -> Service:
|
|||
url=None,
|
||||
can_be_backed_up=False,
|
||||
backup_description="",
|
||||
is_installed=False,
|
||||
)
|
||||
|
||||
|
||||
|
|
|
@ -158,8 +158,8 @@ class System:
|
|||
)
|
||||
)
|
||||
domain_info: SystemDomainInfo = strawberry.field(resolver=get_system_domain_info)
|
||||
settings: SystemSettings = SystemSettings()
|
||||
info: SystemInfo = SystemInfo()
|
||||
settings: SystemSettings = strawberry.field(default_factory=SystemSettings)
|
||||
info: SystemInfo = strawberry.field(default_factory=SystemInfo)
|
||||
provider: SystemProviderInfo = strawberry.field(resolver=get_system_provider_info)
|
||||
|
||||
@strawberry.field
|
||||
|
|
|
@ -1,15 +1,15 @@
|
|||
"""
|
||||
Redis pool module for selfprivacy_api
|
||||
"""
|
||||
|
||||
import redis
|
||||
import redis.asyncio as redis_async
|
||||
from redis.asyncio.client import PubSub
|
||||
|
||||
from selfprivacy_api.utils.singleton_metaclass import SingletonMetaclass
|
||||
|
||||
REDIS_SOCKET = "/run/redis-sp-api/redis.sock"
|
||||
|
||||
|
||||
# class RedisPool(metaclass=SingletonMetaclass):
|
||||
class RedisPool:
|
||||
"""
|
||||
Redis connection pool singleton.
|
||||
|
@ -51,7 +51,7 @@ class RedisPool:
|
|||
"""
|
||||
return redis_async.Redis(connection_pool=self._async_pool)
|
||||
|
||||
async def subscribe_to_keys(self, pattern: str) -> redis_async.client.PubSub:
|
||||
async def subscribe_to_keys(self, pattern: str) -> PubSub:
|
||||
async_redis = self.get_connection_async()
|
||||
pubsub = async_redis.pubsub()
|
||||
await pubsub.psubscribe(f"__keyspace@{self._dbnumber}__:" + pattern)
|
||||
|
|
|
@ -12,7 +12,10 @@ def service_options():
|
|||
return {}
|
||||
|
||||
|
||||
def test_string_service_config_item(service_options):
|
||||
DUMMY_SERVICE = "testservice"
|
||||
|
||||
|
||||
def test_string_service_config_item(dummy_service):
|
||||
item = StringServiceConfigItem(
|
||||
id="test_string",
|
||||
default_value="1337",
|
||||
|
@ -21,11 +24,11 @@ def test_string_service_config_item(service_options):
|
|||
widget="text",
|
||||
allow_empty=False,
|
||||
)
|
||||
assert item.get_value(service_options) == "1337"
|
||||
item.set_value("123", service_options)
|
||||
assert item.get_value(service_options) == "123"
|
||||
assert item.get_value(DUMMY_SERVICE) == "1337"
|
||||
item.set_value("123", DUMMY_SERVICE)
|
||||
assert item.get_value(DUMMY_SERVICE) == "123"
|
||||
with pytest.raises(ValueError):
|
||||
item.set_value("abc", service_options)
|
||||
item.set_value("abc", DUMMY_SERVICE)
|
||||
assert item.validate_value("123") is True
|
||||
assert item.validate_value("abc") is False
|
||||
assert item.validate_value("123abc") is False
|
||||
|
@ -36,7 +39,7 @@ def test_string_service_config_item(service_options):
|
|||
assert item.validate_value(True) is False
|
||||
|
||||
|
||||
def test_string_service_config_item_allows_empty(service_options):
|
||||
def test_string_service_config_item_allows_empty(dummy_service):
|
||||
item = StringServiceConfigItem(
|
||||
id="test_string",
|
||||
default_value="1337",
|
||||
|
@ -44,9 +47,9 @@ def test_string_service_config_item_allows_empty(service_options):
|
|||
widget="text",
|
||||
allow_empty=True,
|
||||
)
|
||||
assert item.get_value(service_options) == "1337"
|
||||
item.set_value("", service_options)
|
||||
assert item.get_value(service_options) == ""
|
||||
assert item.get_value(DUMMY_SERVICE) == "1337"
|
||||
item.set_value("", DUMMY_SERVICE)
|
||||
assert item.get_value(DUMMY_SERVICE) == ""
|
||||
assert item.validate_value("") is True
|
||||
assert item.validate_value(None) is False
|
||||
assert item.validate_value(123) is False
|
||||
|
@ -57,17 +60,17 @@ def test_string_service_config_item_allows_empty(service_options):
|
|||
assert item.validate_value(True) is False
|
||||
|
||||
|
||||
def test_string_service_config_item_not_allows_empty(service_options):
|
||||
def test_string_service_config_item_not_allows_empty(dummy_service):
|
||||
item = StringServiceConfigItem(
|
||||
id="test_string",
|
||||
default_value="1337",
|
||||
description="Test digits string",
|
||||
widget="text",
|
||||
)
|
||||
assert item.get_value(service_options) == "1337"
|
||||
assert item.get_value(DUMMY_SERVICE) == "1337"
|
||||
with pytest.raises(ValueError):
|
||||
item.set_value("", service_options)
|
||||
assert item.get_value(service_options) == "1337"
|
||||
item.set_value("", DUMMY_SERVICE)
|
||||
assert item.get_value(DUMMY_SERVICE) == "1337"
|
||||
assert item.validate_value("") is False
|
||||
assert item.validate_value(None) is False
|
||||
assert item.validate_value(123) is False
|
||||
|
@ -78,16 +81,16 @@ def test_string_service_config_item_not_allows_empty(service_options):
|
|||
assert item.validate_value(True) is False
|
||||
|
||||
|
||||
def test_bool_service_config_item(service_options):
|
||||
def test_bool_service_config_item(dummy_service):
|
||||
item = BoolServiceConfigItem(
|
||||
id="test_bool",
|
||||
default_value=True,
|
||||
description="Test bool",
|
||||
widget="switch",
|
||||
)
|
||||
assert item.get_value(service_options) is True
|
||||
item.set_value(False, service_options)
|
||||
assert item.get_value(service_options) is False
|
||||
assert item.get_value(DUMMY_SERVICE) is True
|
||||
item.set_value(False, DUMMY_SERVICE)
|
||||
assert item.get_value(DUMMY_SERVICE) is False
|
||||
assert item.validate_value(True) is True
|
||||
assert item.validate_value(False) is True
|
||||
assert item.validate_value("True") is False
|
||||
|
@ -97,7 +100,7 @@ def test_bool_service_config_item(service_options):
|
|||
assert item.validate_value("1") is False
|
||||
|
||||
|
||||
def test_enum_service_config_item(service_options):
|
||||
def test_enum_service_config_item(dummy_service):
|
||||
item = EnumServiceConfigItem(
|
||||
id="test_enum",
|
||||
default_value="option1",
|
||||
|
@ -105,11 +108,11 @@ def test_enum_service_config_item(service_options):
|
|||
options=["option1", "option2", "option3"],
|
||||
widget="select",
|
||||
)
|
||||
assert item.get_value(service_options) == "option1"
|
||||
item.set_value("option2", service_options)
|
||||
assert item.get_value(service_options) == "option2"
|
||||
assert item.get_value(DUMMY_SERVICE) == "option1"
|
||||
item.set_value("option2", DUMMY_SERVICE)
|
||||
assert item.get_value(DUMMY_SERVICE) == "option2"
|
||||
with pytest.raises(ValueError):
|
||||
item.set_value("option4", service_options)
|
||||
item.set_value("option4", DUMMY_SERVICE)
|
||||
assert item.validate_value("option1") is True
|
||||
assert item.validate_value("option4") is False
|
||||
assert item.validate_value("option2") is True
|
||||
|
@ -118,7 +121,7 @@ def test_enum_service_config_item(service_options):
|
|||
assert item.validate_value(True) is False
|
||||
|
||||
|
||||
def test_string_service_config_item_subdomain(service_options, dummy_service):
|
||||
def test_string_service_config_item_subdomain(dummy_service):
|
||||
item = StringServiceConfigItem(
|
||||
id="test_subdomain",
|
||||
default_value="example",
|
||||
|
@ -127,13 +130,13 @@ def test_string_service_config_item_subdomain(service_options, dummy_service):
|
|||
allow_empty=False,
|
||||
regex=SUBDOMAIN_REGEX,
|
||||
)
|
||||
assert item.get_value(service_options) == "example"
|
||||
item.set_value("subdomain", service_options)
|
||||
assert item.get_value(service_options) == "subdomain"
|
||||
assert item.get_value(DUMMY_SERVICE) == "example"
|
||||
item.set_value("subdomain", DUMMY_SERVICE)
|
||||
assert item.get_value(DUMMY_SERVICE) == "subdomain"
|
||||
with pytest.raises(ValueError):
|
||||
item.set_value(
|
||||
"invalid-subdomain-because-it-is-very-very-very-very-very-very-long",
|
||||
service_options,
|
||||
DUMMY_SERVICE,
|
||||
)
|
||||
assert item.validate_value("subdomain") is True
|
||||
assert (
|
||||
|
|
|
@ -218,7 +218,7 @@ def api_set_quotas(authorized_client, quotas: _AutobackupQuotas):
|
|||
"/graphql",
|
||||
json={
|
||||
"query": API_SET_AUTOBACKUP_QUOTAS_MUTATION,
|
||||
"variables": {"input": quotas.dict()},
|
||||
"variables": {"input": quotas.model_dump()},
|
||||
},
|
||||
)
|
||||
return response
|
||||
|
@ -401,7 +401,7 @@ def test_autobackup_quotas_nonzero(authorized_client, backups):
|
|||
assert_ok(data)
|
||||
|
||||
configuration = data["configuration"]
|
||||
assert configuration["autobackupQuotas"] == quotas
|
||||
assert configuration["autobackupQuotas"] == quotas.model_dump()
|
||||
|
||||
|
||||
def test_autobackup_period_nonzero(authorized_client, backups):
|
||||
|
|
|
@ -70,7 +70,6 @@ async def test_pubsub(empty_redis, event_loop):
|
|||
# Sanity checking because of previous event loop bugs
|
||||
assert event_loop == asyncio.get_event_loop()
|
||||
assert event_loop == asyncio.events.get_event_loop()
|
||||
assert event_loop == asyncio.events._get_event_loop()
|
||||
assert event_loop == asyncio.events.get_running_loop()
|
||||
|
||||
reader = streams.StreamReader(34)
|
||||
|
|
Loading…
Reference in a new issue