Revert "modules/virtualisation: add shared options, merge various diskSize options" (#340894)

Breaks evaluation of all nixos tests, and is therefore a channel blocker.
This commit is contained in:
Martin Weinelt 2024-09-10 03:12:55 +02:00 committed by GitHub
parent 757e0a34b7
commit 4cec81a995
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
15 changed files with 1293 additions and 1759 deletions

View file

@ -1,50 +1,24 @@
{ { config, lib, pkgs, ... }:
config,
lib,
pkgs,
...
}:
let let
inherit (lib) inherit (lib) mkOption optionalString types versionAtLeast;
mkOption
optionalString
types
versionAtLeast
;
inherit (lib.options) literalExpression; inherit (lib.options) literalExpression;
cfg = config.amazonImage; cfg = config.amazonImage;
amiBootMode = if config.ec2.efi then "uefi" else "legacy-bios"; amiBootMode = if config.ec2.efi then "uefi" else "legacy-bios";
virtualisationOptions = import ../../../modules/virtualisation/virtualisation-options.nix;
in in {
{
imports = [ imports = [ ../../../modules/virtualisation/amazon-image.nix ];
../../../modules/virtualisation/amazon-image.nix
virtualisationOptions.diskSize
(lib.mkRenamedOptionModuleWith {
sinceRelease = 2411;
from = [
"virtualisation"
"amazonImage"
"sizeMB"
];
to = [
"virtualisation"
"diskSize"
];
})
];
# Amazon recommends setting this to the highest possible value for a good EBS # Amazon recommends setting this to the highest possible value for a good EBS
# experience, which prior to 4.15 was 255. # experience, which prior to 4.15 was 255.
# https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/nvme-ebs-volumes.html#timeout-nvme-ebs-volumes # https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/nvme-ebs-volumes.html#timeout-nvme-ebs-volumes
config.boot.kernelParams = config.boot.kernelParams =
let let timeout =
timeout = if versionAtLeast config.boot.kernelPackages.kernel.version "4.15"
if versionAtLeast config.boot.kernelPackages.kernel.version "4.15" then "4294967295" else "255"; then "4294967295"
in else "255";
[ "nvme_core.io_timeout=${timeout}" ]; in [ "nvme_core.io_timeout=${timeout}" ];
options.amazonImage = { options.amazonImage = {
name = mkOption { name = mkOption {
@ -60,30 +34,30 @@ in
} }
] ]
''; '';
default = [ ]; default = [];
description = '' description = ''
This option lists files to be copied to fixed locations in the This option lists files to be copied to fixed locations in the
generated image. Glob patterns work. 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 { format = mkOption {
type = types.enum [ type = types.enum [ "raw" "qcow2" "vpc" ];
"raw"
"qcow2"
"vpc"
];
default = "vpc"; default = "vpc";
description = "The image format to output"; description = "The image format to output";
}; };
}; };
config.virtualisation.diskSize = lib.mkDefault (3 * 1024); config.system.build.amazonImage = let
config.virtualisation.diskSizeAutoSupported = !config.ec2.zfs.enable; configFile = pkgs.writeText "configuration.nix"
''
config.system.build.amazonImage =
let
configFile = pkgs.writeText "configuration.nix" ''
{ modulesPath, ... }: { { modulesPath, ... }: {
imports = [ "''${modulesPath}/virtualisation/amazon-image.nix" ]; imports = [ "''${modulesPath}/virtualisation/amazon-image.nix" ];
${optionalString config.ec2.efi '' ${optionalString config.ec2.efi ''
@ -96,102 +70,91 @@ in
} }
''; '';
zfsBuilder = import ../../../lib/make-multi-disk-zfs-image.nix { zfsBuilder = import ../../../lib/make-multi-disk-zfs-image.nix {
inherit inherit lib config configFile pkgs;
lib inherit (cfg) contents format name;
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; rootSize = cfg.sizeMB;
rootPoolProperties = { rootPoolProperties = {
ashift = 12; ashift = 12;
autoexpand = "on"; 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
'';
}; };
extBuilder = import ../../../lib/make-disk-image.nix { datasets = config.ec2.zfs.datasets;
inherit
lib
config
configFile
pkgs
;
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"; mkdir -p $out/nix-support
partitionTableType = if config.ec2.efi then "efi" else "legacy+gpt"; 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 = '' extBuilder = import ../../../lib/make-disk-image.nix {
extension=''${diskImage##*.} inherit lib config configFile pkgs;
friendlyName=$out/${cfg.name}.$extension
mv "$diskImage" "$friendlyName"
diskImage=$friendlyName
mkdir -p $out/nix-support inherit (cfg) contents format name;
echo "file ${cfg.format} $diskImage" >> $out/nix-support/hydra-build-products
${pkgs.jq}/bin/jq -n \ fsType = "ext4";
--arg system_label ${lib.escapeShellArg config.system.nixos.label} \ partitionTableType = if config.ec2.efi then "efi" else "legacy+gpt";
--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"')" \ diskSize = cfg.sizeMB;
--arg boot_mode "${amiBootMode}" \
--arg file "$diskImage" \ postVM = ''
'{} extension=''${diskImage##*.}
| .label = $system_label friendlyName=$out/${cfg.name}.$extension
| .boot_mode = $boot_mode mv "$diskImage" "$friendlyName"
| .system = $system diskImage=$friendlyName
| .logical_bytes = $logical_bytes
| .file = $file mkdir -p $out/nix-support
| .disks.root.logical_bytes = $logical_bytes echo "file ${cfg.format} $diskImage" >> $out/nix-support/hydra-build-products
| .disks.root.file = $file
' > $out/nix-support/image-info.json ${pkgs.jq}/bin/jq -n \
''; --arg system_label ${lib.escapeShellArg config.system.nixos.label} \
}; --arg system ${lib.escapeShellArg pkgs.stdenv.hostPlatform.system} \
in --arg logical_bytes "$(${pkgs.qemu_kvm}/bin/qemu-img info --output json "$diskImage" | ${pkgs.jq}/bin/jq '."virtual-size"')" \
if config.ec2.zfs.enable then zfsBuilder else extBuilder; --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 ]; meta.maintainers = with lib.maintainers; [ arianvp ];
} }

View file

@ -1,37 +1,18 @@
# nix-build '<nixpkgs/nixos>' -A config.system.build.openstackImage --arg configuration "{ imports = [ ./nixos/maintainers/scripts/openstack/openstack-image.nix ]; }" # nix-build '<nixpkgs/nixos>' -A config.system.build.openstackImage --arg configuration "{ imports = [ ./nixos/maintainers/scripts/openstack/openstack-image.nix ]; }"
{ { config, lib, pkgs, ... }:
config,
lib,
pkgs,
...
}:
let let
inherit (lib) mkOption types; inherit (lib) mkOption types;
copyChannel = true; copyChannel = true;
cfg = config.openstackImage; cfg = config.openstackImage;
imageBootMode = if config.openstack.efi then "uefi" else "legacy-bios"; imageBootMode = if config.openstack.efi then "uefi" else "legacy-bios";
virtualisationOptions = import ../../../modules/virtualisation/virtualisation-options.nix;
in in
{ {
imports = [ imports = [
../../../modules/virtualisation/openstack-config.nix ../../../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); ] ++ (lib.optional copyChannel ../../../modules/installer/cd-dvd/channel.nix);
options.openstackImage = { options.openstackImage = {
name = mkOption { name = mkOption {
type = types.str; type = types.str;
@ -41,15 +22,18 @@ in
ramMB = mkOption { ramMB = mkOption {
type = types.int; type = types.int;
default = (3 * 1024); default = 1024;
description = "RAM allocation for build VM"; description = "RAM allocation for build VM";
}; };
sizeMB = mkOption {
type = types.int;
default = 8192;
description = "The size in MB of the image";
};
format = mkOption { format = mkOption {
type = types.enum [ type = types.enum [ "raw" "qcow2" ];
"raw"
"qcow2"
];
default = "qcow2"; default = "qcow2";
description = "The image format to output"; 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 { system.build.openstackImage = import ../../../lib/make-single-disk-zfs-image.nix {
inherit lib config; inherit lib config;
inherit (cfg) contents format name; inherit (cfg) contents format name;
pkgs = import ../../../.. { inherit (pkgs) system; }; # ensure we use the regular qemu-kvm package pkgs = import ../../../.. { inherit (pkgs) system; }; # ensure we use the regular qemu-kvm package
configFile = pkgs.writeText "configuration.nix" '' configFile = pkgs.writeText "configuration.nix"
{ modulesPath, ... }: { ''
imports = [ "''${modulesPath}/virtualisation/openstack-config.nix" ]; { modulesPath, ... }: {
openstack.zfs.enable = true; imports = [ "''${modulesPath}/virtualisation/openstack-config.nix" ];
} openstack.zfs.enable = true;
''; }
'';
includeChannel = copyChannel; includeChannel = copyChannel;
bootSize = 1000; bootSize = 1000;
memSize = cfg.ramMB; memSize = cfg.ramMB;
rootSize = config.virtualisation.diskSize; rootSize = cfg.sizeMB;
rootPoolProperties = { rootPoolProperties = {
ashift = 12; ashift = 12;
autoexpand = "on"; autoexpand = "on";

View file

@ -1,9 +1,4 @@
{ { config, lib, options, ... }:
config,
lib,
options,
...
}:
let let
keysDirectory = "/var/keys"; keysDirectory = "/var/keys";
@ -20,19 +15,6 @@ in
imports = [ imports = [
../virtualisation/qemu-vm.nix ../virtualisation/qemu-vm.nix
(lib.mkRenamedOptionModuleWith {
sinceRelease = 2411;
from = [
"virtualisation"
"darwin-builder"
"diskSize"
];
to = [
"virtualisation"
"diskSize"
];
})
# Avoid a dependency on stateVersion # Avoid a dependency on stateVersion
{ {
disabledModules = [ disabledModules = [
@ -41,16 +23,17 @@ in
]; ];
# swraid's default depends on stateVersion # swraid's default depends on stateVersion
config.boot.swraid.enable = false; config.boot.swraid.enable = false;
options.boot.isContainer = lib.mkOption { options.boot.isContainer = lib.mkOption { default = false; internal = true; };
default = false;
internal = true;
};
} }
]; ];
options.virtualisation.description = "The maximum disk space allocated to the runner in megabytes";
options.virtualisation.darwin-builder = with lib; { 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 { memorySize = mkOption {
default = 3 * 1024; default = 3 * 1024;
type = types.int; type = types.int;
@ -76,13 +59,13 @@ in
''; '';
}; };
workingDirectory = mkOption { workingDirectory = mkOption {
default = "."; default = ".";
type = types.str; type = types.str;
example = "/var/lib/darwin-builder"; example = "/var/lib/darwin-builder";
description = '' description = ''
The working directory to use to run the script. When running 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. as part of a flake will need to be set to a non read-only filesystem.
''; '';
}; };
hostPort = mkOption { hostPort = mkOption {
default = 31022; default = 31022;
@ -175,34 +158,26 @@ in
script = hostPkgs.writeShellScriptBin "create-builder" ( script = hostPkgs.writeShellScriptBin "create-builder" (
'' ''
set -euo pipefail set -euo pipefail
'' '' +
+ # When running as non-interactively as part of a DarwinConfiguration the working directory
# When running as non-interactively as part of a DarwinConfiguration the working directory # must be set to a writeable directory.
# must be set to a writeable directory. (if cfg.workingDirectory != "." then ''
( ${hostPkgs.coreutils}/bin/mkdir --parent "${cfg.workingDirectory}"
if cfg.workingDirectory != "." then cd "${cfg.workingDirectory}"
'' '' else "") + ''
${hostPkgs.coreutils}/bin/mkdir --parent "${cfg.workingDirectory}" KEYS="''${KEYS:-./keys}"
cd "${cfg.workingDirectory}" ${hostPkgs.coreutils}/bin/mkdir --parent "''${KEYS}"
'' PRIVATE_KEY="''${KEYS}/${user}_${keyType}"
else 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'
KEYS="''${KEYS:-./keys}" fi
${hostPkgs.coreutils}/bin/mkdir --parent "''${KEYS}" if ! ${hostPkgs.diffutils}/bin/cmp "''${PUBLIC_KEY}" ${publicKey}; then
PRIVATE_KEY="''${KEYS}/${user}_${keyType}" (set -x; sudo --reset-timestamp ${installCredentials} "''${KEYS}")
PUBLIC_KEY="''${PRIVATE_KEY}.pub" fi
if [ ! -e "''${PRIVATE_KEY}" ] || [ ! -e "''${PUBLIC_KEY}" ]; then KEYS="$(${hostPkgs.nix}/bin/nix-store --add "$KEYS")" ${lib.getExe config.system.build.vm}
${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 in
script.overrideAttrs (old: { script.overrideAttrs (old: {
@ -248,16 +223,12 @@ in
''; '';
virtualisation = { virtualisation = {
diskSize = lib.mkDefault (20 * 1024); diskSize = cfg.diskSize;
memorySize = cfg.memorySize; memorySize = cfg.memorySize;
forwardPorts = [ 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 # Disable graphics for the builder since users will likely want to run it

View file

@ -1,34 +1,22 @@
{ { config, lib, pkgs, ... }:
config,
lib,
pkgs,
...
}:
with lib; with lib;
let let
cfg = config.virtualisation.azureImage; cfg = config.virtualisation.azureImage;
virtualisationOptions = import ./virtualisation-options.nix;
in in
{ {
imports = [ imports = [ ./azure-common.nix ];
./azure-common.nix
virtualisationOptions.diskSize
(lib.mkRenamedOptionModuleWith {
sinceRelease = 2411;
from = [
"virtualisation"
"azureImage"
"diskSize"
];
to = [
"virtualisation"
"diskSize"
];
})
];
options.virtualisation.azureImage = { 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 { bootSize = mkOption {
type = types.int; type = types.int;
default = 256; default = 256;
@ -47,12 +35,7 @@ in
}; };
vmGeneration = mkOption { vmGeneration = mkOption {
type = type = with types; enum [ "v1" "v2" ];
with types;
enum [
"v1"
"v2"
];
default = "v1"; default = "v1";
description = '' description = ''
VM Generation to use. VM Generation to use.
@ -74,8 +57,7 @@ in
bootSize = "${toString cfg.bootSize}M"; bootSize = "${toString cfg.bootSize}M";
partitionTableType = if cfg.vmGeneration == "v2" then "efi" else "legacy"; partitionTableType = if cfg.vmGeneration == "v2" then "efi" else "legacy";
inherit (cfg) contents; inherit (cfg) diskSize contents;
inherit (config.virtualisation) diskSize;
inherit config lib pkgs; inherit config lib pkgs;
}; };
}; };

View file

@ -1,35 +1,23 @@
{ { config, lib, pkgs, ... }:
config,
lib,
pkgs,
...
}:
with lib; with lib;
let let
cfg = config.virtualisation.digitalOceanImage; cfg = config.virtualisation.digitalOceanImage;
virtualisationOptions = import ./virtualisation-options.nix;
in in
{ {
imports = [ imports = [ ./digital-ocean-config.nix ];
./digital-ocean-config.nix
virtualisationOptions.diskSize
(lib.mkRenamedOptionModuleWith {
sinceRelease = 2411;
from = [
"virtualisation"
"digitialOceanImage"
"diskSize"
];
to = [
"virtualisation"
"diskSize"
];
})
];
options = { 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 { virtualisation.digitalOceanImage.configFile = mkOption {
type = with types; nullOr path; type = with types; nullOr path;
default = null; default = null;
@ -43,10 +31,7 @@ in
}; };
virtualisation.digitalOceanImage.compressionMethod = mkOption { virtualisation.digitalOceanImage.compressionMethod = mkOption {
type = types.enum [ type = types.enum [ "gzip" "bzip2" ];
"gzip"
"bzip2"
];
default = "gzip"; default = "gzip";
example = "bzip2"; example = "bzip2";
description = '' description = ''
@ -59,35 +44,27 @@ in
#### implementation #### implementation
config = { config = {
system.build.digitalOceanImage = import ../../lib/make-disk-image.nix { system.build.digitalOceanImage = import ../../lib/make-disk-image.nix {
name = "digital-ocean-image"; name = "digital-ocean-image";
format = "qcow2"; format = "qcow2";
postVM = postVM = let
let compress = {
compress = "gzip" = "${pkgs.gzip}/bin/gzip";
{ "bzip2" = "${pkgs.bzip2}/bin/bzip2";
"gzip" = "${pkgs.gzip}/bin/gzip"; }.${cfg.compressionMethod};
"bzip2" = "${pkgs.bzip2}/bin/bzip2"; in ''
} ${compress} $diskImage
.${cfg.compressionMethod}; '';
in configFile = if cfg.configFile == null
'' then config.virtualisation.digitalOcean.defaultConfigFile
${compress} $diskImage else cfg.configFile;
''; inherit (cfg) diskSize;
configFile =
if cfg.configFile == null then
config.virtualisation.digitalOcean.defaultConfigFile
else
cfg.configFile;
inherit (config.virtualisation) diskSize;
inherit config lib pkgs; inherit config lib pkgs;
}; };
}; };
meta.maintainers = with maintainers; [ meta.maintainers = with maintainers; [ arianvp eamsden ];
arianvp
eamsden
];
} }

View file

@ -1,9 +1,4 @@
{ { config, lib, pkgs, ... }:
config,
lib,
pkgs,
...
}:
with lib; with lib;
let let
@ -16,28 +11,21 @@ let
]; ];
} }
''; '';
virtualisationOptions = import ./virtualisation-options.nix;
in in
{ {
imports = [ imports = [ ./google-compute-config.nix ];
./google-compute-config.nix
virtualisationOptions.diskSize
(lib.mkRenamedOptionModuleWith {
sinceRelease = 2411;
from = [
"virtualisation"
"googleComputeImage"
"diskSize"
];
to = [
"virtualisation"
"diskSize"
];
})
];
options = { 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 { virtualisation.googleComputeImage.configFile = mkOption {
type = with types; nullOr str; type = with types; nullOr str;
default = null; default = null;
@ -76,13 +64,7 @@ in
system.build.googleComputeImage = import ../../lib/make-disk-image.nix { system.build.googleComputeImage = import ../../lib/make-disk-image.nix {
name = "google-compute-image"; name = "google-compute-image";
postVM = '' postVM = ''
PATH=$PATH:${ PATH=$PATH:${with pkgs; lib.makeBinPath [ gnutar gzip ]}
with pkgs;
lib.makeBinPath [
gnutar
gzip
]
}
pushd $out pushd $out
mv $diskImage disk.raw mv $diskImage disk.raw
tar -Sc disk.raw | gzip -${toString cfg.compressionLevel} > \ tar -Sc disk.raw | gzip -${toString cfg.compressionLevel} > \
@ -93,7 +75,7 @@ in
format = "raw"; format = "raw";
configFile = if cfg.configFile == null then defaultConfigFile else cfg.configFile; configFile = if cfg.configFile == null then defaultConfigFile else cfg.configFile;
partitionTableType = if cfg.efi then "efi" else "legacy"; partitionTableType = if cfg.efi then "efi" else "legacy";
inherit (config.virtualisation) diskSize; inherit (cfg) diskSize;
inherit config lib pkgs; inherit config lib pkgs;
}; };

View file

@ -1,37 +1,21 @@
{ { config, pkgs, lib, ... }:
config,
pkgs,
lib,
...
}:
with lib; with lib;
let let
cfg = config.hyperv; 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 = { options = {
hyperv = { 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 { vmDerivationName = mkOption {
type = types.str; type = types.str;
default = "nixos-hyperv-${config.system.nixos.label}-${pkgs.stdenv.hostPlatform.system}"; default = "nixos-hyperv-${config.system.nixos.label}-${pkgs.stdenv.hostPlatform.system}";
@ -50,8 +34,6 @@ in
}; };
config = { config = {
virtualisation.diskSize = lib.mkDefault (4 * 1024);
system.build.hypervImage = import ../../lib/make-disk-image.nix { system.build.hypervImage = import ../../lib/make-disk-image.nix {
name = cfg.vmDerivationName; name = cfg.vmDerivationName;
postVM = '' postVM = ''
@ -59,7 +41,7 @@ in
rm $diskImage rm $diskImage
''; '';
format = "raw"; format = "raw";
inherit (config.virtualisation) diskSize; diskSize = cfg.baseImageSize;
partitionTableType = "efi"; partitionTableType = "efi";
inherit config lib pkgs; inherit config lib pkgs;
}; };

View file

@ -1,9 +1,4 @@
{ { config, lib, pkgs, ... }:
config,
lib,
pkgs,
...
}:
with lib; with lib;
let let
@ -15,27 +10,19 @@ let
]; ];
} }
''; '';
virtualisationOptions = import ./virtualisation-options.nix;
in in
{ {
imports = [ imports = [ ./linode-config.nix ];
./linode-config.nix
virtualisationOptions.diskSize
(lib.mkRenamedOptionModuleWith {
sinceRelease = 2411;
from = [
"virtualisation"
"linodeImage"
"diskSize"
];
to = [
"virtualisation"
"diskSize"
];
})
];
options = { 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 { virtualisation.linodeImage.configFile = mkOption {
type = with types; nullOr str; type = with types; nullOr str;
@ -70,7 +57,7 @@ in
format = "raw"; format = "raw";
partitionTableType = "none"; partitionTableType = "none";
configFile = if cfg.configFile == null then defaultConfigFile else cfg.configFile; configFile = if cfg.configFile == null then defaultConfigFile else cfg.configFile;
inherit (config.virtualisation) diskSize; inherit (cfg) diskSize;
inherit config lib pkgs; inherit config lib pkgs;
}; };
}; };

View file

@ -1,9 +1,4 @@
{ { config, lib, pkgs, ... }:
config,
lib,
pkgs,
...
}:
let let
cfg = config.oci; cfg = config.oci;
@ -12,12 +7,9 @@ in
imports = [ ./oci-common.nix ]; imports = [ ./oci-common.nix ];
config = { config = {
virtualisation.diskSize = lib.mkDefault (8 * 1024);
virtualisation.diskSizeAutoSupported = false;
system.build.OCIImage = import ../../lib/make-disk-image.nix { system.build.OCIImage = import ../../lib/make-disk-image.nix {
inherit config lib pkgs; inherit config lib pkgs;
inherit (config.virtualisation) diskSize; inherit (cfg) diskSize;
name = "oci-image"; name = "oci-image";
configFile = ./oci-config-user.nix; configFile = ./oci-config-user.nix;
format = "qcow2"; format = "qcow2";
@ -33,10 +25,7 @@ in
after = [ "network-online.target" ]; after = [ "network-online.target" ];
wants = [ "network-online.target" ]; wants = [ "network-online.target" ];
path = [ path = [ pkgs.coreutils pkgs.curl ];
pkgs.coreutils
pkgs.curl
];
script = '' script = ''
mkdir -m 0700 -p /root/.ssh mkdir -m 0700 -p /root/.ssh
if [ -f /root/.ssh/authorized_keys ]; then if [ -f /root/.ssh/authorized_keys ]; then

View file

@ -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 = { options = {
oci = { oci = {
efi = lib.mkOption { efi = lib.mkOption {
@ -31,6 +9,12 @@ in
Whether the OCI instance is using EFI. 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";
};
}; };
}; };
} }

View file

@ -1,31 +1,8 @@
{ { config, pkgs, lib, ... }:
config,
pkgs,
lib,
...
}:
with 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 = { options.proxmox = {
qemuConf = { qemuConf = {
# essential configs # essential configs
@ -77,10 +54,7 @@ in
''; '';
}; };
bios = mkOption { bios = mkOption {
type = types.enum [ type = types.enum [ "seabios" "ovmf" ];
"seabios"
"ovmf"
];
default = "seabios"; default = "seabios";
description = '' description = ''
Select BIOS implementation (seabios = Legacy BIOS, ovmf = UEFI). Select BIOS implementation (seabios = Legacy BIOS, ovmf = UEFI).
@ -113,6 +87,16 @@ in
either "efi" or "hybrid". 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 { net0 = mkOption {
type = types.commas; type = types.commas;
default = "virtio=00:00:00:00:00:00,bridge=vmbr0,firewall=1"; default = "virtio=00:00:00:00:00:00,bridge=vmbr0,firewall=1";
@ -140,13 +124,8 @@ in
}; };
}; };
qemuExtraConf = mkOption { qemuExtraConf = mkOption {
type = type = with types; attrsOf (oneOf [ str int ]);
with types; default = {};
attrsOf (oneOf [
str
int
]);
default = { };
example = literalExpression '' example = literalExpression ''
{ {
cpu = "host"; cpu = "host";
@ -158,12 +137,7 @@ in
''; '';
}; };
partitionTableType = mkOption { partitionTableType = mkOption {
type = types.enum [ type = types.enum [ "efi" "hybrid" "legacy" "legacy+gpt" ];
"efi"
"hybrid"
"legacy"
"legacy+gpt"
];
description = '' description = ''
Partition table type to use. See make-disk-image.nix partitionTableType for details. 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'. Defaults to 'legacy' for 'proxmox.qemuConf.bios="seabios"' (default), other bios values defaults to 'efi'.
@ -211,163 +185,142 @@ in
}; };
}; };
config = config = let
let cfg = config.proxmox;
cfg = config.proxmox; cfgLine = name: value: ''
cfgLine = name: value: '' ${name}: ${builtins.toString value}
${name}: ${builtins.toString value} '';
''; virtio0Storage = builtins.head (builtins.split ":" cfg.qemuConf.virtio0);
virtio0Storage = builtins.head (builtins.split ":" cfg.qemuConf.virtio0); cfgFile = fileName: properties: pkgs.writeTextDir fileName ''
cfgFile = # generated by NixOS
fileName: properties: ${lib.concatStrings (lib.mapAttrsToList cfgLine properties)}
pkgs.writeTextDir fileName '' #qmdump#map:virtio0:drive-virtio0:${virtio0Storage}:raw:
# generated by NixOS '';
${lib.concatStrings (lib.mapAttrsToList cfgLine properties)} inherit (cfg) partitionTableType;
#qmdump#map:virtio0:drive-virtio0:${virtio0Storage}:raw: 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; inherit (cfg) partitionTableType;
supportEfi = partitionTableType == "efi" || partitionTableType == "hybrid"; postVM = let
supportBios = # Build qemu with PVE's patch that adds support for the VMA format
partitionTableType == "legacy" vma = (pkgs.qemu_kvm.override {
|| partitionTableType == "hybrid" alsaSupport = false;
|| partitionTableType == "legacy+gpt"; pulseSupport = false;
hasBootPartition = partitionTableType == "efi" || partitionTableType == "hybrid"; sdlSupport = false;
hasNoFsPartition = partitionTableType == "hybrid" || partitionTableType == "legacy+gpt"; jackSupport = false;
in gtkSupport = false;
{ vncSupport = false;
assertions = [ smartcardSupport = false;
{ spiceSupport = false;
assertion = config.boot.loader.systemd-boot.enable -> config.proxmox.qemuConf.bios == "ovmf"; ncursesSupport = false;
message = "systemd-boot requires 'ovmf' bios"; libiscsiSupport = false;
} tpmSupport = false;
{ numaSupport = false;
assertion = partitionTableType == "efi" -> config.proxmox.qemuConf.bios == "ovmf"; seccompSupport = false;
message = "'efi' disk partitioning requires 'ovmf' bios"; guestAgentSupport = false;
} }).overrideAttrs ( super: rec {
{ # Check https://github.com/proxmox/pve-qemu/tree/master for the version
assertion = partitionTableType == "legacy" -> config.proxmox.qemuConf.bios == "seabios"; # of qemu and patch to use
message = "'legacy' disk partitioning requires 'seabios' bios"; version = "9.0.0";
} src = pkgs.fetchurl {
{ url = "https://download.qemu.org/qemu-${version}.tar.xz";
assertion = partitionTableType == "legacy+gpt" -> config.proxmox.qemuConf.bios == "seabios"; hash = "sha256-MnCKxmww2MiSYz6paMdxwcdtWX1w3erSGg0izPOG2mk=";
message = "'legacy+gpt' disk partitioning requires 'seabios' bios"; };
} patches = [
]; # Proxmox' VMA tool is published as a particular patch upon QEMU
system.build.VMA = import ../../lib/make-disk-image.nix { "${pkgs.fetchFromGitHub {
name = "proxmox-${cfg.filenameSuffix}"; owner = "proxmox";
inherit (cfg) partitionTableType; repo = "pve-qemu";
postVM = rev = "14afbdd55f04d250bd679ca1ad55d3f47cd9d4c8";
let hash = "sha256-lSJQA5SHIHfxJvMLIID2drv2H43crTPMNIlIT37w9Nc=";
# Build qemu with PVE's patch that adds support for the VMA format }}/debian/patches/pve/0027-PVE-Backup-add-vma-backup-format-code.patch"
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 ]; buildInputs = super.buildInputs ++ [ pkgs.libuuid ];
nativeBuildInputs = super.nativeBuildInputs ++ [ pkgs.perl ]; nativeBuildInputs = super.nativeBuildInputs ++ [ pkgs.perl ];
}); });
in in
'' ''
${vma}/bin/vma create "vzdump-qemu-${cfg.filenameSuffix}.vma" \ ${vma}/bin/vma create "vzdump-qemu-${cfg.filenameSuffix}.vma" \
-c ${ -c ${cfgFile "qemu-server.conf" (cfg.qemuConf // cfg.qemuExtraConf)}/qemu-server.conf drive-virtio0=$diskImage
cfgFile "qemu-server.conf" (cfg.qemuConf // cfg.qemuExtraConf) rm $diskImage
}/qemu-server.conf drive-virtio0=$diskImage ${pkgs.zstd}/bin/zstd "vzdump-qemu-${cfg.filenameSuffix}.vma"
rm $diskImage mv "vzdump-qemu-${cfg.filenameSuffix}.vma.zst" $out/
${pkgs.zstd}/bin/zstd "vzdump-qemu-${cfg.filenameSuffix}.vma"
mv "vzdump-qemu-${cfg.filenameSuffix}.vma.zst" $out/
mkdir -p $out/nix-support mkdir -p $out/nix-support
echo "file vma $out/vzdump-qemu-${cfg.filenameSuffix}.vma.zst" > $out/nix-support/hydra-build-products echo "file vma $out/vzdump-qemu-${cfg.filenameSuffix}.vma.zst" > $out/nix-support/hydra-build-products
''; '';
inherit (cfg.qemuConf) additionalSpace bootSize; inherit (cfg.qemuConf) additionalSpace diskSize bootSize;
inherit (config.virtualisation) diskSize; format = "raw";
format = "raw"; inherit config lib pkgs;
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";
}; };
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";
};
} }

File diff suppressed because it is too large Load diff

View file

@ -1,37 +1,23 @@
{ { config, lib, pkgs, ... }:
config,
lib,
pkgs,
...
}:
with lib; with lib;
let let
cfg = config.virtualbox; cfg = config.virtualbox;
virtualisationOptions = import ./virtualisation-options.nix;
in in {
{
imports = [
virtualisationOptions.diskSize
(lib.mkRenamedOptionModuleWith {
sinceRelease = 2411;
from = [
"virtualisation"
"virtualbox"
"baseImageSize"
];
to = [
"virtualisation"
"diskSize"
];
})
];
options = { options = {
virtualbox = { 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 { baseImageFreeSpace = mkOption {
type = with types; int; type = with types; int;
default = 30 * 1024; default = 30 * 1024;
@ -68,14 +54,7 @@ in
''; '';
}; };
params = mkOption { params = mkOption {
type = type = with types; attrsOf (oneOf [ str int bool (listOf str) ]);
with types;
attrsOf (oneOf [
str
int
bool
(listOf str)
]);
example = { example = {
audio = "alsa"; audio = "alsa";
rtcuseutc = "on"; rtcuseutc = "on";
@ -88,21 +67,11 @@ in
''; '';
}; };
exportParams = mkOption { exportParams = mkOption {
type = type = with types; listOf (oneOf [ str int bool (listOf str) ]);
with types;
listOf (oneOf [
str
int
bool
(listOf str)
]);
example = [ example = [
"--vsys" "--vsys" "0" "--vendor" "ACME Inc."
"0"
"--vendor"
"ACME Inc."
]; ];
default = [ ]; default = [];
description = '' description = ''
Parameters passed to the Virtualbox export command. Parameters passed to the Virtualbox export command.
@ -120,25 +89,23 @@ in
mountPoint = "/home/demo/storage"; mountPoint = "/home/demo/storage";
size = 100 * 1024; size = 100 * 1024;
}; };
type = types.nullOr ( type = types.nullOr (types.submodule {
types.submodule { options = {
options = { size = mkOption {
size = mkOption { type = types.int;
type = types.int; description = "Size in MiB";
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.";
};
}; };
} 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 { postExportCommands = mkOption {
type = types.lines; type = types.lines;
@ -158,14 +125,7 @@ in
''; '';
}; };
storageController = mkOption { storageController = mkOption {
type = type = with types; attrsOf (oneOf [ str int bool (listOf str) ]);
with types;
attrsOf (oneOf [
str
int
bool
(listOf str)
]);
example = { example = {
name = "SCSI"; name = "SCSI";
add = "scsi"; add = "scsi";
@ -192,8 +152,6 @@ in
config = { config = {
virtualisation.diskSize = lib.mkDefault (50 * 1024);
virtualbox.params = mkMerge [ virtualbox.params = mkMerge [
(mapAttrs (name: mkDefault) { (mapAttrs (name: mkDefault) {
acpi = "on"; acpi = "on";
@ -217,83 +175,80 @@ in
inherit pkgs lib config; inherit pkgs lib config;
partitionTableType = "legacy"; partitionTableType = "legacy";
inherit (config.virtualisation) diskSize; diskSize = cfg.baseImageSize;
additionalSpace = "${toString cfg.baseImageFreeSpace}M"; additionalSpace = "${toString cfg.baseImageFreeSpace}M";
postVM = '' postVM =
export HOME=$PWD ''
export PATH=${pkgs.virtualbox}/bin:$PATH export HOME=$PWD
export PATH=${pkgs.virtualbox}/bin:$PATH
echo "converting image to VirtualBox format..." echo "converting image to VirtualBox format..."
VBoxManage convertfromraw $diskImage disk.vdi VBoxManage convertfromraw $diskImage disk.vdi
${optionalString (cfg.extraDisk != null) '' ${optionalString (cfg.extraDisk != null) ''
echo "creating extra disk: data-disk.raw" echo "creating extra disk: data-disk.raw"
dataDiskImage=data-disk.raw dataDiskImage=data-disk.raw
truncate -s ${toString cfg.extraDisk.size}M $dataDiskImage truncate -s ${toString cfg.extraDisk.size}M $dataDiskImage
parted --script $dataDiskImage -- \ parted --script $dataDiskImage -- \
mklabel msdos \ mklabel msdos \
mkpart primary ext4 1MiB -1 mkpart primary ext4 1MiB -1
eval $(partx $dataDiskImage -o START,SECTORS --nr 1 --pairs) eval $(partx $dataDiskImage -o START,SECTORS --nr 1 --pairs)
mkfs.ext4 -F -L ${cfg.extraDisk.label} $dataDiskImage -E offset=$(sectorsToBytes $START) $(sectorsToKilobytes $SECTORS)K mkfs.ext4 -F -L ${cfg.extraDisk.label} $dataDiskImage -E offset=$(sectorsToBytes $START) $(sectorsToKilobytes $SECTORS)K
echo "creating extra disk: data-disk.vdi" echo "creating extra disk: data-disk.vdi"
VBoxManage convertfromraw $dataDiskImage data-disk.vdi VBoxManage convertfromraw $dataDiskImage data-disk.vdi
''} ''}
echo "creating VirtualBox VM..." echo "creating VirtualBox VM..."
vmName="${cfg.vmName}"; vmName="${cfg.vmName}";
VBoxManage createvm --name "$vmName" --register \ VBoxManage createvm --name "$vmName" --register \
--ostype ${if pkgs.stdenv.hostPlatform.system == "x86_64-linux" then "Linux26_64" else "Linux26"} --ostype ${if pkgs.stdenv.hostPlatform.system == "x86_64-linux" then "Linux26_64" else "Linux26"}
VBoxManage modifyvm "$vmName" \ VBoxManage modifyvm "$vmName" \
--memory ${toString cfg.memorySize} \ --memory ${toString cfg.memorySize} \
${lib.cli.toGNUCommandLineShell { } cfg.params} ${lib.cli.toGNUCommandLineShell { } cfg.params}
VBoxManage storagectl "$vmName" ${lib.cli.toGNUCommandLineShell { } cfg.storageController} VBoxManage storagectl "$vmName" ${lib.cli.toGNUCommandLineShell { } cfg.storageController}
VBoxManage storageattach "$vmName" --storagectl ${cfg.storageController.name} --port 0 --device 0 --type hdd \ VBoxManage storageattach "$vmName" --storagectl ${cfg.storageController.name} --port 0 --device 0 --type hdd \
--medium disk.vdi --medium disk.vdi
${optionalString (cfg.extraDisk != null) '' ${optionalString (cfg.extraDisk != null) ''
VBoxManage storageattach "$vmName" --storagectl ${cfg.storageController.name} --port 1 --device 0 --type hdd \ VBoxManage storageattach "$vmName" --storagectl ${cfg.storageController.name} --port 1 --device 0 --type hdd \
--medium data-disk.vdi --medium data-disk.vdi
''} ''}
echo "exporting VirtualBox VM..." echo "exporting VirtualBox VM..."
mkdir -p $out mkdir -p $out
fn="$out/${cfg.vmFileName}" fn="$out/${cfg.vmFileName}"
VBoxManage export "$vmName" --output "$fn" --options manifest ${escapeShellArgs cfg.exportParams} VBoxManage export "$vmName" --output "$fn" --options manifest ${escapeShellArgs cfg.exportParams}
${cfg.postExportCommands} ${cfg.postExportCommands}
rm -v $diskImage rm -v $diskImage
mkdir -p $out/nix-support mkdir -p $out/nix-support
echo "file ova $fn" >> $out/nix-support/hydra-build-products echo "file ova $fn" >> $out/nix-support/hydra-build-products
''; '';
}; };
fileSystems = fileSystems = {
{ "/" = {
"/" = { device = "/dev/disk/by-label/nixos";
device = "/dev/disk/by-label/nixos"; autoResize = true;
autoResize = true; fsType = "ext4";
fsType = "ext4"; };
}; } // (lib.optionalAttrs (cfg.extraDisk != null) {
} ${cfg.extraDisk.mountPoint} = {
// (lib.optionalAttrs (cfg.extraDisk != null) { device = "/dev/disk/by-label/" + cfg.extraDisk.label;
${cfg.extraDisk.mountPoint} = { autoResize = true;
device = "/dev/disk/by-label/" + cfg.extraDisk.label; fsType = "ext4";
autoResize = true; };
fsType = "ext4"; });
};
});
boot.growPartition = true; boot.growPartition = true;
boot.loader.grub.device = "/dev/sda"; boot.loader.grub.device = "/dev/sda";
swapDevices = [ swapDevices = [{
{ device = "/var/swap";
device = "/var/swap"; size = 2048;
size = 2048; }];
}
];
virtualisation.virtualbox.guest.enable = true; virtualisation.virtualbox.guest.enable = true;

View file

@ -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.";
}
];
};
};
}

View file

@ -312,7 +312,7 @@ in rec {
[ configuration [ configuration
versionModule versionModule
./maintainers/scripts/ec2/amazon-image.nix ./maintainers/scripts/ec2/amazon-image.nix
({ ... }: { amazonImage.virtualisation.diskSize = "auto"; }) ({ ... }: { amazonImage.sizeMB = "auto"; })
]; ];
}).config.system.build.amazonImage) }).config.system.build.amazonImage)