Merge pull request #167902 from DeterminateSystems/openstack-zfs-cleanup

openstack-image: init, make-single-disk-zfs-image: init
This commit is contained in:
Graham Christensen
2022-04-16 19:44:53 -04:00
committed by GitHub
9 changed files with 547 additions and 19 deletions

View File

@@ -1,8 +1,11 @@
{ pkgs, lib, ... }:
{ config, pkgs, lib, ... }:
with lib;
# image metadata:
# hw_firmware_type=uefi
let
inherit (lib) mkIf mkDefault;
cfg = config.openstack;
metadataFetcher = import ./openstack-metadata-fetcher.nix {
targetRoot = "/";
wgetExtraOptions = "--retry-connrefused";
@@ -11,23 +14,47 @@ in
{
imports = [
../profiles/qemu-guest.nix
# Note: While we do use the headless profile, we also explicitly
# turn on the serial console on tty1 below.
# Note that I could not find any documentation indicating tty1 was
# the correct choice. I picked tty1 because that is what one
# particular host was using.
../profiles/headless.nix
# The Openstack Metadata service exposes data on an EC2 API also.
./ec2-data.nix
./amazon-init.nix
];
config = {
fileSystems."/" = {
fileSystems."/" = mkIf (!cfg.zfs.enable) {
device = "/dev/disk/by-label/nixos";
fsType = "ext4";
autoResize = true;
};
fileSystems."/boot" = mkIf (cfg.efi || cfg.zfs.enable) {
# The ZFS image uses a partition labeled ESP whether or not we're
# booting with EFI.
device = "/dev/disk/by-label/ESP";
fsType = "vfat";
};
boot.growPartition = true;
boot.kernelParams = [ "console=ttyS0" ];
boot.loader.grub.device = "/dev/vda";
boot.loader.timeout = 0;
boot.kernelParams = [ "console=tty1" ];
boot.loader.grub.device = if (!cfg.efi) then "/dev/vda" else "nodev";
boot.loader.grub.efiSupport = cfg.efi;
boot.loader.grub.efiInstallAsRemovable = cfg.efi;
boot.loader.timeout = 1;
boot.loader.grub.extraConfig = ''
serial --unit=1 --speed=115200 --word=8 --parity=no --stop=1
terminal_output console serial
terminal_input console serial
'';
services.zfs.expandOnBoot = mkIf cfg.zfs.enable (lib.mkDefault "all");
boot.zfs.devNodes = mkIf cfg.zfs.enable "/dev/";
# Allow root logins
services.openssh = {
@@ -36,6 +63,11 @@ in
passwordAuthentication = mkDefault false;
};
users.users.root.initialPassword = "foobar";
# Enable the serial console on tty1
systemd.services."serial-getty@tty1".enable = true;
# Force getting the hostname from Openstack metadata.
networking.hostName = mkDefault "";
@@ -43,7 +75,7 @@ in
path = [ pkgs.wget ];
description = "Fetch Metadata on startup";
wantedBy = [ "multi-user.target" ];
before = [ "apply-ec2-data.service" "amazon-init.service"];
before = [ "apply-ec2-data.service" "amazon-init.service" ];
wants = [ "network-online.target" ];
after = [ "network-online.target" ];
script = metadataFetcher;

View File

@@ -14,9 +14,9 @@
wget ${wgetExtraOptions} "$@"
}
wget_imds -O "$metaDir/ami-manifest-path" http://169.254.169.254/1.0/meta-data/ami-manifest-path
wget_imds -O "$metaDir/ami-manifest-path" http://169.254.169.254/1.0/meta-data/ami-manifest-path || true
# When no user-data is provided, the OpenStack metadata server doesn't expose the user-data route.
(umask 077 && wget_imds -O "$metaDir/user-data" http://169.254.169.254/1.0/user-data || rm -f "$metaDir/user-data")
wget_imds -O "$metaDir/hostname" http://169.254.169.254/1.0/meta-data/hostname
wget_imds -O "$metaDir/public-keys-0-openssh-key" http://169.254.169.254/1.0/meta-data/public-keys/0/openssh-key
wget_imds -O "$metaDir/hostname" http://169.254.169.254/1.0/meta-data/hostname || true
wget_imds -O "$metaDir/public-keys-0-openssh-key" http://169.254.169.254/1.0/meta-data/public-keys/0/openssh-key || true
''

View File

@@ -0,0 +1,71 @@
{ config, lib, pkgs, ... }:
let
inherit (lib) literalExpression types;
in
{
options = {
openstack = {
zfs = {
enable = lib.mkOption {
default = false;
internal = true;
description = ''
Whether the OpenStack instance uses a ZFS root.
'';
};
datasets = lib.mkOption {
description = ''
Datasets to create under the `tank` and `boot` zpools.
**NOTE:** This option is used only at image creation time, and
does not attempt to declaratively create or manage datasets
on an existing system.
'';
default = { };
type = types.attrsOf (types.submodule {
options = {
mount = lib.mkOption {
description = "Where to mount this dataset.";
type = types.nullOr types.string;
default = null;
};
properties = lib.mkOption {
description = "Properties to set on this dataset.";
type = types.attrsOf types.string;
default = { };
};
};
});
};
};
efi = lib.mkOption {
default = pkgs.stdenv.hostPlatform.isAarch64;
defaultText = literalExpression "pkgs.stdenv.hostPlatform.isAarch64";
internal = true;
description = ''
Whether the instance is using EFI.
'';
};
};
};
config = lib.mkIf config.openstack.zfs.enable {
networking.hostId = lib.mkDefault "00000000";
fileSystems =
let
mountable = lib.filterAttrs (_: value: ((value.mount or null) != null)) config.openstack.zfs.datasets;
in
lib.mapAttrs'
(dataset: opts: lib.nameValuePair opts.mount {
device = dataset;
fsType = "zfs";
})
mountable;
};
}