summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authormakefu <github@syntax-fehler.de>2016-01-01 16:19:01 +0100
committermakefu <github@syntax-fehler.de>2016-01-01 16:19:01 +0100
commit3903ee56c081a02b2864dba0fee486d6b49139d2 (patch)
tree000c78b2d6c0c2794944d82d2de7cbf32dbbfed8
emergency init
-rw-r--r--build-stuff/build-host.py161
1 files changed, 161 insertions, 0 deletions
diff --git a/build-stuff/build-host.py b/build-stuff/build-host.py
new file mode 100644
index 0000000..6e7b435
--- /dev/null
+++ b/build-stuff/build-host.py
@@ -0,0 +1,161 @@
+#!/bin/sh
+""" usage: build-host [options] HOSTNAME
+
+Options:
+ --secrets-dir DIR Path to secrets [Default: ~/secrets/]
+ --stockholm-dir DIR Path to stockholm [Default: ~/stockholm/]
+ --username USER Primary username of the new host [Default: $LOGNAME]
+ --create-passwords creates <secrets/hashedPasswords.nix>, password input is interactive
+
+Tinc keys are stored in secrets-dir/HOSTNAME/retiolum.rsa_key.priv .
+For building shared hosts set secrets-dir to `<secrets/krebs/>`
+"""
+import sys
+import os
+from os.path import join as path_join,exists
+import logging as log
+log.basicConfig(level=log.DEBUG)
+
+def retiolum_ip(hostname):
+ """ warning this function actually writes stuff to the disk
+ """
+ import ipaddress as ip
+ from random import randint
+
+ mynet4 = ip.ip_network("10.243.0.0/16")
+ mynet6 = ip.ip_network("42::/16")
+
+ ret = {"hostname": hostname}
+ ret["v6"] = str(ip.IPv6Address(mynet6[0] +
+ randint(0,mynet6.num_addresses)))+"/128"
+ ret["v4"] = str(ip.IPv4Address(mynet4[0] +
+ randint(0,mynet4.num_addresses)))+"/32"
+ return ret
+
+def write_stockholm_1systems(ret,stockholm_dir):
+ """ writes new nix file in stockholm/$LOGNAME/1systems/${HOSTNAME}.nix if
+ it not yet exists"""
+ p=path_join(stockholm_dir, ret['username'],'1systems',ret['hostname'])
+ if exists (p):
+ log.warn(" {} already exists, will not override with minimal config".format(p))
+ else:
+ log.info("Creating {} with minimal config".format(p))
+ with open(p,"w+") as f:
+ f.write("""{{ config, pkgs, ... }}:
+{{
+ krebs = {{
+ enable = true;
+ build.user = config.krebs.users.{username};
+ build.host = config.krebs.hosts.{hostname};
+ }};
+ # You want to change these :)
+ boot.loader.grub.device = "/dev/sda";
+ fileSystems."/" = {{
+ device = "/dev/sda1";
+ }};
+}}
+ """.format(**ret))
+
+
+def print_stockholm_krebs_entry(ret):
+ print("""# this entry is autogenerated and can be added to
+# stockholm/krebs/3modules/{username}/default.nix
+{hostname} = rec {{
+ cores = 1;
+ dc = "none";
+ nets = {{
+ retiolm = {{
+ addrs4 = ["{v4}"];
+ addrs6 = ["{v6}"];
+ aliases = [
+ "{hostname}.retiolum"
+ ];
+ tinc.pubkey = ''
+{pubkey}''
+ }};
+ }};
+}};
+ """.format(**ret))
+
+def create_zhosts_file(ret,path):
+ """ creates a new tinc hosts file in path
+ (stockholm/krebs/Zhosts/$hostname) """
+ with open(path,"w+") as f:
+ for i in ('v4','v6'):
+ f.write("Subnet = {}\n".format(ret[i]))
+ f.write(ret['pubkey'])
+
+def generate_tinc_keys(base):
+ """ creates tinc public and private keys in `base`
+ returns rsa public key
+ """
+ from subprocess import Popen,PIPE
+ import shutil
+ from os import rmdir
+ from tempfile import mkdtemp
+ tmpdir = mkdtemp()
+ process = Popen(["tinc","--batch","--config",tmpdir,"generate-keys","2048"],stdout=PIPE,stderr=PIPE,stdin=PIPE,bufsize=0)
+ process.communicate()
+ for i in ["ed25519_key.priv", "ed25519_key.pub",
+ "rsa_key.priv","rsa_key.pub"]:
+ shutil.move(path_join(tmpdir,i),base+"."+i)
+ # should be empty now
+ shutil.rmtree(tmpdir)
+ with open(base+".rsa_key.pub") as pubfile:
+ return pubfile.read()
+
+def prepare_secrets(sec):
+ if not exists(sec):
+ os.makedirs(sec,mode=488)
+ log.info("Creating {}".format(sec))
+ else:
+ log.error(" {} already exists".format(sec))
+ log.error("Use another hostname or remove the folder to continue")
+ sys.exit(1)
+
+def check_existence(files):
+ for f in files:
+ if not exists(f):
+ log.error(" {} does not exist but is a hard requirement for \
+continuing".format(f))
+ log.error("Create/Clone the folder or set it to the correct \
+location via cli options (--help)")
+ log.error(__doc__)
+ sys.exit(1)
+
+def create_passwords(sec):
+ import crypt
+ with open(path_join(sec,"hashedPasswords.nix")):
+ #python3 -c 'import crypt; print(crypt.crypt("test",
+ #crypt.mksalt(crypt.METHOD_SHA512)))'
+
+
+def main():
+ from os.path import expanduser,expandvars
+ from docopt import docopt
+ args = docopt(__doc__)
+ hostname = args["HOSTNAME"]
+ secrets_dir = expanduser(args["--secrets-dir"])
+ username = expandvars(args["--username"])
+ stockholm_dir = expanduser(args["--stockholm-dir"])
+
+ check_existence([secrets_dir,stockholm_dir])
+
+ host_secrets = path_join(secrets_dir,hostname)
+ prepare_secrets(host_secrets)
+
+ ret = retiolum_ip(hostname)
+ ret['username'] = username
+
+ # generate tinc keys, return pubkey
+ retiolum = path_join(secrets_dir,hostname,"retiolum")
+ ret['pubkey'] = generate_tinc_keys(retiolum)
+
+ create_zhosts_file(ret,path_join(stockholm_dir,"krebs/Zhosts",hostname))
+
+ write_stockholm_1systems(ret,stockholm_dir)
+ print_stockholm_krebs_entry(ret)
+ pass
+
+if __name__ == '__main__':
+ main()