diff --git a/.gitignore b/.gitignore index cab324d..52bb496 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,2 @@ -vars/all.yml \ No newline at end of file +vars/all.yml +.ssh diff --git a/README.md b/README.md index 5fb5f02..4f7191c 100644 --- a/README.md +++ b/README.md @@ -1 +1,23 @@ # archlinux-ansible + +## Usage + +Boot the live iso and set a root password, something simple is fine as it's +changed to key based auth anyway. Find the ip address (e.g. by `ip a`) and +add to `inventory/hosts.yml` under the `arch_live` group. + +Enter the `ansible` directory. Before running any playbook, generate a new SSH +key-pair: + +```bash +$ ssh-keygen -t ed25519 -f .ssh/id_ed25519 -N "" +``` + +Now run the `install` playbook: + +```bash +$ ansible-playbook install.yml -k +``` + +When the `install` playbook finishes, wait for the restart. Then find the new +ip address and put in the inventory file under the `arch` group diff --git a/ansible/.yamllint b/ansible/.yamllint new file mode 100644 index 0000000..15a72c1 --- /dev/null +++ b/ansible/.yamllint @@ -0,0 +1,7 @@ +--- +extends: default + +rules: + line-length: + max: 120 + level: warning diff --git a/ansible/ansible.cfg b/ansible/ansible.cfg new file mode 100644 index 0000000..2d04412 --- /dev/null +++ b/ansible/ansible.cfg @@ -0,0 +1,4 @@ +[defaults] +inventory = inventory +private_key_file = .ssh/id_ed25519 +library = library \ No newline at end of file diff --git a/ansible/configure.yml b/ansible/configure.yml new file mode 100644 index 0000000..ab21850 --- /dev/null +++ b/ansible/configure.yml @@ -0,0 +1,5 @@ +--- +- name: Configure system. + hosts: arch + + roles: diff --git a/ansible/install.yml b/ansible/install.yml new file mode 100644 index 0000000..e24ae4a --- /dev/null +++ b/ansible/install.yml @@ -0,0 +1,9 @@ +--- +- name: Install system. + hosts: arch_live + + roles: + - passwordless_connection + - prep + - disksetup + - configure diff --git a/ansible/inventory/hosts.yml b/ansible/inventory/hosts.yml new file mode 100644 index 0000000..966ef18 --- /dev/null +++ b/ansible/inventory/hosts.yml @@ -0,0 +1,10 @@ +--- +arch_live: + hosts: + 192.168.2.230: + ansible_user: root + +arch: + hosts: + 192.168.2.235: + ansible_user: rsrp diff --git a/ansible/library/modules/mkinitcpio/mkinitcpio.py b/ansible/library/modules/mkinitcpio/mkinitcpio.py new file mode 100644 index 0000000..be42719 --- /dev/null +++ b/ansible/library/modules/mkinitcpio/mkinitcpio.py @@ -0,0 +1,126 @@ +from ansible.module_utils.basic import AnsibleModule +import os +import re + + +def parse_mkinitcpio_line(type: str, line: str) -> list[str]: + regex = "^" + type + r"=\((.*)\)$" + result = re.search(regex, line) + if result is None: + return None + + return list(filter(lambda v: v != "", result.group(1).split(" "))) + + +def build_mkinitcpio_line(type: str, values: list[str]) -> str: + return type + "=(" + " ".join(values) + ")" + + +def update_mkinitcpio_line(type: str, desired_state: str, values: list[str], line) -> tuple[str, bool]: + current_values = parse_mkinitcpio_line(type, line) + changed = False + if current_values is not None: + if desired_state == "present": + for value in values: + if value not in current_values: + current_values.append(value) + changed = True + elif desired_state == "absent": + for value in values: + if value in current_values: + current_values.remove(value) + changed = True + else: + raise ValueError("Invalid state: %" % desired_state) + + return build_mkinitcpio_line(type, current_values), changed + else: + return None, False + + +def run_module(): + # define available arguments/parameters a user can pass to the module + module_args = dict( + state=dict(default='present', choices=['present', 'absent']), + binaries=dict(type='list'), + files=dict(type='list'), + hooks=dict(type='list'), + path=dict(type='str', default='/etc/mkinitcpio.conf') + ) + + # seed the result dict in the object + # we primarily care about changed and state + # changed is if this module effectively modified the target + # state will include any data that you want your module to pass back + # for consumption, for example, in a subsequent task + result = dict( + changed=False, + ) + + # the AnsibleModule object will be our abstraction working with Ansible + # this includes instantiation, a couple of common attr would be the + # args/params passed to the execution, as well as if the module + # supports check mode + module = AnsibleModule( + argument_spec=module_args, + supports_check_mode=True + ) + + # if the user is working with this module in only check mode we do not + # want to make any changes to the environment, just return the current + # state with no modifications + if module.check_mode: + module.exit_json(**result) + + path = module.params['path'] + if not os.path.isfile(path): + module.fail_json(msg="The path is invalid: %s does not exist" % path) + + state = module.params['state'] + binaries = module.params['binaries'] + files = module.params['files'] + hooks = module.params['hooks'] + + file = open(path, "r") + lines = file.readlines() + for index, line in enumerate(lines): + if binaries is not None: + updated_line, updated = update_mkinitcpio_line( + "BINARIES", state, binaries, line) + if updated: + result['changed'] = True + if updated_line is not None: + lines[index] = updated_line + + if binaries is not None: + updated_line, updated = update_mkinitcpio_line( + "FILES", state, files, line) + if updated: + result['changed'] = True + if updated_line is not None: + lines[index] = updated_line + + if binaries is not None: + updated_line, updated = update_mkinitcpio_line( + "HOOKS", state, hooks, line) + if updated: + result['changed'] = True + if updated_line is not None: + lines[index] = updated_line + + file = open(path, "w") + file.write("".join(lines)) + + # manipulate or modify the state as needed (this is going to be the + # part where your module will do what it needs to do) + # in the event of a successful module execution, you will want to + # simple AnsibleModule.exit_json(), passing the key/value results + module.exit_json(**result) + + +def main(): + run_module() + + +if __name__ == '__main__': + main() diff --git a/ansible/roles/base_packages/defaults/main.yml b/ansible/roles/base_packages/defaults/main.yml new file mode 100644 index 0000000..22f99d6 --- /dev/null +++ b/ansible/roles/base_packages/defaults/main.yml @@ -0,0 +1,13 @@ +--- +base_packages_list: + # Arch base packages + - base + - base-devel + # Linux kernel + - linux + - linux-firmware + # Additional packages that are needed for further ansible functionality + - sudo + - networkmanager + - openssh + - python diff --git a/ansible/roles/base_packages/tasks/main.yml b/ansible/roles/base_packages/tasks/main.yml new file mode 100644 index 0000000..9d89b68 --- /dev/null +++ b/ansible/roles/base_packages/tasks/main.yml @@ -0,0 +1,7 @@ +--- +- name: Pacstrap with base packages. + include_role: + name: pacstrap + vars: + packages: "{{ base_packages_list }}" + chroot: "{{ partitioning_root_mount_point }}" diff --git a/ansible/roles/configure/defaults/main.yml b/ansible/roles/configure/defaults/main.yml new file mode 100644 index 0000000..0132308 --- /dev/null +++ b/ansible/roles/configure/defaults/main.yml @@ -0,0 +1,2 @@ +--- +configure_root_password: password diff --git a/ansible/roles/configure/tasks/main.yml b/ansible/roles/configure/tasks/main.yml new file mode 100644 index 0000000..84bd5f7 --- /dev/null +++ b/ansible/roles/configure/tasks/main.yml @@ -0,0 +1,29 @@ +--- +- name: Enable services on installed system. + command: arch-chroot {{ partitioning_root_mount_point }} + systemctl enable {{ item }} + with_items: + - sshd + - NetworkManager + - fstrim.timer + changed_when: true + +- name: Make sure root's .ssh directory exists. + file: + state: directory + path: "{{ partitioning_root_mount_point }}/root/.ssh" + owner: root + group: root + mode: 0700 + +- name: Make sure temporary key is in root's authorized_keys + authorized_key: + state: present + user: root + path: "{{ partitioning_root_mount_point }}/root/.ssh/authorized_keys" + key: "{{ tmp_pub_key }}" + manage_dir: true + +- name: Update root password. + command: arch-chroot {{ partitioning_root_mount_point }} sh -c "echo root:{{ configure_root_password }} | chpasswd" + changed_when: true diff --git a/ansible/roles/disksetup/defaults/main.yml b/ansible/roles/disksetup/defaults/main.yml new file mode 100644 index 0000000..dfa8a8e --- /dev/null +++ b/ansible/roles/disksetup/defaults/main.yml @@ -0,0 +1,2 @@ +--- +disksetup_strategy: efi_gpt_luks_btrfs diff --git a/arch-install/roles/grub/files/grub b/ansible/roles/disksetup/efi_gpt_luks_btrfs/bootloader/files/grub similarity index 50% rename from arch-install/roles/grub/files/grub rename to ansible/roles/disksetup/efi_gpt_luks_btrfs/bootloader/files/grub index c7c5412..154e4ba 100644 --- a/arch-install/roles/grub/files/grub +++ b/ansible/roles/disksetup/efi_gpt_luks_btrfs/bootloader/files/grub @@ -1,14 +1,11 @@ -#GRUB_DEFAULT=saved GRUB_TIMEOUT=5 GRUB_DISTRIBUTOR="Arch" -GRUB_CMDLINE_LINUX_DEFAULT="cryptdevice=UUID={{ luks_partition_uuid }}:{{ luks_name }}" +GRUB_CMDLINE_LINUX_DEFAULT="cryptdevice=UUID={{ bootloader_priv_luks_device_node_uuid }}:{{ partitioning_priv_luks_name }}" GRUB_CMDLINE_LINUX="" GRUB_PRELOAD_MODULES="btrfs part_gpt" GRUB_ENABLE_CRYPTODISK=y -#GRUB_SAVEDEFAULT=true GRUB_TIMEOUT_STYLE=menu GRUB_TERMINAL_INPUT=console GRUB_GFXMODE=auto GRUB_GFXPAYLOAD_LINUX=keep -GRUB_DISABLE_RECOVERY=true -GRUB_THEME="/usr/share/grub/themes/Xenlism-Arch/theme.txt" +GRUB_DISABLE_RECOVERY=true \ No newline at end of file diff --git a/ansible/roles/disksetup/efi_gpt_luks_btrfs/bootloader/tasks/main.yml b/ansible/roles/disksetup/efi_gpt_luks_btrfs/bootloader/tasks/main.yml new file mode 100644 index 0000000..22e2c41 --- /dev/null +++ b/ansible/roles/disksetup/efi_gpt_luks_btrfs/bootloader/tasks/main.yml @@ -0,0 +1,34 @@ +--- +- name: Install required packages. + command: arch-chroot {{ partitioning_root_mount_point }} pacman -Sy grub efibootmgr os-prober --noconfirm + changed_when: true + +- name: Get luks device node uuid. + shell: | + set -e -o pipefail + blkid {{ partitioning_priv_luks_device_node }} -o value | head -1 + register: _device_node_uuid + changed_when: false + +- name: Assign device node id to variable. + set_fact: + bootloader_priv_luks_device_node_uuid: "{{ _device_node_uuid.stdout }}" + +- name: Copy grub default config. + template: + src: files/grub + dest: "{{ partitioning_root_mount_point }}/etc/default/grub" + owner: root + group: root + mode: 0644 + +- name: Install grub. + command: + cmd: arch-chroot {{ partitioning_root_mount_point }} grub-install --efi-directory=/boot/efi --bootloader-id=grub + creates: "{{ partitioning_root_mount_point }}/boot/efi/EFI/grub" + +- name: Install theme. + include_role: + name: grub-theme + vars: + chroot: "{{ partitioning_root_mount_point }}" diff --git a/ansible/roles/disksetup/efi_gpt_luks_btrfs/partitioning/defaults/main.yml b/ansible/roles/disksetup/efi_gpt_luks_btrfs/partitioning/defaults/main.yml new file mode 100644 index 0000000..1dfd7d3 --- /dev/null +++ b/ansible/roles/disksetup/efi_gpt_luks_btrfs/partitioning/defaults/main.yml @@ -0,0 +1,38 @@ +--- +##### Public variables used by the rest of the playbook ##### +partitioning_root_mount_point: "/mnt" + +##### Private variables used only by the partitioning roles ##### + +# Two partitions will be created on this device node +# * xxx1 will be used by /boot/efi +# * xxx2 will be a luks container, with btrfs inside +partitioning_priv_device_node: "/dev/sda" + +# The size of the ESP partition to be created +partitioning_priv_esp_size: "{{ 512 * 1024 * 1024 }}" + +# btrfs subvolumes are laid out in a flat fashion: +# +# toplevel (default subvolume, not mounted) +# +-- @ (to be mounted at /) +# +-- @home (to be mmounted at /home) +# +-- ... +# +partitioning_priv_btrfs_subvolumes: "{{ partitioning_priv_core_btrfs_subvolumes + partitioning_priv_extra_btrfs_subvolumes }}" + +# These subvolumes should always be present. DO NOT OVERRIDE. +partitioning_priv_core_btrfs_subvolumes: + - name: "@" + mountpoint: / + +# Other subvolumes can be added here, beginning with an @. +partitioning_priv_extra_btrfs_subvolumes: + - name: "@home" + mountpoint: /home + +# The mapper name of the luks container +partitioning_priv_luks_name: cryptoroot + +# The password used to encrypt the luks container +partitioning_priv_luks_password: password diff --git a/ansible/roles/disksetup/efi_gpt_luks_btrfs/partitioning/tasks/format-disk.yml b/ansible/roles/disksetup/efi_gpt_luks_btrfs/partitioning/tasks/format-disk.yml new file mode 100644 index 0000000..9895de7 --- /dev/null +++ b/ansible/roles/disksetup/efi_gpt_luks_btrfs/partitioning/tasks/format-disk.yml @@ -0,0 +1,33 @@ +--- +- name: Create EFI system partition + parted: + device: "{{ partitioning_priv_device_node }}" + state: present + label: gpt + number: 1 + name: ESP + part_start: "{{ 1024 * 1024 }}B" + part_end: "{{ partitioning_priv_esp_size | int + 1024 * 1024 - 1 }}B" + flags: + - esp + +- name: Create LUKS partition + parted: + device: "{{ partitioning_priv_device_node }}" + state: present + label: gpt + number: 2 + name: LUKS + part_start: "{{ partitioning_priv_esp_size | int + 1024 * 1024 }}B" + +- name: Enumerate created partitions. + shell: | + set -e -o pipefail + lsblk -n -o PATH {{ partitioning_priv_device_node | quote }} | tail -n +2 + register: _partitions + changed_when: false + +- name: Assign partitions to variables. + set_fact: + partitioning_priv_esp_device_node: "{{ _partitions.stdout_lines[0] }}" + partitioning_priv_luks_device_node: "{{ _partitions.stdout_lines[1] }}" diff --git a/ansible/roles/disksetup/efi_gpt_luks_btrfs/partitioning/tasks/format-parts.yml b/ansible/roles/disksetup/efi_gpt_luks_btrfs/partitioning/tasks/format-parts.yml new file mode 100644 index 0000000..00308c2 --- /dev/null +++ b/ansible/roles/disksetup/efi_gpt_luks_btrfs/partitioning/tasks/format-parts.yml @@ -0,0 +1,31 @@ +--- +- name: Format the boot partition with vfat. + filesystem: + device: "{{ partitioning_priv_esp_device_node }}" + state: present + type: vfat + +- name: Format the luks container with btrfs. + filesystem: + device: /dev/mapper/{{ partitioning_priv_luks_name }} + state: present + type: btrfs + +- name: Mount the default subvolume. + mount: + state: mounted + src: /dev/mapper/{{ partitioning_priv_luks_name }} + path: "{{ partitioning_root_mount_point }}" + fstype: btrfs + opts: defaults,noatime,compress=zstd + +- name: Create subvolumes. + command: + cmd: btrfs subvolume create {{ (partitioning_root_mount_point + "/" + item.name) | quote }} + creates: '{{ (partitioning_root_mount_point + "/" + item.name) | quote }}' + with_items: "{{ partitioning_priv_btrfs_subvolumes }}" + +- name: Unmount the default subvolume. + mount: + state: unmounted + path: "{{ partitioning_root_mount_point }}" diff --git a/ansible/roles/disksetup/efi_gpt_luks_btrfs/partitioning/tasks/luks.yml b/ansible/roles/disksetup/efi_gpt_luks_btrfs/partitioning/tasks/luks.yml new file mode 100644 index 0000000..65fdb37 --- /dev/null +++ b/ansible/roles/disksetup/efi_gpt_luks_btrfs/partitioning/tasks/luks.yml @@ -0,0 +1,10 @@ +--- +- name: Create luks container and open it. + luks_device: + device: "{{ partitioning_priv_luks_device_node }}" + state: opened + name: "{{ partitioning_priv_luks_name }}" + type: luks1 + cipher: aes-xts-plain64 + hash: sha256 + passphrase: "{{ partitioning_priv_luks_password }}" diff --git a/ansible/roles/disksetup/efi_gpt_luks_btrfs/partitioning/tasks/main.yml b/ansible/roles/disksetup/efi_gpt_luks_btrfs/partitioning/tasks/main.yml new file mode 100644 index 0000000..b91f53a --- /dev/null +++ b/ansible/roles/disksetup/efi_gpt_luks_btrfs/partitioning/tasks/main.yml @@ -0,0 +1,18 @@ +--- +- name: Fail if not using EFI. + fail: + msg: Must boot using EFI for this disksetup strategy. + when: not efi_mode + +- name: Make sure root mount point is unmounted. + command: umount -R {{ partitioning_root_mount_point }} + changed_when: true + register: result + failed_when: result.rc != 0 and "not mounted" not in result.stderr + +- include_tasks: "{{ item }}" + with_items: + - format-disk.yml + - luks.yml + - format-parts.yml + - mount.yml diff --git a/ansible/roles/disksetup/efi_gpt_luks_btrfs/partitioning/tasks/mount.yml b/ansible/roles/disksetup/efi_gpt_luks_btrfs/partitioning/tasks/mount.yml new file mode 100644 index 0000000..f13ea0b --- /dev/null +++ b/ansible/roles/disksetup/efi_gpt_luks_btrfs/partitioning/tasks/mount.yml @@ -0,0 +1,22 @@ +--- +- name: Mount btrfs subvolumes. + include_tasks: mount_btrfs-subvolume.yml + with_items: "{{ partitioning_priv_btrfs_subvolumes }}" + loop_control: + loop_var: subvolume + +- name: Make EFI mount point. + file: + path: "{{ partitioning_root_mount_point }}/boot/efi" + state: directory + recurse: true + owner: root + group: root + mode: 0700 + +- name: Mount EFI boot partition. + mount: + state: mounted + src: "{{ partitioning_priv_esp_device_node }}" + path: "{{ partitioning_root_mount_point }}/boot/efi" + fstype: vfat diff --git a/ansible/roles/disksetup/efi_gpt_luks_btrfs/partitioning/tasks/mount_btrfs-subvolume.yml b/ansible/roles/disksetup/efi_gpt_luks_btrfs/partitioning/tasks/mount_btrfs-subvolume.yml new file mode 100644 index 0000000..b167ef4 --- /dev/null +++ b/ansible/roles/disksetup/efi_gpt_luks_btrfs/partitioning/tasks/mount_btrfs-subvolume.yml @@ -0,0 +1,17 @@ +--- +- name: Make btrfs subvolume mount point. + file: + state: directory + path: "{{ (partitioning_root_mount_point + subvolume.mountpoint) | quote }}" + owner: root + group: root + mode: 0755 + +- name: Mount btrfs subvolume. + command: > + mount + -t btrfs + -o defaults,noatime,compress=zstd,subvol={{ subvolume.name }} + /dev/mapper/{{ partitioning_priv_luks_name }} + {{ (partitioning_root_mount_point + subvolume.mountpoint) | quote }} + changed_when: true diff --git a/ansible/roles/disksetup/efi_gpt_luks_btrfs/postpartitioning/tasks/main.yml b/ansible/roles/disksetup/efi_gpt_luks_btrfs/postpartitioning/tasks/main.yml new file mode 100644 index 0000000..15ed464 --- /dev/null +++ b/ansible/roles/disksetup/efi_gpt_luks_btrfs/postpartitioning/tasks/main.yml @@ -0,0 +1,47 @@ +--- +- name: Generate fstab. + include_role: + name: genfstab + vars: + chroot: "{{ partitioning_root_mount_point }}" + +- name: Check if btrfs-progs is installed. + command: arch-chroot {{ partitioning_root_mount_point }} + pacman -Qk btrfs-progs + register: _btrfs_progs_installed + failed_when: false + changed_when: false + +- name: Install btrfs-progs. + command: arch-chroot {{ partitioning_root_mount_point }} + pacman -Sy btrfs-progs --noconfirm + when: _btrfs_progs_installed.rc != 0 + +- name: Create crypto keyfile. + shell: + cmd: | + set -e -o pipefail + dd bs=512 count=8 if=/dev/urandom of={{ partitioning_root_mount_point }}/crypto_keyfile.bin + echo {{ partitioning_priv_luks_password }} \ + | cryptsetup luksAddKey {{ partitioning_priv_luks_device_node }} \ + {{ partitioning_root_mount_point }}/crypto_keyfile.bin + creates: "{{ partitioning_root_mount_point }}/crypto_keyfile.bin" + +- name: Set proper permissions on crypto keyfile. + file: + path: "{{ partitioning_root_mount_point }}/crypto_keyfile.bin" + mode: 0000 + +- name: Configure mkinitcpio. + mkinitcpio: + state: present + path: "{{ partitioning_root_mount_point }}/etc/mkinitcpio.conf" + binaries: /usr/bin/btrfs + files: /crypto_keyfile.bin + hooks: + - encrypt + - btrfs + +- name: Run mkinitcpio. + command: arch-chroot {{ partitioning_root_mount_point }} mkinitcpio -P + changed_when: true diff --git a/ansible/roles/disksetup/tasks/main.yml b/ansible/roles/disksetup/tasks/main.yml new file mode 100644 index 0000000..34016b6 --- /dev/null +++ b/ansible/roles/disksetup/tasks/main.yml @@ -0,0 +1,16 @@ +--- +- name: Include partitioning role for selected partitioning strategy. + include_role: + name: "disksetup/{{ disksetup_strategy }}/partitioning" + public: true +- name: Bootstrap system with base packages. + import_role: + name: base_packages +- name: Include postpartitioning role for selected partitioning strategy. + include_role: + name: "disksetup/{{ disksetup_strategy }}/postpartitioning" + public: true +- name: Include bootloader role for selected partitioning strategy. + include_role: + name: "disksetup/{{ disksetup_strategy }}/bootloader" + public: true diff --git a/ansible/roles/genfstab/tasks/main.yml b/ansible/roles/genfstab/tasks/main.yml new file mode 100644 index 0000000..7524c77 --- /dev/null +++ b/ansible/roles/genfstab/tasks/main.yml @@ -0,0 +1,13 @@ +--- +- name: Generate fstab. + command: genfstab -U {{ chroot | quote }} + register: _fstab + changed_when: false + +- name: Save fstab. + copy: + dest: "{{ chroot | quote }}/etc/fstab" + content: "{{ _fstab.stdout }}" + owner: root + group: root + mode: 0644 diff --git a/ansible/roles/grub-mkconfig/tasks/main.yml b/ansible/roles/grub-mkconfig/tasks/main.yml new file mode 100644 index 0000000..b98c763 --- /dev/null +++ b/ansible/roles/grub-mkconfig/tasks/main.yml @@ -0,0 +1,4 @@ +--- +- name: Create grub configuration. + command: arch-chroot {{ chroot }} grub-mkconfig -o /boot/grub/grub.cfg + changed_when: true diff --git a/ansible/roles/grub-theme/defaults/main.yml b/ansible/roles/grub-theme/defaults/main.yml new file mode 100644 index 0000000..effa9e6 --- /dev/null +++ b/ansible/roles/grub-theme/defaults/main.yml @@ -0,0 +1,2 @@ +--- +grub_theme_name: xenlism diff --git a/ansible/roles/grub-theme/tasks/main.yml b/ansible/roles/grub-theme/tasks/main.yml new file mode 100644 index 0000000..d3a3d88 --- /dev/null +++ b/ansible/roles/grub-theme/tasks/main.yml @@ -0,0 +1,9 @@ +--- +- name: Add xenlism theme. + include_role: + name: grub-theme/xenlism + when: grub_theme_name == "xenlism" + +- name: Update grub config. + include_role: + name: grub-mkconfig diff --git a/ansible/roles/grub-theme/xenlism/tasks/main.yml b/ansible/roles/grub-theme/xenlism/tasks/main.yml new file mode 100644 index 0000000..cc8e320 --- /dev/null +++ b/ansible/roles/grub-theme/xenlism/tasks/main.yml @@ -0,0 +1,29 @@ +--- +- name: Make sure git is installed + pacman: + name: git + state: present + update_cache: true + +- name: Clone theme repository. + git: + repo: https://github.com/xenlism/Grub-themes + dest: /tmp/Grub-themes + clone: true + version: main + +- name: Copy theme to grub. + copy: + src: "/tmp/Grub-themes/xenlism-grub-arch-1080p/Xenlism-Arch" + remote_src: true + dest: "{{ chroot }}/usr/share/grub/themes" + owner: root + group: root + mode: 0755 + +- name: Enable theme. + lineinfile: + path: "{{ chroot }}/etc/default/grub" + state: present + regexp: ^GRUB_THEME= + line: GRUB_THEME="/usr/share/grub/themes/Xenlism-Arch/theme.txt" diff --git a/ansible/roles/pacstrap/tasks/main.yml b/ansible/roles/pacstrap/tasks/main.yml new file mode 100644 index 0000000..9cb8331 --- /dev/null +++ b/ansible/roles/pacstrap/tasks/main.yml @@ -0,0 +1,8 @@ +--- +- name: Run pacstrap. + command: > + pacstrap {{ chroot | quote }} --needed + {% for pkg in packages %} + {{ pkg }} + {% endfor %} + changed_when: true diff --git a/ansible/roles/passwordless_connection/tasks/main.yml b/ansible/roles/passwordless_connection/tasks/main.yml new file mode 100644 index 0000000..4948b4a --- /dev/null +++ b/ansible/roles/passwordless_connection/tasks/main.yml @@ -0,0 +1,18 @@ +--- +- name: Read temporary public key. + set_fact: + tmp_pub_key: "{{ lookup('file', '.ssh/id_ed25519.pub') }}" + +- name: Make sure tmp key is in authorized_keys. + authorized_key: + state: present + user: root + key: "{{ tmp_pub_key }}" + manage_dir: true + +- name: Disable password access. + shell: | + set -e + passwd -d root + passwd -l root + changed_when: true diff --git a/ansible/roles/prep/tasks/main.yml b/ansible/roles/prep/tasks/main.yml new file mode 100644 index 0000000..78125b8 --- /dev/null +++ b/ansible/roles/prep/tasks/main.yml @@ -0,0 +1,19 @@ +--- +- name: Check if EFI directory exists. + stat: + path: /sys/firmware/efi + register: private_efi_directory_exists + +- name: Set efi_mode fact. + set_fact: + efi_mode: "{{ private_efi_directory_exists.stat.exists }}" + +- name: Check internet connectivity. + uri: + url: https://archlinux.org + status_code: "200" + timeout: 30 + +- name: Sync time. + command: timedatectl set-ntp true + changed_when: true diff --git a/arch-install/ansible.cfg b/arch-install/ansible.cfg deleted file mode 100644 index 4ece02d..0000000 --- a/arch-install/ansible.cfg +++ /dev/null @@ -1,2 +0,0 @@ -[defaults] -roles_path = ./roles \ No newline at end of file diff --git a/arch-install/inventory/hosts.yml b/arch-install/inventory/hosts.yml deleted file mode 100644 index e012c74..0000000 --- a/arch-install/inventory/hosts.yml +++ /dev/null @@ -1,4 +0,0 @@ -all: - hosts: - 192.168.2.232: - ansible_user: root diff --git a/arch-install/main.yml b/arch-install/main.yml deleted file mode 100644 index 7d740df..0000000 --- a/arch-install/main.yml +++ /dev/null @@ -1,14 +0,0 @@ ---- -- name: Install Arch linux. - hosts: all - vars_files: - - vars/all.yml - - roles: - - prep - - disk - - base-system - - users - - crypto-keyfile - - grub - - initcpio diff --git a/arch-install/roles/base-system/tasks/main.yml b/arch-install/roles/base-system/tasks/main.yml deleted file mode 100644 index 9b776a6..0000000 --- a/arch-install/roles/base-system/tasks/main.yml +++ /dev/null @@ -1,54 +0,0 @@ -- name: Run pacstrap. - command: > - pacstrap /mnt - base base-devel linux linux-firmware - efibootmgr grub openssh networkmanager btrfs-progs python - vim git zsh - -- name: Generate fstab. - shell: genfstab -U /mnt >> /mnt/etc/fstab - -- name: Set localtime. - command: arch-chroot /mnt ln -sf /usr/share/zoneinfo/{{ timezone }} /etc/localtime - -- name: Sync time to hardware. - command: arch-chroot /mnt hwclock --systohc - -- name: Select locales. - lineinfile: - path: /mnt/etc/locale.gen - regexp: '^#en_US\.UTF-8 UTF-8' - line: en_US.UTF-8 UTF-8 - -- name: Generate locales. - command: arch-chroot /mnt locale-gen - -- name: Save locale to /etc/locale.conf. - copy: - dest: /mnt/etc/locale.conf - content: "LANG=en_US.UTF-8" - -- name: Save keyboard layout to /etc/vconsole.conf. - copy: - dest: /mnt/etc/vconsole.conf - content: "KEYMAP=us" - -- name: Set hostname. - copy: - dest: /mnt/etc/hostname - content: "{{ hostname }}" - -- name: Configure /etc/hosts. - copy: - dest: /mnt/etc/hosts - content: | - 127.0.0.1 localhost - ::1 localhost - 127.0.0.1 {{ hostname }}.localdomain {{ hostname }} - -- name: Enable important services. - command: "arch-chroot /mnt systemctl enable {{ item }}" - with_items: - - sshd.service - - NetworkManager.service - - fstrim.timer diff --git a/arch-install/roles/crypto-keyfile/tasks/main.yml b/arch-install/roles/crypto-keyfile/tasks/main.yml deleted file mode 100644 index d997b65..0000000 --- a/arch-install/roles/crypto-keyfile/tasks/main.yml +++ /dev/null @@ -1,17 +0,0 @@ ---- -- name: Create crypto keyfile. - shell: - cmd: | - dd bs=512 count=8 if=/dev/urandom of=/mnt/crypto_keyfile.bin - echo {{ luks_password }} | cryptsetup luksAddKey /dev/{{ disk }}2 /mnt/crypto_keyfile.bin - creates: /mnt/crypto_keyfile.bin - -- name: Set proper permission on crypto keyfile. - file: - path: /mnt/crypto_keyfile.bin - mode: 0000 - -- name: Set proper permissions on boot folder. - file: - path: /mnt/boot - mode: g-rwx,o-rwx diff --git a/arch-install/roles/disk/tasks/create-boot-fs.yml b/arch-install/roles/disk/tasks/create-boot-fs.yml deleted file mode 100644 index b9753f7..0000000 --- a/arch-install/roles/disk/tasks/create-boot-fs.yml +++ /dev/null @@ -1,6 +0,0 @@ -- name: Create ESP filesystem. - filesystem: - device: /dev/{{ disk }}1 - state: present - type: vfat - opts: -F32 diff --git a/arch-install/roles/disk/tasks/create-btrfs.yml b/arch-install/roles/disk/tasks/create-btrfs.yml deleted file mode 100644 index 1d1c776..0000000 --- a/arch-install/roles/disk/tasks/create-btrfs.yml +++ /dev/null @@ -1,28 +0,0 @@ -- name: Create btrfs in LUKS container. - filesystem: - device: /dev/mapper/cryptroot - state: present - type: btrfs - -- name: Mount new filesystem to /mnt. - mount: - state: mounted - src: /dev/mapper/cryptroot - path: /mnt - fstype: btrfs - opts: defaults,noatime,compress=zstd - -- name: Create Btrfs @ subvolume. - command: - cmd: btrfs subvolume create /mnt/@ - creates: /mnt/@ - -- name: Create Btrfs @/root subvolume. - command: - cmd: btrfs subvolume create /mnt/@/root - creates: /mnt/@/root - -- name: Create Btrfs @/home subvolume. - command: - cmd: btrfs subvolume create /mnt/@/home - creates: /mnt/@/home diff --git a/arch-install/roles/disk/tasks/create-luks-container.yml b/arch-install/roles/disk/tasks/create-luks-container.yml deleted file mode 100644 index a3ec1cb..0000000 --- a/arch-install/roles/disk/tasks/create-luks-container.yml +++ /dev/null @@ -1,14 +0,0 @@ -- name: Make sure LUKS container is closed. - luks_device: - device: /dev/{{ disk }}2 - state: closed - -- name: Make sure LUKS container exists and is open. - luks_device: - device: /dev/{{ disk }}2 - state: opened - name: "{{ luks_name }}" - type: luks1 - cipher: aes-xts-plain64 - hash: sha256 - passphrase: "{{ luks_password }}" diff --git a/arch-install/roles/disk/tasks/format-disk.yml b/arch-install/roles/disk/tasks/format-disk.yml deleted file mode 100644 index 0eb7f53..0000000 --- a/arch-install/roles/disk/tasks/format-disk.yml +++ /dev/null @@ -1,22 +0,0 @@ -- name: Create EFI system partition - parted: - device: /dev/{{ disk }} - state: present - label: gpt - name: ESP - number: 1 - part_start: 1MiB - part_end: 512MiB - flags: [esp] - fs_type: fat32 - -- name: Create LUKS partition - parted: - device: /dev/{{ disk }} - state: present - label: gpt - name: LUKS - number: 2 - part_start: 512MiB - part_end: 100% - fs_type: ext4 diff --git a/arch-install/roles/disk/tasks/main.yml b/arch-install/roles/disk/tasks/main.yml deleted file mode 100644 index 1fcc6e5..0000000 --- a/arch-install/roles/disk/tasks/main.yml +++ /dev/null @@ -1,8 +0,0 @@ ---- -- include_tasks: format-disk.yml -- include_tasks: unmount.yml -- include_tasks: create-luks-container.yml -- include_tasks: create-boot-fs.yml -- include_tasks: create-btrfs.yml -- include_tasks: unmount.yml -- include_tasks: mount.yml diff --git a/arch-install/roles/disk/tasks/mount.yml b/arch-install/roles/disk/tasks/mount.yml deleted file mode 100644 index cb32222..0000000 --- a/arch-install/roles/disk/tasks/mount.yml +++ /dev/null @@ -1,27 +0,0 @@ -- name: Mount @/root to /mnt. - mount: - state: mounted - src: /dev/mapper/{{ luks_name }} - path: /mnt - fstype: btrfs - opts: defaults,noatime,compress=zstd,subvol=@/root - -- name: Mount @/home to /mnt/home. - mount: - state: mounted - src: /dev/mapper/{{ luks_name }} - path: /mnt/home - fstype: btrfs - opts: defaults,noatime,compress=zstd,subvol=@/home - -- name: Make sure /mnt/boot/efi exists. - file: - path: /mnt/boot/efi - state: directory - -- name: Mount boot partition to /mnt/boot/efi. - mount: - state: mounted - src: /dev/{{ disk }}1 - path: /mnt/boot/efi - fstype: vfat diff --git a/arch-install/roles/disk/tasks/unmount.yml b/arch-install/roles/disk/tasks/unmount.yml deleted file mode 100644 index 148f0a2..0000000 --- a/arch-install/roles/disk/tasks/unmount.yml +++ /dev/null @@ -1,8 +0,0 @@ -- name: Make sure everything is unmounted. - mount: - state: unmounted - path: "{{ item }}" - with_items: - - /mnt/boot/efi - - /mnt/home - - /mnt diff --git a/arch-install/roles/grub/handlers/main.yml b/arch-install/roles/grub/handlers/main.yml deleted file mode 100644 index c6691a8..0000000 --- a/arch-install/roles/grub/handlers/main.yml +++ /dev/null @@ -1,3 +0,0 @@ ---- -- name: grub mkconfig - command: arch-chroot /mnt grub-mkconfig -o /boot/grub/grub.cfg diff --git a/arch-install/roles/grub/tasks/grub-theme.yml b/arch-install/roles/grub/tasks/grub-theme.yml deleted file mode 100644 index f373af0..0000000 --- a/arch-install/roles/grub/tasks/grub-theme.yml +++ /dev/null @@ -1,16 +0,0 @@ ---- -- name: Clone theme repository. - git: - repo: https://github.com/xenlism/Grub-themes - dest: /tmp/Grub-themes - clone: true - version: main - -- name: Copy theme to grub. - copy: - src: /tmp/Grub-themes/xenlism-grub-arch-1080p/Xenlism-Arch - remote_src: true - dest: /mnt/usr/share/grub/themes - owner: root - group: root - mode: 0755 diff --git a/arch-install/roles/grub/tasks/main.yml b/arch-install/roles/grub/tasks/main.yml deleted file mode 100644 index 0e211b6..0000000 --- a/arch-install/roles/grub/tasks/main.yml +++ /dev/null @@ -1,26 +0,0 @@ -- name: Install packages. - command: arch-chroot /mnt pacman -Sy grub efibootmgr os-prober --noconfirm - -- include_tasks: grub-theme.yml - -- name: Get luks partition id. - shell: blkid /dev/{{ disk }}2 -o value | head -1 - register: luks_partition_uuid - -- name: Get nested value. - set_fact: - luks_partition_uuid: "{{ luks_partition_uuid.stdout }}" - -- name: Copy grub default config. - template: - src: files/grub - dest: /mnt/etc/default/grub - owner: root - group: root - mode: 0644 - notify: grub mkconfig - -- name: Install grub. - command: - cmd: arch-chroot /mnt grub-install --efi-directory=/boot/efi --bootloader-id=grub - creates: /mnt/boot/efi/EFI/grub diff --git a/arch-install/roles/initcpio/files/mkinitcpio.conf b/arch-install/roles/initcpio/files/mkinitcpio.conf deleted file mode 100644 index fe88467..0000000 --- a/arch-install/roles/initcpio/files/mkinitcpio.conf +++ /dev/null @@ -1,4 +0,0 @@ -MODULES=() -BINARIES=(/usr/bin/btrfs) -FILES=(/crypto_keyfile.bin) -HOOKS=(base udev autodetect modconf block filesystems keyboard fsck encrypt btrfs) diff --git a/arch-install/roles/initcpio/handlers/main.yml b/arch-install/roles/initcpio/handlers/main.yml deleted file mode 100644 index ccfcb3b..0000000 --- a/arch-install/roles/initcpio/handlers/main.yml +++ /dev/null @@ -1,3 +0,0 @@ ---- -- name: run mkinitcpio - command: arch-chroot /mnt mkinitcpio -P diff --git a/arch-install/roles/initcpio/tasks/main.yml b/arch-install/roles/initcpio/tasks/main.yml deleted file mode 100644 index 21d39e5..0000000 --- a/arch-install/roles/initcpio/tasks/main.yml +++ /dev/null @@ -1,8 +0,0 @@ -- name: Copy mkinitcpi config. - copy: - src: files/mkinitcpio.conf - dest: /mnt/etc/mkinitcpio.conf - owner: root - group: root - mode: 0644 - notify: run mkinitcpio diff --git a/arch-install/roles/prep/tasks/main.yml b/arch-install/roles/prep/tasks/main.yml deleted file mode 100644 index 999c46d..0000000 --- a/arch-install/roles/prep/tasks/main.yml +++ /dev/null @@ -1,25 +0,0 @@ ---- -- name: Check if EFI directory exists. - stat: - path: /sys/firmware/efi - register: efi_directory_exists - -- name: Fail if not in EFI or UEFI. - fail: - msg: This playbook only support EFI/UEFI! - when: not efi_directory_exists.stat.exists - -- name: Check internet connectivity. - uri: - url: https://archlinux.org - status_code: "200" - timeout: 30 - -- name: Sync time. - command: timedatectl set-ntp true - -- name: Install packages. - pacman: - name: git - update_cache: true - state: present diff --git a/arch-install/roles/users/tasks/main.yml b/arch-install/roles/users/tasks/main.yml deleted file mode 100644 index 7092784..0000000 --- a/arch-install/roles/users/tasks/main.yml +++ /dev/null @@ -1,2 +0,0 @@ -- name: Set root password. - shell: arch-chroot /mnt sh -c "echo root:{{ root_password }} | chpasswd" diff --git a/arch-install/vars/all.example.yml b/arch-install/vars/all.example.yml deleted file mode 100644 index 99b947c..0000000 --- a/arch-install/vars/all.example.yml +++ /dev/null @@ -1,6 +0,0 @@ -disk: sda -luks_name: cryptroot -luks_password: password123 -timezone: Europe/Stockholm -hostname: arch123 -root_password: password123 diff --git a/arch-install/vars/all.yml b/arch-install/vars/all.yml deleted file mode 100644 index 99b947c..0000000 --- a/arch-install/vars/all.yml +++ /dev/null @@ -1,6 +0,0 @@ -disk: sda -luks_name: cryptroot -luks_password: password123 -timezone: Europe/Stockholm -hostname: arch123 -root_password: password123