Merge pull request 'tests: add test for creating machine on minimal clan' (#1596) from DavHau/clan-core:DavHau-dave into main
All checks were successful
deploy / deploy-docs (push) Successful in 20s
buildbot/nix-build .#checks.x86_64-linux.clan-app-pytest Build done.
buildbot/nix-build .#checks.x86_64-linux.clan-app-no-breakpoints Build done.
buildbot/nix-build .#checks.x86_64-linux.clan-dep-bash Build done.
buildbot/nix-build .#checks.x86_64-linux.clan-dep-fakeroot Build done.
buildbot/nix-build .#checks.x86_64-linux.clan-dep-age Build done.
buildbot/nix-build .#checks.x86_64-linux.clan-dep-e2fsprogs Build done.
buildbot/nix-build .#checks.x86_64-linux.borgbackup Build done.
buildbot/nix-build .#checks.x86_64-linux.package-gui-installer-apk Build done.
buildbot/nix-build .#checks.x86_64-linux.package-gui-installer-archlinux Build done.
buildbot/nix-build .#checks.x86_64-linux.package-gui-installer-deb Build done.
buildbot/nix-build .#checks.aarch64-darwin.nixos-test-backup Build done.
buildbot/nix-build .#checks.x86_64-linux.package-clan-cli Build done.
buildbot/nix-build .#checks.x86_64-linux.package-clan-cli-docs Build done.
buildbot/nix-build .#checks.x86_64-linux.package-clan-ts-api Build done.
buildbot/nix-build .#checks.x86_64-linux.package-default Build done.
buildbot/nix-build .#checks.x86_64-linux.module-schema Build done.
buildbot/nix-build .#checks.x86_64-linux.package-clan-app Build done.
buildbot/nix-build .#checks.x86_64-linux.package-editor Build done.
buildbot/nix-build .#checks.x86_64-linux.lib-jsonschema-nix-unit-tests Build done.
buildbot/nix-build .#checks.x86_64-linux.flash Build done.
buildbot/nix-build .#checks.x86_64-linux.nixos-test-backup Build done.
buildbot/nix-build .#checks.x86_64-linux.check-for-breakpoints Build done.
buildbot/nix-build .#checks.aarch64-darwin.nixos-test_install_machine Build done.
buildbot/nix-build .#checks.x86_64-linux.package-gui-installer-rpm Build done.
buildbot/nix-build .#checks.aarch64-darwin.nixos-iso-installer Build done.
buildbot/nix-build .#checks.aarch64-linux.nixos-iso-installer Build done.
buildbot/nix-build .#checks.aarch64-darwin.nixos-flash-installer Build done.
buildbot/nix-build .#checks.aarch64-linux.nixos-test-backup Build done.
buildbot/nix-build .#checks.aarch64-linux.nixos-test_install_machine Build done.
buildbot/nix-build .#checks.x86_64-linux.clan-dep-git Build done.
buildbot/nix-build .#checks.x86_64-linux.clan-dep-nix Build done.
buildbot/nix-build .#checks.x86_64-linux.clan-dep-openssh Build done.
buildbot/nix-build .#checks.x86_64-linux."clan-dep-python3.11-mypy" Build done.
buildbot/nix-build .#checks.x86_64-linux."clan-dep-python3.11-qemu" Build done.
buildbot/nix-build .#checks.x86_64-linux.clan-dep-rsync Build done.
buildbot/nix-build .#checks.x86_64-linux.clan-dep-sops Build done.
buildbot/nix-build .#checks.x86_64-linux.clan-dep-sshpass Build done.
buildbot/nix-build .#checks.x86_64-linux.clan-dep-tor Build done.
buildbot/nix-build .#checks.x86_64-linux.clan-dep-zbar Build done.
buildbot/nix-build .#checks.x86_64-linux.clan-pytest-with-core Build done.
buildbot/nix-build .#checks.x86_64-linux.clan-pytest-without-core Build done.
buildbot/nix-build .#checks.x86_64-linux.devShell-clan-app Build done.
buildbot/nix-build .#checks.x86_64-linux.container Build done.
buildbot/nix-build .#checks.x86_64-linux.devShell-webview-ui Build done.
buildbot/nix-build .#checks.x86_64-linux.lib-jsonschema-example-valid Build done.
buildbot/nix-build .#checks.aarch64-linux.nixos-flash-installer Build done.
buildbot/nix-build .#checks.x86_64-linux.devShell-clan-cli Build done.
buildbot/nix-build .#checks.x86_64-linux.devShell-default Build done.
buildbot/nix-build .#checks.x86_64-linux.devShell-docs Build done.
buildbot/nix-build .#checks.x86_64-linux.deltachat Build done.
buildbot/nix-build .#checks.x86_64-linux.package-zt-tcp-relay Build done.
buildbot/nix-build .#checks.x86_64-linux.package-docs Build done.
buildbot/nix-build .#checks.x86_64-linux.package-deploy-docs Build done.
buildbot/nix-build .#checks.x86_64-linux.nixos-test_install_machine Build done.
buildbot/nix-build .#checks.x86_64-linux.renderClanOptions Build done.
buildbot/nix-build .#checks.x86_64-linux.package-function-schema Build done.
buildbot/nix-build .#checks.x86_64-linux.package-module-docs Build done.
buildbot/nix-build .#checks.x86_64-linux.nixos-flash-installer Build done.
buildbot/nix-build .#checks.x86_64-linux.package-module-schema Build done.
buildbot/nix-build .#checks.x86_64-linux.package-impure-checks Build done.
buildbot/nix-build .#checks.x86_64-linux.matrix-synapse Build done.
buildbot/nix-build .#checks.x86_64-linux.package-merge-after-ci Build done.
buildbot/nix-build .#checks.x86_64-linux.package-moonlight-sunshine-accept Build done.
buildbot/nix-build .#checks.x86_64-linux.package-pending-reviews Build done.
buildbot/nix-build .#checks.x86_64-linux.package-tea-create-pr Build done.
buildbot/nix-build .#checks.x86_64-linux.package-webview-ui Build done.
buildbot/nix-build .#checks.x86_64-linux.package-zerotier-members Build done.
buildbot/nix-build .#checks.x86_64-linux.package-zerotierone Build done.
buildbot/nix-build .#checks.x86_64-linux.test-backups Build done.
buildbot/nix-build .#checks.x86_64-linux.zt-tcp-relay Build done.
buildbot/nix-build .#checks.x86_64-linux.treefmt Build done.
buildbot/nix-build .#checks.x86_64-linux.secrets Build done.
buildbot/nix-build .#checks.x86_64-linux.nixos-iso-installer Build done.
checks / checks-impure (push) Successful in 2m13s
buildbot/nix-build .#checks.x86_64-linux.wayland-proxy-virtwl Build done.
buildbot/nix-build .#checks.x86_64-linux.template-minimal Build done.
buildbot/nix-build .#checks.x86_64-linux.package-iso-installer Build done.
buildbot/nix-build .#checks.x86_64-linux.syncthing Build done.
buildbot/nix-build .#checks.x86_64-linux.test-installation Build done.
buildbot/nix-build .#checks.x86_64-linux.package-gui-install-test-ubuntu-22-04 Build done.
buildbot/nix-eval Build done.
All checks were successful
deploy / deploy-docs (push) Successful in 20s
buildbot/nix-build .#checks.x86_64-linux.clan-app-pytest Build done.
buildbot/nix-build .#checks.x86_64-linux.clan-app-no-breakpoints Build done.
buildbot/nix-build .#checks.x86_64-linux.clan-dep-bash Build done.
buildbot/nix-build .#checks.x86_64-linux.clan-dep-fakeroot Build done.
buildbot/nix-build .#checks.x86_64-linux.clan-dep-age Build done.
buildbot/nix-build .#checks.x86_64-linux.clan-dep-e2fsprogs Build done.
buildbot/nix-build .#checks.x86_64-linux.borgbackup Build done.
buildbot/nix-build .#checks.x86_64-linux.package-gui-installer-apk Build done.
buildbot/nix-build .#checks.x86_64-linux.package-gui-installer-archlinux Build done.
buildbot/nix-build .#checks.x86_64-linux.package-gui-installer-deb Build done.
buildbot/nix-build .#checks.aarch64-darwin.nixos-test-backup Build done.
buildbot/nix-build .#checks.x86_64-linux.package-clan-cli Build done.
buildbot/nix-build .#checks.x86_64-linux.package-clan-cli-docs Build done.
buildbot/nix-build .#checks.x86_64-linux.package-clan-ts-api Build done.
buildbot/nix-build .#checks.x86_64-linux.package-default Build done.
buildbot/nix-build .#checks.x86_64-linux.module-schema Build done.
buildbot/nix-build .#checks.x86_64-linux.package-clan-app Build done.
buildbot/nix-build .#checks.x86_64-linux.package-editor Build done.
buildbot/nix-build .#checks.x86_64-linux.lib-jsonschema-nix-unit-tests Build done.
buildbot/nix-build .#checks.x86_64-linux.flash Build done.
buildbot/nix-build .#checks.x86_64-linux.nixos-test-backup Build done.
buildbot/nix-build .#checks.x86_64-linux.check-for-breakpoints Build done.
buildbot/nix-build .#checks.aarch64-darwin.nixos-test_install_machine Build done.
buildbot/nix-build .#checks.x86_64-linux.package-gui-installer-rpm Build done.
buildbot/nix-build .#checks.aarch64-darwin.nixos-iso-installer Build done.
buildbot/nix-build .#checks.aarch64-linux.nixos-iso-installer Build done.
buildbot/nix-build .#checks.aarch64-darwin.nixos-flash-installer Build done.
buildbot/nix-build .#checks.aarch64-linux.nixos-test-backup Build done.
buildbot/nix-build .#checks.aarch64-linux.nixos-test_install_machine Build done.
buildbot/nix-build .#checks.x86_64-linux.clan-dep-git Build done.
buildbot/nix-build .#checks.x86_64-linux.clan-dep-nix Build done.
buildbot/nix-build .#checks.x86_64-linux.clan-dep-openssh Build done.
buildbot/nix-build .#checks.x86_64-linux."clan-dep-python3.11-mypy" Build done.
buildbot/nix-build .#checks.x86_64-linux."clan-dep-python3.11-qemu" Build done.
buildbot/nix-build .#checks.x86_64-linux.clan-dep-rsync Build done.
buildbot/nix-build .#checks.x86_64-linux.clan-dep-sops Build done.
buildbot/nix-build .#checks.x86_64-linux.clan-dep-sshpass Build done.
buildbot/nix-build .#checks.x86_64-linux.clan-dep-tor Build done.
buildbot/nix-build .#checks.x86_64-linux.clan-dep-zbar Build done.
buildbot/nix-build .#checks.x86_64-linux.clan-pytest-with-core Build done.
buildbot/nix-build .#checks.x86_64-linux.clan-pytest-without-core Build done.
buildbot/nix-build .#checks.x86_64-linux.devShell-clan-app Build done.
buildbot/nix-build .#checks.x86_64-linux.container Build done.
buildbot/nix-build .#checks.x86_64-linux.devShell-webview-ui Build done.
buildbot/nix-build .#checks.x86_64-linux.lib-jsonschema-example-valid Build done.
buildbot/nix-build .#checks.aarch64-linux.nixos-flash-installer Build done.
buildbot/nix-build .#checks.x86_64-linux.devShell-clan-cli Build done.
buildbot/nix-build .#checks.x86_64-linux.devShell-default Build done.
buildbot/nix-build .#checks.x86_64-linux.devShell-docs Build done.
buildbot/nix-build .#checks.x86_64-linux.deltachat Build done.
buildbot/nix-build .#checks.x86_64-linux.package-zt-tcp-relay Build done.
buildbot/nix-build .#checks.x86_64-linux.package-docs Build done.
buildbot/nix-build .#checks.x86_64-linux.package-deploy-docs Build done.
buildbot/nix-build .#checks.x86_64-linux.nixos-test_install_machine Build done.
buildbot/nix-build .#checks.x86_64-linux.renderClanOptions Build done.
buildbot/nix-build .#checks.x86_64-linux.package-function-schema Build done.
buildbot/nix-build .#checks.x86_64-linux.package-module-docs Build done.
buildbot/nix-build .#checks.x86_64-linux.nixos-flash-installer Build done.
buildbot/nix-build .#checks.x86_64-linux.package-module-schema Build done.
buildbot/nix-build .#checks.x86_64-linux.package-impure-checks Build done.
buildbot/nix-build .#checks.x86_64-linux.matrix-synapse Build done.
buildbot/nix-build .#checks.x86_64-linux.package-merge-after-ci Build done.
buildbot/nix-build .#checks.x86_64-linux.package-moonlight-sunshine-accept Build done.
buildbot/nix-build .#checks.x86_64-linux.package-pending-reviews Build done.
buildbot/nix-build .#checks.x86_64-linux.package-tea-create-pr Build done.
buildbot/nix-build .#checks.x86_64-linux.package-webview-ui Build done.
buildbot/nix-build .#checks.x86_64-linux.package-zerotier-members Build done.
buildbot/nix-build .#checks.x86_64-linux.package-zerotierone Build done.
buildbot/nix-build .#checks.x86_64-linux.test-backups Build done.
buildbot/nix-build .#checks.x86_64-linux.zt-tcp-relay Build done.
buildbot/nix-build .#checks.x86_64-linux.treefmt Build done.
buildbot/nix-build .#checks.x86_64-linux.secrets Build done.
buildbot/nix-build .#checks.x86_64-linux.nixos-iso-installer Build done.
checks / checks-impure (push) Successful in 2m13s
buildbot/nix-build .#checks.x86_64-linux.wayland-proxy-virtwl Build done.
buildbot/nix-build .#checks.x86_64-linux.template-minimal Build done.
buildbot/nix-build .#checks.x86_64-linux.package-iso-installer Build done.
buildbot/nix-build .#checks.x86_64-linux.syncthing Build done.
buildbot/nix-build .#checks.x86_64-linux.test-installation Build done.
buildbot/nix-build .#checks.x86_64-linux.package-gui-install-test-ubuntu-22-04 Build done.
buildbot/nix-eval Build done.
This commit is contained in:
commit
1d542d4396
|
@ -179,12 +179,15 @@ def type_to_dict(t: Any, scope: str = "", type_map: dict[TypeVar, type] = {}) ->
|
||||||
raise JSchemaTypeError(
|
raise JSchemaTypeError(
|
||||||
f"Usage of the Any type is not supported for API functions. In: {scope}"
|
f"Usage of the Any type is not supported for API functions. In: {scope}"
|
||||||
)
|
)
|
||||||
|
|
||||||
if t is pathlib.Path:
|
if t is pathlib.Path:
|
||||||
return {
|
return {
|
||||||
# TODO: maybe give it a pattern for URI
|
# TODO: maybe give it a pattern for URI
|
||||||
"type": "string",
|
"type": "string",
|
||||||
}
|
}
|
||||||
|
if t is dict:
|
||||||
|
raise JSchemaTypeError(
|
||||||
|
"Error: generic dict type not supported. Use dict[str. Any] instead"
|
||||||
|
)
|
||||||
|
|
||||||
# Optional[T] gets internally transformed Union[T,NoneType]
|
# Optional[T] gets internally transformed Union[T,NoneType]
|
||||||
if t is NoneType:
|
if t is NoneType:
|
||||||
|
|
|
@ -9,7 +9,8 @@ from ..cmd import CmdOut, run
|
||||||
from ..errors import ClanError
|
from ..errors import ClanError
|
||||||
from ..nix import nix_command, nix_shell
|
from ..nix import nix_command, nix_shell
|
||||||
|
|
||||||
DEFAULT_TEMPLATE_URL: str = "git+https://git.clan.lol/clan/clan-core"
|
default_template_url: str = "git+https://git.clan.lol/clan/clan-core"
|
||||||
|
minimal_template_url: str = "git+https://git.clan.lol/clan/clan-core#templates.minimal"
|
||||||
|
|
||||||
|
|
||||||
@dataclass
|
@dataclass
|
||||||
|
@ -21,7 +22,9 @@ class CreateClanResponse:
|
||||||
|
|
||||||
|
|
||||||
@API.register
|
@API.register
|
||||||
def create_clan(directory: Path, template_url: str) -> CreateClanResponse:
|
def create_clan(
|
||||||
|
directory: Path, template_url: str = minimal_template_url
|
||||||
|
) -> CreateClanResponse:
|
||||||
if not directory.exists():
|
if not directory.exists():
|
||||||
directory.mkdir()
|
directory.mkdir()
|
||||||
else:
|
else:
|
||||||
|
@ -78,7 +81,7 @@ def register_create_parser(parser: argparse.ArgumentParser) -> None:
|
||||||
"--url",
|
"--url",
|
||||||
type=str,
|
type=str,
|
||||||
help="url to the clan template",
|
help="url to the clan template",
|
||||||
default=DEFAULT_TEMPLATE_URL,
|
default=default_template_url,
|
||||||
)
|
)
|
||||||
parser.add_argument(
|
parser.add_argument(
|
||||||
"path", type=Path, help="Path to the clan directory", default=Path(".")
|
"path", type=Path, help="Path to the clan directory", default=Path(".")
|
||||||
|
|
|
@ -2,6 +2,7 @@ import argparse
|
||||||
import logging
|
import logging
|
||||||
from dataclasses import dataclass
|
from dataclasses import dataclass
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
|
from typing import Any
|
||||||
|
|
||||||
from clan_cli.api import API
|
from clan_cli.api import API
|
||||||
from clan_cli.config.machine import set_config_for_machine
|
from clan_cli.config.machine import set_config_for_machine
|
||||||
|
@ -12,7 +13,7 @@ log = logging.getLogger(__name__)
|
||||||
@dataclass
|
@dataclass
|
||||||
class MachineCreateRequest:
|
class MachineCreateRequest:
|
||||||
name: str
|
name: str
|
||||||
config: dict[str, int]
|
config: dict[str, Any]
|
||||||
|
|
||||||
|
|
||||||
@API.register
|
@API.register
|
||||||
|
|
|
@ -12,7 +12,7 @@ log = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
@API.register
|
@API.register
|
||||||
def list_machines(flake_url: str | Path, debug: bool) -> list[str]:
|
def list_machines(flake_url: str | Path, debug: bool = False) -> list[str]:
|
||||||
config = nix_config()
|
config = nix_config()
|
||||||
system = config["system"]
|
system = config["system"]
|
||||||
cmd = nix_eval(
|
cmd = nix_eval(
|
||||||
|
|
|
@ -29,6 +29,9 @@ def substitute(
|
||||||
line = line.replace("__NIXPKGS__", str(nixpkgs_source()))
|
line = line.replace("__NIXPKGS__", str(nixpkgs_source()))
|
||||||
if clan_core_flake:
|
if clan_core_flake:
|
||||||
line = line.replace("__CLAN_CORE__", str(clan_core_flake))
|
line = line.replace("__CLAN_CORE__", str(clan_core_flake))
|
||||||
|
line = line.replace(
|
||||||
|
"git+https://git.clan.lol/clan/clan-core", str(clan_core_flake)
|
||||||
|
)
|
||||||
line = line.replace("__CLAN_SOPS_KEY_PATH__", sops_key)
|
line = line.replace("__CLAN_SOPS_KEY_PATH__", sops_key)
|
||||||
line = line.replace("__CLAN_SOPS_KEY_DIR__", str(flake))
|
line = line.replace("__CLAN_SOPS_KEY_DIR__", str(flake))
|
||||||
print(line, end="")
|
print(line, end="")
|
||||||
|
@ -67,6 +70,7 @@ def generate_flake(
|
||||||
# copy the template to a new temporary location
|
# copy the template to a new temporary location
|
||||||
flake = temporary_home / "flake"
|
flake = temporary_home / "flake"
|
||||||
shutil.copytree(flake_template, flake)
|
shutil.copytree(flake_template, flake)
|
||||||
|
sp.run(["chmod", "+w", "-R", str(flake)], check=True)
|
||||||
|
|
||||||
# substitute `substitutions` in all files of the template
|
# substitute `substitutions` in all files of the template
|
||||||
for file in flake.rglob("*"):
|
for file in flake.rglob("*"):
|
||||||
|
@ -107,7 +111,7 @@ def generate_flake(
|
||||||
def create_flake(
|
def create_flake(
|
||||||
monkeypatch: pytest.MonkeyPatch,
|
monkeypatch: pytest.MonkeyPatch,
|
||||||
temporary_home: Path,
|
temporary_home: Path,
|
||||||
flake_template_name: str,
|
flake_template: str | Path,
|
||||||
clan_core_flake: Path | None = None,
|
clan_core_flake: Path | None = None,
|
||||||
# names referring to pre-defined machines from ../machines
|
# names referring to pre-defined machines from ../machines
|
||||||
machines: list[str] = [],
|
machines: list[str] = [],
|
||||||
|
@ -119,13 +123,19 @@ def create_flake(
|
||||||
Creates a flake with the given name and machines.
|
Creates a flake with the given name and machines.
|
||||||
The machine names map to the machines in ./test_machines
|
The machine names map to the machines in ./test_machines
|
||||||
"""
|
"""
|
||||||
template = Path(__file__).parent / flake_template_name
|
if isinstance(flake_template, Path):
|
||||||
|
template_path = flake_template
|
||||||
|
else:
|
||||||
|
template_path = Path(__file__).parent / flake_template
|
||||||
|
|
||||||
|
flake_template_name = template_path.name
|
||||||
|
|
||||||
# copy the template to a new temporary location
|
# copy the template to a new temporary location
|
||||||
flake = temporary_home / flake_template_name
|
flake = temporary_home / flake_template_name
|
||||||
shutil.copytree(template, flake)
|
shutil.copytree(template_path, flake)
|
||||||
|
sp.run(["chmod", "+w", "-R", str(flake)], check=True)
|
||||||
|
|
||||||
# lookup the requested machines in ./test_machines and include them
|
# add the requested machines to the flake
|
||||||
if machines:
|
if machines:
|
||||||
(flake / "machines").mkdir(parents=True, exist_ok=True)
|
(flake / "machines").mkdir(parents=True, exist_ok=True)
|
||||||
for machine_name in machines:
|
for machine_name in machines:
|
||||||
|
@ -237,3 +247,19 @@ def test_flake_with_core_and_pass(
|
||||||
"test_flake_with_core_and_pass",
|
"test_flake_with_core_and_pass",
|
||||||
CLAN_CORE,
|
CLAN_CORE,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.fixture
|
||||||
|
def test_flake_minimal(
|
||||||
|
monkeypatch: pytest.MonkeyPatch, temporary_home: Path
|
||||||
|
) -> Iterator[FlakeForTest]:
|
||||||
|
if not (CLAN_CORE / "flake.nix").exists():
|
||||||
|
raise Exception(
|
||||||
|
"clan-core flake not found. This test requires the clan-core flake to be present"
|
||||||
|
)
|
||||||
|
yield from create_flake(
|
||||||
|
monkeypatch,
|
||||||
|
temporary_home,
|
||||||
|
CLAN_CORE / "templates" / "minimal",
|
||||||
|
CLAN_CORE,
|
||||||
|
)
|
||||||
|
|
|
@ -2,9 +2,23 @@ import pytest
|
||||||
from fixtures_flakes import FlakeForTest
|
from fixtures_flakes import FlakeForTest
|
||||||
|
|
||||||
from clan_cli.config.schema import machine_schema
|
from clan_cli.config.schema import machine_schema
|
||||||
|
from clan_cli.machines.create import MachineCreateRequest, create_machine
|
||||||
|
from clan_cli.machines.list import list_machines
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.with_core
|
@pytest.mark.with_core
|
||||||
def test_schema_for_machine(test_flake_with_core: FlakeForTest) -> None:
|
def test_schema_for_machine(test_flake_with_core: FlakeForTest) -> None:
|
||||||
schema = machine_schema(test_flake_with_core.path, config={})
|
schema = machine_schema(test_flake_with_core.path, config={})
|
||||||
assert "properties" in schema
|
assert "properties" in schema
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.with_core
|
||||||
|
def test_create_machine_on_minimal_clan(test_flake_minimal: FlakeForTest) -> None:
|
||||||
|
assert list_machines(test_flake_minimal.path) == []
|
||||||
|
create_machine(
|
||||||
|
test_flake_minimal.path,
|
||||||
|
MachineCreateRequest(
|
||||||
|
name="foo", config=dict(nixpkgs=dict(hostSystem="x86_64-linux"))
|
||||||
|
),
|
||||||
|
)
|
||||||
|
assert list_machines(test_flake_minimal.path) == ["foo"]
|
||||||
|
|
Loading…
Reference in New Issue
Block a user