diff options
Diffstat (limited to 'nixos')
-rw-r--r-- | nixos/lib/make-system-tarball.sh | 2 | ||||
-rw-r--r-- | nixos/modules/misc/ids.nix | 2 | ||||
-rw-r--r-- | nixos/modules/module-list.nix | 3 | ||||
-rw-r--r-- | nixos/modules/programs/gphoto2.nix | 31 | ||||
-rw-r--r-- | nixos/modules/rename.nix | 3 | ||||
-rw-r--r-- | nixos/modules/services/audio/alsa.nix | 41 | ||||
-rw-r--r-- | nixos/modules/services/audio/mpd.nix | 8 | ||||
-rw-r--r-- | nixos/modules/services/networking/dnscrypt-proxy.nix | 2 | ||||
-rw-r--r-- | nixos/modules/services/networking/miredo.nix | 93 | ||||
-rw-r--r-- | nixos/modules/services/torrent/flexget.nix | 6 | ||||
-rw-r--r-- | nixos/modules/services/x11/desktop-managers/gnome3.nix | 1 | ||||
-rw-r--r-- | nixos/modules/virtualisation/docker.nix | 4 | ||||
-rw-r--r-- | nixos/modules/virtualisation/openstack/common.nix | 30 | ||||
-rw-r--r-- | nixos/modules/virtualisation/openstack/glance.nix | 245 | ||||
-rw-r--r-- | nixos/release.nix | 1 | ||||
-rw-r--r-- | nixos/tests/glance.nix | 77 |
16 files changed, 528 insertions, 21 deletions
diff --git a/nixos/lib/make-system-tarball.sh b/nixos/lib/make-system-tarball.sh index efb83d91428..73a009d8488 100644 --- a/nixos/lib/make-system-tarball.sh +++ b/nixos/lib/make-system-tarball.sh @@ -54,7 +54,7 @@ mkdir -p $out/tarball rm env-vars -tar --sort=name --mtime='1970-01-01' -cvJf $out/tarball/$fileName.tar.xz * $extraArgs +tar --sort=name --mtime='@1' --owner=0 --group=0 --numeric-owner -cvJf $out/tarball/$fileName.tar.xz * $extraArgs mkdir -p $out/nix-support echo $system > $out/nix-support/system diff --git a/nixos/modules/misc/ids.nix b/nixos/modules/misc/ids.nix index eb6f8e70689..6ab4b24a349 100644 --- a/nixos/modules/misc/ids.nix +++ b/nixos/modules/misc/ids.nix @@ -281,6 +281,7 @@ riak-cs = 263; infinoted = 264; keystone = 265; + glance = 266; # When adding a uid, make sure it doesn't match an existing gid. And don't use uids above 399! @@ -532,6 +533,7 @@ riak-cs = 263; infinoted = 264; keystone = 265; + glance = 266; # When adding a gid, make sure it doesn't match an existing # uid. Users and groups with the same name should have equal diff --git a/nixos/modules/module-list.nix b/nixos/modules/module-list.nix index cd12fe4f9b3..be09fb80e0a 100644 --- a/nixos/modules/module-list.nix +++ b/nixos/modules/module-list.nix @@ -71,6 +71,7 @@ ./programs/environment.nix ./programs/fish.nix ./programs/freetds.nix + ./programs/gphoto2.nix ./programs/info.nix ./programs/java.nix ./programs/kbdlight.nix @@ -392,6 +393,7 @@ ./services/networking/minidlna.nix ./services/networking/miniupnpd.nix ./services/networking/mosquitto.nix + ./services/networking/miredo.nix ./services/networking/mstpd.nix ./services/networking/murmur.nix ./services/networking/namecoind.nix @@ -632,4 +634,5 @@ ./virtualisation/xen-dom0.nix ./virtualisation/xe-guest-utilities.nix ./virtualisation/openstack/keystone.nix + ./virtualisation/openstack/glance.nix ] diff --git a/nixos/modules/programs/gphoto2.nix b/nixos/modules/programs/gphoto2.nix new file mode 100644 index 00000000000..47822562aee --- /dev/null +++ b/nixos/modules/programs/gphoto2.nix @@ -0,0 +1,31 @@ +{ config, lib, pkgs, ... }: + +with lib; + +{ + meta.maintainers = [ maintainers.league ]; + + ###### interface + options = { + programs.gphoto2 = { + enable = mkOption { + default = false; + example = true; + type = types.bool; + description = '' + Whether to configure system to use gphoto2. + To grant digital camera access to a user, the user must + be part of the camera group: + <code>users.extraUsers.alice.extraGroups = ["camera"];</code> + ''; + }; + }; + }; + + ###### implementation + config = mkIf config.programs.gphoto2.enable { + services.udev.packages = [ pkgs.libgphoto2 ]; + environment.systemPackages = [ pkgs.gphoto2 ]; + users.extraGroups.camera = {}; + }; +} diff --git a/nixos/modules/rename.nix b/nixos/modules/rename.nix index a89ce2c743d..8102e0e1f64 100644 --- a/nixos/modules/rename.nix +++ b/nixos/modules/rename.nix @@ -150,6 +150,9 @@ with lib; # tarsnap (mkRemovedOptionModule [ "services" "tarsnap" "cachedir" ] "Use services.tarsnap.archives.<name>.cachedir") + # alsa + (mkRenamedOptionModule [ "sound" "enableMediaKeys" ] [ "sound" "mediaKeys" "enable" ]) + # Options that are obsolete and have no replacement. (mkRemovedOptionModule [ "boot" "initrd" "luks" "enable" ] "") (mkRemovedOptionModule [ "programs" "bash" "enable" ] "") diff --git a/nixos/modules/services/audio/alsa.nix b/nixos/modules/services/audio/alsa.nix index c63f4dc8d7f..53786dbc627 100644 --- a/nixos/modules/services/audio/alsa.nix +++ b/nixos/modules/services/audio/alsa.nix @@ -33,16 +33,6 @@ in ''; }; - enableMediaKeys = mkOption { - type = types.bool; - default = false; - description = '' - Whether to enable volume and capture control with keyboard media keys. - - Enabling this will turn on <option>services.actkbd</option>. - ''; - }; - extraConfig = mkOption { type = types.lines; default = ""; @@ -54,6 +44,31 @@ in ''; }; + mediaKeys = { + + enable = mkOption { + type = types.bool; + default = false; + description = '' + Whether to enable volume and capture control with keyboard media keys. + + Enabling this will turn on <option>services.actkbd</option>. + ''; + }; + + volumeStep = mkOption { + type = types.string; + default = "1"; + example = "1%"; + description = '' + The value by which to increment/decrement volume on media keys. + + See amixer(1) for allowed values. + ''; + }; + + }; + }; }; @@ -90,17 +105,17 @@ in }; }; - services.actkbd = mkIf config.sound.enableMediaKeys { + services.actkbd = mkIf config.sound.mediaKeys.enable { enable = true; bindings = [ # "Mute" media key { keys = [ 113 ]; events = [ "key" ]; command = "${alsaUtils}/bin/amixer -q set Master toggle"; } # "Lower Volume" media key - { keys = [ 114 ]; events = [ "key" "rep" ]; command = "${alsaUtils}/bin/amixer -q set Master 1- unmute"; } + { keys = [ 114 ]; events = [ "key" "rep" ]; command = "${alsaUtils}/bin/amixer -q set Master ${config.sound.mediaKeys.volumeStep}- unmute"; } # "Raise Volume" media key - { keys = [ 115 ]; events = [ "key" "rep" ]; command = "${alsaUtils}/bin/amixer -q set Master 1+ unmute"; } + { keys = [ 115 ]; events = [ "key" "rep" ]; command = "${alsaUtils}/bin/amixer -q set Master ${config.sound.mediaKeys.volumeStep}+ unmute"; } # "Mic Mute" media key { keys = [ 190 ]; events = [ "key" ]; command = "${alsaUtils}/bin/amixer -q set Capture toggle"; } diff --git a/nixos/modules/services/audio/mpd.nix b/nixos/modules/services/audio/mpd.nix index 5ec2e2c2623..a89215d7382 100644 --- a/nixos/modules/services/audio/mpd.nix +++ b/nixos/modules/services/audio/mpd.nix @@ -83,11 +83,11 @@ in { listenAddress = mkOption { type = types.str; - default = "any"; + default = "127.0.0.1"; + example = "any"; description = '' - This setting sets the address for the daemon to listen on. Careful attention - should be paid if this is assigned to anything other then the default, any. - This setting can deny access to control of the daemon. + The address for the daemon to listen on. + Use <literal>any</literal> to listen on all addresses. ''; }; diff --git a/nixos/modules/services/networking/dnscrypt-proxy.nix b/nixos/modules/services/networking/dnscrypt-proxy.nix index 82bf178f4cb..462039803f8 100644 --- a/nixos/modules/services/networking/dnscrypt-proxy.nix +++ b/nixos/modules/services/networking/dnscrypt-proxy.nix @@ -263,6 +263,8 @@ in systemd.services.dnscrypt-proxy = { description = "dnscrypt-proxy daemon"; + before = [ "nss-lookup.target" ]; + after = [ "network.target" ] ++ optional apparmorEnabled "apparmor.service" ++ optional useUpstreamResolverList "init-dnscrypt-proxy-statedir.service"; diff --git a/nixos/modules/services/networking/miredo.nix b/nixos/modules/services/networking/miredo.nix new file mode 100644 index 00000000000..e4422e7f5b0 --- /dev/null +++ b/nixos/modules/services/networking/miredo.nix @@ -0,0 +1,93 @@ +{ config, lib, pkgs, ... }: + +with lib; + +let + cfg = config.services.miredo; + pidFile = "/run/miredo.pid"; + miredoConf = pkgs.writeText "miredo.conf" '' + InterfaceName ${cfg.interfaceName} + ServerAddress ${cfg.serverAddress} + ${optionalString (cfg.bindAddress != null) "BindAddress ${cfg.bindAddress}"} + ${optionalString (cfg.bindPort != null) "BindPort ${cfg.bindPort}"} + ''; +in +{ + + ###### interface + + options = { + + services.miredo = { + + enable = mkEnableOption "Whether miredo should be run on startup."; + + package = mkOption { + type = types.package; + default = pkgs.miredo; + defaultText = "pkgs.miredo"; + description = '' + The package to use for the miredo daemon's binary. + ''; + }; + + serverAddress = mkOption { + default = "teredo.remlab.net"; + type = types.str; + description = '' + The hostname or primary IPv4 address of the Teredo server. + This setting is required if Miredo runs as a Teredo client. + "teredo.remlab.net" is an experimental service for testing only. + Please use another server for production and/or large scale deployments. + ''; + }; + + interfaceName = mkOption { + default = "teredo"; + type = types.str; + description = '' + Name of the network tunneling interface. + ''; + }; + + bindAddress = mkOption { + default = null; + type = types.nullOr types.str; + description = '' + Depending on the local firewall/NAT rules, you might need to force + Miredo to use a fixed UDP port and or IPv4 address. + ''; + }; + + bindPort = mkOption { + default = null; + type = types.nullOr types.str; + description = '' + Depending on the local firewall/NAT rules, you might need to force + Miredo to use a fixed UDP port and or IPv4 address. + ''; + }; + }; + }; + + + ###### implementation + + config = mkIf cfg.enable { + + systemd.services.miredo = { + wantedBy = [ "multi-user.target" ]; + after = [ "network.target" ]; + description = "Teredo IPv6 Tunneling Daemon"; + serviceConfig = { + Restart = "always"; + RestartSec = "5s"; + ExecStartPre = "${cfg.package}/bin/miredo-checkconf -f ${miredoConf}"; + ExecStart = "${cfg.package}/bin/miredo -c ${miredoConf} -p ${pidFile} -f"; + ExecReload = "/bin/kill -HUP $MAINPID"; + }; + }; + + }; + +} diff --git a/nixos/modules/services/torrent/flexget.nix b/nixos/modules/services/torrent/flexget.nix index 1252aa1c549..4b9038e3e25 100644 --- a/nixos/modules/services/torrent/flexget.nix +++ b/nixos/modules/services/torrent/flexget.nix @@ -4,7 +4,7 @@ with lib; let cfg = config.services.flexget; - pkg = pkgs.python27Packages.flexget; + pkg = pkgs.flexget; ymlFile = pkgs.writeText "flexget.yml" '' ${cfg.config} @@ -54,12 +54,12 @@ in { config = mkIf cfg.enable { - environment.systemPackages = [ pkgs.python27Packages.flexget ]; + environment.systemPackages = [ pkg ]; systemd.services = { flexget = { description = "FlexGet Daemon"; - path = [ pkgs.pythonPackages.flexget ]; + path = [ pkg ]; serviceConfig = { User = cfg.user; Environment = "TZ=${config.time.timeZone}"; diff --git a/nixos/modules/services/x11/desktop-managers/gnome3.nix b/nixos/modules/services/x11/desktop-managers/gnome3.nix index 5d1af09e7aa..17e84b1d9a1 100644 --- a/nixos/modules/services/x11/desktop-managers/gnome3.nix +++ b/nixos/modules/services/x11/desktop-managers/gnome3.nix @@ -123,6 +123,7 @@ in { services.packagekit.enable = mkDefault true; hardware.bluetooth.enable = mkDefault true; services.xserver.libinput.enable = mkDefault true; # for controlling touchpad settings via gnome control center + services.udev.packages = [ pkgs.gnome3.gnome_settings_daemon ]; fonts.fonts = [ pkgs.dejavu_fonts pkgs.cantarell_fonts ]; diff --git a/nixos/modules/virtualisation/docker.nix b/nixos/modules/virtualisation/docker.nix index 92249573a4b..4b30a38f832 100644 --- a/nixos/modules/virtualisation/docker.nix +++ b/nixos/modules/virtualisation/docker.nix @@ -130,4 +130,8 @@ in } ]); + imports = [ + (mkRemovedOptionModule ["virtualisation" "docker" "socketActivation"] "This option was removed in favor of starting docker at boot") + ]; + } diff --git a/nixos/modules/virtualisation/openstack/common.nix b/nixos/modules/virtualisation/openstack/common.nix index 3fce54a2fa5..2feb0a87395 100644 --- a/nixos/modules/virtualisation/openstack/common.nix +++ b/nixos/modules/virtualisation/openstack/common.nix @@ -51,4 +51,34 @@ rec { }; };}); }; + + databaseOption = name: { + host = mkOption { + type = types.str; + default = "localhost"; + description = '' + Host of the database. + ''; + }; + + name = mkOption { + type = types.str; + default = name; + description = '' + Name of the existing database. + ''; + }; + + user = mkOption { + type = types.str; + default = name; + description = '' + The database user. The user must exist and has access to + the specified database. + ''; + }; + password = mkSecretOption { + name = name + "MysqlPassword"; + description = "The database user's password";}; + }; } diff --git a/nixos/modules/virtualisation/openstack/glance.nix b/nixos/modules/virtualisation/openstack/glance.nix new file mode 100644 index 00000000000..4d85718e369 --- /dev/null +++ b/nixos/modules/virtualisation/openstack/glance.nix @@ -0,0 +1,245 @@ +{ config, lib, pkgs, ... }: + +with lib; with import ./common.nix {inherit lib;}; + +let + cfg = config.virtualisation.openstack.glance; + commonConf = '' + [database] + connection = "mysql://${cfg.database.user}:${cfg.database.password.pattern}@${cfg.database.host}/${cfg.database.name}" + notification_driver = noop + + [keystone_authtoken] + auth_url = ${cfg.authUrl} + auth_plugin = password + project_name = service + project_domain_id = default + user_domain_id = default + username = ${cfg.serviceUsername} + password = ${cfg.servicePassword.pattern} + + [glance_store] + default_store = file + filesystem_store_datadir = /var/lib/glance/images/ + ''; + glanceApiConfTpl = pkgs.writeText "glance-api.conf" '' + ${commonConf} + + [paste_deploy] + flavor = keystone + config_file = ${cfg.package}/etc/glance-api-paste.ini + ''; + glanceRegistryConfTpl = pkgs.writeText "glance-registry.conf" '' + ${commonConf} + + [paste_deploy] + config_file = ${cfg.package}/etc/glance-registry-paste.ini + ''; + glanceApiConf = "/var/lib/glance/glance-api.conf"; + glanceRegistryConf = "/var/lib/glance/glance-registry.conf"; + +in { + options.virtualisation.openstack.glance = { + package = mkOption { + type = types.package; + default = pkgs.glance; + example = literalExample "pkgs.glance"; + description = '' + Glance package to use. + ''; + }; + + enable = mkOption { + default = false; + type = types.bool; + description = '' + This option enables Glance as a single-machine + installation. That is, all of Glance's components are + enabled on this machine. This is useful for evaluating and + experimenting with Glance. Note we are currently not + providing any configurations for a multi-node setup. + ''; + }; + + authUrl = mkOption { + type = types.str; + default = http://localhost:5000; + description = '' + Complete public Identity (Keystone) API endpoint. Note this is + unversionned. + ''; + }; + + serviceUsername = mkOption { + type = types.str; + default = "glance"; + description = '' + The Glance service username. This user is created if bootstrap + is enable, otherwise it has to be manually created before + starting this service. + ''; + }; + + servicePassword = mkSecretOption { + name = "glanceAdminPassword"; + description = '' + The Glance service user's password. + ''; + }; + + database = databaseOption "glance"; + + bootstrap = { + enable = mkOption { + default = false; + type = types.bool; + description = '' + Bootstrap the Glance service by creating the service tenant, + an admin account and a public endpoint. This option provides + a ready-to-use glance service. This is only done at the + first Glance execution by the systemd post start section. + The keystone admin account is used to create required + Keystone resource for the Glance service. + + <note><para> This option is a helper for setting up + development or testing environments.</para></note> + ''; + }; + + endpointPublic = mkOption { + type = types.str; + default = "http://localhost:9292"; + description = '' + The public image endpoint. The link <link + xlink:href="http://docs.openstack.org/liberty/install-guide-rdo/keystone-services.html"> + create endpoint</link> provides more informations + about that. + ''; + }; + + keystoneAdminUsername = mkOption { + type = types.str; + default = "admin"; + description = '' + The keystone admin user name used to create the Glance account. + ''; + }; + + keystoneAdminPassword = mkSecretOption { + name = "keystoneAdminPassword"; + description = '' + The keystone admin user's password. + ''; + }; + + keystoneAdminTenant = mkOption { + type = types.str; + default = "admin"; + description = '' + The keystone admin tenant used to create the Glance account. + ''; + }; + keystoneAuthUrl = mkOption { + type = types.str; + default = "http://localhost:5000/v2.0"; + description = '' + The keystone auth url used to create the Glance account. + ''; + }; + }; + }; + + config = mkIf cfg.enable { + users.extraUsers = [{ + name = "glance"; + group = "glance"; + uid = config.ids.gids.glance; + + }]; + users.extraGroups = [{ + name = "glance"; + gid = config.ids.gids.glance; + }]; + + systemd.services.glance-registry = { + description = "OpenStack Glance Registry Daemon"; + after = [ "network.target"]; + path = [ pkgs.curl pkgs.pythonPackages.keystoneclient pkgs.gawk ]; + wantedBy = [ "multi-user.target" ]; + preStart = '' + mkdir -m 775 -p /var/lib/glance/{images,scrubber,image_cache} + chown glance:glance /var/lib/glance/{images,scrubber,image_cache} + + # Secret file managment + cp ${glanceRegistryConfTpl} ${glanceRegistryConf}; + chown glance:glance ${glanceRegistryConf}; + chmod 640 ${glanceRegistryConf} + ${replaceSecret cfg.database.password glanceRegistryConf} + ${replaceSecret cfg.servicePassword glanceRegistryConf} + + cp ${glanceApiConfTpl} ${glanceApiConf}; + chown glance:glance ${glanceApiConf}; + chmod 640 ${glanceApiConf} + ${replaceSecret cfg.database.password glanceApiConf} + ${replaceSecret cfg.servicePassword glanceApiConf} + + # Initialise the database + ${cfg.package}/bin/glance-manage --config-file=${glanceApiConf} --config-file=${glanceRegistryConf} db_sync + ''; + postStart = '' + set -eu + export OS_AUTH_URL=${cfg.bootstrap.keystoneAuthUrl} + export OS_USERNAME=${cfg.bootstrap.keystoneAdminUsername} + export OS_PASSWORD=${getSecret cfg.bootstrap.keystoneAdminPassword} + export OS_TENANT_NAME=${cfg.bootstrap.keystoneAdminTenant} + + # Wait until the keystone is available for use + count=0 + while ! keystone user-get ${cfg.bootstrap.keystoneAdminUsername} > /dev/null + do + if [ $count -eq 30 ] + then + echo "Tried 30 times, giving up..." + exit 1 + fi + + echo "Keystone not yet started. Waiting for 1 second..." + count=$((count++)) + sleep 1 + done + + # If the service glance doesn't exist, we consider glance is + # not initialized + if ! keystone service-get glance + then + keystone service-create --type image --name glance + ID=$(keystone service-get glance | awk '/ id / { print $4 }') + keystone endpoint-create --region RegionOne --service $ID --internalurl http://localhost:9292 --adminurl http://localhost:9292 --publicurl ${cfg.bootstrap.endpointPublic} + + keystone user-create --name ${cfg.serviceUsername} --tenant service --pass ${getSecret cfg.servicePassword} + keystone user-role-add --tenant service --user ${cfg.serviceUsername} --role admin + fi + ''; + serviceConfig = { + PermissionsStartOnly = true; # preStart must be run as root + TimeoutStartSec = "600"; # 10min for initial db migrations + User = "glance"; + Group = "glance"; + ExecStart = "${cfg.package}/bin/glance-registry --config-file=${glanceRegistryConf}"; + }; + }; + systemd.services.glance-api = { + description = "OpenStack Glance API Daemon"; + after = [ "glance-registry.service" "network.target"]; + requires = [ "glance-registry.service" "network.target"]; + wantedBy = [ "multi-user.target" ]; + serviceConfig = { + PermissionsStartOnly = true; # preStart must be run as root + User = "glance"; + Group = "glance"; + ExecStart = "${cfg.package}/bin/glance-api --config-file=${glanceApiConf}"; + }; + }; + }; + +} diff --git a/nixos/release.nix b/nixos/release.nix index 366eecf773e..dfa9b67654f 100644 --- a/nixos/release.nix +++ b/nixos/release.nix @@ -242,6 +242,7 @@ in rec { tests.firewall = callTest tests/firewall.nix {}; tests.fleet = hydraJob (import tests/fleet.nix { system = "x86_64-linux"; }); #tests.gitlab = callTest tests/gitlab.nix {}; + tests.glance = callTest tests/glance.nix {}; tests.gocd-agent = callTest tests/gocd-agent.nix {}; tests.gocd-server = callTest tests/gocd-server.nix {}; tests.gnome3 = callTest tests/gnome3.nix {}; diff --git a/nixos/tests/glance.nix b/nixos/tests/glance.nix new file mode 100644 index 00000000000..992b77227a4 --- /dev/null +++ b/nixos/tests/glance.nix @@ -0,0 +1,77 @@ +{ system ? builtins.currentSystem }: + +with import ../lib/testing.nix { inherit system; }; +with pkgs.lib; + +let + glanceMysqlPassword = "glanceMysqlPassword"; + glanceAdminPassword = "glanceAdminPassword"; + + createDb = pkgs.writeText "db-provisionning.sql" '' + create database keystone; + GRANT ALL PRIVILEGES ON keystone.* TO 'keystone'@'localhost' IDENTIFIED BY 'keystone'; + GRANT ALL PRIVILEGES ON keystone.* TO 'keystone'@'%' IDENTIFIED BY 'keystone'; + + create database glance; + GRANT ALL PRIVILEGES ON glance.* TO 'glance'@'localhost' IDENTIFIED BY '${glanceMysqlPassword}'; + GRANT ALL PRIVILEGES ON glance.* TO 'glance'@'%' IDENTIFIED BY '${glanceMysqlPassword}'; + ''; + + image = + (import ../lib/eval-config.nix { + inherit system; + modules = [ ../../nixos/modules/virtualisation/nova-image.nix ]; + }).config.system.build.novaImage; + + # The admin keystone account + adminOpenstackCmd = "OS_TENANT_NAME=admin OS_USERNAME=admin OS_PASSWORD=keystone OS_AUTH_URL=http://localhost:5000/v3 OS_IDENTITY_API_VERSION=3 openstack"; + +in makeTest { + meta = with pkgs.stdenv.lib.maintainers; { + maintainers = [ lewo ]; + }; + machine = + { config, pkgs, ... }: + { + services.mysql.enable = true; + services.mysql.package = pkgs.mysql; + services.mysql.initialScript = createDb; + + virtualisation = { + openstack.keystone = { + enable = true; + database.password = { value = "keystone"; storage = "fromNixStore"; }; + adminToken = { value = "adminToken"; storage = "fromNixStore"; }; + bootstrap.enable = true; + bootstrap.adminPassword = { value = "keystone"; storage = "fromNixStore"; }; + }; + + openstack.glance = { + enable = true; + database.password = { value = glanceMysqlPassword; storage = "fromNixStore"; }; + servicePassword = { value = glanceAdminPassword; storage = "fromNixStore"; }; + + bootstrap = { + enable = true; + keystoneAdminPassword = { value = "keystone"; storage = "fromNixStore"; }; + }; + }; + + memorySize = 2096; + diskSize = 4 * 1024; + }; + + environment.systemPackages = with pkgs.pythonPackages; with pkgs; [ + openstackclient + ]; + }; + + testScript = + '' + $machine->waitForUnit("glance-api.service"); + + # Since Glance api can take time to start, we retry until success + $machine->waitUntilSucceeds("${adminOpenstackCmd} image create nixos --file ${image}/nixos.img --disk-format qcow2 --container-format bare --public"); + $machine->succeed("${adminOpenstackCmd} image list") =~ /nixos/ or die; + ''; +} |