Remove autodeploy scripts

This commit is contained in:
ItsDrike 2021-07-15 22:31:42 +02:00
parent b67f74d539
commit 21ca7d9f09
No known key found for this signature in database
GPG key ID: B5F6B41F708C3ADD
12 changed files with 0 additions and 725 deletions

View file

@ -1,113 +0,0 @@
# Arch installation checklist
This file contains simplified instructions for Arch Linux installation
Following these should lead to a full installation of barebone Arch system,
with grub bootloader and a priviledged sudoer user.
Note: Running the script can automated many of these points, if you are comming
here after running the script, look for a line saying: **Proceed from this line, if you're reading after chrooting**
## Set keyboard layout
Default layout will be US
`ls /usr/share/kbd/keymaps/**/*.map.gz` <- list keymaps
`loadkeys de-latin1` <- modify layout
## Verify boot mode
`ls /sys/firmware/efi/efivars` <- if exist, system is UEFI, else legacy BIOS
## Internet connection
Ethernet connection is automatic, WiFi:
`ip link` <- check network interface works and is enabled
`iwctl` <- authenticate to your WiFi network
`ping archlinux.org` <- test connection
## System clock
`timedatectl set-ntp true` <- make sure the clock will be accurate
`timedatectl status` <- check the status
## Partition the disk
`fdisk /dev/sdX` <- make partitions
- EFI (if UEFI)
- Swap
- Root
- (Home)
## Format the partitions and make filesystems
`mkfs.ext4 /dev/root_partition`
`mkfs.fat -F32 /dev/efi_system_partition`
`mkswap /dev/swap_partition`
## Mount the file systems
`mount /dev/root_partition /mnt`
`mount /dev/efi_system_partition /mnt/boot`
`swapon /dev/swap_partition`
## Install essentials
First select mirrors (`/etc/pacman.d/mirrorlist`)
`pacstrap /mnt base linux linux-firmware base-devel NetworkManager vim`
## Fstab
`genfstab -U /mnt >> /mnt/etc/fstab`
## Chroot
`arch-chroot /mnt`
# Proceed from this line, if you're reading after chrooting
## Set time zone
`ln -sf /usr/share/zoneinfo/Region/Ciry /etc/localtime` <- specify timezone
`hwclock --systohc` <- synchronize clock, to generate `/etc/adjtime`
## Localization
Edit `/etc/locale.gen` and uncomment `en_US.UTF-8 UTF-8` and ISO locales
`locale-gen` <- Generate locales
Set LANG variable in `locale.conf`:
```
LANG=en_US.UTF-8
```
Set persistent keyboard layout in `/etc/vconsole.conf`
(This will default to english, if not set)
```
KEYMAP=de-latin1
```
## Network Config
Define hostname in `/etc/hostname` (name of computer)
Add matching entries to `/etc/hosts`
```
127.0.0.1 localhost
::1 localhost
127.0.1.1 hostname.localdomain hostname
```
## Set root password or make other account
`passwd` <- Set root password
It's better to work with priviledged user rather than root account directly.
To do this, we first have to install `sudo` and `vim`. (We did this with `pacstrap`)
After that, we can edit the configuration by `sudo EDITOR=vim visudo`, in which we will uncomment the line `%wheel ALL=(ALL) ALL` and save
After sudo is set up and `wheel` group is allowed to use it, we can make the user:
`useradd -G wheel,admin -d /path/to/home -m username -`
`passwd username`
After this, we can login as this user and make sure everything works as it shoud:
`sudo su username`
## Install bootloader
This will only cover grub, for other bootloaders, visit `https://wiki.archlinux.org/index.php/Arch_boot_process#Boot_loader`
Install `grub` package with pacman
Note: To detect other operating systems too, you will also need `os-prober` package, also with NTFS systems, if windows isn't detected, try installing `ntfs-3g` and remounting
UEFI:
`efibootmgr` package is also needed for UEFI systems
`grub-install --target=x86_64-efi --efi-directory=boot --bootloader-id=GRUB`
BIOS (Legacy):
`grub-install --target=i386-pc /dev/sdX`, where sdX is the disk, **not a partition**
Note: `--removable` option can be used, which will allow booting if EFI variables are reset or you move to another PC
### Generating grub configuration
`grub-mkconfig -o /boot/grub/grub.cfg`

View file

@ -1,9 +0,0 @@
if ! type "python3" &> /dev/null; then
sudo pacman -S python
fi
if ! type "pip3" &> /dev/null; then
sudo pacman -S python-pip
fi
pip install -r requirements.txt
python3 -m src

View file

@ -1,5 +0,0 @@
pyyaml
psutil
colorama
pyinquirer
inquirer

View file

@ -1,26 +0,0 @@
import sys
import colorama
import inquirer.shortcuts
from src.arch_install import install_arch
from src.dotfiles_install import install_dotfiles
from src.package_install import install_packages
from src.util.command import run_cmd
colorama.init(autoreset=True)
if inquirer.shortcuts.confirm("Do you wish to perform Arch install? (Directly from live ISO)"):
run_cmd("clear")
print(f"{colorama.Fore.BLUE}Running Arch Installation")
root_mountpoint = install_arch()
print(f"{colorama.Fore.GREEN}Arch installation complete")
print(f"{colorama.Fore.CYAN}To install packages and dotfiles, move this whole directory to the new installation and run it from there.")
sys.exit()
if inquirer.shortcuts.confirm("Do you wish to perform package installation (from packages.yaml)"):
install_packages()
if inquirer.shortcuts.confirm("Do you wish to install dotfiles? (from home and root folders)"):
install_dotfiles()

View file

@ -1,130 +0,0 @@
from pathlib import Path
from typing import Optional
import colorama
import inquirer.shortcuts
from src.util.command import run_cmd, run_root_cmd
from src.util.internet import connect_internet
colorama.init(autoreset=True)
def mount_partition(partition_path: Path, mount_path: Optional[Path] = None, default_path: str = "/mnt") -> Path:
"""
Mount given `partition_path` to `mount_path`.;
If `mount_path` wasn't provided, ask user for it.
After mounting, mount_path will be returned
"""
if not mount_path:
mount_path = Path(inquirer.shortcuts.path(f"Specify mountpoint for {partition_path}", default=default_path))
if not mount_path.exists():
run_root_cmd(f"mkdir -p {mount_path}")
run_root_cmd(f"mount {partition_path} {mount_path}")
return mount_path
def partition_disk() -> Path:
"""Create all necessary partitions and return root mountpoint"""
uefi = Path("/sys/firmware/efi/efivars").is_dir()
# Let user make partitions in shell environment
partitions_made = inquirer.shortcuts.confirm("Do you already have partitions pre-made?")
if not partitions_made:
print(
f"{colorama.Fore.CYAN}Dropping to shell environment, create your partitions here."
" When you are done, use `exit` to return\n"
f"{colorama.Style.DIM}This is {'UEFI' if uefi else 'LEGACY (BIOS)'} system\n"
)
run_cmd("exec $SHELL")
# Obtain partitions from user and mount them
root_part = Path(inquirer.shortcuts.path("Specify the root partition (/dev/sdXY)", exists=True))
if inquirer.shortcuts.confirm(f"Do you wish to make EXT4 filesystem on {root_part}?", default=True):
run_root_cmd(f"mkfs.ext4 {root_part}")
root_mountpoint = mount_partition(root_part)
if inquirer.shortcuts.confirm("Do you have an EFI partition?", default=uefi):
if not uefi:
print(
f"{colorama.Fore.RED}Warning: Adding EFI partition from non-uefi system isn't adviced.\n"
"While this process won't directly fail, you won't be able to install a bootloader from "
"this computer. You can proceed, but you will have to use another computer to install the bootloader."
)
efi_part = Path(inquirer.shortcuts.path("Specify EFI partition (/dev/sdXY)", exists=True))
if inquirer.shortcuts.confirm(f"Do you wish to make FAT32 filesystem on {efi_part}?", default=True):
run_root_cmd(f"mkfs.fat -F32 {efi_part}")
mount_partition(efi_part, default_path=str(Path(root_mountpoint, "boot")))
elif uefi:
print(
f"{colorama.Fore.RED}Proceeding without EFI partition on UEFI system is not adviced, "
"unless you want to run this OS with other UEFI capable system"
)
if inquirer.shortcuts.confirm("Do you have a swap partition?"):
swap_part = Path(inquirer.shortcuts.path("Specify the swap partition (/dev/sdXY)", exists=True))
if inquirer.shortcuts.confirm(f"Do you wish to make swap system on {root_part}?", default=True):
run_root_cmd(f"mkswap {swap_part}")
if inquirer.shortcuts.confirm("Do you wish to turn on swap?", default=True):
run_root_cmd(f"swapon {swap_part}")
while inquirer.shortcuts.confirm("Do you have any other partition?"):
part_path = Path(inquirer.shortcuts.path("Specify partition path (/dev/sdXY)", exists=True))
if inquirer.shortcuts.confirm("Do you wish to format this partition?"):
print(f"{colorama.Fore.CYAN}Dropping to shell, format the partition here and type `exit` to return")
run_cmd("exec $SHELL")
mount_partition(part_path)
print(f"{colorama.Fore.LIGHTCYAN_EX}Printing disk report (with lsblk)")
run_root_cmd("lsblk")
if inquirer.shortcuts.confirm("Do you want to drop to shell and make some further adjustments?"):
print(f"{colorama.Fore.CYAN}After you are done, return by typing `exit`")
run_cmd("exec $SHELL")
print(f"{colorama.Fore.GREEN}Partitioning complete")
return root_mountpoint
def run_pacstrap(root_mountpoint: Path):
mirror_setup = inquirer.shortcuts.confirm("Do you wish to setup your mirrors (This is necessary for fast downloads)?", default=True)
if mirror_setup:
print(
f"{colorama.Fore.CYAN}Dropping to shell environment, setup your mirrors from here."
" When you are done, use `exit` to return\n"
f"{colorama.Style.DIM}Mirrors are located in `/etc/pacman.d/mirrorlist`\n"
)
run_cmd("exec $SHELL")
extra_pkgs = inquirer.shortcuts.checkbox(
"You can choose to install additional packages with pacstrap here (select with space)",
choices=["networkmanager", "base-devel", "vim", "nano"]
)
run_root_cmd(f"pacstrap {root_mountpoint} base linux linux-firmware {' '.join(extra_pkgs)}")
if inquirer.shortcuts.confirm("Do you wish to make some further adjustments and drop to shell?"):
print(f"{colorama.Fore.CYAN}When you are done, use `exit` to return")
run_cmd("exec $SHELL")
def install_arch():
"""Perform full Arch installation and return mountpoint and default user"""
connect_internet()
run_root_cmd("timedatectl set-ntp true")
root_mountpoint = partition_disk()
run_pacstrap(root_mountpoint)
print(f"{colorama.Fore.CYAN}Generating fstab")
run_root_cmd(f"genfstab -U {root_mountpoint} >> {root_mountpoint}/etc/fstab")
print(
f"\n{colorama.Fore.GREEN}Core installation complete.\n"
f"{colorama.Fore.YELLOW}Instalation within chroot environment is not possible from this script, "
"run chroot_install.py within chroot environment.\n"
f"{colorama.Fore.LIGHTBLUE_EX}Execute: {colorama.Style.BRIGHT}`arch-chroot /mnt`"
)
if __name__ == "__main__":
install_arch()

View file

@ -1,12 +0,0 @@
import colorama
colorama.init(autoreset=True)
def install_chroot():
print(f"{colorama.Fore.RED}Sorry, chroot installation file is still WIP, for now, proceed manually.")
print(f"{colorama.Fore.LIGHTCYAN_EX}You can use `arch-install-checklist.md` file which containes detailed installation steps.")
if __name__ == "__main__":
install_chroot()

View file

@ -1,111 +0,0 @@
from datetime import datetime
from pathlib import Path
import colorama
import inquirer.shortcuts
from src.util.command import run_root_cmd
colorama.init(autoreset=True)
def _find_all_files(path: Path):
for subpath in path.iterdir():
if subpath.is_dir():
yield from _find_all_files(subpath)
else:
yield subpath
def _walk_dotfiles():
"""
Walk through every stored file in repositorie's dotfiles,
start by going through `home` specific files, and continue
with `root` dotfiles.
"""
yield from _find_all_files(Path.cwd().joinpath("home"))
yield from _find_all_files(Path.cwd().joinpath("root"))
def _dotfile_to_system(dotfile_path: Path) -> Path:
"""Convert dotfile path to corresponding path on real system"""
base_dir = str(Path.cwd())
if base_dir + "/home/" in str(dotfile_path):
rel_path = str(dotfile_path).replace(base_dir + "/home/", "")
return Path.home().joinpath(rel_path)
elif base_dir + "/root/" in str(dotfile_path):
rel_path = str(dotfile_path).replace(base_dir + "/root/", "")
return Path("/", rel_path)
else:
raise ValueError(f"Given path is not a valid dotfile path ({dotfile_path})")
def make_backup() -> None:
"""
Find all files which will be replaced and back them up.
Files which doesn't exist in the real system destination
will be ignored.
"""
print(f"{colorama.Fore.LIGHTYELLOW_EX}Creating current dotfiles backup")
time = str(datetime.now()).replace(" ", "--")
backup_dir = Path.joinpath(Path.cwd(), "backup", time)
backup_dir.mkdir(parents=True, exist_ok=True)
for dotfile_path in _walk_dotfiles():
real_path = _dotfile_to_system(dotfile_path)
if not real_path.exists():
continue
rel_path = str(dotfile_path).replace(str(Path.cwd()) + "/", "")
backup_path = backup_dir.joinpath(rel_path)
# Ensure backup directory existence
if real_path.is_dir():
backup_path.mkdir(parents=True, exist_ok=True)
else:
backup_path.parent.mkdir(parents=True, exist_ok=True)
print(f"{colorama.Style.DIM}Backing up{real_path}")
run_root_cmd(f"cp '{real_path}' '{backup_path}'", enable_debug=False)
print(f"{colorama.Fore.LIGHTYELLOW_EX}Backup complete")
def overwrite_dotfiles() -> None:
for dotfile_path in _walk_dotfiles():
real_path = _dotfile_to_system(dotfile_path)
# Ensure existence of system directory
if dotfile_path.is_dir():
real_path.mkdir(parents=True, exist_ok=True)
else:
dotfile_path.parent.mkdir(parents=True, exist_ok=True)
# If we encounter placeholder file, making folder is suffictient
# don't proceed with copying it to avoid clutterring the original system
# with empty placeholder files, these files are here only for git to
# recognize that directory
if str(dotfile_path).endswith("placeholder"):
continue
print(f"{colorama.Style.DIM}Overwriting {real_path}")
run_root_cmd(f"cp '{dotfile_path}' '{real_path}'")
def install_dotfiles() -> None:
if inquirer.shortcuts.confirm("Do you want to backup current dotfiles? (Recommended)", default=True):
make_backup()
print(f"{colorama.Fore.CYAN}Proceeding with dotfiles installation (this will overwrite your original files)")
if inquirer.shortcuts.confirm(
"Have you adjusted all dotfiles to your liking? "
f"{colorama.Fore.RED}(proceeding without checking the dotfiles first isn't adviced){colorama.Fore.RESET}"
):
overwrite_dotfiles()
print(f"{colorama.Fore.LIGHTYELLOW_EX}Dotfile installation complete, make sure to adjust the dotfiles to your liking.")
else:
print(f"{colorama.Fore.RED}Aborted...")
if __name__ == "__main__":
install_dotfiles()

View file

@ -1,45 +0,0 @@
import typing as t
import colorama
import inquirer.shortcuts
import yaml
from src.util.command import run_root_cmd
from src.util.package import InvalidPackage, Package, PackageAlreadyInstalled
colorama.init(autoreset=True)
def obtain_packages() -> t.List[Package]:
with open("packages.yaml") as f:
yaml_file = yaml.safe_load(f)
pacman_packages = yaml_file["pacman"]
aur_packages = yaml_file["aur"]
git_packages = yaml_file["git"]
packages = []
packages += Package.safe_load(pacman_packages)
packages += Package.safe_load(git_packages, git=True)
packages += Package.safe_load(aur_packages, aur=True)
return packages
def install_packages() -> None:
packages = obtain_packages()
if inquirer.shortcuts.confirm("Do you wish to perform system upgrade first? (Recommended)", default=True):
run_root_cmd("pacman -Syu")
for package in packages:
try:
print(f"{colorama.Fore.CYAN}Installing {package}")
package.install()
except PackageAlreadyInstalled:
print(f"{colorama.Style.DIM}Package {package} is already installed, skipping")
except InvalidPackage as e:
print(f"{colorama.Fore.RED}{str(e)}")
if __name__ == "__main__":
install_packages()

View file

@ -1,47 +0,0 @@
import os
import subprocess
import colorama
import inquirer.shortcuts
DEBUG = True
def debug_confirm_run(cmd):
if DEBUG:
cnfrm = inquirer.shortcuts.confirm(
f"{colorama.Fore.BLUE}[DEBUG] Running command: "
f"{colorama.Fore.YELLOW}{cmd}{colorama.Fore.RESET}"
)
return cnfrm
else:
return True
def run_root_cmd(cmd: str, enable_debug: bool = True) -> subprocess.CompletedProcess:
"""Run command as root"""
if os.geteuid() != 0:
return run_cmd(f"sudo {cmd}", enable_debug=enable_debug)
else:
return run_cmd(cmd, enable_debug=enable_debug)
def run_cmd(cmd: str, capture_out: bool = False, enable_debug: bool = True) -> subprocess.CompletedProcess:
"""Run given command"""
args = {}
if capture_out:
args.update({"stdout": subprocess.PIPE, "stderr": subprocess.STDOUT})
if not enable_debug or debug_confirm_run(cmd):
return subprocess.run(cmd, shell=True, **args)
else:
# If debug confirm wasn't confirmed, return code 1 (error)
return subprocess.CompletedProcess(cmd, returncode=1)
def command_exists(cmd) -> bool:
"""Check if given command can be executed"""
parts = cmd.split()
executable = parts[0] if parts[0] != "sudo" else parts[1]
proc = run_cmd(f"which {executable}", capture_out=True)
return proc.returncode != 1

View file

@ -1,95 +0,0 @@
import sys
import time
import urllib.request
from urllib.error import URLError
import colorama
import inquirer.shortcuts
from src.util.command import command_exists, run_cmd, run_root_cmd
def _connect_wifi() -> bool:
"""
Attempt to connect to internet using WiFI.
This uses `nmtui` with fallback to `iwctl`, if none
of these tools are aviable, either quit or return False,
if the tool was executed properly, return True
Note: True doesn't mean we connected, just that the tool was ran,
it is up to user to use that tool properly and make the connection.
"""
if command_exists("nmtui"):
run_root_cmd("nmtui")
elif command_exists("iwctl"):
run_root_cmd("iwctl")
else:
print(
f"{colorama.Fore.RED}{colorama.Style.BRIGHT}ERROR: "
"WiFi connection tool not found: `nmtui`/`iwctl`, please use Ethernet instead.\n"
"Alternatively, connect manually outside of this script and re-run it."
)
opt = inquirer.shortcuts.list_input(
"How do you wish to proceed?",
choices=["Quit and connect manually", "Proceed with Ethernet"]
)
if opt == "Quit and connect manually":
sys.exit()
else:
return False
return True
def _connect_ethernet(max_wait_time: int = 20, iteration_time: int = 1) -> bool:
"""
Attempt to connect to internet using Ethernet.
This will simply wait for the user to plug in the ethernet cable,
once that happens loop is interrupted and True is returned. In case
it takes over the `max_wait_time`, loop ends and False is returned.
`iteration_time` is the time of each loop iteration, after whcih we
check if connection is valid, if not, we continue iterating.
"""
print(f"{colorama.Style.DIM}Please plug in the Ethernet cable, waiting 20s")
time_elapsed = 0
while not check_connection() and time_elapsed < max_wait_time:
time.sleep(iteration_time)
time_elapsed += iteration_time
if time_elapsed >= max_wait_time:
# We stopped because max wait time was crossed
return False
else:
# We stopped because connection to internet was successful
return True
def connect_internet():
wifi_possible = True
while not check_connection():
run_cmd("clear")
print(f"{colorama.Fore.RED}Internet connection unaviable")
if wifi_possible:
connect_opt = inquirer.shortcuts.list_input("How do you wish to connect to internet?", choices=["Wi-Fi", "Ethernet"])
else:
connect_opt = "Ethernet"
if connect_opt == "Wi-Fi":
wifi_possible = _connect_wifi()
else:
if _connect_ethernet():
break
print(f"{colorama.Fore.GREEN}Internet connection successful")
def check_connection(host="https://google.com") -> bool:
"""Check if system is connected to the internet"""
try:
urllib.request.urlopen(host)
return True
except URLError:
return False

View file

@ -1,113 +0,0 @@
import os
import typing as t
from pathlib import Path
import colorama
import inquirer.shortcuts
from src.util.command import run_cmd, run_root_cmd
colorama.init(autoreset=True)
class InvalidPackage(Exception):
pass
class PackageAlreadyInstalled(Exception):
pass
def is_installed(pkg: str) -> bool:
"""Check if the package is already installed in the system"""
return run_cmd(f"pacman -Qi {pkg}", capture_out=True).returncode != 1
def pacman_install(package: str) -> None:
"""Install given `package`"""
run_root_cmd(f"pacman -S {package}")
def yay_install(package: str) -> None:
"""Install give package via `yay` (from AUR)"""
run_cmd(f"yay -S {package}")
def git_install(url: str) -> None:
"""Clone a git repository with given `url`"""
dir_name = Path(url.split("/")[-1].replace(".git", ""))
if dir_name.exists():
print(f"{colorama.Style.DIM}Git repository {dir_name} already exists")
ret_code = run_cmd(f"git clone {url}").returncode
if ret_code == 128:
print(f"{colorama.Fore.RED}Unable to install git repository {url}")
return
if not Path(dir_name, "PKGBUILD").exists:
print(f"{colorama.Fore.YELLOW}Git repository {dir_name} doesn't contain PKGBUILD, only downloaded.")
return
if inquirer.shortcuts.confirm("Do you wish to run makepkg on the downloaded git repository?"):
cwd = os.getcwd()
os.chdir(dir_name)
run_cmd("makepkg -si")
os.chdir(cwd)
run_cmd(f"rm -rf {dir_name}")
else:
os.makedirs("download")
run_cmd(f"mv {dir_name} download/")
print(f"{colorama.Style.DIM}Your git repository was cloned into `download/{dir_name}`")
class Package:
def __init__(self, name: str, aur: bool = False, git: bool = False):
self.name = name
self.aur = aur
self.git = git
if self.git:
self._resolve_git_package()
def _resolve_git_package(self) -> None:
"""Figure out `git_url` variable from `name`."""
if "/" not in self.name:
raise InvalidPackage("You need to specify both author and repository name for git packages (f.e. `ItsDrike/dotfiles`)")
if "http://" in self.name or "https://" in self.name:
self.git_url = self.name
else:
self.git_url = f"https://github.com/{self.name}"
def install(self) -> None:
if not self.git and is_installed(self.name):
raise PackageAlreadyInstalled(f"Package {self} is already installed")
if self.aur:
if not is_installed("yay"):
raise InvalidPackage(f"Package {self} can't be installed (missing `yay` - AUR installation software), alternatively, you can use git")
yay_install(self.name)
elif self.git:
git_install(self.git_url)
else:
pacman_install(self.name)
def __repr__(self) -> str:
if self.git:
if self.name == self.git_url:
return f"<Git package: {self.name}>"
return f"<Git package: {self.name} ({self.git_url})>"
elif self.aur:
return f"<Aur package: {self.name}>"
return f"<Package: {self.name}>"
@classmethod
def safe_load(cls, packages: t.List[str], aur: bool = False, git: bool = False) -> t.List["Package"]:
loaded_packages = []
for package in packages:
try:
loaded_packages.append(cls(package, aur=aur, git=git))
except InvalidPackage as e:
print(f"{colorama.Fore.RED}{str(e)}")
return loaded_packages

19
tox.ini
View file

@ -1,19 +0,0 @@
[flake8]
max_line_length=150
import-order-style=pycharm
application_import_names=src
exclude=
.venv/**,
.git/**
ignore=
# Ignore missing return type annotations for special methods
ANN204
# Ignore missing type annotations
ANN101 # Init
ANN102 # cls
ANN002, # *Args
ANN003, # **Kwargs
# Allow lambdas
E731
# Allow markdown inline HTML
MD033