fix(nix): install writable home-manager config instead of store symlink

The Home Manager module symlinked ~/.omp/agent/config.yml to a read-only
/nix/store path. OMP acquires an advisory lock on and atomically rewrites
its config when persisting runtime changes; on macOS the lock backend
creates an flock sidecar next to the target, so the first startup save
failed with "Failed to acquire native file lock ... Permission denied
(os error 13)", breaking every launch once programs.omp.settings was set.

Copy the generated config into place as a writable regular file via
home.activation instead. OMP can now lock and rewrite it, and the next
home-manager switch reapplies the declared settings. The DAG entry is
written literally so the home-manager-free module evaluation in flake.nix
keeps working; that check now asserts the activation entry.

Fixes #8775
This commit is contained in:
roboomp
2026-08-17 00:44:52 +00:00
parent 37eee71978
commit 5d5c901c21
3 changed files with 27 additions and 6 deletions
+2 -2
View File
@@ -125,7 +125,7 @@
type = pkgs.lib.types.listOf pkgs.lib.types.package; type = pkgs.lib.types.listOf pkgs.lib.types.package;
default = [ ]; default = [ ];
}; };
options.home.file = pkgs.lib.mkOption { options.home.activation = pkgs.lib.mkOption {
type = pkgs.lib.types.attrsOf pkgs.lib.types.anything; type = pkgs.lib.types.attrsOf pkgs.lib.types.anything;
default = { }; default = { };
}; };
@@ -152,7 +152,7 @@
}; };
modulesEvaluate = modulesEvaluate =
assert builtins.elem self.packages.${system}.default homeManagerEvaluation.config.home.packages; assert builtins.elem self.packages.${system}.default homeManagerEvaluation.config.home.packages;
assert homeManagerEvaluation.config.home.file ? ".omp/agent/config.yml"; assert homeManagerEvaluation.config.home.activation ? ompConfig;
assert builtins.elem self.packages.${system}.default assert builtins.elem self.packages.${system}.default
nixosEvaluation.config.environment.systemPackages; nixosEvaluation.config.environment.systemPackages;
pkgs.runCommand "omp-module-evaluation" { } "touch $out"; pkgs.runCommand "omp-module-evaluation" { } "touch $out";
+21 -4
View File
@@ -8,6 +8,7 @@
let let
cfg = config.programs.omp; cfg = config.programs.omp;
yaml = pkgs.formats.yaml { }; yaml = pkgs.formats.yaml { };
configFile = yaml.generate "omp-config.yml" cfg.settings;
in in
{ {
options.programs.omp = { options.programs.omp = {
@@ -25,8 +26,11 @@ in
default = null; default = null;
description = '' description = ''
Settings written declaratively to {file}`~/.omp/agent/config.yml`. Settings written declaratively to {file}`~/.omp/agent/config.yml`.
The file is a read-only store symlink: changes made from inside OMP On each `home-manager switch` the declared settings are copied into
(`/settings`, onboarding) replace it but revert on the next place as a writable regular file (not a read-only store symlink), so
OMP can acquire its config lock and rewrite the file when persisting
runtime changes (`/settings`, onboarding). Those runtime changes are
overwritten by the declared values again on the next
`home-manager switch`. `home-manager switch`.
''; '';
example = { example = {
@@ -38,8 +42,21 @@ in
config = lib.mkIf cfg.enable { config = lib.mkIf cfg.enable {
home.packages = [ cfg.package ]; home.packages = [ cfg.package ];
home.file.".omp/agent/config.yml" = lib.mkIf (cfg.settings != null) {
source = yaml.generate "omp-config.yml" cfg.settings; # OMP rewrites its config at runtime and acquires an advisory lock on it
# first; on macOS the lock backend creates an flock sidecar next to the
# target file. A `home.file` store symlink is read-only and lives under
# /nix/store, so both the lock and the atomic rewrite fail with EACCES and
# break every launch. Copy a writable regular file instead. The DAG entry
# is written literally (rather than via `lib.hm.dag.entryAfter`) so the
# home-manager-free module evaluation in `flake.nix` keeps working.
home.activation.ompConfig = lib.mkIf (cfg.settings != null) {
before = [ ];
after = [ "writeBoundary" ];
data = ''
run mkdir -p "$HOME/.omp/agent"
run install -m 600 ${configFile} "$HOME/.omp/agent/config.yml"
'';
}; };
}; };
} }
+4
View File
@@ -2,6 +2,10 @@
## [Unreleased] ## [Unreleased]
### Fixed
- Fixed the Home Manager module (`programs.omp.settings`) breaking every launch on macOS with `Failed to acquire native file lock … Permission denied (os error 13)`. The declared config is now copied into `~/.omp/agent/config.yml` as a writable file via `home.activation` instead of a read-only `/nix/store` symlink, so OMP can acquire its config lock and persist runtime changes; `home-manager switch` still reapplies the declared settings ([#8775](https://github.com/can1357/oh-my-pi/issues/8775)).
## [17.3.5] - 2026-08-16 ## [17.3.5] - 2026-08-16
### Added ### Added