xen: nuke, move to by-name. (#345192)
This commit is contained in:
+3
-1
@@ -385,9 +385,11 @@
|
||||
- changed-files:
|
||||
- any-glob-to-any-file:
|
||||
- nixos/modules/virtualisation/xen*
|
||||
- pkgs/applications/virtualization/xen/**
|
||||
- pkgs/by-name/xe/xen/*
|
||||
- pkgs/by-name/qe/qemu_xen/*
|
||||
- pkgs/by-name/xe/xen-guest-agent/*
|
||||
- pkgs/by-name/xt/xtf/*
|
||||
- pkgs/build-support/xen/*
|
||||
- pkgs/development/ocaml-modules/xen*/*
|
||||
- pkgs/development/ocaml-modules/vchan/*
|
||||
|
||||
|
||||
@@ -54,12 +54,11 @@
|
||||
was added through the `boot.initrd.systemd.dmVerity` option.
|
||||
|
||||
- The [Xen Project Hypervisor](https://xenproject.org) is once again available as a virtualisation option under [`virtualisation.xen`](#opt-virtualisation.xen.enable).
|
||||
- This release includes Xen [4.17.5](https://wiki.xenproject.org/wiki/Xen_Project_4.17_Release_Notes), [4.18.3](https://wiki.xenproject.org/wiki/Xen_Project_4.18_Release_Notes) and [4.19.0](https://wiki.xenproject.org/wiki/Xen_Project_4.19_Release_Notes), as well as support for booting the hypervisor on EFI systems.
|
||||
- This release includes Xen [4.19.0](https://wiki.xenproject.org/wiki/Xen_Project_4.19_Release_Notes) and support for booting the hypervisor on EFI systems.
|
||||
::: {.warning}
|
||||
Booting into the Xen Project Hypervisor through a legacy BIOS bootloader or with the legacy script-based Stage 1 initrd have been **deprecated**. Only EFI booting and the new systemd-based Stage 1 initrd are supported.
|
||||
:::
|
||||
- There are two flavours of Xen available by default: `xen`, which includes all built-in components, and `xen-slim`, which replaces the built-in components with their Nixpkgs equivalents.
|
||||
- The `qemu-xen-traditional` component has been deprecated by the upstream Xen Project, and is no longer available in any of the Xen Project Hypervisor packages.
|
||||
- The `qemu-xen-traditional` component has been deprecated by the upstream Xen Project, and is no longer included in the Xen build.
|
||||
- The OCaml-based Xen Store can now be configured using [`virtualisation.xen.store.settings`](#opt-virtualisation.xen.store.settings).
|
||||
- The `virtualisation.xen.bridge` options have been deprecated in this release cycle. Users who need network bridges are encouraged to set up their own networking configurations.
|
||||
|
||||
|
||||
@@ -8,6 +8,35 @@
|
||||
}:
|
||||
|
||||
let
|
||||
inherit (builtins) readFile;
|
||||
inherit (lib.modules) mkRemovedOptionModule mkRenamedOptionModule mkIf;
|
||||
inherit (lib.options)
|
||||
mkOption
|
||||
mkEnableOption
|
||||
literalExpression
|
||||
mkPackageOption
|
||||
;
|
||||
inherit (lib.types)
|
||||
listOf
|
||||
str
|
||||
ints
|
||||
lines
|
||||
enum
|
||||
path
|
||||
submodule
|
||||
addCheck
|
||||
float
|
||||
bool
|
||||
int
|
||||
nullOr
|
||||
;
|
||||
inherit (lib.lists) optional optionals;
|
||||
inherit (lib.strings) hasSuffix optionalString;
|
||||
inherit (lib.meta) getExe;
|
||||
inherit (lib.attrsets) optionalAttrs;
|
||||
inherit (lib.trivial) boolToString;
|
||||
inherit (lib.teams.xen) members;
|
||||
|
||||
cfg = config.virtualisation.xen;
|
||||
|
||||
xenBootBuilder = pkgs.writeShellApplication {
|
||||
@@ -22,7 +51,7 @@ let
|
||||
gnused
|
||||
jq
|
||||
])
|
||||
++ lib.lists.optionals (cfg.efi.bootBuilderVerbosity == "info") (
|
||||
++ optionals (cfg.efi.bootBuilderVerbosity == "info") (
|
||||
with pkgs;
|
||||
[
|
||||
bat
|
||||
@@ -36,12 +65,12 @@ let
|
||||
# We disable SC2016 because we don't want to expand the regexes in the sed commands.
|
||||
excludeShellChecks = [ "SC2016" ];
|
||||
|
||||
text = builtins.readFile ./xen-boot-builder.sh;
|
||||
text = readFile ./xen-boot-builder.sh;
|
||||
};
|
||||
in
|
||||
|
||||
{
|
||||
imports = with lib.modules; [
|
||||
imports = [
|
||||
(mkRemovedOptionModule
|
||||
[
|
||||
"virtualisation"
|
||||
@@ -123,59 +152,33 @@ in
|
||||
|
||||
options.virtualisation.xen = {
|
||||
|
||||
enable = lib.options.mkEnableOption "the Xen Project Hypervisor, a virtualisation technology defined as a *type-1 hypervisor*, which allows multiple virtual machines, known as *domains*, to run concurrently on the physical machine. NixOS runs as the privileged *Domain 0*. This option requires a reboot into a Xen kernel to take effect";
|
||||
enable = mkEnableOption "the Xen Project Hypervisor, a virtualisation technology defined as a *type-1 hypervisor*, which allows multiple virtual machines, known as *domains*, to run concurrently on the physical machine. NixOS runs as the privileged *Domain 0*. This option requires a reboot into a Xen kernel to take effect";
|
||||
|
||||
debug = lib.options.mkEnableOption "Xen debug features for Domain 0. This option enables some hidden debugging tests and features, and should not be used in production";
|
||||
debug = mkEnableOption "Xen debug features for Domain 0. This option enables some hidden debugging tests and features, and should not be used in production";
|
||||
|
||||
trace = lib.options.mkOption {
|
||||
type = lib.types.bool;
|
||||
trace = mkOption {
|
||||
type = bool;
|
||||
default = cfg.debug;
|
||||
defaultText = lib.options.literalExpression "false";
|
||||
defaultText = literalExpression "false";
|
||||
example = true;
|
||||
description = "Whether to enable Xen debug tracing and logging for Domain 0.";
|
||||
};
|
||||
|
||||
package = lib.options.mkOption {
|
||||
type = lib.types.package;
|
||||
default = pkgs.xen;
|
||||
defaultText = lib.options.literalExpression "pkgs.xen";
|
||||
example = lib.options.literalExpression "pkgs.xen-slim";
|
||||
description = ''
|
||||
The package used for Xen Project Hypervisor.
|
||||
'';
|
||||
relatedPackages = [
|
||||
"xen"
|
||||
"xen-slim"
|
||||
];
|
||||
};
|
||||
package = mkPackageOption pkgs "Xen Hypervisor" { default = [ "xen" ]; };
|
||||
|
||||
qemu = {
|
||||
package = lib.options.mkOption {
|
||||
type = lib.types.package;
|
||||
default = pkgs.xen;
|
||||
defaultText = lib.options.literalExpression "pkgs.xen";
|
||||
example = lib.options.literalExpression "pkgs.qemu_xen";
|
||||
description = ''
|
||||
The package with QEMU binaries that runs in Domain 0
|
||||
and virtualises the unprivileged domains.
|
||||
'';
|
||||
relatedPackages = [
|
||||
"xen"
|
||||
{
|
||||
name = "qemu_xen";
|
||||
comment = "For use with `pkgs.xen-slim`.";
|
||||
}
|
||||
];
|
||||
package = mkPackageOption pkgs "QEMU (with Xen Hypervisor support)" {
|
||||
default = [ "qemu_xen" ];
|
||||
};
|
||||
pidFile = lib.options.mkOption {
|
||||
type = lib.types.path;
|
||||
pidFile = mkOption {
|
||||
type = path;
|
||||
default = "/run/xen/qemu-dom0.pid";
|
||||
example = "/var/run/xen/qemu-dom0.pid";
|
||||
description = "Path to the QEMU PID file.";
|
||||
};
|
||||
};
|
||||
|
||||
bootParams = lib.options.mkOption {
|
||||
bootParams = mkOption {
|
||||
default = [ ];
|
||||
example = ''
|
||||
[
|
||||
@@ -184,7 +187,7 @@ in
|
||||
"vga=ask"
|
||||
]
|
||||
'';
|
||||
type = lib.types.listOf lib.types.str;
|
||||
type = listOf str;
|
||||
description = ''
|
||||
Xen Command Line parameters passed to Domain 0 at boot time.
|
||||
Note: these are different from `boot.kernelParams`. See
|
||||
@@ -193,8 +196,8 @@ in
|
||||
};
|
||||
|
||||
efi = {
|
||||
bootBuilderVerbosity = lib.options.mkOption {
|
||||
type = lib.types.enum [
|
||||
bootBuilderVerbosity = mkOption {
|
||||
type = enum [
|
||||
"default"
|
||||
"info"
|
||||
"debug"
|
||||
@@ -218,11 +221,11 @@ in
|
||||
'';
|
||||
};
|
||||
|
||||
path = lib.options.mkOption {
|
||||
type = lib.types.path;
|
||||
path = mkOption {
|
||||
type = path;
|
||||
default = "${cfg.package.boot}/${cfg.package.efi}";
|
||||
defaultText = lib.options.literalExpression "\${config.virtualisation.xen.package.boot}/\${config.virtualisation.xen.package.efi}";
|
||||
example = lib.options.literalExpression "\${config.virtualisation.xen.package}/boot/efi/efi/nixos/xen-\${config.virtualisation.xen.package.version}.efi";
|
||||
defaultText = literalExpression "\${config.virtualisation.xen.package.boot}/\${config.virtualisation.xen.package.efi}";
|
||||
example = literalExpression "\${config.virtualisation.xen.package}/boot/efi/efi/nixos/xen-\${config.virtualisation.xen.package.version}.efi";
|
||||
description = ''
|
||||
Path to xen.efi. `pkgs.xen` is patched to install the xen.efi file
|
||||
on `$boot/boot/xen.efi`, but an unpatched Xen build may install it
|
||||
@@ -234,10 +237,10 @@ in
|
||||
};
|
||||
|
||||
dom0Resources = {
|
||||
maxVCPUs = lib.options.mkOption {
|
||||
maxVCPUs = mkOption {
|
||||
default = 0;
|
||||
example = 4;
|
||||
type = lib.types.ints.unsigned;
|
||||
type = ints.unsigned;
|
||||
description = ''
|
||||
Amount of virtual CPU cores allocated to Domain 0 on boot.
|
||||
If set to 0, all cores are assigned to Domain 0, and
|
||||
@@ -245,10 +248,10 @@ in
|
||||
'';
|
||||
};
|
||||
|
||||
memory = lib.options.mkOption {
|
||||
memory = mkOption {
|
||||
default = 0;
|
||||
example = 512;
|
||||
type = lib.types.ints.unsigned;
|
||||
type = ints.unsigned;
|
||||
description = ''
|
||||
Amount of memory (in MiB) allocated to Domain 0 on boot.
|
||||
If set to 0, all memory is assigned to Domain 0, and
|
||||
@@ -256,11 +259,11 @@ in
|
||||
'';
|
||||
};
|
||||
|
||||
maxMemory = lib.options.mkOption {
|
||||
maxMemory = mkOption {
|
||||
default = cfg.dom0Resources.memory;
|
||||
defaultText = lib.options.literalExpression "config.virtualisation.xen.dom0Resources.memory";
|
||||
defaultText = literalExpression "config.virtualisation.xen.dom0Resources.memory";
|
||||
example = 1024;
|
||||
type = lib.types.ints.unsigned;
|
||||
type = ints.unsigned;
|
||||
description = ''
|
||||
Maximum amount of memory (in MiB) that Domain 0 can
|
||||
dynamically allocate to itself. Does nothing if set
|
||||
@@ -271,8 +274,8 @@ in
|
||||
};
|
||||
|
||||
domains = {
|
||||
extraConfig = lib.options.mkOption {
|
||||
type = lib.types.lines;
|
||||
extraConfig = mkOption {
|
||||
type = lines;
|
||||
default = "";
|
||||
example = ''
|
||||
XENDOMAINS_SAVE=/persist/xen/save
|
||||
@@ -288,28 +291,28 @@ in
|
||||
};
|
||||
|
||||
store = {
|
||||
path = lib.options.mkOption {
|
||||
type = lib.types.path;
|
||||
path = mkOption {
|
||||
type = path;
|
||||
default = "${cfg.package}/bin/oxenstored";
|
||||
defaultText = lib.options.literalExpression "\${config.virtualisation.xen.package}/bin/oxenstored";
|
||||
example = lib.options.literalExpression "\${config.virtualisation.xen.package}/bin/xenstored";
|
||||
defaultText = literalExpression "\${config.virtualisation.xen.package}/bin/oxenstored";
|
||||
example = literalExpression "\${config.virtualisation.xen.package}/bin/xenstored";
|
||||
description = ''
|
||||
Path to the Xen Store Daemon. This option is useful to
|
||||
switch between the legacy C-based Xen Store Daemon, and
|
||||
the newer OCaml-based Xen Store Daemon, `oxenstored`.
|
||||
'';
|
||||
};
|
||||
type = lib.options.mkOption {
|
||||
type = lib.types.enum [
|
||||
type = mkOption {
|
||||
type = enum [
|
||||
"c"
|
||||
"ocaml"
|
||||
];
|
||||
default = if (lib.strings.hasSuffix "oxenstored" cfg.store.path) then "ocaml" else "c";
|
||||
default = if (hasSuffix "oxenstored" cfg.store.path) then "ocaml" else "c";
|
||||
internal = true;
|
||||
readOnly = true;
|
||||
description = "Helper internal option that determines the type of the Xen Store Daemon based on cfg.store.path.";
|
||||
};
|
||||
settings = lib.options.mkOption {
|
||||
settings = mkOption {
|
||||
default = { };
|
||||
example = {
|
||||
enableMerge = false;
|
||||
@@ -324,34 +327,34 @@ in
|
||||
The OCaml-based Xen Store Daemon configuration. This
|
||||
option does nothing with the C-based `xenstored`.
|
||||
'';
|
||||
type = lib.types.submodule {
|
||||
type = submodule {
|
||||
options = {
|
||||
pidFile = lib.options.mkOption {
|
||||
pidFile = mkOption {
|
||||
default = "/run/xen/xenstored.pid";
|
||||
example = "/var/run/xen/xenstored.pid";
|
||||
type = lib.types.path;
|
||||
type = path;
|
||||
description = "Path to the Xen Store Daemon PID file.";
|
||||
};
|
||||
testEAGAIN = lib.options.mkOption {
|
||||
testEAGAIN = mkOption {
|
||||
default = cfg.debug;
|
||||
defaultText = lib.options.literalExpression "config.virtualisation.xen.debug";
|
||||
defaultText = literalExpression "config.virtualisation.xen.debug";
|
||||
example = true;
|
||||
type = lib.types.bool;
|
||||
type = bool;
|
||||
visible = false;
|
||||
description = "Randomly fail a transaction with EAGAIN. This option is used for debugging purposes only.";
|
||||
};
|
||||
enableMerge = lib.options.mkOption {
|
||||
enableMerge = mkOption {
|
||||
default = true;
|
||||
example = false;
|
||||
type = lib.types.bool;
|
||||
type = bool;
|
||||
description = "Whether to enable transaction merge support.";
|
||||
};
|
||||
conflict = {
|
||||
burstLimit = lib.options.mkOption {
|
||||
burstLimit = mkOption {
|
||||
default = 5.0;
|
||||
example = 15.0;
|
||||
type = lib.types.addCheck (
|
||||
lib.types.float
|
||||
type = addCheck (
|
||||
float
|
||||
// {
|
||||
name = "nonnegativeFloat";
|
||||
description = "nonnegative floating point number, meaning >=0";
|
||||
@@ -369,12 +372,12 @@ in
|
||||
domain's requests are ignored.
|
||||
'';
|
||||
};
|
||||
maxHistorySeconds = lib.options.mkOption {
|
||||
maxHistorySeconds = mkOption {
|
||||
default = 5.0e-2;
|
||||
example = 1.0;
|
||||
type = lib.types.addCheck (
|
||||
lib.types.float // { description = "nonnegative floating point number, meaning >=0"; }
|
||||
) (n: n >= 0);
|
||||
type = addCheck (float // { description = "nonnegative floating point number, meaning >=0"; }) (
|
||||
n: n >= 0
|
||||
);
|
||||
description = ''
|
||||
Limits applied to domains whose writes cause other domains' transaction
|
||||
commits to fail. Must include decimal point.
|
||||
@@ -384,10 +387,10 @@ in
|
||||
is the minimum pause-time during which a domain will be ignored.
|
||||
'';
|
||||
};
|
||||
rateLimitIsAggregate = lib.options.mkOption {
|
||||
rateLimitIsAggregate = mkOption {
|
||||
default = true;
|
||||
example = false;
|
||||
type = lib.types.bool;
|
||||
type = bool;
|
||||
description = ''
|
||||
If the conflict.rateLimitIsAggregate option is `true`, then after each
|
||||
tick one point of conflict-credit is given to just one domain: the
|
||||
@@ -408,16 +411,16 @@ in
|
||||
};
|
||||
};
|
||||
perms = {
|
||||
enable = lib.options.mkOption {
|
||||
enable = mkOption {
|
||||
default = true;
|
||||
example = false;
|
||||
type = lib.types.bool;
|
||||
type = bool;
|
||||
description = "Whether to enable the node permission system.";
|
||||
};
|
||||
enableWatch = lib.options.mkOption {
|
||||
enableWatch = mkOption {
|
||||
default = true;
|
||||
example = false;
|
||||
type = lib.types.bool;
|
||||
type = bool;
|
||||
description = ''
|
||||
Whether to enable the watch permission system.
|
||||
|
||||
@@ -432,144 +435,142 @@ in
|
||||
};
|
||||
};
|
||||
quota = {
|
||||
enable = lib.options.mkOption {
|
||||
enable = mkOption {
|
||||
default = true;
|
||||
example = false;
|
||||
type = lib.types.bool;
|
||||
type = bool;
|
||||
description = "Whether to enable the quota system.";
|
||||
};
|
||||
maxEntity = lib.options.mkOption {
|
||||
maxEntity = mkOption {
|
||||
default = 1000;
|
||||
example = 1024;
|
||||
type = lib.types.ints.positive;
|
||||
type = ints.positive;
|
||||
description = "Entity limit for transactions.";
|
||||
};
|
||||
maxSize = lib.options.mkOption {
|
||||
maxSize = mkOption {
|
||||
default = 2048;
|
||||
example = 4096;
|
||||
type = lib.types.ints.positive;
|
||||
type = ints.positive;
|
||||
description = "Size limit for transactions.";
|
||||
};
|
||||
maxWatch = lib.options.mkOption {
|
||||
maxWatch = mkOption {
|
||||
default = 100;
|
||||
example = 256;
|
||||
type = lib.types.ints.positive;
|
||||
type = ints.positive;
|
||||
description = "Maximum number of watches by the Xenstore Watchdog.";
|
||||
};
|
||||
transaction = lib.options.mkOption {
|
||||
transaction = mkOption {
|
||||
default = 10;
|
||||
example = 50;
|
||||
type = lib.types.ints.positive;
|
||||
type = ints.positive;
|
||||
description = "Maximum number of transactions.";
|
||||
};
|
||||
maxRequests = lib.options.mkOption {
|
||||
maxRequests = mkOption {
|
||||
default = 1024;
|
||||
example = 1024;
|
||||
type = lib.types.ints.positive;
|
||||
type = ints.positive;
|
||||
description = "Maximum number of requests per transaction.";
|
||||
};
|
||||
maxPath = lib.options.mkOption {
|
||||
maxPath = mkOption {
|
||||
default = 1024;
|
||||
example = 1024;
|
||||
type = lib.types.ints.positive;
|
||||
type = ints.positive;
|
||||
description = "Path limit for the quota system.";
|
||||
};
|
||||
maxOutstanding = lib.options.mkOption {
|
||||
maxOutstanding = mkOption {
|
||||
default = 1024;
|
||||
example = 1024;
|
||||
type = lib.types.ints.positive;
|
||||
type = ints.positive;
|
||||
description = "Maximum outstanding requests, i.e. in-flight requests / domain.";
|
||||
};
|
||||
maxWatchEvents = lib.options.mkOption {
|
||||
maxWatchEvents = mkOption {
|
||||
default = 1024;
|
||||
example = 2048;
|
||||
type = lib.types.ints.positive;
|
||||
type = ints.positive;
|
||||
description = "Maximum number of outstanding watch events per watch.";
|
||||
};
|
||||
};
|
||||
persistent = lib.options.mkOption {
|
||||
persistent = mkOption {
|
||||
default = false;
|
||||
example = true;
|
||||
type = lib.types.bool;
|
||||
type = bool;
|
||||
description = "Whether to activate the filed base backend.";
|
||||
};
|
||||
xenstored = {
|
||||
log = {
|
||||
file = lib.options.mkOption {
|
||||
file = mkOption {
|
||||
default = "/var/log/xen/xenstored.log";
|
||||
example = "/dev/null";
|
||||
type = lib.types.path;
|
||||
type = path;
|
||||
description = "Path to the Xen Store log file.";
|
||||
};
|
||||
level = lib.options.mkOption {
|
||||
level = mkOption {
|
||||
default = if cfg.trace then "debug" else null;
|
||||
defaultText = lib.options.literalExpression "if (config.virtualisation.xen.trace == true) then \"debug\" else null";
|
||||
defaultText = literalExpression "if (config.virtualisation.xen.trace == true) then \"debug\" else null";
|
||||
example = "error";
|
||||
type = lib.types.nullOr (
|
||||
lib.types.enum [
|
||||
"debug"
|
||||
"info"
|
||||
"warn"
|
||||
"error"
|
||||
]
|
||||
);
|
||||
type = nullOr (enum [
|
||||
"debug"
|
||||
"info"
|
||||
"warn"
|
||||
"error"
|
||||
]);
|
||||
description = "Logging level for the Xen Store.";
|
||||
};
|
||||
# The hidden options below have no upstream documentation whatsoever.
|
||||
# The nb* options appear to alter the log rotation behaviour, and
|
||||
# the specialOps option appears to affect the Xenbus logging logic.
|
||||
nbFiles = lib.options.mkOption {
|
||||
nbFiles = mkOption {
|
||||
default = 10;
|
||||
example = 16;
|
||||
type = lib.types.int;
|
||||
type = int;
|
||||
visible = false;
|
||||
description = "Set `xenstored-log-nb-files`.";
|
||||
};
|
||||
};
|
||||
accessLog = {
|
||||
file = lib.options.mkOption {
|
||||
file = mkOption {
|
||||
default = "/var/log/xen/xenstored-access.log";
|
||||
example = "/var/log/security/xenstored-access.log";
|
||||
type = lib.types.path;
|
||||
type = path;
|
||||
description = "Path to the Xen Store access log file.";
|
||||
};
|
||||
nbLines = lib.options.mkOption {
|
||||
nbLines = mkOption {
|
||||
default = 13215;
|
||||
example = 16384;
|
||||
type = lib.types.int;
|
||||
type = int;
|
||||
visible = false;
|
||||
description = "Set `access-log-nb-lines`.";
|
||||
};
|
||||
nbChars = lib.options.mkOption {
|
||||
nbChars = mkOption {
|
||||
default = 180;
|
||||
example = 256;
|
||||
type = lib.types.int;
|
||||
type = int;
|
||||
visible = false;
|
||||
description = "Set `acesss-log-nb-chars`.";
|
||||
};
|
||||
specialOps = lib.options.mkOption {
|
||||
specialOps = mkOption {
|
||||
default = false;
|
||||
example = true;
|
||||
type = lib.types.bool;
|
||||
type = bool;
|
||||
visible = false;
|
||||
description = "Set `access-log-special-ops`.";
|
||||
};
|
||||
};
|
||||
xenfs = {
|
||||
kva = lib.options.mkOption {
|
||||
kva = mkOption {
|
||||
default = "/proc/xen/xsd_kva";
|
||||
example = cfg.store.settings.xenstored.xenfs.kva;
|
||||
type = lib.types.path;
|
||||
type = path;
|
||||
visible = false;
|
||||
description = ''
|
||||
Path to the Xen Store Daemon KVA location inside the XenFS pseudo-filesystem.
|
||||
While it is possible to alter this value, some drivers may be hardcoded to follow the default paths.
|
||||
'';
|
||||
};
|
||||
port = lib.options.mkOption {
|
||||
port = mkOption {
|
||||
default = "/proc/xen/xsd_port";
|
||||
example = cfg.store.settings.xenstored.xenfs.port;
|
||||
type = lib.types.path;
|
||||
type = path;
|
||||
visible = false;
|
||||
description = ''
|
||||
Path to the Xen Store Daemon userspace port inside the XenFS pseudo-filesystem.
|
||||
@@ -578,11 +579,11 @@ in
|
||||
};
|
||||
};
|
||||
};
|
||||
ringScanInterval = lib.options.mkOption {
|
||||
ringScanInterval = mkOption {
|
||||
default = 20;
|
||||
example = 30;
|
||||
type = lib.types.addCheck (
|
||||
lib.types.int
|
||||
type = addCheck (
|
||||
int
|
||||
// {
|
||||
name = "nonzeroInt";
|
||||
description = "nonzero signed integer, meaning !=0";
|
||||
@@ -602,7 +603,7 @@ in
|
||||
|
||||
## Implementation ##
|
||||
|
||||
config = lib.modules.mkIf cfg.enable {
|
||||
config = mkIf cfg.enable {
|
||||
assertions = [
|
||||
{
|
||||
assertion = pkgs.stdenv.hostPlatform.isx86_64;
|
||||
@@ -639,18 +640,18 @@ in
|
||||
];
|
||||
|
||||
virtualisation.xen.bootParams =
|
||||
lib.lists.optionals cfg.trace [
|
||||
optionals cfg.trace [
|
||||
"loglvl=all"
|
||||
"guest_loglvl=all"
|
||||
]
|
||||
++
|
||||
lib.lists.optional (cfg.dom0Resources.memory != 0)
|
||||
optional (cfg.dom0Resources.memory != 0)
|
||||
"dom0_mem=${toString cfg.dom0Resources.memory}M${
|
||||
lib.strings.optionalString (
|
||||
optionalString (
|
||||
cfg.dom0Resources.memory != cfg.dom0Resources.maxMemory
|
||||
) ",max:${toString cfg.dom0Resources.maxMemory}M"
|
||||
}"
|
||||
++ lib.lists.optional (
|
||||
++ optional (
|
||||
cfg.dom0Resources.maxVCPUs != 0
|
||||
) "dom0_max_vcpus=${toString cfg.dom0Resources.maxVCPUs}";
|
||||
|
||||
@@ -701,7 +702,7 @@ in
|
||||
|
||||
# See the `xenBootBuilder` script in the main `let...in` statement of this file.
|
||||
loader.systemd-boot.extraInstallCommands = ''
|
||||
${lib.meta.getExe xenBootBuilder} ${cfg.efi.bootBuilderVerbosity}
|
||||
${getExe xenBootBuilder} ${cfg.efi.bootBuilderVerbosity}
|
||||
'';
|
||||
};
|
||||
|
||||
@@ -744,7 +745,7 @@ in
|
||||
|
||||
XENSTORED="${cfg.store.path}"
|
||||
QEMU_XEN="${cfg.qemu.package}/${cfg.qemu.package.qemu-system-i386}"
|
||||
${lib.strings.optionalString cfg.trace ''
|
||||
${optionalString cfg.trace ''
|
||||
XENSTORED_TRACE=yes
|
||||
XENCONSOLED_TRACE=all
|
||||
''}
|
||||
@@ -756,10 +757,10 @@ in
|
||||
'';
|
||||
}
|
||||
# The OCaml-based Xen Store Daemon requires /etc/xen/oxenstored.conf to start.
|
||||
// lib.attrsets.optionalAttrs (cfg.store.type == "ocaml") {
|
||||
// optionalAttrs (cfg.store.type == "ocaml") {
|
||||
"xen/oxenstored.conf".text = ''
|
||||
pid-file = ${cfg.store.settings.pidFile}
|
||||
test-eagain = ${lib.trivial.boolToString cfg.store.settings.testEAGAIN}
|
||||
test-eagain = ${boolToString cfg.store.settings.testEAGAIN}
|
||||
merge-activate = ${toString cfg.store.settings.enableMerge}
|
||||
conflict-burst-limit = ${toString cfg.store.settings.conflict.burstLimit}
|
||||
conflict-max-history-seconds = ${toString cfg.store.settings.conflict.maxHistorySeconds}
|
||||
@@ -775,7 +776,7 @@ in
|
||||
quota-path-max = ${toString cfg.store.settings.quota.maxPath}
|
||||
quota-maxoutstanding = ${toString cfg.store.settings.quota.maxOutstanding}
|
||||
quota-maxwatchevents = ${toString cfg.store.settings.quota.maxWatchEvents}
|
||||
persistent = ${lib.trivial.boolToString cfg.store.settings.persistent}
|
||||
persistent = ${boolToString cfg.store.settings.persistent}
|
||||
xenstored-log-file = ${cfg.store.settings.xenstored.log.file}
|
||||
xenstored-log-level = ${
|
||||
if isNull cfg.store.settings.xenstored.log.level then
|
||||
@@ -787,7 +788,7 @@ in
|
||||
access-log-file = ${cfg.store.settings.xenstored.accessLog.file}
|
||||
access-log-nb-lines = ${toString cfg.store.settings.xenstored.accessLog.nbLines}
|
||||
acesss-log-nb-chars = ${toString cfg.store.settings.xenstored.accessLog.nbChars}
|
||||
access-log-special-ops = ${lib.trivial.boolToString cfg.store.settings.xenstored.accessLog.specialOps}
|
||||
access-log-special-ops = ${boolToString cfg.store.settings.xenstored.accessLog.specialOps}
|
||||
ring-scan-interval = ${toString cfg.store.settings.ringScanInterval}
|
||||
xenstored-kva = ${cfg.store.settings.xenstored.xenfs.kva}
|
||||
xenstored-port = ${cfg.store.settings.xenstored.xenfs.port}
|
||||
@@ -870,5 +871,5 @@ in
|
||||
};
|
||||
};
|
||||
};
|
||||
meta.maintainers = lib.teams.xen.members;
|
||||
meta.maintainers = members;
|
||||
}
|
||||
|
||||
@@ -38,6 +38,8 @@
|
||||
, hostCpuOnly ? false
|
||||
, hostCpuTargets ? (if toolsOnly
|
||||
then [ ]
|
||||
else if xenSupport
|
||||
then [ "i386-softmmu" ]
|
||||
else if hostCpuOnly
|
||||
then (lib.optional stdenv.hostPlatform.isx86_64 "i386-softmmu"
|
||||
++ ["${stdenv.hostPlatform.qemuArch}-softmmu"])
|
||||
@@ -50,6 +52,8 @@
|
||||
, qemu-utils # for tests attribute
|
||||
}:
|
||||
|
||||
assert lib.assertMsg (xenSupport -> hostCpuTargets == [ "i386-softmmu" ]) "Xen should not use any other QEMU architecture other than i386.";
|
||||
|
||||
let
|
||||
hexagonSupport = hostCpuTargets == null || lib.elem "hexagon" hostCpuTargets;
|
||||
|
||||
|
||||
@@ -1,56 +0,0 @@
|
||||
{
|
||||
lib,
|
||||
fetchpatch,
|
||||
callPackage,
|
||||
ocaml-ng,
|
||||
...
|
||||
}@genericDefinition:
|
||||
|
||||
let
|
||||
upstreamPatches = import ../generic/patches.nix {
|
||||
inherit lib;
|
||||
inherit fetchpatch;
|
||||
};
|
||||
|
||||
upstreamPatchList = lib.lists.flatten (
|
||||
with upstreamPatches;
|
||||
[
|
||||
QUBES_REPRODUCIBLE_BUILDS
|
||||
XSA_462
|
||||
]
|
||||
);
|
||||
in
|
||||
|
||||
callPackage (import ../generic/default.nix {
|
||||
pname = "xen";
|
||||
branch = "4.17";
|
||||
version = "4.17.5";
|
||||
latest = false;
|
||||
pkg = {
|
||||
xen = {
|
||||
rev = "430ce6cd936546ad883ecd1c85ddea32d790604b";
|
||||
hash = "sha256-UoMdXRW0yWSaQPPV0rgoTZVO2ghdnqWruBHn7+ZjKzI=";
|
||||
patches = [ ] ++ upstreamPatchList;
|
||||
};
|
||||
qemu = {
|
||||
rev = "ffb451126550b22b43b62fb8731a0d78e3376c03";
|
||||
hash = "sha256-G0hMPid9d3fd1jAY7CiZ33xUZf1hdy96T1VUKFGeHSk=";
|
||||
patches = [ ];
|
||||
};
|
||||
seaBIOS = {
|
||||
rev = "d239552ce7220e448ae81f41515138f7b9e3c4db";
|
||||
hash = "sha256-UKMceJhIprN4/4Xe4EG2EvKlanxVcEi5Qcrrk3Ogiik=";
|
||||
patches = [ ];
|
||||
};
|
||||
ovmf = {
|
||||
rev = "7b4a99be8a39c12d3a7fc4b8db9f0eab4ac688d5";
|
||||
hash = "sha256-Qq2RgktCkJZBsq6Ch+6tyRHhme4lfcN7d2oQfxwhQt8=";
|
||||
patches = [ ];
|
||||
};
|
||||
ipxe = {
|
||||
rev = "1d1cf74a5e58811822bee4b3da3cff7282fcdfca";
|
||||
hash = "sha256-8pwoPrmkpL6jIM+Y/C0xSvyrBM/Uv0D1GuBwNm+0DHU=";
|
||||
patches = [ ];
|
||||
};
|
||||
};
|
||||
}) ({ ocamlPackages = ocaml-ng.ocamlPackages_4_14; } // genericDefinition)
|
||||
@@ -1,56 +0,0 @@
|
||||
{
|
||||
lib,
|
||||
fetchpatch,
|
||||
callPackage,
|
||||
ocaml-ng,
|
||||
...
|
||||
}@genericDefinition:
|
||||
|
||||
let
|
||||
upstreamPatches = import ../generic/patches.nix {
|
||||
inherit lib;
|
||||
inherit fetchpatch;
|
||||
};
|
||||
|
||||
upstreamPatchList = lib.lists.flatten (
|
||||
with upstreamPatches;
|
||||
[
|
||||
QUBES_REPRODUCIBLE_BUILDS
|
||||
XSA_462
|
||||
]
|
||||
);
|
||||
in
|
||||
|
||||
callPackage (import ../generic/default.nix {
|
||||
pname = "xen";
|
||||
branch = "4.18";
|
||||
version = "4.18.3";
|
||||
latest = false;
|
||||
pkg = {
|
||||
xen = {
|
||||
rev = "bd51e573a730efc569646379cd59ccba967cde97";
|
||||
hash = "sha256-OFiFdpPCXR+sWjzFHCORtY4DkWyggvxkcsGdgEyO1ts=";
|
||||
patches = [ ] ++ upstreamPatchList;
|
||||
};
|
||||
qemu = {
|
||||
rev = "0df9387c8983e1b1e72d8c574356f572342c03e6";
|
||||
hash = "sha256-BX+LXfNzwdUMALwwI1ZDW12dJ357oynjnrboLHREDGQ=";
|
||||
patches = [ ];
|
||||
};
|
||||
seaBIOS = {
|
||||
rev = "ea1b7a0733906b8425d948ae94fba63c32b1d425";
|
||||
hash = "sha256-J2FuT+FXn9YoFLSfxDOxyKZvKrys59a6bP1eYvEXVNU=";
|
||||
patches = [ ];
|
||||
};
|
||||
ovmf = {
|
||||
rev = "ba91d0292e593df8528b66f99c1b0b14fadc8e16";
|
||||
hash = "sha256-htOvV43Hw5K05g0SF3po69HncLyma3BtgpqYSdzRG4s=";
|
||||
patches = [ ];
|
||||
};
|
||||
ipxe = {
|
||||
rev = "1d1cf74a5e58811822bee4b3da3cff7282fcdfca";
|
||||
hash = "sha256-8pwoPrmkpL6jIM+Y/C0xSvyrBM/Uv0D1GuBwNm+0DHU=";
|
||||
patches = [ ];
|
||||
};
|
||||
};
|
||||
}) ({ ocamlPackages = ocaml-ng.ocamlPackages_4_14; } // genericDefinition)
|
||||
@@ -1,58 +0,0 @@
|
||||
{
|
||||
lib,
|
||||
fetchpatch,
|
||||
callPackage,
|
||||
ocaml-ng,
|
||||
...
|
||||
}@genericDefinition:
|
||||
|
||||
let
|
||||
upstreamPatches = import ../generic/patches.nix {
|
||||
inherit lib;
|
||||
inherit fetchpatch;
|
||||
};
|
||||
|
||||
upstreamPatchList = lib.lists.flatten (
|
||||
with upstreamPatches;
|
||||
[
|
||||
QUBES_REPRODUCIBLE_BUILDS
|
||||
XSA_460
|
||||
XSA_461
|
||||
XSA_462
|
||||
]
|
||||
);
|
||||
in
|
||||
|
||||
callPackage (import ../generic/default.nix {
|
||||
pname = "xen";
|
||||
branch = "4.19";
|
||||
version = "4.19.0";
|
||||
latest = true;
|
||||
pkg = {
|
||||
xen = {
|
||||
rev = "026c9fa29716b0ff0f8b7c687908e71ba29cf239";
|
||||
hash = "sha256-Q6x+2fZ4ITBz6sKICI0NHGx773Rc919cl+wzI89UY+Q=";
|
||||
patches = [ ] ++ upstreamPatchList;
|
||||
};
|
||||
qemu = {
|
||||
rev = "0df9387c8983e1b1e72d8c574356f572342c03e6";
|
||||
hash = "sha256-BX+LXfNzwdUMALwwI1ZDW12dJ357oynjnrboLHREDGQ=";
|
||||
patches = [ ];
|
||||
};
|
||||
seaBIOS = {
|
||||
rev = "a6ed6b701f0a57db0569ab98b0661c12a6ec3ff8";
|
||||
hash = "sha256-hWemj83cxdY8p+Jhkh5GcPvI0Sy5aKYZJCsKDjHTUUk=";
|
||||
patches = [ ];
|
||||
};
|
||||
ovmf = {
|
||||
rev = "ba91d0292e593df8528b66f99c1b0b14fadc8e16";
|
||||
hash = "sha256-htOvV43Hw5K05g0SF3po69HncLyma3BtgpqYSdzRG4s=";
|
||||
patches = [ ];
|
||||
};
|
||||
ipxe = {
|
||||
rev = "1d1cf74a5e58811822bee4b3da3cff7282fcdfca";
|
||||
hash = "sha256-8pwoPrmkpL6jIM+Y/C0xSvyrBM/Uv0D1GuBwNm+0DHU=";
|
||||
patches = [ ];
|
||||
};
|
||||
};
|
||||
}) ({ ocamlPackages = ocaml-ng.ocamlPackages_4_14; } // genericDefinition)
|
||||
@@ -1,209 +0,0 @@
|
||||
<p align="center">
|
||||
<a href="https://xenproject.org/">
|
||||
<picture>
|
||||
<source
|
||||
media="(prefers-color-scheme: light)"
|
||||
srcset="https://downloads.xenproject.org/Branding/Logos/Green+Black/xen_project_logo_dualcolor_2000x832.png">
|
||||
<source
|
||||
media="(prefers-color-scheme: dark)"
|
||||
srcset="https://xenproject.org/wp-content/uploads/sites/79/2018/09/logo_xenproject.png">
|
||||
<img
|
||||
src="https://downloads.xenproject.org/Branding/Logos/Green+Black/xen_project_logo_dualcolor_2000x832.png"
|
||||
width="512px"
|
||||
alt="Xen Project Logo">
|
||||
</picture>
|
||||
</a>
|
||||
</p>
|
||||
|
||||
# Xen Project Hypervisor <a href="https://xenproject.org/"><img src="https://downloads.xenproject.org/Branding/Mascots/Xen-Fu-Panda-2000px.png" width="48px" align="top" alt="Xen Fu Panda"></a>
|
||||
|
||||
This directory includes the build recipes for the [Xen Project Hypervisor](https://xenproject.org/).
|
||||
|
||||
Some other notable packages that compose the Xen Project Ecosystem include:
|
||||
|
||||
- `ocamlPackages.xenstore`: Mirage's `oxenstore` implementation.
|
||||
- `ocamlPackages.vchan`: Mirage's `xen-vchan` implementation.
|
||||
- `ocamlPackages.xenstore-tool`: XAPI's `oxenstore` utilities.
|
||||
- `xen-guest-agent`: Guest drivers for UNIX domUs.
|
||||
- `win-pvdrivers`: Guest drivers for Windows domUs.
|
||||
- `xtf`: The Xen Test Framework.
|
||||
|
||||
## Updating
|
||||
|
||||
### Automatically
|
||||
|
||||
An automated update script is available in this directory. To produce up-to-date
|
||||
files for all supported Xen branches, simply run `./update.sh`, and follow the
|
||||
instructions given to you by the script. Notably, it will request that you verify
|
||||
the Xen Project code signing PGP key. This README understands that the fingerprint
|
||||
of that key is [`23E3 222C 145F 4475 FA80 60A7 83FE 14C9 57E8 2BD9`](https://keys.openpgp.org/search?q=pgp%40xen.org),
|
||||
but you should verify this information by seeking the fingerprint from other trusted
|
||||
sources, as this document may be compromised. Once the PGP key is verified, it will
|
||||
use `git verify-tag` to ascertain the validity of the cloned Xen sources.
|
||||
|
||||
After the script is done, follow the steps in
|
||||
[**For Both Update Methods**](#for-both-update-methods) below.
|
||||
|
||||
#### Downstream Patch Names
|
||||
|
||||
The script expects local patch names to follow a certain specification.
|
||||
Please name any required patches using the template below:
|
||||
|
||||
```console
|
||||
0000-project-description-branch.patch
|
||||
```
|
||||
|
||||
Where:
|
||||
|
||||
1. The first four numbers define the patch order.
|
||||
**0001** will be applied after **0000**, and so on.
|
||||
1. `project` means the name of the source the patch should be applied to.
|
||||
- If you are applying patches to the main Xen sources, use `xen`.
|
||||
- For the pre-fetched QEMU, use `qemu`.
|
||||
- For SeaBIOS, use `seabios`.
|
||||
- For OVMF, use `ovmf`.
|
||||
- For iPXE, use `ipxe`.
|
||||
1. `description` is a string with uppercase and lowercase letters, numbers and
|
||||
dashes. It describes the patch name and what it does to the upstream code.
|
||||
1. `branch` is the branch for which this patch is supposed to patch.
|
||||
It should match the name of the directory it is in.
|
||||
|
||||
For example, a patch fixing `xentop`'s output in the 4.15 branch should have
|
||||
the following name: `0000-xen-xentop-output-4.15.patch`, and it should be added
|
||||
to the `4.15/` directory.
|
||||
|
||||
### Manually
|
||||
|
||||
The script is not infallible, and it may break in the future. If that happens,
|
||||
open a PR fixing the script, and update Xen manually:
|
||||
|
||||
1. Check the support matrix to see which branches are security-supported.
|
||||
1. Create one directory per branch.
|
||||
1. [Update](https://xenbits.xenproject.org/gitweb/) the `default.nix` files for
|
||||
the branches that already exist and copy a new one to any branches that do
|
||||
not yet exist in Nixpkgs.
|
||||
- Do not forget to set the `branch`, `version`, and `latest` attributes for
|
||||
each of the `default.nix` files.
|
||||
- The revisions are preferably commit hashes, but tag names are acceptable
|
||||
as well.
|
||||
|
||||
### For Both Update Methods
|
||||
|
||||
1. Update `packages.nix` and `../../../top-level/all-packages.nix` with the new
|
||||
versions. Don't forget the `slim` packages!
|
||||
1. Make sure all branches build. (Both the `standard` and `slim` versions)
|
||||
1. Use the NixOS module to test if dom0 boots successfully on all new versions.
|
||||
1. Make sure the `meta` attributes evaluate to something that makes sense. The
|
||||
following one-line command is useful for testing this:
|
||||
|
||||
```console
|
||||
xenToEvaluate=xen; echo -e "\033[1m$(nix eval .#"$xenToEvaluate".meta.description --raw 2> /dev/null)\033[0m\n\n$(nix eval .#"$xenToEvaluate".meta.longDescription --raw 2> /dev/null)"
|
||||
```
|
||||
|
||||
Change the value of `xenToEvaluate` to evaluate all relevant Xen packages.
|
||||
1. Run `xtf --all --host` as root when booted into the Xen update, and make
|
||||
sure no tests fail.
|
||||
1. Clean up your changes and commit them, making sure to follow the
|
||||
[Nixpkgs Contribution Guidelines](../../../../CONTRIBUTING.md).
|
||||
1. Open a PR and await a review from the current maintainers.
|
||||
|
||||
## Features
|
||||
|
||||
### Pre-fetched Sources
|
||||
|
||||
On a typical Xen build, the Xen Makefiles will fetch more required sources with
|
||||
`git` and `wget`. Due to the Nix Sandbox, build-time fetching will fail, so we
|
||||
pre-fetch the required sources before building.[^1] To accomplish this, we have
|
||||
a `prefetchedSources` attribute that contains the required derivations, if they
|
||||
are requested by the main Xen build.
|
||||
|
||||
### EFI
|
||||
|
||||
Building `xen.efi` requires an `ld` with PE support.[^2]
|
||||
|
||||
We use a `makeFlag` to override the `$LD` environment variable to point to our
|
||||
patched `efiBinutils`. For more information, see the comment in `./generic/default.nix`.
|
||||
|
||||
> [!TIP]
|
||||
> If you are certain you will not be running Xen in an x86 EFI environment, disable
|
||||
the `withEFI` flag with an [override](https://nixos.org/manual/nixpkgs/stable/#chap-overrides)
|
||||
to save you the need to compile `efiBinutils`.
|
||||
|
||||
### Default Overrides
|
||||
|
||||
By default, Xen also builds
|
||||
[QEMU](https://www.qemu.org/),
|
||||
[SeaBIOS](https://www.seabios.org/SeaBIOS),
|
||||
[OVMF](https://github.com/tianocore/tianocore.github.io/wiki/OVMF) and
|
||||
[iPXE](https://ipxe.org/).
|
||||
|
||||
- QEMU is used for stubdomains and handling devices.
|
||||
- SeaBIOS is the default legacy BIOS ROM for HVM domains.
|
||||
- OVMF is the default UEFI ROM for HVM domains.
|
||||
- iPXE provides a PXE boot environment for HVMs.
|
||||
|
||||
However, those packages are already available on Nixpkgs, and Xen does not
|
||||
necessarily need to build them into the main hypervisor build. For this reason,
|
||||
we also have the `withInternal<Component>` flags, which enables and disables
|
||||
building those built-in components. The two most popular Xen configurations will
|
||||
be the default build, with all built-in components, and a `slim` build, with none
|
||||
of those components. To simplify this process, the `./packages.nix` file includes
|
||||
the `xen-slim` package overrides that have all `withInternal<Component>` flags
|
||||
disabled. See the `meta.longDescription` attribute for the `xen-slim` packages
|
||||
for more information.
|
||||
|
||||
## Security
|
||||
|
||||
We aim to support all **security-supported** versions of Xen at any given time.
|
||||
See the [Xen Support Matrix](https://xenbits.xen.org/docs/unstable/support-matrix.html)
|
||||
for a list of versions. As soon as a version is no longer **security-supported**,
|
||||
it should be removed from Nixpkgs.
|
||||
|
||||
> [!CAUTION]
|
||||
> Pull requests that introduce XSA patches
|
||||
should have the `1.severity: security` label.
|
||||
|
||||
### Maintainers
|
||||
|
||||
Xen is a particularly complex piece of software, so we are always looking for new
|
||||
maintainers. Help out by [making and triaging issues](https://github.com/NixOS/nixpkgs/issues/new/choose),
|
||||
[sending build fixes and improvements through PRs](https://github.com/NixOS/nixpkgs/compare),
|
||||
updating the branches, and [patching security flaws](https://xenbits.xenproject.org/xsa/).
|
||||
|
||||
We are also looking for testers, particularly those who can test Xen on AArch64
|
||||
machines. Open issues for any build failures or runtime errors you find!
|
||||
|
||||
## Tests
|
||||
|
||||
So far, we only have had one simple automated test that checks for
|
||||
the correct `pkg-config` output files.
|
||||
|
||||
Due to Xen's nature as a type-1 hypervisor, it is not a trivial matter to design
|
||||
new tests, as even basic functionality requires a machine booted in a dom0
|
||||
kernel. For this reason, most testing done with this package must be done
|
||||
manually in a NixOS machine with `virtualisation.xen.enable` set to `true`.
|
||||
|
||||
Another unfortunate thing is that none of the Xen commands have a `--version`
|
||||
flag. This means that `testers.testVersion` cannot ascertain the Xen version.
|
||||
The only way to verify that you have indeed built the correct version is to
|
||||
boot into the freshly built Xen kernel and run `xl info`.
|
||||
|
||||
<p align="center">
|
||||
<a href="https://xenproject.org/">
|
||||
<img
|
||||
src="https://downloads.xenproject.org/Branding/Mascots/Xen%20Big%20Panda%204242x3129.png"
|
||||
width="96px"
|
||||
alt="Xen Fu Panda">
|
||||
</a>
|
||||
</p>
|
||||
|
||||
[^1]: We also produce fake `git`, `wget` and `hostname` binaries that do nothing,
|
||||
to prevent the build from failing because Xen cannot fetch the sources that
|
||||
were already fetched by Nix.
|
||||
[^2]: From the [Xen Documentation](https://xenbits.xenproject.org/docs/unstable/misc/efi.html):
|
||||
> For x86, building `xen.efi` requires `gcc` 4.5.x or above (4.6.x or newer
|
||||
recommended, as 4.5.x was probably never really tested for this purpose)
|
||||
and `binutils` 2.22 or newer. Additionally, the `binutils` build must be
|
||||
configured to include support for the x86_64-pep emulation (i.e.
|
||||
`--enable-targets=x86_64-pep` or an option of equivalent effect should be
|
||||
passed to the configure script).
|
||||
@@ -1,27 +0,0 @@
|
||||
Hack to make etherboot use pre-fetched iPXE.
|
||||
|
||||
diff --git a/tools/firmware/etherboot/Makefile b/tools/firmware/etherboot/Makefile
|
||||
index ed9e11305f..979a3acea8 100644
|
||||
--- a/tools/firmware/etherboot/Makefile
|
||||
+++ b/tools/firmware/etherboot/Makefile
|
||||
@@ -16,6 +16,7 @@ IPXE_TARBALL_URL ?= $(XEN_EXTFILES_URL)/ipxe-git-$(IPXE_GIT_TAG).tar.gz
|
||||
|
||||
D=ipxe
|
||||
T=ipxe.tar.gz
|
||||
+G=ipxe.git
|
||||
|
||||
ROMS = $(addprefix $D/src/bin/, $(addsuffix .rom, $(ETHERBOOT_NICS)))
|
||||
ROM = $D/src/bin/ipxe.bin
|
||||
@@ -41,9 +42,9 @@ $T:
|
||||
fi
|
||||
mv _$T $T
|
||||
|
||||
-$D/src/arch/i386/Makefile: $T Config
|
||||
- rm -rf $D
|
||||
- gzip -dc $T | tar xf -
|
||||
+$D/src/arch/i386/Makefile: $G Config
|
||||
+ mkdir $D
|
||||
+ cp -a $G/* $D
|
||||
for i in $$(cat patches/series) ; do \
|
||||
patch -d $D -p1 --quiet <patches/$$i || exit 1 ; \
|
||||
done
|
||||
@@ -1,728 +0,0 @@
|
||||
versionDefinition:
|
||||
{
|
||||
lib,
|
||||
stdenv,
|
||||
autoPatchelfHook,
|
||||
cmake,
|
||||
ninja,
|
||||
pkg-config,
|
||||
testers,
|
||||
which,
|
||||
|
||||
fetchgit,
|
||||
fetchFromGitHub,
|
||||
|
||||
# Xen
|
||||
acpica-tools,
|
||||
bison,
|
||||
bzip2,
|
||||
dev86,
|
||||
e2fsprogs,
|
||||
flex,
|
||||
libnl,
|
||||
libuuid,
|
||||
lzo,
|
||||
ncurses,
|
||||
ocamlPackages,
|
||||
perl,
|
||||
python3Packages,
|
||||
systemdMinimal,
|
||||
xz,
|
||||
yajl,
|
||||
zlib,
|
||||
zstd,
|
||||
|
||||
# Xen Optional
|
||||
withInternalQEMU ? true,
|
||||
pixman,
|
||||
glib,
|
||||
|
||||
withInternalSeaBIOS ? true,
|
||||
withSeaBIOS ? !withInternalSeaBIOS,
|
||||
seabios,
|
||||
|
||||
withInternalOVMF ? true,
|
||||
withOVMF ? !withInternalOVMF,
|
||||
OVMF,
|
||||
nasm,
|
||||
|
||||
withInternalIPXE ? true,
|
||||
withIPXE ? !withInternalIPXE,
|
||||
ipxe,
|
||||
|
||||
withFlask ? false,
|
||||
checkpolicy,
|
||||
|
||||
efiVendor ? "nixos", # Allow downstreams with custom branding to quickly override the EFI Vendor string.
|
||||
withEFI ? true,
|
||||
binutils-unwrapped,
|
||||
|
||||
# Documentation
|
||||
pandoc,
|
||||
|
||||
# Scripts
|
||||
bridge-utils,
|
||||
coreutils,
|
||||
diffutils,
|
||||
gawk,
|
||||
gnugrep,
|
||||
gnused,
|
||||
inetutils,
|
||||
iproute2,
|
||||
iptables,
|
||||
multipath-tools,
|
||||
nbd,
|
||||
openvswitch,
|
||||
util-linux,
|
||||
...
|
||||
}@packageDefinition:
|
||||
|
||||
let
|
||||
#TODO: fix paths instead.
|
||||
scriptEnvPath = lib.strings.makeSearchPathOutput "out" "bin" [
|
||||
bridge-utils
|
||||
coreutils
|
||||
diffutils
|
||||
gawk
|
||||
gnugrep
|
||||
gnused
|
||||
inetutils
|
||||
iproute2
|
||||
iptables
|
||||
multipath-tools
|
||||
nbd
|
||||
openvswitch
|
||||
perl
|
||||
util-linux.bin
|
||||
which
|
||||
];
|
||||
|
||||
# Inherit attributes from a versionDefinition.
|
||||
inherit (versionDefinition)
|
||||
pname
|
||||
branch
|
||||
version
|
||||
latest
|
||||
pkg
|
||||
;
|
||||
|
||||
# Mark versions older than minSupportedVersion as EOL.
|
||||
minSupportedVersion = "4.17";
|
||||
|
||||
## Pre-fetched Source Handling ##
|
||||
|
||||
# Main attribute set for sources needed to build tools and firmwares.
|
||||
# Each source takes in:
|
||||
# * A `src` attribute, which contains the actual fetcher,
|
||||
# * A 'patches` attribute, which is a list of patches that need to be applied in the source.
|
||||
# * A `path` attribute, which is the destination of the source inside the Xen tree.
|
||||
prefetchedSources =
|
||||
lib.attrsets.optionalAttrs withInternalQEMU {
|
||||
qemu = {
|
||||
src = fetchgit {
|
||||
url = "https://xenbits.xenproject.org/git-http/qemu-xen.git";
|
||||
fetchSubmodules = true;
|
||||
inherit (pkg.qemu) rev hash;
|
||||
};
|
||||
patches = lib.lists.optionals (lib.attrsets.hasAttrByPath [ "patches" ] pkg.qemu) pkg.qemu.patches;
|
||||
path = "tools/qemu-xen";
|
||||
};
|
||||
}
|
||||
// lib.attrsets.optionalAttrs withInternalSeaBIOS {
|
||||
seaBIOS = {
|
||||
src = fetchgit {
|
||||
url = "https://xenbits.xenproject.org/git-http/seabios.git";
|
||||
inherit (pkg.seaBIOS) rev hash;
|
||||
};
|
||||
patches = lib.lists.optionals (lib.attrsets.hasAttrByPath [
|
||||
"patches"
|
||||
] pkg.seaBIOS) pkg.seaBIOS.patches;
|
||||
path = "tools/firmware/seabios-dir-remote";
|
||||
};
|
||||
}
|
||||
// lib.attrsets.optionalAttrs withInternalOVMF {
|
||||
ovmf = {
|
||||
src = fetchgit {
|
||||
url = "https://xenbits.xenproject.org/git-http/ovmf.git";
|
||||
fetchSubmodules = true;
|
||||
inherit (pkg.ovmf) rev hash;
|
||||
};
|
||||
patches = lib.lists.optionals (lib.attrsets.hasAttrByPath [ "patches" ] pkg.ovmf) pkg.ovmf.patches;
|
||||
path = "tools/firmware/ovmf-dir-remote";
|
||||
};
|
||||
}
|
||||
// lib.attrsets.optionalAttrs withInternalIPXE {
|
||||
ipxe = {
|
||||
src = fetchFromGitHub {
|
||||
owner = "ipxe";
|
||||
repo = "ipxe";
|
||||
inherit (pkg.ipxe) rev hash;
|
||||
};
|
||||
patches = lib.lists.optionals (lib.attrsets.hasAttrByPath [ "patches" ] pkg.ipxe) pkg.ipxe.patches;
|
||||
path = "tools/firmware/etherboot/ipxe.git";
|
||||
};
|
||||
};
|
||||
|
||||
# Gets a list containing the names of the top-level attribute for each pre-fetched
|
||||
# source, to be used in the map functions below.
|
||||
prefetchedSourcesList = lib.attrsets.mapAttrsToList (name: value: name) prefetchedSources;
|
||||
|
||||
# Produces bash commands that will copy each pre-fetched source.
|
||||
copyPrefetchedSources =
|
||||
# Finish the deployment by concatnating the list of commands together.
|
||||
lib.strings.concatLines (
|
||||
# Iterate on each pre-fetched source.
|
||||
builtins.map (
|
||||
source:
|
||||
# Only produce a copy command if patches exist.
|
||||
lib.strings.optionalString (lib.attrsets.hasAttrByPath [ "${source}" ] prefetchedSources)
|
||||
# The actual copy command. `src` is always an absolute path to a fetcher output
|
||||
# inside the /nix/store, and `path` is always a path relative to the Xen root.
|
||||
# We need to `mkdir -p` the target directory first, and `chmod +w` the contents last,
|
||||
# as the copied files will still be edited by the postPatchPhase.
|
||||
''
|
||||
echo "Copying ${prefetchedSources.${source}.src} -> ${prefetchedSources.${source}.path}"
|
||||
mkdir --parents ${prefetchedSources.${source}.path}
|
||||
cp --recursive --no-target-directory ${prefetchedSources.${source}.src} ${
|
||||
prefetchedSources.${source}.path
|
||||
}
|
||||
chmod --recursive +w ${prefetchedSources.${source}.path}
|
||||
''
|
||||
) prefetchedSourcesList
|
||||
);
|
||||
|
||||
# Produces strings with `patch` commands to be ran on postPatch.
|
||||
# These deploy the .patch files for each pre-fetched source.
|
||||
deployPrefetchedSourcesPatches =
|
||||
# Finish the deployment by concatnating the list of commands together.
|
||||
lib.strings.concatLines (
|
||||
# The double map functions create a list of lists. Flatten it so we can concatnate it.
|
||||
lib.lists.flatten (
|
||||
# Iterate on each pre-fetched source.
|
||||
builtins.map (
|
||||
source:
|
||||
# Iterate on each available patch.
|
||||
(builtins.map (
|
||||
patch:
|
||||
# Only produce a patch command if patches exist.
|
||||
lib.strings.optionalString
|
||||
(lib.attrsets.hasAttrByPath [
|
||||
"${source}"
|
||||
"patches"
|
||||
] prefetchedSources)
|
||||
# The actual patch command. It changes directories to the correct source each time.
|
||||
''
|
||||
echo "Applying patch ${patch} to ${source}."
|
||||
patch --directory ${prefetchedSources.${source}.path} --strip 1 < ${patch}
|
||||
''
|
||||
) prefetchedSources.${source}.patches)
|
||||
) prefetchedSourcesList
|
||||
)
|
||||
);
|
||||
|
||||
## XSA Patches Description Builder ##
|
||||
|
||||
# Sometimes patches are sourced through a path, like ./0000-xen.patch.
|
||||
# This would break the patch attribute parser functions, so we normalise
|
||||
# all patches sourced through paths by setting them to a { type = "path"; }
|
||||
# attribute set.
|
||||
# Patches from fetchpatch are already attribute sets.
|
||||
normalisedPatchList = builtins.map (
|
||||
patch:
|
||||
if !builtins.isAttrs patch then
|
||||
if builtins.isPath patch then
|
||||
{ type = "path"; }
|
||||
else
|
||||
throw "xen/generic/default.nix: normalisedPatchList attempted to normalise something that is not a Path or an Attribute Set."
|
||||
else
|
||||
patch
|
||||
) pkg.xen.patches;
|
||||
|
||||
# Simple counter for the number of attrsets (patches) in the patches list after normalisation.
|
||||
numberOfPatches = lib.lists.count (patch: builtins.isAttrs patch) normalisedPatchList;
|
||||
|
||||
# builtins.elemAt's index begins at 0, so we subtract 1 from the number of patches in order to
|
||||
# produce the range that will be used in the following builtin.map calls.
|
||||
availablePatchesToTry = lib.lists.range 0 (numberOfPatches - 1);
|
||||
|
||||
# Takes in an attrByPath input, and outputs the attribute value for each patch in a list.
|
||||
# If a patch does not have a given attribute, returns `null`. Use lib.lists.remove null
|
||||
# to remove these junk values, if necessary.
|
||||
retrievePatchAttributes =
|
||||
attributeName:
|
||||
builtins.map (
|
||||
x: lib.attrsets.attrByPath attributeName null (builtins.elemAt normalisedPatchList x)
|
||||
) availablePatchesToTry;
|
||||
|
||||
# Produces a list of newline-separated strings that lists the vulnerabilities this
|
||||
# Xen is NOT affected by, due to the applied Xen Security Advisory patches. This is
|
||||
# then used in meta.longDescription, to let users know their Xen is patched against
|
||||
# known vulnerabilities, as the package version isn't always the best indicator.
|
||||
#
|
||||
# Produces something like this: (one string for each XSA)
|
||||
# * [Xen Security Advisory #1](https://xenbits.xenproject.org/xsa/advisory-1.html): **Title for XSA.**
|
||||
# >Description of issue in XSA
|
||||
#Extra lines
|
||||
#are not indented,
|
||||
#but markdown should be
|
||||
#fine with it.
|
||||
# Fixes:
|
||||
# * [CVE-1999-00001](https://www.cve.org/CVERecord?id=CVE-1999-00001)
|
||||
# * [CVE-1999-00002](https://www.cve.org/CVERecord?id=CVE-1999-00002)
|
||||
# * [CVE-1999-00003](https://www.cve.org/CVERecord?id=CVE-1999-00003)
|
||||
writeAdvisoryDescription =
|
||||
if (lib.lists.remove null (retrievePatchAttributes [ "xsa" ]) != [ ]) then
|
||||
lib.lists.zipListsWith (a: b: a + b)
|
||||
(lib.lists.zipListsWith (a: b: a + "**" + b + ".**\n >")
|
||||
(lib.lists.zipListsWith (a: b: "* [Xen Security Advisory #" + a + "](" + b + "): ")
|
||||
(lib.lists.remove null (retrievePatchAttributes [ "xsa" ]))
|
||||
(
|
||||
lib.lists.remove null (retrievePatchAttributes [
|
||||
"meta"
|
||||
"homepage"
|
||||
])
|
||||
)
|
||||
)
|
||||
(
|
||||
lib.lists.remove null (retrievePatchAttributes [
|
||||
"meta"
|
||||
"description"
|
||||
])
|
||||
)
|
||||
)
|
||||
(
|
||||
lib.lists.remove null (retrievePatchAttributes [
|
||||
"meta"
|
||||
"longDescription"
|
||||
])
|
||||
)
|
||||
else
|
||||
[ ];
|
||||
|
||||
## Binutils Override ##
|
||||
|
||||
# Originally, there were two versions of binutils being used: the standard one and
|
||||
# this patched one. Unfortunately, that required patches to the Xen Makefiles, and
|
||||
# quickly became too complex to maintain. The new solution is to simply build this
|
||||
# efi-binutils derivation and use it for the whole build process, except if
|
||||
# enableEFI is disabled; it'll then use `binutils`.
|
||||
efiBinutils = binutils-unwrapped.overrideAttrs (oldAttrs: {
|
||||
name = "efi-binutils";
|
||||
configureFlags = oldAttrs.configureFlags ++ [ "--enable-targets=x86_64-pep" ];
|
||||
doInstallCheck = false; # We get a spurious failure otherwise, due to a host/target mismatch.
|
||||
meta.mainProgram = "ld"; # We only really care for `ld`.
|
||||
});
|
||||
in
|
||||
|
||||
stdenv.mkDerivation (finalAttrs: {
|
||||
inherit pname version;
|
||||
|
||||
outputs = [
|
||||
"out" # TODO: Split $out in $bin for binaries and $lib for libraries.
|
||||
"man" # Manual pages for Xen userspace utilities.
|
||||
"doc" # The full Xen documentation in HTML format.
|
||||
"dev" # Development headers.
|
||||
"boot" # xen.gz kernel, policy file if Flask is enabled, xen.efi if EFI is enabled.
|
||||
# TODO: Python package to be in separate output/package.
|
||||
];
|
||||
|
||||
# Main Xen source.
|
||||
src = fetchgit {
|
||||
url = "https://xenbits.xenproject.org/git-http/xen.git";
|
||||
inherit (pkg.xen) rev hash;
|
||||
};
|
||||
|
||||
patches =
|
||||
# Generic Xen patches that apply to all Xen versions.
|
||||
[ ./0000-xen-ipxe-src-generic.patch ]
|
||||
# Gets the patches from the pkg.xen.patches attribute from the versioned files.
|
||||
++ lib.lists.optionals (lib.attrsets.hasAttrByPath [ "patches" ] pkg.xen) pkg.xen.patches;
|
||||
|
||||
nativeBuildInputs =
|
||||
[
|
||||
autoPatchelfHook
|
||||
bison
|
||||
cmake
|
||||
flex
|
||||
pandoc
|
||||
pkg-config
|
||||
python3Packages.setuptools
|
||||
]
|
||||
++ lib.lists.optionals withInternalQEMU [
|
||||
ninja
|
||||
python3Packages.sphinx
|
||||
];
|
||||
buildInputs =
|
||||
[
|
||||
# Xen
|
||||
acpica-tools
|
||||
bzip2
|
||||
dev86
|
||||
e2fsprogs.dev
|
||||
libnl
|
||||
libuuid
|
||||
lzo
|
||||
ncurses
|
||||
perl
|
||||
python3Packages.python
|
||||
xz
|
||||
yajl
|
||||
zlib
|
||||
zstd
|
||||
|
||||
# oxenstored
|
||||
ocamlPackages.findlib
|
||||
ocamlPackages.ocaml
|
||||
|
||||
# Python Fixes
|
||||
python3Packages.wrapPython
|
||||
]
|
||||
++ lib.lists.optionals withInternalQEMU [
|
||||
glib
|
||||
pixman
|
||||
]
|
||||
++ lib.lists.optional withInternalOVMF nasm
|
||||
++ lib.lists.optional withFlask checkpolicy
|
||||
++ lib.lists.optional (lib.strings.versionOlder version "4.19") systemdMinimal;
|
||||
|
||||
configureFlags =
|
||||
[
|
||||
"--enable-systemd"
|
||||
"--disable-qemu-traditional"
|
||||
]
|
||||
++ lib.lists.optional (!withInternalQEMU) "--with-system-qemu"
|
||||
|
||||
++ lib.lists.optional withSeaBIOS "--with-system-seabios=${seabios}/share/seabios"
|
||||
++ lib.lists.optional (!withInternalSeaBIOS && !withSeaBIOS) "--disable-seabios"
|
||||
|
||||
++ lib.lists.optional withOVMF "--with-system-ovmf=${OVMF.firmware}"
|
||||
++ lib.lists.optional withInternalOVMF "--enable-ovmf"
|
||||
|
||||
++ lib.lists.optional withIPXE "--with-system-ipxe=${ipxe}"
|
||||
++ lib.lists.optional withInternalIPXE "--enable-ipxe"
|
||||
|
||||
++ lib.lists.optional withFlask "--enable-xsmpolicy";
|
||||
|
||||
makeFlags =
|
||||
[
|
||||
"PREFIX=$(out)"
|
||||
"CONFIG_DIR=/etc"
|
||||
"XEN_SCRIPT_DIR=$(CONFIG_DIR)/xen/scripts"
|
||||
"BASH_COMPLETION_DIR=$(PREFIX)/share/bash-completion/completions"
|
||||
]
|
||||
++ lib.lists.optionals withEFI [
|
||||
"EFI_VENDOR=${efiVendor}"
|
||||
"INSTALL_EFI_STRIP=1"
|
||||
"LD=${lib.meta.getExe efiBinutils}" # See the comment in the efiBinutils definition above.
|
||||
]
|
||||
# These flags set the CONFIG_* options in /boot/xen.config
|
||||
# and define if the default policy file is built. However,
|
||||
# the Flask binaries always get compiled by default.
|
||||
++ lib.lists.optionals withFlask [
|
||||
"XSM_ENABLE=y"
|
||||
"FLASK_ENABLE=y"
|
||||
]
|
||||
++ (pkg.xen.makeFlags or [ ]);
|
||||
|
||||
buildFlags = [
|
||||
"xen" # Build the Xen Hypervisor.
|
||||
"tools" # Build the userspace tools, such as `xl`.
|
||||
"docs" # Build the Xen Documentation
|
||||
];
|
||||
|
||||
enableParallelBuilding = true;
|
||||
|
||||
env.NIX_CFLAGS_COMPILE = builtins.toString (
|
||||
[
|
||||
"-Wno-error=maybe-uninitialized"
|
||||
"-Wno-error=array-bounds"
|
||||
]
|
||||
++ lib.lists.optionals withInternalOVMF [
|
||||
"-Wno-error=format-security"
|
||||
"-Wno-error=use-after-free"
|
||||
"-Wno-error=vla-parameter"
|
||||
"-Wno-error=dangling-pointer"
|
||||
"-Wno-error=stringop-overflow"
|
||||
]
|
||||
);
|
||||
|
||||
dontUseCmakeConfigure = true;
|
||||
dontUseNinjaBuild = withInternalQEMU;
|
||||
|
||||
prePatch =
|
||||
# Xen's stubdoms, tools and firmwares need various sources that
|
||||
# are usually fetched at build time using wget and git. We can't
|
||||
# have that, so we pre-fetch them in the versioned Nix expressions,
|
||||
# and produce fake wget and git executables for debugging purposes.
|
||||
#
|
||||
# We also produce a fake hostname executable to prevent spurious
|
||||
# command-not-found errors during compilation.
|
||||
#
|
||||
# The snippet below produces executables that simply print in stdout
|
||||
# what they were supposed to fetch, and exit gracefully.
|
||||
''
|
||||
mkdir fake-bin
|
||||
|
||||
cat > fake-bin/wget << EOF
|
||||
#!${stdenv.shell} -e
|
||||
echo ===== FAKE WGET: Not fetching \$*
|
||||
[ -e \$3 ]
|
||||
EOF
|
||||
|
||||
cat > fake-bin/git << EOF
|
||||
#!${stdenv.shell}
|
||||
echo ===== FAKE GIT: Not cloning \$*
|
||||
[ -e \$3 ]
|
||||
EOF
|
||||
|
||||
cat > fake-bin/hostname << EOF
|
||||
#!${stdenv.shell}
|
||||
echo ${efiVendor}
|
||||
[ -e \$3 ]
|
||||
EOF
|
||||
|
||||
chmod +x fake-bin/*
|
||||
export PATH=$PATH:$PWD/fake-bin
|
||||
''
|
||||
|
||||
# Remove in-tree QEMU sources, as we either pre-fetch them through
|
||||
# the versioned Nix expressions if withInternalQEMU is true, or we
|
||||
# don't build QEMU at all if withInternalQEMU is false.
|
||||
+ ''
|
||||
rm --recursive --force tools/qemu-xen tools/qemu-xen-traditional
|
||||
''
|
||||
|
||||
# Call copyPrefetchedSources, which copies all aviable sources to their correct positions.
|
||||
+ ''
|
||||
${copyPrefetchedSources}
|
||||
'';
|
||||
|
||||
postPatch =
|
||||
# The following patch forces Xen to install xen.efi on $out/boot
|
||||
# instead of $out/boot/efi/efi/nixos, as the latter directory
|
||||
# would otherwise need to be created manually. This also creates
|
||||
# a more consistent output for downstreams who override the
|
||||
# efiVendor attribute above.
|
||||
''
|
||||
substituteInPlace xen/Makefile \
|
||||
--replace-fail "\$(D)\$(EFI_MOUNTPOINT)/efi/\$(EFI_VENDOR)/\$(T)-\$(XEN_FULLVERSION).efi" \
|
||||
"\$(D)\$(BOOT_DIR)/\$(T)-\$(XEN_FULLVERSION).efi"
|
||||
''
|
||||
|
||||
# The following patch fixes the call to /bin/mkdir on the
|
||||
# launch_xenstore.sh helper script.
|
||||
+ ''
|
||||
substituteInPlace tools/hotplug/Linux/launch-xenstore.in \
|
||||
--replace-fail "/bin/mkdir" "${coreutils}/bin/mkdir"
|
||||
''
|
||||
|
||||
# The following expression fixes the paths called by Xen's systemd
|
||||
# units, so we can use them in the NixOS module.
|
||||
+ ''
|
||||
substituteInPlace \
|
||||
tools/hotplug/Linux/systemd/{xen-init-dom0,xen-qemu-dom0-disk-backend,xenconsoled,xendomains,xenstored}.service.in \
|
||||
--replace-fail /bin/grep ${gnugrep}/bin/grep
|
||||
substituteInPlace \
|
||||
tools/hotplug/Linux/systemd/{xen-qemu-dom0-disk-backend,xenconsoled}.service.in \
|
||||
--replace-fail "/bin/mkdir" "${coreutils}/bin/mkdir"
|
||||
''
|
||||
|
||||
# # Call deployPrefetchedSourcesPatches, which patches all pre-fetched sources with their specified patchlists.
|
||||
+ ''
|
||||
${deployPrefetchedSourcesPatches}
|
||||
''
|
||||
# Patch shebangs for QEMU and OVMF build scripts.
|
||||
+ lib.strings.optionalString withInternalQEMU ''
|
||||
patchShebangs --build tools/qemu-xen/scripts/tracetool.py
|
||||
''
|
||||
+ lib.strings.optionalString withInternalOVMF ''
|
||||
patchShebangs --build tools/firmware/ovmf-dir-remote/OvmfPkg/build.sh tools/firmware/ovmf-dir-remote/BaseTools/BinWrappers/PosixLike/{AmlToC,BrotliCompress,build,GenFfs,GenFv,GenFw,GenSec,LzmaCompress,TianoCompress,Trim,VfrCompile}
|
||||
'';
|
||||
|
||||
installPhase =
|
||||
let
|
||||
cpFlags = builtins.toString [
|
||||
"--preserve=mode,ownership,timestamps,link"
|
||||
"--recursive"
|
||||
"--verbose"
|
||||
"--no-dereference"
|
||||
];
|
||||
in
|
||||
# Run the preInstall tasks.
|
||||
''
|
||||
runHook preInstall
|
||||
''
|
||||
|
||||
# Create $out directories and copy build output.
|
||||
+ ''
|
||||
mkdir --parents $out $out/share $boot
|
||||
cp ${cpFlags} dist/install/nix/store/*/* $out/
|
||||
cp ${cpFlags} dist/install/etc $out
|
||||
cp ${cpFlags} dist/install/boot $boot
|
||||
''
|
||||
|
||||
# Run the postInstall tasks.
|
||||
+ ''
|
||||
runHook postInstall
|
||||
'';
|
||||
|
||||
postInstall =
|
||||
# Wrap xencov_split, xenmon and xentrace_format.
|
||||
''
|
||||
wrapPythonPrograms
|
||||
''
|
||||
|
||||
# We also need to wrap pygrub, which lies in $out/libexec/xen/bin.
|
||||
+ ''
|
||||
wrapPythonProgramsIn "$out/libexec/xen/bin" "$out $pythonPath"
|
||||
''
|
||||
|
||||
# Fix shebangs in Xen's various scripts.
|
||||
#TODO: Remove any and all usage of `sed` and replace these complicated magic runes with readable code.
|
||||
+ ''
|
||||
shopt -s extglob
|
||||
for i in $out/etc/xen/scripts/!(*.sh); do
|
||||
sed --in-place "2s@^@export PATH=$out/bin:${scriptEnvPath}\n@" $i
|
||||
done
|
||||
'';
|
||||
|
||||
postFixup =
|
||||
# Fix binaries in $out/libexec/xen/bin.
|
||||
''
|
||||
addAutoPatchelfSearchPath $out/lib
|
||||
autoPatchelf $out/libexec/xen/bin
|
||||
''
|
||||
# Flask is particularly hard to disable. Even after
|
||||
# setting the make flags to `n`, it still gets compiled.
|
||||
# If withFlask is disabled, delete the extra binaries.
|
||||
+ lib.strings.optionalString (!withFlask) ''
|
||||
rm -f $out/bin/flask-*
|
||||
'';
|
||||
|
||||
passthru = {
|
||||
efi =
|
||||
if withEFI then "boot/xen-${version}.efi" else throw "This Xen was compiled without an EFI binary.";
|
||||
flaskPolicy =
|
||||
if withFlask then
|
||||
"boot/xenpolicy-${version}"
|
||||
else
|
||||
throw "This Xen was compiled without FLASK support.";
|
||||
qemu-system-i386 =
|
||||
if withInternalQEMU then
|
||||
"libexec/xen/bin/qemu-system-i386"
|
||||
else
|
||||
throw "This Xen was compiled without a built-in QEMU.";
|
||||
# This test suite is very simple, as Xen's userspace
|
||||
# utilities require the hypervisor to be booted.
|
||||
tests = {
|
||||
pkg-config = testers.hasPkgConfigModules {
|
||||
package = finalAttrs.finalPackage;
|
||||
moduleNames = [
|
||||
"xencall"
|
||||
"xencontrol"
|
||||
"xendevicemodel"
|
||||
"xenevtchn"
|
||||
"xenforeignmemory"
|
||||
"xengnttab"
|
||||
"xenguest"
|
||||
"xenhypfs"
|
||||
"xenlight"
|
||||
"xenstat"
|
||||
"xenstore"
|
||||
"xentoolcore"
|
||||
"xentoollog"
|
||||
"xenvchan"
|
||||
"xlutil"
|
||||
];
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
meta =
|
||||
if
|
||||
!(lib.attrsets.hasAttrByPath [
|
||||
"meta"
|
||||
] versionDefinition)
|
||||
then
|
||||
{
|
||||
inherit branch;
|
||||
|
||||
# Short description for Xen.
|
||||
description =
|
||||
"Xen Project Hypervisor"
|
||||
# The "and related components" addition is automatically hidden if said components aren't being built.
|
||||
+ lib.strings.optionalString (prefetchedSources != { }) " and related components"
|
||||
# To alter the description inside the paranthesis, edit ./packages.nix.
|
||||
+ lib.strings.optionalString (lib.attrsets.hasAttrByPath [
|
||||
"meta"
|
||||
"description"
|
||||
] packageDefinition) " (${packageDefinition.meta.description})";
|
||||
|
||||
# Long description for Xen.
|
||||
longDescription =
|
||||
# Starts with the longDescription from ./packages.nix.
|
||||
(packageDefinition.meta.longDescription or "")
|
||||
+ lib.strings.optionalString (!withInternalQEMU) (
|
||||
"\nUse with `qemu_xen_${lib.strings.stringAsChars (x: if x == "." then "_" else x) branch}`"
|
||||
+ lib.strings.optionalString latest " or `qemu_xen`"
|
||||
+ ".\n"
|
||||
)
|
||||
# Then, if any of the optional with* components are being built, add the "Includes:" string.
|
||||
+
|
||||
lib.strings.optionalString
|
||||
(
|
||||
withInternalQEMU
|
||||
|| withInternalSeaBIOS
|
||||
|| withInternalOVMF
|
||||
|| withInternalIPXE
|
||||
|| withEFI
|
||||
|| withFlask
|
||||
)
|
||||
(
|
||||
"\nIncludes:"
|
||||
# Originally, this was a call for the complicated withPrefetchedSources. Since there aren't
|
||||
# that many optional components, we just use lib.strings.optionalString, because it's simpler.
|
||||
# Optional components that aren't being built are automatically hidden.
|
||||
+ lib.strings.optionalString withEFI "\n* `xen.efi`: The Xen Project's [EFI binary](https://xenbits.xenproject.org/docs/${branch}-testing/misc/efi.html), available on the `boot` output of this package."
|
||||
+ lib.strings.optionalString withFlask "\n* `xsm-flask`: The [FLASK Xen Security Module](https://wiki.xenproject.org/wiki/Xen_Security_Modules_:_XSM-FLASK). The `xenpolicy-${version}` file is available on the `boot` output of this package."
|
||||
+ lib.strings.optionalString withInternalQEMU "\n* `qemu-xen`: The Xen Project's mirror of [QEMU](https://www.qemu.org/)."
|
||||
+ lib.strings.optionalString withInternalSeaBIOS "\n* `seabios-xen`: The Xen Project's mirror of [SeaBIOS](https://www.seabios.org/SeaBIOS)."
|
||||
+ lib.strings.optionalString withInternalOVMF "\n* `ovmf-xen`: The Xen Project's mirror of [OVMF](https://github.com/tianocore/tianocore.github.io/wiki/OVMF)."
|
||||
+ lib.strings.optionalString withInternalIPXE "\n* `ipxe-xen`: The Xen Project's pinned version of [iPXE](https://ipxe.org/)."
|
||||
)
|
||||
# Finally, we write a notice explaining which vulnerabilities this Xen is NOT vulnerable to.
|
||||
# This will hopefully give users the peace of mind that their Xen is secure, without needing
|
||||
# to search the source code for the XSA patches.
|
||||
+ lib.strings.optionalString (writeAdvisoryDescription != [ ]) (
|
||||
"\n\nThis Xen Project Hypervisor (${version}) has been patched against the following known security vulnerabilities:\n"
|
||||
+ lib.strings.removeSuffix "\n" (lib.strings.concatLines writeAdvisoryDescription)
|
||||
);
|
||||
|
||||
homepage = "https://xenproject.org/";
|
||||
downloadPage = "https://downloads.xenproject.org/release/xen/${version}/";
|
||||
changelog = "https://wiki.xenproject.org/wiki/Xen_Project_${branch}_Release_Notes";
|
||||
|
||||
license = with lib.licenses; [
|
||||
# Documentation.
|
||||
cc-by-40
|
||||
# Most of Xen is licensed under the GPL v2.0.
|
||||
gpl2Only
|
||||
# Xen Libraries and the `xl` command-line utility.
|
||||
lgpl21Only
|
||||
# Development headers in $dev/include.
|
||||
mit
|
||||
];
|
||||
|
||||
# This automatically removes maintainers from EOL versions of Xen, so we aren't bothered about versions we don't explictly support.
|
||||
maintainers = lib.lists.optionals (lib.strings.versionAtLeast version minSupportedVersion) lib.teams.xen.members;
|
||||
knownVulnerabilities = lib.lists.optional (lib.strings.versionOlder version minSupportedVersion) "The Xen Project Hypervisor version ${version} is no longer supported by the Xen Project Security Team. See https://xenbits.xenproject.org/docs/unstable/support-matrix.html";
|
||||
|
||||
mainProgram = "xl";
|
||||
|
||||
# Evaluates to x86_64-linux.
|
||||
platforms = lib.lists.intersectLists lib.platforms.linux lib.platforms.x86_64;
|
||||
|
||||
}
|
||||
else
|
||||
versionDefinition.meta;
|
||||
})
|
||||
@@ -1,71 +0,0 @@
|
||||
{
|
||||
python3Packages,
|
||||
python311Packages,
|
||||
callPackage,
|
||||
}:
|
||||
let
|
||||
standard = {
|
||||
# Broken with python 3.12+ when using internal QEMU due to https://github.com/NixOS/nixpkgs/issues/253751
|
||||
python3Packages = python311Packages;
|
||||
meta = {
|
||||
description = "Standard";
|
||||
longDescription = ''
|
||||
Standard version of the Xen Project Hypervisor. Uses forks of QEMU, SeaBIOS,
|
||||
OVMF and iPXE provided by the Xen Project. This provides the vanilla Xen
|
||||
experience, but wastes space and build time. A typical NixOS setup that runs
|
||||
lots of VMs will usually need to build two different versions of QEMU when using
|
||||
this Xen derivation (one fork and upstream).
|
||||
'';
|
||||
};
|
||||
};
|
||||
slim = {
|
||||
inherit python3Packages;
|
||||
meta = {
|
||||
description = "Without Internal Components";
|
||||
longDescription = ''
|
||||
Slimmed-down version of the Xen Project Hypervisor that reuses nixpkgs packages
|
||||
as much as possible. Instead of using the Xen Project forks for various internal
|
||||
components, this version uses `seabios`, `ovmf` and `ipxe` from Nixpkgs. These
|
||||
components may ocasionally get out of sync with the hypervisor itself, but this
|
||||
builds faster and uses less space than the default derivation.
|
||||
'';
|
||||
};
|
||||
};
|
||||
in
|
||||
# TODO: generalise this to automatically generate both Xen variants for each ./<version>/default.nix.
|
||||
rec {
|
||||
xen_4_19 = callPackage ./4.19/default.nix {
|
||||
inherit (standard) meta python3Packages;
|
||||
};
|
||||
xen_4_19-slim = xen_4_19.override {
|
||||
withInternalQEMU = false;
|
||||
withInternalSeaBIOS = false;
|
||||
withInternalOVMF = false;
|
||||
withInternalIPXE = false;
|
||||
inherit (slim) meta python3Packages;
|
||||
};
|
||||
|
||||
xen_4_18 = callPackage ./4.18/default.nix {
|
||||
inherit (standard) meta python3Packages;
|
||||
};
|
||||
xen_4_18-slim = xen_4_18.override {
|
||||
withInternalQEMU = false;
|
||||
withInternalSeaBIOS = false;
|
||||
withInternalOVMF = false;
|
||||
withInternalIPXE = false;
|
||||
inherit (slim) meta python3Packages;
|
||||
};
|
||||
|
||||
xen_4_17 = callPackage ./4.17/default.nix {
|
||||
inherit (standard) meta python3Packages;
|
||||
};
|
||||
xen_4_17-slim = xen_4_17.override {
|
||||
withInternalQEMU = false;
|
||||
withInternalSeaBIOS = false;
|
||||
withInternalOVMF = false;
|
||||
withInternalIPXE = false;
|
||||
inherit (slim) meta;
|
||||
# Broken with python 3.12+ due to distutils missing.
|
||||
python3Packages = python311Packages;
|
||||
};
|
||||
}
|
||||
@@ -1,202 +0,0 @@
|
||||
#!/usr/bin/env nix-shell
|
||||
#!nix-shell -i bash -p gitMinimal curl gnupg nix-prefetch-git nixfmt-rfc-style
|
||||
# shellcheck disable=SC2206,SC2207 shell=bash
|
||||
set -o errexit
|
||||
set -o pipefail
|
||||
set -o nounset
|
||||
|
||||
#TODO: Use `jq` instead of `sed`.
|
||||
#TODO: Accept the small security drawback and make this script runnable by r-ryantm.
|
||||
|
||||
# This script expects to be called in an interactive terminal somewhere inside Nixpkgs.
|
||||
echo "Preparing..."
|
||||
nixpkgs=$(git rev-parse --show-toplevel)
|
||||
xenPath="$nixpkgs/pkgs/applications/virtualization/xen"
|
||||
rm -rf /tmp/xenUpdateScript
|
||||
mkdir /tmp/xenUpdateScript
|
||||
|
||||
# Import and verify PGP key.
|
||||
curl --silent --output /tmp/xenUpdateScript/xen.asc https://keys.openpgp.org/vks/v1/by-fingerprint/23E3222C145F4475FA8060A783FE14C957E82BD9
|
||||
gpg --homedir /tmp/xenUpdateScript/.gnupg --quiet --import /tmp/xenUpdateScript/xen.asc
|
||||
fingerprint="$(gpg --homedir /tmp/xenUpdateScript/.gnupg --with-colons --fingerprint "pgp@xen.org" 2>/dev/null | awk -F: '/^pub:.*/ { getline; print $10}')"
|
||||
echo -e "Please ascertain through multiple external sources that the \e[1;32mXen Project PGP Key Fingerprint\e[0m is indeed \e[1;33m$fingerprint\e[0m. If that is not the case, \e[1;31mexit immediately\e[0m."
|
||||
read -r -p $'Press \e[1;34menter\e[0m to continue with a pre-filled expected fingerprint, or input an arbitrary PGP fingerprint to match with the key\'s fingerprint: ' userInputFingerprint
|
||||
userInputFingerprint=${userInputFingerprint:-"23E3222C145F4475FA8060A783FE14C957E82BD9"}
|
||||
|
||||
# Clone xen.git.
|
||||
echo -e "Cloning \e[1;34mxen.git\e[0m..."
|
||||
git clone --quiet https://xenbits.xenproject.org/git-http/xen.git /tmp/xenUpdateScript/xen
|
||||
cd /tmp/xenUpdateScript/xen
|
||||
|
||||
# Get list of versions and branches.
|
||||
versionList="$(git tag --list "RELEASE-*" | sed s/RELEASE-//g | sed s/4.1.6.1//g | sort --numeric-sort)"
|
||||
latestVersion=$(echo "$versionList" | tr ' ' '\n' | tail --lines=1)
|
||||
branchList=($(echo "$versionList" | tr ' ' '\n' | sed s/\.[0-9]*$//g | awk '!seen[$0]++'))
|
||||
|
||||
# Figure out which versions we're actually going to install.
|
||||
minSupportedBranch="$(grep " minSupportedVersion = " "$xenPath"/generic/default.nix | sed s/' minSupportedVersion = "'//g | sed s/'";'//g)"
|
||||
supportedBranches=($(for version in "${branchList[@]}"; do if [ "$(printf '%s\n' "$minSupportedBranch" "$version" | sort -V | head -n1)" = "$minSupportedBranch" ]; then echo "$version"; fi; done))
|
||||
supportedVersions=($(for version in "${supportedBranches[@]}"; do echo "$versionList" | tr ' ' '\n' | grep "$version" | tail --lines=1; done))
|
||||
|
||||
echo -e "\e[1mNOTE\e[0m: As we're also pre-fetching the submodules, QEMU and OVMF may take a very long time to fetch."
|
||||
|
||||
# Main loop that installs every supportedVersion.
|
||||
for version in "${supportedVersions[@]}"; do
|
||||
echo -e "\n------------------------------------------------"
|
||||
branch=${version/%.[0-9]/}
|
||||
if [[ "$version" == "$latestVersion" ]]; then
|
||||
latest=true
|
||||
echo -e "\nFound \e[1;34mlatest\e[0m release: \e[1;32mXen $version\e[0m in branch \e[1;36m$branch\e[0m."
|
||||
else
|
||||
latest=false
|
||||
echo -e "\nFound \e[1;33msecurity-supported\e[0m release: \e[1;32mXen $version\e[0m in branch \e[1;36m$branch\e[0m."
|
||||
fi
|
||||
|
||||
# Verify PGP key automatically. If the fingerprint matches what the user specified, or the default fingerprint, then we consider it trusted.
|
||||
cd /tmp/xenUpdateScript/xen
|
||||
if [[ "$fingerprint" = "$userInputFingerprint" ]]; then
|
||||
echo "$fingerprint:6:" | gpg --homedir /tmp/xenUpdateScript/.gnupg --quiet --import-ownertrust
|
||||
(git verify-tag RELEASE-"$version" 2>/dev/null && echo -e "\n\e[1;32mSuccessfully authenticated Xen $version.\e[0m") || (echo -e "\e[1;31merror:\e[0m Unable to verify tag \e[1;32mRELEASE-$version\e[0m.\n- It is possible that \e[1;33mthis script has broken\e[0m, the Xen Project has \e[1;33mcycled their PGP keys\e[0m, or a \e[1;31msupply chain attack is in progress\e[0m.\n\n\e[1;31mPlease update manually.\e[0m" && exit 1)
|
||||
else
|
||||
echo -e "\e[1;31merror:\e[0m Unable to verify \e[1;34mpgp@xen.org\e[0m's fingerprint.\n- It is possible that \e[1;33mthis script has broken\e[0m, the Xen Project has \e[1;33mcycled their PGP keys\e[0m, or an \e[1;31mimpersonation attack is in progress\e[0m.\n\n\e[1;31mPlease update manually.\e[0m" && exit 1
|
||||
fi
|
||||
|
||||
git switch --quiet --detach RELEASE-"$version"
|
||||
|
||||
# Originally we told people to go check the Makefile themselves.
|
||||
echo -e -n "\nDetermining source versions from Xen Makefiles..."
|
||||
qemuVersion="$(grep "QEMU_UPSTREAM_REVISION ?=" /tmp/xenUpdateScript/xen/Config.mk | sed s/"QEMU_UPSTREAM_REVISION ?= "//g)"
|
||||
seaBIOSVersion="$(grep "SEABIOS_UPSTREAM_REVISION ?= rel-" /tmp/xenUpdateScript/xen/Config.mk | sed s/"SEABIOS_UPSTREAM_REVISION ?= "//g)"
|
||||
ovmfVersion="$(grep "OVMF_UPSTREAM_REVISION ?=" /tmp/xenUpdateScript/xen/Config.mk | sed s/"OVMF_UPSTREAM_REVISION ?= "//g)"
|
||||
miniOSVersion="$(grep "MINIOS_UPSTREAM_REVISION ?=" /tmp/xenUpdateScript/xen/Config.mk | sed s/"MINIOS_UPSTREAM_REVISION ?= "//g)"
|
||||
ipxeVersion="$(grep "IPXE_GIT_TAG :=" /tmp/xenUpdateScript/xen/tools/firmware/etherboot/Makefile | sed s/"IPXE_GIT_TAG := "//g)"
|
||||
echo "done!"
|
||||
|
||||
# Use `nix-prefetch-git` to fetch `rev`s and `hash`es.
|
||||
echo "Pre-fetching sources and determining hashes..."
|
||||
echo -e -n " \e[1;32mXen\e[0m..."
|
||||
fetchXen=$(nix-prefetch-git --url https://xenbits.xenproject.org/git-http/xen.git --rev RELEASE-"$version" --quiet)
|
||||
finalVersion="$(echo "$fetchXen" | tr ', ' '\n ' | grep -ie rev | sed s/' "rev": "'//g | sed s/'"'//g)"
|
||||
hash="$(echo "$fetchXen" | tr ', ' '\n ' | grep -ie hash | sed s/' "hash": "'//g | sed s/'"'//g)"
|
||||
echo "done!"
|
||||
echo -e -n " \e[1;36mQEMU\e[0m..."
|
||||
fetchQEMU=$(nix-prefetch-git --url https://xenbits.xenproject.org/git-http/qemu-xen.git --rev "$qemuVersion" --quiet --fetch-submodules)
|
||||
finalQEMUVersion="$(echo "$fetchQEMU" | tr ', ' '\n ' | grep -ie rev | sed s/' "rev": "'//g | sed s/'"'//g)"
|
||||
qemuHash="$(echo "$fetchQEMU" | tr ', ' '\n ' | grep -ie hash | sed s/' "hash": "'//g | sed s/'"'//g)"
|
||||
echo "done!"
|
||||
echo -e -n " \e[1;36mSeaBIOS\e[0m..."
|
||||
fetchSeaBIOS=$(nix-prefetch-git --url https://xenbits.xenproject.org/git-http/seabios.git --rev "$seaBIOSVersion" --quiet)
|
||||
finalSeaBIOSVersion="$(echo "$fetchSeaBIOS" | tr ', ' '\n ' | grep -ie rev | sed s/' "rev": "'//g | sed s/'"'//g)"
|
||||
seaBIOSHash="$(echo "$fetchSeaBIOS" | tr ', ' '\n ' | grep -ie hash | sed s/' "hash": "'//g | sed s/'"'//g)"
|
||||
echo "done!"
|
||||
echo -e -n " \e[1;36mOVMF\e[0m..."
|
||||
ovmfHash="$(nix-prefetch-git --url https://xenbits.xenproject.org/git-http/ovmf.git --rev "$ovmfVersion" --quiet --fetch-submodules | grep -ie hash | sed s/' "hash": "'//g | sed s/'",'//g)"
|
||||
echo "done!"
|
||||
echo -e -n " \e[1;36miPXE\e[0m..."
|
||||
ipxeHash="$(nix-prefetch-git --url https://github.com/ipxe/ipxe.git --rev "$ipxeVersion" --quiet | grep -ie hash | sed s/' "hash": "'//g | sed s/'",'//g)"
|
||||
echo "done!"
|
||||
|
||||
cd "$xenPath"
|
||||
|
||||
echo -e "\nFound the following revisions:\n \e[1;32mXen\e[0m: \e[1;33m$finalVersion\e[0m (\e[1;33m$hash\e[0m)\n \e[1;36mQEMU\e[0m: \e[1;33m$finalQEMUVersion\e[0m (\e[1;33m$qemuHash\e[0m)\n \e[1;36mSeaBIOS\e[0m: \e[1;33m$finalSeaBIOSVersion\e[0m (\e[1;33m$seaBIOSHash\e[0m)\n \e[1;36mOVMF\e[0m: \e[1;33m$ovmfVersion\e[0m (\e[1;33m$ovmfHash\e[0m)\n \e[1;36miPXE\e[0m: \e[1;33m$ipxeVersion\e[0m (\e[1;33m$ipxeHash\e[0m)"
|
||||
|
||||
# Set OCaml Version
|
||||
read -r -p $'\nEnter the corresponding \e[1;33mOCaml\e[0m version for \e[1;32mXen '"$version"$'\e[0m, or press \e[1;34menter\e[0m for the default value of \e[1;32m4_14\e[0m: ' ocamlVersion
|
||||
ocamlVersion=${ocamlVersion:-"4_14"}
|
||||
|
||||
mkdir -p "$branch"/
|
||||
rm -f "$branch"/default.nix
|
||||
|
||||
# Prepare any .patch files that are called by Nix through a path value.
|
||||
echo -e "\nPlease add any required patches to version \e[1;32m$branch\e[0m in \e[1;34m$branch/\e[0m, and press \e[1;34menter\e[0m when done."
|
||||
read -r -p $'Remember to follow the naming specification as defined in \e[1;34m./README.md\e[0m.'
|
||||
|
||||
echo -e "\nDiscovering patches..."
|
||||
discoveredXenPatches="$(find "$branch"/ -type f -name "[0-9][0-9][0-9][0-9]-xen-*-$branch.patch" -printf "./%f ")"
|
||||
discoveredQEMUPatches="$(find "$branch"/ -type f -name "[0-9][0-9][0-9][0-9]-qemu-*-$branch.patch" -printf "./%f ")"
|
||||
discoveredSeaBIOSPatches="$(find "$branch"/ -type f -name "[0-9][0-9][0-9][0-9]-seabios-*-$branch.patch" -printf "./%f ")"
|
||||
discoveredOVMFPatches="$(find "$branch"/ -type f -name "[0-9][0-9][0-9][0-9]-ovmf-*-$branch.patch" -printf "./%f ")"
|
||||
discoveredIPXEPatches="$(find "$branch"/ -type f -name "[0-9][0-9][0-9][0-9]-ipxe-*-$branch.patch" -printf "./%f ")"
|
||||
|
||||
discoveredXenPatchesEcho=${discoveredXenPatches:-"\e[1;31mNone found!\e[0m"}
|
||||
discoveredQEMUPatchesEcho=${discoveredQEMUPatches:-"\e[1;31mNone found!\e[0m"}
|
||||
discoveredSeaBIOSPatchesEcho=${discoveredSeaBIOSPatches:-"\e[1;31mNone found!\e[0m"}
|
||||
discoveredOVMFPatchesEcho=${discoveredOVMFPatches:-"\e[1;31mNone found!\e[0m"}
|
||||
discoveredIPXEPatchesEcho=${discoveredIPXEPatches:-"\e[1;31mNone found!\e[0m"}
|
||||
|
||||
echo -e "Found the following patches:\n \e[1;32mXen\e[0m: \e[1;33m$discoveredXenPatchesEcho\e[0m\n \e[1;36mQEMU\e[0m: \e[1;33m$discoveredQEMUPatchesEcho\e[0m\n \e[1;36mSeaBIOS\e[0m: \e[1;33m$discoveredSeaBIOSPatchesEcho\e[0m\n \e[1;36mOVMF\e[0m: \e[1;33m$discoveredOVMFPatchesEcho\e[0m\n \e[1;36miPXE\e[0m: \e[1;33m$discoveredIPXEPatchesEcho\e[0m"
|
||||
|
||||
# Prepare patches that are called in ./patches.nix.
|
||||
defaultPatchListInit=("QUBES_REPRODUCIBLE_BUILDS" "XSA_460" "XSA_461" )
|
||||
read -r -a defaultPatchList -p $'\nWould you like to override the \e[1;34mupstreamPatches\e[0m list for \e[1;32mXen '"$version"$'\e[0m? If no, press \e[1;34menter\e[0m to use the default patch list: [ \e[1;34m'"${defaultPatchListInit[*]}"$' \e[0m]: '
|
||||
defaultPatchList=(${defaultPatchList[@]:-${defaultPatchListInit[@]}})
|
||||
upstreamPatches=${defaultPatchList[*]}
|
||||
|
||||
# Write and format default.nix file.
|
||||
echo -e -n "\nWriting updated \e[1;34mversionDefinition\e[0m..."
|
||||
cat >"$branch"/default.nix <<EOF
|
||||
{
|
||||
lib,
|
||||
fetchpatch,
|
||||
callPackage,
|
||||
ocaml-ng,
|
||||
...
|
||||
}@genericDefinition:
|
||||
|
||||
let
|
||||
upstreamPatches = import ../generic/patches.nix {
|
||||
inherit lib;
|
||||
inherit fetchpatch;
|
||||
};
|
||||
|
||||
upstreamPatchList = lib.lists.flatten (with upstreamPatches; [
|
||||
$upstreamPatches
|
||||
]);
|
||||
in
|
||||
|
||||
callPackage (import ../generic/default.nix {
|
||||
pname = "xen";
|
||||
branch = "$branch";
|
||||
version = "$version";
|
||||
latest = $latest;
|
||||
pkg = {
|
||||
xen = {
|
||||
rev = "$finalVersion";
|
||||
hash = "$hash";
|
||||
patches = [ $discoveredXenPatches ] ++ upstreamPatchList;
|
||||
};
|
||||
qemu = {
|
||||
rev = "$finalQEMUVersion";
|
||||
hash = "$qemuHash";
|
||||
patches = [ $discoveredQEMUPatches ];
|
||||
};
|
||||
seaBIOS = {
|
||||
rev = "$finalSeaBIOSVersion";
|
||||
hash = "$seaBIOSHash";
|
||||
patches = [ $discoveredSeaBIOSPatches ];
|
||||
};
|
||||
ovmf = {
|
||||
rev = "$ovmfVersion";
|
||||
hash = "$ovmfHash";
|
||||
patches = [ $discoveredOVMFPatches ];
|
||||
};
|
||||
ipxe = {
|
||||
rev = "$ipxeVersion";
|
||||
hash = "$ipxeHash";
|
||||
patches = [ $discoveredIPXEPatches ];
|
||||
};
|
||||
};
|
||||
}) ({ ocamlPackages = ocaml-ng.ocamlPackages_$ocamlVersion; } // genericDefinition)
|
||||
EOF
|
||||
echo done!
|
||||
|
||||
echo -n "Formatting..."
|
||||
nixfmt "$branch"/default.nix
|
||||
echo done!
|
||||
|
||||
echo -e "\n\e[1;32mSuccessfully produced $branch/default.nix.\e[0m"
|
||||
done
|
||||
|
||||
echo -e -n "\nCleaning up..."
|
||||
rm -rf /tmp/xenUpdateScript
|
||||
echo done!
|
||||
@@ -0,0 +1,495 @@
|
||||
{
|
||||
lib,
|
||||
stdenv,
|
||||
autoPatchelfHook,
|
||||
cmake,
|
||||
pkg-config,
|
||||
testers,
|
||||
which,
|
||||
fetchgit,
|
||||
fetchpatch,
|
||||
|
||||
# Xen
|
||||
acpica-tools,
|
||||
bison,
|
||||
bzip2,
|
||||
dev86,
|
||||
e2fsprogs,
|
||||
flex,
|
||||
libnl,
|
||||
libuuid,
|
||||
lzo,
|
||||
ncurses,
|
||||
ocamlPackages,
|
||||
perl,
|
||||
python3Packages,
|
||||
systemdMinimal,
|
||||
xz,
|
||||
yajl,
|
||||
zlib,
|
||||
zstd,
|
||||
|
||||
# Optional Components
|
||||
seabios,
|
||||
OVMF,
|
||||
ipxe,
|
||||
checkpolicy,
|
||||
binutils-unwrapped,
|
||||
|
||||
# Documentation
|
||||
pandoc,
|
||||
|
||||
# Scripts
|
||||
bridge-utils,
|
||||
coreutils,
|
||||
diffutils,
|
||||
gawk,
|
||||
gnugrep,
|
||||
gnused,
|
||||
inetutils,
|
||||
iproute2,
|
||||
iptables,
|
||||
multipath-tools,
|
||||
nbd,
|
||||
openvswitch,
|
||||
util-linux,
|
||||
}:
|
||||
|
||||
{
|
||||
pname,
|
||||
branch ? lib.versions.majorMinor version,
|
||||
version,
|
||||
vendor ? "nixos",
|
||||
withEFI ? true,
|
||||
withFlask ? false,
|
||||
withSeaBIOS ? true,
|
||||
withOVMF ? true,
|
||||
withIPXE ? true,
|
||||
useDefaultPatchList ? true,
|
||||
rev,
|
||||
hash,
|
||||
patches ? [ ],
|
||||
meta ? { },
|
||||
}:
|
||||
|
||||
let
|
||||
# Inherit helper functions from lib and builtins.
|
||||
inherit (builtins) elemAt isAttrs;
|
||||
inherit (lib.strings)
|
||||
concatLines
|
||||
enableFeature
|
||||
makeSearchPathOutput
|
||||
optionalString
|
||||
removeSuffix
|
||||
versionOlder
|
||||
;
|
||||
inherit (lib.platforms) linux aarch64;
|
||||
inherit (lib) teams;
|
||||
inherit (lib.licenses)
|
||||
cc-by-40
|
||||
gpl2Only
|
||||
lgpl21Only
|
||||
mit
|
||||
;
|
||||
inherit (lib.meta) getExe;
|
||||
inherit (lib.lists)
|
||||
count
|
||||
flatten
|
||||
optional
|
||||
optionals
|
||||
range
|
||||
remove
|
||||
zipListsWith
|
||||
;
|
||||
inherit (lib.attrsets) attrByPath;
|
||||
|
||||
# Mark versions older than minSupportedVersion as EOL.
|
||||
minSupportedVersion = "4.16";
|
||||
|
||||
## Generic Patch Handling ##
|
||||
|
||||
upstreamPatches = import ./patches.nix {
|
||||
inherit lib fetchpatch;
|
||||
};
|
||||
|
||||
upstreamPatchList = flatten (
|
||||
with upstreamPatches;
|
||||
[
|
||||
QUBES_REPRODUCIBLE_BUILDS
|
||||
XSA_460
|
||||
XSA_461
|
||||
XSA_462
|
||||
]
|
||||
);
|
||||
|
||||
## XSA Patches Description Builder ##
|
||||
|
||||
# Simple counter for the number of attrsets (patches) in the patches list after normalisation.
|
||||
numberOfPatches = count (patch: isAttrs patch) upstreamPatchList;
|
||||
|
||||
# builtins.elemAt's index begins at 0, so we subtract 1 from the number of patches in order to
|
||||
# produce the range that will be used in the following builtin.map calls.
|
||||
availablePatchesToTry = range 0 (numberOfPatches - 1);
|
||||
|
||||
# Takes in an attrByPath input, and outputs the attribute value for each patch in a list.
|
||||
# If a patch does not have a given attribute, returns `null`. Use lib.lists.remove null
|
||||
# to remove these junk values, if necessary.
|
||||
retrievePatchAttributes =
|
||||
attributeName:
|
||||
map (x: attrByPath attributeName null (elemAt upstreamPatchList x)) availablePatchesToTry;
|
||||
|
||||
# Produces a list of newline-separated strings that lists the vulnerabilities this
|
||||
# Xen is NOT affected by, due to the applied Xen Security Advisory patches. This is
|
||||
# then used in meta.longDescription, to let users know their Xen is patched against
|
||||
# known vulnerabilities, as the package version isn't always the best indicator.
|
||||
#
|
||||
# Produces something like this: (one string for each XSA)
|
||||
# * [Xen Security Advisory #1](https://xenbits.xenproject.org/xsa/advisory-1.html): **Title for XSA.**
|
||||
# >Description of issue in XSA
|
||||
#Extra lines
|
||||
#are not indented,
|
||||
#but markdown should be
|
||||
#fine with it.
|
||||
# Fixes:
|
||||
# * [CVE-1999-00001](https://www.cve.org/CVERecord?id=CVE-1999-00001)
|
||||
# * [CVE-1999-00002](https://www.cve.org/CVERecord?id=CVE-1999-00002)
|
||||
# * [CVE-1999-00003](https://www.cve.org/CVERecord?id=CVE-1999-00003)
|
||||
writeAdvisoryDescription =
|
||||
if (remove null (retrievePatchAttributes [ "xsa" ]) != [ ]) then
|
||||
zipListsWith (a: b: a + b)
|
||||
(zipListsWith (a: b: a + "**" + b + ".**\n >")
|
||||
(zipListsWith (a: b: "* [Xen Security Advisory #" + a + "](" + b + "): ")
|
||||
(remove null (retrievePatchAttributes [ "xsa" ]))
|
||||
(
|
||||
remove null (retrievePatchAttributes [
|
||||
"meta"
|
||||
"homepage"
|
||||
])
|
||||
)
|
||||
)
|
||||
(
|
||||
remove null (retrievePatchAttributes [
|
||||
"meta"
|
||||
"description"
|
||||
])
|
||||
)
|
||||
)
|
||||
(
|
||||
remove null (retrievePatchAttributes [
|
||||
"meta"
|
||||
"longDescription"
|
||||
])
|
||||
)
|
||||
else
|
||||
[ ];
|
||||
|
||||
## Binutils Override ##
|
||||
|
||||
# Originally, there were two versions of binutils being used: the standard one and
|
||||
# this patched one. Unfortunately, that required patches to the Xen Makefiles, and
|
||||
# quickly became too complex to maintain. The new solution is to simply build this
|
||||
# efi-binutils derivation and use it for the whole build process, except if
|
||||
# enableEFI is disabled; it'll then use `binutils`.
|
||||
efiBinutils = binutils-unwrapped.overrideAttrs (oldAttrs: {
|
||||
name = "efi-binutils";
|
||||
configureFlags = oldAttrs.configureFlags ++ [ "--enable-targets=x86_64-pep" ];
|
||||
doInstallCheck = false; # We get a spurious failure otherwise, due to a host/target mismatch.
|
||||
meta.mainProgram = "ld"; # We only really care for `ld`.
|
||||
});
|
||||
|
||||
#TODO: fix paths instead.
|
||||
scriptEnvPath = makeSearchPathOutput "out" "bin" [
|
||||
bridge-utils
|
||||
coreutils
|
||||
diffutils
|
||||
gawk
|
||||
gnugrep
|
||||
gnused
|
||||
inetutils
|
||||
iproute2
|
||||
iptables
|
||||
multipath-tools
|
||||
nbd
|
||||
openvswitch
|
||||
perl
|
||||
util-linux.bin
|
||||
which
|
||||
];
|
||||
in
|
||||
|
||||
stdenv.mkDerivation (finalAttrs: {
|
||||
inherit pname version;
|
||||
|
||||
# TODO: Split $out in $bin for binaries and $lib for libraries.
|
||||
# TODO: Python package to be in separate output/package.
|
||||
outputs = [
|
||||
"out"
|
||||
"man"
|
||||
"doc"
|
||||
"dev"
|
||||
"boot"
|
||||
];
|
||||
|
||||
# Main Xen source.
|
||||
src = fetchgit {
|
||||
url = "https://xenbits.xenproject.org/git-http/xen.git";
|
||||
inherit rev hash;
|
||||
};
|
||||
|
||||
patches = optionals useDefaultPatchList upstreamPatchList ++ patches;
|
||||
|
||||
nativeBuildInputs = [
|
||||
autoPatchelfHook
|
||||
bison
|
||||
cmake
|
||||
flex
|
||||
pandoc
|
||||
pkg-config
|
||||
python3Packages.setuptools
|
||||
];
|
||||
buildInputs = [
|
||||
# Xen
|
||||
acpica-tools
|
||||
bzip2
|
||||
dev86
|
||||
e2fsprogs.dev
|
||||
libnl
|
||||
libuuid
|
||||
lzo
|
||||
ncurses
|
||||
perl
|
||||
python3Packages.python
|
||||
xz
|
||||
yajl
|
||||
zlib
|
||||
zstd
|
||||
|
||||
# oxenstored
|
||||
ocamlPackages.findlib
|
||||
ocamlPackages.ocaml
|
||||
|
||||
# Python Fixes
|
||||
python3Packages.wrapPython
|
||||
] ++ optional withFlask checkpolicy ++ optional (versionOlder version "4.19") systemdMinimal;
|
||||
|
||||
configureFlags = [
|
||||
"--enable-systemd"
|
||||
"--disable-qemu-traditional"
|
||||
"--with-system-qemu"
|
||||
(if withSeaBIOS then "--with-system-seabios=${seabios}/share/seabios" else "--disable-seabios")
|
||||
(if withOVMF then "--with-system-ovmf=${OVMF.firmware}" else "--disable-ovmf")
|
||||
(if withIPXE then "--with-system-ipxe=${ipxe}" else "--disable-ipxe")
|
||||
(enableFeature withFlask "xsmpolicy")
|
||||
];
|
||||
|
||||
makeFlags =
|
||||
[
|
||||
"SUBSYSTEMS=${toString finalAttrs.buildFlags}"
|
||||
|
||||
"PREFIX=$(out)"
|
||||
"BASH_COMPLETION_DIR=$(PREFIX)/share/bash-completion/completions"
|
||||
|
||||
"XEN_WHOAMI=${pname}"
|
||||
"XEN_DOMAIN=${vendor}"
|
||||
|
||||
"GIT=${coreutils}/bin/false"
|
||||
"WGET=${coreutils}/bin/false"
|
||||
]
|
||||
++ optionals withEFI [
|
||||
"EFI_VENDOR=${vendor}"
|
||||
"INSTALL_EFI_STRIP=1"
|
||||
"LD=${getExe efiBinutils}" # See the comment in the efiBinutils definition above.
|
||||
]
|
||||
# These flags set the CONFIG_* options in /boot/xen.config
|
||||
# and define if the default policy file is built. However,
|
||||
# the Flask binaries always get compiled by default.
|
||||
++ optionals withFlask [
|
||||
"XSM_ENABLE=y"
|
||||
"FLASK_ENABLE=y"
|
||||
];
|
||||
|
||||
buildFlags = [
|
||||
"xen"
|
||||
"tools"
|
||||
"docs"
|
||||
];
|
||||
|
||||
enableParallelBuilding = true;
|
||||
|
||||
env.NIX_CFLAGS_COMPILE = toString [
|
||||
"-Wno-error=maybe-uninitialized"
|
||||
"-Wno-error=array-bounds"
|
||||
];
|
||||
|
||||
dontUseCmakeConfigure = true;
|
||||
|
||||
# Remove in-tree QEMU sources, we don't need them in any circumstance.
|
||||
prePatch = "rm --recursive --force tools/qemu-xen tools/qemu-xen-traditional";
|
||||
|
||||
postPatch =
|
||||
# The following patch forces Xen to install xen.efi on $out/boot
|
||||
# instead of $out/boot/efi/efi/nixos, as the latter directory
|
||||
# would otherwise need to be created manually. This also creates
|
||||
# a more consistent output for downstreams who override the
|
||||
# vendor attribute above.
|
||||
''
|
||||
substituteInPlace xen/Makefile \
|
||||
--replace-fail "\$(D)\$(EFI_MOUNTPOINT)/efi/\$(EFI_VENDOR)/\$(T)-\$(XEN_FULLVERSION).efi" \
|
||||
"\$(D)\$(BOOT_DIR)/\$(T)-\$(XEN_FULLVERSION).efi"
|
||||
''
|
||||
|
||||
# The following patch fixes the call to /bin/mkdir on the
|
||||
# launch_xenstore.sh helper script.
|
||||
+ ''
|
||||
substituteInPlace tools/hotplug/Linux/launch-xenstore.in \
|
||||
--replace-fail "/bin/mkdir" "${coreutils}/bin/mkdir"
|
||||
''
|
||||
|
||||
# The following expression fixes the paths called by Xen's systemd
|
||||
# units, so we can use them in the NixOS module.
|
||||
+ ''
|
||||
substituteInPlace \
|
||||
tools/hotplug/Linux/systemd/{xen-init-dom0,xen-qemu-dom0-disk-backend,xenconsoled,xendomains,xenstored}.service.in \
|
||||
--replace-fail /bin/grep ${gnugrep}/bin/grep
|
||||
substituteInPlace \
|
||||
tools/hotplug/Linux/systemd/{xen-qemu-dom0-disk-backend,xenconsoled}.service.in \
|
||||
--replace-fail "/bin/mkdir" "${coreutils}/bin/mkdir"
|
||||
'';
|
||||
|
||||
installPhase = ''
|
||||
runHook preInstall
|
||||
|
||||
mkdir --parents $out $out/share $boot
|
||||
cp -prvd dist/install/nix/store/*/* $out/
|
||||
cp -prvd dist/install/etc $out
|
||||
cp -prvd dist/install/boot $boot
|
||||
|
||||
runHook postInstall
|
||||
'';
|
||||
|
||||
postInstall =
|
||||
# Wrap xencov_split, xenmon and xentrace_format.
|
||||
''
|
||||
wrapPythonPrograms
|
||||
''
|
||||
|
||||
# We also need to wrap pygrub, which lies in $out/libexec/xen/bin.
|
||||
+ ''
|
||||
wrapPythonProgramsIn "$out/libexec/xen/bin" "$out $pythonPath"
|
||||
''
|
||||
|
||||
# Fix shebangs in Xen's various scripts.
|
||||
#TODO: Remove any and all usage of `sed` and replace these complicated magic runes with readable code.
|
||||
+ ''
|
||||
shopt -s extglob
|
||||
for i in $out/etc/xen/scripts/!(*.sh); do
|
||||
sed --in-place "2s@^@export PATH=$out/bin:${scriptEnvPath}\n@" $i
|
||||
done
|
||||
'';
|
||||
|
||||
postFixup =
|
||||
''
|
||||
addAutoPatchelfSearchPath $out/lib
|
||||
autoPatchelf $out/libexec/xen/bin
|
||||
''
|
||||
# Flask is particularly hard to disable. Even after
|
||||
# setting the make flags to `n`, it still gets compiled.
|
||||
# If withFlask is disabled, delete the extra binaries.
|
||||
+ optionalString (!withFlask) ''
|
||||
rm -f $out/bin/flask-*
|
||||
'';
|
||||
|
||||
passthru = {
|
||||
efi =
|
||||
if withEFI then "boot/xen-${version}.efi" else throw "This Xen was compiled without an EFI binary.";
|
||||
flaskPolicy =
|
||||
if withFlask then
|
||||
"boot/xenpolicy-${version}"
|
||||
else
|
||||
throw "This Xen was compiled without FLASK support.";
|
||||
# This test suite is very simple, as Xen's userspace
|
||||
# utilities require the hypervisor to be booted.
|
||||
tests = {
|
||||
pkg-config = testers.hasPkgConfigModules {
|
||||
package = finalAttrs.finalPackage;
|
||||
moduleNames = [
|
||||
"xencall"
|
||||
"xencontrol"
|
||||
"xendevicemodel"
|
||||
"xenevtchn"
|
||||
"xenforeignmemory"
|
||||
"xengnttab"
|
||||
"xenguest"
|
||||
"xenhypfs"
|
||||
"xenlight"
|
||||
"xenstat"
|
||||
"xenstore"
|
||||
"xentoolcore"
|
||||
"xentoollog"
|
||||
"xenvchan"
|
||||
"xlutil"
|
||||
];
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
meta = {
|
||||
inherit branch;
|
||||
|
||||
description = "Type-1 hypervisor intended for embedded and hyperscale use cases";
|
||||
longDescription =
|
||||
''
|
||||
The Xen Project Hypervisor is a virtualisation technology defined as a *type-1
|
||||
hypervisor*, which allows multiple virtual machines, known as domains, to run
|
||||
concurrently with the host on the physical machine. On a typical *type-2
|
||||
hypervisor*, the virtual machines run as applications on top of the
|
||||
host. NixOS runs as the privileged **Domain 0**, and can paravirtualise or fully
|
||||
virtualise **Unprivileged Domains**.
|
||||
|
||||
Use with the `qemu_xen` package.
|
||||
''
|
||||
# Then, if any of the optional with* components are being built, add the "Includes:" string.
|
||||
+ optionalString (withEFI || withFlask) (
|
||||
"\nIncludes:"
|
||||
# Originally, this was a call for the complicated withPrefetchedSources. Since there aren't
|
||||
# that many optional components, we just use lib.strings.optionalString, because it's simpler.
|
||||
# Optional components that aren't being built are automatically hidden.
|
||||
+ optionalString withEFI "\n* `xen.efi`: The Xen Project's [EFI binary](https://xenbits.xenproject.org/docs/${branch}-testing/misc/efi.html), available on the `boot` output of this package."
|
||||
+ optionalString withFlask "\n* `xsm-flask`: The [FLASK Xen Security Module](https://wiki.xenproject.org/wiki/Xen_Security_Modules_:_XSM-FLASK). The `xenpolicy-${version}` file is available on the `boot` output of this package."
|
||||
+ optionalString withSeaBIOS "\n* `seabios`: Support for the SeaBIOS boot firmware on HVM domains."
|
||||
+ optionalString withOVMF "\n* `ovmf`: Support for the OVMF UEFI boot firmware on HVM domains."
|
||||
+ optionalString withIPXE "\n* `ipxe`: Support for the iPXE boot firmware on HVM domains."
|
||||
)
|
||||
# Finally, we write a notice explaining which vulnerabilities this Xen is NOT vulnerable to.
|
||||
# This will hopefully give users the peace of mind that their Xen is secure, without needing
|
||||
# to search the source code for the XSA patches.
|
||||
+ optionalString (writeAdvisoryDescription != [ ]) (
|
||||
"\n\nThis Xen Project Hypervisor (${version}) has been patched against the following known security vulnerabilities:\n"
|
||||
+ removeSuffix "\n" (concatLines writeAdvisoryDescription)
|
||||
);
|
||||
|
||||
homepage = "https://xenproject.org/";
|
||||
downloadPage = "https://downloads.xenproject.org/release/xen/${version}/";
|
||||
changelog = "https://wiki.xenproject.org/wiki/Xen_Project_${branch}_Release_Notes";
|
||||
|
||||
license = [
|
||||
# Documentation.
|
||||
cc-by-40
|
||||
# Most of Xen is licensed under the GPL v2.0.
|
||||
gpl2Only
|
||||
# Xen Libraries and the `xl` command-line utility.
|
||||
lgpl21Only
|
||||
# Development headers in $dev/include.
|
||||
mit
|
||||
];
|
||||
|
||||
maintainers = teams.xen.members;
|
||||
knownVulnerabilities = optional (versionOlder version minSupportedVersion) "The Xen Project Hypervisor version ${version} is no longer supported by the Xen Project Security Team. See https://xenbits.xenproject.org/docs/unstable/support-matrix.html";
|
||||
|
||||
mainProgram = "xl";
|
||||
|
||||
#TODO: Migrate meta.platforms to the new lib.systems.inspect.patterns.* format.
|
||||
platforms = linux;
|
||||
badPlatforms = aarch64;
|
||||
} // meta;
|
||||
})
|
||||
+5
-5
@@ -6,6 +6,9 @@
|
||||
{ lib, fetchpatch }:
|
||||
|
||||
let
|
||||
inherit (builtins) concatStringsSep;
|
||||
inherit (lib.strings) optionalString concatMapStrings;
|
||||
|
||||
xsaPatch =
|
||||
{
|
||||
id,
|
||||
@@ -16,8 +19,7 @@ let
|
||||
cve ? null,
|
||||
}:
|
||||
(fetchpatch {
|
||||
name =
|
||||
"XSA-" + id + lib.strings.optionalString (cve != null) ("-" + builtins.concatStringsSep "+" cve);
|
||||
name = "XSA-" + id + optionalString (cve != null) ("-" + concatStringsSep "+" cve);
|
||||
url = "https://xenbits.xen.org/xsa/xsa${id}.patch";
|
||||
inherit hash;
|
||||
passthru = {
|
||||
@@ -37,9 +39,7 @@ let
|
||||
" _No CVE was assigned to this XSA._"
|
||||
else
|
||||
" Fixes:${
|
||||
lib.strings.concatMapStrings (
|
||||
x: "\n * [" + x + "](https://www.cve.org/CVERecord?id=" + x + ")"
|
||||
) cve
|
||||
concatMapStrings (x: "\n * [" + x + "](https://www.cve.org/CVERecord?id=" + x + ")") cve
|
||||
}"
|
||||
);
|
||||
homepage = "https://xenbits.xenproject.org/xsa/advisory-${id}.html";
|
||||
@@ -19,7 +19,7 @@
|
||||
libkvmi,
|
||||
|
||||
xenSupport ? true,
|
||||
xen-slim,
|
||||
xen,
|
||||
}:
|
||||
|
||||
let
|
||||
@@ -58,7 +58,7 @@ stdenv.mkDerivation {
|
||||
json_c
|
||||
libvirt
|
||||
]
|
||||
++ lib.optionals xenSupport [ xen-slim ]
|
||||
++ lib.optionals xenSupport [ xen ]
|
||||
++ lib.optionals (!legacyKVM) [ libkvmi ]
|
||||
++ lib.optionals withVMIFS [ fuse ];
|
||||
|
||||
@@ -71,7 +71,7 @@ stdenv.mkDerivation {
|
||||
postFixup = lib.optionalString xenSupport ''
|
||||
libvmi="$lib/lib/libvmi.so.${libVersion}"
|
||||
oldrpath=$(patchelf --print-rpath "$libvmi")
|
||||
patchelf --set-rpath "$oldrpath:${lib.makeLibraryPath [ xen-slim ]}" "$libvmi"
|
||||
patchelf --set-rpath "$oldrpath:${lib.makeLibraryPath [ xen ]}" "$libvmi"
|
||||
'';
|
||||
|
||||
passthru = {
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
{ qemu }: qemu.override { xenSupport = true; }
|
||||
@@ -4,7 +4,7 @@
|
||||
rustPlatform,
|
||||
llvmPackages,
|
||||
pkg-config,
|
||||
xen-slim,
|
||||
xen,
|
||||
}:
|
||||
rustPlatform.buildRustPackage rec {
|
||||
pname = "xen-guest-agent";
|
||||
@@ -25,7 +25,7 @@ rustPlatform.buildRustPackage rec {
|
||||
pkg-config
|
||||
];
|
||||
|
||||
buildInputs = [ xen-slim ];
|
||||
buildInputs = [ xen ];
|
||||
|
||||
postInstall =
|
||||
# Install the sample systemd service.
|
||||
@@ -38,7 +38,7 @@ rustPlatform.buildRustPackage rec {
|
||||
|
||||
postFixup =
|
||||
# Add the Xen libraries in the runpath so the guest agent can find libxenstore.
|
||||
"patchelf $out/bin/xen-guest-agent --add-rpath ${xen-slim.out}/lib";
|
||||
"patchelf $out/bin/xen-guest-agent --add-rpath ${xen}/lib";
|
||||
|
||||
meta = {
|
||||
description = "Xen agent running in Linux/BSDs (POSIX) VMs";
|
||||
|
||||
@@ -0,0 +1,133 @@
|
||||
<p align="center">
|
||||
<a href="https://xenproject.org/">
|
||||
<picture>
|
||||
<source
|
||||
media="(prefers-color-scheme: light)"
|
||||
srcset="https://downloads.xenproject.org/Branding/Logos/Green+Black/xen_project_logo_dualcolor_2000x832.png">
|
||||
<source
|
||||
media="(prefers-color-scheme: dark)"
|
||||
srcset="https://xenproject.org/wp-content/uploads/sites/79/2018/09/logo_xenproject.png">
|
||||
<img
|
||||
src="https://downloads.xenproject.org/Branding/Logos/Green+Black/xen_project_logo_dualcolor_2000x832.png"
|
||||
width="512px"
|
||||
alt="Xen Project Logo">
|
||||
</picture>
|
||||
</a>
|
||||
</p>
|
||||
|
||||
# Xen Project Hypervisor <a href="https://xenproject.org/"><img src="https://downloads.xenproject.org/Branding/Mascots/Xen-Fu-Panda-2000px.png" width="48px" align="top" alt="Xen Fu Panda"></a>
|
||||
|
||||
This directory begins the [Xen Project Hypervisor](https://xenproject.org/) build process.
|
||||
|
||||
Some other notable packages that compose the Xen Project Ecosystem include:
|
||||
|
||||
- `ocamlPackages.xenstore`: Mirage's `oxenstore` implementation.
|
||||
- `ocamlPackages.vchan`: Mirage's `xen-vchan` implementation.
|
||||
- `ocamlPackages.xenstore-tool`: XAPI's `oxenstore` utilities.
|
||||
- `xen-guest-agent`: Guest drivers for UNIX domUs.
|
||||
- `win-pvdrivers`: Guest drivers for Windows domUs.
|
||||
- `xtf`: The Xen Test Framework.
|
||||
|
||||
## Updating
|
||||
|
||||
### Manually
|
||||
|
||||
1. [Update](https://xenbits.xenproject.org/gitweb/) the `package.nix` file for
|
||||
the latest branch of Xen.
|
||||
- Do not forget to set the `branch`, `version`, and `latest` attributes.
|
||||
- The revisions are preferably commit hashes, but tag names are acceptable
|
||||
as well.
|
||||
1. Make sure it builds.
|
||||
1. Use the NixOS module to test if dom0 boots successfully on the new version.
|
||||
1. Make sure the `meta` attributes evaluate to something that makes sense. The
|
||||
following one-line command is useful for testing this:
|
||||
|
||||
```console
|
||||
echo -e "\033[1m$(nix eval .#xen.meta.description --raw 2> /dev/null)\033[0m\n\n$(nix eval .#xen.meta.longDescription --raw 2> /dev/null)"
|
||||
```
|
||||
|
||||
1. Run `xtf --all --host` as root when booted into the Xen update, and make
|
||||
sure no important tests fail.
|
||||
1. Clean up your changes and commit them, making sure to follow the
|
||||
[Nixpkgs Contribution Guidelines](../../../../CONTRIBUTING.md).
|
||||
1. Open a PR and await a review from the current maintainers.
|
||||
|
||||
## Features
|
||||
|
||||
### Generic Builder
|
||||
|
||||
`buildXenPackage` is a helpful utility capable of building Xen when passed
|
||||
certain attributes. The `package.nix` file on this directory includes all
|
||||
important attributes for building a Xen package with Nix. Downstreams can
|
||||
pin their Xen revision or include extra patches if the default Xen package
|
||||
does not meet their needs.
|
||||
|
||||
### EFI
|
||||
|
||||
Building `xen.efi` requires an `ld` with PE support.[^2]
|
||||
|
||||
We use a `makeFlag` to override the `$LD` environment variable to point to our
|
||||
patched `efiBinutils`. For more information, see the comment in `pkgs/build-support/xen/default.nix`.
|
||||
|
||||
> [!TIP]
|
||||
> If you are certain you will not be running Xen in an x86 EFI environment, disable
|
||||
the `withEFI` flag with an [override](https://nixos.org/manual/nixpkgs/stable/#chap-overrides)
|
||||
to save you the need to compile `efiBinutils`.
|
||||
|
||||
## Security
|
||||
|
||||
We aim to support the **latest** version of Xen at any given time.
|
||||
See the [Xen Support Matrix](https://xenbits.xen.org/docs/unstable/support-matrix.html)
|
||||
for a list of versions. As soon as a version is no longer the newest, it should
|
||||
be removed from Nixpkgs (`master`). If you need earlier versions of Xen, consider
|
||||
building your own Xen by following the instructions in the **Generic Builder**
|
||||
section.
|
||||
|
||||
> [!CAUTION]
|
||||
> Pull requests that introduce XSA patches
|
||||
should have the `1.severity: security` label.
|
||||
|
||||
### Maintainers
|
||||
|
||||
Xen is a particularly complex piece of software, so we are always looking for new
|
||||
maintainers. Help out by [making and triaging issues](https://github.com/NixOS/nixpkgs/issues/new/choose),
|
||||
[sending build fixes and improvements through PRs](https://github.com/NixOS/nixpkgs/compare),
|
||||
updating the branches, and [patching security flaws](https://xenbits.xenproject.org/xsa/).
|
||||
|
||||
We are also looking for testers, particularly those who can test Xen on AArch64
|
||||
machines. Open issues for any build failures or runtime errors you find!
|
||||
|
||||
## Tests
|
||||
|
||||
So far, we only have had one simple automated test that checks for
|
||||
the correct `pkg-config` output files.
|
||||
|
||||
Due to Xen's nature as a type-1 hypervisor, it is not a trivial matter to design
|
||||
new tests, as even basic functionality requires a machine booted in a dom0
|
||||
kernel. For this reason, most testing done with this package must be done
|
||||
manually in a NixOS machine with `virtualisation.xen.enable` set to `true`.
|
||||
|
||||
Another unfortunate thing is that none of the Xen commands have a `--version`
|
||||
flag. This means that `testers.testVersion` cannot ascertain the Xen version.
|
||||
The only way to verify that you have indeed built the correct version is to
|
||||
boot into the freshly built Xen kernel and run `xl info`.
|
||||
|
||||
<p align="center">
|
||||
<a href="https://xenproject.org/">
|
||||
<img
|
||||
src="https://downloads.xenproject.org/Branding/Mascots/Xen%20Big%20Panda%204242x3129.png"
|
||||
width="96px"
|
||||
alt="Xen Fu Panda">
|
||||
</a>
|
||||
</p>
|
||||
|
||||
[^1]: We also produce fake `git`, `wget` and `hostname` binaries that do nothing,
|
||||
to prevent the build from failing because Xen cannot fetch the sources that
|
||||
were already fetched by Nix.
|
||||
[^2]: From the [Xen Documentation](https://xenbits.xenproject.org/docs/unstable/misc/efi.html):
|
||||
> For x86, building `xen.efi` requires `gcc` 4.5.x or above (4.6.x or newer
|
||||
recommended, as 4.5.x was probably never really tested for this purpose)
|
||||
and `binutils` 2.22 or newer. Additionally, the `binutils` build must be
|
||||
configured to include support for the x86_64-pep emulation (i.e.
|
||||
`--enable-targets=x86_64-pep` or an option of equivalent effect should be
|
||||
passed to the configure script).
|
||||
@@ -0,0 +1,11 @@
|
||||
{
|
||||
buildXenPackage,
|
||||
python3Packages,
|
||||
}:
|
||||
|
||||
buildXenPackage.override { inherit python3Packages; } {
|
||||
pname = "xen";
|
||||
version = "4.19.0";
|
||||
rev = "026c9fa29716b0ff0f8b7c687908e71ba29cf239";
|
||||
hash = "sha256-Q6x+2fZ4ITBz6sKICI0NHGx773Rc919cl+wzI89UY+Q=";
|
||||
}
|
||||
@@ -1705,6 +1705,12 @@ mapAliases {
|
||||
xcodebuild6 = throw "'xcodebuild6' has been renamed to/replaced by 'xcodebuild'"; # Added 2023-12-10
|
||||
xdg_utils = xdg-utils; # Added 2021-02-01
|
||||
xen-light = throw "'xen-light' has been renamed to/replaced by 'xen-slim'"; # Added 2024-06-30
|
||||
xen-slim = throw "'xen-slim' has been renamed to 'xen'. The old Xen package with built-in components no longer exists"; # Added 2024-10-05
|
||||
xen_4_16 = throw "While Xen 4.16 was still security-supported when it was removed from Nixpkgs, it would have reached its End of Life a couple of days after NixOS 24.11 released. To avoid shipping an insecure version of Xen, the Xen Project Hypervisor Maintenance Team decided to delete the derivation entirely"; # Added 2024-10-05
|
||||
xen_4_17 = throw "Due to technical challenges involving building older versions of Xen with newer dependencies, the Xen Project Hypervisor Maintenance Team decided to switch to a latest-only support cycle. As Xen 4.17 would have been the 'n-2' version, it was removed"; # Added 2024-10-05
|
||||
xen_4_18 = throw "Due to technical challenges involving building older versions of Xen with newer dependencies, the Xen Project Hypervisor Maintenance Team decided to switch to a latest-only support cycle. As Xen 4.18 would have been the 'n-1' version, it was removed"; # Added 2024-10-05
|
||||
xen_4_19 = throw "Use 'xen' instead"; # Added 2024-10-05
|
||||
xenPackages = throw "The attributes in the xenPackages set have been promoted to the top-level. (xenPackages.xen_4_19 -> xen)";
|
||||
xineLib = xine-lib; # Added 2021-04-27
|
||||
xineUI = xine-ui; # Added 2021-04-27
|
||||
xmlada = gnatPackages.xmlada; # Added 2024-02-25
|
||||
|
||||
@@ -26400,13 +26400,6 @@ with pkgs;
|
||||
glusterfsSupport = lib.meta.availableOn stdenv.hostPlatform glusterfs && lib.meta.availableOn stdenv.hostPlatform libuuid;
|
||||
});
|
||||
|
||||
# See `xenPackages` source for explanations.
|
||||
# Building with `xen` instead of `xen-slim` is possible, but makes no sense.
|
||||
qemu_xen_4_19 = lowPrio (qemu.override { hostCpuTargets = [ "i386-softmmu" ]; xenSupport = true; xen = xenPackages.xen_4_19-slim; });
|
||||
qemu_xen_4_18 = lowPrio (qemu.override { hostCpuTargets = [ "i386-softmmu" ]; xenSupport = true; xen = xenPackages.xen_4_18-slim; });
|
||||
qemu_xen_4_17 = lowPrio (qemu.override { hostCpuTargets = [ "i386-softmmu" ]; xenSupport = true; xen = xenPackages.xen_4_17-slim; });
|
||||
qemu_xen = qemu_xen_4_19;
|
||||
|
||||
qemu_test = lowPrio (qemu.override { hostCpuOnly = true; nixosTestRunner = true; });
|
||||
|
||||
quick-lint-js = callPackage ../development/tools/quick-lint-js { };
|
||||
@@ -33834,10 +33827,7 @@ with pkgs;
|
||||
|
||||
xdotool = callPackage ../tools/X11/xdotool { };
|
||||
|
||||
xenPackages = recurseIntoAttrs (callPackage ../applications/virtualization/xen/packages.nix {});
|
||||
|
||||
xen = xenPackages.xen_4_19;
|
||||
xen-slim = xenPackages.xen_4_19-slim;
|
||||
buildXenPackage = callPackage ../build-support/xen { };
|
||||
|
||||
xkbset = callPackage ../tools/X11/xkbset { };
|
||||
|
||||
|
||||
@@ -17590,7 +17590,7 @@ self: super: with self; {
|
||||
inherit (pkgs) graphviz;
|
||||
};
|
||||
|
||||
xen = toPythonModule (pkgs.xen-slim.override {
|
||||
xen = toPythonModule (pkgs.xen.override {
|
||||
python3Packages = self;
|
||||
});
|
||||
|
||||
|
||||
Reference in New Issue
Block a user