From 485752f224caef63e15329f3acb70e7372e06372 Mon Sep 17 00:00:00 2001 From: Andreas Zweili Date: Thu, 19 Oct 2023 20:15:49 +0200 Subject: [PATCH] Rewrite to devenv --- .envrc | 59 +++-------- .github/workflows/tests.yml | 4 +- .gitignore | 1 + Procfile | 3 +- dev.sh | 8 +- flake.lock | 201 +++++++++++++++++++++++++++++++++++- flake.nix | 153 ++++++++++----------------- 7 files changed, 270 insertions(+), 159 deletions(-) diff --git a/.envrc b/.envrc index 708b96e..1c9a792 100644 --- a/.envrc +++ b/.envrc @@ -1,48 +1,17 @@ -use flake -eval "$shellHook" -layout_postgres() { - export PGDATA="$(direnv_layout_dir)/postgres" - export PGHOST="$PGDATA" - if [[ ! -d "$PGDATA" ]]; then - initdb - echo -e "listen_addresses = 'localhost'\nunix_socket_directories = '$PGHOST'" >>"$PGDATA/postgresql.conf" - echo "CREATE DATABASE django;" | postgres --single -E postgres - fi -} -layout postgres +if ! has nix_direnv_version || ! nix_direnv_version 2.2.1; then + source_url "https://raw.githubusercontent.com/nix-community/nix-direnv/2.2.1/direnvrc" "sha256-zelF0vLbEl5uaqrfIzbgNzJWGmLzCmYAkInj/LNxvKs=" +fi -layout_poetry() { - PYPROJECT_TOML="${PYPROJECT_TOML:-pyproject.toml}" - if [[ ! -f "$PYPROJECT_TOML" ]]; then - log_status "No pyproject.toml found. Executing \`poetry init\` to create a \`$PYPROJECT_TOML\` first." - poetry init - fi - - if [[ -d ".venv" ]]; then - VIRTUAL_ENV="$(pwd)/.venv" - poetry install - else - VIRTUAL_ENV=$( - poetry env info --path 2>/dev/null - true - ) - fi - - if [[ -z $VIRTUAL_ENV || ! -d $VIRTUAL_ENV ]]; then - log_status "No virtual environment exists. Executing \`poetry install\` to create one." - poetry install - VIRTUAL_ENV=$(poetry env info --path) - fi - - PATH_add "$VIRTUAL_ENV/bin" - export POETRY_ACTIVE=1 - export VIRTUAL_ENV -} - -layout poetry -export PROJECT_DIR=$(pwd) export WEBPORT=$(($RANDOM + 1100)) export PGPORT=$(($WEBPORT + 100)) -watch_file "$PGDATA/postgresql.conf" -watch_file ./dev.sh -watch_file ./pyproject.toml +export PROJECT_DIR=$(pwd) + +nix_direnv_watch_file devenv.nix +nix_direnv_watch_file devenv.lock +nix_direnv_watch_file devenv.yaml +nix_direnv_watch_file dev.sh +nix_direnv_watch_file pyproject.toml + +if ! use flake . --impure; then + echo "devenv could not be built. The devenv environment was not loaded. Make the necessary changes to devenv.nix and hit enter to try again." >&2 +fi diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 4d6373f..4dfd1ac 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -14,8 +14,8 @@ jobs: - uses: cachix/install-nix-action@v22 - uses: DeterminateSystems/magic-nix-cache-action@main - name: Environment setup - run: nix develop --command bash -c "poetry install" + run: nix develop --impure --command bash -c "poetry install" - name: Test - run: nix develop --command bash -c "dev test" + run: nix develop --impure --command bash -c "dev test" env: PROJECT_DIR: ${{ github.workspace }} diff --git a/.gitignore b/.gitignore index da8739b..649acf8 100644 --- a/.gitignore +++ b/.gitignore @@ -181,3 +181,4 @@ db_data .direnv /result /static/ +/.devenv/ diff --git a/Procfile b/Procfile index 070d7cf..3ea9b47 100644 --- a/Procfile +++ b/Procfile @@ -1,2 +1 @@ -web: python ./src/manage.py runserver 0.0.0.0:$WEBPORT -db: postgres -p $PGPORT +web: devenv up diff --git a/dev.sh b/dev.sh index 71a80c1..09bb8cd 100755 --- a/dev.sh +++ b/dev.sh @@ -8,9 +8,9 @@ _init() { # Setup the database _setup() { - overmind start -l db -D + overmind start -D + sleep 5 if [ -f .direnv/first_run ]; then - sleep 2 python ./src/manage.py collectstatic --noinput python ./src/manage.py makemigrations python ./src/manage.py migrate @@ -37,8 +37,6 @@ _setup() { _init touch .direnv/first_run fi - overmind quit - sleep 2 } _open_url() { @@ -67,9 +65,9 @@ run() { find . -name __pycache__ -o -name "*.pyc" -delete url=$(_create_url) sudo iptables -I INPUT -p tcp --dport $WEBPORT -j ACCEPT - overmind start -D printf "\n---\n webserver: $url\n---\n" _open_url $url + overmind echo } descriptions["run"]="Start the webserver." tasks["run"]=run diff --git a/flake.lock b/flake.lock index 1006455..ee9a81c 100644 --- a/flake.lock +++ b/flake.lock @@ -1,15 +1,52 @@ { "nodes": { + "devenv": { + "inputs": { + "flake-compat": "flake-compat", + "nix": "nix", + "nixpkgs": "nixpkgs", + "pre-commit-hooks": "pre-commit-hooks" + }, + "locked": { + "lastModified": 1697058441, + "narHash": "sha256-gjtW+nkM9suMsjyid63HPmt6WZQEvuVqA5cOAf4lLM0=", + "owner": "cachix", + "repo": "devenv", + "rev": "55294461a62d90c8626feca22f52b0d3d0e18e39", + "type": "github" + }, + "original": { + "owner": "cachix", + "repo": "devenv", + "type": "github" + } + }, + "flake-compat": { + "flake": false, + "locked": { + "lastModified": 1673956053, + "narHash": "sha256-4gtG9iQuiKITOjNQQeQIpoIB6b16fm+504Ch3sNKLd8=", + "owner": "edolstra", + "repo": "flake-compat", + "rev": "35bb57c0c8d8b62bbfd284272c928ceb64ddbde9", + "type": "github" + }, + "original": { + "owner": "edolstra", + "repo": "flake-compat", + "type": "github" + } + }, "flake-utils": { "inputs": { "systems": "systems" }, "locked": { - "lastModified": 1687709756, - "narHash": "sha256-Y5wKlQSkgEK2weWdOu4J3riRd+kV/VCgHsqLNTTWQ/0=", + "lastModified": 1685518550, + "narHash": "sha256-o2d0KcvaXzTrPRIo0kOLV0/QXHhDQ5DTi+OxcjO8xqY=", "owner": "numtide", "repo": "flake-utils", - "rev": "dbabf0ca0c0c4bce6ea5eaf65af5cb694d2082c7", + "rev": "a1720a10a6cfe8234c0e93907ffe81be440f4cef", "type": "github" }, "original": { @@ -18,7 +55,117 @@ "type": "github" } }, + "gitignore": { + "inputs": { + "nixpkgs": [ + "devenv", + "pre-commit-hooks", + "nixpkgs" + ] + }, + "locked": { + "lastModified": 1660459072, + "narHash": "sha256-8DFJjXG8zqoONA1vXtgeKXy68KdJL5UaXR8NtVMUbx8=", + "owner": "hercules-ci", + "repo": "gitignore.nix", + "rev": "a20de23b925fd8264fd7fad6454652e142fd7f73", + "type": "github" + }, + "original": { + "owner": "hercules-ci", + "repo": "gitignore.nix", + "type": "github" + } + }, + "lowdown-src": { + "flake": false, + "locked": { + "lastModified": 1633514407, + "narHash": "sha256-Dw32tiMjdK9t3ETl5fzGrutQTzh2rufgZV4A/BbxuD4=", + "owner": "kristapsdz", + "repo": "lowdown", + "rev": "d2c2b44ff6c27b936ec27358a2653caaef8f73b8", + "type": "github" + }, + "original": { + "owner": "kristapsdz", + "repo": "lowdown", + "type": "github" + } + }, + "nix": { + "inputs": { + "lowdown-src": "lowdown-src", + "nixpkgs": [ + "devenv", + "nixpkgs" + ], + "nixpkgs-regression": "nixpkgs-regression" + }, + "locked": { + "lastModified": 1676545802, + "narHash": "sha256-EK4rZ+Hd5hsvXnzSzk2ikhStJnD63odF7SzsQ8CuSPU=", + "owner": "domenkozar", + "repo": "nix", + "rev": "7c91803598ffbcfe4a55c44ac6d49b2cf07a527f", + "type": "github" + }, + "original": { + "owner": "domenkozar", + "ref": "relaxed-flakes", + "repo": "nix", + "type": "github" + } + }, "nixpkgs": { + "locked": { + "lastModified": 1678875422, + "narHash": "sha256-T3o6NcQPwXjxJMn2shz86Chch4ljXgZn746c2caGxd8=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "126f49a01de5b7e35a43fd43f891ecf6d3a51459", + "type": "github" + }, + "original": { + "owner": "NixOS", + "ref": "nixpkgs-unstable", + "repo": "nixpkgs", + "type": "github" + } + }, + "nixpkgs-regression": { + "locked": { + "lastModified": 1643052045, + "narHash": "sha256-uGJ0VXIhWKGXxkeNnq4TvV3CIOkUJ3PAoLZ3HMzNVMw=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "215d4d0fd80ca5163643b03a33fde804a29cc1e2", + "type": "github" + }, + "original": { + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "215d4d0fd80ca5163643b03a33fde804a29cc1e2", + "type": "github" + } + }, + "nixpkgs-stable": { + "locked": { + "lastModified": 1685801374, + "narHash": "sha256-otaSUoFEMM+LjBI1XL/xGB5ao6IwnZOXc47qhIgJe8U=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "c37ca420157f4abc31e26f436c1145f8951ff373", + "type": "github" + }, + "original": { + "owner": "NixOS", + "ref": "nixos-23.05", + "repo": "nixpkgs", + "type": "github" + } + }, + "nixpkgs_2": { "locked": { "lastModified": 1688918189, "narHash": "sha256-f8ZlJ67LgEUDnN7ZsAyd1/Fyby1VdOXWg4XY/irSGrQ=", @@ -34,10 +181,39 @@ "type": "github" } }, + "pre-commit-hooks": { + "inputs": { + "flake-compat": [ + "devenv", + "flake-compat" + ], + "flake-utils": "flake-utils", + "gitignore": "gitignore", + "nixpkgs": [ + "devenv", + "nixpkgs" + ], + "nixpkgs-stable": "nixpkgs-stable" + }, + "locked": { + "lastModified": 1688056373, + "narHash": "sha256-2+SDlNRTKsgo3LBRiMUcoEUb6sDViRNQhzJquZ4koOI=", + "owner": "cachix", + "repo": "pre-commit-hooks.nix", + "rev": "5843cf069272d92b60c3ed9e55b7a8989c01d4c7", + "type": "github" + }, + "original": { + "owner": "cachix", + "repo": "pre-commit-hooks.nix", + "type": "github" + } + }, "root": { "inputs": { - "flake-utils": "flake-utils", - "nixpkgs": "nixpkgs" + "devenv": "devenv", + "nixpkgs": "nixpkgs_2", + "systems": "systems_2" } }, "systems": { @@ -54,6 +230,21 @@ "repo": "default", "type": "github" } + }, + "systems_2": { + "locked": { + "lastModified": 1681028828, + "narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=", + "owner": "nix-systems", + "repo": "default", + "rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e", + "type": "github" + }, + "original": { + "owner": "nix-systems", + "repo": "default", + "type": "github" + } } }, "root": "root", diff --git a/flake.nix b/flake.nix index ca6c787..cacf10d 100644 --- a/flake.nix +++ b/flake.nix @@ -2,105 +2,58 @@ description = "A Python API for various tools I use at work."; inputs = { nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable"; - flake-utils.url = "github:numtide/flake-utils"; + systems.url = "github:nix-systems/default"; + devenv.url = "github:cachix/devenv"; + }; + nixConfig = { + extra-trusted-public-keys = "devenv.cachix.org-1:w1cLUi8dv3hnoSPGAuibQv+f9TZLr6cv/Hm9XgU50cw="; + extra-substituters = "https://devenv.cachix.org"; }; - outputs = { self, nixpkgs, flake-utils }: - (flake-utils.lib.eachDefaultSystem (system: - let - pkgs = import nixpkgs { - inherit system; - }; - inventory = pkgs.stdenv.mkDerivation { - src = ./.; - version = "latest"; - pname = "network-inventory"; - installPhase = '' - mkdir -p $out - cp -r ./src $out/code - ''; - }; - in - rec { - devShells.default = pkgs.mkShell { - buildInputs = [ - pkgs.poetry - pkgs.python310 - pkgs.overmind - pkgs.postgresql_15 - (pkgs.writeScriptBin "dev" "${builtins.readFile ./dev.sh}") - ]; - # Put the venv on the repo, so direnv can access it - POETRY_VIRTUALENVS_IN_PROJECT = "true"; - # Use python from path, so you can use a different version to the one - # bundled with poetry - POETRY_VIRTUALENVS_PREFER_ACTIVE_PYTHON = "true"; - PYTHON_KEYRING_BACKEND = "keyring.backends.fail.Keyring"; - LD_LIBRARY_PATH = pkgs.lib.makeLibraryPath [ - pkgs.stdenv.cc.cc - # Add any missing library needed You can use the nix-index package - # to locate them, e.g. - # nix-locate -w --top-level --at-root /lib/libudev.so.1 - ]; - shellHook = '' - export DJANGO_SETTINGS_MODULE=network_inventory.settings.local - ''; - }; - packages = { - container = pkgs.dockerTools.buildImage { - name = "network-inventory"; - tag = "latest"; - created = "now"; - copyToRoot = pkgs.buildEnv { - name = "image-root"; - paths = [ - inventory - pkgs.bashInteractive - pkgs.coreutils - pkgs.poetry - (pkgs.writeShellScriptBin "start-inventory" '' - if [ -f .first_run ]; then - sleep 2 - django-admin collectstatic --noinput - django-admin makemigrations - django-admin migrate - else - django-admin collectstatic --noinput - django-admin makemigrations backups - django-admin makemigrations computers - django-admin makemigrations core - django-admin makemigrations customers - django-admin makemigrations devices - django-admin makemigrations licenses - django-admin makemigrations nets - django-admin makemigrations softwares - django-admin makemigrations users - django-admin makemigrations - django-admin migrate - django-admin loaddata backups - django-admin loaddata computers - django-admin loaddata core - django-admin loaddata devices - django-admin loaddata nets - django-admin loaddata softwares - django-admin shell -c "from django.contrib.auth import get_user_model; User = get_user_model(); User.objects.create_superuser('admin', 'admin@example.com', 'password')" - touch .first_run - fi - gunicorn network_inventory.wsgi:application --reload --bind 0.0.0.0:8000 --workers 3 - '') - ]; - }; - config = { - Cmd = [ "start-inventory" ]; - WorkingDir = "/code"; - Env = [ - "POSTGRES_DB=network_inventory" - "DJANGO_SETTINGS_MODULE=network_inventory.settings.production" - "PYTHONPATH=/lib/python3.10:/lib/python3.10/site-packages:/code" - ]; - }; - }; - default = packages.container; - }; - })); -} + outputs = { self, nixpkgs, devenv, systems }@inputs: + let + forEachSystem = nixpkgs.lib.genAttrs (import systems); + in + { + packages = forEachSystem (system: { + devenv-up = self.devShells.${system}.default.config.procfileScript; + }); + devShells = forEachSystem + (system: + let + pkgs = nixpkgs.legacyPackages.${system}; + in + { + default = devenv.lib.mkShell { + inherit inputs pkgs; + modules = [ + { + packages = [ + pkgs.overmind + (pkgs.writeScriptBin "dev" "${builtins.readFile ./dev.sh}") + ]; + env = { + DJANGO_SETTINGS_MODULE = "network_inventory.settings.local"; + PYTHON_KEYRING_BACKEND = "keyring.backends.fail.Keyring"; + }; + languages.python = { + enable = true; + package = pkgs.python310; + poetry = { + activate.enable = true; + enable = true; + install.enable = true; + }; + }; + processes.webserver.exec = "poetry run python ./src/manage.py runserver 0.0.0.0:$WEBPORT"; + services.postgres = { + enable = true; + initialDatabases = [{ name = "django"; }]; + package = pkgs.postgresql_15; + }; + } + ]; + }; + }); + }; +}