chimera-pyinfra/install-bios.py
2024-12-09 09:29:39 +10:00

196 lines
4.6 KiB
Python

import string
import random
from pyinfra.operations import server, files
def generate_password(length=20):
characters = string.ascii_letters + string.digits
password = "".join(random.choice(characters) for _ in range(length))
return password
# User to setup
username = input("Username for regular user: ")
## Determine the disk to install on to
disk = input("Disk device (E.g. /dev/vda): ")
if not disk.startswith("/dev"):
cont = input(f"{disk} does not start with /dev. Continue [y/n]? ")
if cont != "y":
exit(1)
rootpw = generate_password()
print(f"Password for root will be: {rootpw}")
ok = input(f"Install onto {disk} [y/n]? ")
if ok != "y":
exit(1)
# TODO: Make this data?
user_ssh_key = ""
# partition the disk
files.put(
name="Upload partition layout",
src="files/partition-map-bios.sfdisk",
dest="/tmp/partition-map-bios.sfdisk",
mode=True,
create_remote_dir=False,
)
server.shell(name="Wipe the disk", commands=[f"wipefs -a {disk}"])
server.shell(
name="Partition the disk",
commands=[f"sfdisk {disk} < /tmp/partition-map-bios.sfdisk"],
)
root = f"{disk}1"
server.shell(name="Format partitions", commands=[f"mkfs.ext4 {root}"])
files.directory(name="Create mount point for root", path="/media/root")
server.mount(name="Mount root", path="/media/root", device=root)
files.directory(
name="Ensure target permissions are right", path="/media/root", mode="755"
)
server.shell(
name="Bootstrap system",
commands=["chimera-bootstrap /media/root base-minimal mkfs"],
)
server.shell(name="Update packages", commands=["chimera-chroot /media/root apk update"])
server.shell(
name="Upgrade packages",
commands=["chimera-chroot /media/root apk upgrade --available"],
)
server.shell(
name="Add kernel package",
commands=["chimera-chroot /media/root apk add linux-lts"],
)
server.shell(
name="Add swap",
commands=[
"chimera-chroot /media/root mkswap -U clear --size 512M --file /swapfile",
"chimera-chroot /media/root swapon /swapfile",
],
)
server.shell(
name="Generate fstab", commands=["genfstab -U /media/root >> /media/root/etc/fstab"]
)
extra_packages = [
"chimerautils-extra",
"dhcpcd",
"dmesg",
"dosfstools",
"e2fsprogs",
"file",
"initramfs-tools",
"iproute2",
"iputils",
"less",
"opendoas",
"openssh",
"syslog-ng",
]
server.shell(
name="Add extra packages",
commands=[f"chimera-chroot /media/root apk add {' '.join(extra_packages)}"],
)
server.shell(
name="Enable ssh, dhcpcd, and syslog",
commands=[
"chimera-chroot /media/root dinitctl --offline enable sshd",
"chimera-chroot /media/root dinitctl --offline enable dhcpcd",
"chimera-chroot /media/root dinitctl --offline enable syslog-ng",
],
)
server.shell(
name="Set root password",
commands=[f"echo '{rootpw}' | chimera-chroot /media/root passwd --stdin root"],
)
server.shell(
name="Refresh initramfs",
commands=["chimera-chroot /media/root update-initramfs -c -k all"],
)
server.shell(
name="Add bootloader",
commands=[
"chimera-chroot /media/root apk add grub-i386-pc",
f"chimera-chroot /media/root grub-install {disk}",
"chimera-chroot /media/root update-grub",
],
)
files.directory(
name="Create .ssh for root",
path="/media/root/root/.ssh",
mode="700",
)
files.line(
name="Add authorized_key to root",
path="/media/root/root/.ssh/authorized_keys",
line=user_ssh_key,
ensure_newline=True,
)
server.shell(
name="Add regular user",
commands=[
f"chimera-chroot /media/root useradd -m {username}",
f"chimera-chroot /media/root usermod -a -G wheel {username}",
],
)
# NOTE: These assume that {username} gets the uid/gid 1000
files.directory(
name=f"Create .ssh for {username}",
path=f"/media/root/home/{username}/.ssh",
mode="700",
user="1000",
group="1000",
)
files.file(
name=f"Create authorized_keys for {username}",
path=f"/media/root/home/{username}/.ssh/authorized_keys",
user="1000",
group="1000",
)
files.line(
name=f"Add authorized_key to {username}",
path=f"/media/root/home/{username}/.ssh/authorized_keys",
line=user_ssh_key,
ensure_newline=True,
)
files.line(
name="Disable SSH password authentication",
path="/media/root/etc/ssh/sshd_config",
line="^#PasswordAuthentication .*$",
replace="PasswordAuthentication no",
)
files.line(
name="Allow :wheel to use doas",
path="/media/root/etc/doas.conf",
line="permit persist :wheel",
ensure_newline=True,
)