summary refs log tree commit diff
path: root/nixos/modules/virtualisation/nova.nix
blob: 8795b5b52d5a49047342e3bde403eaf1be30b7f6 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
# Module for Nova, a.k.a. OpenStack Compute.

{ config, lib, pkgs, ... }:

with lib;

let

  cfg = config.virtualisation.nova;

  nova = pkgs.nova;

  novaConf = pkgs.writeText "nova.conf"
    ''
      --nodaemon
      --verbose
      ${cfg.extraConfig}
    '';

in

{

  ###### interface

  options = {

    virtualisation.nova.enableSingleNode =
      mkOption {
        default = false;
        description =
          ''
            This option enables Nova, also known as OpenStack Compute,
            a cloud computing system, as a single-machine
            installation.  That is, all of Nova's components are
            enabled on this machine, using SQLite as Nova's database.
            This is useful for evaluating and experimenting with Nova.
            However, for a real cloud computing environment, you'll
            want to enable some of Nova's services on other machines,
            and use a database such as MySQL.
          '';
      };

    virtualisation.nova.extraConfig =
      mkOption {
        default = "";
        description =
          ''
            Additional text appended to <filename>nova.conf</filename>,
            the main Nova configuration file.
          '';
      };

  };


  ###### implementation

  config = mkIf cfg.enableSingleNode {

    environment.systemPackages = [ nova pkgs.euca2ools pkgs.novaclient ];

    environment.etc =
      [ { source = novaConf;
          target = "nova/nova.conf";
        }
      ];

    # Nova requires libvirtd and RabbitMQ.
    virtualisation.libvirtd.enable = true;
    services.rabbitmq.enable = true;

    # `qemu-nbd' required the `nbd' kernel module.
    boot.kernelModules = [ "nbd" ];

    system.activationScripts.nova =
      ''
        mkdir -m 755 -p /var/lib/nova
        mkdir -m 755 -p /var/lib/nova/networks
        mkdir -m 700 -p /var/lib/nova/instances
        mkdir -m 700 -p /var/lib/nova/keys

        # Allow the CA certificate generation script (called by
        # nova-api) to work.
        mkdir -m 700 -p /var/lib/nova/CA /var/lib/nova/CA/private

        # Initialise the SQLite database.
        ${nova}/bin/nova-manage db sync
      '';

    # `nova-api' receives and executes external client requests from
    # tools such as euca2ools.  It listens on port 8773 (XML) and 8774
    # (JSON).
    jobs.nova_api =
      { name = "nova-api";

        description = "Nova API service";

        startOn = "ip-up";

        # `openssl' is required to generate the CA.  `openssh' is
        # required to generate key pairs.
        path = [ pkgs.openssl pkgs.openssh pkgs.bash ];

        respawn = false;

        exec = "${nova}/bin/nova-api --flagfile=${novaConf} --api_paste_config=${nova}/etc/nova/api-paste.ini";
      };

    # `nova-objectstore' is a simple image server.  Useful if you're
    # not running the OpenStack Imaging Service (Swift).  It serves
    # images placed in /var/lib/nova/images/.
    jobs.nova_objectstore =
      { name = "nova-objectstore";

        description = "Nova Simple Object Store Service";

        startOn = "ip-up";

        preStart =
          ''
            mkdir -m 700 -p /var/lib/nova/images
          '';

        exec = "${nova}/bin/nova-objectstore --flagfile=${novaConf}";
      };

    # `nova-scheduler' schedules VM execution requests.
    jobs.nova_scheduler =
      { name = "nova-scheduler";

        description = "Nova Scheduler Service";

        startOn = "ip-up";

        exec = "${nova}/bin/nova-scheduler --flagfile=${novaConf}";
      };

    # `nova-compute' starts and manages virtual machines.
    jobs.nova_compute =
      { name = "nova-compute";

        description = "Nova Compute Service";

        startOn = "ip-up";

        path =
          [ pkgs.sudo pkgs.vlan pkgs.nettools pkgs.iptables pkgs.qemu_kvm
            pkgs.e2fsprogs pkgs.utillinux pkgs.multipath_tools pkgs.iproute
            pkgs.bridge_utils
          ];

        exec = "${nova}/bin/nova-compute --flagfile=${novaConf}";
      };

    # `nova-network' manages networks and allocates IP addresses.
    jobs.nova_network =
      { name = "nova-network";

        description = "Nova Network Service";

        startOn = "ip-up";

        path =
          [ pkgs.sudo pkgs.vlan pkgs.dnsmasq pkgs.nettools pkgs.iptables
            pkgs.iproute pkgs.bridge_utils pkgs.radvd
          ];

        exec = "${nova}/bin/nova-network --flagfile=${novaConf}";
      };

  };

}