[Nix-dev] [disnix] Deactivation of services

Kamil Klimkiewicz miglanz at gmail.com
Fri Apr 15 13:59:29 CEST 2011


Hi Sander,

> Disnix does deactivate previous services, but only the ones that are
> obsolete. So if your old distribution model and new distribution model
> contain the same service, Disnix tries to keep them intact.

OK, I understand now. It means everything works as expected :) I simply
thought that previous incarnation of the same service would get
deactivate "signal".

> In your case, I think you may have removed a machine from your
> infrastructure model, which has some services running that are
> previously deployed. Not having a machine in your infrastructure model
> means that this particular machine is no longer available and it is no
> longer known how it can be reached and what it's other relevant
> properties are. Therefore Disnix skips the deactivation.

Nope, it was simply my misunderstanding of the correct behaviour :)

> I hope this makes things a bit more clear. The reason why Disnix
> behaves this way is to deal with networks in which machines may
> randomly appear or disappear. When a machine crashes, it may be
> possible that an upgrade cannot be performed. By skipping a
> non-existent machine you can "fix" the deployment of a system in a
> crashing network.

Yes, it is clear now. BTW, I must say that disnix (together with nix) is
so great when it comes to deployment it's not even funny. Let me tell
you what I achieved in a couple of days (just as a reminder, I'm
deploying Django application):

- my application consists of the following services: nginx web server,
  stunnel (for HTTPS), memcached, postgresql, pgpool - postgresql
  connection pooling, gunicorn - Python application server, and let's
  call firewall a service too;
- each service runs in its own Linux Container (lxc) - it means each
  service is isolated from each other; this is really fun part;
  isolation is really nice - thanks to exportReferenceGraph I can easily
  create environments that contain only parts necessary to run each
  service; the nix store is mounted in ro mode, so it's not possible to
  change anything here, even by root; data directories are mounted with
  noexec setting, so even if you somehow get access to, let's say, gcc
  and create some nasty executable you can't use it; thanks to lxc there
  are plenty of possibilities of limiting services - resources (CPU,
  memory, etc); but w/o disnix/nix it would be really PITA to create
  nicely isolated environments;
- moreover I treat the Nix expression language as a simple configuration
  language, look for example at my firewall configuration:

    conf = {
	external_ip = "x.x.x.x";
	input_accept = [ "ssh" ];
	dnat = [
		[ 80 http ]
		[ 443 https ]
	];
	snat = [ gunicorn ]; # (only gunicorn can access outside world)
	forward = [
		[ https http ] # https (stunnel) may only talk to http
		[ http gunicorn ] # and so on...
		[ gunicorn pgpool ]
		[ gunicorn memcached ]
		[ pgpool postgresql ]
		[ app_db postgresql ]
	];
    };

  from the above configuration I generate iptables rules, and thus only
  http and https are visible to the outside world, I even limit access
  from some services to the others - it's that simple!
- of course everything is easy to rollback should anything wrong happen;

I hope to write some blog posting about all of this and probably make
this whole thing available to others once I clean everything up. My idea
is to create a little (maybe Django- or Python-specific) deployment
framework on top of disnix. But from my initial understanding of disnix
itself it seems it's mostly a wrapper on top of base nix tools, so if I
find and limitations I can still build my own solution easily (I think
I would go with higher level language - like Python, I know, I'm
biased, because I sometimes get segfaults with disnix - see note below).

The only missing part I'd still like to get is hot reloading of nginx
(it has this possibility that if you send SIGHUP to the nginx it will
reload its configuration while still running). I haven't started working
on it yet so I'm not sure if it's even possible with current disnix
incarnation.

Anyway, let me thank you once again!

P.S. as for the segmentation faults: they occur if I put nested
attribute sets in the infrastructure.nix, for example:
{
  test1 = {
	hostname = "...";
	someProperty = {
		someSubProperty = "xxx";
	};
  };
}

-- 
Best regards,
Kamil




More information about the nix-dev mailing list