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, )