Files
oott/flake.nix
T

167 lines
6.7 KiB
Nix
Raw Normal View History

2026-01-24 12:16:24 -05:00
{
2026-01-24 15:30:10 -05:00
description = "OOTT - An easy to setup and use network device monitoring service";
2026-01-24 12:16:24 -05:00
inputs = {
nixpkgs.url = "nixpkgs/nixos-unstable";
};
outputs = {
self,
nixpkgs,
}: let
# System types to support.
supportedSystems = ["x86_64-linux"];
# Helper function to generate an attrset '{ x86_64-linux = f "x86_64-linux"; ... }'.
2026-01-25 10:37:47 -05:00
forEachSystem = nixpkgs.lib.genAttrs supportedSystems;
# Package overlays to include
overlayList = [self.overlays.default];
2026-01-24 12:16:24 -05:00
# Nixpkgs instantiated for supported system types.
2026-01-25 10:37:47 -05:00
pkgsBySystem = forEachSystem (system:
import nixpkgs {
inherit system;
overlays = overlayList;
2026-02-11 14:07:27 -05:00
# Front-end specific items
config = {
android_sdk.accept_license = true;
allowUnfree = true;
};
2026-01-25 10:37:47 -05:00
});
in rec {
2026-02-11 14:07:27 -05:00
# Development shell to test the app locally
devShells = forEachSystem (system: let
pythonEnv = pkgsBySystem.${system}.python3.withPackages (ps: [ps.anthropic]);
# Pin the Android SDK composition so the emulator system image is always
# available and reproducible across machines, instead of relying on the
# contents of the default androidPkgs bundle (which can drift over time).
androidComposition = pkgsBySystem.${system}.androidenv.composeAndroidPackages {
# 36 = Flutter 3.41 app compileSdk/targetSdk; 33-35 cover plugin subprojects
# which each pin their own compileSdk (e.g. package_info_plus -> 34, jni -> 35).
platformVersions = ["33" "34" "35" "36"];
buildToolsVersions = ["35.0.0"]; # required by Android Gradle Plugin 8.11.1
includeEmulator = true;
includeSystemImages = true;
systemImageTypes = ["google_apis"];
abiVersions = ["x86_64"];
includeNDK = true;
ndkVersions = ["28.2.13676358"]; # matches Flutter 3.41 flutter.ndkVersion
cmakeVersions = ["3.22.1"]; # required by plugin native (externalNativeBuild) tasks
};
in {
2026-02-11 14:07:27 -05:00
default = pkgsBySystem.${system}.mkShell rec {
androidSdk = androidComposition.androidsdk;
2026-02-11 14:07:27 -05:00
ANDROID_SDK_ROOT = "${androidSdk}/libexec/android-sdk";
nativeBuildInputs = with pkgsBySystem.${system}; [
pkg-config
];
buildInputs = with pkgsBySystem.${system}; [
openssl
rustc
cargo
sqlite
flutter
android-tools
androidSdk
jdk17
2026-05-27 08:24:48 -04:00
claude-code
2026-05-27 14:09:02 -04:00
clippy # Rust linter
pythonEnv
gh # GitHub CLI tool (for release process)
2026-02-11 14:07:27 -05:00
];
2026-02-21 15:10:35 -05:00
# fish > all
shellHook = ''
export PATH="${pythonEnv}/bin:$PATH"
# Create the reproducible Android emulator (AVD) on first entry.
# The system image is pinned by the flake, but an AVD is mutable state
# that lives in ~/.android/avd and cannot reside in the read-only Nix
# store, so we (re)create it here. Idempotent: a no-op once it exists.
export ANDROID_AVD_NAME="oott_api36"
if ! emulator -list-avds 2>/dev/null | grep -qx "$ANDROID_AVD_NAME"; then
echo "Creating Android emulator '$ANDROID_AVD_NAME'..."
echo no | avdmanager create avd \
--name "$ANDROID_AVD_NAME" \
--package "system-images;android-36;google_apis;x86_64" \
--device pixel_6 >/dev/null 2>&1 \
&& echo " Android emulator '$ANDROID_AVD_NAME' ready." \
|| echo " WARNING: failed to create Android emulator '$ANDROID_AVD_NAME'."
fi
# Enable the emulated hardware keyboard so the host keyboard is
# forwarded into the guest. This image always exposes a (phantom)
# hardware keyboard, which makes Gboard hide the on-screen keyboard
# for non-password fields; without host-keyboard forwarding those
# fields are untypable. Enforced on every entry so it also fixes a
# pre-existing AVD, and a changed hardware config makes the emulator
# cold-boot once so the setting takes effect.
avdConfig="$HOME/.android/avd/$ANDROID_AVD_NAME.avd/config.ini"
if [ -f "$avdConfig" ]; then
if grep -q '^hw.keyboard=' "$avdConfig"; then
sed -i 's/^hw.keyboard=.*/hw.keyboard=yes/' "$avdConfig"
else
printf 'hw.keyboard=yes\n' >> "$avdConfig"
fi
fi
# Point the Android Gradle Plugin at the Nix-patched aapt2 shipped in
# the SDK build-tools. AGP otherwise downloads a prebuilt aapt2 from
# Maven that cannot run on NixOS (its ELF interpreter is missing).
# We write this to the user-global Gradle properties because the
# project's android/gradle.properties is version-controlled and must
# not contain a machine-specific Nix store path. The managed block is
# rewritten on every entry so it tracks the pinned SDK store path.
aapt2Bin="$(ls "$ANDROID_SDK_ROOT"/build-tools/*/aapt2 2>/dev/null | sort | tail -n1)"
if [ -n "$aapt2Bin" ]; then
mkdir -p "$HOME/.gradle"
gradleProps="$HOME/.gradle/gradle.properties"
touch "$gradleProps"
sed -i '/# >>> oott-nix >>>/,/# <<< oott-nix <<</d' "$gradleProps"
printf '# >>> oott-nix >>>\nandroid.aapt2FromMavenOverride=%s\n# <<< oott-nix <<<\n' "$aapt2Bin" >> "$gradleProps"
fi
DEV_SHELL=oott exec fish
2026-02-21 15:10:35 -05:00
'';
2026-02-11 14:07:27 -05:00
};
});
# A Nixpkgs overlay that provides the 'oott' package and its bundled front-end.
overlays.default = final: prev: {
oott-frontend = final.callPackage ./nix/frontend.nix {};
oott = final.callPackage ./nix/package.nix {};
};
2026-01-24 19:26:09 -05:00
# Package definition
2026-01-25 10:37:47 -05:00
packages = forEachSystem (system: {
2026-01-25 11:01:11 -05:00
oott = pkgsBySystem.${system}.oott;
default = pkgsBySystem.${system}.oott;
# Docker image generation
# use via 'nix build .#dockerImage'
dockerImage = with pkgsBySystem.${system};
dockerTools.buildLayeredImage {
name = "oott";
tag = "latest";
# oott carries its full runtime closure (incl. the bundled front-end);
# cacert provides the trust store referenced by SSL_CERT_FILE below.
contents = [oott cacert];
# Ensure a writable /tmp exists (no base image provides one).
extraCommands = "mkdir -p tmp";
config = {
Cmd = ["${oott}/bin/oott" "--config" "/config/oott.toml"];
# Let openssl/native-tls (used for Pushover notifications) find the CA bundle.
Env = ["SSL_CERT_FILE=${cacert}/etc/ssl/certs/ca-bundle.crt"];
};
};
2026-01-24 12:16:24 -05:00
});
2026-01-24 14:43:46 -05:00
2026-01-25 10:37:47 -05:00
# Modules definition
2026-01-25 11:01:11 -05:00
nixosModules = import ./nix/modules {overlays = overlayList;};
2026-01-24 12:16:24 -05:00
};
}