diff --git a/nixos/doc/manual/release-notes/rl-2411.section.md b/nixos/doc/manual/release-notes/rl-2411.section.md index f2543ca50135..718bb4baae69 100644 --- a/nixos/doc/manual/release-notes/rl-2411.section.md +++ b/nixos/doc/manual/release-notes/rl-2411.section.md @@ -397,6 +397,12 @@ - The `services.trust-dns` module has been renamed to `services.hickory-dns`. +- The option `services.prometheus.exporters.pgbouncer.connectionStringFile` has been removed since + it leaked the connection string (and thus potentially the DB password) into the cmdline + of process making it effectively world-readable. + + Use [`services.prometheus.exporters.pgbouncer.connectionEnvFile`](#opt-services.prometheus.exporters.pgbouncer.connectionEnvFile) instead. + - The `lsh` package and the `services.lshd` module have been removed as they had no maintainer in Nixpkgs and hadn’t seen an upstream release in over a decade. It is recommended to migrate to `openssh` and `services.openssh`. - `opencv2` and `opencv3` have been removed, as they are obsolete and diff --git a/nixos/maintainers/scripts/ec2/amazon-image.nix b/nixos/maintainers/scripts/ec2/amazon-image.nix index b8a7526120aa..1b3724bfc170 100644 --- a/nixos/maintainers/scripts/ec2/amazon-image.nix +++ b/nixos/maintainers/scripts/ec2/amazon-image.nix @@ -1,50 +1,24 @@ -{ - config, - lib, - pkgs, - ... -}: +{ config, lib, pkgs, ... }: let - inherit (lib) - mkOption - optionalString - types - versionAtLeast - ; + inherit (lib) mkOption optionalString types versionAtLeast; inherit (lib.options) literalExpression; cfg = config.amazonImage; amiBootMode = if config.ec2.efi then "uefi" else "legacy-bios"; - virtualisationOptions = import ../../../modules/virtualisation/virtualisation-options.nix; -in -{ - imports = [ - ../../../modules/virtualisation/amazon-image.nix - virtualisationOptions.diskSize - (lib.mkRenamedOptionModuleWith { - sinceRelease = 2411; - from = [ - "virtualisation" - "amazonImage" - "sizeMB" - ]; - to = [ - "virtualisation" - "diskSize" - ]; - }) - ]; +in { + + imports = [ ../../../modules/virtualisation/amazon-image.nix ]; # Amazon recommends setting this to the highest possible value for a good EBS # experience, which prior to 4.15 was 255. # https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/nvme-ebs-volumes.html#timeout-nvme-ebs-volumes config.boot.kernelParams = - let - timeout = - if versionAtLeast config.boot.kernelPackages.kernel.version "4.15" then "4294967295" else "255"; - in - [ "nvme_core.io_timeout=${timeout}" ]; + let timeout = + if versionAtLeast config.boot.kernelPackages.kernel.version "4.15" + then "4294967295" + else "255"; + in [ "nvme_core.io_timeout=${timeout}" ]; options.amazonImage = { name = mkOption { @@ -60,30 +34,30 @@ in } ] ''; - default = [ ]; + default = []; description = '' This option lists files to be copied to fixed locations in the generated image. Glob patterns work. ''; }; + sizeMB = mkOption { + type = with types; either (enum [ "auto" ]) int; + default = 3072; + example = 8192; + description = "The size in MB of the image"; + }; + format = mkOption { - type = types.enum [ - "raw" - "qcow2" - "vpc" - ]; + type = types.enum [ "raw" "qcow2" "vpc" ]; default = "vpc"; description = "The image format to output"; }; }; - config.virtualisation.diskSize = lib.mkDefault (3 * 1024); - config.virtualisation.diskSizeAutoSupported = !config.ec2.zfs.enable; - - config.system.build.amazonImage = - let - configFile = pkgs.writeText "configuration.nix" '' + config.system.build.amazonImage = let + configFile = pkgs.writeText "configuration.nix" + '' { modulesPath, ... }: { imports = [ "''${modulesPath}/virtualisation/amazon-image.nix" ]; ${optionalString config.ec2.efi '' @@ -96,102 +70,91 @@ in } ''; - zfsBuilder = import ../../../lib/make-multi-disk-zfs-image.nix { - inherit - lib - config - configFile - pkgs - ; - inherit (cfg) contents format name; + zfsBuilder = import ../../../lib/make-multi-disk-zfs-image.nix { + inherit lib config configFile pkgs; + inherit (cfg) contents format name; - includeChannel = true; + includeChannel = true; - bootSize = 1000; # 1G is the minimum EBS volume + bootSize = 1000; # 1G is the minimum EBS volume - rootSize = config.virtualisation.diskSize; - rootPoolProperties = { - ashift = 12; - autoexpand = "on"; - }; - - datasets = config.ec2.zfs.datasets; - - postVM = '' - extension=''${rootDiskImage##*.} - friendlyName=$out/${cfg.name} - rootDisk="$friendlyName.root.$extension" - bootDisk="$friendlyName.boot.$extension" - mv "$rootDiskImage" "$rootDisk" - mv "$bootDiskImage" "$bootDisk" - - mkdir -p $out/nix-support - echo "file ${cfg.format} $bootDisk" >> $out/nix-support/hydra-build-products - echo "file ${cfg.format} $rootDisk" >> $out/nix-support/hydra-build-products - - ${pkgs.jq}/bin/jq -n \ - --arg system_label ${lib.escapeShellArg config.system.nixos.label} \ - --arg system ${lib.escapeShellArg pkgs.stdenv.hostPlatform.system} \ - --arg root_logical_bytes "$(${pkgs.qemu_kvm}/bin/qemu-img info --output json "$rootDisk" | ${pkgs.jq}/bin/jq '."virtual-size"')" \ - --arg boot_logical_bytes "$(${pkgs.qemu_kvm}/bin/qemu-img info --output json "$bootDisk" | ${pkgs.jq}/bin/jq '."virtual-size"')" \ - --arg boot_mode "${amiBootMode}" \ - --arg root "$rootDisk" \ - --arg boot "$bootDisk" \ - '{} - | .label = $system_label - | .boot_mode = $boot_mode - | .system = $system - | .disks.boot.logical_bytes = $boot_logical_bytes - | .disks.boot.file = $boot - | .disks.root.logical_bytes = $root_logical_bytes - | .disks.root.file = $root - ' > $out/nix-support/image-info.json - ''; + rootSize = cfg.sizeMB; + rootPoolProperties = { + ashift = 12; + autoexpand = "on"; }; - extBuilder = import ../../../lib/make-disk-image.nix { - inherit - lib - config - configFile - pkgs - ; + datasets = config.ec2.zfs.datasets; - inherit (cfg) contents format name; + postVM = '' + extension=''${rootDiskImage##*.} + friendlyName=$out/${cfg.name} + rootDisk="$friendlyName.root.$extension" + bootDisk="$friendlyName.boot.$extension" + mv "$rootDiskImage" "$rootDisk" + mv "$bootDiskImage" "$bootDisk" - fsType = "ext4"; - partitionTableType = if config.ec2.efi then "efi" else "legacy+gpt"; + mkdir -p $out/nix-support + echo "file ${cfg.format} $bootDisk" >> $out/nix-support/hydra-build-products + echo "file ${cfg.format} $rootDisk" >> $out/nix-support/hydra-build-products - inherit (config.virtualisation) diskSize; + ${pkgs.jq}/bin/jq -n \ + --arg system_label ${lib.escapeShellArg config.system.nixos.label} \ + --arg system ${lib.escapeShellArg pkgs.stdenv.hostPlatform.system} \ + --arg root_logical_bytes "$(${pkgs.qemu_kvm}/bin/qemu-img info --output json "$rootDisk" | ${pkgs.jq}/bin/jq '."virtual-size"')" \ + --arg boot_logical_bytes "$(${pkgs.qemu_kvm}/bin/qemu-img info --output json "$bootDisk" | ${pkgs.jq}/bin/jq '."virtual-size"')" \ + --arg boot_mode "${amiBootMode}" \ + --arg root "$rootDisk" \ + --arg boot "$bootDisk" \ + '{} + | .label = $system_label + | .boot_mode = $boot_mode + | .system = $system + | .disks.boot.logical_bytes = $boot_logical_bytes + | .disks.boot.file = $boot + | .disks.root.logical_bytes = $root_logical_bytes + | .disks.root.file = $root + ' > $out/nix-support/image-info.json + ''; + }; - postVM = '' - extension=''${diskImage##*.} - friendlyName=$out/${cfg.name}.$extension - mv "$diskImage" "$friendlyName" - diskImage=$friendlyName + extBuilder = import ../../../lib/make-disk-image.nix { + inherit lib config configFile pkgs; - mkdir -p $out/nix-support - echo "file ${cfg.format} $diskImage" >> $out/nix-support/hydra-build-products + inherit (cfg) contents format name; - ${pkgs.jq}/bin/jq -n \ - --arg system_label ${lib.escapeShellArg config.system.nixos.label} \ - --arg system ${lib.escapeShellArg pkgs.stdenv.hostPlatform.system} \ - --arg logical_bytes "$(${pkgs.qemu_kvm}/bin/qemu-img info --output json "$diskImage" | ${pkgs.jq}/bin/jq '."virtual-size"')" \ - --arg boot_mode "${amiBootMode}" \ - --arg file "$diskImage" \ - '{} - | .label = $system_label - | .boot_mode = $boot_mode - | .system = $system - | .logical_bytes = $logical_bytes - | .file = $file - | .disks.root.logical_bytes = $logical_bytes - | .disks.root.file = $file - ' > $out/nix-support/image-info.json - ''; - }; - in - if config.ec2.zfs.enable then zfsBuilder else extBuilder; + fsType = "ext4"; + partitionTableType = if config.ec2.efi then "efi" else "legacy+gpt"; + + diskSize = cfg.sizeMB; + + postVM = '' + extension=''${diskImage##*.} + friendlyName=$out/${cfg.name}.$extension + mv "$diskImage" "$friendlyName" + diskImage=$friendlyName + + mkdir -p $out/nix-support + echo "file ${cfg.format} $diskImage" >> $out/nix-support/hydra-build-products + + ${pkgs.jq}/bin/jq -n \ + --arg system_label ${lib.escapeShellArg config.system.nixos.label} \ + --arg system ${lib.escapeShellArg pkgs.stdenv.hostPlatform.system} \ + --arg logical_bytes "$(${pkgs.qemu_kvm}/bin/qemu-img info --output json "$diskImage" | ${pkgs.jq}/bin/jq '."virtual-size"')" \ + --arg boot_mode "${amiBootMode}" \ + --arg file "$diskImage" \ + '{} + | .label = $system_label + | .boot_mode = $boot_mode + | .system = $system + | .logical_bytes = $logical_bytes + | .file = $file + | .disks.root.logical_bytes = $logical_bytes + | .disks.root.file = $file + ' > $out/nix-support/image-info.json + ''; + }; + in if config.ec2.zfs.enable then zfsBuilder else extBuilder; meta.maintainers = with lib.maintainers; [ arianvp ]; } diff --git a/nixos/maintainers/scripts/openstack/openstack-image-zfs.nix b/nixos/maintainers/scripts/openstack/openstack-image-zfs.nix index 03895b9aa833..9799f333aec0 100644 --- a/nixos/maintainers/scripts/openstack/openstack-image-zfs.nix +++ b/nixos/maintainers/scripts/openstack/openstack-image-zfs.nix @@ -1,37 +1,18 @@ # nix-build '' -A config.system.build.openstackImage --arg configuration "{ imports = [ ./nixos/maintainers/scripts/openstack/openstack-image.nix ]; }" -{ - config, - lib, - pkgs, - ... -}: +{ config, lib, pkgs, ... }: let inherit (lib) mkOption types; copyChannel = true; cfg = config.openstackImage; imageBootMode = if config.openstack.efi then "uefi" else "legacy-bios"; - virtualisationOptions = import ../../../modules/virtualisation/virtualisation-options.nix; in { imports = [ ../../../modules/virtualisation/openstack-config.nix - virtualisationOptions.diskSize - (lib.mkRenamedOptionModuleWith { - sinceRelease = 2411; - from = [ - "virtualisation" - "openstackImage" - "sizeMB" - ]; - to = [ - "virtualisation" - "diskSize" - ]; - }) - ] ++ (lib.optional copyChannel ../../../modules/installer/cd-dvd/channel.nix); + options.openstackImage = { name = mkOption { type = types.str; @@ -41,15 +22,18 @@ in ramMB = mkOption { type = types.int; - default = (3 * 1024); + default = 1024; description = "RAM allocation for build VM"; }; + sizeMB = mkOption { + type = types.int; + default = 8192; + description = "The size in MB of the image"; + }; + format = mkOption { - type = types.enum [ - "raw" - "qcow2" - ]; + type = types.enum [ "raw" "qcow2" ]; default = "qcow2"; description = "The image format to output"; }; @@ -70,26 +54,24 @@ in }; }; - virtualisation.diskSize = lib.mkDefault (8 * 1024); - virtualisation.diskSizeAutoSupported = false; - system.build.openstackImage = import ../../../lib/make-single-disk-zfs-image.nix { inherit lib config; inherit (cfg) contents format name; pkgs = import ../../../.. { inherit (pkgs) system; }; # ensure we use the regular qemu-kvm package - configFile = pkgs.writeText "configuration.nix" '' - { modulesPath, ... }: { - imports = [ "''${modulesPath}/virtualisation/openstack-config.nix" ]; - openstack.zfs.enable = true; - } - ''; + configFile = pkgs.writeText "configuration.nix" + '' + { modulesPath, ... }: { + imports = [ "''${modulesPath}/virtualisation/openstack-config.nix" ]; + openstack.zfs.enable = true; + } + ''; includeChannel = copyChannel; bootSize = 1000; memSize = cfg.ramMB; - rootSize = config.virtualisation.diskSize; + rootSize = cfg.sizeMB; rootPoolProperties = { ashift = 12; autoexpand = "on"; diff --git a/nixos/modules/profiles/macos-builder.nix b/nixos/modules/profiles/macos-builder.nix index 28832d2b7157..bf8414e1e108 100644 --- a/nixos/modules/profiles/macos-builder.nix +++ b/nixos/modules/profiles/macos-builder.nix @@ -1,9 +1,4 @@ -{ - config, - lib, - options, - ... -}: +{ config, lib, options, ... }: let keysDirectory = "/var/keys"; @@ -20,19 +15,6 @@ in imports = [ ../virtualisation/qemu-vm.nix - (lib.mkRenamedOptionModuleWith { - sinceRelease = 2411; - from = [ - "virtualisation" - "darwin-builder" - "diskSize" - ]; - to = [ - "virtualisation" - "diskSize" - ]; - }) - # Avoid a dependency on stateVersion { disabledModules = [ @@ -41,16 +23,17 @@ in ]; # swraid's default depends on stateVersion config.boot.swraid.enable = false; - options.boot.isContainer = lib.mkOption { - default = false; - internal = true; - }; + options.boot.isContainer = lib.mkOption { default = false; internal = true; }; } ]; - options.virtualisation.description = "The maximum disk space allocated to the runner in megabytes"; - options.virtualisation.darwin-builder = with lib; { + diskSize = mkOption { + default = 20 * 1024; + type = types.int; + example = 30720; + description = "The maximum disk space allocated to the runner in MB"; + }; memorySize = mkOption { default = 3 * 1024; type = types.int; @@ -76,13 +59,13 @@ in ''; }; workingDirectory = mkOption { - default = "."; - type = types.str; - example = "/var/lib/darwin-builder"; - description = '' - The working directory to use to run the script. When running - as part of a flake will need to be set to a non read-only filesystem. - ''; + default = "."; + type = types.str; + example = "/var/lib/darwin-builder"; + description = '' + The working directory to use to run the script. When running + as part of a flake will need to be set to a non read-only filesystem. + ''; }; hostPort = mkOption { default = 31022; @@ -175,34 +158,26 @@ in script = hostPkgs.writeShellScriptBin "create-builder" ( '' set -euo pipefail - '' - + - # When running as non-interactively as part of a DarwinConfiguration the working directory - # must be set to a writeable directory. - ( - if cfg.workingDirectory != "." then - '' - ${hostPkgs.coreutils}/bin/mkdir --parent "${cfg.workingDirectory}" - cd "${cfg.workingDirectory}" - '' - else - "" - ) - + '' - KEYS="''${KEYS:-./keys}" - ${hostPkgs.coreutils}/bin/mkdir --parent "''${KEYS}" - PRIVATE_KEY="''${KEYS}/${user}_${keyType}" - PUBLIC_KEY="''${PRIVATE_KEY}.pub" - if [ ! -e "''${PRIVATE_KEY}" ] || [ ! -e "''${PUBLIC_KEY}" ]; then - ${hostPkgs.coreutils}/bin/rm --force -- "''${PRIVATE_KEY}" "''${PUBLIC_KEY}" - ${hostPkgs.openssh}/bin/ssh-keygen -q -f "''${PRIVATE_KEY}" -t ${keyType} -N "" -C 'builder@localhost' - fi - if ! ${hostPkgs.diffutils}/bin/cmp "''${PUBLIC_KEY}" ${publicKey}; then - (set -x; sudo --reset-timestamp ${installCredentials} "''${KEYS}") - fi - KEYS="$(${hostPkgs.nix}/bin/nix-store --add "$KEYS")" ${lib.getExe config.system.build.vm} - '' - ); + '' + + # When running as non-interactively as part of a DarwinConfiguration the working directory + # must be set to a writeable directory. + (if cfg.workingDirectory != "." then '' + ${hostPkgs.coreutils}/bin/mkdir --parent "${cfg.workingDirectory}" + cd "${cfg.workingDirectory}" + '' else "") + '' + KEYS="''${KEYS:-./keys}" + ${hostPkgs.coreutils}/bin/mkdir --parent "''${KEYS}" + PRIVATE_KEY="''${KEYS}/${user}_${keyType}" + PUBLIC_KEY="''${PRIVATE_KEY}.pub" + if [ ! -e "''${PRIVATE_KEY}" ] || [ ! -e "''${PUBLIC_KEY}" ]; then + ${hostPkgs.coreutils}/bin/rm --force -- "''${PRIVATE_KEY}" "''${PUBLIC_KEY}" + ${hostPkgs.openssh}/bin/ssh-keygen -q -f "''${PRIVATE_KEY}" -t ${keyType} -N "" -C 'builder@localhost' + fi + if ! ${hostPkgs.diffutils}/bin/cmp "''${PUBLIC_KEY}" ${publicKey}; then + (set -x; sudo --reset-timestamp ${installCredentials} "''${KEYS}") + fi + KEYS="$(${hostPkgs.nix}/bin/nix-store --add "$KEYS")" ${lib.getExe config.system.build.vm} + ''); in script.overrideAttrs (old: { @@ -248,16 +223,12 @@ in ''; virtualisation = { - diskSize = lib.mkDefault (20 * 1024); + diskSize = cfg.diskSize; memorySize = cfg.memorySize; forwardPorts = [ - { - from = "host"; - guest.port = 22; - host.port = cfg.hostPort; - } + { from = "host"; guest.port = 22; host.port = cfg.hostPort; } ]; # Disable graphics for the builder since users will likely want to run it diff --git a/nixos/modules/services/monitoring/prometheus/exporters.nix b/nixos/modules/services/monitoring/prometheus/exporters.nix index 1471f97f1c24..c698c9005aaf 100644 --- a/nixos/modules/services/monitoring/prometheus/exporters.nix +++ b/nixos/modules/services/monitoring/prometheus/exporters.nix @@ -3,7 +3,7 @@ let inherit (lib) concatStrings foldl foldl' genAttrs literalExpression maintainers mapAttrs mapAttrsToList mkDefault mkEnableOption mkIf mkMerge mkOption - optional types mkOptionDefault flip attrNames; + optional types mkOptionDefault flip attrNames xor; cfg = config.services.prometheus.exporters; @@ -230,6 +230,7 @@ let in mkIf conf.enable { warnings = conf.warnings or []; + assertions = conf.assertions or []; users.users."${name}-exporter" = (mkIf (conf.user == "${name}-exporter" && !enableDynamicUser) { description = "Prometheus ${name} exporter service user"; isSystemUser = true; @@ -359,13 +360,6 @@ in Please specify either 'services.prometheus.exporters.nextcloud.passwordFile' or 'services.prometheus.exporters.nextcloud.tokenFile' ''; - } { - assertion = cfg.pgbouncer.enable -> ( - (cfg.pgbouncer.connectionStringFile != null || cfg.pgbouncer.connectionString != "") - ); - message = '' - PgBouncer exporter needs either connectionStringFile or connectionString configured" - ''; } { assertion = cfg.sql.enable -> ( (cfg.sql.configFile == null) != (cfg.sql.configuration == null) @@ -405,7 +399,15 @@ in Please ensure you have either `services.prometheus.exporters.deluge.delugePassword' or `services.prometheus.exporters.deluge.delugePasswordFile' set! ''; - } ] ++ (flip map (attrNames exporterOpts) (exporter: { + } { + assertion = cfg.pgbouncer.enable -> ( + xor (cfg.pgbouncer.connectionEnvFile == null) (cfg.pgbouncer.connectionString == null) + ); + message = '' + Options `services.prometheus.exporters.pgbouncer.connectionEnvFile` and + `services.prometheus.exporters.pgbouncer.connectionString` are mutually exclusive! + ''; + }] ++ (flip map (attrNames exporterOpts) (exporter: { assertion = cfg.${exporter}.firewallFilter != null -> cfg.${exporter}.openFirewall; message = '' The `firewallFilter'-option of exporter ${exporter} doesn't have any effect unless @@ -419,11 +421,6 @@ in Consider using `services.prometheus.exporters.idrac.configuration` instead. '' ) - (mkIf - (cfg.pgbouncer.enable && cfg.pgbouncer.connectionString != "") '' - config.services.prometheus.exporters.pgbouncer.connectionString is insecure. Use connectionStringFile instead. - '' - ) ] ++ config.services.prometheus.exporters.warnings; }] ++ [(mkIf config.services.prometheus.exporters.rtl_433.enable { hardware.rtl-sdr.enable = mkDefault true; diff --git a/nixos/modules/services/monitoring/prometheus/exporters/pgbouncer.nix b/nixos/modules/services/monitoring/prometheus/exporters/pgbouncer.nix index 9cd261099a95..5c111687c1d7 100644 --- a/nixos/modules/services/monitoring/prometheus/exporters/pgbouncer.nix +++ b/nixos/modules/services/monitoring/prometheus/exporters/pgbouncer.nix @@ -7,11 +7,8 @@ let mkPackageOption types optionals - optionalString getExe - getExe' escapeShellArg - escapeShellArgs concatStringsSep ; in @@ -29,8 +26,8 @@ in }; connectionString = mkOption { - type = types.str; - default = ""; + type = types.nullOr types.str; + default = null; example = "postgres://admin:@localhost:6432/pgbouncer?sslmode=require"; description = '' Connection string for accessing pgBouncer. @@ -43,26 +40,28 @@ in auth_file if auth_type other than "any" is used. WARNING: this secret is stored in the world-readable Nix store! - Use {option}`connectionStringFile` instead. + Use [](#opt-services.prometheus.exporters.pgbouncer.connectionEnvFile) if the + URL contains a secret. ''; }; - connectionStringFile = mkOption { - type = types.nullOr types.path; + connectionEnvFile = mkOption { + type = types.nullOr types.str; default = null; - example = "/run/keys/pgBouncer-connection-string"; description = '' - File that contains pgBouncer connection string in format: - postgres://admin:@localhost:6432/pgbouncer?sslmode=require + File that must contain the environment variable + `PGBOUNCER_EXPORTER_CONNECTION_STRING` which is set to the connection + string used by pgbouncer. I.e. the format is supposed to look like this: - NOTE: You MUST keep pgbouncer as database name (special internal db)!!! + ``` + PGBOUNCER_EXPORTER_CONNECTION_STRING="postgres://admin@localhost:6432/pgbouncer?sslmode=require" + ``` - NOTE: ignore_startup_parameters MUST contain "extra_float_digits". + NOTE: You MUST keep pgbouncer as database name (special internal db)! + NOTE: `services.pgbouncer.settings.pgbouncer.ignore_startup_parameters` + MUST contain "extra_float_digits". - NOTE: Admin user (with password or passwordless) MUST exist in the - auth_file if auth_type other than "any" is used. - - {option}`connectionStringFile` takes precedence over {option}`connectionString` + Mutually exclusive with [](#opt-services.prometheus.exporters.pgbouncer.connectionString). ''; }; @@ -126,16 +125,11 @@ in serviceOpts = { after = [ "pgbouncer.service" ]; - script = optionalString (cfg.connectionStringFile != null) '' - connectionString=$(${escapeShellArgs [ - (getExe' pkgs.coreutils "cat") "--" cfg.connectionStringFile - ]}) - '' + concatStringsSep " " ([ + script = concatStringsSep " " ([ "exec -- ${escapeShellArg (getExe cfg.package)}" "--web.listen-address ${cfg.listenAddress}:${toString cfg.port}" - "--pgBouncer.connectionString ${if cfg.connectionStringFile != null - then "\"$connectionString\"" - else "${escapeShellArg cfg.connectionString}"}" + ] ++ optionals (cfg.connectionString != null) [ + "--pgBouncer.connectionString ${escapeShellArg cfg.connectionString}" ] ++ optionals (cfg.telemetryPath != null) [ "--web.telemetry-path ${escapeShellArg cfg.telemetryPath}" ] ++ optionals (cfg.pidFile != null) [ @@ -151,5 +145,21 @@ in ] ++ cfg.extraFlags); serviceConfig.RestrictAddressFamilies = [ "AF_INET" "AF_INET6" "AF_UNIX" ]; + serviceConfig.EnvironmentFile = lib.mkIf (cfg.connectionEnvFile != null) [ + cfg.connectionEnvFile + ]; }; + + imports = [ + (lib.mkRemovedOptionModule [ "connectionStringFile" ] '' + As replacement, the option `services.prometheus.exporters.pgbouncer.connectionEnvFile` + has been added. In contrast to `connectionStringFile` it must be an environment file + with the connection string being set to `PGBOUNCER_EXPORTER_CONNECTION_STRING`. + + The change was necessary since the former option wrote the contents of the file + into the cmdline of the exporter making the connection string effectively + world-readable. + '') + ({ options.warnings = options.warnings; options.assertions = options.assertions; }) + ]; } diff --git a/nixos/modules/virtualisation/azure-image.nix b/nixos/modules/virtualisation/azure-image.nix index 4c321ad95fc8..ecb57483cce9 100644 --- a/nixos/modules/virtualisation/azure-image.nix +++ b/nixos/modules/virtualisation/azure-image.nix @@ -1,34 +1,22 @@ -{ - config, - lib, - pkgs, - ... -}: +{ config, lib, pkgs, ... }: with lib; let cfg = config.virtualisation.azureImage; - virtualisationOptions = import ./virtualisation-options.nix; in { - imports = [ - ./azure-common.nix - virtualisationOptions.diskSize - (lib.mkRenamedOptionModuleWith { - sinceRelease = 2411; - from = [ - "virtualisation" - "azureImage" - "diskSize" - ]; - to = [ - "virtualisation" - "diskSize" - ]; - }) - ]; + imports = [ ./azure-common.nix ]; options.virtualisation.azureImage = { + diskSize = mkOption { + type = with types; either (enum [ "auto" ]) int; + default = "auto"; + example = 2048; + description = '' + Size of disk image. Unit is MB. + ''; + }; + bootSize = mkOption { type = types.int; default = 256; @@ -47,12 +35,7 @@ in }; vmGeneration = mkOption { - type = - with types; - enum [ - "v1" - "v2" - ]; + type = with types; enum [ "v1" "v2" ]; default = "v1"; description = '' VM Generation to use. @@ -74,8 +57,7 @@ in bootSize = "${toString cfg.bootSize}M"; partitionTableType = if cfg.vmGeneration == "v2" then "efi" else "legacy"; - inherit (cfg) contents; - inherit (config.virtualisation) diskSize; + inherit (cfg) diskSize contents; inherit config lib pkgs; }; }; diff --git a/nixos/modules/virtualisation/digital-ocean-image.nix b/nixos/modules/virtualisation/digital-ocean-image.nix index 597f2c2f7a3f..53791e911406 100644 --- a/nixos/modules/virtualisation/digital-ocean-image.nix +++ b/nixos/modules/virtualisation/digital-ocean-image.nix @@ -1,35 +1,23 @@ -{ - config, - lib, - pkgs, - ... -}: +{ config, lib, pkgs, ... }: with lib; let cfg = config.virtualisation.digitalOceanImage; - virtualisationOptions = import ./virtualisation-options.nix; in { - imports = [ - ./digital-ocean-config.nix - virtualisationOptions.diskSize - (lib.mkRenamedOptionModuleWith { - sinceRelease = 2411; - from = [ - "virtualisation" - "digitialOceanImage" - "diskSize" - ]; - to = [ - "virtualisation" - "diskSize" - ]; - }) - ]; + imports = [ ./digital-ocean-config.nix ]; options = { + virtualisation.digitalOceanImage.diskSize = mkOption { + type = with types; either (enum [ "auto" ]) int; + default = "auto"; + example = 4096; + description = '' + Size of disk image. Unit is MB. + ''; + }; + virtualisation.digitalOceanImage.configFile = mkOption { type = with types; nullOr path; default = null; @@ -43,10 +31,7 @@ in }; virtualisation.digitalOceanImage.compressionMethod = mkOption { - type = types.enum [ - "gzip" - "bzip2" - ]; + type = types.enum [ "gzip" "bzip2" ]; default = "gzip"; example = "bzip2"; description = '' @@ -59,35 +44,27 @@ in #### implementation config = { + system.build.digitalOceanImage = import ../../lib/make-disk-image.nix { name = "digital-ocean-image"; format = "qcow2"; - postVM = - let - compress = - { - "gzip" = "${pkgs.gzip}/bin/gzip"; - "bzip2" = "${pkgs.bzip2}/bin/bzip2"; - } - .${cfg.compressionMethod}; - in - '' - ${compress} $diskImage - ''; - configFile = - if cfg.configFile == null then - config.virtualisation.digitalOcean.defaultConfigFile - else - cfg.configFile; - inherit (config.virtualisation) diskSize; + postVM = let + compress = { + "gzip" = "${pkgs.gzip}/bin/gzip"; + "bzip2" = "${pkgs.bzip2}/bin/bzip2"; + }.${cfg.compressionMethod}; + in '' + ${compress} $diskImage + ''; + configFile = if cfg.configFile == null + then config.virtualisation.digitalOcean.defaultConfigFile + else cfg.configFile; + inherit (cfg) diskSize; inherit config lib pkgs; }; }; - meta.maintainers = with maintainers; [ - arianvp - eamsden - ]; + meta.maintainers = with maintainers; [ arianvp eamsden ]; } diff --git a/nixos/modules/virtualisation/google-compute-image.nix b/nixos/modules/virtualisation/google-compute-image.nix index 200c512ecf66..8e7b31b439bf 100644 --- a/nixos/modules/virtualisation/google-compute-image.nix +++ b/nixos/modules/virtualisation/google-compute-image.nix @@ -1,9 +1,4 @@ -{ - config, - lib, - pkgs, - ... -}: +{ config, lib, pkgs, ... }: with lib; let @@ -16,28 +11,21 @@ let ]; } ''; - virtualisationOptions = import ./virtualisation-options.nix; in { - imports = [ - ./google-compute-config.nix - virtualisationOptions.diskSize - (lib.mkRenamedOptionModuleWith { - sinceRelease = 2411; - from = [ - "virtualisation" - "googleComputeImage" - "diskSize" - ]; - to = [ - "virtualisation" - "diskSize" - ]; - }) - ]; + imports = [ ./google-compute-config.nix ]; options = { + virtualisation.googleComputeImage.diskSize = mkOption { + type = with types; either (enum [ "auto" ]) int; + default = "auto"; + example = 1536; + description = '' + Size of disk image. Unit is MB. + ''; + }; + virtualisation.googleComputeImage.configFile = mkOption { type = with types; nullOr str; default = null; @@ -76,13 +64,7 @@ in system.build.googleComputeImage = import ../../lib/make-disk-image.nix { name = "google-compute-image"; postVM = '' - PATH=$PATH:${ - with pkgs; - lib.makeBinPath [ - gnutar - gzip - ] - } + PATH=$PATH:${with pkgs; lib.makeBinPath [ gnutar gzip ]} pushd $out mv $diskImage disk.raw tar -Sc disk.raw | gzip -${toString cfg.compressionLevel} > \ @@ -93,7 +75,7 @@ in format = "raw"; configFile = if cfg.configFile == null then defaultConfigFile else cfg.configFile; partitionTableType = if cfg.efi then "efi" else "legacy"; - inherit (config.virtualisation) diskSize; + inherit (cfg) diskSize; inherit config lib pkgs; }; diff --git a/nixos/modules/virtualisation/hyperv-image.nix b/nixos/modules/virtualisation/hyperv-image.nix index fe48ce632dcf..eb1bbe9f3a58 100644 --- a/nixos/modules/virtualisation/hyperv-image.nix +++ b/nixos/modules/virtualisation/hyperv-image.nix @@ -1,37 +1,21 @@ -{ - config, - pkgs, - lib, - ... -}: +{ config, pkgs, lib, ... }: with lib; let cfg = config.hyperv; - virtualisationOptions = import ./virtualisation-options.nix; - -in -{ - - imports = [ - virtualisationOptions.diskSize - (lib.mkRenamedOptionModuleWith { - sinceRelease = 2411; - from = [ - "virtualisation" - "hyperv" - "baseImageSize" - ]; - to = [ - "virtualisation" - "diskSize" - ]; - }) - ]; +in { options = { hyperv = { + baseImageSize = mkOption { + type = with types; either (enum [ "auto" ]) int; + default = "auto"; + example = 2048; + description = '' + The size of the hyper-v base image in MiB. + ''; + }; vmDerivationName = mkOption { type = types.str; default = "nixos-hyperv-${config.system.nixos.label}-${pkgs.stdenv.hostPlatform.system}"; @@ -50,8 +34,6 @@ in }; config = { - virtualisation.diskSize = lib.mkDefault (4 * 1024); - system.build.hypervImage = import ../../lib/make-disk-image.nix { name = cfg.vmDerivationName; postVM = '' @@ -59,7 +41,7 @@ in rm $diskImage ''; format = "raw"; - inherit (config.virtualisation) diskSize; + diskSize = cfg.baseImageSize; partitionTableType = "efi"; inherit config lib pkgs; }; diff --git a/nixos/modules/virtualisation/linode-image.nix b/nixos/modules/virtualisation/linode-image.nix index 4725f0a2f9b7..51f793ac011d 100644 --- a/nixos/modules/virtualisation/linode-image.nix +++ b/nixos/modules/virtualisation/linode-image.nix @@ -1,9 +1,4 @@ -{ - config, - lib, - pkgs, - ... -}: +{ config, lib, pkgs, ... }: with lib; let @@ -15,27 +10,19 @@ let ]; } ''; - virtualisationOptions = import ./virtualisation-options.nix; in { - imports = [ - ./linode-config.nix - virtualisationOptions.diskSize - (lib.mkRenamedOptionModuleWith { - sinceRelease = 2411; - from = [ - "virtualisation" - "linodeImage" - "diskSize" - ]; - to = [ - "virtualisation" - "diskSize" - ]; - }) - ]; + imports = [ ./linode-config.nix ]; options = { + virtualisation.linodeImage.diskSize = mkOption { + type = with types; either (enum (singleton "auto")) ints.positive; + default = "auto"; + example = 1536; + description = '' + Size of disk image in MB. + ''; + }; virtualisation.linodeImage.configFile = mkOption { type = with types; nullOr str; @@ -70,7 +57,7 @@ in format = "raw"; partitionTableType = "none"; configFile = if cfg.configFile == null then defaultConfigFile else cfg.configFile; - inherit (config.virtualisation) diskSize; + inherit (cfg) diskSize; inherit config lib pkgs; }; }; diff --git a/nixos/modules/virtualisation/oci-image.nix b/nixos/modules/virtualisation/oci-image.nix index 44a6ef7ef6f6..1e2b90bfd46e 100644 --- a/nixos/modules/virtualisation/oci-image.nix +++ b/nixos/modules/virtualisation/oci-image.nix @@ -1,9 +1,4 @@ -{ - config, - lib, - pkgs, - ... -}: +{ config, lib, pkgs, ... }: let cfg = config.oci; @@ -12,12 +7,9 @@ in imports = [ ./oci-common.nix ]; config = { - virtualisation.diskSize = lib.mkDefault (8 * 1024); - virtualisation.diskSizeAutoSupported = false; - system.build.OCIImage = import ../../lib/make-disk-image.nix { inherit config lib pkgs; - inherit (config.virtualisation) diskSize; + inherit (cfg) diskSize; name = "oci-image"; configFile = ./oci-config-user.nix; format = "qcow2"; @@ -33,10 +25,7 @@ in after = [ "network-online.target" ]; wants = [ "network-online.target" ]; - path = [ - pkgs.coreutils - pkgs.curl - ]; + path = [ pkgs.coreutils pkgs.curl ]; script = '' mkdir -m 0700 -p /root/.ssh if [ -f /root/.ssh/authorized_keys ]; then diff --git a/nixos/modules/virtualisation/oci-options.nix b/nixos/modules/virtualisation/oci-options.nix index 8a1ac4e03446..76f3475a4281 100644 --- a/nixos/modules/virtualisation/oci-options.nix +++ b/nixos/modules/virtualisation/oci-options.nix @@ -1,27 +1,5 @@ +{ config, lib, pkgs, ... }: { - lib, - ... -}: -let - virtualisationOptions = import ./virtualisation-options.nix; -in -{ - imports = [ - virtualisationOptions.diskSize - (lib.mkRenamedOptionModuleWith { - sinceRelease = 2411; - from = [ - "virtualisation" - "oci" - "diskSize" - ]; - to = [ - "virtualisation" - "diskSize" - ]; - }) - ]; - options = { oci = { efi = lib.mkOption { @@ -31,6 +9,12 @@ in Whether the OCI instance is using EFI. ''; }; + diskSize = lib.mkOption { + type = lib.types.int; + default = 8192; + description = "Size of the disk image created in MB."; + example = "diskSize = 12 * 1024; # 12GiB"; + }; }; }; } diff --git a/nixos/modules/virtualisation/proxmox-image.nix b/nixos/modules/virtualisation/proxmox-image.nix index 2cfc7fa1b530..d390c78432ae 100644 --- a/nixos/modules/virtualisation/proxmox-image.nix +++ b/nixos/modules/virtualisation/proxmox-image.nix @@ -1,31 +1,8 @@ -{ - config, - pkgs, - lib, - ... -}: +{ config, pkgs, lib, ... }: with lib; -let - virtualisationOptions = import ./virtualisation-options.nix; -in -{ - imports = [ - virtualisationOptions.diskSize - (lib.mkRenamedOptionModuleWith { - sinceRelease = 2411; - from = [ - "virtualisation" - "proxmoxImage" - "diskSize" - ]; - to = [ - "virtualisation" - "diskSize" - ]; - }) - ]; +{ options.proxmox = { qemuConf = { # essential configs @@ -77,10 +54,7 @@ in ''; }; bios = mkOption { - type = types.enum [ - "seabios" - "ovmf" - ]; + type = types.enum [ "seabios" "ovmf" ]; default = "seabios"; description = '' Select BIOS implementation (seabios = Legacy BIOS, ovmf = UEFI). @@ -113,6 +87,16 @@ in either "efi" or "hybrid". ''; }; + diskSize = mkOption { + type = types.str; + default = "auto"; + example = "20480"; + description = '' + The size of the disk, in megabytes. + if "auto" size is calculated based on the contents copied to it and + additionalSpace is taken into account. + ''; + }; net0 = mkOption { type = types.commas; default = "virtio=00:00:00:00:00:00,bridge=vmbr0,firewall=1"; @@ -140,13 +124,8 @@ in }; }; qemuExtraConf = mkOption { - type = - with types; - attrsOf (oneOf [ - str - int - ]); - default = { }; + type = with types; attrsOf (oneOf [ str int ]); + default = {}; example = literalExpression '' { cpu = "host"; @@ -158,12 +137,7 @@ in ''; }; partitionTableType = mkOption { - type = types.enum [ - "efi" - "hybrid" - "legacy" - "legacy+gpt" - ]; + type = types.enum [ "efi" "hybrid" "legacy" "legacy+gpt" ]; description = '' Partition table type to use. See make-disk-image.nix partitionTableType for details. Defaults to 'legacy' for 'proxmox.qemuConf.bios="seabios"' (default), other bios values defaults to 'efi'. @@ -211,163 +185,142 @@ in }; }; - config = - let - cfg = config.proxmox; - cfgLine = name: value: '' - ${name}: ${builtins.toString value} - ''; - virtio0Storage = builtins.head (builtins.split ":" cfg.qemuConf.virtio0); - cfgFile = - fileName: properties: - pkgs.writeTextDir fileName '' - # generated by NixOS - ${lib.concatStrings (lib.mapAttrsToList cfgLine properties)} - #qmdump#map:virtio0:drive-virtio0:${virtio0Storage}:raw: - ''; + config = let + cfg = config.proxmox; + cfgLine = name: value: '' + ${name}: ${builtins.toString value} + ''; + virtio0Storage = builtins.head (builtins.split ":" cfg.qemuConf.virtio0); + cfgFile = fileName: properties: pkgs.writeTextDir fileName '' + # generated by NixOS + ${lib.concatStrings (lib.mapAttrsToList cfgLine properties)} + #qmdump#map:virtio0:drive-virtio0:${virtio0Storage}:raw: + ''; + inherit (cfg) partitionTableType; + supportEfi = partitionTableType == "efi" || partitionTableType == "hybrid"; + supportBios = partitionTableType == "legacy" || partitionTableType == "hybrid" || partitionTableType == "legacy+gpt"; + hasBootPartition = partitionTableType == "efi" || partitionTableType == "hybrid"; + hasNoFsPartition = partitionTableType == "hybrid" || partitionTableType == "legacy+gpt"; + in { + assertions = [ + { + assertion = config.boot.loader.systemd-boot.enable -> config.proxmox.qemuConf.bios == "ovmf"; + message = "systemd-boot requires 'ovmf' bios"; + } + { + assertion = partitionTableType == "efi" -> config.proxmox.qemuConf.bios == "ovmf"; + message = "'efi' disk partitioning requires 'ovmf' bios"; + } + { + assertion = partitionTableType == "legacy" -> config.proxmox.qemuConf.bios == "seabios"; + message = "'legacy' disk partitioning requires 'seabios' bios"; + } + { + assertion = partitionTableType == "legacy+gpt" -> config.proxmox.qemuConf.bios == "seabios"; + message = "'legacy+gpt' disk partitioning requires 'seabios' bios"; + } + ]; + system.build.VMA = import ../../lib/make-disk-image.nix { + name = "proxmox-${cfg.filenameSuffix}"; inherit (cfg) partitionTableType; - supportEfi = partitionTableType == "efi" || partitionTableType == "hybrid"; - supportBios = - partitionTableType == "legacy" - || partitionTableType == "hybrid" - || partitionTableType == "legacy+gpt"; - hasBootPartition = partitionTableType == "efi" || partitionTableType == "hybrid"; - hasNoFsPartition = partitionTableType == "hybrid" || partitionTableType == "legacy+gpt"; - in - { - assertions = [ - { - assertion = config.boot.loader.systemd-boot.enable -> config.proxmox.qemuConf.bios == "ovmf"; - message = "systemd-boot requires 'ovmf' bios"; - } - { - assertion = partitionTableType == "efi" -> config.proxmox.qemuConf.bios == "ovmf"; - message = "'efi' disk partitioning requires 'ovmf' bios"; - } - { - assertion = partitionTableType == "legacy" -> config.proxmox.qemuConf.bios == "seabios"; - message = "'legacy' disk partitioning requires 'seabios' bios"; - } - { - assertion = partitionTableType == "legacy+gpt" -> config.proxmox.qemuConf.bios == "seabios"; - message = "'legacy+gpt' disk partitioning requires 'seabios' bios"; - } - ]; - system.build.VMA = import ../../lib/make-disk-image.nix { - name = "proxmox-${cfg.filenameSuffix}"; - inherit (cfg) partitionTableType; - postVM = - let - # Build qemu with PVE's patch that adds support for the VMA format - vma = - (pkgs.qemu_kvm.override { - alsaSupport = false; - pulseSupport = false; - sdlSupport = false; - jackSupport = false; - gtkSupport = false; - vncSupport = false; - smartcardSupport = false; - spiceSupport = false; - ncursesSupport = false; - libiscsiSupport = false; - tpmSupport = false; - numaSupport = false; - seccompSupport = false; - guestAgentSupport = false; - }).overrideAttrs - (super: rec { - # Check https://github.com/proxmox/pve-qemu/tree/master for the version - # of qemu and patch to use - version = "9.0.0"; - src = pkgs.fetchurl { - url = "https://download.qemu.org/qemu-${version}.tar.xz"; - hash = "sha256-MnCKxmww2MiSYz6paMdxwcdtWX1w3erSGg0izPOG2mk="; - }; - patches = [ - # Proxmox' VMA tool is published as a particular patch upon QEMU - "${ - pkgs.fetchFromGitHub { - owner = "proxmox"; - repo = "pve-qemu"; - rev = "14afbdd55f04d250bd679ca1ad55d3f47cd9d4c8"; - hash = "sha256-lSJQA5SHIHfxJvMLIID2drv2H43crTPMNIlIT37w9Nc="; - } - }/debian/patches/pve/0027-PVE-Backup-add-vma-backup-format-code.patch" - ]; + postVM = let + # Build qemu with PVE's patch that adds support for the VMA format + vma = (pkgs.qemu_kvm.override { + alsaSupport = false; + pulseSupport = false; + sdlSupport = false; + jackSupport = false; + gtkSupport = false; + vncSupport = false; + smartcardSupport = false; + spiceSupport = false; + ncursesSupport = false; + libiscsiSupport = false; + tpmSupport = false; + numaSupport = false; + seccompSupport = false; + guestAgentSupport = false; + }).overrideAttrs ( super: rec { + # Check https://github.com/proxmox/pve-qemu/tree/master for the version + # of qemu and patch to use + version = "9.0.0"; + src = pkgs.fetchurl { + url = "https://download.qemu.org/qemu-${version}.tar.xz"; + hash = "sha256-MnCKxmww2MiSYz6paMdxwcdtWX1w3erSGg0izPOG2mk="; + }; + patches = [ + # Proxmox' VMA tool is published as a particular patch upon QEMU + "${pkgs.fetchFromGitHub { + owner = "proxmox"; + repo = "pve-qemu"; + rev = "14afbdd55f04d250bd679ca1ad55d3f47cd9d4c8"; + hash = "sha256-lSJQA5SHIHfxJvMLIID2drv2H43crTPMNIlIT37w9Nc="; + }}/debian/patches/pve/0027-PVE-Backup-add-vma-backup-format-code.patch" + ]; - buildInputs = super.buildInputs ++ [ pkgs.libuuid ]; - nativeBuildInputs = super.nativeBuildInputs ++ [ pkgs.perl ]; + buildInputs = super.buildInputs ++ [ pkgs.libuuid ]; + nativeBuildInputs = super.nativeBuildInputs ++ [ pkgs.perl ]; - }); - in - '' - ${vma}/bin/vma create "vzdump-qemu-${cfg.filenameSuffix}.vma" \ - -c ${ - cfgFile "qemu-server.conf" (cfg.qemuConf // cfg.qemuExtraConf) - }/qemu-server.conf drive-virtio0=$diskImage - rm $diskImage - ${pkgs.zstd}/bin/zstd "vzdump-qemu-${cfg.filenameSuffix}.vma" - mv "vzdump-qemu-${cfg.filenameSuffix}.vma.zst" $out/ + }); + in + '' + ${vma}/bin/vma create "vzdump-qemu-${cfg.filenameSuffix}.vma" \ + -c ${cfgFile "qemu-server.conf" (cfg.qemuConf // cfg.qemuExtraConf)}/qemu-server.conf drive-virtio0=$diskImage + rm $diskImage + ${pkgs.zstd}/bin/zstd "vzdump-qemu-${cfg.filenameSuffix}.vma" + mv "vzdump-qemu-${cfg.filenameSuffix}.vma.zst" $out/ - mkdir -p $out/nix-support - echo "file vma $out/vzdump-qemu-${cfg.filenameSuffix}.vma.zst" > $out/nix-support/hydra-build-products - ''; - inherit (cfg.qemuConf) additionalSpace bootSize; - inherit (config.virtualisation) diskSize; - format = "raw"; - inherit config lib pkgs; - }; - - boot = { - growPartition = true; - kernelParams = [ "console=ttyS0" ]; - loader.grub = { - device = lib.mkDefault ( - if (hasNoFsPartition || supportBios) then - # Even if there is a separate no-fs partition ("/dev/disk/by-partlabel/no-fs" i.e. "/dev/vda2"), - # which will be used the bootloader, do not set it as loader.grub.device. - # GRUB installation fails, unless the whole disk is selected. - "/dev/vda" - else - "nodev" - ); - efiSupport = lib.mkDefault supportEfi; - efiInstallAsRemovable = lib.mkDefault supportEfi; - }; - - loader.timeout = 0; - initrd.availableKernelModules = [ - "uas" - "virtio_blk" - "virtio_pci" - ]; - }; - - fileSystems."/" = { - device = "/dev/disk/by-label/nixos"; - autoResize = true; - fsType = "ext4"; - }; - fileSystems."/boot" = lib.mkIf hasBootPartition { - device = "/dev/disk/by-label/ESP"; - fsType = "vfat"; - }; - - networking = mkIf cfg.cloudInit.enable { - hostName = mkForce ""; - useDHCP = false; - }; - - services = { - cloud-init = mkIf cfg.cloudInit.enable { - enable = true; - network.enable = true; - }; - sshd.enable = mkDefault true; - qemuGuest.enable = true; - }; - - proxmox.qemuExtraConf.${cfg.cloudInit.device} = "${cfg.cloudInit.defaultStorage}:vm-9999-cloudinit,media=cdrom"; + mkdir -p $out/nix-support + echo "file vma $out/vzdump-qemu-${cfg.filenameSuffix}.vma.zst" > $out/nix-support/hydra-build-products + ''; + inherit (cfg.qemuConf) additionalSpace diskSize bootSize; + format = "raw"; + inherit config lib pkgs; }; + + boot = { + growPartition = true; + kernelParams = [ "console=ttyS0" ]; + loader.grub = { + device = lib.mkDefault (if (hasNoFsPartition || supportBios) then + # Even if there is a separate no-fs partition ("/dev/disk/by-partlabel/no-fs" i.e. "/dev/vda2"), + # which will be used the bootloader, do not set it as loader.grub.device. + # GRUB installation fails, unless the whole disk is selected. + "/dev/vda" + else + "nodev"); + efiSupport = lib.mkDefault supportEfi; + efiInstallAsRemovable = lib.mkDefault supportEfi; + }; + + loader.timeout = 0; + initrd.availableKernelModules = [ "uas" "virtio_blk" "virtio_pci" ]; + }; + + fileSystems."/" = { + device = "/dev/disk/by-label/nixos"; + autoResize = true; + fsType = "ext4"; + }; + fileSystems."/boot" = lib.mkIf hasBootPartition { + device = "/dev/disk/by-label/ESP"; + fsType = "vfat"; + }; + + networking = mkIf cfg.cloudInit.enable { + hostName = mkForce ""; + useDHCP = false; + }; + + services = { + cloud-init = mkIf cfg.cloudInit.enable { + enable = true; + network.enable = true; + }; + sshd.enable = mkDefault true; + qemuGuest.enable = true; + }; + + proxmox.qemuExtraConf.${cfg.cloudInit.device} = "${cfg.cloudInit.defaultStorage}:vm-9999-cloudinit,media=cdrom"; + }; } diff --git a/nixos/modules/virtualisation/qemu-vm.nix b/nixos/modules/virtualisation/qemu-vm.nix index 7b9b5086dbb9..153dc877352a 100644 --- a/nixos/modules/virtualisation/qemu-vm.nix +++ b/nixos/modules/virtualisation/qemu-vm.nix @@ -4,13 +4,7 @@ # `config'. By default, the Nix store is shared read-only with the # host, which makes (re)building VMs very efficient. -{ - config, - lib, - pkgs, - options, - ... -}: +{ config, lib, pkgs, options, ... }: with lib; @@ -28,262 +22,235 @@ let consoles = lib.concatMapStringsSep " " (c: "console=${c}") cfg.qemu.consoles; - driveOpts = - { ... }: - { + driveOpts = { ... }: { - options = { + options = { - file = mkOption { - type = types.str; - description = "The file image used for this drive."; - }; + file = mkOption { + type = types.str; + description = "The file image used for this drive."; + }; - driveExtraOpts = mkOption { - type = types.attrsOf types.str; - default = { }; - description = "Extra options passed to drive flag."; - }; + driveExtraOpts = mkOption { + type = types.attrsOf types.str; + default = {}; + description = "Extra options passed to drive flag."; + }; - deviceExtraOpts = mkOption { - type = types.attrsOf types.str; - default = { }; - description = "Extra options passed to device flag."; - }; - - name = mkOption { - type = types.nullOr types.str; - default = null; - description = "A name for the drive. Must be unique in the drives list. Not passed to qemu."; - }; + deviceExtraOpts = mkOption { + type = types.attrsOf types.str; + default = {}; + description = "Extra options passed to device flag."; + }; + name = mkOption { + type = types.nullOr types.str; + default = null; + description = "A name for the drive. Must be unique in the drives list. Not passed to qemu."; }; }; - selectPartitionTableLayout = - { useEFIBoot, useDefaultFilesystems }: - if useDefaultFilesystems then if useEFIBoot then "efi" else "legacy" else "none"; + }; - driveCmdline = - idx: - { - file, - driveExtraOpts, - deviceExtraOpts, - ... - }: + selectPartitionTableLayout = { useEFIBoot, useDefaultFilesystems }: + if useDefaultFilesystems then + if useEFIBoot then "efi" else "legacy" + else "none"; + + driveCmdline = idx: { file, driveExtraOpts, deviceExtraOpts, ... }: let drvId = "drive${toString idx}"; - mkKeyValue = generators.mkKeyValueDefault { } "="; + mkKeyValue = generators.mkKeyValueDefault {} "="; mkOpts = opts: concatStringsSep "," (mapAttrsToList mkKeyValue opts); - driveOpts = mkOpts ( - driveExtraOpts - // { - index = idx; - id = drvId; - "if" = "none"; - inherit file; - } - ); - deviceOpts = mkOpts ( - deviceExtraOpts - // { - drive = drvId; - } - ); + driveOpts = mkOpts (driveExtraOpts // { + index = idx; + id = drvId; + "if" = "none"; + inherit file; + }); + deviceOpts = mkOpts (deviceExtraOpts // { + drive = drvId; + }); device = if cfg.qemu.diskInterface == "scsi" then "-device lsi53c895a -device scsi-hd,${deviceOpts}" else "-device virtio-blk-pci,${deviceOpts}"; in - "-drive ${driveOpts} ${device}"; + "-drive ${driveOpts} ${device}"; drivesCmdLine = drives: concatStringsSep "\\\n " (imap1 driveCmdline drives); # Shell script to start the VM. - startVM = '' - #! ${hostPkgs.runtimeShell} + startVM = + '' + #! ${hostPkgs.runtimeShell} - export PATH=${makeBinPath [ hostPkgs.coreutils ]}''${PATH:+:}$PATH + export PATH=${makeBinPath [ hostPkgs.coreutils ]}''${PATH:+:}$PATH - set -e + set -e - # Create an empty ext4 filesystem image. A filesystem image does not - # contain a partition table but just a filesystem. - createEmptyFilesystemImage() { - local name=$1 - local size=$2 - local temp=$(mktemp) - ${qemu}/bin/qemu-img create -f raw "$temp" "$size" - ${hostPkgs.e2fsprogs}/bin/mkfs.ext4 -L ${rootFilesystemLabel} "$temp" - ${qemu}/bin/qemu-img convert -f raw -O qcow2 "$temp" "$name" - rm "$temp" - } + # Create an empty ext4 filesystem image. A filesystem image does not + # contain a partition table but just a filesystem. + createEmptyFilesystemImage() { + local name=$1 + local size=$2 + local temp=$(mktemp) + ${qemu}/bin/qemu-img create -f raw "$temp" "$size" + ${hostPkgs.e2fsprogs}/bin/mkfs.ext4 -L ${rootFilesystemLabel} "$temp" + ${qemu}/bin/qemu-img convert -f raw -O qcow2 "$temp" "$name" + rm "$temp" + } - NIX_DISK_IMAGE=$(readlink -f "''${NIX_DISK_IMAGE:-${toString config.virtualisation.diskImage}}") || test -z "$NIX_DISK_IMAGE" + NIX_DISK_IMAGE=$(readlink -f "''${NIX_DISK_IMAGE:-${toString config.virtualisation.diskImage}}") || test -z "$NIX_DISK_IMAGE" - if test -n "$NIX_DISK_IMAGE" && ! test -e "$NIX_DISK_IMAGE"; then - echo "Disk image do not exist, creating the virtualisation disk image..." + if test -n "$NIX_DISK_IMAGE" && ! test -e "$NIX_DISK_IMAGE"; then + echo "Disk image do not exist, creating the virtualisation disk image..." - ${ - if (cfg.useBootLoader && cfg.useDefaultFilesystems) then - '' - # Create a writable qcow2 image using the systemImage as a backing - # image. + ${if (cfg.useBootLoader && cfg.useDefaultFilesystems) then '' + # Create a writable qcow2 image using the systemImage as a backing + # image. - # CoW prevent size to be attributed to an image. - # FIXME: raise this issue to upstream. - ${qemu}/bin/qemu-img create \ - -f qcow2 \ - -b ${systemImage}/nixos.qcow2 \ - -F qcow2 \ - "$NIX_DISK_IMAGE" - '' - else if cfg.useDefaultFilesystems then - '' - createEmptyFilesystemImage "$NIX_DISK_IMAGE" "${toString cfg.diskSize}M" - '' - else - '' - # Create an empty disk image without a filesystem. - ${qemu}/bin/qemu-img create -f qcow2 "$NIX_DISK_IMAGE" "${toString cfg.diskSize}M" - '' - } - echo "Virtualisation disk image created." - fi - - # Create a directory for storing temporary data of the running VM. - if [ -z "$TMPDIR" ] || [ -z "$USE_TMPDIR" ]; then - TMPDIR=$(mktemp -d nix-vm.XXXXXXXXXX --tmpdir) - fi - - ${lib.optionalString (cfg.useNixStoreImage) '' - echo "Creating Nix store image..." - - ${hostPkgs.gnutar}/bin/tar --create \ - --absolute-names \ - --verbatim-files-from \ - --transform 'flags=rSh;s|/nix/store/||' \ - --files-from ${ - hostPkgs.closureInfo { - rootPaths = [ - config.system.build.toplevel - regInfo - ]; + # CoW prevent size to be attributed to an image. + # FIXME: raise this issue to upstream. + ${qemu}/bin/qemu-img create \ + -f qcow2 \ + -b ${systemImage}/nixos.qcow2 \ + -F qcow2 \ + "$NIX_DISK_IMAGE" + '' else if cfg.useDefaultFilesystems then '' + createEmptyFilesystemImage "$NIX_DISK_IMAGE" "${toString cfg.diskSize}M" + '' else '' + # Create an empty disk image without a filesystem. + ${qemu}/bin/qemu-img create -f qcow2 "$NIX_DISK_IMAGE" "${toString cfg.diskSize}M" + '' } - }/store-paths \ - | ${hostPkgs.erofs-utils}/bin/mkfs.erofs \ - --quiet \ - --force-uid=0 \ - --force-gid=0 \ - -L ${nixStoreFilesystemLabel} \ - -U eb176051-bd15-49b7-9e6b-462e0b467019 \ - -T 0 \ - --tar=f \ - "$TMPDIR"/store.img - - echo "Created Nix store image." - ''} - - # Create a directory for exchanging data with the VM. - mkdir -p "$TMPDIR/xchg" - - ${lib.optionalString cfg.useHostCerts '' - mkdir -p "$TMPDIR/certs" - if [ -e "$NIX_SSL_CERT_FILE" ]; then - cp -L "$NIX_SSL_CERT_FILE" "$TMPDIR"/certs/ca-certificates.crt - else - echo \$NIX_SSL_CERT_FILE should point to a valid file if virtualisation.useHostCerts is enabled. + echo "Virtualisation disk image created." fi - ''} - ${lib.optionalString cfg.useEFIBoot '' - # Expose EFI variables, it's useful even when we are not using a bootloader (!). - # We might be interested in having EFI variable storage present even if we aren't booting via UEFI, hence - # no guard against `useBootLoader`. Examples: - # - testing PXE boot or other EFI applications - # - directbooting LinuxBoot, which `kexec()s` into a UEFI environment that can boot e.g. Windows - NIX_EFI_VARS=$(readlink -f "''${NIX_EFI_VARS:-${config.system.name}-efi-vars.fd}") - # VM needs writable EFI vars - if ! test -e "$NIX_EFI_VARS"; then - ${ - if cfg.efi.keepVariables then - # We still need the EFI var from the make-disk-image derivation - # because our "switch-to-configuration" process might - # write into it and we want to keep this data. - ''cp ${systemImage}/efi-vars.fd "$NIX_EFI_VARS"'' + # Create a directory for storing temporary data of the running VM. + if [ -z "$TMPDIR" ] || [ -z "$USE_TMPDIR" ]; then + TMPDIR=$(mktemp -d nix-vm.XXXXXXXXXX --tmpdir) + fi + + ${lib.optionalString (cfg.useNixStoreImage) '' + echo "Creating Nix store image..." + + ${hostPkgs.gnutar}/bin/tar --create \ + --absolute-names \ + --verbatim-files-from \ + --transform 'flags=rSh;s|/nix/store/||' \ + --files-from ${hostPkgs.closureInfo { rootPaths = [ config.system.build.toplevel regInfo ]; }}/store-paths \ + | ${hostPkgs.erofs-utils}/bin/mkfs.erofs \ + --quiet \ + --force-uid=0 \ + --force-gid=0 \ + -L ${nixStoreFilesystemLabel} \ + -U eb176051-bd15-49b7-9e6b-462e0b467019 \ + -T 0 \ + --tar=f \ + "$TMPDIR"/store.img + + echo "Created Nix store image." + '' + } + + # Create a directory for exchanging data with the VM. + mkdir -p "$TMPDIR/xchg" + + ${lib.optionalString cfg.useHostCerts + '' + mkdir -p "$TMPDIR/certs" + if [ -e "$NIX_SSL_CERT_FILE" ]; then + cp -L "$NIX_SSL_CERT_FILE" "$TMPDIR"/certs/ca-certificates.crt else - ''cp ${cfg.efi.variables} "$NIX_EFI_VARS"'' - } - chmod 0644 "$NIX_EFI_VARS" - fi - ''} + echo \$NIX_SSL_CERT_FILE should point to a valid file if virtualisation.useHostCerts is enabled. + fi + ''} - ${lib.optionalString cfg.tpm.enable '' - NIX_SWTPM_DIR=$(readlink -f "''${NIX_SWTPM_DIR:-${config.system.name}-swtpm}") - mkdir -p "$NIX_SWTPM_DIR" - ${lib.getExe cfg.tpm.package} \ - socket \ - --tpmstate dir="$NIX_SWTPM_DIR" \ - --ctrl type=unixio,path="$NIX_SWTPM_DIR"/socket,terminate \ - --pid file="$NIX_SWTPM_DIR"/pid --daemon \ - --tpm2 \ - --log file="$NIX_SWTPM_DIR"/stdout,level=6 + ${lib.optionalString cfg.useEFIBoot + '' + # Expose EFI variables, it's useful even when we are not using a bootloader (!). + # We might be interested in having EFI variable storage present even if we aren't booting via UEFI, hence + # no guard against `useBootLoader`. Examples: + # - testing PXE boot or other EFI applications + # - directbooting LinuxBoot, which `kexec()s` into a UEFI environment that can boot e.g. Windows + NIX_EFI_VARS=$(readlink -f "''${NIX_EFI_VARS:-${config.system.name}-efi-vars.fd}") + # VM needs writable EFI vars + if ! test -e "$NIX_EFI_VARS"; then + ${if cfg.efi.keepVariables then + # We still need the EFI var from the make-disk-image derivation + # because our "switch-to-configuration" process might + # write into it and we want to keep this data. + ''cp ${systemImage}/efi-vars.fd "$NIX_EFI_VARS"'' + else + ''cp ${cfg.efi.variables} "$NIX_EFI_VARS"'' + } + chmod 0644 "$NIX_EFI_VARS" + fi + ''} - # Enable `fdflags` builtin in Bash - # We will need it to perform surgical modification of the file descriptor - # passed in the coprocess to remove `FD_CLOEXEC`, i.e. close the file descriptor - # on exec. - # If let alone, it will trigger the coprocess to read EOF when QEMU is `exec` - # at the end of this script. To work around that, we will just clear - # the `FD_CLOEXEC` bits as a first step. - enable -f ${hostPkgs.bash}/lib/bash/fdflags fdflags - # leave a dangling subprocess because the swtpm ctrl socket has - # "terminate" when the last connection disconnects, it stops swtpm. - # When qemu stops, or if the main shell process ends, the coproc will - # get signaled by virtue of the pipe between main and coproc ending. - # Which in turns triggers a socat connect-disconnect to swtpm which - # will stop it. - coproc waitingswtpm { - read || : - echo "" | ${lib.getExe hostPkgs.socat} STDIO UNIX-CONNECT:"$NIX_SWTPM_DIR"/socket - } - # Clear `FD_CLOEXEC` on the coprocess' file descriptor stdin. - fdflags -s-cloexec ''${waitingswtpm[1]} - ''} + ${lib.optionalString cfg.tpm.enable '' + NIX_SWTPM_DIR=$(readlink -f "''${NIX_SWTPM_DIR:-${config.system.name}-swtpm}") + mkdir -p "$NIX_SWTPM_DIR" + ${lib.getExe cfg.tpm.package} \ + socket \ + --tpmstate dir="$NIX_SWTPM_DIR" \ + --ctrl type=unixio,path="$NIX_SWTPM_DIR"/socket,terminate \ + --pid file="$NIX_SWTPM_DIR"/pid --daemon \ + --tpm2 \ + --log file="$NIX_SWTPM_DIR"/stdout,level=6 - cd "$TMPDIR" + # Enable `fdflags` builtin in Bash + # We will need it to perform surgical modification of the file descriptor + # passed in the coprocess to remove `FD_CLOEXEC`, i.e. close the file descriptor + # on exec. + # If let alone, it will trigger the coprocess to read EOF when QEMU is `exec` + # at the end of this script. To work around that, we will just clear + # the `FD_CLOEXEC` bits as a first step. + enable -f ${hostPkgs.bash}/lib/bash/fdflags fdflags + # leave a dangling subprocess because the swtpm ctrl socket has + # "terminate" when the last connection disconnects, it stops swtpm. + # When qemu stops, or if the main shell process ends, the coproc will + # get signaled by virtue of the pipe between main and coproc ending. + # Which in turns triggers a socat connect-disconnect to swtpm which + # will stop it. + coproc waitingswtpm { + read || : + echo "" | ${lib.getExe hostPkgs.socat} STDIO UNIX-CONNECT:"$NIX_SWTPM_DIR"/socket + } + # Clear `FD_CLOEXEC` on the coprocess' file descriptor stdin. + fdflags -s-cloexec ''${waitingswtpm[1]} + ''} - ${lib.optionalString (cfg.emptyDiskImages != [ ]) "idx=0"} - ${flip concatMapStrings cfg.emptyDiskImages (size: '' - if ! test -e "empty$idx.qcow2"; then - ${qemu}/bin/qemu-img create -f qcow2 "empty$idx.qcow2" "${toString size}M" - fi - idx=$((idx + 1)) - '')} + cd "$TMPDIR" + + ${lib.optionalString (cfg.emptyDiskImages != []) "idx=0"} + ${flip concatMapStrings cfg.emptyDiskImages (size: '' + if ! test -e "empty$idx.qcow2"; then + ${qemu}/bin/qemu-img create -f qcow2 "empty$idx.qcow2" "${toString size}M" + fi + idx=$((idx + 1)) + '')} + + # Start QEMU. + exec ${qemu-common.qemuBinary qemu} \ + -name ${config.system.name} \ + -m ${toString config.virtualisation.memorySize} \ + -smp ${toString config.virtualisation.cores} \ + -device virtio-rng-pci \ + ${concatStringsSep " " config.virtualisation.qemu.networkingOptions} \ + ${concatStringsSep " \\\n " + (mapAttrsToList + (tag: share: "-virtfs local,path=${share.source},security_model=${share.securityModel},mount_tag=${tag}") + config.virtualisation.sharedDirectories)} \ + ${drivesCmdLine config.virtualisation.qemu.drives} \ + ${concatStringsSep " \\\n " config.virtualisation.qemu.options} \ + $QEMU_OPTS \ + "$@" + ''; - # Start QEMU. - exec ${qemu-common.qemuBinary qemu} \ - -name ${config.system.name} \ - -m ${toString config.virtualisation.memorySize} \ - -smp ${toString config.virtualisation.cores} \ - -device virtio-rng-pci \ - ${concatStringsSep " " config.virtualisation.qemu.networkingOptions} \ - ${ - concatStringsSep " \\\n " ( - mapAttrsToList ( - tag: share: - "-virtfs local,path=${share.source},security_model=${share.securityModel},mount_tag=${tag}" - ) config.virtualisation.sharedDirectories - ) - } \ - ${drivesCmdLine config.virtualisation.qemu.drives} \ - ${concatStringsSep " \\\n " config.virtualisation.qemu.options} \ - $QEMU_OPTS \ - "$@" - ''; regInfo = hostPkgs.closureInfo { rootPaths = config.virtualisation.additionalPaths; }; @@ -325,243 +292,215 @@ let OVMF = cfg.efi.OVMF; }; - virtualisationOptions = import ./virtualisation-options.nix; - in { imports = [ - ./virtualisation-options.nix ../profiles/qemu-guest.nix - virtualisationOptions.diskSize - (mkRenamedOptionModule - [ - "virtualisation" - "pathsInNixDB" - ] - [ - "virtualisation" - "additionalPaths" - ] - ) - (mkRemovedOptionModule - [ - "virtualisation" - "bootDevice" - ] - "This option was renamed to `virtualisation.rootDevice`, as it was incorrectly named and misleading. Take the time to review what you want to do and look at the new options like `virtualisation.{bootLoaderDevice, bootPartition}`, open an issue in case of issues." - ) - (mkRemovedOptionModule - [ - "virtualisation" - "efiVars" - ] - "This option was removed, it is possible to provide a template UEFI variable with `virtualisation.efi.variables` ; if this option is important to you, open an issue" - ) - (mkRemovedOptionModule - [ - "virtualisation" - "persistBootDevice" - ] - "Boot device is always persisted if you use a bootloader through the root disk image ; if this does not work for your usecase, please examine carefully what `virtualisation.{bootDevice, rootDevice, bootPartition}` options offer you and open an issue explaining your need.`" - ) + (mkRenamedOptionModule [ "virtualisation" "pathsInNixDB" ] [ "virtualisation" "additionalPaths" ]) + (mkRemovedOptionModule [ "virtualisation" "bootDevice" ] "This option was renamed to `virtualisation.rootDevice`, as it was incorrectly named and misleading. Take the time to review what you want to do and look at the new options like `virtualisation.{bootLoaderDevice, bootPartition}`, open an issue in case of issues.") + (mkRemovedOptionModule [ "virtualisation" "efiVars" ] "This option was removed, it is possible to provide a template UEFI variable with `virtualisation.efi.variables` ; if this option is important to you, open an issue") + (mkRemovedOptionModule [ "virtualisation" "persistBootDevice" ] "Boot device is always persisted if you use a bootloader through the root disk image ; if this does not work for your usecase, please examine carefully what `virtualisation.{bootDevice, rootDevice, bootPartition}` options offer you and open an issue explaining your need.`") ]; options = { virtualisation.fileSystems = options.fileSystems; - virtualisation.memorySize = mkOption { - type = types.ints.positive; - default = 1024; - description = '' - The memory size in megabytes of the virtual machine. - ''; - }; - - virtualisation.msize = mkOption { - type = types.ints.positive; - default = 16384; - description = '' - The msize (maximum packet size) option passed to 9p file systems, in - bytes. Increasing this should increase performance significantly, - at the cost of higher RAM usage. - ''; - }; - - virtualisation.diskImage = mkOption { - type = types.nullOr types.str; - default = "./${config.system.name}.qcow2"; - defaultText = literalExpression ''"./''${config.system.name}.qcow2"''; - description = '' - Path to the disk image containing the root filesystem. - The image will be created on startup if it does not - exist. - - If null, a tmpfs will be used as the root filesystem and - the VM's state will not be persistent. - ''; - }; - - virtualisation.bootLoaderDevice = mkOption { - type = types.path; - default = "/dev/disk/by-id/virtio-${rootDriveSerialAttr}"; - defaultText = literalExpression ''/dev/disk/by-id/virtio-${rootDriveSerialAttr}''; - example = "/dev/disk/by-id/virtio-boot-loader-device"; - description = '' - The path (inside th VM) to the device to boot from when legacy booting. - ''; - }; - - virtualisation.bootPartition = mkOption { - type = types.nullOr types.path; - default = if cfg.useEFIBoot then "/dev/disk/by-label/${espFilesystemLabel}" else null; - defaultText = literalExpression ''if cfg.useEFIBoot then "/dev/disk/by-label/${espFilesystemLabel}" else null''; - example = "/dev/disk/by-label/esp"; - description = '' - The path (inside the VM) to the device containing the EFI System Partition (ESP). - - If you are *not* booting from a UEFI firmware, this value is, by - default, `null`. The ESP is mounted to `boot.loader.efi.efiSysMountpoint`. - ''; - }; - - virtualisation.rootDevice = mkOption { - type = types.nullOr types.path; - default = "/dev/disk/by-label/${rootFilesystemLabel}"; - defaultText = literalExpression ''/dev/disk/by-label/${rootFilesystemLabel}''; - example = "/dev/disk/by-label/nixos"; - description = '' - The path (inside the VM) to the device containing the root filesystem. - ''; - }; - - virtualisation.emptyDiskImages = mkOption { - type = types.listOf types.ints.positive; - default = [ ]; - description = '' - Additional disk images to provide to the VM. The value is - a list of size in megabytes of each disk. These disks are - writeable by the VM. - ''; - }; - - virtualisation.graphics = mkOption { - type = types.bool; - default = true; - description = '' - Whether to run QEMU with a graphics window, or in nographic mode. - Serial console will be enabled on both settings, but this will - change the preferred console. - ''; - }; - - virtualisation.resolution = mkOption { - type = options.services.xserver.resolutions.type.nestedTypes.elemType; - default = { - x = 1024; - y = 768; + virtualisation.memorySize = + mkOption { + type = types.ints.positive; + default = 1024; + description = '' + The memory size in megabytes of the virtual machine. + ''; }; - description = '' - The resolution of the virtual machine display. - ''; - }; - virtualisation.cores = mkOption { - type = types.ints.positive; - default = 1; - description = '' - Specify the number of cores the guest is permitted to use. - The number can be higher than the available cores on the - host system. - ''; - }; + virtualisation.msize = + mkOption { + type = types.ints.positive; + default = 16384; + description = '' + The msize (maximum packet size) option passed to 9p file systems, in + bytes. Increasing this should increase performance significantly, + at the cost of higher RAM usage. + ''; + }; - virtualisation.sharedDirectories = mkOption { - type = types.attrsOf ( - types.submodule { - options.source = mkOption { - type = types.str; - description = "The path of the directory to share, can be a shell variable"; - }; - options.target = mkOption { - type = types.path; - description = "The mount point of the directory inside the virtual machine"; - }; - options.securityModel = mkOption { - type = types.enum [ - "passthrough" - "mapped-xattr" - "mapped-file" - "none" - ]; - default = "mapped-xattr"; - description = '' - The security model to use for this share: + virtualisation.diskSize = + mkOption { + type = types.ints.positive; + default = 1024; + description = '' + The disk size in megabytes of the virtual machine. + ''; + }; - - `passthrough`: files are stored using the same credentials as they are created on the guest (this requires QEMU to run as root) - - `mapped-xattr`: some of the file attributes like uid, gid, mode bits and link target are stored as file attributes - - `mapped-file`: the attributes are stored in the hidden .virtfs_metadata directory. Directories exported by this security model cannot interact with other unix tools - - `none`: same as "passthrough" except the sever won't report failures if it fails to set file attributes like ownership - ''; - }; - } - ); - default = { }; - example = { - my-share = { - source = "/path/to/be/shared"; - target = "/mnt/shared"; + virtualisation.diskImage = + mkOption { + type = types.nullOr types.str; + default = "./${config.system.name}.qcow2"; + defaultText = literalExpression ''"./''${config.system.name}.qcow2"''; + description = '' + Path to the disk image containing the root filesystem. + The image will be created on startup if it does not + exist. + + If null, a tmpfs will be used as the root filesystem and + the VM's state will not be persistent. + ''; + }; + + virtualisation.bootLoaderDevice = + mkOption { + type = types.path; + default = "/dev/disk/by-id/virtio-${rootDriveSerialAttr}"; + defaultText = literalExpression ''/dev/disk/by-id/virtio-${rootDriveSerialAttr}''; + example = "/dev/disk/by-id/virtio-boot-loader-device"; + description = '' + The path (inside th VM) to the device to boot from when legacy booting. + ''; }; + + virtualisation.bootPartition = + mkOption { + type = types.nullOr types.path; + default = if cfg.useEFIBoot then "/dev/disk/by-label/${espFilesystemLabel}" else null; + defaultText = literalExpression ''if cfg.useEFIBoot then "/dev/disk/by-label/${espFilesystemLabel}" else null''; + example = "/dev/disk/by-label/esp"; + description = '' + The path (inside the VM) to the device containing the EFI System Partition (ESP). + + If you are *not* booting from a UEFI firmware, this value is, by + default, `null`. The ESP is mounted to `boot.loader.efi.efiSysMountpoint`. + ''; }; - description = '' - An attributes set of directories that will be shared with the - virtual machine using VirtFS (9P filesystem over VirtIO). - The attribute name will be used as the 9P mount tag. - ''; - }; - virtualisation.additionalPaths = mkOption { - type = types.listOf types.path; - default = [ ]; - description = '' - A list of paths whose closure should be made available to - the VM. + virtualisation.rootDevice = + mkOption { + type = types.nullOr types.path; + default = "/dev/disk/by-label/${rootFilesystemLabel}"; + defaultText = literalExpression ''/dev/disk/by-label/${rootFilesystemLabel}''; + example = "/dev/disk/by-label/nixos"; + description = '' + The path (inside the VM) to the device containing the root filesystem. + ''; + }; - When 9p is used, the closure is registered in the Nix - database in the VM. All other paths in the host Nix store - appear in the guest Nix store as well, but are considered - garbage (because they are not registered in the Nix - database of the guest). + virtualisation.emptyDiskImages = + mkOption { + type = types.listOf types.ints.positive; + default = []; + description = '' + Additional disk images to provide to the VM. The value is + a list of size in megabytes of each disk. These disks are + writeable by the VM. + ''; + }; - When {option}`virtualisation.useNixStoreImage` is - set, the closure is copied to the Nix store image. - ''; - }; + virtualisation.graphics = + mkOption { + type = types.bool; + default = true; + description = '' + Whether to run QEMU with a graphics window, or in nographic mode. + Serial console will be enabled on both settings, but this will + change the preferred console. + ''; + }; + + virtualisation.resolution = + mkOption { + type = options.services.xserver.resolutions.type.nestedTypes.elemType; + default = { x = 1024; y = 768; }; + description = '' + The resolution of the virtual machine display. + ''; + }; + + virtualisation.cores = + mkOption { + type = types.ints.positive; + default = 1; + description = '' + Specify the number of cores the guest is permitted to use. + The number can be higher than the available cores on the + host system. + ''; + }; + + virtualisation.sharedDirectories = + mkOption { + type = types.attrsOf + (types.submodule { + options.source = mkOption { + type = types.str; + description = "The path of the directory to share, can be a shell variable"; + }; + options.target = mkOption { + type = types.path; + description = "The mount point of the directory inside the virtual machine"; + }; + options.securityModel = mkOption { + type = types.enum [ "passthrough" "mapped-xattr" "mapped-file" "none" ]; + default = "mapped-xattr"; + description = '' + The security model to use for this share: + + - `passthrough`: files are stored using the same credentials as they are created on the guest (this requires QEMU to run as root) + - `mapped-xattr`: some of the file attributes like uid, gid, mode bits and link target are stored as file attributes + - `mapped-file`: the attributes are stored in the hidden .virtfs_metadata directory. Directories exported by this security model cannot interact with other unix tools + - `none`: same as "passthrough" except the sever won't report failures if it fails to set file attributes like ownership + ''; + }; + }); + default = { }; + example = { + my-share = { source = "/path/to/be/shared"; target = "/mnt/shared"; }; + }; + description = '' + An attributes set of directories that will be shared with the + virtual machine using VirtFS (9P filesystem over VirtIO). + The attribute name will be used as the 9P mount tag. + ''; + }; + + virtualisation.additionalPaths = + mkOption { + type = types.listOf types.path; + default = []; + description = '' + A list of paths whose closure should be made available to + the VM. + + When 9p is used, the closure is registered in the Nix + database in the VM. All other paths in the host Nix store + appear in the guest Nix store as well, but are considered + garbage (because they are not registered in the Nix + database of the guest). + + When {option}`virtualisation.useNixStoreImage` is + set, the closure is copied to the Nix store image. + ''; + }; virtualisation.forwardPorts = mkOption { - type = types.listOf ( - types.submodule { + type = types.listOf + (types.submodule { options.from = mkOption { - type = types.enum [ - "host" - "guest" - ]; + type = types.enum [ "host" "guest" ]; default = "host"; description = '' - Controls the direction in which the ports are mapped: + Controls the direction in which the ports are mapped: - - `"host"` means traffic from the host ports - is forwarded to the given guest port. - - `"guest"` means traffic from the guest ports - is forwarded to the given host port. - ''; + - `"host"` means traffic from the host ports + is forwarded to the given guest port. + - `"guest"` means traffic from the guest ports + is forwarded to the given host port. + ''; }; options.proto = mkOption { - type = types.enum [ - "tcp" - "udp" - ]; + type = types.enum [ "tcp" "udp" ]; default = "tcp"; description = "The protocol to forward."; }; @@ -583,10 +522,10 @@ in type = types.port; description = "The guest port to be mapped."; }; - } - ); - default = [ ]; - example = lib.literalExpression '' + }); + default = []; + example = lib.literalExpression + '' [ # forward local port 2222 -> 22, to ssh into the VM { from = "host"; host.port = 2222; guest.port = 22; } @@ -596,121 +535,122 @@ in host.address = "127.0.0.1"; host.port = 80; } ] - ''; + ''; description = '' - When using the SLiRP user networking (default), this option allows to - forward ports to/from the host/guest. + When using the SLiRP user networking (default), this option allows to + forward ports to/from the host/guest. - ::: {.warning} - If the NixOS firewall on the virtual machine is enabled, you also - have to open the guest ports to enable the traffic between host and - guest. - ::: + ::: {.warning} + If the NixOS firewall on the virtual machine is enabled, you also + have to open the guest ports to enable the traffic between host and + guest. + ::: - ::: {.note} - Currently QEMU supports only IPv4 forwarding. - ::: - ''; + ::: {.note} + Currently QEMU supports only IPv4 forwarding. + ::: + ''; }; - virtualisation.restrictNetwork = mkOption { - type = types.bool; - default = false; - example = true; - description = '' - If this option is enabled, the guest will be isolated, i.e. it will - not be able to contact the host and no guest IP packets will be - routed over the host to the outside. This option does not affect - any explicitly set forwarding rules. - ''; - }; + virtualisation.restrictNetwork = + mkOption { + type = types.bool; + default = false; + example = true; + description = '' + If this option is enabled, the guest will be isolated, i.e. it will + not be able to contact the host and no guest IP packets will be + routed over the host to the outside. This option does not affect + any explicitly set forwarding rules. + ''; + }; - virtualisation.vlans = mkOption { - type = types.listOf types.ints.unsigned; - default = if config.virtualisation.interfaces == { } then [ 1 ] else [ ]; - defaultText = lib.literalExpression ''if config.virtualisation.interfaces == {} then [ 1 ] else [ ]''; - example = [ - 1 - 2 - ]; - description = '' - Virtual networks to which the VM is connected. Each - number «N» in this list causes - the VM to have a virtual Ethernet interface attached to a - separate virtual network on which it will be assigned IP - address - `192.168.«N».«M»`, - where «M» is the index of this VM - in the list of VMs. - ''; - }; + virtualisation.vlans = + mkOption { + type = types.listOf types.ints.unsigned; + default = if config.virtualisation.interfaces == {} then [ 1 ] else [ ]; + defaultText = lib.literalExpression ''if config.virtualisation.interfaces == {} then [ 1 ] else [ ]''; + example = [ 1 2 ]; + description = '' + Virtual networks to which the VM is connected. Each + number «N» in this list causes + the VM to have a virtual Ethernet interface attached to a + separate virtual network on which it will be assigned IP + address + `192.168.«N».«M»`, + where «M» is the index of this VM + in the list of VMs. + ''; + }; virtualisation.interfaces = mkOption { - default = { }; + default = {}; example = { enp1s0.vlan = 1; }; description = '' Network interfaces to add to the VM. ''; - type = - with types; - attrsOf (submodule { - options = { - vlan = mkOption { - type = types.ints.unsigned; - description = '' - VLAN to which the network interface is connected. - ''; - }; - - assignIP = mkOption { - type = types.bool; - default = false; - description = '' - Automatically assign an IP address to the network interface using the same scheme as - virtualisation.vlans. - ''; - }; + type = with types; attrsOf (submodule { + options = { + vlan = mkOption { + type = types.ints.unsigned; + description = '' + VLAN to which the network interface is connected. + ''; }; - }); + + assignIP = mkOption { + type = types.bool; + default = false; + description = '' + Automatically assign an IP address to the network interface using the same scheme as + virtualisation.vlans. + ''; + }; + }; + }); }; - virtualisation.writableStore = mkOption { - type = types.bool; - default = cfg.mountHostNixStore; - defaultText = literalExpression "cfg.mountHostNixStore"; - description = '' - If enabled, the Nix store in the VM is made writable by - layering an overlay filesystem on top of the host's Nix - store. + virtualisation.writableStore = + mkOption { + type = types.bool; + default = cfg.mountHostNixStore; + defaultText = literalExpression "cfg.mountHostNixStore"; + description = '' + If enabled, the Nix store in the VM is made writable by + layering an overlay filesystem on top of the host's Nix + store. - By default, this is enabled if you mount a host Nix store. - ''; - }; + By default, this is enabled if you mount a host Nix store. + ''; + }; - virtualisation.writableStoreUseTmpfs = mkOption { - type = types.bool; - default = true; - description = '' - Use a tmpfs for the writable store instead of writing to the VM's - own filesystem. - ''; - }; + virtualisation.writableStoreUseTmpfs = + mkOption { + type = types.bool; + default = true; + description = '' + Use a tmpfs for the writable store instead of writing to the VM's + own filesystem. + ''; + }; - networking.primaryIPAddress = mkOption { - type = types.str; - default = ""; - internal = true; - description = "Primary IP address used in /etc/hosts."; - }; + networking.primaryIPAddress = + mkOption { + type = types.str; + default = ""; + internal = true; + description = "Primary IP address used in /etc/hosts."; + }; - networking.primaryIPv6Address = mkOption { - type = types.str; - default = ""; - internal = true; - description = "Primary IPv6 address used in /etc/hosts."; - }; + networking.primaryIPv6Address = + mkOption { + type = types.str; + default = ""; + internal = true; + description = "Primary IPv6 address used in /etc/hosts."; + }; virtualisation.host.pkgs = mkOption { type = options.nixpkgs.pkgs.type; @@ -726,38 +666,31 @@ in }; virtualisation.qemu = { - package = mkOption { - type = types.package; - default = - if hostPkgs.stdenv.hostPlatform.qemuArch == pkgs.stdenv.hostPlatform.qemuArch then - hostPkgs.qemu_kvm - else - hostPkgs.qemu; - defaultText = literalExpression "if hostPkgs.stdenv.hostPlatform.qemuArch == pkgs.stdenv.hostPlatform.qemuArch then config.virtualisation.host.pkgs.qemu_kvm else config.virtualisation.host.pkgs.qemu"; - example = literalExpression "pkgs.qemu_test"; - description = "QEMU package to use."; - }; + package = + mkOption { + type = types.package; + default = if hostPkgs.stdenv.hostPlatform.qemuArch == pkgs.stdenv.hostPlatform.qemuArch then hostPkgs.qemu_kvm else hostPkgs.qemu; + defaultText = literalExpression "if hostPkgs.stdenv.hostPlatform.qemuArch == pkgs.stdenv.hostPlatform.qemuArch then config.virtualisation.host.pkgs.qemu_kvm else config.virtualisation.host.pkgs.qemu"; + example = literalExpression "pkgs.qemu_test"; + description = "QEMU package to use."; + }; - options = mkOption { - type = types.listOf types.str; - default = [ ]; - example = [ "-vga std" ]; - description = '' - Options passed to QEMU. - See [QEMU User Documentation](https://www.qemu.org/docs/master/system/qemu-manpage) for a complete list. - ''; - }; + options = + mkOption { + type = types.listOf types.str; + default = []; + example = [ "-vga std" ]; + description = '' + Options passed to QEMU. + See [QEMU User Documentation](https://www.qemu.org/docs/master/system/qemu-manpage) for a complete list. + ''; + }; consoles = mkOption { type = types.listOf types.str; - default = - let - consoles = [ - "${qemu-common.qemuSerialDevice},115200n8" - "tty0" - ]; - in - if cfg.graphics then consoles else reverseList consoles; + default = let + consoles = [ "${qemu-common.qemuSerialDevice},115200n8" "tty0" ]; + in if cfg.graphics then consoles else reverseList consoles; example = [ "console=tty1" ]; description = '' The output console devices to pass to the kernel command line via the @@ -770,158 +703,163 @@ in ''; }; - networkingOptions = mkOption { - type = types.listOf types.str; - default = [ ]; - example = [ - "-net nic,netdev=user.0,model=virtio" - "-netdev user,id=user.0,\${QEMU_NET_OPTS:+,$QEMU_NET_OPTS}" - ]; - description = '' - Networking-related command-line options that should be passed to qemu. - The default is to use userspace networking (SLiRP). - See the [QEMU Wiki on Networking](https://wiki.qemu.org/Documentation/Networking) for details. + networkingOptions = + mkOption { + type = types.listOf types.str; + default = [ ]; + example = [ + "-net nic,netdev=user.0,model=virtio" + "-netdev user,id=user.0,\${QEMU_NET_OPTS:+,$QEMU_NET_OPTS}" + ]; + description = '' + Networking-related command-line options that should be passed to qemu. + The default is to use userspace networking (SLiRP). + See the [QEMU Wiki on Networking](https://wiki.qemu.org/Documentation/Networking) for details. - If you override this option, be advised to keep - `''${QEMU_NET_OPTS:+,$QEMU_NET_OPTS}` (as seen in the example) - to keep the default runtime behaviour. - ''; - }; + If you override this option, be advised to keep + `''${QEMU_NET_OPTS:+,$QEMU_NET_OPTS}` (as seen in the example) + to keep the default runtime behaviour. + ''; + }; - drives = mkOption { - type = types.listOf (types.submodule driveOpts); - description = "Drives passed to qemu."; - }; + drives = + mkOption { + type = types.listOf (types.submodule driveOpts); + description = "Drives passed to qemu."; + }; - diskInterface = mkOption { - type = types.enum [ - "virtio" - "scsi" - "ide" - ]; - default = "virtio"; - example = "scsi"; - description = "The interface used for the virtual hard disks."; - }; + diskInterface = + mkOption { + type = types.enum [ "virtio" "scsi" "ide" ]; + default = "virtio"; + example = "scsi"; + description = "The interface used for the virtual hard disks."; + }; - guestAgent.enable = mkOption { + guestAgent.enable = + mkOption { + type = types.bool; + default = true; + description = '' + Enable the Qemu guest agent. + ''; + }; + + virtioKeyboard = + mkOption { + type = types.bool; + default = true; + description = '' + Enable the virtio-keyboard device. + ''; + }; + }; + + virtualisation.useNixStoreImage = + mkOption { type = types.bool; - default = true; + default = false; description = '' - Enable the Qemu guest agent. + Build and use a disk image for the Nix store, instead of + accessing the host's one through 9p. + + For applications which do a lot of reads from the store, + this can drastically improve performance, but at the cost of + disk space and image build time. + + The Nix store image is built just-in-time right before the VM is + started. Because it does not produce another derivation, the image is + not cached between invocations and never lands in the store or binary + cache. + + If you want a full disk image with a partition table and a root + filesystem instead of only a store image, enable + {option}`virtualisation.useBootLoader` instead. ''; }; - virtioKeyboard = mkOption { + virtualisation.mountHostNixStore = + mkOption { type = types.bool; - default = true; + default = !cfg.useNixStoreImage && !cfg.useBootLoader; + defaultText = literalExpression "!cfg.useNixStoreImage && !cfg.useBootLoader"; description = '' - Enable the virtio-keyboard device. + Mount the host Nix store as a 9p mount. ''; }; - }; - - virtualisation.useNixStoreImage = mkOption { - type = types.bool; - default = false; - description = '' - Build and use a disk image for the Nix store, instead of - accessing the host's one through 9p. - - For applications which do a lot of reads from the store, - this can drastically improve performance, but at the cost of - disk space and image build time. - - The Nix store image is built just-in-time right before the VM is - started. Because it does not produce another derivation, the image is - not cached between invocations and never lands in the store or binary - cache. - - If you want a full disk image with a partition table and a root - filesystem instead of only a store image, enable - {option}`virtualisation.useBootLoader` instead. - ''; - }; - - virtualisation.mountHostNixStore = mkOption { - type = types.bool; - default = !cfg.useNixStoreImage && !cfg.useBootLoader; - defaultText = literalExpression "!cfg.useNixStoreImage && !cfg.useBootLoader"; - description = '' - Mount the host Nix store as a 9p mount. - ''; - }; virtualisation.directBoot = { - enable = mkOption { + enable = + mkOption { + type = types.bool; + default = !cfg.useBootLoader; + defaultText = "!cfg.useBootLoader"; + description = '' + If enabled, the virtual machine will boot directly into the kernel instead of through a bootloader. + Read more about this feature in the [QEMU documentation on Direct Linux Boot](https://qemu-project.gitlab.io/qemu/system/linuxboot.html) + + This is enabled by default. + If you want to test netboot, consider disabling this option. + Enable a bootloader with {option}`virtualisation.useBootLoader` if you need. + + Relevant parameters such as those set in `boot.initrd` and `boot.kernelParams` are also passed to QEMU. + Additional parameters can be supplied on invocation through the environment variable `$QEMU_KERNEL_PARAMS`. + They are added to the `-append` option, see [QEMU User Documentation](https://www.qemu.org/docs/master/system/qemu-manpage) for details + For example, to let QEMU use the parent terminal as the serial console, set `QEMU_KERNEL_PARAMS="console=ttyS0"`. + + This will not (re-)boot correctly into a system that has switched to a different configuration on disk. + ''; + }; + initrd = + mkOption { + type = types.str; + default = "${config.system.build.initialRamdisk}/${config.system.boot.loader.initrdFile}"; + defaultText = "\${config.system.build.initialRamdisk}/\${config.system.boot.loader.initrdFile}"; + description = '' + In direct boot situations, you may want to influence the initrd to load + to use your own customized payload. + + This is useful if you want to test the netboot image without + testing the firmware or the loading part. + ''; + }; + }; + + virtualisation.useBootLoader = + mkOption { type = types.bool; - default = !cfg.useBootLoader; - defaultText = "!cfg.useBootLoader"; + default = false; description = '' - If enabled, the virtual machine will boot directly into the kernel instead of through a bootloader. - Read more about this feature in the [QEMU documentation on Direct Linux Boot](https://qemu-project.gitlab.io/qemu/system/linuxboot.html) + Use a boot loader to boot the system. + This allows, among other things, testing the boot loader. - This is enabled by default. - If you want to test netboot, consider disabling this option. - Enable a bootloader with {option}`virtualisation.useBootLoader` if you need. + If disabled, the kernel and initrd are directly booted, + forgoing any bootloader. - Relevant parameters such as those set in `boot.initrd` and `boot.kernelParams` are also passed to QEMU. - Additional parameters can be supplied on invocation through the environment variable `$QEMU_KERNEL_PARAMS`. - They are added to the `-append` option, see [QEMU User Documentation](https://www.qemu.org/docs/master/system/qemu-manpage) for details - For example, to let QEMU use the parent terminal as the serial console, set `QEMU_KERNEL_PARAMS="console=ttyS0"`. - - This will not (re-)boot correctly into a system that has switched to a different configuration on disk. - ''; + Check the documentation on {option}`virtualisation.directBoot.enable` for details. + ''; }; - initrd = mkOption { - type = types.str; - default = "${config.system.build.initialRamdisk}/${config.system.boot.loader.initrdFile}"; - defaultText = "\${config.system.build.initialRamdisk}/\${config.system.boot.loader.initrdFile}"; + + virtualisation.useEFIBoot = + mkOption { + type = types.bool; + default = false; description = '' - In direct boot situations, you may want to influence the initrd to load - to use your own customized payload. - - This is useful if you want to test the netboot image without - testing the firmware or the loading part. - ''; - }; - }; - - virtualisation.useBootLoader = mkOption { - type = types.bool; - default = false; - description = '' - Use a boot loader to boot the system. - This allows, among other things, testing the boot loader. - - If disabled, the kernel and initrd are directly booted, - forgoing any bootloader. - - Check the documentation on {option}`virtualisation.directBoot.enable` for details. - ''; - }; - - virtualisation.useEFIBoot = mkOption { - type = types.bool; - default = false; - description = '' - If enabled, the virtual machine will provide a EFI boot - manager. - useEFIBoot is ignored if useBootLoader == false. - ''; - }; + If enabled, the virtual machine will provide a EFI boot + manager. + useEFIBoot is ignored if useBootLoader == false. + ''; + }; virtualisation.efi = { OVMF = mkOption { type = types.package; - default = - (pkgs.OVMF.override { - secureBoot = cfg.useSecureBoot; - }).fd; - defaultText = '' - (pkgs.OVMF.override { - secureBoot = cfg.useSecureBoot; - }).fd''; + default = (pkgs.OVMF.override { + secureBoot = cfg.useSecureBoot; + }).fd; + defaultText = ''(pkgs.OVMF.override { + secureBoot = cfg.useSecureBoot; + }).fd''; description = "OVMF firmware package, defaults to OVMF configured with secure boot if needed."; }; @@ -930,8 +868,8 @@ in default = cfg.efi.OVMF.firmware; defaultText = literalExpression "cfg.efi.OVMF.firmware"; description = '' - Firmware binary for EFI implementation, defaults to OVMF. - ''; + Firmware binary for EFI implementation, defaults to OVMF. + ''; }; variables = mkOption { @@ -939,9 +877,9 @@ in default = cfg.efi.OVMF.variables; defaultText = literalExpression "cfg.efi.OVMF.variables"; description = '' - Platform-specific flash binary for EFI variables, implementation-dependent to the EFI firmware. - Defaults to OVMF. - ''; + Platform-specific flash binary for EFI variables, implementation-dependent to the EFI firmware. + Defaults to OVMF. + ''; }; keepVariables = mkOption { @@ -959,16 +897,13 @@ in deviceModel = mkOption { type = types.str; - default = ( - { - "i686-linux" = "tpm-tis"; - "x86_64-linux" = "tpm-tis"; - "ppc64-linux" = "tpm-spapr"; - "armv7-linux" = "tpm-tis-device"; - "aarch64-linux" = "tpm-tis-device"; - } - .${pkgs.stdenv.hostPlatform.system} or (throw "Unsupported system for TPM2 emulation in QEMU") - ); + default = ({ + "i686-linux" = "tpm-tis"; + "x86_64-linux" = "tpm-tis"; + "ppc64-linux" = "tpm-spapr"; + "armv7-linux" = "tpm-tis-device"; + "aarch64-linux" = "tpm-tis-device"; + }.${pkgs.stdenv.hostPlatform.system} or (throw "Unsupported system for TPM2 emulation in QEMU")); defaultText = '' Based on the guest platform Linux system: @@ -981,97 +916,97 @@ in }; }; - virtualisation.useDefaultFilesystems = mkOption { - type = types.bool; - default = true; - description = '' - If enabled, the boot disk of the virtual machine will be - formatted and mounted with the default filesystems for - testing. Swap devices and LUKS will be disabled. + virtualisation.useDefaultFilesystems = + mkOption { + type = types.bool; + default = true; + description = '' + If enabled, the boot disk of the virtual machine will be + formatted and mounted with the default filesystems for + testing. Swap devices and LUKS will be disabled. - If disabled, a root filesystem has to be specified and - formatted (for example in the initial ramdisk). - ''; - }; + If disabled, a root filesystem has to be specified and + formatted (for example in the initial ramdisk). + ''; + }; - virtualisation.useSecureBoot = mkOption { - type = types.bool; - default = false; - description = '' - Enable Secure Boot support in the EFI firmware. - ''; - }; + virtualisation.useSecureBoot = + mkOption { + type = types.bool; + default = false; + description = '' + Enable Secure Boot support in the EFI firmware. + ''; + }; - virtualisation.bios = mkOption { - type = types.nullOr types.package; - default = null; - description = '' - An alternate BIOS (such as `qboot`) with which to start the VM. - Should contain a file named `bios.bin`. - If `null`, QEMU's builtin SeaBIOS will be used. - ''; - }; + virtualisation.bios = + mkOption { + type = types.nullOr types.package; + default = null; + description = '' + An alternate BIOS (such as `qboot`) with which to start the VM. + Should contain a file named `bios.bin`. + If `null`, QEMU's builtin SeaBIOS will be used. + ''; + }; - virtualisation.useHostCerts = mkOption { - type = types.bool; - default = false; - description = '' - If enabled, when `NIX_SSL_CERT_FILE` is set on the host, - pass the CA certificates from the host to the VM. - ''; - }; + virtualisation.useHostCerts = + mkOption { + type = types.bool; + default = false; + description = '' + If enabled, when `NIX_SSL_CERT_FILE` is set on the host, + pass the CA certificates from the host to the VM. + ''; + }; }; config = { assertions = - lib.concatLists ( - lib.flip lib.imap cfg.forwardPorts ( - i: rule: [ - { - assertion = rule.from == "guest" -> rule.proto == "tcp"; - message = '' + lib.concatLists (lib.flip lib.imap cfg.forwardPorts (i: rule: + [ + { assertion = rule.from == "guest" -> rule.proto == "tcp"; + message = + '' Invalid virtualisation.forwardPorts..proto: Guest forwarding supports only TCP connections. ''; - } - { - assertion = rule.from == "guest" -> lib.hasPrefix "10.0.2." rule.guest.address; - message = '' + } + { assertion = rule.from == "guest" -> lib.hasPrefix "10.0.2." rule.guest.address; + message = + '' Invalid virtualisation.forwardPorts..guest.address: The address must be in the default VLAN (10.0.2.0/24). ''; - } - ] - ) - ) - ++ [ - { - assertion = pkgs.stdenv.hostPlatform.is32bit -> cfg.memorySize < 2047; - message = '' - virtualisation.memorySize is above 2047, but qemu is only able to allocate 2047MB RAM on 32bit max. - ''; - } - { - assertion = - cfg.directBoot.enable || cfg.directBoot.initrd == options.virtualisation.directBoot.initrd.default; - message = '' - You changed the default of `virtualisation.directBoot.initrd` but you are not - using QEMU direct boot. This initrd will not be used in your current - boot configuration. + } + ])) ++ [ + { assertion = pkgs.stdenv.hostPlatform.is32bit -> cfg.memorySize < 2047; + message = '' + virtualisation.memorySize is above 2047, but qemu is only able to allocate 2047MB RAM on 32bit max. + ''; + } + { assertion = cfg.directBoot.enable || cfg.directBoot.initrd == options.virtualisation.directBoot.initrd.default; + message = + '' + You changed the default of `virtualisation.directBoot.initrd` but you are not + using QEMU direct boot. This initrd will not be used in your current + boot configuration. - Either do not mutate `virtualisation.directBoot.initrd` or enable direct boot. + Either do not mutate `virtualisation.directBoot.initrd` or enable direct boot. - If you have a more advanced usecase, please open an issue or a pull request. - ''; - } - ]; + If you have a more advanced usecase, please open an issue or a pull request. + ''; + } + ]; - warnings = optional (cfg.directBoot.enable && cfg.useBootLoader) '' - You enabled direct boot and a bootloader, QEMU will not boot your bootloader, rendering - `useBootLoader` useless. You might want to disable one of those options. - ''; + warnings = + optional (cfg.directBoot.enable && cfg.useBootLoader) + '' + You enabled direct boot and a bootloader, QEMU will not boot your bootloader, rendering + `useBootLoader` useless. You might want to disable one of those options. + ''; # In UEFI boot, we use a EFI-only partition table layout, thus GRUB will fail when trying to install # legacy and UEFI. In order to avoid this, we have to put "nodev" to force UEFI-only installs. @@ -1089,11 +1024,12 @@ in # allow `system.build.toplevel' to be included. (If we had a direct # reference to ${regInfo} here, then we would get a cyclic # dependency.) - boot.postBootCommands = lib.mkIf config.nix.enable '' - if [[ "$(cat /proc/cmdline)" =~ regInfo=([^ ]*) ]]; then - ${config.nix.package.out}/bin/nix-store --load-db < ''${BASH_REMATCH[1]} - fi - ''; + boot.postBootCommands = lib.mkIf config.nix.enable + '' + if [[ "$(cat /proc/cmdline)" =~ regInfo=([^ ]*) ]]; then + ${config.nix.package.out}/bin/nix-store --load-db < ''${BASH_REMATCH[1]} + fi + ''; boot.initrd.availableKernelModules = optional (cfg.qemu.diskInterface == "scsi") "sym53c8xx" @@ -1130,20 +1066,14 @@ in virtualisation.qemu.networkingOptions = let - forwardingOptions = flip concatMapStrings cfg.forwardPorts ( - { - proto, - from, - host, - guest, - }: - if from == "host" then - "hostfwd=${proto}:${host.address}:${toString host.port}-" - + "${guest.address}:${toString guest.port}," - else - "'guestfwd=${proto}:${guest.address}:${toString guest.port}-" - + "cmd:${pkgs.netcat}/bin/nc ${host.address} ${toString host.port}'," - ); + forwardingOptions = flip concatMapStrings cfg.forwardPorts + ({ proto, from, host, guest }: + if from == "host" + then "hostfwd=${proto}:${host.address}:${toString host.port}-" + + "${guest.address}:${toString guest.port}," + else "'guestfwd=${proto}:${guest.address}:${toString guest.port}-" + + "cmd:${pkgs.netcat}/bin/nc ${host.address} ${toString host.port}'," + ); restrictNetworkOption = lib.optionalString cfg.restrictNetwork "restrict=on,"; in [ @@ -1156,29 +1086,20 @@ in "-device virtio-keyboard" ]) (mkIf pkgs.stdenv.hostPlatform.isx86 [ - "-usb" - "-device usb-tablet,bus=usb-bus.0" + "-usb" "-device usb-tablet,bus=usb-bus.0" ]) (mkIf pkgs.stdenv.hostPlatform.isAarch [ - "-device virtio-gpu-pci" - "-device usb-ehci,id=usb0" - "-device usb-kbd" - "-device usb-tablet" + "-device virtio-gpu-pci" "-device usb-ehci,id=usb0" "-device usb-kbd" "-device usb-tablet" + ]) + (let + alphaNumericChars = lowerChars ++ upperChars ++ (map toString (range 0 9)); + # Replace all non-alphanumeric characters with underscores + sanitizeShellIdent = s: concatMapStrings (c: if builtins.elem c alphaNumericChars then c else "_") (stringToCharacters s); + in mkIf cfg.directBoot.enable [ + "-kernel \${NIXPKGS_QEMU_KERNEL_${sanitizeShellIdent config.system.name}:-${config.system.build.toplevel}/kernel}" + "-initrd ${cfg.directBoot.initrd}" + ''-append "$(cat ${config.system.build.toplevel}/kernel-params) init=${config.system.build.toplevel}/init regInfo=${regInfo}/registration ${consoles} $QEMU_KERNEL_PARAMS"'' ]) - ( - let - alphaNumericChars = lowerChars ++ upperChars ++ (map toString (range 0 9)); - # Replace all non-alphanumeric characters with underscores - sanitizeShellIdent = - s: - concatMapStrings (c: if builtins.elem c alphaNumericChars then c else "_") (stringToCharacters s); - in - mkIf cfg.directBoot.enable [ - "-kernel \${NIXPKGS_QEMU_KERNEL_${sanitizeShellIdent config.system.name}:-${config.system.build.toplevel}/kernel}" - "-initrd ${cfg.directBoot.initrd}" - ''-append "$(cat ${config.system.build.toplevel}/kernel-params) init=${config.system.build.toplevel}/init regInfo=${regInfo}/registration ${consoles} $QEMU_KERNEL_PARAMS"'' - ] - ) (mkIf cfg.useEFIBoot [ "-drive if=pflash,format=raw,unit=0,readonly=on,file=${cfg.efi.firmware}" "-drive if=pflash,format=raw,unit=1,readonly=off,file=$NIX_EFI_VARS" @@ -1195,32 +1116,26 @@ in "-device ${cfg.tpm.deviceModel},tpmdev=tpm_dev_0" ]) (mkIf (pkgs.stdenv.hostPlatform.isx86 && cfg.efi.OVMF.systemManagementModeRequired) [ - "-machine" - "q35,smm=on" - "-global" - "driver=cfi.pflash01,property=secure,value=on" + "-machine" "q35,smm=on" + "-global" "driver=cfi.pflash01,property=secure,value=on" ]) ]; virtualisation.qemu.drives = mkMerge [ - (mkIf (cfg.diskImage != null) [ - { - name = "root"; - file = ''"$NIX_DISK_IMAGE"''; - driveExtraOpts.cache = "writeback"; - driveExtraOpts.werror = "report"; - deviceExtraOpts.bootindex = "1"; - deviceExtraOpts.serial = rootDriveSerialAttr; - } - ]) - (mkIf cfg.useNixStoreImage [ - { - name = "nix-store"; - file = ''"$TMPDIR"/store.img''; - deviceExtraOpts.bootindex = "2"; - driveExtraOpts.format = "raw"; - } - ]) + (mkIf (cfg.diskImage != null) [{ + name = "root"; + file = ''"$NIX_DISK_IMAGE"''; + driveExtraOpts.cache = "writeback"; + driveExtraOpts.werror = "report"; + deviceExtraOpts.bootindex = "1"; + deviceExtraOpts.serial = rootDriveSerialAttr; + }]) + (mkIf cfg.useNixStoreImage [{ + name = "nix-store"; + file = ''"$TMPDIR"/store.img''; + deviceExtraOpts.bootindex = "2"; + driveExtraOpts.format = "raw"; + }]) (imap0 (idx: _: { file = "$(pwd)/empty${toString idx}.qcow2"; driveExtraOpts.werror = "report"; @@ -1234,115 +1149,91 @@ in # override by setting `virtualisation.fileSystems = lib.mkForce { };`. fileSystems = lib.mkIf (cfg.fileSystems != { }) (mkVMOverride cfg.fileSystems); - virtualisation.diskSizeAutoSupported = false; - - virtualisation.fileSystems = - let - mkSharedDir = tag: share: { + virtualisation.fileSystems = let + mkSharedDir = tag: share: + { name = share.target; value.device = tag; value.fsType = "9p"; value.neededForBoot = true; - value.options = [ - "trans=virtio" - "version=9p2000.L" - "msize=${toString cfg.msize}" - ] ++ lib.optional (tag == "nix-store") "cache=loose"; + value.options = + [ "trans=virtio" "version=9p2000.L" "msize=${toString cfg.msize}" ] + ++ lib.optional (tag == "nix-store") "cache=loose"; }; - in - lib.mkMerge [ - (lib.mapAttrs' mkSharedDir cfg.sharedDirectories) - { - "/" = lib.mkIf cfg.useDefaultFilesystems ( - if cfg.diskImage == null then - { - device = "tmpfs"; - fsType = "tmpfs"; - } - else - { - device = cfg.rootDevice; - fsType = "ext4"; - } - ); - "/tmp" = lib.mkIf config.boot.tmp.useTmpfs { - device = "tmpfs"; - fsType = "tmpfs"; - neededForBoot = true; - # Sync with systemd's tmp.mount; - options = [ - "mode=1777" - "strictatime" - "nosuid" - "nodev" - "size=${toString config.boot.tmp.tmpfsSize}" - ]; + in lib.mkMerge [ + (lib.mapAttrs' mkSharedDir cfg.sharedDirectories) + { + "/" = lib.mkIf cfg.useDefaultFilesystems (if cfg.diskImage == null then { + device = "tmpfs"; + fsType = "tmpfs"; + } else { + device = cfg.rootDevice; + fsType = "ext4"; + }); + "/tmp" = lib.mkIf config.boot.tmp.useTmpfs { + device = "tmpfs"; + fsType = "tmpfs"; + neededForBoot = true; + # Sync with systemd's tmp.mount; + options = [ "mode=1777" "strictatime" "nosuid" "nodev" "size=${toString config.boot.tmp.tmpfsSize}" ]; + }; + "/nix/store" = lib.mkIf (cfg.useNixStoreImage || cfg.mountHostNixStore) (if cfg.writableStore then { + overlay = { + lowerdir = [ "/nix/.ro-store" ]; + upperdir = "/nix/.rw-store/upper"; + workdir = "/nix/.rw-store/work"; }; - "/nix/store" = lib.mkIf (cfg.useNixStoreImage || cfg.mountHostNixStore) ( - if cfg.writableStore then - { - overlay = { - lowerdir = [ "/nix/.ro-store" ]; - upperdir = "/nix/.rw-store/upper"; - workdir = "/nix/.rw-store/work"; - }; - } - else - { - device = "/nix/.ro-store"; - options = [ "bind" ]; - } - ); - "/nix/.ro-store" = lib.mkIf cfg.useNixStoreImage { - device = "/dev/disk/by-label/${nixStoreFilesystemLabel}"; - fsType = "erofs"; - neededForBoot = true; - options = [ "ro" ]; - }; - "/nix/.rw-store" = lib.mkIf (cfg.writableStore && cfg.writableStoreUseTmpfs) { - fsType = "tmpfs"; - options = [ "mode=0755" ]; - neededForBoot = true; - }; - "${config.boot.loader.efi.efiSysMountPoint}" = - lib.mkIf (cfg.useBootLoader && cfg.bootPartition != null) - { - device = cfg.bootPartition; - fsType = "vfat"; - }; - } - ]; + } else { + device = "/nix/.ro-store"; + options = [ "bind" ]; + }); + "/nix/.ro-store" = lib.mkIf cfg.useNixStoreImage { + device = "/dev/disk/by-label/${nixStoreFilesystemLabel}"; + fsType = "erofs"; + neededForBoot = true; + options = [ "ro" ]; + }; + "/nix/.rw-store" = lib.mkIf (cfg.writableStore && cfg.writableStoreUseTmpfs) { + fsType = "tmpfs"; + options = [ "mode=0755" ]; + neededForBoot = true; + }; + "${config.boot.loader.efi.efiSysMountPoint}" = lib.mkIf (cfg.useBootLoader && cfg.bootPartition != null) { + device = cfg.bootPartition; + fsType = "vfat"; + }; + } + ]; swapDevices = (if cfg.useDefaultFilesystems then mkVMOverride else mkDefault) [ ]; - boot.initrd.luks.devices = (if cfg.useDefaultFilesystems then mkVMOverride else mkDefault) { }; + boot.initrd.luks.devices = (if cfg.useDefaultFilesystems then mkVMOverride else mkDefault) {}; # Don't run ntpd in the guest. It should get the correct time from KVM. services.timesyncd.enable = false; services.qemuGuest.enable = cfg.qemu.guestAgent.enable; - system.build.vm = - hostPkgs.runCommand "nixos-vm" - { - preferLocalBuild = true; - meta.mainProgram = "run-${config.system.name}-vm"; - } - '' - mkdir -p $out/bin - ln -s ${config.system.build.toplevel} $out/system - ln -s ${hostPkgs.writeScript "run-nixos-vm" startVM} $out/bin/run-${config.system.name}-vm - ''; + system.build.vm = hostPkgs.runCommand "nixos-vm" { + preferLocalBuild = true; + meta.mainProgram = "run-${config.system.name}-vm"; + } + '' + mkdir -p $out/bin + ln -s ${config.system.build.toplevel} $out/system + ln -s ${hostPkgs.writeScript "run-nixos-vm" startVM} $out/bin/run-${config.system.name}-vm + ''; # When building a regular system configuration, override whatever # video driver the host uses. services.xserver.videoDrivers = mkVMOverride [ "modesetting" ]; services.xserver.defaultDepth = mkVMOverride 0; services.xserver.resolutions = mkVMOverride [ cfg.resolution ]; - services.xserver.monitorSection = '' - # Set a higher refresh rate so that resolutions > 800x600 work. - HorizSync 30-140 - VertRefresh 50-160 - ''; + services.xserver.monitorSection = + '' + # Set a higher refresh rate so that resolutions > 800x600 work. + HorizSync 30-140 + VertRefresh 50-160 + ''; # Wireless won't work in the VM. networking.wireless.enable = mkVMOverride false; @@ -1353,10 +1244,8 @@ in networking.usePredictableInterfaceNames = false; - system.requiredKernelConfig = - with config.lib.kernelConfig; - [ - (isEnabled "VIRTIO_BLK") + system.requiredKernelConfig = with config.lib.kernelConfig; + [ (isEnabled "VIRTIO_BLK") (isEnabled "VIRTIO_PCI") (isEnabled "VIRTIO_NET") (isEnabled "EXT4_FS") @@ -1368,12 +1257,10 @@ in (isYes "NET_CORE") (isYes "INET") (isYes "NETWORK_FILESYSTEMS") - ] - ++ optionals (!cfg.graphics) [ + ] ++ optionals (!cfg.graphics) [ (isYes "SERIAL_8250_CONSOLE") (isYes "SERIAL_8250") - ] - ++ optionals (cfg.writableStore) [ + ] ++ optionals (cfg.writableStore) [ (isEnabled "OVERLAY_FS") ]; diff --git a/nixos/modules/virtualisation/virtualbox-image.nix b/nixos/modules/virtualisation/virtualbox-image.nix index de9be384a7fe..1c8b9b99c01c 100644 --- a/nixos/modules/virtualisation/virtualbox-image.nix +++ b/nixos/modules/virtualisation/virtualbox-image.nix @@ -1,37 +1,23 @@ -{ - config, - lib, - pkgs, - ... -}: +{ config, lib, pkgs, ... }: with lib; let cfg = config.virtualbox; - virtualisationOptions = import ./virtualisation-options.nix; -in -{ - imports = [ - virtualisationOptions.diskSize - (lib.mkRenamedOptionModuleWith { - sinceRelease = 2411; - from = [ - "virtualisation" - "virtualbox" - "baseImageSize" - ]; - to = [ - "virtualisation" - "diskSize" - ]; - }) - ]; +in { options = { virtualbox = { + baseImageSize = mkOption { + type = with types; either (enum [ "auto" ]) int; + default = "auto"; + example = 50 * 1024; + description = '' + The size of the VirtualBox base image in MiB. + ''; + }; baseImageFreeSpace = mkOption { type = with types; int; default = 30 * 1024; @@ -68,14 +54,7 @@ in ''; }; params = mkOption { - type = - with types; - attrsOf (oneOf [ - str - int - bool - (listOf str) - ]); + type = with types; attrsOf (oneOf [ str int bool (listOf str) ]); example = { audio = "alsa"; rtcuseutc = "on"; @@ -88,21 +67,11 @@ in ''; }; exportParams = mkOption { - type = - with types; - listOf (oneOf [ - str - int - bool - (listOf str) - ]); + type = with types; listOf (oneOf [ str int bool (listOf str) ]); example = [ - "--vsys" - "0" - "--vendor" - "ACME Inc." + "--vsys" "0" "--vendor" "ACME Inc." ]; - default = [ ]; + default = []; description = '' Parameters passed to the Virtualbox export command. @@ -120,25 +89,23 @@ in mountPoint = "/home/demo/storage"; size = 100 * 1024; }; - type = types.nullOr ( - types.submodule { - options = { - size = mkOption { - type = types.int; - description = "Size in MiB"; - }; - label = mkOption { - type = types.str; - default = "vm-extra-storage"; - description = "Label for the disk partition"; - }; - mountPoint = mkOption { - type = types.str; - description = "Path where to mount this disk."; - }; + type = types.nullOr (types.submodule { + options = { + size = mkOption { + type = types.int; + description = "Size in MiB"; }; - } - ); + label = mkOption { + type = types.str; + default = "vm-extra-storage"; + description = "Label for the disk partition"; + }; + mountPoint = mkOption { + type = types.str; + description = "Path where to mount this disk."; + }; + }; + }); }; postExportCommands = mkOption { type = types.lines; @@ -158,14 +125,7 @@ in ''; }; storageController = mkOption { - type = - with types; - attrsOf (oneOf [ - str - int - bool - (listOf str) - ]); + type = with types; attrsOf (oneOf [ str int bool (listOf str) ]); example = { name = "SCSI"; add = "scsi"; @@ -192,8 +152,6 @@ in config = { - virtualisation.diskSize = lib.mkDefault (50 * 1024); - virtualbox.params = mkMerge [ (mapAttrs (name: mkDefault) { acpi = "on"; @@ -217,83 +175,80 @@ in inherit pkgs lib config; partitionTableType = "legacy"; - inherit (config.virtualisation) diskSize; + diskSize = cfg.baseImageSize; additionalSpace = "${toString cfg.baseImageFreeSpace}M"; - postVM = '' - export HOME=$PWD - export PATH=${pkgs.virtualbox}/bin:$PATH + postVM = + '' + export HOME=$PWD + export PATH=${pkgs.virtualbox}/bin:$PATH - echo "converting image to VirtualBox format..." - VBoxManage convertfromraw $diskImage disk.vdi + echo "converting image to VirtualBox format..." + VBoxManage convertfromraw $diskImage disk.vdi - ${optionalString (cfg.extraDisk != null) '' - echo "creating extra disk: data-disk.raw" - dataDiskImage=data-disk.raw - truncate -s ${toString cfg.extraDisk.size}M $dataDiskImage + ${optionalString (cfg.extraDisk != null) '' + echo "creating extra disk: data-disk.raw" + dataDiskImage=data-disk.raw + truncate -s ${toString cfg.extraDisk.size}M $dataDiskImage - parted --script $dataDiskImage -- \ - mklabel msdos \ - mkpart primary ext4 1MiB -1 - eval $(partx $dataDiskImage -o START,SECTORS --nr 1 --pairs) - mkfs.ext4 -F -L ${cfg.extraDisk.label} $dataDiskImage -E offset=$(sectorsToBytes $START) $(sectorsToKilobytes $SECTORS)K - echo "creating extra disk: data-disk.vdi" - VBoxManage convertfromraw $dataDiskImage data-disk.vdi - ''} + parted --script $dataDiskImage -- \ + mklabel msdos \ + mkpart primary ext4 1MiB -1 + eval $(partx $dataDiskImage -o START,SECTORS --nr 1 --pairs) + mkfs.ext4 -F -L ${cfg.extraDisk.label} $dataDiskImage -E offset=$(sectorsToBytes $START) $(sectorsToKilobytes $SECTORS)K + echo "creating extra disk: data-disk.vdi" + VBoxManage convertfromraw $dataDiskImage data-disk.vdi + ''} - echo "creating VirtualBox VM..." - vmName="${cfg.vmName}"; - VBoxManage createvm --name "$vmName" --register \ - --ostype ${if pkgs.stdenv.hostPlatform.system == "x86_64-linux" then "Linux26_64" else "Linux26"} - VBoxManage modifyvm "$vmName" \ - --memory ${toString cfg.memorySize} \ - ${lib.cli.toGNUCommandLineShell { } cfg.params} - VBoxManage storagectl "$vmName" ${lib.cli.toGNUCommandLineShell { } cfg.storageController} - VBoxManage storageattach "$vmName" --storagectl ${cfg.storageController.name} --port 0 --device 0 --type hdd \ - --medium disk.vdi - ${optionalString (cfg.extraDisk != null) '' - VBoxManage storageattach "$vmName" --storagectl ${cfg.storageController.name} --port 1 --device 0 --type hdd \ - --medium data-disk.vdi - ''} + echo "creating VirtualBox VM..." + vmName="${cfg.vmName}"; + VBoxManage createvm --name "$vmName" --register \ + --ostype ${if pkgs.stdenv.hostPlatform.system == "x86_64-linux" then "Linux26_64" else "Linux26"} + VBoxManage modifyvm "$vmName" \ + --memory ${toString cfg.memorySize} \ + ${lib.cli.toGNUCommandLineShell { } cfg.params} + VBoxManage storagectl "$vmName" ${lib.cli.toGNUCommandLineShell { } cfg.storageController} + VBoxManage storageattach "$vmName" --storagectl ${cfg.storageController.name} --port 0 --device 0 --type hdd \ + --medium disk.vdi + ${optionalString (cfg.extraDisk != null) '' + VBoxManage storageattach "$vmName" --storagectl ${cfg.storageController.name} --port 1 --device 0 --type hdd \ + --medium data-disk.vdi + ''} - echo "exporting VirtualBox VM..." - mkdir -p $out - fn="$out/${cfg.vmFileName}" - VBoxManage export "$vmName" --output "$fn" --options manifest ${escapeShellArgs cfg.exportParams} - ${cfg.postExportCommands} + echo "exporting VirtualBox VM..." + mkdir -p $out + fn="$out/${cfg.vmFileName}" + VBoxManage export "$vmName" --output "$fn" --options manifest ${escapeShellArgs cfg.exportParams} + ${cfg.postExportCommands} - rm -v $diskImage + rm -v $diskImage - mkdir -p $out/nix-support - echo "file ova $fn" >> $out/nix-support/hydra-build-products - ''; + mkdir -p $out/nix-support + echo "file ova $fn" >> $out/nix-support/hydra-build-products + ''; }; - fileSystems = - { - "/" = { - device = "/dev/disk/by-label/nixos"; - autoResize = true; - fsType = "ext4"; - }; - } - // (lib.optionalAttrs (cfg.extraDisk != null) { - ${cfg.extraDisk.mountPoint} = { - device = "/dev/disk/by-label/" + cfg.extraDisk.label; - autoResize = true; - fsType = "ext4"; - }; - }); + fileSystems = { + "/" = { + device = "/dev/disk/by-label/nixos"; + autoResize = true; + fsType = "ext4"; + }; + } // (lib.optionalAttrs (cfg.extraDisk != null) { + ${cfg.extraDisk.mountPoint} = { + device = "/dev/disk/by-label/" + cfg.extraDisk.label; + autoResize = true; + fsType = "ext4"; + }; + }); boot.growPartition = true; boot.loader.grub.device = "/dev/sda"; - swapDevices = [ - { - device = "/var/swap"; - size = 2048; - } - ]; + swapDevices = [{ + device = "/var/swap"; + size = 2048; + }]; virtualisation.virtualbox.guest.enable = true; diff --git a/nixos/modules/virtualisation/virtualisation-options.nix b/nixos/modules/virtualisation/virtualisation-options.nix deleted file mode 100644 index 5040a7916d84..000000000000 --- a/nixos/modules/virtualisation/virtualisation-options.nix +++ /dev/null @@ -1,60 +0,0 @@ -# This modules declares shared options for virtual machines, -# containers and anything else in `virtualisation`. -# -# This is useful to declare e.g. defaults for -# `virtualisation.diskSize` once, while building multiple -# different image formats of a NixOS configuration. -# -# Additional options can be migrated over time from -# `modules/virtualisation/qemu-vm.nix` and others. -# Please keep defaults and descriptions here generic -# and independent of i.e. hypervisor-specific notes -# and defaults where. -# Those can be added in the consuming modules where needed. -# needed. -let - _file = ./virtualisation-options.nix; - key = _file; -in -{ - diskSize = - { lib, config, ... }: - let - t = lib.types; - in - { - inherit _file key; - - options = { - virtualisation.diskSizeAutoSupported = lib.mkOption { - type = t.bool; - default = true; - description = '' - Whether the current image builder or vm runner supports `virtualisation.diskSize = "auto".` - ''; - internal = true; - }; - - virtualisation.diskSize = lib.mkOption { - type = t.either (t.enum [ "auto" ]) t.ints.positive; - default = "auto"; - description = '' - The disk size in megabytes of the virtual machine. - ''; - }; - }; - - config = - let - inherit (config.virtualisation) diskSize diskSizeAutoSupported; - in - { - assertions = [ - { - assertion = diskSize != "auto" || diskSizeAutoSupported; - message = "Setting virtualisation.diskSize to `auto` is not supported by the current image build or vm runner; use an explicit size."; - } - ]; - }; - }; -} diff --git a/nixos/release.nix b/nixos/release.nix index dc131dcba52c..eeca73ea4c55 100644 --- a/nixos/release.nix +++ b/nixos/release.nix @@ -312,7 +312,7 @@ in rec { [ configuration versionModule ./maintainers/scripts/ec2/amazon-image.nix - ({ ... }: { amazonImage.virtualisation.diskSize = "auto"; }) + ({ ... }: { amazonImage.sizeMB = "auto"; }) ]; }).config.system.build.amazonImage) diff --git a/nixos/tests/prometheus-exporters.nix b/nixos/tests/prometheus-exporters.nix index 3ce296c0cacf..71eef72df6f3 100644 --- a/nixos/tests/prometheus-exporters.nix +++ b/nixos/tests/prometheus-exporters.nix @@ -482,7 +482,6 @@ let json = { exporterConfig = { enable = true; - url = "http://localhost"; configFile = pkgs.writeText "json-exporter-conf.json" (builtins.toJSON { modules = { default = { @@ -932,7 +931,9 @@ let pgbouncer = { exporterConfig = { enable = true; - connectionStringFile = pkgs.writeText "connection.conf" "postgres://admin:@localhost:6432/pgbouncer?sslmode=disable"; + connectionEnvFile = "${pkgs.writeText "connstr-env" '' + PGBOUNCER_EXPORTER_CONNECTION_STRING=postgres://admin@localhost:6432/pgbouncer?sslmode=disable + ''}"; }; metricProvider = { diff --git a/pkgs/applications/networking/browsers/vivaldi/default.nix b/pkgs/applications/networking/browsers/vivaldi/default.nix index 7563f184d2a7..652cf97de4c1 100644 --- a/pkgs/applications/networking/browsers/vivaldi/default.nix +++ b/pkgs/applications/networking/browsers/vivaldi/default.nix @@ -24,7 +24,7 @@ let vivaldiName = if isSnapshot then "vivaldi-snapshot" else "vivaldi"; in stdenv.mkDerivation rec { pname = "vivaldi"; - version = "6.9.3447.37"; + version = "6.9.3447.41"; suffix = { aarch64-linux = "arm64"; @@ -34,8 +34,8 @@ in stdenv.mkDerivation rec { src = fetchurl { url = "https://downloads.vivaldi.com/${branch}/vivaldi-${branch}_${version}-1_${suffix}.deb"; hash = { - aarch64-linux = "sha256-kYTnWad/jrJt9z+AhjXzHYxVSIwIIO3RKD7szuPEg2s="; - x86_64-linux = "sha256-+h7SHci8gZ+epKFHD0PiXyME2xT+loD2KXpJGFCfIFg="; + aarch64-linux = "sha256-Up2n7G3vatsQC9JKF1A1jAIBbdWm9UhL/75AXuxDCsg="; + x86_64-linux = "sha256-Hcd8W8bDlRUT/zPYP+aiJnUmepS38KuK0wRFYB3uW1Y="; }.${stdenv.hostPlatform.system} or (throw "Unsupported system: ${stdenv.hostPlatform.system}"); }; diff --git a/pkgs/applications/networking/cluster/terraform-providers/default.nix b/pkgs/applications/networking/cluster/terraform-providers/default.nix index 9e4d3d824f7b..2b34e7c6d544 100644 --- a/pkgs/applications/networking/cluster/terraform-providers/default.nix +++ b/pkgs/applications/networking/cluster/terraform-providers/default.nix @@ -1,6 +1,7 @@ { lib , stdenv , buildGoModule +, buildGo123Module , fetchFromGitHub , fetchFromGitLab , callPackage @@ -24,7 +25,7 @@ let , deleteVendor ? false , proxyVendor ? false , mkProviderFetcher ? fetchFromGitHub - , mkProviderGoModule ? buildGoModule + , mkProviderGoModule ? buildGo123Module # "https://registry.terraform.io/providers/vancluever/acme" , homepage ? "" # "registry.terraform.io/vancluever/acme" diff --git a/pkgs/applications/networking/cluster/terraform-providers/providers.json b/pkgs/applications/networking/cluster/terraform-providers/providers.json index f883b0ff82af..35ba84a27c26 100644 --- a/pkgs/applications/networking/cluster/terraform-providers/providers.json +++ b/pkgs/applications/networking/cluster/terraform-providers/providers.json @@ -9,13 +9,13 @@ "vendorHash": null }, "acme": { - "hash": "sha256-LlpPc3um4D2nNJFZRoXnw5ss0E0rrJN0wKKmuV0S6NU=", + "hash": "sha256-RboEWeTUgEZShZ9NrR9yuUzbGPq9wauTyoFiHXZS2oI=", "homepage": "https://registry.terraform.io/providers/vancluever/acme", "owner": "vancluever", "repo": "terraform-provider-acme", - "rev": "v2.24.2", + "rev": "v2.26.0", "spdx": "MPL-2.0", - "vendorHash": "sha256-ptZ14WWarYeKT8gIcUDi4LmCFkpoTwAhSwMXmLPlWxs=" + "vendorHash": "sha256-pJlt35kPV3CYOE4RiIjHLT9YEwSreQHgzRuY3ba9oBk=" }, "age": { "hash": "sha256-bJrzjvkrCX93bNqCA+FdRibHnAw6cb61StqtwUY5ok4=", @@ -27,29 +27,29 @@ "vendorHash": "sha256-jK7JuARpoxq7hvq5+vTtUwcYot0YqlOZdtDwq4IqKvk=" }, "aiven": { - "hash": "sha256-X3KtT4Thsf7bYeZJEUphRiXAlNamabFE0rjS636dJSY=", + "hash": "sha256-cNcF8pyqRR1YEc2RuKhOtcpFDkdFU8OFCYHRhefdHHk=", "homepage": "https://registry.terraform.io/providers/aiven/aiven", "owner": "aiven", "repo": "terraform-provider-aiven", - "rev": "v4.20.0", + "rev": "v4.24.0", "spdx": "MIT", - "vendorHash": "sha256-QzbtTp78tROVj8kPYzjP5kBRHASlvqK6xpmRnJF6jsw=" + "vendorHash": "sha256-ENH/TfC/Yv+jjn4giiThfj9SatFxkfwR/Xj3W+FT/Lg=" }, "akamai": { - "hash": "sha256-jDCrNDJ6O9dXE6bG4GAMFytlVbEe/Z8mb6vx4DG355U=", + "hash": "sha256-d4unurf1WYmVx5z698kAeqKslkVH+tM8G4hrCofDtUs=", "homepage": "https://registry.terraform.io/providers/akamai/akamai", "owner": "akamai", "repo": "terraform-provider-akamai", - "rev": "v6.2.0", + "rev": "v6.4.0", "spdx": "MPL-2.0", - "vendorHash": "sha256-QQaLUJJs/7hfLTIOIkG9WF7XmkLXsJP9MOQAvQoDQOw=" + "vendorHash": "sha256-qnKpQpK/AoFOxPiGHkUMqcF5loc0hVbqOuPaDLzj1Es=" }, "alicloud": { - "hash": "sha256-WaMvv/NqyblA2rrauZ7p4pHCND6S6/kfBKS/2xIrcjI=", + "hash": "sha256-lVQAkdwrnZrSZlBqNj2BBpQwzI0d5c+NGaKJxVpgQPg=", "homepage": "https://registry.terraform.io/providers/aliyun/alicloud", "owner": "aliyun", "repo": "terraform-provider-alicloud", - "rev": "v1.226.0", + "rev": "v1.230.0", "spdx": "MPL-2.0", "vendorHash": null }, @@ -63,13 +63,13 @@ "vendorHash": "sha256-OAd8SeTqTrH0kMoM2LsK3vM2PI23b3gl57FaJYM9hM0=" }, "archive": { - "hash": "sha256-jkqbj7NGrTQeMQcg52JVurV3ce8iosxAJjBGdoQ3PLY=", + "hash": "sha256-Xm9BT8O18aTIa1h166dElYaTq4PlC4u7TgFgCfcC6jI=", "homepage": "https://registry.terraform.io/providers/hashicorp/archive", "owner": "hashicorp", "repo": "terraform-provider-archive", - "rev": "v2.4.2", + "rev": "v2.6.0", "spdx": "MPL-2.0", - "vendorHash": "sha256-buKYDNVCIcSDLCrCL4ZAKNQ7HqkH3+/7RHjyyR4dLmU=" + "vendorHash": "sha256-b8yGtOUZezGRgURXigv8ySaxxHN/vCCDPgoDC5EBlok=" }, "argocd": { "hash": "sha256-dHIvMFz5XIxxBvBFsEw8lqi6yVoYM9E4tLIoTY+mdiQ=", @@ -81,22 +81,22 @@ "vendorHash": "sha256-yyTU+D4zMDcJPZ9j7a2ZuPjGBCHvED5R0rvevCEaoAI=" }, "artifactory": { - "hash": "sha256-j9TtO8dJltf7SZdlMZaiCWdJbcEPloPbDhYfWcCzgss=", + "hash": "sha256-m6eRhNPxMa08OYYkFDt+Ew2iCkJdI/5aQth9qiE0v4o=", "homepage": "https://registry.terraform.io/providers/jfrog/artifactory", "owner": "jfrog", "repo": "terraform-provider-artifactory", - "rev": "v11.1.0", + "rev": "v11.9.1", "spdx": "Apache-2.0", - "vendorHash": "sha256-nPEN1ee0RmNpgKIlz0jHcHkG6oYZn7LV/Gmmdd9krq8=" + "vendorHash": "sha256-+3EemRl+rKoCg2HpHvjMPvN6ajrDOnO5C98NVGkYdo4=" }, "auth0": { - "hash": "sha256-Ay/EPlAxpEehbDsOeOyOViwT3jDsd3FmpHB5sxnAxAs=", + "hash": "sha256-Yltf+s1gEgP/dbX8EuK45VPBAEzelP+CAcllUaqvnAQ=", "homepage": "https://registry.terraform.io/providers/auth0/auth0", "owner": "auth0", "repo": "terraform-provider-auth0", - "rev": "v1.3.0", + "rev": "v1.6.0", "spdx": "MPL-2.0", - "vendorHash": "sha256-oc6ZI5j7pqiiFgfbaTARb6sn+Ma/rqrupv/RPN05mrc=" + "vendorHash": "sha256-76Uf6vQpQ6GlumPHd1uBi0gO5aGmm/HAhNY3I7WCr8k=" }, "avi": { "hash": "sha256-OKUxIJO5WR8ZVkhst1xIgxKsAy+9PNHOmG2NsaRUxFY=", @@ -108,22 +108,22 @@ "vendorHash": "sha256-Sq304WOdKx4J1sD1+YA7uDi+uQtUiXa+BISs/j87dWw=" }, "aviatrix": { - "hash": "sha256-84MtHPrDVaLMQQYnAfuP/pZuzruWxUTLpziwn3ny1oU=", + "hash": "sha256-erBjyDX6xG8lpqcPq8iqgsanJKLuSgmiW/9PC8Xbyag=", "homepage": "https://registry.terraform.io/providers/AviatrixSystems/aviatrix", "owner": "AviatrixSystems", "repo": "terraform-provider-aviatrix", - "rev": "v3.1.4", + "rev": "v3.1.5", "spdx": "MPL-2.0", "vendorHash": null }, "aws": { - "hash": "sha256-DJ0mfqcWIs1iLSEfhlYEgHr1PKz8HchlgvHfEwIAnlA=", + "hash": "sha256-Fmhb3mKRviYsl3qQfXuQMI6KBpmDN0rtwJxDjSkj4EM=", "homepage": "https://registry.terraform.io/providers/hashicorp/aws", "owner": "hashicorp", "repo": "terraform-provider-aws", - "rev": "v5.57.0", + "rev": "v5.66.0", "spdx": "MPL-2.0", - "vendorHash": "sha256-NlFP7cRE+6PiGMSz2y/SDQas/TNWAJk/EBEqIeG2INY=" + "vendorHash": "sha256-9DWxMDsyWl/bczvbPOmdRTwjIYAKTuNXyBzrCHExNUA=" }, "azuread": { "hash": "sha256-UOaEfmhGPrqQBkodNYybYb5rnB3X8wpXKHlpKqZnnXU=", @@ -135,11 +135,11 @@ "vendorHash": null }, "azurerm": { - "hash": "sha256-3EHm4fpeYJYzwrwaQLMdgFq1dgmV755WwAhKBG3f10M=", + "hash": "sha256-tCZKDqMrmwAGqs4eoMWj4lty4aVOkzF16RpEl24GNPc=", "homepage": "https://registry.terraform.io/providers/hashicorp/azurerm", "owner": "hashicorp", "repo": "terraform-provider-azurerm", - "rev": "v3.111.0", + "rev": "v4.1.0", "spdx": "MPL-2.0", "vendorHash": null }, @@ -153,20 +153,20 @@ "vendorHash": null }, "baiducloud": { - "hash": "sha256-uKIBimMMTManwztb4vdMCpsRWMr6GB8O7vK850sVI2g=", + "hash": "sha256-kLEEbBQ1YdxJkvCCHzpGHBX2wC9JtLVY6chZEmAziSU=", "homepage": "https://registry.terraform.io/providers/baidubce/baiducloud", "owner": "baidubce", "repo": "terraform-provider-baiducloud", - "rev": "v1.21.8", + "rev": "v1.21.9", "spdx": "MPL-2.0", "vendorHash": null }, "bigip": { - "hash": "sha256-F7AD3Wb6R6exPRcEByOTuEQFdYSJB+V2cVotO2cabt0=", + "hash": "sha256-jCQgjxGBSy2d9DIJeshLVdj6N/SXWEPcd5EpJ5GAXe4=", "homepage": "https://registry.terraform.io/providers/F5Networks/bigip", "owner": "F5Networks", "repo": "terraform-provider-bigip", - "rev": "v1.22.2", + "rev": "v1.22.3", "spdx": "MPL-2.0", "vendorHash": null }, @@ -180,13 +180,13 @@ "vendorHash": "sha256-oDMKf39uNMO9/kyiZ1IuZlj2yIF1q5Z3wewxEBh3yso=" }, "bitwarden": { - "hash": "sha256-+zuKZBwoOSp3HIdxmK1FInE33/1D5nX2N7zYBCtRvHA=", + "hash": "sha256-YB+9CWd3U6Yl33ZFbTxzjomrLCilpBPKLdn6Yv7LAUA=", "homepage": "https://registry.terraform.io/providers/maxlaverse/bitwarden", "owner": "maxlaverse", "repo": "terraform-provider-bitwarden", - "rev": "v0.8.0", + "rev": "v0.8.1", "spdx": "MPL-2.0", - "vendorHash": "sha256-u9ICJtPZveRrK5BOthvFDGkNcUiA0/Hb39KM0eIhUVI=" + "vendorHash": "sha256-BZ1+D0JQrGb6qE25+eTLSHIQdCmzucMPKUY/6x2LwT8=" }, "brightbox": { "hash": "sha256-pwFbCP+qDL/4IUfbPRCkddkbsEEeAu7Wp12/mDL0ABA=", @@ -198,22 +198,22 @@ "vendorHash": "sha256-/dOiXO2aPkuZaFiwv/6AXJdIADgx8T7eOwvJfBBoqg8=" }, "buildkite": { - "hash": "sha256-QS+JCFLYPvxwLIVzCS/gKZkBZQhOOxRfn7Vudgiox+E=", + "hash": "sha256-kwrhIii1jGpIZBzT58UdgnDtX5279shW77HphLobaEI=", "homepage": "https://registry.terraform.io/providers/buildkite/buildkite", "owner": "buildkite", "repo": "terraform-provider-buildkite", - "rev": "v1.10.1", + "rev": "v1.10.2", "spdx": "MIT", - "vendorHash": "sha256-gTJakGr9f9bzR5pbmgAMTJL54e2mS/h92TM4ft3ABdw=" + "vendorHash": "sha256-PFeWgDw1hkW/ekQfubRSYlaD4d4wJ4GOohOJ00QcEqQ=" }, "checkly": { - "hash": "sha256-qPlXaw8J2J7DPKJvfiTLalgMIWpttqbdMg2UB3rvt14=", + "hash": "sha256-4J7pwtlAa920RXF6ZoSoi03qA15NBzUlXQCZRErI2Co=", "homepage": "https://registry.terraform.io/providers/checkly/checkly", "owner": "checkly", "repo": "terraform-provider-checkly", - "rev": "v1.8.0", + "rev": "v1.8.2", "spdx": null, - "vendorHash": "sha256-+GirqFNV0eIC9CzpW53UOi9cDUzXs8ozSLX7dKQnOQ8=" + "vendorHash": "sha256-DcRe3nBzKn8fC0Q8Dx/p0PXuUccX+4kmOMdZa3HuXNI=" }, "ciscoasa": { "hash": "sha256-xzc44FEy2MPo51Faq/VFwg411JK9e0kQucpt0vdN8yg=", @@ -225,22 +225,22 @@ "vendorHash": null }, "cloudamqp": { - "hash": "sha256-aEbGvGPYvW3NOO+Q89/ebcJWNrXIoNQkqAIbv9ikiI8=", + "hash": "sha256-0lqVHIq37CebSVDR5Ni4kFyXeZZ+tOqpj8gN4h7OaA0=", "homepage": "https://registry.terraform.io/providers/cloudamqp/cloudamqp", "owner": "cloudamqp", "repo": "terraform-provider-cloudamqp", - "rev": "v1.29.4", + "rev": "v1.32.0", "spdx": "MPL-2.0", - "vendorHash": "sha256-cI3brJwN+7FTceOMwR0HMbZCNHhwvm31OXqjAEvrzrs=" + "vendorHash": "sha256-j3qdi19dxJL+R8Xa6MDag6KHMuBnzEZ9lUhuSAEZOAQ=" }, "cloudflare": { - "hash": "sha256-7MdXh5SIQwFPL5APmdrkrh++shZRbRUAYrVIHDGjM68=", + "hash": "sha256-9M7PQEBg0qDmyz2B35krNUF9dDo0g28JomFor7b/Nsc=", "homepage": "https://registry.terraform.io/providers/cloudflare/cloudflare", "owner": "cloudflare", "repo": "terraform-provider-cloudflare", - "rev": "v4.36.0", + "rev": "v4.41.0", "spdx": "MPL-2.0", - "vendorHash": "sha256-og31UnUsXGgOm2dH0jlvEpvjOnxUlRy04s2TffiVX00=" + "vendorHash": "sha256-uLkoG0m3v1vohXO03nCrfxEhvJYfJOvYSIHsgYCjKtc=" }, "cloudfoundry": { "hash": "sha256-1nYncJLVU/f9WD6Quh9IieIXgixPzbPk4zbtI1zmf9g=", @@ -262,32 +262,32 @@ "vendorHash": "sha256-Hny481ihxllpoVPL5/0rTV9oCAmyoGKxCYiN986aKTk=" }, "cloudscale": { - "hash": "sha256-O4Y8p5S5C4SldryndecoaX5d8nrX10nqurAkJ0Un2NY=", + "hash": "sha256-4RU1CD0WwLMd3NsnJWl2Smc8XBYlP9K8Iev16uqsetE=", "homepage": "https://registry.terraform.io/providers/cloudscale-ch/cloudscale", "owner": "cloudscale-ch", "repo": "terraform-provider-cloudscale", - "rev": "v4.3.0", + "rev": "v4.4.0", "spdx": "MIT", "vendorHash": null }, "constellix": { "deleteVendor": true, - "hash": "sha256-ecwXWYrs7XJM1web+kia2ccpvTjxAVFPzav6lLal4e4=", + "hash": "sha256-yDXZ+lizDK+Ds8/Z3jfNLjO7fvlfRhx5y88bMLZCaj0=", "homepage": "https://registry.terraform.io/providers/Constellix/constellix", "owner": "Constellix", "repo": "terraform-provider-constellix", - "rev": "v0.4.5", + "rev": "v0.4.6", "spdx": "MPL-2.0", "vendorHash": "sha256-UJHDX/vx3n/RTuQ50Y6TAhpEEFk9yBoaz8yK02E8Fhw=" }, "consul": { - "hash": "sha256-Glgig56QdXZ9VNZx25/60YPChg9MtLq/S95nuAco3m0=", + "hash": "sha256-QiVE1ezwViOjCNhTAfeR5G8hXAHCi19PqwWnBlwhPCc=", "homepage": "https://registry.terraform.io/providers/hashicorp/consul", "owner": "hashicorp", "repo": "terraform-provider-consul", - "rev": "v2.20.0", + "rev": "v2.21.0", "spdx": "MPL-2.0", - "vendorHash": "sha256-OKKcyx5JAQGMoUMRxIbe3lg825vhwCcWcPNZqo+/gl4=" + "vendorHash": "sha256-hR20+dRvS3tZ6aoTKCHs4zkyE5jWHEh62uLBkVJPA4M=" }, "ct": { "hash": "sha256-c1cqTfMlZ5fXDNMYLsk4447X0p/qIQYvRTqVY8cSs+E=", @@ -299,22 +299,22 @@ "vendorHash": "sha256-ZCMSmOCPEMxCSpl3DjIUGPj1W/KNJgyjtHpmQ19JquA=" }, "datadog": { - "hash": "sha256-sWcVMQiSRFyjwYIHUdKQm9sKX279pnA3FVLwUJ3kBKw=", + "hash": "sha256-s1JCno9cpXk0RdovXjTue77Gv9cLX3lB46jYy2xgOOk=", "homepage": "https://registry.terraform.io/providers/DataDog/datadog", "owner": "DataDog", "repo": "terraform-provider-datadog", - "rev": "v3.40.0", + "rev": "v3.44.0", "spdx": "MPL-2.0", - "vendorHash": "sha256-GEZmpCyqZCxsS5aFxEznNscs5CcgQiiPvJweA3mKkRY=" + "vendorHash": "sha256-ZmOuk2uNnFQzXSfRp6Lz/1bplEm0AuB/M94+dRnqhHU=" }, "dexidp": { - "hash": "sha256-XR8OI+Nf3PKNzZzM+jvylF8Itnapb9Xdztxq4OyXPVQ=", + "hash": "sha256-ommpazPlY4dMAOB1pgI7942aGH6YYPn6WtaowucQpZY=", "homepage": "https://registry.terraform.io/providers/marcofranssen/dexidp", "owner": "marcofranssen", "repo": "terraform-provider-dexidp", - "rev": "v0.5.0", + "rev": "v0.6.1", "spdx": "MIT", - "vendorHash": "sha256-xW0sPt2TGmoQXc5a2lp6471amBbDDPZbyc9YIIHP+M0=" + "vendorHash": "sha256-3swcRmm+JZ4ZQX0hvXZosYDGwk0KSyZcqEdNGDYcyYE=" }, "dhall": { "hash": "sha256-QjY5ZazQn4HiLQtdmw9X7o5tFw+27B2IISzmzMMHjHE=", @@ -327,11 +327,11 @@ "vendorHash": "sha256-quoFrJbB1vjz+MdV+jnr7FPACHuUe5Gx9POLubD2IaM=" }, "digitalocean": { - "hash": "sha256-66bG22xNzJEjCZJ7pHY4OW1vj8qTJIXd0CF/0zLiyug=", + "hash": "sha256-EpT0pL6JrQ9BKL7IyUmEYllRyIFbjJepVvVZdxQhFKs=", "homepage": "https://registry.terraform.io/providers/digitalocean/digitalocean", "owner": "digitalocean", "repo": "terraform-provider-digitalocean", - "rev": "v2.39.2", + "rev": "v2.40.0", "spdx": "MPL-2.0", "vendorHash": null }, @@ -354,13 +354,13 @@ "vendorHash": "sha256-yOuZcvaregVLf0O6Teuvv6FtapuQGgHjTkqiH2euV8U=" }, "dnsimple": { - "hash": "sha256-xF0zvUKJgB67rKNkeHKyKU0k7INiCKzN+G6v0PIq204=", + "hash": "sha256-19h4x+kxhFwlNUdTmTLjoLRQB7fNBh0CxxoQDGRPPiQ=", "homepage": "https://registry.terraform.io/providers/dnsimple/dnsimple", "owner": "dnsimple", "repo": "terraform-provider-dnsimple", - "rev": "v1.6.0", + "rev": "v1.7.0", "spdx": "MPL-2.0", - "vendorHash": "sha256-Zl98s0+sgs+n/OkrJMsia0MxqO/AGWId8zzY+/n6LXM=" + "vendorHash": "sha256-5445cUKxjNlZcQ6opJKgXgT7I9XUmqbPMB/iKuEBPwg=" }, "docker": { "hash": "sha256-UyHOI8C0eDV5YllAi9clHp/CEldHjIp3FHHMPy1rK58=", @@ -372,11 +372,11 @@ "vendorHash": "sha256-XxltOTtCgmJ9wZX8Yw39HkwVVZb58kZjAH7jfKPhjKM=" }, "doppler": { - "hash": "sha256-jDCmIHdfHi+gp3+HGo8Wh+xYiHVU2Zy0lxETKW2rvGA=", + "hash": "sha256-yHWOMDhsqF+DXIKREyx8FftItZiWlWFoRhpub752UtU=", "homepage": "https://registry.terraform.io/providers/DopplerHQ/doppler", "owner": "DopplerHQ", "repo": "terraform-provider-doppler", - "rev": "v1.8.0", + "rev": "v1.10.0", "spdx": "Apache-2.0", "vendorHash": "sha256-UvpSfCelEsV9gjRWHxdYvVe3HAnYWWY5KYLVYiqc/So=" }, @@ -390,20 +390,20 @@ "vendorHash": "sha256-oVTanZpCWs05HwyIKW2ajiBPz1HXOFzBAt5Us+EtTRw=" }, "equinix": { - "hash": "sha256-Ipl+POTZRKe9xKR08x/TPm2S7kv6w54im16pp56rWDE=", + "hash": "sha256-Wj/qrc18/wJekWZdNgzheT1hsIlAPTAf/tAIrpw6N9Y=", "homepage": "https://registry.terraform.io/providers/equinix/equinix", "owner": "equinix", "repo": "terraform-provider-equinix", - "rev": "v2.0.1", + "rev": "v2.4.1", "spdx": "MIT", - "vendorHash": "sha256-oxtFq1tejyqsY2uEkMjiub1CwdkFpuSVRb1Z2u3CebQ=" + "vendorHash": "sha256-5M/ceHvcwAlIhjpYO1JTQVUmuBLa9pT5opwiC/tp6+8=" }, "exoscale": { - "hash": "sha256-d6vdYtEBD34SPHDAlkpTb/T8D7TaLbVwMYjSefuNdr0=", + "hash": "sha256-i7Lp3NhaxVR317vHfdE/2aXAxmKk7u7kETM7JTJr5BI=", "homepage": "https://registry.terraform.io/providers/exoscale/exoscale", "owner": "exoscale", "repo": "terraform-provider-exoscale", - "rev": "v0.59.1", + "rev": "v0.59.2", "spdx": "MPL-2.0", "vendorHash": null }, @@ -417,11 +417,11 @@ "vendorHash": "sha256-qeKXdjrDPJWO4xW8by6djJReeYbCjh8VzQmE5/65zII=" }, "fastly": { - "hash": "sha256-FfdXMrGfz+JFEyWfZytIt1R0M/v7JUmkvu4VohF1vSA=", + "hash": "sha256-NzuWXQtaobbkk4oKcs+aT6ONeIsmLZsyRhW3BP7+5Wg=", "homepage": "https://registry.terraform.io/providers/fastly/fastly", "owner": "fastly", "repo": "terraform-provider-fastly", - "rev": "v5.11.0", + "rev": "v5.13.0", "spdx": "MPL-2.0", "vendorHash": null }, @@ -453,40 +453,40 @@ "vendorHash": "sha256-EiTWJ4bw8IwsRTD9Lt28Up2DXH0oVneO2IaO8VqWtkw=" }, "github": { - "hash": "sha256-6RAGc1UXebNm24d4+7S0LugvpSVgjIvqa7B6y+pozkA=", + "hash": "sha256-8TP3iw/NeVjq49HhurCULXbAOvP2ye6mZsVe62FxSAE=", "homepage": "https://registry.terraform.io/providers/integrations/github", "owner": "integrations", "repo": "terraform-provider-github", - "rev": "v6.2.2", + "rev": "v6.2.3", "spdx": "MIT", "vendorHash": null }, "gitlab": { - "hash": "sha256-F73eY0m+KdzfAFCFPOZ0a29OOfgOm87WZvi8+mHwPek=", + "hash": "sha256-F+ps7hpRm6+DHJwVOMe2qwVvKSL2o1JUl0Blgd8qFsA=", "homepage": "https://registry.terraform.io/providers/gitlabhq/gitlab", "owner": "gitlabhq", "repo": "terraform-provider-gitlab", - "rev": "v17.1.0", + "rev": "v17.3.1", "spdx": "MPL-2.0", - "vendorHash": "sha256-FrmQsuLinm5Z4+GHC1PV19lt1rfxv3TwQiEUxTvlTtk=" + "vendorHash": "sha256-vIGqb5+e9vZkJFsH7f1UU13V80XtQVcsQ1hYu5laV70=" }, "google": { - "hash": "sha256-RJ01+OA3BXMNThRk9aGkYa2jrj3SYgOh9eA5al5wR/Q=", + "hash": "sha256-RIBSJc5wmBXvd+NWaz3oCOClAOqXEOpSXIR8+wYKfk0=", "homepage": "https://registry.terraform.io/providers/hashicorp/google", "owner": "hashicorp", "repo": "terraform-provider-google", - "rev": "v5.36.0", + "rev": "v6.2.0", "spdx": "MPL-2.0", - "vendorHash": "sha256-0SxftrOjmpYK4ud3RweYaW6qgdKwi43D1ZhN470rvVs=" + "vendorHash": "sha256-iRN3qqJHmpLuuAbmaFCj9wFXAHTXK+farkFlkWt1hyU=" }, "google-beta": { - "hash": "sha256-r9ndcNxiocRHH++zvEtuIwJ8U2fE5cgndPcYjdhLpEA=", + "hash": "sha256-CxoWwoR4CVW5sVSOpOmfnn5xECKmbSuSpBWVAhW24D0=", "homepage": "https://registry.terraform.io/providers/hashicorp/google-beta", "owner": "hashicorp", "repo": "terraform-provider-google-beta", - "rev": "v5.36.0", + "rev": "v6.2.0", "spdx": "MPL-2.0", - "vendorHash": "sha256-XkpLgFB/974WEbZe34uKrLSEWjinrkmpOFOG7uYDHhg=" + "vendorHash": "sha256-RgquPp7hJQcgXZndl9kojAxunGA3KxSneYACru23WUk=" }, "googleworkspace": { "hash": "sha256-dedYnsKHizxJZibuvJOMbJoux0W6zgKaK5fxIofKqCY=", @@ -498,49 +498,49 @@ "vendorHash": "sha256-fqVBnAivVekV+4tpkl+E6eNA3wi8mhLevJRCs3W7L2g=" }, "grafana": { - "hash": "sha256-VEg95n7S4PDWjGPbuADOQWymGDlS4jupQAHo2OCkfAA=", + "hash": "sha256-tUx6L+ESPsa9VWFztNoYAtspnPoNO8QX3AQk3i0VyNc=", "homepage": "https://registry.terraform.io/providers/grafana/grafana", "owner": "grafana", "repo": "terraform-provider-grafana", - "rev": "v3.2.1", + "rev": "v3.7.0", "spdx": "MPL-2.0", - "vendorHash": "sha256-ykPnplAA7s6lVQ7M0We7irIxOM2Ie4zSdQQynIjLFWA=" + "vendorHash": "sha256-d7ugVKmKQovewfeZF5k5KHbELwCSY9Krknow7q/7HWo=" }, "gridscale": { - "hash": "sha256-pFBH3J61Bk3QSfYVtLx3NrAFqrAnvKjKzL8qpeH5cOw=", + "hash": "sha256-GVOjkena3zRaOxO3YRYf+gfM2/CRm8VajpuWGTU0F1Y=", "homepage": "https://registry.terraform.io/providers/gridscale/gridscale", "owner": "gridscale", "repo": "terraform-provider-gridscale", - "rev": "v1.25.0", + "rev": "v1.26.0", "spdx": "MPL-2.0", "vendorHash": null }, "harbor": { - "hash": "sha256-dlAjbiSSgTuuZhTML66l4mSa3Rf14G86++RyXUJYbkw=", + "hash": "sha256-JdCBeUYB6rkSNhfTTIoRV8Bz4FnlHJFJxEZZbqyzAyc=", "homepage": "https://registry.terraform.io/providers/goharbor/harbor", "owner": "goharbor", "repo": "terraform-provider-harbor", - "rev": "v3.10.12", + "rev": "v3.10.15", "spdx": "MIT", "vendorHash": "sha256-TZxiDRVZPfg3jSflZsSbVaVcfUNqJ2U+ymHIm01pgkI=" }, "hcloud": { - "hash": "sha256-2eCHgHh6SVSHqjf+h4tRaD1orzh1LRUNVJdNsfLtZMc=", + "hash": "sha256-td1R2Xeo1QfsNJOwE7cCuzF5OjW4XUQJOVd0LPAXfuE=", "homepage": "https://registry.terraform.io/providers/hetznercloud/hcloud", "owner": "hetznercloud", "repo": "terraform-provider-hcloud", - "rev": "v1.47.0", + "rev": "v1.48.1", "spdx": "MPL-2.0", - "vendorHash": "sha256-wCr9tYaA6Y1LgbhvWbRtqtDrviMu45WnXAB/WMWpkl0=" + "vendorHash": "sha256-t9nXq30jRSlx9gMR+s8irDVdSE5tg9ZvMp47HZwEm7w=" }, "helm": { - "hash": "sha256-SD5lUEkbn09S/fnQNyCE9ZZ2fkXbcFZfdE95GGEqHzE=", + "hash": "sha256-82jM8XZF8X7tYbebMXPYNyhNGqQ51zl3WxYWX2ObD1g=", "homepage": "https://registry.terraform.io/providers/hashicorp/helm", "owner": "hashicorp", "repo": "terraform-provider-helm", - "rev": "v2.14.0", + "rev": "v2.15.0", "spdx": "MPL-2.0", - "vendorHash": "sha256-p6VUNSJKJtPrawdsi8Lgmu0uYjRmsdP4nsOl2L6h3JA=" + "vendorHash": "sha256-QERpwymuz45RiH9SMuAJPyl/z8r0a5Wd8NBMFKV6NjI=" }, "heroku": { "hash": "sha256-B/NaFe8KOKGJJlF3vZnpdMnbD1VxBktqodPBk+4NZEc=", @@ -570,20 +570,20 @@ "vendorHash": "sha256-zo22ng+J9ItkptdgUt6Pekkd9T7hFTYdVAWnp2k2vrs=" }, "http": { - "hash": "sha256-fGJBrgobtDAOPXnAIcmuepgCRVIdSCABQlP+dycAm+E=", + "hash": "sha256-fYbOfsKTah+5pgJdSftZvVlYmBp75o/6ByJO+ayXDhQ=", "homepage": "https://registry.terraform.io/providers/hashicorp/http", "owner": "hashicorp", "repo": "terraform-provider-http", - "rev": "v3.4.3", + "rev": "v3.4.4", "spdx": "MPL-2.0", - "vendorHash": "sha256-3yrcTs0QV2I4CX1TZgY9FimXC2G/p1s+xNsurH0n8e8=" + "vendorHash": "sha256-+U6k+mAVdGWOKzopp0yfaMmKuhqG0Laut+jHap4hBWs=" }, "huaweicloud": { - "hash": "sha256-p5vS7rnoBqE81Dhj35xeAs5ja/ekpeVEaNALtxw0/Tc=", + "hash": "sha256-Qs5/bDIb2SkQn9oXYU0kgpHY2q2obf8h2bN4prsaNrs=", "homepage": "https://registry.terraform.io/providers/huaweicloud/huaweicloud", "owner": "huaweicloud", "repo": "terraform-provider-huaweicloud", - "rev": "v1.66.0", + "rev": "v1.68.1", "spdx": "MPL-2.0", "vendorHash": null }, @@ -606,13 +606,13 @@ "vendorHash": null }, "ibm": { - "hash": "sha256-91EXK/8Kovq2yqyF5lFgWV/AJMvU6eHCnIBnLpzsQws=", + "hash": "sha256-PgrC6k6xGfGR9DoTBLSbWDjfF5comrpLGxgUIeof1lI=", "homepage": "https://registry.terraform.io/providers/IBM-Cloud/ibm", "owner": "IBM-Cloud", "repo": "terraform-provider-ibm", - "rev": "v1.67.1", + "rev": "v1.69.0", "spdx": "MPL-2.0", - "vendorHash": "sha256-ioyfsNgXoQOtzU1eBJkjMw4hgIo5ryFPIFKqOdn4fuk=" + "vendorHash": "sha256-Ve0qfeuDU59W3jCXpNvcZbnLt7OLAreBbGam2Wp/3Ig=" }, "icinga2": { "hash": "sha256-Y/Oq0aTzP+oSKPhHiHY9Leal4HJJm7TNDpcdqkUsCmk=", @@ -624,13 +624,13 @@ "vendorHash": null }, "incus": { - "hash": "sha256-nyL8sWFgTlJjuAYhBuzThCm89UHwYmb+x+A39z2FCj0=", + "hash": "sha256-VHoEUcFwsERC3EKfobTEoWOxuiOEBzEaWXL+mzlTe44=", "homepage": "https://registry.terraform.io/providers/lxc/incus", "owner": "lxc", "repo": "terraform-provider-incus", - "rev": "v0.1.2", + "rev": "v0.1.4", "spdx": "MPL-2.0", - "vendorHash": "sha256-81ykw34Qj5qAAa06p7br94bvlIM4uNiKNUI8d+Gw07g=" + "vendorHash": "sha256-7MQi9gJU0RAm9jTiY/YjkEU5QsxSX2lbUC7qvT20mes=" }, "infoblox": { "hash": "sha256-x5WGCYvsXby2O8J15fvoRNsYnBCaYdjx6LuDkYAfIlU=", @@ -651,13 +651,13 @@ "vendorHash": "sha256-NEGjgtrn6ZowqSF6NAK1NnSjYVUvfWuH/4R5ZPdTZSs=" }, "kafka": { - "hash": "sha256-bkZfgA/PgLWC3YXrIgoF2YRgOFQhoT+Seeifg1GvVFY=", + "hash": "sha256-CIA+0BMVPOpsB83QD6QEVOhohzeEFjFYTQ5UE+9MMIY=", "homepage": "https://registry.terraform.io/providers/Mongey/kafka", "owner": "Mongey", "repo": "terraform-provider-kafka", - "rev": "v0.7.1", + "rev": "v0.8.1", "spdx": "MIT", - "vendorHash": "sha256-Adfz3r3xWY7a4u9/m6a1rvQYGq+E8Q5pAuS/uMgZRQM=" + "vendorHash": "sha256-wfN5tgW/Pqm6PqHLnuON4SQwd7U6DFj7e8HiTSrTGbo=" }, "kafka-connect": { "hash": "sha256-3EUTte3txaDRz3jh0h23+Bf1tdLeCvPN9x8mYWY5VjI=", @@ -687,22 +687,22 @@ "vendorHash": "sha256-lXQHo66b9X0jZhoF+5Ix5qewQGyI82VPJ7gGzc2CHao=" }, "kubernetes": { - "hash": "sha256-MlM7OEpzDOmM8BaaGYn6ZSDaIO8IswreOIkLOkbqQHo=", + "hash": "sha256-SXHi6iW946P7EjNOtci2b0ioftxMHtqTIZmTBnHvmU4=", "homepage": "https://registry.terraform.io/providers/hashicorp/kubernetes", "owner": "hashicorp", "repo": "terraform-provider-kubernetes", - "rev": "v2.31.0", + "rev": "v2.32.0", "spdx": "MPL-2.0", "vendorHash": "sha256-MfXuVZC7aroO83CJTNCh5YfbmMlUG1CiPeGgxhUFjN0=" }, "launchdarkly": { - "hash": "sha256-ZJxtrDGUH/Ea07CwBX+om0Ccsg6oSUjoS9pKIOnl0GM=", + "hash": "sha256-ke7o4I6d1JSsk+/6hk0EXUatnyCnXzb8xdgPX/cr4eM=", "homepage": "https://registry.terraform.io/providers/launchdarkly/launchdarkly", "owner": "launchdarkly", "repo": "terraform-provider-launchdarkly", - "rev": "v2.19.0", + "rev": "v2.20.2", "spdx": "MPL-2.0", - "vendorHash": "sha256-pO9QTtqA+YG0i+o1+p3PYg8E/mUpzIV3II++CxQcuHE=" + "vendorHash": "sha256-v9N7lj7bEgR5HZm1SO0+DSCmQFVnsRvHPMycYMfpYwo=" }, "libvirt": { "hash": "sha256-yGlNBbixrQxjh7zgZoK3YXpUmr1vrLiLZhKpXvQULYg=", @@ -714,13 +714,13 @@ "vendorHash": "sha256-K/PH8DAi6Wj+isPx9xefQcLPKnrimfItZFSPfktTias=" }, "linode": { - "hash": "sha256-X7Uslu8HjJg/Ikz48hg1aIaDNNcr3Xz4gBTPB+y949k=", + "hash": "sha256-4uRKers66pbuft7lWKzBbsE3fFWTfyozWvGjmDke210=", "homepage": "https://registry.terraform.io/providers/linode/linode", "owner": "linode", "repo": "terraform-provider-linode", - "rev": "v2.23.1", + "rev": "v2.27.0", "spdx": "MPL-2.0", - "vendorHash": "sha256-lQ1+MVErv0g2Q7PSrO95Qzs0o/0hpL6JKK9E5J1EGic=" + "vendorHash": "sha256-bWyHzN+W3G83V8sjqn1bfLBuB71/O5DuUWsro58A2xs=" }, "linuxbox": { "hash": "sha256-MzasMVtXO7ZeZ+qEx2Z+7881fOIA0SFzSvXVHeEROtg=", @@ -741,13 +741,13 @@ "vendorHash": "sha256-PpLqFek6FnD+xWF8QMS2PFUP7sXXVWWWosq6fpLRzxg=" }, "lxd": { - "hash": "sha256-z7AjOKMSf2XnyCQiBcjFY0V9mDLF6Fj54Ck7971Ehio=", + "hash": "sha256-LGho9iCjKn0OR8sbnkduZtLIxcnVwpedvVinA78791c=", "homepage": "https://registry.terraform.io/providers/terraform-lxd/lxd", "owner": "terraform-lxd", "repo": "terraform-provider-lxd", - "rev": "v2.1.0", + "rev": "v2.3.0", "spdx": "MPL-2.0", - "vendorHash": "sha256-fu6EgUIw1rFswXM3xUi0DLSChhl2c3a70uJO7aZhX+I=" + "vendorHash": "sha256-J1KWnU0IspjoosI5wIAc8ygOImXlc3tFkhV3yDXoDl4=" }, "mailgun": { "hash": "sha256-Sj6iejtaSdAPg2tI5f0b88Lni431cervHxlQWwGl8Bo=", @@ -777,31 +777,31 @@ "vendorHash": "sha256-QxbZv6YMa5/I4bTeQBNdmG3EKtLEmstnH7HMiZzFJrI=" }, "migadu": { - "hash": "sha256-EGVIk828DwYGMkRBGs3Lnt9goYb+biWoZcXmfuy/OPg=", + "hash": "sha256-/VR2pko5ctH/Gz3zUMhmwlZOpxQPu1AgZ3wRddndf6c=", "homepage": "https://registry.terraform.io/providers/metio/migadu", "owner": "metio", "repo": "terraform-provider-migadu", - "rev": "2024.6.6", + "rev": "2024.9.5", "spdx": "0BSD", - "vendorHash": "sha256-xUb3tRMG9Exth2d2/1hGVa3llFss99up1cnNaldwse0=" + "vendorHash": "sha256-3pPRgmoC0eYFyu/kNpJty45MfIjBMN5uV8l7iQErAns=" }, "minio": { - "hash": "sha256-P+rhDVmZl8DouSOTkBRE2MNG0ZcpLDveO3Npt1AIEGU=", + "hash": "sha256-1f6T5sfrBPgwxKKZMknd3JJd7mv90zuGtXInDPKAg0M=", "homepage": "https://registry.terraform.io/providers/aminueza/minio", "owner": "aminueza", "repo": "terraform-provider-minio", - "rev": "v2.3.2", + "rev": "v2.5.0", "spdx": "AGPL-3.0", "vendorHash": "sha256-Gn4P4NIksv8S4DmnuYArxdSQDQsyCeayJJAIkmm/I6A=" }, "mongodbatlas": { - "hash": "sha256-8A2csdDMS5W0SzVRy7QATWUEDEZqR7gLRDpVAeROsZk=", + "hash": "sha256-ZAgoC6HNBIQP3tCo3+kZh7TyMDi+caPstqB5HpjTa5g=", "homepage": "https://registry.terraform.io/providers/mongodb/mongodbatlas", "owner": "mongodb", "repo": "terraform-provider-mongodbatlas", - "rev": "v1.17.3", + "rev": "v1.18.1", "spdx": "MPL-2.0", - "vendorHash": "sha256-idXan9/OGEKY+VT2dwWwj+P1fFQIrIs2ghkthz53j/g=" + "vendorHash": "sha256-llbYJi3ghgh9y97ri03a7ZBXSUPMs7f3FLd4iLRRmmk=" }, "namecheap": { "hash": "sha256-g3i7jZBOl2umsyRk1z7Radv8a9Ry6oQ8oorv3YbY7Xo=", @@ -822,31 +822,31 @@ "vendorHash": null }, "newrelic": { - "hash": "sha256-hJKYz95+i1j1KhDuh5Jcm8cZzBAD3cK5+a5B1vCYBXM=", + "hash": "sha256-Q1wY613U8cdAlHd+mVTKVNO4KBqVm2/HcKp66DTzbII=", "homepage": "https://registry.terraform.io/providers/newrelic/newrelic", "owner": "newrelic", "repo": "terraform-provider-newrelic", - "rev": "v3.39.1", + "rev": "v3.45.0", "spdx": "MPL-2.0", - "vendorHash": "sha256-EHO78DEZ92WRDP8ZA0M9zdZ8KsPWMA2ljgFY6dX29YM=" + "vendorHash": "sha256-C3dDWWmV7YrorPps0m0V9DQDraID57+vXWg8pBIYXIE=" }, "nomad": { - "hash": "sha256-42QZfbbugxV6USCz0Urnhfcsf+DZKpOepC44Z37dGkw=", + "hash": "sha256-OdttxZEY4fiLiK6ReoIFjN3VAvEgARQ9yBAqemVyheU=", "homepage": "https://registry.terraform.io/providers/hashicorp/nomad", "owner": "hashicorp", "repo": "terraform-provider-nomad", - "rev": "v2.3.0", + "rev": "v2.3.1", "spdx": "MPL-2.0", - "vendorHash": "sha256-+4JU2z56W/uT+DW4+LRf1hwK0nLK9WARTY31bqMpHNM=" + "vendorHash": "sha256-WTfhKSaSzXOsYH8Aso735y5fYCKEjwMtWto5oZ6lU4s=" }, "ns1": { - "hash": "sha256-96q68P+d7K4UycCZ0Z5w3HWIcKwsC4/UD6WPU6yyC7M=", + "hash": "sha256-3NDHEpvBlVb3IgkEjJ1g2Jpvy2MbgXSeabuCPlpKZmM=", "homepage": "https://registry.terraform.io/providers/ns1-terraform/ns1", "owner": "ns1-terraform", "repo": "terraform-provider-ns1", - "rev": "v2.3.1", + "rev": "v2.4.1", "spdx": "MPL-2.0", - "vendorHash": "sha256-0RRZF7/NHo9y7SUKZbq8nNU+gFdCb0u4XJgsobNeWsk=" + "vendorHash": "sha256-jTsjVhVEgtI3B+tLl9xLqQsGI2piQc6QA2EHqfVhDxg=" }, "null": { "hash": "sha256-KOwJXGvMc9Xgq4Kbr72aW6RDwzldUrU1C3aDxpKO3qE=", @@ -868,22 +868,22 @@ "vendorHash": "sha256-LRIfxQGwG988HE5fftGl6JmBG7tTknvmgpm4Fu1NbWI=" }, "oci": { - "hash": "sha256-yiHBWcOE2QxyhzKqjSPvgqAFu0hL13idWXbwkhAhNeE=", + "hash": "sha256-LlRy0i4JGjaeHMQMWUYtKgJOUqm0RFwtyDO+KtQcCRI=", "homepage": "https://registry.terraform.io/providers/oracle/oci", "owner": "oracle", "repo": "terraform-provider-oci", - "rev": "v6.1.0", + "rev": "v6.9.0", "spdx": "MPL-2.0", "vendorHash": null }, "okta": { - "hash": "sha256-GHC2HhpyPBQ5gPg/HPmP+Bms6O5mLhdAysKW58FWhwA=", + "hash": "sha256-lSZWAAZWkM2+fgLpbfsHLvu1m6R8LMrtc7hUPdwiioc=", "homepage": "https://registry.terraform.io/providers/okta/okta", "owner": "okta", "repo": "terraform-provider-okta", - "rev": "v4.9.1", + "rev": "v4.10.0", "spdx": "MPL-2.0", - "vendorHash": "sha256-71z33jsQmNQoCVSQCiyjHnfUMtwY+KB5Mn2MHItwGa0=" + "vendorHash": "sha256-8Wez4UkS0LsJTtgepdPpyZHhNZADxvGwOEVu6RLBI0o=" }, "oktaasa": { "hash": "sha256-2LhxgowqKvDDDOwdznusL52p2DKP+UiXALHcs9ZQd0U=", @@ -895,11 +895,11 @@ "vendorHash": null }, "onepassword": { - "hash": "sha256-rdS9Udzfc/U7E4CIyySnntOCVBBZL0/GuAiVCI5uMrc=", + "hash": "sha256-u2nSzEKD0o/e0AzeHdKQj3+h7mAt6r5cxaKsPn6nRGo=", "homepage": "https://registry.terraform.io/providers/1Password/onepassword", "owner": "1Password", "repo": "terraform-provider-onepassword", - "rev": "v2.1.0", + "rev": "v2.1.2", "spdx": "MIT", "vendorHash": null }, @@ -913,47 +913,47 @@ "vendorHash": "sha256-Hd6vh4ihuR1rRk5yIu1mPuDMb4Not4soKld10MfOuGU=" }, "openstack": { - "hash": "sha256-NSfKyXTuPiEYFE8guWsRcJsKiccMrHJRK4I5REzzIZQ=", + "hash": "sha256-Vt6cFZBfM5sP62zWeyoCuEPU6vRucGG8z7zeQywDA40=", "homepage": "https://registry.terraform.io/providers/terraform-provider-openstack/openstack", "owner": "terraform-provider-openstack", "repo": "terraform-provider-openstack", - "rev": "v2.0.0", + "rev": "v2.1.0", "spdx": "MPL-2.0", - "vendorHash": "sha256-TS1Zp9IMD+Mq91QhyRuDgzbwd61bASWLPft5JdNCcy4=" + "vendorHash": "sha256-UH4LgC4UATpglZ2lYb92LvEeAgqXyDFzujNnaYCYN3g=" }, "opentelekomcloud": { - "hash": "sha256-UhECzYRA9AaATeYdC68ALd3aoB8G0okWQm1U9VkgL5c=", + "hash": "sha256-CXWaIISfDtT6jTdFKE67LiRPlGaq+9fRO77GqIMrZhs=", "homepage": "https://registry.terraform.io/providers/opentelekomcloud/opentelekomcloud", "owner": "opentelekomcloud", "repo": "terraform-provider-opentelekomcloud", - "rev": "v1.36.12", + "rev": "v1.36.18", "spdx": "MPL-2.0", - "vendorHash": "sha256-PwYc9p8nRe0QkgLKLOeb7KYTLgFiT2JQGsmTfFLzBH4=" + "vendorHash": "sha256-vsK74qZ20VOID5sg7kHjxBXiu1dkyJ961zFf0+QkqH0=" }, "opsgenie": { - "hash": "sha256-ZssKhfwFrzCjvlebEmKAHWBInN5daVqxbmVFoA92dv8=", + "hash": "sha256-+msy9kPAryR0Ll5jKOd47DMjeMxEdSIfKZZKVHohQGY=", "homepage": "https://registry.terraform.io/providers/opsgenie/opsgenie", "owner": "opsgenie", "repo": "terraform-provider-opsgenie", - "rev": "v0.6.35", + "rev": "v0.6.37", "spdx": "MPL-2.0", "vendorHash": null }, "ovh": { - "hash": "sha256-346lBl1AnEdZmLEfsPiTW7I6rhOv61t004DBx7gRkF8=", + "hash": "sha256-XVNinT1kjvjrVLB4NXELw1Rf6UZEkX4el+dKzOO0QjY=", "homepage": "https://registry.terraform.io/providers/ovh/ovh", "owner": "ovh", "repo": "terraform-provider-ovh", - "rev": "v0.45.0", + "rev": "v0.48.0", "spdx": "MPL-2.0", "vendorHash": null }, "pagerduty": { - "hash": "sha256-sXFRN05mn5hMIqxhwIvYWlMgkrUGZqi+J29Sq9GRS90=", + "hash": "sha256-+8Ar/PDGSSe9Xs2BoNndrBCXZpgqKHNXz7HNVvok1Eo=", "homepage": "https://registry.terraform.io/providers/PagerDuty/pagerduty", "owner": "PagerDuty", "repo": "terraform-provider-pagerduty", - "rev": "v3.14.5", + "rev": "v3.15.6", "spdx": "MPL-2.0", "vendorHash": null }, @@ -976,13 +976,13 @@ "vendorHash": "sha256-pbJk35O8EowCa2dgLCrPDgakR0EJVaAnEvePGnrl/YQ=" }, "postgresql": { - "hash": "sha256-UNnAe5alro4dEZ9x2ZDsjybOgHq2IVs8w9rMcMJBm8w=", + "hash": "sha256-v/88uUvILQT0uHRgfwMuLQWw0ma2ELT691kQ9GVjr/A=", "homepage": "https://registry.terraform.io/providers/cyrilgdn/postgresql", "owner": "cyrilgdn", "repo": "terraform-provider-postgresql", - "rev": "v1.22.0", + "rev": "v1.23.0", "spdx": "MPL-2.0", - "vendorHash": "sha256-omJjWeCLIdHIySQW8tcDPQ1XPmfWbPDOGwPUedrb8Bw=" + "vendorHash": "sha256-fHNXJGyOWGF7Dwfk14GWmLXSIENsshIHbxkF7iQJNuI=" }, "powerdns": { "hash": "sha256-NtJs2oNJbjUYNFsbrfo2RYhqOlKA15GJt9gi1HuTIw0=", @@ -994,13 +994,13 @@ "vendorHash": null }, "project": { - "hash": "sha256-CuUHTuq2ufSuolpvfkT4Q30tiIGkpuIoYCYqY9EOd9s=", + "hash": "sha256-rxv1owtlc9P9uZDReH0lKFUUTSL+X+HlkWL5FWz3bHw=", "homepage": "https://registry.terraform.io/providers/jfrog/project", "owner": "jfrog", "repo": "terraform-provider-project", - "rev": "v1.6.2", + "rev": "v1.7.2", "spdx": "Apache-2.0", - "vendorHash": "sha256-UcoTldBVqCPh1SVaZm2aKeRVCVfgE/zGOR7+feDEUM0=" + "vendorHash": "sha256-ld52rPoG4bCfU+qizliuwmz6ncxrhcoAYOEZo5mnCYI=" }, "proxmox": { "hash": "sha256-ikXLLNoAjrnGGGI3fHTKFXm8YwqNazE/U39JTjOBsW4=", @@ -1021,13 +1021,13 @@ "vendorHash": "sha256-j+3qtGlueKZgf0LuNps4Wc9G3EmpSgl8ZNSLqslyizI=" }, "rancher2": { - "hash": "sha256-w9oAeE8KuD7kdBFOkNgifaELrxr3X1yKYXFiQLyaGY8=", + "hash": "sha256-n4sEIew7C7tG19paaJjgtCwGt5KhUyoR/OGoLu4Kal8=", "homepage": "https://registry.terraform.io/providers/rancher/rancher2", "owner": "rancher", "repo": "terraform-provider-rancher2", - "rev": "v4.1.0", + "rev": "v5.0.0", "spdx": "MPL-2.0", - "vendorHash": "sha256-kzOEHkVCHOwISXVPmKbJJ2BbBdIJ3G1JtA1nFGZYnG8=" + "vendorHash": "sha256-uIyLOqabx8wQurxcG70LHm+jBga+bCNyf5XxGrt5OKA=" }, "random": { "hash": "sha256-10SRHJx7h04qRH4XnBsqiwJ43nxTodj89kkik2UTI6E=", @@ -1057,13 +1057,13 @@ "vendorHash": null }, "scaleway": { - "hash": "sha256-VTtS5iqeMzcaVveMlnJZDrXUSf0Ts/FG7STVix08mQs=", + "hash": "sha256-h30SfKtx2l9zp9ZGy1KRoQRmb83B4e48R/URJ2I2J+U=", "homepage": "https://registry.terraform.io/providers/scaleway/scaleway", "owner": "scaleway", "repo": "terraform-provider-scaleway", - "rev": "v2.41.3", + "rev": "v2.44.0", "spdx": "MPL-2.0", - "vendorHash": "sha256-eLQLozDXk83vjfTrsJHQqU3GMZToMwvjadqf+X7OeOU=" + "vendorHash": "sha256-crp1XJRsWBEhRFC1CzLTgBTrTLaM2Y39Mwx+l1mg0Ks=" }, "secret": { "hash": "sha256-MmAnA/4SAPqLY/gYcJSTnEttQTsDd2kEdkQjQj6Bb+A=", @@ -1075,13 +1075,13 @@ "vendorHash": null }, "selectel": { - "hash": "sha256-yIQdxwkcpFKm2+woHW7yClWAwQr82XaCDFHh6KAOaQI=", + "hash": "sha256-cLN0wNT8Yn+uiaGZFzdDg1ZN4pzm5VHriMgRGZv3ZpU=", "homepage": "https://registry.terraform.io/providers/selectel/selectel", "owner": "selectel", "repo": "terraform-provider-selectel", - "rev": "v5.1.1", + "rev": "v5.3.0", "spdx": "MPL-2.0", - "vendorHash": "sha256-PyATpaCqu8csmpf83EODKgecZaquraFlh1bTYhhhBO4=" + "vendorHash": "sha256-MP44e56j7rLyT4+TbFDfDb5GNc/LzZNLplm1/qqeGiw=" }, "sentry": { "hash": "sha256-iTwl5FowrrhznO+Zr7QXy7/6HlYWCryZTMxNsBGSfWI=", @@ -1102,13 +1102,13 @@ "vendorHash": "sha256-MIO0VHofPtKPtynbvjvEukMNr5NXHgk7BqwIhbc9+u0=" }, "signalfx": { - "hash": "sha256-JPL2VjYIg8qW9kk6QaT3+alWtMvKHXRlqLD6AZ2+cQ0=", + "hash": "sha256-OmM3NvTnT/yZBgBYf15vITJSVOXQ7Vvqn6T6+LXOpbk=", "homepage": "https://registry.terraform.io/providers/splunk-terraform/signalfx", "owner": "splunk-terraform", "repo": "terraform-provider-signalfx", - "rev": "v9.1.5", + "rev": "v9.1.6", "spdx": "MPL-2.0", - "vendorHash": "sha256-uPAWL2BigYiazZQSScM/J39dLDtYheq2P6l4A9M3rOA=" + "vendorHash": "sha256-h+tusSFbu4jmfu0v1BwRrSoDEPYjXZwQ+YykRUoXlv4=" }, "skytap": { "hash": "sha256-JII4czazo6Di2sad1uFHMKDO2gWgZlQE8l/+IRYHQHU=", @@ -1129,40 +1129,40 @@ "vendorHash": "sha256-F1AuO/dkldEDRvkwrbq2EjByxjg3K2rohZAM4DzKPUw=" }, "snowflake": { - "hash": "sha256-3vC246+XoCfmnEdNFHW8iy0fy5aN+kmaZzgJot4hKs0=", + "hash": "sha256-jIzLT2tQViOdNOQ462fM1SFt0E22QZbUdh33OjmUf+k=", "homepage": "https://registry.terraform.io/providers/Snowflake-Labs/snowflake", "owner": "Snowflake-Labs", "repo": "terraform-provider-snowflake", - "rev": "v0.92.0", + "rev": "v0.95.0", "spdx": "MIT", - "vendorHash": "sha256-pxti3wXBke16zoEPaTbXrTc/LI1QbvKfBvbUSxnAIOk=" + "vendorHash": "sha256-FPIqTXbGLui6QW1bFhwV4rGgo8IUw3XkmryqmjpM5Sw=" }, "sops": { - "hash": "sha256-ZastswL5AVurQY3xn6yx3M1BMvQ9RjfcZdXX0S/oZqw=", + "hash": "sha256-MdsWKV98kWpZpTK5qC7x6vN6cODxeeiVVc+gtlh1s88=", "homepage": "https://registry.terraform.io/providers/carlpett/sops", "owner": "carlpett", "repo": "terraform-provider-sops", - "rev": "v1.0.0", + "rev": "v1.1.1", "spdx": "MPL-2.0", - "vendorHash": "sha256-8W1PK4T98iK1N6EB6AVjvr1P9Ja51+kSOmYAEosxrh8=" + "vendorHash": "sha256-YFV+qXD78eajSeagJPgPu+qIktx1Vh/ZT0fUPOBuZyo=" }, "spacelift": { - "hash": "sha256-xDkOngj8wPsqZhyYh0oVA9YVwMY+bRnpXL2yjpkN38M=", + "hash": "sha256-kEfZ1ErNMdUGw1eRiX4SphreCCGMQj1Wj0DLFikTfxI=", "homepage": "https://registry.terraform.io/providers/spacelift-io/spacelift", "owner": "spacelift-io", "repo": "terraform-provider-spacelift", - "rev": "v1.14.0", + "rev": "v1.15.0", "spdx": "MIT", "vendorHash": "sha256-m/J390su2nUpYMXrrYcOfKSjZb5Y23+g24rroLRss4U=" }, "spotinst": { - "hash": "sha256-SOzaTZIBEC9se942ofYHURH8btw38upJtnlDDWmLcTM=", + "hash": "sha256-ChtaZkztmyFPJvtoE+TUPzZyEEoZ6y3o1CgnKsnK6I4=", "homepage": "https://registry.terraform.io/providers/spotinst/spotinst", "owner": "spotinst", "repo": "terraform-provider-spotinst", - "rev": "v1.180.2", + "rev": "v1.190.0", "spdx": "MPL-2.0", - "vendorHash": "sha256-mgDWGimTq7AODC+ojipWUgCDKpC/EP/W8x8kbey05mQ=" + "vendorHash": "sha256-JGwBQMsMGxH5ceHOd5CbSQFQdL6u99lHpWFgJUyMYRQ=" }, "ssh": { "hash": "sha256-1UN5QJyjCuxs2vQYlSuz2jsu/HgGTxOoWWRcv4qcwow=", @@ -1192,20 +1192,20 @@ "vendorHash": "sha256-9M1DsE/FPQK8TG7xCJWbU3HAJCK3p/7lxdzjO1oAfWs=" }, "sumologic": { - "hash": "sha256-LPJwJ6j/eZzOliHH7Ci49c5CqDckaqSm7ikLKTVhuew=", + "hash": "sha256-e/Vmu+odmn/IasHl6dSy5aYLRi/lTcVjpzJl+YYn1mg=", "homepage": "https://registry.terraform.io/providers/SumoLogic/sumologic", "owner": "SumoLogic", "repo": "terraform-provider-sumologic", - "rev": "v2.31.1", + "rev": "v2.31.3", "spdx": "MPL-2.0", "vendorHash": "sha256-YdWs2orKhbwAZSQYC73t4e/vvVxk8LrBPG9ZC38VcZE=" }, "tailscale": { - "hash": "sha256-hMcnHTdxxEfAU5cd0nlK2Bc+fxfrERk4wYaRidPM4mA=", + "hash": "sha256-GflanQbIPpS0mxmw7LXeTfPly+CmgpsoLHBIMe6f7xM=", "homepage": "https://registry.terraform.io/providers/tailscale/tailscale", "owner": "tailscale", "repo": "terraform-provider-tailscale", - "rev": "v0.16.1", + "rev": "v0.16.2", "spdx": "MIT", "vendorHash": "sha256-RAmAN57hIHvQvZ2pjbLbanixUk8Cart6a3PQPXhnx9U=" }, @@ -1219,49 +1219,49 @@ "vendorHash": "sha256-939lQsdp0Ixj9FU7IqxbOAM93GwL+X6gC3kY5/0x+AE=" }, "temporalcloud": { - "hash": "sha256-PIqsCdIaFob/C2b1Rem/JYl7bQVvdRecDQDkcAZutz0=", + "hash": "sha256-OD3cCNRZG9wQSu/aFmnVzcUbJyASusM1rt2PdpWKXkI=", "homepage": "https://registry.terraform.io/providers/temporalio/temporalcloud", "owner": "temporalio", "repo": "terraform-provider-temporalcloud", - "rev": "v0.0.9", + "rev": "v0.0.11", "spdx": "MPL-2.0", "vendorHash": "sha256-/yXPJgwpUCKRs3Sf2BbuHp3pfQiheTAh7Auxk3qkTFg=" }, "tencentcloud": { - "hash": "sha256-PZWBVLUfWn13B7saz2XecMv6pWWqPMOfBzqr2pErnvs=", + "hash": "sha256-HgBC+C7z15cdVUBOAaPE3ddhEKMfp7Ow+lWqS/EkD98=", "homepage": "https://registry.terraform.io/providers/tencentcloudstack/tencentcloud", "owner": "tencentcloudstack", "repo": "terraform-provider-tencentcloud", - "rev": "v1.81.107", + "rev": "v1.81.120", "spdx": "MPL-2.0", "vendorHash": null }, "tfe": { - "hash": "sha256-mfJtQs+fl7zfysWJO/EBM/DMYYOvR5nuOwDA6sei1PI=", + "hash": "sha256-lXwdNtdbCwiotVCGBIiAPHUjNdj+srpBaW30GUWW0ao=", "homepage": "https://registry.terraform.io/providers/hashicorp/tfe", "owner": "hashicorp", "repo": "terraform-provider-tfe", - "rev": "v0.56.0", + "rev": "v0.58.1", "spdx": "MPL-2.0", - "vendorHash": "sha256-heMfI1NLjOHSKondXY8mRCNWFedSYJqfn9nU2Ywj57c=" + "vendorHash": "sha256-eeVkzZ+ATTyZCEq4loEbIb0XO/Ir1jejUaWi4Jd6nMo=" }, "thunder": { - "hash": "sha256-ezolcZ652YUV/CDoNKNRZkiRpRoa5AMqHxeYLxluA5A=", + "hash": "sha256-2i1DSOSt/vbFs0QCPogEBvADhLJFKbrQzwZ20ChCQMk=", "homepage": "https://registry.terraform.io/providers/a10networks/thunder", "owner": "a10networks", "repo": "terraform-provider-thunder", - "rev": "v1.4.1", + "rev": "v1.4.2", "spdx": "BSD-2-Clause", "vendorHash": null }, "time": { - "hash": "sha256-Uwe0VpY7CKXNy6RNS+yoIkyLmMQ2daJ5x7IhJV+KuxU=", + "hash": "sha256-mAGBcBMd00r2URY/jqZQBLjo0mN+IMG5ONVKj0AwXNs=", "homepage": "https://registry.terraform.io/providers/hashicorp/time", "owner": "hashicorp", "repo": "terraform-provider-time", - "rev": "v0.11.2", + "rev": "v0.12.0", "spdx": "MPL-2.0", - "vendorHash": "sha256-dmBCjbVmK4Qa07bcgUxKch5Vj7nylgNA7rzx+7ag3CY=" + "vendorHash": "sha256-C40wkY1M9d5oPO6TOm/iu99Gcrnnin1ggn9mbOJ0YjY=" }, "tls": { "hash": "sha256-2K18jY2+oPvelMtZ2o4WJcAPhc93nCvJdHq+VNfmWZI=", @@ -1283,11 +1283,11 @@ "vendorHash": "sha256-UuLHaOEG6jmOAgfdNOtLyUimlAr3g6K8n3Ehu64sKqk=" }, "turbot": { - "hash": "sha256-OmhNZZcCw6tGsL3Ha4cdg76GHqMjKeRB6aOXfqkIOjQ=", + "hash": "sha256-lVKJKMCAm8paXxfPo6YvJBnHdmV4iwaTYmwdN31s/e4=", "homepage": "https://registry.terraform.io/providers/turbot/turbot", "owner": "turbot", "repo": "terraform-provider-turbot", - "rev": "v1.10.1", + "rev": "v1.11.1", "spdx": "MPL-2.0", "vendorHash": null }, @@ -1301,22 +1301,22 @@ "vendorHash": null }, "utils": { - "hash": "sha256-9a8K2Yl3hfmUG+/QgQJdXnW6lxkOJps1BskFto3tIwg=", + "hash": "sha256-bxjEdmPgKPFpRM9Jz9nichDhXY+7x74WS6VjZGf9VUE=", "homepage": "https://registry.terraform.io/providers/cloudposse/utils", "owner": "cloudposse", "repo": "terraform-provider-utils", - "rev": "1.23.0", + "rev": "v1.26.0", "spdx": "Apache-2.0", - "vendorHash": "sha256-oaVBYSH2ix9SUqvrFo+oBIS80/Sb3E7Z/Jpvznt+OtU=" + "vendorHash": "sha256-zJtVKDaqOMQqyAzq4VtVv5MgXS999BwxeWhXQI6McC4=" }, "vault": { - "hash": "sha256-tPRwdSwygypfgXAS3QmZNAb4GXe/8IFsRs8YGa4HDJg=", + "hash": "sha256-EiCLz5Z0ztwWrn8yHG9JnuIizicpi3WtvDSGyBtzgSY=", "homepage": "https://registry.terraform.io/providers/hashicorp/vault", "owner": "hashicorp", "repo": "terraform-provider-vault", - "rev": "v4.3.0", + "rev": "v4.4.0", "spdx": "MPL-2.0", - "vendorHash": "sha256-rS6tigtjTGG2c4FwSjn6dvblwqYtPQS/tl7qQ+P7uVM=" + "vendorHash": "sha256-z9qg6NVKYIU2OQTW8g72t6B69aTL/BeLCUFeoII75cE=" }, "vcd": { "hash": "sha256-4+7CblKeop9Uwpl7XxjmR33XE/mcmZfOuFJrJuqzZmw=", @@ -1364,13 +1364,13 @@ "vendorHash": null }, "vsphere": { - "hash": "sha256-rF7gtZUPse6ewcawmxlIfCmVRKKNJMUwqVVEBaLvLbE=", + "hash": "sha256-V13LeUNJ4LbP18CMRphU/w/7eytg49j5//gl/sZSV04=", "homepage": "https://registry.terraform.io/providers/hashicorp/vsphere", "owner": "hashicorp", "repo": "terraform-provider-vsphere", - "rev": "v2.8.2", + "rev": "v2.9.1", "spdx": "MPL-2.0", - "vendorHash": "sha256-TxaYIJtEIgy0Q56Gk1JXqIUuVyVJNVH0gKmdzzDWW/E=" + "vendorHash": "sha256-ozdbYuqz6ua1ubh48IkLxJZ6xAV2ho9mkhtnCTwzRIM=" }, "vultr": { "hash": "sha256-gQwLGnYmB9bwpGrLNdbw+zY0MlPPrY/37rJPtindT1Q=", @@ -1391,12 +1391,12 @@ "vendorHash": "sha256-GRnVhGpVgFI83Lg34Zv1xgV5Kp8ioKTFV5uaqS80ATg=" }, "yandex": { - "hash": "sha256-FwwjHWwUUtOwZZh0YeUbSnSLFH1Q80ALFHhd0tCAZNQ=", + "hash": "sha256-47aAZuGLhiHLzk0mvHD48NfoSUs1Ec3R4DGEpbvPyj8=", "homepage": "https://registry.terraform.io/providers/yandex-cloud/yandex", "owner": "yandex-cloud", "repo": "terraform-provider-yandex", - "rev": "v0.123.0", + "rev": "v0.128.0", "spdx": "MPL-2.0", - "vendorHash": "sha256-K6Khgg9sAG2S/onFUlVG5mZfMtvpvVJeU6YQOyA4Liw=" + "vendorHash": "sha256-4uHYcg+dJg1bJQRsJWDT9VEsPs5JOvGIdrw8cj0IkrE=" } } diff --git a/pkgs/by-name/do/dotenvx/package.nix b/pkgs/by-name/do/dotenvx/package.nix index a285b546d75b..ca2c269d728b 100644 --- a/pkgs/by-name/do/dotenvx/package.nix +++ b/pkgs/by-name/do/dotenvx/package.nix @@ -8,16 +8,16 @@ buildNpmPackage rec { pname = "dotenvx"; - version = "1.8.0"; + version = "1.14.0"; src = fetchFromGitHub { owner = "dotenvx"; repo = "dotenvx"; rev = "refs/tags/v${version}"; - hash = "sha256-j30ZEYO8OBMhEPn+LDipZ/aciWrI9QWStz6tHq0uX7E="; + hash = "sha256-UVev21LZ2y0C8BCSm6I8BTQziSDZUXP3A/ThOpKtsrQ="; }; - npmDepsHash = "sha256-ZSnrV1C9NX/Wq7cjKlM1w/m6T7snfnPru5g0pqFTGis="; + npmDepsHash = "sha256-ehWHIKYkSAkdTLGpBOU7lJoWNa5uv9Zy0+2qwnCv0m8="; dontNpmBuild = true; diff --git a/pkgs/by-name/ki/kitex/package.nix b/pkgs/by-name/ki/kitex/package.nix index ee1f5fcf85ff..b18d972886f0 100644 --- a/pkgs/by-name/ki/kitex/package.nix +++ b/pkgs/by-name/ki/kitex/package.nix @@ -7,16 +7,16 @@ buildGoModule rec { pname = "kitex"; - version = "0.10.3"; + version = "0.11.0"; src = fetchFromGitHub { owner = "cloudwego"; repo = "kitex"; rev = "v${version}"; - hash = "sha256-aSvN8yjCHxhzLHwQovWFMaoD6ljy8aikxI7jUoeRvDs="; + hash = "sha256-SD898LbygIHL0X5YVSoJRdP1GQiB8NGfIAFAlx4Gfe8="; }; - vendorHash = "sha256-nscMcJGFZ1YPPynTV+Mp8tXndtlIcszDZm36zMbNBYs="; + vendorHash = "sha256-tdtiG0jf7Ilvs1KZWggGyqBOQXAWs+zlF09AN80AoC0="; subPackages = [ "tool/cmd/kitex" ]; diff --git a/pkgs/applications/networking/cluster/kubectl-gadget/default.nix b/pkgs/by-name/ku/kubectl-gadget/package.nix similarity index 64% rename from pkgs/applications/networking/cluster/kubectl-gadget/default.nix rename to pkgs/by-name/ku/kubectl-gadget/package.nix index 30e835ba2c0b..5126591d7960 100644 --- a/pkgs/applications/networking/cluster/kubectl-gadget/default.nix +++ b/pkgs/by-name/ku/kubectl-gadget/package.nix @@ -1,17 +1,17 @@ -{ lib, buildGoModule, fetchFromGitHub }: +{ lib, buildGoModule, fetchFromGitHub, kubectl-gadget, testers }: buildGoModule rec { pname = "kubectl-gadget"; - version = "0.31.0"; + version = "0.32.0"; src = fetchFromGitHub { owner = "inspektor-gadget"; repo = "inspektor-gadget"; rev = "v${version}"; - hash = "sha256-f93PdSA3OGiUUXSQn0aUP3o5xfvjiq/3L3Bz9k4OigI="; + hash = "sha256-c6hy7B8zaU/LnTMAohc9KPzu1ocOVFJ9wL4GOIwxqkw="; }; - vendorHash = "sha256-lBfz0tzCWKEAAmpvjB2kUJ3aLjlzAjniIu/1aNE80Xg="; + vendorHash = "sha256-7HfYCHxQUapDo33IAzxCp2iaL4G7oOqK0KyjqbmbR/w="; CGO_ENABLED = 0; @@ -28,6 +28,12 @@ buildGoModule rec { subPackages = [ "cmd/kubectl-gadget" ]; + passthru.tests.version = testers.testVersion { + package = kubectl-gadget; + command = "kubectl-gadget version || true"; # mask non-zero return code if no kubeconfig present + version = "v${version}"; + }; + meta = with lib; { description = "Collection of gadgets for troubleshooting Kubernetes applications using eBPF"; mainProgram = "kubectl-gadget"; diff --git a/pkgs/by-name/mo/monitorets/package.nix b/pkgs/by-name/mo/monitorets/package.nix new file mode 100644 index 000000000000..4234bbf0904f --- /dev/null +++ b/pkgs/by-name/mo/monitorets/package.nix @@ -0,0 +1,61 @@ +{ + lib, + python3Packages, + fetchFromGitHub, + meson, + ninja, + pkg-config, + gobject-introspection, + wrapGAppsHook4, + desktop-file-utils, + libadwaita, +}: + +python3Packages.buildPythonApplication rec { + pname = "monitorets"; + version = "0.10.1"; + # built with meson, not a python format + pyproject = false; + + src = fetchFromGitHub { + owner = "jorchube"; + repo = "monitorets"; + rev = "refs/tags/${version}"; + hash = "sha256-Y6cd9Wf2IzHwdxzLUP/U4rervlPUr8s2gKSW8y5I7bg="; + }; + + nativeBuildInputs = [ + meson + ninja + pkg-config + gobject-introspection + wrapGAppsHook4 + desktop-file-utils + ]; + + buildInputs = [ libadwaita ]; + + dependencies = with python3Packages; [ + pygobject3 + xdg + psutil + ]; + + dontWrapGApps = true; + + preFixup = '' + makeWrapperArgs+=("''${gappsWrapperArgs[@]}") + ''; + + meta = { + description = "Simple and quick view at the usage of your computer resources"; + homepage = "https://github.com/jorchube/monitorets"; + license = with lib.licenses; [ + gpl3Plus + cc0 + ]; + mainProgram = "monitorets"; + maintainers = with lib.maintainers; [ aleksana ]; + platforms = lib.platforms.linux; + }; +} diff --git a/pkgs/development/python-modules/ansible-compat/default.nix b/pkgs/development/python-modules/ansible-compat/default.nix index 012a749e3831..cbe3fde9a5bf 100644 --- a/pkgs/development/python-modules/ansible-compat/default.nix +++ b/pkgs/development/python-modules/ansible-compat/default.nix @@ -16,7 +16,7 @@ buildPythonPackage rec { pname = "ansible-compat"; - version = "24.8.0"; + version = "24.9.0"; pyproject = true; disabled = pythonOlder "3.10"; @@ -24,7 +24,7 @@ buildPythonPackage rec { src = fetchPypi { pname = "ansible_compat"; inherit version; - hash = "sha256-z6rcY/TYXcv0eI97zsLKhWPntcn9MFgAXv15iPHBciw="; + hash = "sha256-xaQqVt0hJiXPyx0x5RpuD1JZNpG94f5KeIgeixt4prg="; }; nativeBuildInputs = [ diff --git a/pkgs/development/python-modules/etils/default.nix b/pkgs/development/python-modules/etils/default.nix index 401fbba09893..a78831b4aedf 100644 --- a/pkgs/development/python-modules/etils/default.nix +++ b/pkgs/development/python-modules/etils/default.nix @@ -29,14 +29,14 @@ buildPythonPackage rec { pname = "etils"; - version = "1.9.3"; + version = "1.9.4"; pyproject = true; disabled = pythonOlder "3.10"; src = fetchPypi { inherit pname version; - hash = "sha256-qjt6hF3jwbabMMoHBG6MT9LoXsvmBKpL8Y6pPnsxhPA="; + hash = "sha256-+tlQQU8KHKWMcMcJFbABT5lT3ZvPiqlRoPdf+b7L6yQ="; }; nativeBuildInputs = [ flit-core ]; diff --git a/pkgs/development/python-modules/pytest-textual-snapshot/default.nix b/pkgs/development/python-modules/pytest-textual-snapshot/default.nix index 6661b9397ac9..911cdd5d0def 100644 --- a/pkgs/development/python-modules/pytest-textual-snapshot/default.nix +++ b/pkgs/development/python-modules/pytest-textual-snapshot/default.nix @@ -13,7 +13,7 @@ buildPythonPackage rec { pname = "pytest-textual-snapshot"; - version = "0.4.0"; + version = "1.0.0"; pyproject = true; disabled = pythonOlder "3.8"; @@ -22,7 +22,7 @@ buildPythonPackage rec { owner = "Textualize"; repo = "pytest-textual-snapshot"; rev = "refs/tags/v${version}"; - hash = "sha256-XkXeyodRdwWqCP63Onx82Z3IbNLDDR/Lvaw8xUY7fAg="; + hash = "sha256-C8vL2kLOvVcDlTtNiG/pf7PwHzb/F0sWdkEcLvdGrd8="; }; nativeBuildInputs = [ poetry-core ]; diff --git a/pkgs/development/python-modules/rns/default.nix b/pkgs/development/python-modules/rns/default.nix index 0b17ff43caf5..0dd92d28305f 100644 --- a/pkgs/development/python-modules/rns/default.nix +++ b/pkgs/development/python-modules/rns/default.nix @@ -13,7 +13,7 @@ buildPythonPackage rec { pname = "rns"; - version = "0.7.6"; + version = "0.7.7"; pyproject = true; disabled = pythonOlder "3.7"; @@ -22,7 +22,7 @@ buildPythonPackage rec { owner = "markqvist"; repo = "Reticulum"; rev = "refs/tags/${version}"; - hash = "sha256-YSaabiCsSoG3BZ/0gM/fRIKQKdQ9MRtlHe+tPnzFJSw="; + hash = "sha256-cNOVk7JCu4kMevH9MAWWvtLIzfbBBy+h7bhTBhkfrvI="; }; patches = [ diff --git a/pkgs/servers/monitoring/prometheus/pgbouncer-exporter.nix b/pkgs/servers/monitoring/prometheus/pgbouncer-exporter.nix index 970d63ec0f2e..90ffdb48f0d1 100644 --- a/pkgs/servers/monitoring/prometheus/pgbouncer-exporter.nix +++ b/pkgs/servers/monitoring/prometheus/pgbouncer-exporter.nix @@ -2,16 +2,16 @@ buildGoModule rec { pname = "pgbouncer-exporter"; - version = "0.8.0"; + version = "0.9.0"; src = fetchFromGitHub { owner = "prometheus-community"; repo = "pgbouncer_exporter"; rev = "v${version}"; - hash = "sha256-QnA9H4qedCPZKqJQ1I2OJO42mCWcWqYxLmeF3+JXzTw="; + hash = "sha256-fKoyRHYLwVefsZ014eazVCD5B9eV8/CUkuHE4mbUqVo="; }; - vendorHash = "sha256-NYiVW+CNrxFrEUl1nsTeNNgy7SmTYgqs1d50rCvyBcw="; + vendorHash = "sha256-IxmxfF9WsF0Hbym4G0UecyW8hAvucoaCFUE1kXUljJs="; meta = with lib; { description = "Prometheus exporter for PgBouncer"; diff --git a/pkgs/tools/networking/nebula/default.nix b/pkgs/tools/networking/nebula/default.nix index 0f6c0cc8b754..9c3bf4494666 100644 --- a/pkgs/tools/networking/nebula/default.nix +++ b/pkgs/tools/networking/nebula/default.nix @@ -6,16 +6,16 @@ buildGoModule rec { pname = "nebula"; - version = "1.9.3"; + version = "1.9.4"; src = fetchFromGitHub { owner = "slackhq"; repo = pname; rev = "refs/tags/v${version}"; - hash = "sha256-+RferzOPlx7UuqpckQBY/RDO9gptknhuan+Es0Vf/yM="; + hash = "sha256-Y8BTbvdSJ+xlxHuy0TzQEGiymJzAqlHe3PiXAlUddPs="; }; - vendorHash = "sha256-4BnFvA0dxsEK7ictDUZ6nol6PtM54kk9dwKPTQbRUR0="; + vendorHash = "sha256-oXhq+s5gDKPVClZpOzYi7BaYwcDqbCLBEO5BNGy9LJA="; subPackages = [ "cmd/nebula" "cmd/nebula-cert" ]; diff --git a/pkgs/tools/package-management/nix/default.nix b/pkgs/tools/package-management/nix/default.nix index 35edaf2bef46..65fdeb5446c0 100644 --- a/pkgs/tools/package-management/nix/default.nix +++ b/pkgs/tools/package-management/nix/default.nix @@ -184,7 +184,7 @@ in lib.makeExtensible (self: ({ self_attribute_name = "nix_2_23"; }; - nix_2_24 = (common { + nix_2_24 = ((common { version = "2.24.5"; hash = "sha256-mYvdPwl4gcc17UAomkbbOJEgxBQpowmJDrRMWtlYzFY="; self_attribute_name = "nix_2_24"; @@ -197,9 +197,13 @@ in lib.makeExtensible (self: ({ # allocation function Clang uses with this setting actually works # all the way back to 10.6. stdenv = overrideSDK stdenv { darwinMinVersion = "10.13"; }; + })).overrideAttrs (o: { + meta.knownVulnerabilities = [ + "Nix >= 2.24.0 and master have a vulnerability. Please downgrade from nix_2_24 to nix_2_23" + ]; }); - git = (common rec { + git = ((common rec { version = "2.25.0"; suffix = "pre20240807_${lib.substring 0 8 src.rev}"; src = fetchFromGitHub { @@ -218,9 +222,13 @@ in lib.makeExtensible (self: ({ # allocation function Clang uses with this setting actually works # all the way back to 10.6. stdenv = overrideSDK stdenv { darwinMinVersion = "10.13"; }; + })).overrideAttrs (o: { + meta.knownVulnerabilities = [ + "Nix >= 2.24.0 and master have a vulnerability. Please downgrade from nixVersions.git to nixVersions.nix_2_23" + ]; }); - latest = self.nix_2_24; + latest = self.nix_2_23; # The minimum Nix version supported by Nixpkgs # Note that some functionality *might* have been backported into this Nix version, diff --git a/pkgs/top-level/all-packages.nix b/pkgs/top-level/all-packages.nix index 7da154278426..0f0dead899f4 100644 --- a/pkgs/top-level/all-packages.nix +++ b/pkgs/top-level/all-packages.nix @@ -31190,8 +31190,6 @@ with pkgs; kubectl-explore = callPackage ../applications/networking/cluster/kubectl-explore { }; - kubectl-gadget = callPackage ../applications/networking/cluster/kubectl-gadget { }; - kubectl-images = callPackage ../applications/networking/cluster/kubectl-images { }; kubectl-klock = callPackage ../applications/networking/cluster/kubectl-klock { };