Hi Kamil,

Good to hear that you have discovered our tooling :)

If I understand everything correctly, you want to "tune" services to have host 
specific settings, right?

In most examples I have used for Disnix, services are relocatable and are 
built/configured only using properties of their intra-dependencies and 
inter-dependencies. If a service needs machine specific settings (e.g. a port 
number), you basically have to create a tuned variant, configured for that 
particular machine. I have encountered a similar issue in the Disnix TCP proxy 
example. To tune services for a particular host, you can write a Disnix 
expression like this:

{stdenv}:
{port}:
{hello_world_server}:

let 
  makeFlags = "PREFIX=$out srcPort=${toString port} 
destHostname=${hello_world_server.target.hostname} destPort=${toString 
(hello_world_server.port)}";
in
stdenv.mkDerivation {
  name = "disnix-tcp-proxy";
  src = ../../../services/disnix-tcp-proxy;
  buildPhase = "make ${makeFlags}";
  installPhase = "make ${makeFlags} install";
}

Basically, this expression takes 3 arguments. The first argument are its 
intra-dependencies (similar to ordinary Disnix expressions, the second argument 
is a port-number (which is configured in the services model), the third 
argument are the inter-dependencies. As you can see, the value of the port 
number is configurable, and in the stdenv.mkDerivation function (which builds 
the service) the makeFlags argument is used to pass the port value to make.

In the services.nix model, the port number is provided and configured:

{system, distribution, pkgs}:

let customPkgs = import ../top-level/all-packages.nix { inherit system pkgs; };
in
rec {
  hello_world_server = rec {
    name = "hello_world_server";
    pkg = customPkgs.hello_world_server { inherit port; }; # calling the 
previous expression with desired 'port' argument
    port = 5000; # This is the TCP port where we want to run the service on
    type = "wrapper";
  };
  
  ...
}

You may wonder why we put this 'port' attribute in the services model? This 
makes it possible to retrieve those values through inter-dependency arguments. 
So for instance, if you have a service which has an inter-dependency on the 
hello_world_server and you want to know the port number on which it is running 
you can fetch this property directly through inter-dependency arguments:

{stdenv, inetutils}:                                                            
                                                                                
                                                   
{hello_world_server}: # Refers to the hello_world_service defined in 
services.nix                                                                    
                                                                                
                                       
                                                                                
                                                                                
                                                   
let makeFlags = "PREFIX=$out 
helloWorldHostname=${hello_world_server.target.hostname} 
helloWorldPort=${toString (hello_world_server.port)} inetutils=${inetutils}"; # 
Configured the client to use the port number of the server.
                                              
in                                                                              
                                                                                
                                                   
stdenv.mkDerivation {                                                           
                                                                                
                                                   
  name = "hello-world-client";                                                  
                                                                                
                                                   
  src = ../../../services/hello-world-client;                                   
                                                                                
                                                   
  buildPhase = "make ${makeFlags}";
  installPhase = "make ${makeFlags} install";
}

The expression above shows the Disnix expression of the hello world client. 
This expression fetches the 'port' attribute from the hello_world_server 
inter-dependency argument. In the body the client is configured to use to port 
value of the server.

I hope this explanation clarifies some things a bit. You can obtain the source 
code and Nix expressions from the example I have given from Disnix download 
page, or through Subversion: 
https://svn.nixos.org/repos/nix/disnix/examples/disnix-proxy-example/trunk

-----Original Message-----
From: [email protected] on behalf of Kamil Klimkiewicz
Sent: Thu 3/31/2011 12:25 AM
To: [email protected]
Subject: [Nix-dev] [disnix] per-host configuration file generation
 
Hi guys,

I found out about Nix/NixOS/Disnix a couple of days ago, by accident. I
have to say it's a great piece of software. It was a little tricky to
grasp the whole expression language (especially given I last used any
functional language 5+ years ago) at first, but now I think I'm slowly
getting used to it.

Anyway, I have one question about disnix. I'm trying to use it for
deployment of Django application (together with all dependent services -
PostgreSQL, pgpool, nginx, gunicorn WSGI server, etc.). The whole thing
will sit on Ubuntu server(s) - for various reasons. Everything looks
great so far.

But I got into a little problem. Let's say I have a nginx service that
sits on single machine and django/gunicorn/pgpool service that sits on a
couple of machines. How would you go about providing configuration file
for pgpool service that depends on the machine this service is running
on? Let's say I want the pgpool service to use different ports on
particular servers. My current ideas are:
- Generate configuration files for each machine in advance using pgpool
  service Nix expression - I simply store files named
  pgpool-machine1.conf, pgpool-machine2.conf, etc. in the pgpool's nix
  store. This has one major drawback - whenever I change configuration
  for single machine I have to distribute the service to all pgpool
  machines and possibly it will restart pgpool services on all machines.
- Generate configuration files in service activation script - this
  doesn't look too nix-y in my opinion.
- Create separate "subservice" for each machine.

How would you resolve this issue? What I have in mind is some kind of
map that takes a service generator function and a list of machines, but
I don't see a way to make it work. Any ideas?

-- 
Best regards,
Kamil Klimkiewicz
_______________________________________________
nix-dev mailing list
[email protected]
https://mail.cs.uu.nl/mailman/listinfo/nix-dev

_______________________________________________
nix-dev mailing list
[email protected]
https://mail.cs.uu.nl/mailman/listinfo/nix-dev

Reply via email to