From b7092dc95cbb6d1c77f078c5dd87200cfe62eb3a Mon Sep 17 00:00:00 2001 From: Jaka Hudoklin Date: Sun, 7 Dec 2014 21:52:52 +0100 Subject: [PATCH] nixos: add fleet module --- nixos/modules/misc/ids.nix | 1 + nixos/modules/module-list.nix | 1 + nixos/modules/virtualisation/fleet.nix | 147 +++++++++++++++++++++++++ nixos/release.nix | 1 + nixos/tests/fleet.nix | 73 ++++++++++++ 5 files changed, 223 insertions(+) create mode 100644 nixos/modules/virtualisation/fleet.nix create mode 100644 nixos/tests/fleet.nix diff --git a/nixos/modules/misc/ids.nix b/nixos/modules/misc/ids.nix index 0804a67a7dc..bdaf85a03ce 100644 --- a/nixos/modules/misc/ids.nix +++ b/nixos/modules/misc/ids.nix @@ -307,6 +307,7 @@ scollector = 156; bosun = 157; kubernetes = 158; + fleet = 159; # When adding a gid, make sure it doesn't match an existing uid. And don't use gids above 399! diff --git a/nixos/modules/module-list.nix b/nixos/modules/module-list.nix index 77a9f97d5a5..177eb6d0e19 100755 --- a/nixos/modules/module-list.nix +++ b/nixos/modules/module-list.nix @@ -399,6 +399,7 @@ ./virtualisation/container-config.nix ./virtualisation/containers.nix ./virtualisation/docker.nix + ./virtualisation/fleet.nix ./virtualisation/kubernetes.nix ./virtualisation/libvirtd.nix ./virtualisation/lxc.nix diff --git a/nixos/modules/virtualisation/fleet.nix b/nixos/modules/virtualisation/fleet.nix new file mode 100644 index 00000000000..4246da8293b --- /dev/null +++ b/nixos/modules/virtualisation/fleet.nix @@ -0,0 +1,147 @@ +{ config, lib, pkgs, ... }: + +with lib; + +let + cfg = config.virtualisation.fleet; + +in { + + ##### Interface + options.virtualisation.fleet = { + enable = mkOption { + type = types.bool; + default = false; + description = '' + Whether to enable fleet service. + ''; + }; + + listen = mkOption { + type = types.listOf types.str; + default = [ "/var/run/fleet.sock" ]; + example = [ "/var/run/fleet.sock" "127.0.0.1:49153" ]; + description = '' + Fleet listening addresses. + ''; + }; + + etcdServers = mkOption { + type = types.listOf types.str; + default = [ "http://127.0.0.1:4001" ]; + description = '' + Fleet list of etcd endpoints to use. + ''; + }; + + publicIp = mkOption { + type = types.nullOr types.str; + default = ""; + description = '' + Fleet IP address that should be published with the local Machine's + state and any socket information. If not set, fleetd will attempt + to detect the IP it should publish based on the machine's IP + routing information. + ''; + }; + + etcdCafile = mkOption { + type = types.nullOr types.path; + default = null; + description = '' + Fleet TLS ca file when SSL certificate authentication is enabled + in etcd endpoints. + ''; + }; + + etcdKeyfile = mkOption { + type = types.nullOr types.path; + default = null; + description = '' + Fleet TLS key file when SSL certificate authentication is enabled + in etcd endpoints. + ''; + }; + + etcdCertfile = mkOption { + type = types.nullOr types.path; + default = null; + description = '' + Fleet TLS cert file when SSL certificate authentication is enabled + in etcd endpoints. + ''; + }; + + metadata = mkOption { + type = types.attrsOf types.str; + default = {}; + apply = attrs: concatMapStringsSep "," (n: "${n}=${attrs."${n}"}") (attrNames attrs); + example = literalExample '' + { + region = "us-west"; + az = "us-west-1"; + } + ''; + description = '' + Key/value pairs that are published with the local to the fleet registry. + This data can be used directly by a client of fleet to make scheduling decisions. + ''; + }; + + extraConfig = mkOption { + type = types.attrsOf types.str; + apply = mapAttrs' (n: v: nameValuePair ("ETCD_" + n) v); + default = {}; + example = literalExample '' + { + VERBOSITY = 1; + ETCD_REQUEST_TIMEOUT = "2.0"; + AGENT_TTL = "40s"; + } + ''; + description = '' + Fleet extra config. See + + for configuration options. + ''; + }; + + }; + + ##### Implementation + config = mkIf cfg.enable { + systemd.services.fleet = { + description = "Fleet Init System Daemon"; + wantedBy = [ "multi-user.target" ]; + after = [ "network.target" "fleet.socket" "etcd.service" "docker.service" ]; + requires = [ "fleet.socket" ]; + environment = { + FLEET_ETCD_SERVERS = concatStringsSep "," cfg.etcdServers; + FLEET_PUBLIC_IP = cfg.publicIp; + FLEET_ETCD_CAFILE = cfg.etcdCafile; + FLEET_ETCD_KEYFILE = cfg.etcdKeyfile; + FEELT_ETCD_CERTFILE = cfg.etcdCertfile; + FLEET_METADATA = cfg.metadata; + } // cfg.extraConfig; + serviceConfig = { + ExecStart = "${pkgs.fleet}/bin/fleetd"; + Group = "fleet"; + }; + }; + + systemd.sockets.fleet = { + description = "Fleet Socket for the API"; + wantedBy = [ "sockets.target" ]; + listenStreams = cfg.listen; + socketConfig = { + ListenStream = "/var/run/fleet.sock"; + SocketMode = "0660"; + SocketUser = "root"; + SocketGroup = "fleet"; + }; + }; + + environment.systemPackages = [ pkgs.fleet ]; + users.extraGroups.fleet.gid = config.ids.gids.fleet; + }; +} diff --git a/nixos/release.nix b/nixos/release.nix index e0530276b64..b0932c318c9 100644 --- a/nixos/release.nix +++ b/nixos/release.nix @@ -244,6 +244,7 @@ in rec { tests.etcd = scrubDrv (import tests/etcd.nix { system = "x86_64-linux"; }); tests.firefox = callTest tests/firefox.nix {}; tests.firewall = callTest tests/firewall.nix {}; + tests.fleet = scrubDrv (import tests/fleet.nix { system = "x86_64-linux"; }); tests.gnome3 = callTest tests/gnome3.nix {}; tests.installer.grub1 = forAllSystems (system: scrubDrv (import tests/installer.nix { inherit system; }).grub1.test); tests.installer.lvm = forAllSystems (system: scrubDrv (import tests/installer.nix { inherit system; }).lvm.test); diff --git a/nixos/tests/fleet.nix b/nixos/tests/fleet.nix new file mode 100644 index 00000000000..4e006c00bee --- /dev/null +++ b/nixos/tests/fleet.nix @@ -0,0 +1,73 @@ +import ./make-test.nix rec { + name = "simple"; + + nodes = { + node1 = + { config, pkgs, ... }: + { + services = { + etcd = { + enable = true; + listenPeerUrls = ["http://0.0.0.0:7001"]; + initialAdvertisePeerUrls = ["http://node1:7001"]; + initialCluster = ["node1=http://node1:7001" "node2=http://node2:7001"]; + }; + }; + + virtualisation.fleet = { + enable = true; + metadata.name = "node1"; + }; + + networking.firewall.allowedTCPPorts = [ 7001 ]; + }; + + node2 = + { config, pkgs, ... }: + { + services = { + etcd = { + enable = true; + listenPeerUrls = ["http://0.0.0.0:7001"]; + initialAdvertisePeerUrls = ["http://node2:7001"]; + initialCluster = ["node1=http://node1:7001" "node2=http://node2:7001"]; + }; + }; + + virtualisation.fleet = { + enable = true; + metadata.name = "node2"; + }; + + networking.firewall.allowedTCPPorts = [ 7001 ]; + }; + }; + + service = builtins.toFile "hello.service" '' + [Unit] + Description=Hello World + + [Service] + ExecStart=/bin/sh -c "while true; do echo \"Hello, world\"; /var/run/current-system/sw/bin/sleep 1; done" + + [X-Fleet] + MachineMetadata=name=node2 + ''; + + testScript = + '' + startAll; + $node1->waitForUnit("fleet.service"); + $node2->waitForUnit("fleet.service"); + + $node2->waitUntilSucceeds("fleetctl list-machines | grep node1"); + $node1->waitUntilSucceeds("fleetctl list-machines | grep node2"); + + $node1->succeed("cp ${service} hello.service && fleetctl submit hello.service"); + $node1->succeed("fleetctl list-unit-files | grep hello"); + $node1->succeed("fleetctl start hello.service"); + $node1->waitUntilSucceeds("fleetctl list-units | grep running"); + $node1->succeed("fleetctl stop hello.service"); + $node1->succeed("fleetctl destroy hello.service"); + ''; +}