summary refs log tree commit diff
path: root/nixos/modules/virtualisation/openvswitch.nix
blob: 32646f60f8e046234f82802b9fc11a35d77e3151 (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
# Systemd services for openvswitch

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

with lib;

let
  cfg = config.virtualisation.vswitch;

in {

  options.virtualisation.vswitch = {
    enable = mkOption {
      type = types.bool;
      default = false;
      description = lib.mdDoc ''
        Whether to enable Open vSwitch. A configuration daemon (ovs-server)
        will be started.
        '';
    };

    resetOnStart = mkOption {
      type = types.bool;
      default = false;
      description = lib.mdDoc ''
        Whether to reset the Open vSwitch configuration database to a default
        configuration on every start of the systemd `ovsdb.service`.
        '';
    };

    package = mkOption {
      type = types.package;
      default = pkgs.openvswitch;
      defaultText = literalExpression "pkgs.openvswitch";
      description = lib.mdDoc ''
        Open vSwitch package to use.
      '';
    };
  };

  config = mkIf cfg.enable (let

    # Where the communication sockets live
    runDir = "/run/openvswitch";

    # The path to the an initialized version of the database
    db = pkgs.stdenv.mkDerivation {
      name = "vswitch.db";
      dontUnpack = true;
      buildPhase = "true";
      buildInputs = with pkgs; [
        cfg.package
      ];
      installPhase = "mkdir -p $out";
    };

  in {
    environment.systemPackages = [ cfg.package ];
    boot.kernelModules = [ "tun" "openvswitch" ];

    boot.extraModulePackages = [ cfg.package ];

    systemd.services.ovsdb = {
      description = "Open_vSwitch Database Server";
      wantedBy = [ "multi-user.target" ];
      after = [ "systemd-udev-settle.service" ];
      path = [ cfg.package ];
      restartTriggers = [ db cfg.package ];
      # Create the config database
      preStart =
        ''
        mkdir -p ${runDir}
        mkdir -p /var/db/openvswitch
        chmod +w /var/db/openvswitch
        ${optionalString cfg.resetOnStart "rm -f /var/db/openvswitch/conf.db"}
        if [[ ! -e /var/db/openvswitch/conf.db ]]; then
          ${cfg.package}/bin/ovsdb-tool create \
            "/var/db/openvswitch/conf.db" \
            "${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 =
          ''
          ${cfg.package}/bin/ovsdb-server \
            --remote=punix:${runDir}/db.sock \
            --private-key=db:Open_vSwitch,SSL,private_key \
            --certificate=db:Open_vSwitch,SSL,certificate \
            --bootstrap-ca-cert=db:Open_vSwitch,SSL,ca_cert \
            --unixctl=ovsdb.ctl.sock \
            --pidfile=/run/openvswitch/ovsdb.pid \
            --detach \
            /var/db/openvswitch/conf.db
          '';
        Restart = "always";
        RestartSec = 3;
        PIDFile = "/run/openvswitch/ovsdb.pid";
        # Use service type 'forking' to correctly determine when ovsdb-server is ready.
        Type = "forking";
      };
      postStart = ''
        ${cfg.package}/bin/ovs-vsctl --timeout 3 --retry --no-wait init
      '';
    };

    systemd.services.ovs-vswitchd = {
      description = "Open_vSwitch Daemon";
      wantedBy = [ "multi-user.target" ];
      bindsTo = [ "ovsdb.service" ];
      after = [ "ovsdb.service" ];
      path = [ cfg.package ];
      serviceConfig = {
        ExecStart = ''
          ${cfg.package}/bin/ovs-vswitchd \
          --pidfile=/run/openvswitch/ovs-vswitchd.pid \
          --detach
        '';
        PIDFile = "/run/openvswitch/ovs-vswitchd.pid";
        # Use service type 'forking' to correctly determine when vswitchd is ready.
        Type = "forking";
        Restart = "always";
        RestartSec = 3;
      };
    };

  });

  imports = [
    (mkRemovedOptionModule [ "virtualisation" "vswitch" "ipsec" ] ''
      OpenVSwitch IPSec functionality has been removed, because it depended on racoon,
      which was removed from nixpkgs, because it was abanoded upstream.
    '')
  ];

  meta.maintainers = with maintainers; [ netixx ];

}