def test_function_call(self): self.assert_nix(Call(RawValue("fun_call"), {"a": "b"}), '( fun_call { a = "b"; } )') self.assert_nix( Call(RawValue("multiline_call"), {"a": "b"}), '(\n multiline_call\n {\n a = "b";\n }\n)', maxwidth=0, )
def test_list_compound(self): self.assert_nix([Call(RawValue("123 //"), 456), RawValue("a b c")], '[ (( 123 // 456 )) (a b c) ]') self.assert_nix([ RawValue("a b c"), { 'cde': [RawValue("1,2,3"), RawValue("4 5 6"), RawValue("7\n8\n9")] } ], '[ (a b c) { cde = [ 1,2,3 (4 5 6) (7\n8\n9) ]; } ]')
def get_physical_backup_spec(self, backupid): val = {} if backupid in self.backups: for dev, snap in self.backups[backupid].items(): val[dev] = { 'snapshot': Call(RawValue("pkgs.lib.mkOverride 10"), snap) } val = {('deployment', 'gce', 'blockDeviceMapping'): val} else: val = RawValue( "{{}} /* No backup found for id '{0}' */".format(backupid)) return Function("{ config, pkgs, ... }", val)
def destroy_resources(self, include=[], exclude=[], wipe=False): """Destroy all active or obsolete resources.""" with self._get_deployment_lock(): for r in self.resources.itervalues(): r._destroyed_event = threading.Event() r._errored = False for rev_dep in r.destroy_before(self.resources.itervalues()): try: rev_dep._wait_for.append(r) except AttributeError: rev_dep._wait_for = [ r ] def worker(m): try: if not should_do(m, include, exclude): return try: for dep in m._wait_for: dep._destroyed_event.wait() # !!! Should we print a message here? if dep._errored: m._errored = True return except AttributeError: pass if m.destroy(wipe=wipe): self.delete_resource(m) except: m._errored = True raise finally: m._destroyed_event.set() nixops.parallel.run_tasks(nr_workers=-1, tasks=self.resources.values(), worker_fun=worker) # Remove the destroyed machines from the rollback profile. # This way, a subsequent "nix-env --delete-generations old" or # "nix-collect-garbage -d" will get rid of the machine # configurations. if self.rollback_enabled: # and len(self.active) == 0: profile = self.create_profile() attrs = {m.name: Call(RawValue("builtins.storePath", m.cur_toplevel)) for m in self.active.itervalues() if m.cur_toplevel} if subprocess.call( ["nix-env", "-p", profile, "--set", "*", "-I", "nixops=" + self.expr_path, "-f", "<nixops/update-profile.nix>", "--arg", "machines", py2nix(attrs, inline=True)]) != 0: raise Exception("cannot update profile ‘{0}’".format(profile))
def get_physical_spec(self): block_device_mapping = {} for k, v in self.block_device_mapping.items(): if (v.get('encrypt', False) and v.get('passphrase', "") == "" and v.get('generatedKey', "") != ""): block_device_mapping[k] = { 'passphrase': Call(RawValue("pkgs.lib.mkOverride 10"), v['generatedKey']), } return { 'imports': [ RawValue("<nixpkgs/nixos/modules/virtualisation/google-compute-config.nix>") ], ('deployment', 'gce', 'blockDeviceMapping'): block_device_mapping, }
def destroy_resources(self, include=[], exclude=[], wipe=False): """Destroy all active and obsolete resources.""" with self._get_deployment_lock(): self._destroy_resources(include, exclude, wipe) # Remove the destroyed machines from the rollback profile. # This way, a subsequent "nix-env --delete-generations old" or # "nix-collect-garbage -d" will get rid of the machine # configurations. if self.rollback_enabled: # and len(self.active) == 0: profile = self.create_profile() attrs = {m.name: Call(RawValue("builtins.storePath"), m.cur_toplevel) for m in self.active.itervalues() if m.cur_toplevel} if subprocess.call( ["nix-env", "-p", profile, "--set", "*", "-I", "nixops=" + self.expr_path, "-f", "<nixops/update-profile.nix>", "--arg", "machines", py2nix(attrs, inline=True)]) != 0: raise Exception("cannot update profile ‘{0}’".format(profile))
def do_machine(m): defn = self.definitions[m.name] attrs_list = attrs_per_resource[m.name] # Emit configuration to realise encrypted peer-to-peer links. for m2 in active_resources.itervalues(): ip = m.address_to(m2) if ip: hosts[m.name][ip] += [m2.name, m2.name + "-unencrypted"] # Always use the encrypted/unencrypted suffixes for aliases rather # than for the canonical name! hosts[m.name]["127.0.0.1"].append(m.name + "-encrypted") for m2_name in defn.encrypted_links_to: if m2_name not in active_machines: raise Exception("‘deployment.encryptedLinksTo’ in machine ‘{0}’ refers to an unknown machine ‘{1}’" .format(m.name, m2_name)) m2 = active_machines[m2_name] # Don't create two tunnels between a pair of machines. if m.name in self.definitions[m2.name].encrypted_links_to and m.name >= m2.name: continue local_ipv4 = index_to_private_ip(m.index) remote_ipv4 = index_to_private_ip(m2.index) local_tunnel = 10000 + m2.index remote_tunnel = 10000 + m.index attrs_list.append({ ('networking', 'p2pTunnels', 'ssh', m2.name): { 'target': '{0}-unencrypted'.format(m2.name), 'targetPort': m2.ssh_port, 'localTunnel': local_tunnel, 'remoteTunnel': remote_tunnel, 'localIPv4': local_ipv4, 'remoteIPv4': remote_ipv4, 'privateKey': '/root/.ssh/id_charon_vpn', } }) # FIXME: set up the authorized_key file such that ‘m’ # can do nothing more than create a tunnel. authorized_keys[m2.name].append(m.public_vpn_key) kernel_modules[m.name].add('tun') kernel_modules[m2.name].add('tun') hosts[m.name][remote_ipv4] += [m2.name, m2.name + "-encrypted"] hosts[m2.name][local_ipv4] += [m.name, m.name + "-encrypted"] trusted_interfaces[m.name].add('tun' + str(local_tunnel)) trusted_interfaces[m2.name].add('tun' + str(remote_tunnel)) private_ipv4 = m.private_ipv4 if private_ipv4: attrs_list.append({ ('networking', 'privateIPv4'): private_ipv4 }) public_ipv4 = m.public_ipv4 if public_ipv4: attrs_list.append({ ('networking', 'publicIPv4'): public_ipv4 }) public_vpn_key = m.public_vpn_key if public_vpn_key: attrs_list.append({ ('networking', 'vpnPublicKey'): public_vpn_key }) # Set system.stateVersion if the Nixpkgs version supports it. if nixops.util.parse_nixos_version(defn.config["nixosVersion"]) >= ["15", "09"]: attrs_list.append({ ('system', 'stateVersion'): Call(RawValue("lib.mkDefault"), m.state_version or '14.12') }) if self.nixos_version_suffix: attrs_list.append({ ('system', 'nixosVersionSuffix'): self.nixos_version_suffix })