mirror of
https://github.com/dragonlock2/matthewtran.com.git
synced 2026-06-28 01:58:34 +00:00
wip6
This commit is contained in:
@@ -1,302 +0,0 @@
|
||||
#!/usr/bin/env python3
|
||||
|
||||
import base64
|
||||
import json
|
||||
import secrets
|
||||
import subprocess
|
||||
import yaml
|
||||
from pathlib import Path
|
||||
from update import SOURCE_DIR, IMAGES, generate
|
||||
|
||||
UIDS = {
|
||||
"web" : 1001,
|
||||
"monero" : 1002,
|
||||
"game" : 1003,
|
||||
"nas" : 1004,
|
||||
}
|
||||
|
||||
PORTS = {
|
||||
"monero": [
|
||||
"18080:18080", # monerod
|
||||
"18081:18081",
|
||||
"3333:3333", # p2pool
|
||||
"37888:37888",
|
||||
"37889:37889",
|
||||
],
|
||||
"game": [
|
||||
"25565:25565", # minecraft
|
||||
"19132:19132/udp", # minecraft_bedrock
|
||||
"19133:19133/udp",
|
||||
"7777:7777", # terraria
|
||||
],
|
||||
}
|
||||
|
||||
def check_keys():
|
||||
if "home_key" not in cfg["core"]:
|
||||
print(f'cfg["core"]["home_key"] doesn\'t exist, try "{base64.b64encode(secrets.token_bytes(64)).decode("utf-8")}"')
|
||||
exit(1)
|
||||
for i, d in enumerate(cfg["drives"]):
|
||||
if "key" not in d:
|
||||
print(f'cfg["drives"][{i}]["key"] doesn\'t exist, try "{base64.b64encode(secrets.token_bytes(64)).decode("utf-8")}"')
|
||||
exit(1)
|
||||
|
||||
def add_root_drive():
|
||||
but["storage"] = {
|
||||
"disks": [
|
||||
{
|
||||
"device": "/dev/disk/by-id/coreos-boot-disk",
|
||||
"wipe_table": False,
|
||||
"partitions": [
|
||||
{
|
||||
"number": 4,
|
||||
"label": "root",
|
||||
"size_mib": 16384,
|
||||
"resize": True,
|
||||
},
|
||||
{
|
||||
"label": "home",
|
||||
"size_mib": 0,
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
"raid": [],
|
||||
"luks": [
|
||||
{
|
||||
"name": "root",
|
||||
"label": "luks-root",
|
||||
"device": "/dev/disk/by-partlabel/root",
|
||||
"wipe_volume": True,
|
||||
"clevis": { "tpm2": True },
|
||||
},
|
||||
{
|
||||
"name": "home",
|
||||
"device": "/dev/disk/by-partlabel/home",
|
||||
"wipe_volume": cfg["core"]["home_wipe"],
|
||||
"key_file": { "inline": base64.b64decode(cfg["core"]["home_key"]) },
|
||||
},
|
||||
],
|
||||
"filesystems": [
|
||||
{
|
||||
"device": "/dev/mapper/root",
|
||||
"format": "xfs",
|
||||
"wipe_filesystem": True,
|
||||
"label": "root",
|
||||
},
|
||||
{
|
||||
"path": "/var/home",
|
||||
"device": "/dev/mapper/home",
|
||||
"format": "xfs",
|
||||
"wipe_filesystem": cfg["core"]["home_wipe"],
|
||||
"with_mount_unit": True,
|
||||
},
|
||||
],
|
||||
"directories": [],
|
||||
"files": [],
|
||||
}
|
||||
|
||||
def add_more_drive():
|
||||
for d in cfg["drives"]:
|
||||
raid = len(d["devices"]) > 1
|
||||
if raid:
|
||||
but["storage"]["raid"].append({
|
||||
"name": d["name"],
|
||||
"level": "raid1",
|
||||
"devices": d["devices"],
|
||||
})
|
||||
but["storage"]["luks"].append({
|
||||
"name": d["name"],
|
||||
"device": f"/dev/md/{d["name"]}" if raid else d["devices"][0],
|
||||
"wipe_volume": d["wipe"],
|
||||
"key_file": { "inline": base64.b64decode(d["key"]) },
|
||||
})
|
||||
but["storage"]["filesystems"].append({
|
||||
"path": f"/var/mnt/{d["name"]}",
|
||||
"device": f"/dev/mapper/{d["name"]}",
|
||||
"format": "ext4",
|
||||
"wipe_filesystem": d["wipe"],
|
||||
"with_mount_unit": True,
|
||||
})
|
||||
but["storage"]["directories"].append({
|
||||
"path": f"/var/mnt/{d["name"]}",
|
||||
"user": { "name": "core" },
|
||||
"group": { "name": "core" },
|
||||
})
|
||||
|
||||
def add_packages():
|
||||
# TODO update once done https://github.com/coreos/fedora-coreos-tracker/issues/681
|
||||
but["systemd"] = {
|
||||
"units": [
|
||||
{
|
||||
"name": "rpm-ostree-install.service",
|
||||
"enabled": True,
|
||||
"contents": "\n".join([
|
||||
"[Unit]",
|
||||
"Description=Install packages",
|
||||
"Wants=network-online.target",
|
||||
"After=network-online.target",
|
||||
"Before=zincati.service",
|
||||
"ConditionPathExists=!/etc/rpm/%N.stamp",
|
||||
"[Service]",
|
||||
"Type=oneshot",
|
||||
"RemainAfterExit=yes",
|
||||
"ExecStart=/usr/bin/rpm-ostree install -y --allow-inactive " + " ".join([
|
||||
"avahi",
|
||||
"htop",
|
||||
"vim",
|
||||
]),
|
||||
"ExecStart=/bin/touch /etc/rpm/%N.stamp",
|
||||
"ExecStart=/bin/systemctl --no-block reboot",
|
||||
"[Install]",
|
||||
"WantedBy=multi-user.target",
|
||||
]),
|
||||
},
|
||||
],
|
||||
}
|
||||
|
||||
def add_ssh_keys():
|
||||
assert(len(cfg["core"]["ssh_keys"]) > 0)
|
||||
but["passwd"] = {
|
||||
"users": [
|
||||
{
|
||||
"name": "core",
|
||||
"ssh_authorized_keys": cfg["core"]["ssh_keys"],
|
||||
},
|
||||
],
|
||||
}
|
||||
|
||||
def set_hostname():
|
||||
but["storage"]["files"].append({
|
||||
"path": "/etc/hostname",
|
||||
"mode": 0o644,
|
||||
"contents": { "inline": cfg["core"]["hostname"] },
|
||||
})
|
||||
|
||||
def allow_port_access():
|
||||
but["storage"]["files"].append({
|
||||
"path": "/etc/sysctl.d/99-unprivileged-ports.conf",
|
||||
"mode": 0o644,
|
||||
"contents": { "inline": "net.ipv4.ip_unprivileged_port_start=80" },
|
||||
})
|
||||
|
||||
def add_users():
|
||||
for user in UIDS:
|
||||
but["passwd"]["users"].append({
|
||||
"name": user,
|
||||
"uid": UIDS[user],
|
||||
})
|
||||
but["storage"]["files"].append({
|
||||
"path": f"/var/lib/systemd/linger/{user}",
|
||||
"contents": { "inline": "" },
|
||||
})
|
||||
|
||||
def copy_source():
|
||||
but["storage"]["directories"].append({
|
||||
"path": SOURCE_DIR,
|
||||
"user": { "name": "core" },
|
||||
"group": { "name": "core" },
|
||||
})
|
||||
for i in (f for s in IMAGES.values() for f in s):
|
||||
but["storage"]["directories"].append({
|
||||
"path": str(Path(SOURCE_DIR) / i),
|
||||
"user": { "name": "core" },
|
||||
"group": { "name": "core" },
|
||||
})
|
||||
for f in Path(i).glob("*"):
|
||||
but["storage"]["files"].append({
|
||||
"path": str(Path(SOURCE_DIR) / f),
|
||||
"contents": { "inline": open(f, "r").read() },
|
||||
"user": { "name": "core" },
|
||||
"group": { "name": "core" },
|
||||
})
|
||||
|
||||
def build_images():
|
||||
but["storage"]["directories"].append({ "path": "/etc/containers/systemd/users" })
|
||||
for user in IMAGES:
|
||||
but["storage"]["directories"].append({ "path": f"/etc/containers/systemd/users/{UIDS[user]}" })
|
||||
for img in IMAGES[user]:
|
||||
but["storage"]["files"].append({
|
||||
"path": f"/etc/containers/systemd/users/{UIDS[user]}/{img}.build",
|
||||
"contents": { "inline": "\n".join([
|
||||
"[Build]",
|
||||
f"ImageTag={img}",
|
||||
f"SetWorkingDirectory={SOURCE_DIR}/{img}",
|
||||
])}
|
||||
})
|
||||
|
||||
def create_pods():
|
||||
for user in IMAGES:
|
||||
but["storage"]["files"].append({
|
||||
"path": f"/etc/containers/systemd/users/{UIDS[user]}/{user}.pod",
|
||||
"contents": { "inline": "[Pod]\n" + "\n".join([f"PublishPort={p}" for p in PORTS[user]])}
|
||||
})
|
||||
|
||||
def create_folders():
|
||||
but["storage"]["directories"].append({
|
||||
"path": cfg["core"]["data_dir"],
|
||||
"user": { "name": "core" },
|
||||
"group": { "name": "core" },
|
||||
})
|
||||
for user in IMAGES:
|
||||
for img in IMAGES[user]:
|
||||
but["storage"]["directories"].append({
|
||||
"path": str(Path(cfg["core"]["data_dir"]) / img),
|
||||
"user": { "name": user },
|
||||
"group": { "name": user },
|
||||
})
|
||||
|
||||
def run_containers():
|
||||
for user in IMAGES:
|
||||
for img in IMAGES[user]:
|
||||
but["storage"]["files"].append({
|
||||
"path": f"/etc/containers/systemd/users/{UIDS[user]}/{img}.container",
|
||||
"contents": { "inline": "\n".join([
|
||||
"[Container]",
|
||||
f"ContainerName={img}",
|
||||
f"Image={img}.build",
|
||||
f"Pod={user}.pod",
|
||||
f"Volume={str(Path(cfg["core"]["data_dir"]) / img)}:/root/data:z",
|
||||
"[Install]",
|
||||
"WantedBy=default.target",
|
||||
])}
|
||||
})
|
||||
|
||||
if __name__ == "__main__":
|
||||
cfg = json.load(open("config/server.json"))
|
||||
but = {
|
||||
"variant": "fcos",
|
||||
"version": "1.6.0",
|
||||
}
|
||||
|
||||
# core setup
|
||||
check_keys()
|
||||
add_root_drive()
|
||||
add_more_drive()
|
||||
add_packages()
|
||||
add_ssh_keys()
|
||||
set_hostname()
|
||||
allow_port_access()
|
||||
|
||||
# server setup
|
||||
add_users()
|
||||
generate(cfg)
|
||||
copy_source()
|
||||
build_images()
|
||||
create_pods()
|
||||
create_folders()
|
||||
run_containers()
|
||||
|
||||
|
||||
# TODO add rest of containers
|
||||
# add core to nas group
|
||||
# TODO script to backup => restore backup if desired
|
||||
# TODO reduce disk logging?
|
||||
|
||||
|
||||
# TODO generate ISO, else nginx if --insecure
|
||||
with open("config/server.bu", "w") as f:
|
||||
f.write(yaml.dump(but, sort_keys=False))
|
||||
subprocess.check_output(["butane", "-p", "-s", "-o", "config/server.ign", "config/server.bu"])
|
||||
|
||||
print("NOTE - TPM may need to be cleared after enough provisions.")
|
||||
print("WARNING - Using unencrypted connections without authentication, ensure LAN is secure!")
|
||||
@@ -1,75 +0,0 @@
|
||||
#!/usr/bin/env python3
|
||||
|
||||
import json
|
||||
import shutil
|
||||
import subprocess
|
||||
from pathlib import Path
|
||||
|
||||
SOURCE_DIR = "/var/source"
|
||||
|
||||
IMAGES = {
|
||||
"monero": [
|
||||
"monerod",
|
||||
"p2pool",
|
||||
],
|
||||
"game": [
|
||||
"minecraft",
|
||||
"minecraft_bedrock",
|
||||
"terraria",
|
||||
],
|
||||
}
|
||||
|
||||
def generate(cfg):
|
||||
# minecraft
|
||||
shutil.copy("minecraft/server.default", "minecraft/server.properties")
|
||||
with open("minecraft/server.properties", "a") as f:
|
||||
f.write(f"level-name=data/{cfg["minecraft"]["world"]}\n")
|
||||
|
||||
# minecraft_bedrock
|
||||
shutil.copy("minecraft_bedrock/server.default", "minecraft_bedrock/server.properties")
|
||||
with open("minecraft_bedrock/server.properties", "a") as f:
|
||||
f.write(f"level-name={cfg["minecraft_bedrock"]["world"]}\n")
|
||||
|
||||
# terraria
|
||||
shutil.copy("terraria/config.default", "terraria/config.txt")
|
||||
with open("terraria/config.txt", "a") as f:
|
||||
f.write(f"world=/root/data/worlds/{cfg["terraria"]["world"]}.wld\n")
|
||||
f.write(f"autocreate={cfg["terraria"]["autogen"]["size"]}\n") # 1=small, 2=medium, 3=large
|
||||
f.write(f"difficulty={cfg["terraria"]["autogen"]["difficulty"]}\n") # 0=normal, 1=expert, 2=master, 3=journey
|
||||
with open("terraria/password.txt", "w") as f:
|
||||
f.write(cfg["terraria"]["password"])
|
||||
|
||||
def run(cmds):
|
||||
try:
|
||||
subprocess.check_output(["ssh", f"core@{cfg["core"]["hostname"]}.local", ";".join(cmds)], stderr=subprocess.STDOUT)
|
||||
except subprocess.CalledProcessError as e:
|
||||
print("\033[31m", end="")
|
||||
print(e.output.decode())
|
||||
print("\033[0m", end="")
|
||||
exit(1)
|
||||
|
||||
if __name__ == "__main__":
|
||||
cfg = json.load(open("config/server.json"))
|
||||
|
||||
# generate helper files
|
||||
generate(cfg)
|
||||
|
||||
# copy files
|
||||
for f in (f for l in IMAGES.values() for f in l):
|
||||
subprocess.run(["scp", "-r", f, f"core@{cfg["core"]["hostname"]}.local:{SOURCE_DIR}"], check=True)
|
||||
|
||||
# run builds
|
||||
for user in IMAGES:
|
||||
print(f"building images for {user}...")
|
||||
run([f"cd {SOURCE_DIR}"] + [
|
||||
f"sudo -u {user} podman build --tag {i} {SOURCE_DIR}/{i}"
|
||||
for i in IMAGES[user]
|
||||
])
|
||||
|
||||
# restart pods
|
||||
for user in IMAGES:
|
||||
print(f"restarting pod for {user}...")
|
||||
run([
|
||||
f"cd {SOURCE_DIR}",
|
||||
f"sudo systemctl --machine={user}@.host --user restart {user}-pod " + " ".join(IMAGES[user]),
|
||||
])
|
||||
Reference in New Issue
Block a user