···13131414For other versions such as daily builds (beta and nightly),
1515use either `rustup` from nixpkgs (which will manage the rust installation in your home directory),
1616-or use Mozilla's [Rust nightlies overlay](#using-the-rust-nightlies-overlay).
1616+or use a community maintained [Rust overlay](#using-community-rust-overlays).
17171818## Compiling Rust applications with Cargo {#compiling-rust-applications-with-cargo}
1919···900900901901To see that you are using nightly.
902902903903-## Using the Rust nightlies overlay {#using-the-rust-nightlies-overlay}
903903+## Using community Rust overlays {#using-community-rust-overlays}
904904905905-Mozilla provides an overlay for nixpkgs to bring a nightly version of Rust into scope.
906906-This overlay can _also_ be used to install recent unstable or stable versions
907907-of Rust, if desired.
905905+There are two community maintained approaches to Rust toolchain management:
906906+- [oxalica's Rust overlay](https://github.com/oxalica/rust-overlay)
907907+- [fenix](https://github.com/nix-community/fenix)
908908909909-### Rust overlay installation {#rust-overlay-installation}
909909+Oxalica's overlay allows you to select a particular Rust version and components.
910910+See [their documentation](https://github.com/oxalica/rust-overlay#rust-overlay) for more
911911+detailed usage.
910912911911-You can use this overlay by either changing your local nixpkgs configuration,
912912-or by adding the overlay declaratively in a nix expression, e.g. in `configuration.nix`.
913913-For more information see [the manual on installing overlays](#sec-overlays-install).
913913+Fenix is an alternative to `rustup` and can also be used as an overlay.
914914915915-#### Imperative rust overlay installation {#imperative-rust-overlay-installation}
915915+Both Oxalica's overlay and fenix better integrate with nix and cache optimizations.
916916+Because of this and ergonomics, either of those community projects
917917+should be preferred to the Mozilla's Rust overlay (nixpkgs-mozilla).
916918917917-Clone [nixpkgs-mozilla](https://github.com/mozilla/nixpkgs-mozilla),
918918-and create a symbolic link to the file
919919-[rust-overlay.nix](https://github.com/mozilla/nixpkgs-mozilla/blob/master/rust-overlay.nix)
920920-in the `~/.config/nixpkgs/overlays` directory.
919919+### How to select a specific rustc and toolchain version {#how-to-select-a-specific-rustc-and-toolchain-version}
921920922922-```ShellSession
923923-$ git clone https://github.com/mozilla/nixpkgs-mozilla.git
924924-$ mkdir -p ~/.config/nixpkgs/overlays
925925-$ ln -s $(pwd)/nixpkgs-mozilla/rust-overlay.nix ~/.config/nixpkgs/overlays/rust-overlay.nix
921921+You can consume the oxalica overlay and use it to grab a specific Rust toolchain version.
922922+Here is an example `shell.nix` showing how to grab the current stable toolchain:
923923+```nix
924924+{ pkgs ? import <nixpkgs> {
925925+ overlays = [
926926+ (import (fetchTarball "https://github.com/oxalica/rust-overlay/archive/master.tar.gz"))
927927+ ];
928928+ }
929929+}:
930930+pkgs.mkShell {
931931+ nativeBuildInputs = with pkgs; [
932932+ pkg-config
933933+ rust-bin.stable.latest.minimal
934934+ ];
935935+}
926936```
927937928928-### Declarative rust overlay installation {#declarative-rust-overlay-installation}
938938+You can try this out by:
939939+1. Saving that to `shell.nix`
940940+2. Executing `nix-shell --pure --command 'rustc --version'`
941941+942942+As of writing, this prints out `rustc 1.56.0 (09c42c458 2021-10-18)`.
929943930930-Add the following to your `configuration.nix`, `home-configuration.nix`, `shell.nix`, or similar:
944944+### How to use an overlay toolchain in a derivation {#how-to-use-an-overlay-toolchain-in-a-derivation}
931945946946+You can also use an overlay's Rust toolchain with `buildRustPackage`.
947947+The below snippet demonstrates invoking `buildRustPackage` with an oxalica overlay selected Rust toolchain:
932948```nix
933933-{ pkgs ? import <nixpkgs> {
934934- overlays = [
935935- (import (builtins.fetchTarball https://github.com/mozilla/nixpkgs-mozilla/archive/master.tar.gz))
936936- # Further overlays go here
937937- ];
938938- };
949949+with import <nixpkgs> {
950950+ overlays = [
951951+ (import (fetchTarball "https://github.com/oxalica/rust-overlay/archive/master.tar.gz"))
952952+ ];
939953};
940940-```
954954+955955+rustPlatform.buildRustPackage rec {
956956+ pname = "ripgrep";
957957+ version = "12.1.1";
958958+ nativeBuildInputs = [
959959+ rust-bin.stable.latest.minimal
960960+ ];
941961942942-Note that this will fetch the latest overlay version when rebuilding your system.
962962+ src = fetchFromGitHub {
963963+ owner = "BurntSushi";
964964+ repo = "ripgrep";
965965+ rev = version;
966966+ sha256 = "1hqps7l5qrjh9f914r5i6kmcz6f1yb951nv4lby0cjnp5l253kps";
967967+ };
943968944944-### Rust overlay usage {#rust-overlay-usage}
969969+ cargoSha256 = "03wf9r2csi6jpa7v5sw5lpxkrk4wfzwmzx7k3991q3bdjzcwnnwp";
945970946946-The overlay contains attribute sets corresponding to different versions of the rust toolchain, such as:
971971+ meta = with lib; {
972972+ description = "A fast line-oriented regex search tool, similar to ag and ack";
973973+ homepage = "https://github.com/BurntSushi/ripgrep";
974974+ license = licenses.unlicense;
975975+ maintainers = [ maintainers.tailhook ];
976976+ };
977977+}
978978+```
947979948948-* `latest.rustChannels.stable`
949949-* `latest.rustChannels.nightly`
950950-* a function `rustChannelOf`, called as `(rustChannelOf { date = "2018-04-11"; channel = "nightly"; })`, or...
951951-* `(nixpkgs.rustChannelOf { rustToolchain = ./rust-toolchain; })` if you have a local `rust-toolchain` file (see https://github.com/mozilla/nixpkgs-mozilla#using-in-nix-expressions for an example)
980980+Follow the below steps to try that snippet.
981981+1. create a new directory
982982+1. save the above snippet as `default.nix` in that directory
983983+1. cd into that directory and run `nix-build`
952984953953-Each of these contain packages such as `rust`, which contains your usual rust development tools with the respective toolchain chosen.
954954-For example, you might want to add `latest.rustChannels.stable.rust` to the list of packages in your configuration.
985985+### Rust overlay installation {#rust-overlay-installation}
955986956956-Imperatively, the latest stable version can be installed with the following command:
987987+You can use this overlay by either changing your local nixpkgs configuration,
988988+or by adding the overlay declaratively in a nix expression, e.g. in `configuration.nix`.
989989+For more information see [the manual on installing overlays](#sec-overlays-install).
957990958958-```ShellSession
959959-$ nix-env -Ai nixpkgs.latest.rustChannels.stable.rust
960960-```
991991+### Declarative Rust overlay installation {#declarative-rust-overlay-installation}
961992962962-Or using the attribute with nix-shell:
993993+This snippet shows how to use oxalica's Rust overlay.
994994+Add the following to your `configuration.nix`, `home-configuration.nix`, `shell.nix`, or similar:
963995964964-```ShellSession
965965-$ nix-shell -p nixpkgs.latest.rustChannels.stable.rust
996996+```nix
997997+{ pkgs ? import <nixpkgs> {
998998+ overlays = [
999999+ (import (builtins.fetchTarball "https://github.com/oxalica/rust-overlay/archive/master.tar.gz"))
10001000+ # Further overlays go here
10011001+ ];
10021002+ };
10031003+};
9661004```
9671005968968-Substitute the `nixpkgs` prefix with `nixos` on NixOS.
969969-To install the beta or nightly channel, "stable" should be substituted by
970970-"nightly" or "beta", or
971971-use the function provided by this overlay to pull a version based on a
972972-build date.
973973-974974-The overlay automatically updates itself as it uses the same source as
975975-[rustup](https://www.rustup.rs/).
10061006+Note that this will fetch the latest overlay version when rebuilding your system.
···17561756 </listitem>
17571757 <listitem>
17581758 <para>
17591759+ A new option
17601760+ <literal>services.prometheus.enableReload</literal> has been
17611761+ added which can be enabled to reload the prometheus service
17621762+ when its config file changes instead of restarting.
17631763+ </para>
17641764+ </listitem>
17651765+ <listitem>
17661766+ <para>
17591767 Dokuwiki now supports caddy! However
17601768 </para>
17611769 <itemizedlist spacing="compact">
+2
nixos/doc/manual/release-notes/rl-2111.section.md
···497497498498- The `cawbird` Twitter client now uses its own API keys to count as different application than upstream builds. This is done to evade application-level rate limiting. While existing accounts continue to work, users may want to remove and re-register their account in the client to enjoy a better user experience and benefit from this change.
499499500500+- A new option `services.prometheus.enableReload` has been added which can be enabled to reload the prometheus service when its config file changes instead of restarting.
501501+500502- Dokuwiki now supports caddy! However
501503 - the nginx option has been removed, in the new configuration, please use the `dokuwiki.webserver = "nginx"` instead.
502504 - The "${hostname}" option has been deprecated, please use `dokuwiki.sites = [ "${hostname}" ]` instead
···7788 workingDir = "/var/lib/" + cfg.stateDir;
991010+ prometheusYmlOut = "${workingDir}/prometheus-substituted.yaml";
1111+1212+ writeConfig = pkgs.writeShellScriptBin "write-prometheus-config" ''
1313+ PATH="${makeBinPath (with pkgs; [ coreutils envsubst ])}"
1414+ touch '${prometheusYmlOut}'
1515+ chmod 600 '${prometheusYmlOut}'
1616+ envsubst -o '${prometheusYmlOut}' -i '${prometheusYml}'
1717+ '';
1818+1919+ triggerReload = pkgs.writeShellScriptBin "trigger-reload-prometheus" ''
2020+ PATH="${makeBinPath (with pkgs; [ systemd ])}"
2121+ if systemctl -q is-active prometheus.service; then
2222+ systemctl reload prometheus.service
2323+ fi
2424+ '';
2525+2626+ reload = pkgs.writeShellScriptBin "reload-prometheus" ''
2727+ PATH="${makeBinPath (with pkgs; [ systemd coreutils gnugrep ])}"
2828+ cursor=$(journalctl --show-cursor -n0 | grep -oP "cursor: \K.*")
2929+ kill -HUP $MAINPID
3030+ journalctl -u prometheus.service --after-cursor="$cursor" -f \
3131+ | grep -m 1 "Completed loading of configuration file" > /dev/null
3232+ '';
3333+1034 # a wrapper that verifies that the configuration is valid
1135 promtoolCheck = what: name: file:
1236 if cfg.checkConfig then
···47714872 cmdlineArgs = cfg.extraFlags ++ [
4973 "--storage.tsdb.path=${workingDir}/data/"
5050- "--config.file=/run/prometheus/prometheus-substituted.yaml"
7474+ "--config.file=${
7575+ if cfg.enableReload
7676+ then prometheusYmlOut
7777+ else "/run/prometheus/prometheus-substituted.yaml"
7878+ }"
5179 "--web.listen-address=${cfg.listenAddress}:${builtins.toString cfg.port}"
5280 "--alertmanager.notification-queue-capacity=${toString cfg.alertmanagerNotificationQueueCapacity}"
5381 "--alertmanager.timeout=${toString cfg.alertmanagerTimeout}s"
···731759 '';
732760 };
733761762762+ enableReload = mkOption {
763763+ default = false;
764764+ type = types.bool;
765765+ description = ''
766766+ Reload prometheus when configuration file changes (instead of restart).
767767+768768+ The following property holds: switching to a configuration
769769+ (<literal>switch-to-configuration</literal>) that changes the prometheus
770770+ configuration only finishes successully when prometheus has finished
771771+ loading the new configuration.
772772+773773+ Note that prometheus will also get reloaded when the location of the
774774+ <option>environmentFile</option> changes but not when its contents
775775+ changes. So when you change it contents make sure to reload prometheus
776776+ manually or include the hash of <option>environmentFile</option> in its
777777+ name.
778778+ '';
779779+ };
780780+734781 environmentFile = mkOption {
735782 type = types.nullOr types.path;
736783 default = null;
···928975 systemd.services.prometheus = {
929976 wantedBy = [ "multi-user.target" ];
930977 after = [ "network.target" ];
931931- preStart = ''
978978+ preStart = mkIf (!cfg.enableReload) ''
932979 ${lib.getBin pkgs.envsubst}/bin/envsubst -o "/run/prometheus/prometheus-substituted.yaml" \
933980 -i "${prometheusYml}"
934981 '';
···936983 ExecStart = "${cfg.package}/bin/prometheus" +
937984 optionalString (length cmdlineArgs != 0) (" \\\n " +
938985 concatStringsSep " \\\n " cmdlineArgs);
986986+ ExecReload = mkIf cfg.enableReload "+${reload}/bin/reload-prometheus";
939987 User = "prometheus";
940988 Restart = "always";
941941- EnvironmentFile = mkIf (cfg.environmentFile != null) [ cfg.environmentFile ];
989989+ EnvironmentFile = mkIf (cfg.environmentFile != null && !cfg.enableReload) [ cfg.environmentFile ];
942990 RuntimeDirectory = "prometheus";
943991 RuntimeDirectoryMode = "0700";
944992 WorkingDirectory = workingDir;
945993 StateDirectory = cfg.stateDir;
946994 StateDirectoryMode = "0700";
995995+ };
996996+ };
997997+ systemd.services.prometheus-config-write = mkIf cfg.enableReload {
998998+ wantedBy = [ "prometheus.service" ];
999999+ before = [ "prometheus.service" ];
10001000+ serviceConfig = {
10011001+ Type = "oneshot";
10021002+ User = "prometheus";
10031003+ StateDirectory = cfg.stateDir;
10041004+ StateDirectoryMode = "0700";
10051005+ EnvironmentFile = mkIf (cfg.environmentFile != null) [ cfg.environmentFile ];
10061006+ ExecStart = "${writeConfig}/bin/write-prometheus-config";
10071007+ };
10081008+ };
10091009+ # prometheus-config-reload will activate after prometheus. However, what we
10101010+ # don't want is that on startup it immediately reloads prometheus because
10111011+ # prometheus itself might have just started.
10121012+ #
10131013+ # Instead we only want to reload prometheus when the config file has
10141014+ # changed. So on startup prometheus-config-reload will just output a
10151015+ # harmless message and then stay active (RemainAfterExit).
10161016+ #
10171017+ # Then, when the config file has changed, switch-to-configuration notices
10181018+ # that this service has changed and needs to be reloaded
10191019+ # (reloadIfChanged). The reload command then actually writes the new config
10201020+ # and reloads prometheus.
10211021+ systemd.services.prometheus-config-reload = mkIf cfg.enableReload {
10221022+ wantedBy = [ "prometheus.service" ];
10231023+ after = [ "prometheus.service" ];
10241024+ reloadIfChanged = true;
10251025+ serviceConfig = {
10261026+ Type = "oneshot";
10271027+ User = "prometheus";
10281028+ StateDirectory = cfg.stateDir;
10291029+ StateDirectoryMode = "0700";
10301030+ EnvironmentFile = mkIf (cfg.environmentFile != null) [ cfg.environmentFile ];
10311031+ RemainAfterExit = true;
10321032+ TimeoutSec = 60;
10331033+ ExecStart = "${pkgs.logger}/bin/logger 'prometheus-config-reload will only reload prometheus when reloaded itself.'";
10341034+ ExecReload = [
10351035+ "${writeConfig}/bin/write-prometheus-config"
10361036+ "+${triggerReload}/bin/trigger-reload-prometheus"
10371037+ ];
9471038 };
9481039 };
9491040 };
+6
nixos/modules/system/etc/setup-etc.pl
···138138# Rewrite /etc/.clean.
139139close CLEAN;
140140write_file("/etc/.clean", map { "$_\n" } @copied);
141141+142142+# Create /etc/NIXOS tag if not exists.
143143+# When /etc is not on a persistent filesystem, it will be wiped after reboot,
144144+# so we need to check and re-create it during activation.
145145+open TAG, ">>/etc/NIXOS";
146146+close TAG;
+100
nixos/tests/prometheus.nix
···4141 networking.firewall.allowedTCPPorts = [ grpcPort ];
4242 services.prometheus = {
4343 enable = true;
4444+ enableReload = true;
4445 scrapeConfigs = [
4546 {
4647 job_name = "prometheus";
···118119 # };
119120 #};
120121 };
122122+ # Adds a "specialisation" of the above config which allows us to
123123+ # "switch" to it and see if the services.prometheus.enableReload
124124+ # functionality actually reloads the prometheus service instead of
125125+ # restarting it.
126126+ specialisation = {
127127+ "prometheus-config-change" = {
128128+ configuration = {
129129+ environment.systemPackages = [ pkgs.yq ];
130130+131131+ # This configuration just adds a new prometheus job
132132+ # to scrape the node_exporter metrics of the s3 machine.
133133+ # We also use an environmentFile to test if that works correctly.
134134+ services.prometheus = {
135135+ environmentFile = pkgs.writeText "prometheus-config-env-file" ''
136136+ JOB_NAME=s3-node_exporter
137137+ '';
138138+ scrapeConfigs = [
139139+ {
140140+ job_name = "$JOB_NAME";
141141+ static_configs = [
142142+ {
143143+ targets = [ "s3:9100" ];
144144+ }
145145+ ];
146146+ }
147147+ ];
148148+ };
149149+ };
150150+ };
151151+ };
121152 };
122153123154 query = { pkgs, ... }: {
···171202 };
172203173204 environment.systemPackages = [ pkgs.minio-client ];
205205+206206+ services.prometheus.exporters.node = {
207207+ enable = true;
208208+ openFirewall = true;
209209+ };
174210 };
175211 };
176212177213 testScript = { nodes, ... } : ''
214214+ import json
215215+178216 # Before starting the other machines we first make sure that our S3 service is online
179217 # and has a bucket added for thanos:
180218 s3.start()
···193231194232 # Check if prometheus responds to requests:
195233 prometheus.wait_for_unit("prometheus.service")
234234+235235+ # Check if prometheus' config file is correctly locked down because it could contain secrets.
236236+ prometheus.succeed(
237237+ "stat -c '%a %U' /var/lib/prometheus2/prometheus-substituted.yaml | grep '600 prometheus'"
238238+ )
239239+196240 prometheus.wait_for_open_port(${toString queryPort})
197241 prometheus.succeed("curl -sf http://127.0.0.1:${toString queryPort}/metrics")
198242···245289 + "jq .thanos.labels.some_label | "
246290 + "grep 'required by thanos'"
247291 )
292292+293293+ # Check if switching to a NixOS configuration that changes the prometheus
294294+ # configuration reloads (instead of restarts) prometheus before the switch
295295+ # finishes successfully:
296296+ with subtest("config change reloads prometheus"):
297297+ # We check if prometheus has finished reloading by looking for the message
298298+ # "Completed loading of configuration file" in the journal between the start
299299+ # and finish of switching to the new NixOS configuration.
300300+ #
301301+ # To mark the start we record the journal cursor before starting the switch:
302302+ cursor_before_switching = json.loads(
303303+ prometheus.succeed("journalctl -n1 -o json --output-fields=__CURSOR")
304304+ )["__CURSOR"]
305305+306306+ # Now we switch:
307307+ prometheus_config_change = prometheus.succeed(
308308+ "readlink /run/current-system/specialisation/prometheus-config-change"
309309+ ).strip()
310310+ prometheus.succeed(prometheus_config_change + "/bin/switch-to-configuration test")
311311+312312+ # Next we retrieve all logs since the start of switching:
313313+ logs_after_starting_switching = prometheus.succeed(
314314+ """
315315+ journalctl --after-cursor='{cursor_before_switching}' -o json --output-fields=MESSAGE
316316+ """.format(
317317+ cursor_before_switching=cursor_before_switching
318318+ )
319319+ )
320320+321321+ # Finally we check if the message "Completed loading of configuration file"
322322+ # occurs before the "finished switching to system configuration" message:
323323+ finished_switching_msg = (
324324+ "finished switching to system configuration " + prometheus_config_change
325325+ )
326326+ reloaded_before_switching_finished = False
327327+ finished_switching = False
328328+ for log_line in logs_after_starting_switching.split("\n"):
329329+ msg = json.loads(log_line)["MESSAGE"]
330330+ if "Completed loading of configuration file" in msg:
331331+ reloaded_before_switching_finished = True
332332+ if msg == finished_switching_msg:
333333+ finished_switching = True
334334+ break
335335+336336+ assert reloaded_before_switching_finished
337337+ assert finished_switching
338338+339339+ # Check if the reloaded config includes the new s3-node_exporter job:
340340+ prometheus.succeed(
341341+ """
342342+ curl -sf http://127.0.0.1:${toString queryPort}/api/v1/status/config \
343343+ | jq -r .data.yaml \
344344+ | yq '.scrape_configs | any(.job_name == "s3-node_exporter")' \
345345+ | grep true
346346+ """
347347+ )
248348 '';
249349}
···11+{ lib
22+, buildGoPackage
33+, fetchFromGitHub
44+}:
55+66+buildGoPackage rec {
77+ pname = "go-mk";
88+ version = "0.pre+date=2015-03-24";
99+1010+ src = fetchFromGitHub {
1111+ owner = "dcjones";
1212+ repo = "mk";
1313+ rev = "73d1b31466c16d0a13a220e5fad7cd8ef6d984d1";
1414+ hash = "sha256-fk2Qd3LDMx+RapKi1M9yCuxpS0IB6xlbEWW+H6t94AI=";
1515+ };
1616+1717+ goPackagePath = "github.com/dcjones/mk";
1818+1919+ meta = with lib; {
2020+ inherit (src.meta) homepage;
2121+ description = "A reboot of Plan9's mk, written in Go";
2222+ longDescription = ''
2323+ Mk is a reboot of the Plan 9 mk command, which itself is a successor to
2424+ make. This tool is for anyone who loves make, but hates all its stupid
2525+ bullshit.
2626+ '';
2727+ license = licenses.bsd2;
2828+ maintainers = with maintainers; [ AndersonTorres ];
2929+ platforms = platforms.unix;
3030+ };
3131+}