diff --git a/nixos/doc/manual/release-notes/rl-2505.section.md b/nixos/doc/manual/release-notes/rl-2505.section.md index f9cc4337af7e..2ef9de7cb51c 100644 --- a/nixos/doc/manual/release-notes/rl-2505.section.md +++ b/nixos/doc/manual/release-notes/rl-2505.section.md @@ -578,6 +578,8 @@ - GOverlay has been updated to 1.2, please check the [upstream changelog](https://github.com/benjamimgois/goverlay/releases) for more details. +- [`services.geoclue2`](#opt-services.geoclue2.enable) now has an `enableStatic` option, which allows the NixOS configuration to specify a fixed location for GeoClue to use. + - [`services.mongodb`](#opt-services.mongodb.enable) is now compatible with the `mongodb-ce` binary package. To make use of it, set [`services.mongodb.package`](#opt-services.mongodb.package) to `pkgs.mongodb-ce`. - [`services.jupyter`](#opt-services.jupyter.enable) is now compatible with `Jupyter Notebook 7`. See [the migration guide](https://jupyter-notebook.readthedocs.io/en/latest/migrate_to_notebook7.html) for details. diff --git a/nixos/modules/services/desktops/geoclue2.nix b/nixos/modules/services/desktops/geoclue2.nix index 16d1cb17ca06..bc5d52f9e374 100644 --- a/nixos/modules/services/desktops/geoclue2.nix +++ b/nixos/modules/services/desktops/geoclue2.nix @@ -136,6 +136,48 @@ in ''; }; + enableStatic = lib.mkOption { + type = lib.types.bool; + default = false; + description = '' + Whether to enable the static source. This source defines a fixed + location using the `staticLatitude`, `staticLongitude`, + `staticAltitude`, and `staticAccuracy` options. + + Setting `enableStatic` to true will disable all other sources, to + prevent conflicts. Use `lib.mkForce true` when enabling other sources + if for some reason you want to override this. + ''; + }; + + staticLatitude = lib.mkOption { + type = lib.types.numbers.between (-90) 90; + description = '' + Latitude to use for the static source. Defaults to `location.latitude`. + ''; + }; + + staticLongitude = lib.mkOption { + type = lib.types.numbers.between (-180) 180; + description = '' + Longitude to use for the static source. Defaults to `location.longitude`. + ''; + }; + + staticAltitude = lib.mkOption { + type = lib.types.number; + description = '' + Altitude in meters to use for the static source. + ''; + }; + + staticAccuracy = lib.mkOption { + type = lib.types.numbers.positive; + description = '' + Accuracy radius in meters to use for the static source. + ''; + }; + geoProviderUrl = lib.mkOption { type = lib.types.str; default = "https://location.services.mozilla.com/v1/geolocate?key=geoclue"; @@ -224,6 +266,16 @@ in groups.geoclue = { }; }; + services.geoclue2 = { + enable3G = lib.mkIf cfg.enableStatic false; + enableCDMA = lib.mkIf cfg.enableStatic false; + enableModemGPS = lib.mkIf cfg.enableStatic false; + enableNmea = lib.mkIf cfg.enableStatic false; + enableWifi = lib.mkIf cfg.enableStatic false; + staticLatitude = lib.mkDefault config.location.latitude; + staticLongitude = lib.mkDefault config.location.longitude; + }; + systemd.services.geoclue = { wants = lib.optionals cfg.enableWifi [ "network-online.target" ]; after = lib.optionals cfg.enableWifi [ "network-online.target" ]; @@ -284,16 +336,33 @@ in modem-gps = { enable = cfg.enableModemGPS; }; - wifi = { - enable = cfg.enableWifi; - url = cfg.geoProviderUrl; - submit-data = lib.boolToString cfg.submitData; - submission-url = cfg.submissionUrl; - submission-nick = cfg.submissionNick; + wifi = + { + enable = cfg.enableWifi; + } + // lib.optionalAttrs cfg.enableWifi { + url = cfg.geoProviderUrl; + submit-data = lib.boolToString cfg.submitData; + submission-url = cfg.submissionUrl; + submission-nick = cfg.submissionNick; + }; + static-source = { + enable = cfg.enableStatic; }; } // lib.mapAttrs' appConfigToINICompatible cfg.appConfig ); + + environment.etc.geolocation = lib.mkIf cfg.enableStatic { + mode = "0440"; + group = "geoclue"; + text = '' + ${toString cfg.staticLatitude} + ${toString cfg.staticLongitude} + ${toString cfg.staticAltitude} + ${toString cfg.staticAccuracy} + ''; + }; }; meta = with lib; { diff --git a/nixos/tests/all-tests.nix b/nixos/tests/all-tests.nix index ca3b04135b4f..b70683de021e 100644 --- a/nixos/tests/all-tests.nix +++ b/nixos/tests/all-tests.nix @@ -455,6 +455,7 @@ in { garage = handleTest ./garage {}; gatus = runTest ./gatus.nix; gemstash = handleTest ./gemstash.nix {}; + geoclue2 = runTest ./geoclue2.nix; geoserver = runTest ./geoserver.nix; gerrit = handleTest ./gerrit.nix {}; geth = handleTest ./geth.nix {}; diff --git a/nixos/tests/geoclue2.nix b/nixos/tests/geoclue2.nix new file mode 100644 index 000000000000..0a2f311c286f --- /dev/null +++ b/nixos/tests/geoclue2.nix @@ -0,0 +1,36 @@ +{ config, lib, ... }: +{ + name = "geoclue2"; + meta = { + maintainers = with lib.maintainers; [ rhendric ]; + }; + + nodes.machine = { + imports = [ common/user-account.nix ]; + + location = { + latitude = 12.345; + longitude = -67.890; + }; + + services.geoclue2 = { + enable = true; + enableDemoAgent = true; + enableStatic = true; + staticAltitude = 123.45; + staticAccuracy = 1000; + }; + }; + + testScript = + let + inherit (config.node) pkgs; + in + '' + whereAmI = machine.succeed('machinectl shell alice@.host ${pkgs.geoclue2}/libexec/geoclue-2.0/demos/where-am-i -t 5') + assert ("Latitude: 12.345000°" in whereAmI), f"Incorrect latitude in:\n{whereAmI}" + assert ("Longitude: -67.890000°" in whereAmI), f"Incorrect longitude in:\n{whereAmI}" + assert ("Altitude: 123.450000 meters" in whereAmI), f"Incorrect altitude in:\n{whereAmI}" + assert ("Accuracy: 1000.000000 meters" in whereAmI), f"Incorrect accuracy in:\n{whereAmI}" + ''; +} diff --git a/pkgs/by-name/ge/geoclue2/add-option-for-installation-sysconfdir.patch b/pkgs/by-name/ge/geoclue2/add-option-for-installation-sysconfdir.patch index 11bd6f561c8b..2d2ccbd5c4ba 100644 --- a/pkgs/by-name/ge/geoclue2/add-option-for-installation-sysconfdir.patch +++ b/pkgs/by-name/ge/geoclue2/add-option-for-installation-sysconfdir.patch @@ -2,14 +2,6 @@ diff --git a/data/meson.build b/data/meson.build index b22ff55..01c5910 100644 --- a/data/meson.build +++ b/data/meson.build -@@ -1,6 +1,6 @@ - if get_option('enable-backend') - conf = configuration_data() -- conf.set('sysconfdir', sysconfdir) -+ conf.set('sysconfdir', sysconfdir_install) - - if get_option('demo-agent') - conf.set('demo_agent', 'geoclue-demo-agent;') @@ -14,7 +14,7 @@ if get_option('enable-backend') conf.set('default_wifi_enable', 'false') endif @@ -19,15 +11,6 @@ index b22ff55..01c5910 100644 configure_file(output: 'geoclue.conf', input: 'geoclue.conf.in', configuration: conf, -@@ -23,7 +23,7 @@ if get_option('enable-backend') - conf = configuration_data() - conf.set('libexecdir', libexecdir) - conf.set('dbus_srv_user', get_option('dbus-srv-user')) -- conf.set('sysconfdir', sysconfdir) -+ conf.set('sysconfdir', sysconfdir_install) - - confd_dir = join_paths(conf_dir, 'conf.d') - install_emptydir(confd_dir) diff --git a/demo/meson.build b/demo/meson.build index 1427fbe..2623f16 100644 --- a/demo/meson.build diff --git a/pkgs/by-name/ge/geoclue2/package.nix b/pkgs/by-name/ge/geoclue2/package.nix index cb6e524a9cb8..0abca745cb33 100644 --- a/pkgs/by-name/ge/geoclue2/package.nix +++ b/pkgs/by-name/ge/geoclue2/package.nix @@ -24,6 +24,7 @@ vala, withDemoAgent ? false, nix-update-script, + nixosTests, }: stdenv.mkDerivation (finalAttrs: { @@ -107,7 +108,12 @@ stdenv.mkDerivation (finalAttrs: { patchShebangs demo/install-file.py ''; - passthru.updateScript = nix-update-script { }; + passthru = { + tests = { + inherit (nixosTests) geoclue2; + }; + updateScript = nix-update-script { }; + }; meta = with lib; { broken = stdenv.hostPlatform.isDarwin && withDemoAgent;