Merge pull request 'clan-vm-manager' (#556) from clan-vm-manager into main
This commit is contained in:
4
.envrc
4
.envrc
@@ -1,5 +1,5 @@
|
||||
if ! has nix_direnv_version || ! nix_direnv_version 2.3.0; then
|
||||
source_url "https://raw.githubusercontent.com/nix-community/nix-direnv/2.3.0/direnvrc" "sha256-Dmd+j63L84wuzgyjITIfSxSD57Tx7v51DMxVZOsiUD8="
|
||||
if ! has nix_direnv_version || ! nix_direnv_version 2.4.0; then
|
||||
source_url "https://raw.githubusercontent.com/nix-community/nix-direnv/2.4.0/direnvrc" "sha256-Dmd+j63L84wuzgyjITIfSxSD57Tx7v51DMxVZOsiUD8="
|
||||
fi
|
||||
|
||||
use flake
|
||||
|
||||
@@ -78,6 +78,8 @@ Let's get your development environment up and running:
|
||||
```
|
||||
- Wait for the frontend to build.
|
||||
|
||||
NOTE: If you have the error "@clan/colors.json" you executed `npm install`, please do not do that. `direnv reload` will handle dependency management. Please delete node_modules with `rm -rf node_modules`.
|
||||
|
||||
9. **Start the Frontend**:
|
||||
- To start the frontend, execute:
|
||||
```bash
|
||||
|
||||
@@ -33,7 +33,6 @@
|
||||
"aarch64-darwin"
|
||||
];
|
||||
imports = [
|
||||
|
||||
./checks/flake-module.nix
|
||||
./devShell.nix
|
||||
./formatter.nix
|
||||
|
||||
@@ -1,13 +1,6 @@
|
||||
# Because we depend on nixpkgs sources, uploading to builders takes a long time
|
||||
|
||||
source_up
|
||||
|
||||
nix_direnv_watch_file flake-module.nix default.nix
|
||||
|
||||
if type nix_direnv_watch_file &>/dev/null; then
|
||||
nix_direnv_watch_file flake-module.nix
|
||||
nix_direnv_watch_file default.nix
|
||||
else
|
||||
direnv watch flake-module.nix
|
||||
direnv watch default.nix
|
||||
fi
|
||||
# Because we depend on nixpkgs sources, uploading to builders takes a long time
|
||||
use flake .#clan-cli --builders ''
|
||||
|
||||
@@ -5,9 +5,12 @@ import tempfile
|
||||
from pathlib import Path
|
||||
from typing import Any
|
||||
|
||||
from .deal import deal
|
||||
from .dirs import nixpkgs_flake, nixpkgs_source
|
||||
from .errors import ClanError
|
||||
|
||||
|
||||
@deal.raises(ClanError)
|
||||
def nix_command(flags: list[str]) -> list[str]:
|
||||
return ["nix", "--extra-experimental-features", "nix-command flakes"] + flags
|
||||
|
||||
@@ -25,6 +28,7 @@ def nix_flake_show(flake_url: str | Path) -> list[str]:
|
||||
)
|
||||
|
||||
|
||||
@deal.raises(ClanError)
|
||||
def nix_build(
|
||||
flags: list[str],
|
||||
) -> list[str]:
|
||||
@@ -41,6 +45,7 @@ def nix_build(
|
||||
)
|
||||
|
||||
|
||||
@deal.raises(ClanError)
|
||||
def nix_config() -> dict[str, Any]:
|
||||
cmd = nix_command(["show-config", "--json"])
|
||||
proc = subprocess.run(cmd, check=True, text=True, stdout=subprocess.PIPE)
|
||||
@@ -51,6 +56,7 @@ def nix_config() -> dict[str, Any]:
|
||||
return config
|
||||
|
||||
|
||||
@deal.raises(ClanError)
|
||||
def nix_eval(flags: list[str]) -> list[str]:
|
||||
default_flags = nix_command(
|
||||
[
|
||||
@@ -78,6 +84,7 @@ def nix_eval(flags: list[str]) -> list[str]:
|
||||
return default_flags + flags
|
||||
|
||||
|
||||
@deal.raises(ClanError)
|
||||
def nix_shell(packages: list[str], cmd: list[str]) -> list[str]:
|
||||
# we cannot use nix-shell inside the nix sandbox
|
||||
# in our tests we just make sure we have all the packages
|
||||
|
||||
@@ -187,9 +187,13 @@ def get_task(uuid: UUID) -> BaseTask:
|
||||
T = TypeVar("T", bound="BaseTask")
|
||||
|
||||
|
||||
@deal.raises(ClanError)
|
||||
def create_task(task_type: Type[T], *args: Any) -> T:
|
||||
global POOL
|
||||
|
||||
# check if task_type is a callable
|
||||
if not callable(task_type):
|
||||
raise ClanError("task_type must be callable")
|
||||
uuid = uuid4()
|
||||
|
||||
task = task_type(uuid, *args)
|
||||
|
||||
@@ -28,7 +28,6 @@
|
||||
, tor
|
||||
, git
|
||||
, nixpkgs
|
||||
, copyDesktopItems
|
||||
, qemu
|
||||
, gnupg
|
||||
, e2fsprogs
|
||||
@@ -36,7 +35,7 @@
|
||||
, deal
|
||||
, rope
|
||||
, clan-core-path
|
||||
, schemathesis
|
||||
, schemathesis ? null
|
||||
}:
|
||||
let
|
||||
|
||||
@@ -129,7 +128,6 @@ python3.pkgs.buildPythonApplication {
|
||||
nativeBuildInputs = [
|
||||
setuptools
|
||||
installShellFiles
|
||||
copyDesktopItems
|
||||
];
|
||||
propagatedBuildInputs = dependencies;
|
||||
|
||||
|
||||
@@ -38,6 +38,11 @@ exclude = "clan_cli.nixpkgs"
|
||||
module = "argcomplete.*"
|
||||
ignore_missing_imports = true
|
||||
|
||||
[[tool.mypy.overrides]]
|
||||
module = "gi.*"
|
||||
ignore_missing_imports = true
|
||||
|
||||
|
||||
[[tool.mypy.overrides]]
|
||||
module = "jsonschema.*"
|
||||
ignore_missing_imports = true
|
||||
@@ -58,4 +63,4 @@ ignore_missing_imports = true
|
||||
line-length = 88
|
||||
|
||||
select = [ "E", "F", "I", "N"]
|
||||
ignore = [ "E501" ]
|
||||
ignore = [ "E501", "E402" ]
|
||||
|
||||
@@ -38,14 +38,12 @@ mkShell {
|
||||
--prefix "$tmp_path/python" \
|
||||
--editable $repo_root
|
||||
|
||||
rm -f clan_cli/nixpkgs clan_cli/webui/assets
|
||||
ln -sf ${clan-cli.nixpkgs} clan_cli/nixpkgs
|
||||
ln -sf ${ui-assets} clan_cli/webui/assets
|
||||
ln -sfT ${clan-cli.nixpkgs} clan_cli/nixpkgs
|
||||
ln -sfT ${ui-assets} clan_cli/webui/assets
|
||||
|
||||
export PATH="$tmp_path/python/bin:${checkScript}/bin:$PATH"
|
||||
export PYTHONPATH="$repo_root:$tmp_path/python/${pythonWithDeps.sitePackages}:"
|
||||
|
||||
|
||||
export XDG_DATA_DIRS="$tmp_path/share''${XDG_DATA_DIRS:+:$XDG_DATA_DIRS}"
|
||||
export fish_complete_path="$tmp_path/share/fish/vendor_completions.d''${fish_complete_path:+:$fish_complete_path}"
|
||||
mkdir -p \
|
||||
|
||||
@@ -1,8 +1,38 @@
|
||||
import deal
|
||||
|
||||
from clan_cli.task_manager import get_task
|
||||
from clan_cli import nix, task_manager
|
||||
|
||||
|
||||
@deal.cases(get_task)
|
||||
@deal.cases(task_manager.get_task)
|
||||
def test_get_task(case: deal.TestCase) -> None:
|
||||
case()
|
||||
|
||||
|
||||
@deal.cases(task_manager.create_task)
|
||||
def test_create_task(case: deal.TestCase) -> None:
|
||||
case()
|
||||
|
||||
|
||||
@deal.cases(nix.nix_command)
|
||||
def test_nix_command(case: deal.TestCase) -> None:
|
||||
case()
|
||||
|
||||
|
||||
@deal.cases(nix.nix_build)
|
||||
def test_nix_build(case: deal.TestCase) -> None:
|
||||
case()
|
||||
|
||||
|
||||
@deal.cases(nix.nix_config)
|
||||
def test_nix_config(case: deal.TestCase) -> None:
|
||||
case()
|
||||
|
||||
|
||||
@deal.cases(nix.nix_eval)
|
||||
def test_nix_eval(case: deal.TestCase) -> None:
|
||||
case()
|
||||
|
||||
|
||||
@deal.cases(nix.nix_shell)
|
||||
def test_nix_shell(case: deal.TestCase) -> None:
|
||||
case()
|
||||
|
||||
6
pkgs/clan-vm-manager/.envrc
Normal file
6
pkgs/clan-vm-manager/.envrc
Normal file
@@ -0,0 +1,6 @@
|
||||
source_up
|
||||
|
||||
nix_direnv_watch_file flake-module.nix default.nix
|
||||
|
||||
# Because we depend on nixpkgs sources, uploading to builders takes a long time
|
||||
use flake .#clan-vm-manager --builders ''
|
||||
13
pkgs/clan-vm-manager/bin/clan-vm-manager
Executable file
13
pkgs/clan-vm-manager/bin/clan-vm-manager
Executable file
@@ -0,0 +1,13 @@
|
||||
#!/usr/bin/env python3
|
||||
import sys
|
||||
from pathlib import Path
|
||||
|
||||
module_path = Path(__file__).parent.parent.absolute()
|
||||
|
||||
sys.path.insert(0, str(module_path))
|
||||
sys.path.insert(0, str(module_path.parent / "clan_cli"))
|
||||
|
||||
from clan_vm_manager import main # NOQA
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
13
pkgs/clan-vm-manager/clan_vm_manager/__init__.py
Normal file
13
pkgs/clan-vm-manager/clan_vm_manager/__init__.py
Normal file
@@ -0,0 +1,13 @@
|
||||
import argparse
|
||||
from typing import Callable, Optional
|
||||
|
||||
start_app: Optional[Callable] = None
|
||||
|
||||
from .app import start_app
|
||||
|
||||
|
||||
def main() -> None:
|
||||
parser = argparse.ArgumentParser(description="clan-vm-manager")
|
||||
parser.set_defaults(func=start_app)
|
||||
args = parser.parse_args()
|
||||
args.func(args)
|
||||
49
pkgs/clan-vm-manager/clan_vm_manager/app.glade
Normal file
49
pkgs/clan-vm-manager/clan_vm_manager/app.glade
Normal file
@@ -0,0 +1,49 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!-- Generated with glade 3.40.0 -->
|
||||
<interface>
|
||||
<requires lib="gtk+" version="3.24"/>
|
||||
<object class="GtkApplicationWindow" id="main-window">
|
||||
<property name="can-focus">False</property>
|
||||
<child>
|
||||
<object class="GtkFixed">
|
||||
<property name="name">asdasd</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can-focus">False</property>
|
||||
<child>
|
||||
<object class="GtkButton" id="help_button">
|
||||
<property name="label" translatable="yes">May I help you?</property>
|
||||
<property name="name">asdasd</property>
|
||||
<property name="width-request">100</property>
|
||||
<property name="height-request">80</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can-focus">True</property>
|
||||
<property name="receives-default">True</property>
|
||||
<property name="image-position">top</property>
|
||||
<signal name="clicked" handler="on_help_button_clicked" object="coffee_label" swapped="no"/>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="x">21</property>
|
||||
<property name="y">21</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel" id="coffee_label">
|
||||
<property name="width-request">100</property>
|
||||
<property name="height-request">80</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can-focus">False</property>
|
||||
<property name="label" translatable="yes">Get me some coffe! </property>
|
||||
<property name="width-chars">0</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="x">178</property>
|
||||
<property name="y">120</property>
|
||||
</packing>
|
||||
</child>
|
||||
<style>
|
||||
<class name="asdasd"/>
|
||||
</style>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</interface>
|
||||
19
pkgs/clan-vm-manager/clan_vm_manager/app.py
Normal file
19
pkgs/clan-vm-manager/clan_vm_manager/app.py
Normal file
@@ -0,0 +1,19 @@
|
||||
# !/usr/bin/env python3
|
||||
|
||||
import argparse # noqa
|
||||
from pathlib import Path # noqa
|
||||
|
||||
import gi # noqa
|
||||
|
||||
gi.require_version("Gtk", "3.0") # noqa
|
||||
from gi.repository import Gtk # noqa
|
||||
|
||||
|
||||
def start_app(args: argparse.Namespace) -> None:
|
||||
builder = Gtk.Builder()
|
||||
glade_file = Path(__file__).parent / "app.glade"
|
||||
builder.add_from_file(str(glade_file))
|
||||
window = builder.get_object("main-window")
|
||||
window.show_all()
|
||||
|
||||
Gtk.main()
|
||||
68
pkgs/clan-vm-manager/default.nix
Normal file
68
pkgs/clan-vm-manager/default.nix
Normal file
@@ -0,0 +1,68 @@
|
||||
{ python3
|
||||
, runCommand
|
||||
, setuptools
|
||||
, copyDesktopItems
|
||||
, pygobject3
|
||||
, wrapGAppsHook
|
||||
, gtk3
|
||||
, gnome
|
||||
, gobject-introspection
|
||||
, clan-cli
|
||||
, makeDesktopItem
|
||||
}:
|
||||
let
|
||||
source = ./.;
|
||||
in
|
||||
python3.pkgs.buildPythonApplication {
|
||||
name = "clan-vm-manager";
|
||||
src = source;
|
||||
format = "pyproject";
|
||||
|
||||
makeWrapperArgs = [
|
||||
# This prevents problems with mixed glibc versions that might occur when the
|
||||
# cli is called through a browser built against another glibc
|
||||
"--unset LD_LIBRARY_PATH"
|
||||
];
|
||||
|
||||
nativeBuildInputs = [
|
||||
setuptools
|
||||
copyDesktopItems
|
||||
wrapGAppsHook
|
||||
gobject-introspection
|
||||
];
|
||||
|
||||
buildInputs = [ gtk3 gnome.adwaita-icon-theme ];
|
||||
propagatedBuildInputs = [ pygobject3 clan-cli ];
|
||||
|
||||
# also re-expose dependencies so we test them in CI
|
||||
passthru.tests = {
|
||||
clan-vm-manager-no-breakpoints = runCommand "clan-vm-manager-no-breakpoints" { } ''
|
||||
if grep --include \*.py -Rq "breakpoint()" ${source}; then
|
||||
echo "breakpoint() found in ${source}:"
|
||||
grep --include \*.py -Rn "breakpoint()" ${source}
|
||||
exit 1
|
||||
fi
|
||||
touch $out
|
||||
'';
|
||||
};
|
||||
|
||||
# Don't leak python packages into a devshell.
|
||||
# It can be very confusing if you `nix run` than load the cli from the devshell instead.
|
||||
postFixup = ''
|
||||
rm $out/nix-support/propagated-build-inputs
|
||||
'';
|
||||
checkPhase = ''
|
||||
PYTHONPATH= $out/bin/clan-vm-manager --help
|
||||
'';
|
||||
meta.mainProgram = "clan";
|
||||
desktopItems = [
|
||||
(makeDesktopItem {
|
||||
name = "clan-vm-manager";
|
||||
# TODO: this subcommand is not implemented yet
|
||||
exec = "clan-vm-manager join %u";
|
||||
desktopName = "CLan VM Manager";
|
||||
startupWMClass = "clan";
|
||||
mimeTypes = [ "x-scheme-handler/clan" ];
|
||||
})
|
||||
];
|
||||
}
|
||||
12
pkgs/clan-vm-manager/flake-module.nix
Normal file
12
pkgs/clan-vm-manager/flake-module.nix
Normal file
@@ -0,0 +1,12 @@
|
||||
{ ... }: {
|
||||
perSystem = { config, pkgs, ... }: {
|
||||
devShells.clan-vm-manager = pkgs.callPackage ./shell.nix {
|
||||
inherit (config.packages) clan-cli clan-vm-manager;
|
||||
};
|
||||
packages.clan-vm-manager = pkgs.python3.pkgs.callPackage ./default.nix {
|
||||
inherit (config.packages) clan-cli;
|
||||
};
|
||||
|
||||
checks = config.packages.clan-vm-manager.tests;
|
||||
};
|
||||
}
|
||||
28
pkgs/clan-vm-manager/pyproject.toml
Normal file
28
pkgs/clan-vm-manager/pyproject.toml
Normal file
@@ -0,0 +1,28 @@
|
||||
[build-system]
|
||||
requires = ["setuptools"]
|
||||
build-backend = "setuptools.build_meta"
|
||||
|
||||
[project]
|
||||
name = "clan-vm-manager"
|
||||
dynamic = ["version"]
|
||||
scripts = { clan-vm-manager = "clan_vm_manager:main" }
|
||||
|
||||
[tool.setuptools.package-data]
|
||||
clan_vm_manager = ["*.glade"]
|
||||
|
||||
[tool.mypy]
|
||||
python_version = "3.10"
|
||||
warn_redundant_casts = true
|
||||
disallow_untyped_calls = true
|
||||
disallow_untyped_defs = true
|
||||
no_implicit_optional = true
|
||||
|
||||
[[tool.mypy.overrides]]
|
||||
module = "gi.*"
|
||||
ignore_missing_imports = true
|
||||
|
||||
[tool.ruff]
|
||||
line-length = 88
|
||||
|
||||
select = ["E", "F", "I", "N"]
|
||||
ignore = ["E501", "E402"]
|
||||
14
pkgs/clan-vm-manager/shell.nix
Normal file
14
pkgs/clan-vm-manager/shell.nix
Normal file
@@ -0,0 +1,14 @@
|
||||
{ clan-vm-manager, clan-cli, mkShell, ruff }:
|
||||
mkShell {
|
||||
inherit (clan-vm-manager) propagatedBuildInputs buildInputs;
|
||||
nativeBuildInputs = [
|
||||
ruff
|
||||
] ++ clan-vm-manager.nativeBuildInputs;
|
||||
|
||||
shellHook = ''
|
||||
ln -sfT ${clan-cli.nixpkgs} ../clan-cli/clan_cli/nixpkgs
|
||||
|
||||
# prepend clan-cli for development
|
||||
export PYTHONPATH=../clan-cli:$PYTHONPATH
|
||||
'';
|
||||
}
|
||||
@@ -1,6 +1,7 @@
|
||||
{ ... }: {
|
||||
imports = [
|
||||
./clan-cli/flake-module.nix
|
||||
./clan-vm-manager/flake-module.nix
|
||||
./installer/flake-module.nix
|
||||
./ui/flake-module.nix
|
||||
./theme/flake-module.nix
|
||||
|
||||
Reference in New Issue
Block a user