This commit is contained in:
2025-05-29 17:57:06 +02:00
parent 2c14192d95
commit 394b5f13f8
6 changed files with 172 additions and 195 deletions

18
.gitignore vendored
View File

@ -1,3 +1,9 @@
# Nix #
/result
# Direnv #
/.direnv/
# Python # # Python #
# Virtual Environment # Virtual Environment
/.venv/ /.venv/
@ -13,18 +19,6 @@ __pycache__/
/.pytest_cache/ /.pytest_cache/
/.mypy_cache/ /.mypy_cache/
# Nix #
# Build
/result
# MicroVM
/var.img
/control.socket
# Direnv #
/.direnv/
# Project specific files # # Project specific files #
config.json config.json
db.json db.json

26
flake.lock generated
View File

@ -27,11 +27,11 @@
"spectrum": "spectrum" "spectrum": "spectrum"
}, },
"locked": { "locked": {
"lastModified": 1735074045, "lastModified": 1748464257,
"narHash": "sha256-CeYsC8J2dNiV2FCQOxK1oZ/jNpOF2io7aCEFHmfi95U=", "narHash": "sha256-PdnQSE2vPfql9WEjunj2qQnDpuuvk7HH+4djgXJSwFs=",
"owner": "astro", "owner": "astro",
"repo": "microvm.nix", "repo": "microvm.nix",
"rev": "2ae08de8e8068b00193b9cfbc0acc9dfdda03181", "rev": "e238645b6f0447a2eb1d538d300d5049d4006f9f",
"type": "github" "type": "github"
}, },
"original": { "original": {
@ -42,17 +42,17 @@
}, },
"nixpkgs": { "nixpkgs": {
"locked": { "locked": {
"lastModified": 1733759999, "lastModified": 1748370509,
"narHash": "sha256-463SNPWmz46iLzJKRzO3Q2b0Aurff3U1n0nYItxq7jU=", "narHash": "sha256-QlL8slIgc16W5UaI3w7xHQEP+Qmv/6vSNTpoZrrSlbk=",
"owner": "nixos", "owner": "NixOS",
"repo": "nixpkgs", "repo": "nixpkgs",
"rev": "a73246e2eef4c6ed172979932bc80e1404ba2d56", "rev": "4faa5f5321320e49a78ae7848582f684d64783e9",
"type": "github" "type": "github"
}, },
"original": { "original": {
"owner": "nixos", "owner": "NixOS",
"ref": "nixos-unstable",
"repo": "nixpkgs", "repo": "nixpkgs",
"rev": "a73246e2eef4c6ed172979932bc80e1404ba2d56",
"type": "github" "type": "github"
} }
}, },
@ -65,11 +65,11 @@
"spectrum": { "spectrum": {
"flake": false, "flake": false,
"locked": { "locked": {
"lastModified": 1733308308, "lastModified": 1746869549,
"narHash": "sha256-+RcbMAjSxV1wW5UpS9abIG1lFZC8bITPiFIKNnE7RLs=", "narHash": "sha256-BKZ/yZO/qeLKh9YqVkKB6wJiDQJAZNN5rk5NsMImsWs=",
"ref": "refs/heads/main", "ref": "refs/heads/main",
"rev": "80c9e9830d460c944c8f730065f18bb733bc7ee2", "rev": "d927e78530892ec8ed389e8fae5f38abee00ad87",
"revCount": 792, "revCount": 862,
"type": "git", "type": "git",
"url": "https://spectrum-os.org/git/spectrum" "url": "https://spectrum-os.org/git/spectrum"
}, },

124
flake.nix
View File

@ -2,7 +2,7 @@
description = "A webserver to create files for testing purposes"; description = "A webserver to create files for testing purposes";
inputs = { inputs = {
nixpkgs.url = "github:nixos/nixpkgs?rev=a73246e2eef4c6ed172979932bc80e1404ba2d56"; nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable";
microvm = { microvm = {
url = "github:astro/microvm.nix"; url = "github:astro/microvm.nix";
@ -10,82 +10,25 @@
}; };
}; };
outputs = { outputs =
{
self, self,
nixpkgs, nixpkgs,
... ...
} @ inputs: let }@inputs:
supportedSystems = ["x86_64-linux" "x86_64-darwin" "aarch64-linux" "aarch64-darwin"]; let
supportedSystems = [ "x86_64-linux" ];
forAllSystems = nixpkgs.lib.genAttrs supportedSystems; forAllSystems = nixpkgs.lib.genAttrs supportedSystems;
pkgs = forAllSystems (system: nixpkgs.legacyPackages.${system}.extend overlay); pkgs = forAllSystems (system: nixpkgs.legacyPackages.${system});
overlay = final: prev: rec {
python3Packages = prev.python3Packages.overrideScope (pfinal: pprev: {
packageNameToDrv = x: builtins.getAttr (cleanPythonPackageName x) final.python3Packages;
});
cleanPythonPackageName = x: let
cleanName = builtins.match "([a-z,A-Z,0-9,_,-]+).*" x;
in in
if cleanName != null {
then builtins.elemAt cleanName 0
else builtins.warn "Could not determine package name from '${x}'" null;
};
pyproject = builtins.fromTOML (builtins.readFile ./pyproject.toml);
buildDependencies = forAllSystems (system: builtins.map pkgs.${system}.python3Packages.packageNameToDrv pyproject.build-system.requires);
runtimeDependencies = forAllSystems (system: builtins.map pkgs.${system}.python3Packages.packageNameToDrv pyproject.project.dependencies);
optionalDependencies = forAllSystems (system: builtins.mapAttrs (name: value: builtins.map pkgs.${system}.python3Packages.packageNameToDrv value) pyproject.project.optional-dependencies);
in {
# `nix build` # `nix build`
packages = forAllSystems (system: let packages = forAllSystems (system: rec {
buildTestdata = {skipCheck ? false}:
pkgs.${system}.python3Packages.buildPythonPackage {
pname = pyproject.project.name;
version = pyproject.project.version;
src = ./.;
pyproject = true;
build-system = buildDependencies.${system};
dependencies = runtimeDependencies.${system};
optional-dependencies = optionalDependencies.${system};
nativeCheckInputs = optionalDependencies.${system}.dev;
checkPhase = let
dev = builtins.map (x: x.pname) optionalDependencies.${system}.dev;
in ''
${
if builtins.elem "pytest" dev && !skipCheck
then "pytest tests"
else ""
}
${
if builtins.elem "mypy" dev && !skipCheck
then "mypy src"
else ""
}
${
if builtins.elem "pylint" dev && !skipCheck
then "pylint src"
else ""
}
'';
};
in rec {
default = testdata; default = testdata;
testdata = buildTestdata {skipCheck = false;}; testdata = pkgs.${system}.callPackage ./nix/package.nix { src = ./.; };
quick = buildTestdata {skipCheck = true;};
vm = self.nixosConfigurations.vm.config.microvm.declaredRunner; vm = self.nixosConfigurations.vm.config.microvm.declaredRunner;
}); });
# `nix fmt`
formatter = forAllSystems (system: pkgs.${system}.alejandra);
# `nix develop` # `nix develop`
devShells = forAllSystems (system: rec { devShells = forAllSystems (system: rec {
default = venv; default = venv;
@ -108,36 +51,24 @@
# NixOS Module # NixOS Module
nixosModules.default = import ./nix/module.nix inputs; nixosModules.default = import ./nix/module.nix inputs;
# nixos definition for a microvm to test nixosModules # NixOS definition for a microvm to test nixosModules
nixosConfigurations = let nixosConfigurations."vm" = nixpkgs.lib.nixosSystem {
system = "x86_64-linux"; system = "x86_64-linux";
in {
vm = nixpkgs.lib.nixosSystem {
inherit system;
modules = [ modules = [
inputs.microvm.nixosModules.microvm inputs.microvm.nixosModules.microvm
({config, ...}: { (
system.stateVersion = config.system.nixos.version; { config, ... }:
{
networking.hostName = "vm"; services.getty.autologinUser = "root";
users.users.root.password = "";
microvm = { microvm = {
# volumes = [ hypervisor = "qemu";
# {
# mountPoint = "/var";
# image = "var.img";
# size = 256;
# }
# ];
shares = [ shares = [
{ {
# use proto = "virtiofs" for MicroVMs that are started by systemd # Host's /nix/store will be picked up so that no squashfs/erofs will be built for it.
proto = "9p";
tag = "ro-store"; tag = "ro-store";
# a host's /nix/store will be picked up so that no
# squashfs/erofs will be built for it.
source = "/nix/store"; source = "/nix/store";
mountPoint = "/nix/.ro-store"; mountPoint = "/nix/.ro-store";
} }
@ -147,6 +78,7 @@
{ {
type = "user"; type = "user";
id = "qemu"; id = "qemu";
# Locally administered have one of 2/6/A/E in the second nibble.
mac = "02:00:00:01:01:01"; mac = "02:00:00:01:01:01";
} }
]; ];
@ -157,12 +89,9 @@
guest.port = config.services.testdata.port; guest.port = config.services.testdata.port;
} }
]; ];
# "qemu" has 9p built-in!
hypervisor = "qemu";
socket = "control.socket";
}; };
}) }
)
self.nixosModules.default self.nixosModules.default
rec { rec {
@ -174,11 +103,15 @@
port = 1234; port = 1234;
settings = { settings = {
keys = ["one" "two" "three"]; keys = [
"one"
"two"
"three"
];
max-size = "1GB"; max-size = "1GB";
max-data = "100GB"; max-data = "100GB";
buffer-size = "12MiB"; buffer-size = "12MiB";
database = "/root/testdata_state.json"; database = "/root/testdata-state.json";
database-update-interval = 5.0; database-update-interval = 5.0;
log = "/root/log.jsonl"; log = "/root/log.jsonl";
}; };
@ -187,5 +120,4 @@
]; ];
}; };
}; };
};
} }

View File

@ -1,23 +1,32 @@
inputs: { inputs:
{
config, config,
lib, lib,
pkgs, pkgs,
... ...
}: let }:
let
cfg = config.services.testdata; cfg = config.services.testdata;
package = inputs.self.packages.${pkgs.stdenv.hostPlatform.system}.default; package = inputs.self.packages.${pkgs.stdenv.hostPlatform.system}.default;
inherit (lib) mkIf mkEnableOption mkOption types; inherit (lib)
mkIf
mkEnableOption
mkOption
types
;
format = pkgs.formats.json { }; format = pkgs.formats.json { };
configFile = format.generate "config.json" cfg.settings; configFile = format.generate "config.json" cfg.settings;
in { in
{
options.services.testdata = { options.services.testdata = {
enable = mkEnableOption "testdata"; enable = mkEnableOption "testdata";
settings = mkOption { settings = mkOption {
type = with types; let type =
with types;
let
valueType = nullOr (oneOf [ valueType = nullOr (oneOf [
# TODO: restrict type to actual config file structure
bool bool
int int
float float

46
nix/package.nix Normal file
View File

@ -0,0 +1,46 @@
{
src,
python3Packages,
}:
let
inherit (python3Packages)
setuptools
fastapi
uvicorn
pydantic
pytest
requests
mypy
pylint
;
project = (builtins.fromTOML (builtins.readFile "${src}/pyproject.toml")).project;
pname = project.name;
version = project.version;
in
python3Packages.buildPythonPackage {
inherit pname version src;
pyproject = true;
build-system = [ setuptools ];
dependencies = [
fastapi
uvicorn
pydantic
];
nativeCheckInputs = [
pytest
requests
mypy
pylint
];
checkPhase = ''
pytest tests
mypy src
pylint src
'';
}

View File

@ -1,12 +1,8 @@
[project] [project]
name = "testdata" name = "testdata"
version = "1.2.1" version = "1.2.2"
requires-python = "~=3.12, <4" requires-python = "~=3.12, <4"
dependencies = [ dependencies = ["fastapi~=0.115", "uvicorn~=0.32", "pydantic~=2.9"]
"fastapi~=0.115",
"uvicorn~=0.32",
"pydantic~=2.9",
]
[project.optional-dependencies] [project.optional-dependencies]
dev = [ dev = [
@ -14,14 +10,14 @@ dev = [
"mypy~=1.13", "mypy~=1.13",
"pylint~=3.3", "pylint~=3.3",
"requests~=2.32", "requests~=2.32",
"types-requests~=2.32" "types-requests~=2.32",
] ]
[project.scripts] [project.scripts]
testdata = "testdata.main:main" testdata = "testdata.main:main"
[build-system] [build-system]
requires = ["setuptools~=75.1"] requires = ["setuptools~=78.1"]
build-backend = "setuptools.build_meta" build-backend = "setuptools.build_meta"
[tool.setuptools.packages.find] [tool.setuptools.packages.find]
@ -40,5 +36,5 @@ disable = [
"missing-class-docstring", "missing-class-docstring",
"missing-function-docstring", "missing-function-docstring",
"too-few-public-methods", "too-few-public-methods",
"broad-exception-caught" "broad-exception-caught",
] ]