about summary refs log tree commit diff
path: root/nixos
diff options
context:
space:
mode:
authorJörg Thalheim <joerg@higgsboson.tk>2017-01-01 06:39:37 +0100
committerGitHub <noreply@github.com>2017-01-01 06:39:37 +0100
commitdd4bedba5223e7ec8de92aaa15c1f6a42f599cc3 (patch)
tree8f2044f212c352d4012dc667d6478033bfb5d197 /nixos
parent48f270db52b6b17d917e447eb236ccaac03c2b55 (diff)
parent49efa083c780cf24a65a90adf0caac4cb70df415 (diff)
Merge pull request #21447 from nlewo/pr/glance
nixos/glance: init at liberty version
Diffstat (limited to 'nixos')
-rw-r--r--nixos/modules/misc/ids.nix2
-rw-r--r--nixos/modules/module-list.nix1
-rw-r--r--nixos/modules/virtualisation/openstack/common.nix30
-rw-r--r--nixos/modules/virtualisation/openstack/glance.nix245
-rw-r--r--nixos/release.nix1
-rw-r--r--nixos/tests/glance.nix77
6 files changed, 356 insertions, 0 deletions
diff --git a/nixos/modules/misc/ids.nix b/nixos/modules/misc/ids.nix
index eb6f8e7068964..6ab4b24a3491a 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 5900a4ce0d2cf..f07fe7c1395c3 100644
--- a/nixos/modules/module-list.nix
+++ b/nixos/modules/module-list.nix
@@ -633,4 +633,5 @@
   ./virtualisation/xen-dom0.nix
   ./virtualisation/xe-guest-utilities.nix
   ./virtualisation/openstack/keystone.nix
+  ./virtualisation/openstack/glance.nix
 ]
diff --git a/nixos/modules/virtualisation/openstack/common.nix b/nixos/modules/virtualisation/openstack/common.nix
index 3fce54a2fa59f..2feb0a8739512 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 0000000000000..4d85718e369c9
--- /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 366eecf773e25..dfa9b67654fb6 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 0000000000000..992b77227a4bc
--- /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;
+    '';
+}