GCE backend: initial implementation

A snapshot of the work in progress. There's support for instances, disks, static ips and basic networking. --check is thoroughtly implemented. Backups work but need more testing. Luks and tunnels work. Moving resources between different zones and projects might fail(not tested). Tried to find the balance between letting the user know what's going on and spamming useless trace messages. 

Use nixpkgs master to build nixops and deployments or else... Don't press ctrl+c, just don't. 

Improvements to follow shortly.

The following example deployment also contains some useful comments:

trivial.nix:
```
{
  network.description = "Trivial test network";

  machine = { config, pkgs, ... }: { 
    services.httpd.enable = true;
    services.httpd.adminAddr = "eelco.dolstra@logicblox.com";

    services.httpd.documentRoot = "${pkgs.valgrind}/share/doc/valgrind/html";
    networking.firewall.allowedTCPPorts = [ 80 ];
  };

  machine2 = { config, pkgs, ... }: {};

}

```

trivial-gce.nix:
```
let

  # change this as necessary or wipe and use ENV vars
  credentials = {
    project = "logicblox-dev";
    serviceAccount = "572772620792-gecnc5v4ks9e6s13tociphd1p9ct6emr@developer.gserviceaccount.com";
    accessKey = "/path/to/key.pem";
  };

in

{
  # test initializing from image
  resources.gceDisks.tnxp-disk = credentials // {
      region = "europe-west1-b";
      image = "nixos-14-04pre-d215564-x86-64-linux";
      size = 165;
  };

  # just a small "lab rat" disk
  resources.gceDisks.tiny = credentials // {
      region = "europe-west1-b";
      size = 2;
  };

  resources.gceStaticIPs.perma-ip = credentials // {
    region = "europe-west1";
  };

  # the most important rules are allow-ssh and allow-http

  # allow-ssh rule is present in the default network
  # created by GCE, but it isn't present in custom networks,
  # so we have to create it by hand

  # allow-http is needed to that we can curl the machine IP
  # and see that the apache service is indeed up and working

  # allow-ping is required to avoid pings being blackholed

  # allow-test is there just to test various features

  resources.gceNetworks.coolnet = credentials // {
      addressRange = "192.168.3.0/24";
      firewall = {
          allow-http.allowed.tcp = [ 80 ];
          allow-ssh.allowed.tcp = [ 22 ];
          allow-ping.allowed.icmp = null;

          allow-test = {
            sourceRanges =  ["0.0.0.0/0"];
            allowed.tcp = [ 88 "8080" ];
            #sourceTags = ["blah" "hmm" ];
          };
      };
  };

  machine =
    { resources, ...}: {

      # for network/firewall tests
      networking.firewall.allowPing = true;

      deployment.targetEnv = "gce";
      deployment.gce.region = "europe-west1-b";

      # don't forget to change these too
      deployment.gce.project = "logicblox-dev";
      deployment.gce.serviceAccount = "572772620792-gecnc5v4ks9e6s13tociphd1p9ct6emr@developer.gserviceaccount.com";
      deployment.gce.accessKey = "/path/to/key.pem";

      # random
      deployment.gce.tags = [ "seems-to" "work" ];

      # meaningless despite sounding seriously
      deployment.gce.metadata = { loglevel = "error"; secondmeta = "2"; };


      # (un)comment mount points and see what happens!

      # It's very important to ensure that disk names and devices match.
      # One day device names will be generated from disk names.

      fileSystems = {

        # for testing what is effectively an ephemeral device, which nevertheless
        # survives "GCE reboots", that is instance teardown/recreation instead of start/stop

        "/data" = {
          autoFormat = true; fsType = "ext4";
          gce = { size = 14;  disk_name = "machine-data";  };
        };

       # testing external/persistent disks
       # toggling readOnly works but forces a reboot because there's no clean remount GCE api available
       "/tiny" = { gce.readOnly = false; gce.disk = resources.gceDisks.tiny; autoFormat = true; fsType = "ext4";
      };

      # ip and network changes require a hard restart: deploy --allow-reboot

      deployment.gce.ipAddress = resources.gceStaticIPs.perma-ip;
      #deployment.gce.ipAddress ="nixops-2e0a724a-f030-11e3-8239-b8e8560f8b58-perma-ip"; # 

      deployment.gce.network = resources.gceNetworks.coolnet;
      #deployment.gce.network = "nixops-2e0a724a-f030-11e3-8239-b8e8560f8b58-coolnet";


      # Uncomment and see what happens!

      #deployment.gce.instanceType = "n1-standard-1";
      #deployment.gce.scheduling.automaticRestart = false;
      #deployment.gce.scheduling.onHostMaintenance = "TERMINATE";

    };

  # minimal deployment
  machine2 = { resources, ...}: {

      deployment.targetEnv = "gce";
      deployment.gce = credentials // {
        region = "europe-west1-b";
      };

  };

}
```