diff options
Diffstat (limited to 'nixos')
-rw-r--r-- | nixos/doc/manual/release-notes/rl-2003.xml | 5 | ||||
-rw-r--r-- | nixos/modules/module-list.nix | 1 | ||||
-rw-r--r-- | nixos/modules/rename.nix | 4 | ||||
-rw-r--r-- | nixos/modules/services/databases/mysql.nix | 12 | ||||
-rw-r--r-- | nixos/modules/services/network-filesystems/beegfs.nix | 357 | ||||
-rw-r--r-- | nixos/modules/services/networking/znc/default.nix | 2 | ||||
-rw-r--r-- | nixos/modules/system/boot/loader/grub/grub.nix | 4 | ||||
-rw-r--r-- | nixos/modules/virtualisation/digital-ocean-config.nix | 197 | ||||
-rw-r--r-- | nixos/modules/virtualisation/digital-ocean-image.nix | 69 | ||||
-rw-r--r-- | nixos/modules/virtualisation/digital-ocean-init.nix | 95 | ||||
-rw-r--r-- | nixos/modules/virtualisation/openvswitch.nix | 13 | ||||
-rw-r--r-- | nixos/tests/all-tests.nix | 2 | ||||
-rw-r--r-- | nixos/tests/beegfs.nix | 115 | ||||
-rw-r--r-- | nixos/tests/bees.nix | 37 | ||||
-rw-r--r-- | nixos/tests/gitolite.nix | 103 | ||||
-rw-r--r-- | nixos/tests/influxdb.nix | 33 | ||||
-rw-r--r-- | nixos/tests/jenkins.nix | 19 | ||||
-rw-r--r-- | nixos/tests/minio.nix | 32 | ||||
-rw-r--r-- | nixos/tests/sudo.nix | 52 | ||||
-rw-r--r-- | nixos/tests/uwsgi.nix | 10 | ||||
-rw-r--r-- | nixos/tests/wordpress.nix | 42 |
21 files changed, 562 insertions, 642 deletions
diff --git a/nixos/doc/manual/release-notes/rl-2003.xml b/nixos/doc/manual/release-notes/rl-2003.xml index 6916fd225dac..e8e89c5bbc28 100644 --- a/nixos/doc/manual/release-notes/rl-2003.xml +++ b/nixos/doc/manual/release-notes/rl-2003.xml @@ -176,6 +176,11 @@ KDE’s old multimedia framework Phonon no longer supports Qt 4. For that reason, Plasma desktop also does not have <option>enableQt4Support</option> option any more. </para> </listitem> + <listitem> + <para> + The BeeGFS module has been removed. + </para> + </listitem> </itemizedlist> </section> diff --git a/nixos/modules/module-list.nix b/nixos/modules/module-list.nix index 5f4a608d74d5..6d1ef0d234ab 100644 --- a/nixos/modules/module-list.nix +++ b/nixos/modules/module-list.nix @@ -538,7 +538,6 @@ ./services/monitoring/zabbix-agent.nix ./services/monitoring/zabbix-proxy.nix ./services/monitoring/zabbix-server.nix - ./services/network-filesystems/beegfs.nix ./services/network-filesystems/cachefilesd.nix ./services/network-filesystems/davfs2.nix ./services/network-filesystems/drbd.nix diff --git a/nixos/modules/rename.nix b/nixos/modules/rename.nix index a109b26a5f3d..c810bcf3bca1 100644 --- a/nixos/modules/rename.nix +++ b/nixos/modules/rename.nix @@ -280,6 +280,10 @@ with lib; # BLCR (mkRemovedOptionModule [ "environment.blcr.enable" ] "The BLCR module has been removed") + # beegfs + (mkRemovedOptionModule [ "services.beegfsEnable" ] "The BeeGFS module has been removed") + (mkRemovedOptionModule [ "services.beegfs" ] "The BeeGFS module has been removed") + # Redis (mkRemovedOptionModule [ "services" "redis" "user" ] "The redis module now is hardcoded to the redis user.") (mkRemovedOptionModule [ "services" "redis" "dbpath" ] "The redis module now uses /var/lib/redis as data directory.") diff --git a/nixos/modules/services/databases/mysql.nix b/nixos/modules/services/databases/mysql.nix index 39192d059485..5549cfa5cf4d 100644 --- a/nixos/modules/services/databases/mysql.nix +++ b/nixos/modules/services/databases/mysql.nix @@ -8,15 +8,11 @@ let mysql = cfg.package; - isMariaDB = - let - pName = _p: (builtins.parseDrvName (_p.name)).name; - in pName mysql == pName pkgs.mariadb; + isMariaDB = lib.getName mysql == lib.getName pkgs.mariadb; + isMysqlAtLeast57 = - let - pName = _p: (builtins.parseDrvName (_p.name)).name; - in (pName mysql == pName pkgs.mysql57) - && ((builtins.compareVersions mysql.version "5.7") >= 0); + (lib.getName mysql == lib.getName pkgs.mysql57) + && (builtins.compareVersions mysql.version "5.7" >= 0); mysqldOptions = "--user=${cfg.user} --datadir=${cfg.dataDir} --basedir=${mysql}"; diff --git a/nixos/modules/services/network-filesystems/beegfs.nix b/nixos/modules/services/network-filesystems/beegfs.nix deleted file mode 100644 index 2e03a422665a..000000000000 --- a/nixos/modules/services/network-filesystems/beegfs.nix +++ /dev/null @@ -1,357 +0,0 @@ -{ config, lib, pkgs, ...} : - -with lib; - -let - cfg = config.services.beegfs; - - # functions for the generations of config files - - configMgmtd = name: cfg: pkgs.writeText "mgmt-${name}.conf" '' - storeMgmtdDirectory = ${cfg.mgmtd.storeDir} - storeAllowFirstRunInit = false - connAuthFile = ${cfg.connAuthFile} - connPortShift = ${toString cfg.connPortShift} - - ${cfg.mgmtd.extraConfig} - ''; - - configAdmon = name: cfg: pkgs.writeText "admon-${name}.conf" '' - sysMgmtdHost = ${cfg.mgmtdHost} - connAuthFile = ${cfg.connAuthFile} - connPortShift = ${toString cfg.connPortShift} - - ${cfg.admon.extraConfig} - ''; - - configMeta = name: cfg: pkgs.writeText "meta-${name}.conf" '' - storeMetaDirectory = ${cfg.meta.storeDir} - sysMgmtdHost = ${cfg.mgmtdHost} - connAuthFile = ${cfg.connAuthFile} - connPortShift = ${toString cfg.connPortShift} - storeAllowFirstRunInit = false - - ${cfg.meta.extraConfig} - ''; - - configStorage = name: cfg: pkgs.writeText "storage-${name}.conf" '' - storeStorageDirectory = ${cfg.storage.storeDir} - sysMgmtdHost = ${cfg.mgmtdHost} - connAuthFile = ${cfg.connAuthFile} - connPortShift = ${toString cfg.connPortShift} - storeAllowFirstRunInit = false - - ${cfg.storage.extraConfig} - ''; - - configHelperd = name: cfg: pkgs.writeText "helperd-${name}.conf" '' - connAuthFile = ${cfg.connAuthFile} - ${cfg.helperd.extraConfig} - ''; - - configClientFilename = name : "/etc/beegfs/client-${name}.conf"; - - configClient = name: cfg: '' - sysMgmtdHost = ${cfg.mgmtdHost} - connAuthFile = ${cfg.connAuthFile} - connPortShift = ${toString cfg.connPortShift} - - ${cfg.client.extraConfig} - ''; - - serviceList = [ - { service = "admon"; cfgFile = configAdmon; } - { service = "meta"; cfgFile = configMeta; } - { service = "mgmtd"; cfgFile = configMgmtd; } - { service = "storage"; cfgFile = configStorage; } - ]; - - # functions to generate systemd.service entries - - systemdEntry = service: cfgFile: (mapAttrs' ( name: cfg: - (nameValuePair "beegfs-${service}-${name}" (mkIf cfg.${service}.enable { - wantedBy = [ "multi-user.target" ]; - requires = [ "network-online.target" ]; - after = [ "network-online.target" ]; - serviceConfig = rec { - ExecStart = '' - ${pkgs.beegfs}/bin/beegfs-${service} \ - cfgFile=${cfgFile name cfg} \ - pidFile=${PIDFile} - ''; - PIDFile = "/run/beegfs-${service}-${name}.pid"; - TimeoutStopSec = "300"; - }; - }))) cfg); - - systemdHelperd = mapAttrs' ( name: cfg: - (nameValuePair "beegfs-helperd-${name}" (mkIf cfg.client.enable { - wantedBy = [ "multi-user.target" ]; - requires = [ "network-online.target" ]; - after = [ "network-online.target" ]; - serviceConfig = rec { - ExecStart = '' - ${pkgs.beegfs}/bin/beegfs-helperd \ - cfgFile=${configHelperd name cfg} \ - pidFile=${PIDFile} - ''; - PIDFile = "/run/beegfs-helperd-${name}.pid"; - TimeoutStopSec = "300"; - }; - }))) cfg; - - # wrappers to beegfs tools. Avoid typing path of config files - utilWrappers = mapAttrsToList ( name: cfg: - ( pkgs.runCommand "beegfs-utils-${name}" { - nativeBuildInputs = [ pkgs.makeWrapper ]; - preferLocalBuild = true; - } '' - mkdir -p $out/bin - - makeWrapper ${pkgs.beegfs}/bin/beegfs-check-servers \ - $out/bin/beegfs-check-servers-${name} \ - --add-flags "-c ${configClientFilename name}" \ - --prefix PATH : ${lib.makeBinPath [ pkgs.beegfs ]} - - makeWrapper ${pkgs.beegfs}/bin/beegfs-ctl \ - $out/bin/beegfs-ctl-${name} \ - --add-flags "--cfgFile=${configClientFilename name}" - - makeWrapper ${pkgs.beegfs}/bin/beegfs-ctl \ - $out/bin/beegfs-df-${name} \ - --add-flags "--cfgFile=${configClientFilename name}" \ - --add-flags --listtargets \ - --add-flags --hidenodeid \ - --add-flags --pools \ - --add-flags --spaceinfo - - makeWrapper ${pkgs.beegfs}/bin/beegfs-fsck \ - $out/bin/beegfs-fsck-${name} \ - --add-flags "--cfgFile=${configClientFilename name}" - '' - )) cfg; -in -{ - ###### interface - - options = { - services.beegfsEnable = mkEnableOption "BeeGFS"; - - services.beegfs = mkOption { - default = {}; - description = '' - BeeGFS configurations. Every mount point requires a separate configuration. - ''; - type = with types; attrsOf (submodule ({ ... } : { - options = { - mgmtdHost = mkOption { - type = types.str; - default = null; - example = "master"; - description = ''Hostname of managament host.''; - }; - - connAuthFile = mkOption { - type = types.str; - default = ""; - example = "/etc/my.key"; - description = "File containing shared secret authentication."; - }; - - connPortShift = mkOption { - type = types.int; - default = 0; - example = 5; - description = '' - For each additional beegfs configuration shift all - service TCP/UDP ports by at least 5. - ''; - }; - - client = { - enable = mkEnableOption "BeeGFS client"; - - mount = mkOption { - type = types.bool; - default = true; - description = "Create fstab entry automatically"; - }; - - mountPoint = mkOption { - type = types.str; - default = "/run/beegfs"; - description = '' - Mount point under which the beegfs filesytem should be mounted. - If mounted manually the mount option specifing the config file is needed: - cfgFile=/etc/beegfs/beegfs-client-<name>.conf - ''; - }; - - extraConfig = mkOption { - type = types.lines; - default = ""; - description = '' - Additional lines for beegfs-client.conf. - See documentation for further details. - ''; - }; - }; - - helperd = { - enable = mkOption { - type = types.bool; - default = true; - description = '' - Enable the BeeGFS helperd. - The helpered is need for logging purposes on the client. - Disabling <literal>helperd</literal> allows for runing the client - with <literal>allowUnfree = false</literal>. - ''; - }; - - extraConfig = mkOption { - type = types.lines; - default = ""; - description = '' - Additional lines for beegfs-helperd.conf. See documentation - for further details. - ''; - }; - }; - - mgmtd = { - enable = mkEnableOption "BeeGFS mgmtd daemon"; - - storeDir = mkOption { - type = types.path; - default = null; - example = "/data/beegfs-mgmtd"; - description = '' - Data directory for mgmtd. - Must not be shared with other beegfs daemons. - This directory must exist and it must be initialized - with beegfs-setup-mgmtd, e.g. "beegfs-setup-mgmtd -C -p <storeDir>" - ''; - }; - - extraConfig = mkOption { - type = types.lines; - default = ""; - description = '' - Additional lines for beegfs-mgmtd.conf. See documentation - for further details. - ''; - }; - }; - - admon = { - enable = mkEnableOption "BeeGFS admon daemon"; - - extraConfig = mkOption { - type = types.lines; - default = ""; - description = '' - Additional lines for beegfs-admon.conf. See documentation - for further details. - ''; - }; - }; - - meta = { - enable = mkEnableOption "BeeGFS meta data daemon"; - - storeDir = mkOption { - type = types.path; - default = null; - example = "/data/beegfs-meta"; - description = '' - Data directory for meta data service. - Must not be shared with other beegfs daemons. - The underlying filesystem must be mounted with xattr turned on. - This directory must exist and it must be initialized - with beegfs-setup-meta, e.g. - "beegfs-setup-meta -C -s <serviceID> -p <storeDir>" - ''; - }; - - extraConfig = mkOption { - type = types.str; - default = ""; - description = '' - Additional lines for beegfs-meta.conf. See documentation - for further details. - ''; - }; - }; - - storage = { - enable = mkEnableOption "BeeGFS storage daemon"; - - storeDir = mkOption { - type = types.path; - default = null; - example = "/data/beegfs-storage"; - description = '' - Data directories for storage service. - Must not be shared with other beegfs daemons. - The underlying filesystem must be mounted with xattr turned on. - This directory must exist and it must be initialized - with beegfs-setup-storage, e.g. - "beegfs-setup-storage -C -s <serviceID> -i <storageTargetID> -p <storeDir>" - ''; - }; - - extraConfig = mkOption { - type = types.str; - default = ""; - description = '' - Addional lines for beegfs-storage.conf. See documentation - for further details. - ''; - }; - }; - }; - })); - }; - }; - - ###### implementation - - config = - mkIf config.services.beegfsEnable { - - environment.systemPackages = utilWrappers; - - # Put the client.conf files in /etc since they are needed - # by the commandline tools - environment.etc = mapAttrs' ( name: cfg: - (nameValuePair "beegfs/client-${name}.conf" (mkIf (cfg.client.enable) - { - enable = true; - text = configClient name cfg; - }))) cfg; - - # Kernel module, we need it only once per host. - boot = mkIf ( - foldr (a: b: a || b) false - (map (x: x.client.enable) (collect (x: x ? client) cfg))) - { - kernelModules = [ "beegfs" ]; - extraModulePackages = [ pkgs.linuxPackages.beegfs-module ]; - }; - - # generate fstab entries - fileSystems = mapAttrs' (name: cfg: - (nameValuePair cfg.client.mountPoint (optionalAttrs cfg.client.mount (mkIf cfg.client.enable { - device = "beegfs_nodev"; - fsType = "beegfs"; - mountPoint = cfg.client.mountPoint; - options = [ "cfgFile=${configClientFilename name}" "_netdev" ]; - })))) cfg; - - # generate systemd services - systemd.services = systemdHelperd // - foldr (a: b: a // b) {} - (map (x: systemdEntry x.service x.cfgFile) serviceList); - }; -} diff --git a/nixos/modules/services/networking/znc/default.nix b/nixos/modules/services/networking/znc/default.nix index 05f97bfa539f..0a9848a49349 100644 --- a/nixos/modules/services/networking/znc/default.nix +++ b/nixos/modules/services/networking/znc/default.nix @@ -239,7 +239,7 @@ in services.znc = { configFile = mkDefault (pkgs.writeText "znc-generated.conf" semanticString); config = { - Version = (builtins.parseDrvName pkgs.znc.name).version; + Version = lib.getVersion pkgs.znc; Listener.l.Port = mkDefault 5000; Listener.l.SSL = mkDefault true; }; diff --git a/nixos/modules/system/boot/loader/grub/grub.nix b/nixos/modules/system/boot/loader/grub/grub.nix index e13f0421d38f..9a4db84f7b73 100644 --- a/nixos/modules/system/boot/loader/grub/grub.nix +++ b/nixos/modules/system/boot/loader/grub/grub.nix @@ -47,8 +47,8 @@ let grub = f grub; grubTarget = f (grub.grubTarget or ""); shell = "${pkgs.runtimeShell}"; - fullName = (builtins.parseDrvName realGrub.name).name; - fullVersion = (builtins.parseDrvName realGrub.name).version; + fullName = lib.getName realGrub; + fullVersion = lib.getVersion realGrub; grubEfi = f grubEfi; grubTargetEfi = if cfg.efiSupport && (cfg.version == 2) then f (grubEfi.grubTarget or "") else ""; bootPath = args.path; diff --git a/nixos/modules/virtualisation/digital-ocean-config.nix b/nixos/modules/virtualisation/digital-ocean-config.nix new file mode 100644 index 000000000000..88cb0cd450e8 --- /dev/null +++ b/nixos/modules/virtualisation/digital-ocean-config.nix @@ -0,0 +1,197 @@ +{ config, pkgs, lib, modulesPath, ... }: +with lib; +{ + imports = [ + (modulesPath + "/profiles/qemu-guest.nix") + (modulesPath + "/virtualisation/digital-ocean-init.nix") + ]; + options.virtualisation.digitalOcean = with types; { + setRootPassword = mkOption { + type = bool; + default = false; + example = true; + description = "Whether to set the root password from the Digital Ocean metadata"; + }; + setSshKeys = mkOption { + type = bool; + default = true; + example = true; + description = "Whether to fetch ssh keys from Digital Ocean"; + }; + seedEntropy = mkOption { + type = bool; + default = true; + example = true; + description = "Whether to run the kernel RNG entropy seeding script from the Digital Ocean vendor data"; + }; + }; + config = + let + cfg = config.virtualisation.digitalOcean; + hostName = config.networking.hostName; + doMetadataFile = "/run/do-metadata/v1.json"; + in mkMerge [{ + fileSystems."/" = { + device = "/dev/disk/by-label/nixos"; + autoResize = true; + fsType = "ext4"; + }; + boot = { + growPartition = true; + kernelParams = [ "console=ttyS0" "panic=1" "boot.panic_on_fail" ]; + initrd.kernelModules = [ "virtio_scsi" ]; + kernelModules = [ "virtio_pci" "virtio_net" ]; + loader = { + grub.device = "/dev/vda"; + timeout = 0; + grub.configurationLimit = 0; + }; + }; + services.openssh = { + enable = mkDefault true; + passwordAuthentication = mkDefault false; + }; + services.do-agent.enable = mkDefault true; + networking = { + hostName = mkDefault ""; # use Digital Ocean metadata server + }; + + /* Check for and wait for the metadata server to become reachable. + * This serves as a dependency for all the other metadata services. */ + systemd.services.digitalocean-metadata = { + path = [ pkgs.curl ]; + description = "Get host metadata provided by Digitalocean"; + script = '' + set -eu + DO_DELAY_ATTEMPTS=0 + while ! curl -fsSL -o $RUNTIME_DIRECTORY/v1.json http://169.254.169.254/metadata/v1.json; do + DO_DELAY_ATTEMPTS=$((DO_DELAY_ATTEMPTS + 1)) + if (( $DO_DELAY_ATTEMPTS >= $DO_DELAY_ATTEMPTS_MAX )); then + echo "giving up" + exit 1 + fi + + echo "metadata unavailable, trying again in 1s..." + sleep 1 + done + chmod 600 $RUNTIME_DIRECTORY/v1.json + ''; + environment = { + DO_DELAY_ATTEMPTS_MAX = "10"; + }; + serviceConfig = { + Type = "oneshot"; + RemainAfterExit = true; + RuntimeDirectory = "do-metadata"; + RuntimeDirectoryPreserve = "yes"; + }; + unitConfig = { + ConditionPathExists = "!${doMetadataFile}"; + After = [ "network-pre.target" ] ++ + optional config.networking.dhcpcd.enable "dhcpcd.service" ++ + optional config.systemd.network.enable "systemd-networkd.service"; + }; + }; + + /* Fetch the root password from the digital ocean metadata. + * There is no specific route for this, so we use jq to get + * it from the One Big JSON metadata blob */ + systemd.services.digitalocean-set-root-password = mkIf cfg.setRootPassword { + path = [ pkgs.shadow pkgs.jq ]; + description = "Set root password provided by Digitalocean"; + wantedBy = [ "multi-user.target" ]; + script = '' + set -eo pipefail + ROOT_PASSWORD=$(jq -er '.auth_key' ${doMetadataFile}) + echo "root:$ROOT_PASSWORD" | chpasswd + mkdir -p /etc/do-metadata/set-root-password + ''; + unitConfig = { + ConditionPathExists = "!/etc/do-metadata/set-root-password"; + Before = optional config.services.openssh.enable "sshd.service"; + After = [ "digitalocean-metadata.service" ]; + Requires = [ "digitalocean-metadata.service" ]; + }; + serviceConfig = { + Type = "oneshot"; + }; + }; + + /* Set the hostname from Digital Ocean, unless the user configured it in + * the NixOS configuration. The cached metadata file isn't used here + * because the hostname is a mutable part of the droplet. */ + systemd.services.digitalocean-set-hostname = mkIf (hostName == "") { + path = [ pkgs.curl pkgs.nettools ]; + description = "Set hostname provided by Digitalocean"; + wantedBy = [ "network.target" ]; + script = '' + set -e + DIGITALOCEAN_HOSTNAME=$(curl -fsSL http://169.254.169.254/metadata/v1/hostname) + hostname "$DIGITALOCEAN_HOSTNAME" + if [[ ! -e /etc/hostname || -w /etc/hostname ]]; then + printf "%s\n" "$DIGITALOCEAN_HOSTNAME" > /etc/hostname + fi + ''; + unitConfig = { + Before = [ "network.target" ]; + After = [ "digitalocean-metadata.service" ]; + Wants = [ "digitalocean-metadata.service" ]; + }; + serviceConfig = { + Type = "oneshot"; + }; + }; + + /* Fetch the ssh keys for root from Digital Ocean */ + systemd.services.digitalocean-ssh-keys = mkIf cfg.setSshKeys { + description = "Set root ssh keys provided by Digital Ocean"; + wantedBy = [ "multi-user.target" ]; + path = [ pkgs.jq ]; + script = '' + set -e + mkdir -m 0700 -p /root/.ssh + jq -er '.public_keys[]' ${doMetadataFile} > /root/.ssh/authorized_keys + chmod 600 /root/.ssh/authorized_keys + ''; + serviceConfig = { + Type = "oneshot"; + RemainAfterExit = true; + }; + unitConfig = { + ConditionPathExists = "!/root/.ssh/authorized_keys"; + Before = optional config.services.openssh.enable "sshd.service"; + After = [ "digitalocean-metadata.service" ]; + Requires = [ "digitalocean-metadata.service" ]; + }; + }; + + /* Initialize the RNG by running the entropy-seed script from the + * Digital Ocean metadata + */ + systemd.services.digitalocean-entropy-seed = mkIf cfg.seedEntropy { + description = "Run the kernel RNG entropy seeding script from the Digital Ocean vendor data"; + wantedBy = [ "network.target" ]; + path = [ pkgs.jq pkgs.mpack ]; + script = '' + set -eo pipefail + TEMPDIR=$(mktemp -d) + jq -er '.vendor_data' ${doMetadataFile} | munpack -tC $TEMPDIR + ENTROPY_SEED=$(grep -rl "DigitalOcean Entropy Seed script" $TEMPDIR) + ${pkgs.runtimeShell} $ENTROPY_SEED + rm -rf $TEMPDIR + ''; + unitConfig = { + Before = [ "network.target" ]; + After = [ "digitalocean-metadata.service" ]; + Requires = [ "digitalocean-metadata.service" ]; + }; + serviceConfig = { + Type = "oneshot"; + }; + }; + + } + ]; + meta.maintainers = with maintainers; [ arianvp eamsden ]; +} + diff --git a/nixos/modules/virtualisation/digital-ocean-image.nix b/nixos/modules/virtualisation/digital-ocean-image.nix new file mode 100644 index 000000000000..b582e235d435 --- /dev/null +++ b/nixos/modules/virtualisation/digital-ocean-image.nix @@ -0,0 +1,69 @@ +{ config, lib, pkgs, ... }: + +with lib; +let + cfg = config.virtualisation.digitalOceanImage; +in +{ + + imports = [ ./digital-ocean-config.nix ]; + + options = { + virtualisation.digitalOceanImage.diskSize = mkOption { + type = with types; int; + default = 4096; + description = '' + Size of disk image. Unit is MB. + ''; + }; + + virtualisation.digitalOceanImage.configFile = mkOption { + type = with types; nullOr path; + default = null; + description = '' + A path to a configuration file which will be placed at + <literal>/etc/nixos/configuration.nix</literal> and be used when switching + to a new configuration. If set to <literal>null</literal>, a default + configuration is used that imports + <literal>(modulesPath + "/virtualisation/digital-ocean-config.nix")</literal>. + ''; + }; + + virtualisation.digitalOceanImage.compressionMethod = mkOption { + type = types.enum [ "gzip" "bzip2" ]; + default = "gzip"; + example = "bzip2"; + description = '' + Disk image compression method. Choose bzip2 to generate smaller images that + take longer to generate but will consume less metered storage space on your + Digital Ocean account. + ''; + }; + }; + + #### implementation + config = { + + system.build.digitalOceanImage = import ../../lib/make-disk-image.nix { + name = "digital-ocean-image"; + format = "qcow2"; + postVM = let + compress = { + "gzip" = "${pkgs.gzip}/bin/gzip"; + "bzip2" = "${pkgs.bzip2}/bin/bzip2"; + }.${cfg.compressionMethod}; + in '' + ${compress} $diskImage + ''; + configFile = if cfg.configFile == null + then config.virtualisation.digitalOcean.defaultConfigFile + else cfg.configFile; + inherit (cfg) diskSize; + inherit config lib pkgs; + }; + + }; + + meta.maintainers = with maintainers; [ arianvp eamsden ]; + +} diff --git a/nixos/modules/virtualisation/digital-ocean-init.nix b/nixos/modules/virtualisation/digital-ocean-init.nix new file mode 100644 index 000000000000..02f4de009fa8 --- /dev/null +++ b/nixos/modules/virtualisation/digital-ocean-init.nix @@ -0,0 +1,95 @@ +{ config, pkgs, lib, ... }: +with lib; +let + cfg = config.virtualisation.digitalOcean; + defaultConfigFile = pkgs.writeText "digitalocean-configuration.nix" '' + { modulesPath, lib, ... }: + { + imports = lib.optional (builtins.pathExists ./do-userdata.nix) ./do-userdata.nix ++ [ + (modulesPath + "/virtualisation/digital-ocean-config.nix") + ]; + } + ''; +in { + options.virtualisation.digitalOcean.rebuildFromUserData = mkOption { + type = types.bool; + default = true; + example = true; + description = "Whether to reconfigure the system from Digital Ocean user data"; + }; + options.virtualisation.digitalOcean.defaultConfigFile = mkOption { + type = types.path; + default = defaultConfigFile; + defaultText = '' + The default configuration imports user-data if applicable and + <literal>(modulesPath + "/virtualisation/digital-ocean-config.nix")</literal>. + ''; + description = '' + A path to a configuration file which will be placed at + <literal>/etc/nixos/configuration.nix</literal> and be used when switching to + a new configuration. + ''; + }; + + config = { + systemd.services.digitalocean-init = mkIf cfg.rebuildFromUserData { + description = "Reconfigure the system from Digital Ocean userdata on startup"; + wantedBy = [ "network-online.target" ]; + unitConfig = { + ConditionPathExists = "!/etc/nixos/do-userdata.nix"; + After = [ "digitalocean-metadata.service" "network-online.target" ]; + Requires = [ "digitalocean-metadata.service" ]; + X-StopOnRemoval = false; + }; + serviceConfig = { + Type = "oneshot"; + RemainAfterExit = true; + }; + restartIfChanged = false; + path = [ pkgs.jq pkgs.gnused pkgs.gnugrep pkgs.systemd config.nix.package config.system.build.nixos-rebuild ]; + environment = { + HOME = "/root"; + NIX_PATH = concatStringsSep ":" [ + "/nix/var/nix/profiles/per-user/root/channels/nixos" + "nixos-config=/etc/nixos/configuration.nix" + "/nix/var/nix/profiles/per-user/root/channels" + ]; + }; + script = '' + set -e + echo "attempting to fetch configuration from Digital Ocean user data..." + userData=$(mktemp) + if jq -er '.user_data' /run/do-metadata/v1.json > $userData; then + # If the user-data looks like it could be a nix expression, + # copy it over. Also, look for a magic three-hash comment and set + # that as the channel. + if nix-instantiate --parse $userData > /dev/null; then + channels="$(grep '^###' "$userData" | sed 's|###\s*||')" + printf "%s" "$channels" | while read channel; do + echo "writing channel: $channel" + done + + if [[ -n "$channels" ]]; then + printf "%s" "$channels" > /root/.nix-channels + nix-channel --update + fi + + echo "setting configuration from Digital Ocean user data" + cp "$userData" /etc/nixos/do-userdata.nix + if [[ ! -e /etc/nixos/configuration.nix ]]; then + install -m0644 ${cfg.defaultConfigFile} /etc/nixos/configuration.nix + fi + else + echo "user data does not appear to be a Nix expression; ignoring" + exit + fi + + nixos-rebuild switch + else + echo "no user data is available" + fi + ''; + }; + }; + meta.maintainers = with maintainers; [ arianvp eamsden ]; +} diff --git a/nixos/modules/virtualisation/openvswitch.nix b/nixos/modules/virtualisation/openvswitch.nix index edec37402308..6b8ad83661fe 100644 --- a/nixos/modules/virtualisation/openvswitch.nix +++ b/nixos/modules/virtualisation/openvswitch.nix @@ -42,6 +42,9 @@ in { default = false; description = '' Whether to start racoon service for openvswitch. + Supported only if openvswitch version is less than 2.6.0. + Use <literal>virtualisation.vswitch.package = pkgs.openvswitch-lts</literal> + for a version that supports ipsec over GRE. ''; }; }; @@ -89,6 +92,13 @@ in { "${cfg.package}/share/openvswitch/vswitch.ovsschema" fi chmod -R +w /var/db/openvswitch + if ${cfg.package}/bin/ovsdb-tool needs-conversion /var/db/openvswitch/conf.db | grep -q "yes" + then + echo "Performing database upgrade" + ${cfg.package}/bin/ovsdb-tool convert /var/db/openvswitch/conf.db + else + echo "Database already up to date" + fi ''; serviceConfig = { ExecStart = @@ -133,7 +143,7 @@ in { }; } - (mkIf cfg.ipsec { + (mkIf (cfg.ipsec && (versionOlder cfg.package.version "2.6.0")) { services.racoon.enable = true; services.racoon.configPath = "${runDir}/ipsec/etc/racoon/racoon.conf"; @@ -172,5 +182,4 @@ in { ''; }; })])); - } diff --git a/nixos/tests/all-tests.nix b/nixos/tests/all-tests.nix index a2129ef7076e..3d5bc408c445 100644 --- a/nixos/tests/all-tests.nix +++ b/nixos/tests/all-tests.nix @@ -28,7 +28,7 @@ in babeld = handleTest ./babeld.nix {}; bcachefs = handleTestOn ["x86_64-linux"] ./bcachefs.nix {}; # linux-4.18.2018.10.12 is unsupported on aarch64 beanstalkd = handleTest ./beanstalkd.nix {}; - beegfs = handleTestOn ["x86_64-linux"] ./beegfs.nix {}; # beegfs is unsupported on aarch64 + bees = handleTest ./bees.nix {}; bind = handleTest ./bind.nix {}; bittorrent = handleTest ./bittorrent.nix {}; #blivet = handleTest ./blivet.nix {}; # broken since 2017-07024 diff --git a/nixos/tests/beegfs.nix b/nixos/tests/beegfs.nix deleted file mode 100644 index 3465272f5599..000000000000 --- a/nixos/tests/beegfs.nix +++ /dev/null @@ -1,115 +0,0 @@ -import ./make-test.nix ({ ... } : - -let - connAuthFile="beegfs/auth-def.key"; - - client = { pkgs, ... } : { - networking.firewall.enable = false; - services.beegfsEnable = true; - services.beegfs.default = { - mgmtdHost = "mgmt"; - connAuthFile = "/etc/${connAuthFile}"; - client = { - mount = false; - enable = true; - }; - }; - - fileSystems = pkgs.lib.mkVMOverride # FIXME: this should be creatd by the module - [ { mountPoint = "/beegfs"; - device = "default"; - fsType = "beegfs"; - options = [ "cfgFile=/etc/beegfs/client-default.conf" "_netdev" ]; - } - ]; - - environment.etc.${connAuthFile} = { - enable = true; - text = "ThisIsALousySecret"; - mode = "0600"; - }; - }; - - - server = service : { pkgs, ... } : { - networking.firewall.enable = false; - boot.initrd.postDeviceCommands = '' - ${pkgs.e2fsprogs}/bin/mkfs.ext4 -L data /dev/vdb - ''; - - virtualisation.emptyDiskImages = [ 4096 ]; - - fileSystems = pkgs.lib.mkVMOverride - [ { mountPoint = "/data"; - device = "/dev/disk/by-label/data"; - fsType = "ext4"; - } - ]; - - environment.systemPackages = with pkgs; [ beegfs ]; - environment.etc.${connAuthFile} = { - enable = true; - text = "ThisIsALousySecret"; - mode = "0600"; - }; - - services.beegfsEnable = true; - services.beegfs.default = { - mgmtdHost = "mgmt"; - connAuthFile = "/etc/${connAuthFile}"; - ${service} = { - enable = true; - storeDir = "/data"; - }; - }; - }; - -in -{ - name = "beegfs"; - - nodes = { - meta = server "meta"; - mgmt = server "mgmtd"; - storage1 = server "storage"; - storage2 = server "storage"; - client1 = client; - client2 = client; - }; - - testScript = '' - # Initalize the data directories - $mgmt->waitForUnit("default.target"); - $mgmt->succeed("beegfs-setup-mgmtd -C -f -p /data"); - $mgmt->succeed("systemctl start beegfs-mgmtd-default"); - - $meta->waitForUnit("default.target"); - $meta->succeed("beegfs-setup-meta -C -f -s 1 -p /data"); - $meta->succeed("systemctl start beegfs-meta-default"); - - $storage1->waitForUnit("default.target"); - $storage1->succeed("beegfs-setup-storage -C -f -s 1 -i 1 -p /data"); - $storage1->succeed("systemctl start beegfs-storage-default"); - - $storage2->waitForUnit("default.target"); - $storage2->succeed("beegfs-setup-storage -C -f -s 2 -i 2 -p /data"); - $storage2->succeed("systemctl start beegfs-storage-default"); - - # - - # Basic test - $client1->waitForUnit("beegfs.mount"); - $client1->succeed("beegfs-check-servers-default"); - $client1->succeed("echo test > /beegfs/test"); - $client2->waitForUnit("beegfs.mount"); - $client2->succeed("test -e /beegfs/test"); - $client2->succeed("cat /beegfs/test | grep test"); - - # test raid0/stripping - $client1->succeed("dd if=/dev/urandom bs=1M count=10 of=/beegfs/striped"); - $client2->succeed("cat /beegfs/striped > /dev/null"); - - # check if fs is still healthy - $client1->succeed("beegfs-fsck-default --checkfs"); - ''; -}) diff --git a/nixos/tests/bees.nix b/nixos/tests/bees.nix index 6f68c2f834f1..6e6a9c3446b0 100644 --- a/nixos/tests/bees.nix +++ b/nixos/tests/bees.nix @@ -1,4 +1,4 @@ -import ./make-test.nix ({ lib, ... }: +import ./make-test-python.nix ({ lib, pkgs, ... }: { name = "bees"; @@ -29,27 +29,34 @@ import ./make-test.nix ({ lib, ... }: testScript = let - withRetry = content: maxTests: sleepTime: '' - max_tests=${lib.escapeShellArg maxTests}; sleep_time=${lib.escapeShellArg sleepTime}; for ((i=0; i<max_tests; i++)); do ${content} && exit 0; sleep "$sleep_time"; done; exit 1; + someContentIsShared = loc: pkgs.writeShellScript "some-content-is-shared" '' + [[ $(btrfs fi du -s --raw ${lib.escapeShellArg loc}/dedup-me-{1,2} | awk 'BEGIN { count=0; } NR>1 && $3 == 0 { count++ } END { print count }') -eq 0 ]] ''; - someContentIsShared = loc: ''[[ $(btrfs fi du -s --raw ${lib.escapeShellArg loc}/dedup-me-{1,2} | awk 'BEGIN { count=0; } NR>1 && $3 == 0 { count++ } END { print count }') -eq 0 ]]''; in '' # shut down the instance started by systemd at boot, so we can test our test procedure - $machine->succeed("systemctl stop beesd\@aux1.service"); + machine.succeed("systemctl stop beesd@aux1.service") - $machine->succeed("dd if=/dev/urandom of=/aux1/dedup-me-1 bs=1M count=8"); - $machine->succeed("cp --reflink=never /aux1/dedup-me-1 /aux1/dedup-me-2"); - $machine->succeed("cp --reflink=never /aux1/* /aux2/"); - $machine->succeed("sync"); - $machine->fail(q(${someContentIsShared "/aux1"})); - $machine->fail(q(${someContentIsShared "/aux2"})); - $machine->succeed("systemctl start beesd\@aux1.service"); + machine.succeed( + "dd if=/dev/urandom of=/aux1/dedup-me-1 bs=1M count=8", + "cp --reflink=never /aux1/dedup-me-1 /aux1/dedup-me-2", + "cp --reflink=never /aux1/* /aux2/", + "sync", + ) + machine.fail( + "${someContentIsShared "/aux1"}", + "${someContentIsShared "/aux2"}", + ) + machine.succeed("systemctl start beesd@aux1.service") # assert that "Set Shared" column is nonzero - $machine->succeed(q(${withRetry (someContentIsShared "/aux1") 20 2})); - $machine->fail(q(${someContentIsShared "/aux2"})); + machine.wait_until_succeeds( + "${someContentIsShared "/aux1"}", + ) + machine.fail("${someContentIsShared "/aux2"}") # assert that 16MB hash table size requested was honored - $machine->succeed(q([[ $(stat -c %s /aux1/.beeshome/beeshash.dat) = $(( 16 * 1024 * 1024)) ]])) + machine.succeed( + "[[ $(stat -c %s /aux1/.beeshome/beeshash.dat) = $(( 16 * 1024 * 1024)) ]]" + ) ''; }) diff --git a/nixos/tests/gitolite.nix b/nixos/tests/gitolite.nix index 690e456ed7c8..a928645bd80f 100644 --- a/nixos/tests/gitolite.nix +++ b/nixos/tests/gitolite.nix @@ -1,4 +1,4 @@ -import ./make-test.nix ({ pkgs, ...}: +import ./make-test-python.nix ({ pkgs, ...}: let adminPrivateKey = pkgs.writeText "id_ed25519" '' @@ -43,7 +43,7 @@ let ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIJZNonUP1ePHLrvn0W9D2hdN6zWWZYFyJc+QR6pOKQEw bob@client ''; - gitoliteAdminConfSnippet = '' + gitoliteAdminConfSnippet = pkgs.writeText "gitolite-admin-conf-snippet" '' repo alice-project RW+ = alice ''; @@ -85,55 +85,54 @@ in }; testScript = '' - startAll; - - subtest "can setup ssh keys on system", sub { - $client->mustSucceed("mkdir -p ~root/.ssh"); - $client->mustSucceed("cp ${adminPrivateKey} ~root/.ssh/id_ed25519"); - $client->mustSucceed("chmod 600 ~root/.ssh/id_ed25519"); - - $client->mustSucceed("sudo -u alice mkdir -p ~alice/.ssh"); - $client->mustSucceed("sudo -u alice cp ${alicePrivateKey} ~alice/.ssh/id_ed25519"); - $client->mustSucceed("sudo -u alice chmod 600 ~alice/.ssh/id_ed25519"); - - $client->mustSucceed("sudo -u bob mkdir -p ~bob/.ssh"); - $client->mustSucceed("sudo -u bob cp ${bobPrivateKey} ~bob/.ssh/id_ed25519"); - $client->mustSucceed("sudo -u bob chmod 600 ~bob/.ssh/id_ed25519"); - }; - - subtest "gitolite server starts", sub { - $server->waitForUnit("gitolite-init.service"); - $server->waitForUnit("sshd.service"); - $client->mustSucceed('ssh gitolite@server info'); - }; - - subtest "admin can clone and configure gitolite-admin.git", sub { - $client->mustSucceed('git clone gitolite@server:gitolite-admin.git'); - $client->mustSucceed("git config --global user.name 'System Administrator'"); - $client->mustSucceed("git config --global user.email root\@domain.example"); - $client->mustSucceed("cp ${alicePublicKey} gitolite-admin/keydir/alice.pub"); - $client->mustSucceed("cp ${bobPublicKey} gitolite-admin/keydir/bob.pub"); - $client->mustSucceed('(cd gitolite-admin && git add . && git commit -m "Add keys for alice, bob" && git push)'); - $client->mustSucceed("printf '${gitoliteAdminConfSnippet}' >> gitolite-admin/conf/gitolite.conf"); - $client->mustSucceed('(cd gitolite-admin && git add . && git commit -m "Add repo for alice" && git push)'); - }; - - subtest "non-admins cannot clone gitolite-admin.git", sub { - $client->mustFail('sudo -i -u alice git clone gitolite@server:gitolite-admin.git'); - $client->mustFail('sudo -i -u bob git clone gitolite@server:gitolite-admin.git'); - }; - - subtest "non-admins can clone testing.git", sub { - $client->mustSucceed('sudo -i -u alice git clone gitolite@server:testing.git'); - $client->mustSucceed('sudo -i -u bob git clone gitolite@server:testing.git'); - }; - - subtest "alice can clone alice-project.git", sub { - $client->mustSucceed('sudo -i -u alice git clone gitolite@server:alice-project.git'); - }; - - subtest "bob cannot clone alice-project.git", sub { - $client->mustFail('sudo -i -u bob git clone gitolite@server:alice-project.git'); - }; + start_all() + + with subtest("can setup ssh keys on system"): + client.succeed( + "mkdir -p ~root/.ssh", + "cp ${adminPrivateKey} ~root/.ssh/id_ed25519", + "chmod 600 ~root/.ssh/id_ed25519", + ) + client.succeed( + "sudo -u alice mkdir -p ~alice/.ssh", + "sudo -u alice cp ${alicePrivateKey} ~alice/.ssh/id_ed25519", + "sudo -u alice chmod 600 ~alice/.ssh/id_ed25519", + ) + client.succeed( + "sudo -u bob mkdir -p ~bob/.ssh", + "sudo -u bob cp ${bobPrivateKey} ~bob/.ssh/id_ed25519", + "sudo -u bob chmod 600 ~bob/.ssh/id_ed25519", + ) + + with subtest("gitolite server starts"): + server.wait_for_unit("gitolite-init.service") + server.wait_for_unit("sshd.service") + client.succeed("ssh gitolite@server info") + + with subtest("admin can clone and configure gitolite-admin.git"): + client.succeed( + "git clone gitolite@server:gitolite-admin.git", + "git config --global user.name 'System Administrator'", + "git config --global user.email root\@domain.example", + "cp ${alicePublicKey} gitolite-admin/keydir/alice.pub", + "cp ${bobPublicKey} gitolite-admin/keydir/bob.pub", + "(cd gitolite-admin && git add . && git commit -m 'Add keys for alice, bob' && git push)", + "cat ${gitoliteAdminConfSnippet} >> gitolite-admin/conf/gitolite.conf", + "(cd gitolite-admin && git add . && git commit -m 'Add repo for alice' && git push)", + ) + + with subtest("non-admins cannot clone gitolite-admin.git"): + client.fail("sudo -i -u alice git clone gitolite@server:gitolite-admin.git") + client.fail("sudo -i -u bob git clone gitolite@server:gitolite-admin.git") + + with subtest("non-admins can clone testing.git"): + client.succeed("sudo -i -u alice git clone gitolite@server:testing.git") + client.succeed("sudo -i -u bob git clone gitolite@server:testing.git") + + with subtest("alice can clone alice-project.git"): + client.succeed("sudo -i -u alice git clone gitolite@server:alice-project.git") + + with subtest("bob cannot clone alice-project.git"): + client.fail("sudo -i -u bob git clone gitolite@server:alice-project.git") ''; }) diff --git a/nixos/tests/influxdb.nix b/nixos/tests/influxdb.nix index 61201202204b..04ef80461010 100644 --- a/nixos/tests/influxdb.nix +++ b/nixos/tests/influxdb.nix @@ -1,6 +1,6 @@ # This test runs influxdb and checks if influxdb is up and running -import ./make-test.nix ({ pkgs, ...} : { +import ./make-test-python.nix ({ pkgs, ...} : { name = "influxdb"; meta = with pkgs.stdenv.lib.maintainers; { maintainers = [ offline ]; @@ -9,25 +9,32 @@ import ./make-test.nix ({ pkgs, ...} : { nodes = { one = { ... }: { services.influxdb.enable = true; + environment.systemPackages = [ pkgs.httpie ]; }; }; testScript = '' - startAll; - - $one->waitForUnit("influxdb.service"); + import shlex + + start_all() + + one.wait_for_unit("influxdb.service") # create database - $one->succeed(q~ - curl -XPOST http://localhost:8086/query --data-urlencode "q=CREATE DATABASE test" - ~); + one.succeed( + "curl -XPOST http://localhost:8086/query --data-urlencode 'q=CREATE DATABASE test'" + ) # write some points and run simple query - $one->succeed(q~ - curl -XPOST 'http://localhost:8086/write?db=test' --data-binary 'cpu_load_short,host=server01,region=us-west value=0.64 1434055562000000000' - ~); - $one->succeed(q~ - curl -GET 'http://localhost:8086/query' --data-urlencode "db=test" --data-urlencode "q=SELECT \"value\" FROM \"cpu_load_short\" WHERE \"region\"='us-west'" | grep "0\.64" - ~); + out = one.succeed( + "curl -XPOST 'http://localhost:8086/write?db=test' --data-binary 'cpu_load_short,host=server01,region=us-west value=0.64 1434055562000000000'" + ) + + qv = "SELECT value FROM cpu_load_short WHERE region='us-west'" + cmd = f'curl -GET "http://localhost:8086/query?db=test" --data-urlencode {shlex.quote("q="+ qv)}' + out = one.succeed(cmd) + + assert "2015-06-11T20:46:02Z" in out + assert "0.64" in out ''; }) diff --git a/nixos/tests/jenkins.nix b/nixos/tests/jenkins.nix index a6eec411ff28..cd64ff512878 100644 --- a/nixos/tests/jenkins.nix +++ b/nixos/tests/jenkins.nix @@ -3,7 +3,7 @@ # 2. jenkins user can be extended on both master and slave # 3. jenkins service not started on slave node -import ./make-test.nix ({ pkgs, ...} : { +import ./make-test-python.nix ({ pkgs, ...} : { name = "jenkins"; meta = with pkgs.stdenv.lib.maintainers; { maintainers = [ bjornfor coconnor domenkozar eelco ]; @@ -33,18 +33,17 @@ import ./make-test.nix ({ pkgs, ...} : { }; testScript = '' - startAll; + start_all() - $master->waitForUnit("jenkins"); + master.wait_for_unit("jenkins") - $master->mustSucceed("curl http://localhost:8080 | grep 'Authentication required'"); + assert "Authentication required" in master.succeed("curl http://localhost:8080") - print $master->execute("sudo -u jenkins groups"); - $master->mustSucceed("sudo -u jenkins groups | grep jenkins | grep users"); + for host in master, slave: + groups = host.succeed("sudo -u jenkins groups") + assert "jenkins" in groups + assert "users" in groups - print $slave->execute("sudo -u jenkins groups"); - $slave->mustSucceed("sudo -u jenkins groups | grep jenkins | grep users"); - - $slave->mustFail("systemctl is-enabled jenkins.service"); + slave.fail("systemctl is-enabled jenkins.service") ''; }) diff --git a/nixos/tests/minio.nix b/nixos/tests/minio.nix index f1218b537711..3b0619742671 100644 --- a/nixos/tests/minio.nix +++ b/nixos/tests/minio.nix @@ -1,4 +1,4 @@ -import ./make-test.nix ({ pkgs, ...} : +import ./make-test-python.nix ({ pkgs, ...} : let accessKey = "BKIKJAA5BMMU2RHO6IBB"; secretKey = "V7f1CwQqAcwo80UEIJEjc5gVQUSSx5ohQ9GSrr12"; @@ -18,7 +18,7 @@ let sio.seek(0) minioClient.put_object('test-bucket', 'test.txt', sio, sio_len, content_type='text/plain') ''; - in { +in { name = "minio"; meta = with pkgs.stdenv.lib.maintainers; { maintainers = [ bachp ]; @@ -37,19 +37,19 @@ let }; }; - testScript = - '' - startAll; - $machine->waitForUnit("minio.service"); - $machine->waitForOpenPort(9000); + testScript = '' + start_all() + machine.wait_for_unit("minio.service") + machine.wait_for_open_port(9000) - # Create a test bucket on the server - $machine->succeed("mc config host add minio http://localhost:9000 ${accessKey} ${secretKey} S3v4"); - $machine->succeed("mc mb minio/test-bucket"); - $machine->succeed("${minioPythonScript}"); - $machine->succeed("mc ls minio") =~ /test-bucket/ or die; - $machine->succeed("mc cat minio/test-bucket/test.txt") =~ /Test from Python/ or die; - $machine->shutdown; - - ''; + # Create a test bucket on the server + machine.succeed( + "mc config host add minio http://localhost:9000 ${accessKey} ${secretKey} S3v4" + ) + machine.succeed("mc mb minio/test-bucket") + machine.succeed("${minioPythonScript}") + assert "test-bucket" in machine.succeed("mc ls minio") + assert "Test from Python" in machine.succeed("mc cat minio/test-bucket/test.txt") + machine.shutdown() + ''; }) diff --git a/nixos/tests/sudo.nix b/nixos/tests/sudo.nix index fc16b99cc19c..5bbec3d57269 100644 --- a/nixos/tests/sudo.nix +++ b/nixos/tests/sudo.nix @@ -4,7 +4,7 @@ let password = "helloworld"; in - import ./make-test.nix ({ pkgs, ...} : { + import ./make-test-python.nix ({ pkgs, ...} : { name = "sudo"; meta = with pkgs.stdenv.lib.maintainers; { maintainers = [ lschuermann ]; @@ -50,44 +50,34 @@ in testScript = '' - subtest "users in wheel group should have passwordless sudo", sub { - $machine->succeed("su - test0 -c \"sudo -u root true\""); - }; + with subtest("users in wheel group should have passwordless sudo"): + machine.succeed('su - test0 -c "sudo -u root true"') - subtest "test1 user should have sudo with password", sub { - $machine->succeed("su - test1 -c \"echo ${password} | sudo -S -u root true\""); - }; + with subtest("test1 user should have sudo with password"): + machine.succeed('su - test1 -c "echo ${password} | sudo -S -u root true"') - subtest "test1 user should not be able to use sudo without password", sub { - $machine->fail("su - test1 -c \"sudo -n -u root true\""); - }; + with subtest("test1 user should not be able to use sudo without password"): + machine.fail('su - test1 -c "sudo -n -u root true"') - subtest "users in group 'foobar' should be able to use sudo with password", sub { - $machine->succeed("sudo -u test2 echo ${password} | sudo -S -u root true"); - }; + with subtest("users in group 'foobar' should be able to use sudo with password"): + machine.succeed("sudo -u test2 echo ${password} | sudo -S -u root true") - subtest "users in group 'barfoo' should be able to use sudo without password", sub { - $machine->succeed("sudo -u test3 sudo -n -u root true"); - }; + with subtest("users in group 'barfoo' should be able to use sudo without password"): + machine.succeed("sudo -u test3 sudo -n -u root true") - subtest "users in group 'baz' (GID 1337) should be able to use sudo without password", sub { - $machine->succeed("sudo -u test4 sudo -n -u root echo true"); - }; + with subtest("users in group 'baz' (GID 1337)"): + machine.succeed("sudo -u test4 sudo -n -u root echo true") - subtest "test5 user should be able to run commands under test1", sub { - $machine->succeed("sudo -u test5 sudo -n -u test1 true"); - }; + with subtest("test5 user should be able to run commands under test1"): + machine.succeed("sudo -u test5 sudo -n -u test1 true") - subtest "test5 user should not be able to run commands under root", sub { - $machine->fail("sudo -u test5 sudo -n -u root true"); - }; + with subtest("test5 user should not be able to run commands under root"): + machine.fail("sudo -u test5 sudo -n -u root true") - subtest "test5 user should be able to keep his environment", sub { - $machine->succeed("sudo -u test5 sudo -n -E -u test1 true"); - }; + with subtest("test5 user should be able to keep his environment"): + machine.succeed("sudo -u test5 sudo -n -E -u test1 true") - subtest "users in group 'barfoo' should not be able to keep their environment", sub { - $machine->fail("sudo -u test3 sudo -n -E -u root true"); - }; + with subtest("users in group 'barfoo' should not be able to keep their environment"): + machine.fail("sudo -u test3 sudo -n -E -u root true") ''; }) diff --git a/nixos/tests/uwsgi.nix b/nixos/tests/uwsgi.nix index afc03e74ed7e..78a87147f55c 100644 --- a/nixos/tests/uwsgi.nix +++ b/nixos/tests/uwsgi.nix @@ -1,4 +1,4 @@ -import ./make-test.nix ({ pkgs, ... }: +import ./make-test-python.nix ({ pkgs, ... }: { name = "uwsgi"; meta = with pkgs.stdenv.lib.maintainers; { @@ -30,9 +30,9 @@ import ./make-test.nix ({ pkgs, ... }: testScript = '' - $machine->waitForUnit('multi-user.target'); - $machine->waitForUnit('uwsgi.service'); - $machine->waitForOpenPort(8000); - $machine->succeed('curl -v 127.0.0.1:8000 | grep "Hello World!"'); + machine.wait_for_unit("multi-user.target") + machine.wait_for_unit("uwsgi.service") + machine.wait_for_open_port(8000) + assert "Hello World" in machine.succeed("curl -v 127.0.0.1:8000") ''; }) diff --git a/nixos/tests/wordpress.nix b/nixos/tests/wordpress.nix index c6acfa6c1f3d..64c533d70f42 100644 --- a/nixos/tests/wordpress.nix +++ b/nixos/tests/wordpress.nix @@ -1,9 +1,13 @@ -import ./make-test.nix ({ pkgs, ... }: +import ./make-test-python.nix ({ pkgs, ... }: { name = "wordpress"; meta = with pkgs.stdenv.lib.maintainers; { - maintainers = [ grahamc ]; # under duress! + maintainers = [ + flokli + grahamc # under duress! + mmilata + ]; }; machine = @@ -23,19 +27,31 @@ import ./make-test.nix ({ pkgs, ... }: }; testScript = '' - startAll; + import re - $machine->waitForUnit("httpd"); - $machine->waitForUnit("phpfpm-wordpress-site1.local"); - $machine->waitForUnit("phpfpm-wordpress-site2.local"); + start_all() - $machine->succeed("curl -L site1.local | grep 'Welcome to the famous'"); - $machine->succeed("curl -L site2.local | grep 'Welcome to the famous'"); + machine.wait_for_unit("httpd") - $machine->succeed("systemctl --no-pager show wordpress-init-site1.local.service | grep 'ExecStart=.*status=0'"); - $machine->succeed("systemctl --no-pager show wordpress-init-site2.local.service | grep 'ExecStart=.*status=0'"); - $machine->succeed("grep -E '^define.*NONCE_SALT.{64,};\$' /var/lib/wordpress/site1.local/secret-keys.php"); - $machine->succeed("grep -E '^define.*NONCE_SALT.{64,};\$' /var/lib/wordpress/site2.local/secret-keys.php"); - ''; + machine.wait_for_unit("phpfpm-wordpress-site1.local") + machine.wait_for_unit("phpfpm-wordpress-site2.local") + + site_names = ["site1.local", "site2.local"] + + with subtest("website returns welcome screen"): + for site_name in site_names: + assert "Welcome to the famous" in machine.succeed(f"curl -L {site_name}") + with subtest("wordpress-init went through"): + for site_name in site_names: + info = machine.get_unit_info(f"wordpress-init-{site_name}") + assert info.Result == "success" + + with subtest("secret keys are set"): + re.compile(r"^define.*NONCE_SALT.{64,};$") + for site_name in site_names: + assert r.match( + machine.succeed(f"cat /var/lib/wordpress/{site_name}/secret-keys.php") + ) + ''; }) |