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

217 lines
5.4 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 = "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDVcZe1QPxVd/I7D2FyTZiLqg1K3Ire/Ap+0nExmSRw4gEWzufSFefNWUSYhCoAUdfAqaE1KzjY7zy+NQ0LIyJO/fnF0K1EeyoNVYZkB5VyfoCXkT+zamO03tCJTmX4/5v5stUuF4Rem1EmgJIbRGUWJ1gOdLYFtodj0WhGo7gU8uNwvVdyIhum5JhC1j6s1Rtv729PITFZ+JPEqkyMD1ZX8AVDamLZy4fhaHJD3xcTbkFxRHbZTMlfogD8c2MXKIV1Qk9FbuVeOuc5r08D/NkEFm9cOKPoJ5eLl+zDo7uoS3oTlyVrw80HixofqvTvZtGlXMQPRWH77EY9tUDvaYZz wmoore-new-key"
# partition the disk
files.put(
name="Upload partition layout",
src="files/partition-map.sfdisk",
dest="/tmp/partition-map.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.sfdisk"]
)
esp = f"{disk}1"
root = f"{disk}2"
server.shell(
name="Format partitions", commands=[f"mkfs.vfat {esp}", 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"
)
files.directory(name="Create mount point for ESP", path="/media/root/boot")
server.mount(name="Mount ESP", path="/media/root/boot", device=esp)
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-stable"],
)
server.shell(
name="Add swap",
commands=[
"chimera-chroot /media/root mkswap -U clear --size 2G --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 systemd-boot",
"chimera-chroot /media/root bootctl install",
],
)
files.line(
name="Configure loader.conf",
path="/media/root/boot/loader/loader.conf",
line="timeout",
replace="timeout 1",
)
# TODO: Deal with /boot permissions messages from bootctl
server.shell(
name="Generate bootloader entries",
commands=[
"chimera-chroot /media/root gen-systemd-boot",
],
)
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 the regular user 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,
)