Esempio n. 1
0
def gen_iso(iso_image, authorized_key, mode=None):
    with tempfile.TemporaryDirectory() as d:
        inclusion = []

        with open(os.path.join(d, "dns_bootstrap_lines"), "w") as outfile:
            outfile.write(setup.dns_bootstrap_lines())

        inclusion += ["dns_bootstrap_lines"]
        util.copy(authorized_key, os.path.join(d, "authorized.pub"))
        util.writefile(os.path.join(d, "keyservertls.pem"),
                       authority.get_pubkey_by_filename("./server.pem"))
        resource.copy_to("postinstall.sh", os.path.join(d, "postinstall.sh"))
        os.chmod(os.path.join(d, "postinstall.sh"), 0o755)
        inclusion += ["authorized.pub", "keyservertls.pem", "postinstall.sh"]

        for variant in configuration.KEYCLIENT_VARIANTS:
            util.writefile(os.path.join(d, "keyclient-%s.yaml" % variant),
                           configuration.get_keyclient_yaml(variant).encode())
            inclusion.append("keyclient-%s.yaml" % variant)

        resource.copy_to("sshd_config", os.path.join(d, "sshd_config.new"))

        preseeded = resource.get_resource("preseed.cfg.in")
        generated_password = util.pwgen(20)
        creation_time = datetime.datetime.now().isoformat()
        git_hash = get_git_version().encode()
        add_password_to_log(generated_password, creation_time)
        print("generated password added to log")
        preseeded = preseeded.replace(b"{{HASH}}",
                                      util.mkpasswd(generated_password))
        preseeded = preseeded.replace(b"{{BUILDDATE}}", creation_time.encode())
        preseeded = preseeded.replace(b"{{GITHASH}}", git_hash)

        mirror = configuration.get_config().mirror
        if mirror.count("/") < 1 or mirror.count(".") < 1:
            command.fail(
                "invalid mirror specification '%s'; must be of the form HOST.NAME/PATH"
            )
        mirror_host, mirror_dir = mirror.split("/", 1)
        preseeded = preseeded.replace(b"{{MIRROR-HOST}}", mirror_host.encode())
        preseeded = preseeded.replace(b"{{MIRROR-DIR}}",
                                      ("/" + mirror_dir).encode())

        realm = configuration.get_config().realm
        preseeded = preseeded.replace(b"{{KERBEROS-REALM}}", realm.encode())

        cidr_nodes, upstream_dns_servers = configuration.get_config(
        ).cidr_nodes, configuration.get_config().dns_upstreams

        node_cidr_prefix = ".".join(str(cidr_nodes.ip).split(".")[:-1]) + "."
        preseeded = preseeded.replace(b"{{IP-PREFIX}}",
                                      node_cidr_prefix.encode())

        node_cidr_gateway = cidr_nodes.gateway()
        preseeded = preseeded.replace(b"{{GATEWAY}}",
                                      str(node_cidr_gateway).encode())

        node_cidr_netmask = cidr_nodes.netmask()
        preseeded = preseeded.replace(b"{{NETMASK}}",
                                      str(node_cidr_netmask).encode())

        preseeded = preseeded.replace(
            b"{{NAMESERVERS}}",
            " ".join(str(server_ip)
                     for server_ip in upstream_dns_servers).encode())
        util.writefile(os.path.join(d, "preseed.cfg"), preseeded)

        inclusion += ["sshd_config.new", "preseed.cfg"]

        for package_name, (short_filename,
                           package_bytes) in packages.verified_download_full(
                               PACKAGES).items():
            assert "/" not in short_filename, "invalid package name: %s for %s" % (
                short_filename, package_name)
            assert short_filename.startswith(
                package_name +
                "_"), "invalid package name: %s for %s" % (short_filename,
                                                           package_name)
            assert short_filename.endswith(
                "_amd64.deb"), "invalid package name: %s for %s" % (
                    short_filename, package_name)
            util.writefile(os.path.join(d, short_filename), package_bytes)
            inclusion.append(short_filename)

        cddir = os.path.join(d, "cd")
        os.mkdir(cddir)
        subprocess.check_call(
            ["bsdtar", "-C", cddir, "-xzf", "/usr/share/homeworld/debian.iso"])
        subprocess.check_call(["chmod", "+w", "--recursive", cddir])

        if mode is not None:
            if mode not in MODES:
                command.fail("no such ISO mode: %s" % mode)
            MODES[mode](d, cddir, inclusion)

        with gzip.open(os.path.join(cddir, "initrd.gz"), "ab") as f:
            subprocess.run(["cpio", "--create", "--format=newc"],
                           check=True,
                           stdout=f,
                           input="".join("%s\n" % filename
                                         for filename in inclusion).encode(),
                           cwd=d)

        files_for_md5sum = subprocess.check_output(
            ["find", ".", "-follow", "-type", "f", "-print0"],
            cwd=cddir).decode().split("\0")
        assert files_for_md5sum.pop() == ""
        md5s = subprocess.check_output(["md5sum", "--"] + files_for_md5sum,
                                       cwd=cddir)
        util.writefile(os.path.join(cddir, "md5sum.txt"), md5s)

        temp_iso = os.path.join(d, "temp.iso")
        subprocess.check_call([
            "xorriso", "-as", "mkisofs", "-quiet", "-o", temp_iso, "-r", "-J",
            "-c", "boot.cat", "-b", "isolinux.bin", "-no-emul-boot",
            "-boot-load-size", "4", "-boot-info-table", cddir
        ])
        subprocess.check_call(["isohybrid", "-h", "64", "-s", "32", temp_iso])
        util.copy(temp_iso, iso_image)
Esempio n. 2
0
def gen_iso(iso_image, authorized_key, mode=None):
    "generate ISO"
    with tempfile.TemporaryDirectory() as d:
        config = configuration.get_config()
        inclusion = []

        with open(os.path.join(d, "dns_bootstrap_lines"), "w") as outfile:
            outfile.write(setup.dns_bootstrap_lines())

        inclusion += ["dns_bootstrap_lines"]
        util.copy(authorized_key, os.path.join(d, "authorized.pub"))
        util.writefile(os.path.join(d, "keyservertls.pem"),
                       authority.get_pubkey_by_filename("./clusterca.pem"))
        inclusion += ["authorized.pub", "keyservertls.pem"]

        os.makedirs(os.path.join(d, "var/lib/dpkg/info"))
        scripts = {
            "//spire/resources:postinstall.sh":
            "postinstall.sh",
            "//spire/resources:prepartition.sh":
            "prepartition.sh",
            "//spire/resources:netcfg.postinst":
            "var/lib/dpkg/info/netcfg.postinst",
        }
        for source, destination in sorted(scripts.items()):
            resource.extract(source, os.path.join(d, destination))
            os.chmod(os.path.join(d, destination), 0o755)
            inclusion.append(destination)

        util.writefile(os.path.join(d, "keyserver.domain"),
                       configuration.get_keyserver_domain().encode())
        inclusion.append("keyserver.domain")

        util.writefile(os.path.join(d, "vlan.txt"), b"%d\n" % config.vlan)
        inclusion.append("vlan.txt")

        resource.extract("//spire/resources:sshd_config",
                         os.path.join(d, "sshd_config.new"))

        preseeded = resource.get("//spire/resources:preseed.cfg.in")
        generated_password = util.pwgen(20)
        creation_time = datetime.datetime.now().isoformat()
        git_hash = metadata.get_git_version().encode()
        add_password_to_log(generated_password, creation_time)
        print("generated password added to log")
        preseeded = preseeded.replace(b"{{HASH}}",
                                      util.mkpasswd(generated_password))
        preseeded = preseeded.replace(b"{{BUILDDATE}}", creation_time.encode())
        preseeded = preseeded.replace(b"{{GITHASH}}", git_hash)

        mirror = config.mirror
        if mirror.count("/") < 1 or mirror.count(".") < 1:
            command.fail(
                "invalid mirror specification '%s'; must be of the form HOST.NAME/PATH"
            )
        mirror_host, mirror_dir = mirror.split("/", 1)
        preseeded = preseeded.replace(b"{{MIRROR-HOST}}", mirror_host.encode())
        preseeded = preseeded.replace(b"{{MIRROR-DIR}}",
                                      ("/" + mirror_dir).encode())

        preseeded = preseeded.replace(b"{{KERBEROS-REALM}}",
                                      config.realm.encode())

        cidr_nodes = config.cidr_nodes

        node_cidr_prefix = ".".join(
            str(cidr_nodes.network_address).split(".")[:-1]) + "."
        preseeded = preseeded.replace(b"{{IP-PREFIX}}",
                                      node_cidr_prefix.encode())

        node_cidr_gateway = next(cidr_nodes.hosts())
        preseeded = preseeded.replace(b"{{GATEWAY}}",
                                      str(node_cidr_gateway).encode())

        preseeded = preseeded.replace(b"{{NETMASK}}",
                                      str(cidr_nodes.netmask).encode())

        preseeded = preseeded.replace(
            b"{{NAMESERVERS}}",
            " ".join(str(server_ip)
                     for server_ip in config.dns_upstreams).encode())
        util.writefile(os.path.join(d, "preseed.cfg"), preseeded)

        inclusion += ["sshd_config.new", "preseed.cfg"]

        for package_name, (short_filename,
                           package_bytes) in packages.verified_download_full(
                               PACKAGES).items():
            if ("/" in short_filename
                    or not short_filename.startswith(package_name + "_")
                    or not short_filename.endswith("_amd64.deb")):
                raise ValueError("invalid package name: %s for %s" %
                                 (short_filename, package_name))
            util.writefile(os.path.join(d, short_filename), package_bytes)
            inclusion.append(short_filename)

        cddir = os.path.join(d, "cd")
        os.mkdir(cddir)
        subprocess.check_call(
            ["bsdtar", "-C", cddir, "-xzf", "/usr/share/homeworld/debian.iso"])
        subprocess.check_call(["chmod", "+w", "--recursive", cddir])

        if mode is not None:
            if mode not in MODES:
                command.fail("no such ISO mode: %s" % mode)
            MODES[mode](d, cddir, inclusion)

        with gzip.open(os.path.join(cddir, "initrd.gz"), "ab") as f:
            f.write(
                subprocess.check_output(
                    ["cpio", "--create", "--format=newc"],
                    input="".join("%s\n" % filename
                                  for filename in inclusion).encode(),
                    cwd=d))

        files_for_md5sum = subprocess.check_output(
            ["find", ".", "-follow", "-type", "f", "-print0"],
            cwd=cddir).decode().split("\0")
        files_for_md5sum = [x for x in files_for_md5sum if x]
        md5s = subprocess.check_output(["md5sum", "--"] + files_for_md5sum,
                                       cwd=cddir)
        util.writefile(os.path.join(cddir, "md5sum.txt"), md5s)

        temp_iso = os.path.join(d, "temp.iso")
        subprocess.check_call([
            "xorriso", "-as", "mkisofs", "-quiet", "-o", temp_iso, "-r", "-J",
            "-c", "boot.cat", "-b", "isolinux.bin", "-no-emul-boot",
            "-boot-load-size", "4", "-boot-info-table", cddir
        ])
        subprocess.check_call(["isohybrid", "-h", "64", "-s", "32", temp_iso])
        util.copy(temp_iso, iso_image)
Esempio n. 3
0
def gen_iso(iso_image, authorized_key, cdpack=None):
    with tempfile.TemporaryDirectory() as d:
        inclusion = []

        util.copy(authorized_key, os.path.join(d, "authorized.pub"))
        util.writefile(os.path.join(d, "keyservertls.pem"),
                       authority.get_pubkey_by_filename("./server.pem"))
        resource.copy_to("postinstall.sh", os.path.join(d, "postinstall.sh"))
        os.chmod(os.path.join(d, "postinstall.sh"), 0o755)
        inclusion += ["authorized.pub", "keyservertls.pem", "postinstall.sh"]

        for variant in configuration.KEYCLIENT_VARIANTS:
            util.writefile(os.path.join(d, "keyclient-%s.yaml" % variant),
                           configuration.get_keyclient_yaml(variant).encode())
            inclusion.append("keyclient-%s.yaml" % variant)

        resource.copy_to("sshd_config", os.path.join(d, "sshd_config.new"))

        preseeded = resource.get_resource("preseed.cfg.in")
        generated_password = util.pwgen(20)
        add_password_to_log(generated_password)
        print("generated password added to log")
        preseeded = preseeded.replace(b"{{HASH}}",
                                      util.mkpasswd(generated_password))
        util.writefile(os.path.join(d, "preseed.cfg"), preseeded)

        inclusion += ["sshd_config.new", "preseed.cfg"]

        for package_name, (short_filename,
                           package_bytes) in packages.verified_download_full(
                               PACKAGES).items():
            assert "/" not in short_filename, "invalid package name: %s for %s" % (
                short_filename, package_name)
            assert short_filename.startswith(
                package_name +
                "_"), "invalid package name: %s for %s" % (short_filename,
                                                           package_name)
            assert short_filename.endswith(
                "_amd64.deb"), "invalid package name: %s for %s" % (
                    short_filename, package_name)
            util.writefile(os.path.join(d, short_filename), package_bytes)
            inclusion.append(short_filename)

        if cdpack is not None:
            subprocess.check_call(["tar", "-C", d, "-xzf", cdpack, "cd"])
        else:
            subprocess.check_output(
                ["tar", "-C", d, "-xz", "cd"],
                input=resource.get_resource("debian-9.2.0-cdpack.tgz"))

        subprocess.check_output([
            "cpio", "--create", "--append", "--format=newc", "--file=cd/initrd"
        ],
                                input="".join(
                                    "%s\n" % filename
                                    for filename in inclusion).encode(),
                                cwd=d)
        subprocess.check_call(["gzip", os.path.join(d, "cd/initrd")])

        files_for_md5sum = subprocess.check_output(
            ["find", ".", "-follow", "-type", "f", "-print0"],
            cwd=os.path.join(d, "cd")).decode().split("\0")
        assert files_for_md5sum.pop() == ""
        md5s = subprocess.check_output(["md5sum", "--"] + files_for_md5sum,
                                       cwd=os.path.join(d, "cd"))
        util.writefile(os.path.join(d, "cd", "md5sum.txt"), md5s)

        subprocess.check_call([
            "genisoimage", "-quiet", "-o", iso_image, "-r", "-J",
            "-no-emul-boot", "-boot-load-size", "4", "-boot-info-table", "-b",
            "isolinux.bin", "-c", "isolinux.cat",
            os.path.join(d, "cd")
        ])