From ea93524e433b6acea920f11a96a99ea857deb0ae Mon Sep 17 00:00:00 2001 From: Greg Hellings Date: Sun, 13 Aug 2023 23:58:13 -0500 Subject: [PATCH] Add NixOS --- ansible/playbook.yml | 43 ++++++- ansible/roles/qemu/handlers/main.yml | 3 + ansible/roles/qemu/tasks/main.yml | 37 ++++++ ansible/roles/vagrant/tasks/main.yml | 9 -- ansible/roles/virtualbox/tasks/main.yml | 126 +++++++++++++-------- distros/nixos/23.05/http/configuration.nix | 55 +++++++++ distros/nixos/23.05/http/in-chroot.sh | 15 +++ distros/nixos/23.05/http/install.sh | 47 ++++++++ distros/nixos/23.05/x86_64.pkrvars.hcl | 15 +++ distros/nixos/supports.yml | 5 + 10 files changed, 296 insertions(+), 59 deletions(-) create mode 100644 ansible/roles/qemu/handlers/main.yml create mode 100644 distros/nixos/23.05/http/configuration.nix create mode 100644 distros/nixos/23.05/http/in-chroot.sh create mode 100644 distros/nixos/23.05/http/install.sh create mode 100644 distros/nixos/23.05/x86_64.pkrvars.hcl create mode 100644 distros/nixos/supports.yml diff --git a/ansible/playbook.yml b/ansible/playbook.yml index dfa86eb..f8509fb 100644 --- a/ansible/playbook.yml +++ b/ansible/playbook.yml @@ -2,20 +2,57 @@ hosts: default vars: ansible_remote_tmp: /tmp + no_touchy: + - NixOS pre_tasks: - name: Pause for a moment in case we need cloud-init to finish ansible.builtin.pause: seconds: 20 + + - name: Help with debugging + ansible.builtin.debug: + msg: "Detected distro: {{ ansible_facts['distribution'] }}" + + - name: get build time + become: true + ansible.builtin.copy: + content: "{{ ansible_facts.date_time.date }} {{ ansible_facts.date_time.hour }}:{{ ansible_facts.date_time.minute }}" + dest: /etc/vagrant_box_build_time + owner: root + group: root + mode: 0644 roles: - role: latest + when: + - ansible_facts.distribution not in no_touchy + - role: devroles.system.epel + - role: virtualbox - when: packer_builder_type == 'virtualbox-iso' + when: + - packer_builder_type == 'virtualbox-iso' + - role: vmware - when: packer_builder_type == 'vmware-iso' + when: + - packer_builder_type == 'vmware-iso' + - ansible_facts.distribution not in no_touchy + - role: qemu - when: packer_builder_type == 'qemu' + when: + - packer_builder_type == 'qemu' + - role: init + when: + - ansible_facts.distribution not in no_touchy + - role: locale + when: + - ansible_facts.distribution not in no_touchy + - role: vagrant + when: + - ansible_facts.distribution not in no_touchy + - role: cleanup + when: + - ansible_facts.distribution not in no_touchy diff --git a/ansible/roles/qemu/handlers/main.yml b/ansible/roles/qemu/handlers/main.yml new file mode 100644 index 0000000..2b2814b --- /dev/null +++ b/ansible/roles/qemu/handlers/main.yml @@ -0,0 +1,3 @@ +- name: Rebuild nixos + become: true + ansible.builtin.command: nixos-rebuild switch diff --git a/ansible/roles/qemu/tasks/main.yml b/ansible/roles/qemu/tasks/main.yml index b453398..20eda97 100644 --- a/ansible/roles/qemu/tasks/main.yml +++ b/ansible/roles/qemu/tasks/main.yml @@ -1,6 +1,43 @@ +- name: Load version information + ansible.builtin.include_vars: "{{ item }}" + loop: + - "{{ role_path }}/vars/{{ ansible_facts['os_family'] }}.yml" + - "{{ role_path }}/vars/{{ ansible_facts['distribution'] }}.yml" + - "{{ role_path }}/vars/{{ ansible_facts['distribution'] }}_{{ ansible_facts['distribution_major_version'] }}.yml" + - "{{ role_path }}/vars/{{ ansible_facts['distribution'] }}_{{ ansible_facts['distribution_version'] }}.yml" + when: item is file + - name: Install qemu-guest-agent become: true ansible.builtin.package: name: - qemu-guest-agent state: present + when: ansible_facts.distribution != 'NixOS' + +############################################################################### +############################################################################### +############################################################################### +############################################################################### +############################################################################### + +- when: ansible_facts.distribution == 'NixOS' + block: + - name: Tell the configuration to pick up guest agent + ansible.builtin.replace: + path: /etc/nixos/configuration.nix + regexp: "\\./hardware-configuration\\.nix" + replace: | + ./hardware-configuration.nix + ./guest-agent.nix + + - name: Create guest additions configuration + ansible.builtin.copy: + dest: /etc/nixos/guest-agent.nix + owner: vagrant + content: | + {...}: + { + services.qemuGuest.enable = true; + } + notify: Rebuild nixos diff --git a/ansible/roles/vagrant/tasks/main.yml b/ansible/roles/vagrant/tasks/main.yml index c524140..a7e4539 100644 --- a/ansible/roles/vagrant/tasks/main.yml +++ b/ansible/roles/vagrant/tasks/main.yml @@ -13,15 +13,6 @@ state: absent when: ansible_facts.pkg_mgr not in ['atomic_container'] -- name: get build time - become: true - ansible.builtin.copy: - content: "{{ ansible_facts.date_time.date }} {{ ansible_facts.date_time.hour }}:{{ ansible_facts.date_time.minute }}" - dest: /etc/vagrant_box_build_time - owner: root - group: root - mode: 0644 - - name: create .ssh directory ansible.builtin.file: path: "{{ ansible_user_dir }}/.ssh" diff --git a/ansible/roles/virtualbox/tasks/main.yml b/ansible/roles/virtualbox/tasks/main.yml index 5fd8be5..cc91bf0 100644 --- a/ansible/roles/virtualbox/tasks/main.yml +++ b/ansible/roles/virtualbox/tasks/main.yml @@ -7,56 +7,88 @@ - "{{ role_path }}/vars/{{ ansible_facts['distribution'] }}_{{ ansible_facts['distribution_version'] }}.yml" when: item is file -- name: Install build deps for virtualbox addons - become: true - ansible.builtin.package: - name: "{{ virtualbox_packages }}" - state: present - update_cache: true - register: _pkg_install - retries: 3 - until: _pkg_install is success - -- name: Start services - become: true - ansible.builtin.service: - name: "{{ item }}" - state: started - enabled: true - loop: "{{ virtualbox_services }}" - -- name: Run commands to install from ISO - when: virtualbox_from_iso - become: true +- when: ansible_facts.distribution != 'NixOS' block: - - name: Mount ISO file - ansible.posix.mount: - fstype: auto - path: /mnt - src: "{{ virtualbox_iso_location }}" - state: mounted - boot: false - opts: loop + - name: Install build deps for virtualbox addons + become: true + ansible.builtin.package: + name: "{{ virtualbox_packages }}" + state: present + update_cache: true + register: _pkg_install + retries: 3 + until: _pkg_install is success - - name: Install additions - ansible.builtin.shell: /mnt/VBoxLinuxAdditions.run install 2>&1 > /root/vbox_addon_install.log - changed_when: false - failed_when: _cmd.rc not in [0, 2] - register: _cmd + - name: Start services + become: true + ansible.builtin.service: + name: "{{ item }}" + state: started + enabled: true + loop: "{{ virtualbox_services }}" - - name: Unmount ISO file - ansible.posix.mount: - path: /mnt + - name: Run commands to install from ISO + when: virtualbox_from_iso + become: true + block: + - name: Mount ISO file + ansible.posix.mount: + fstype: auto + path: /mnt + src: "{{ virtualbox_iso_location }}" + state: mounted + boot: false + opts: loop + + - name: Install additions + ansible.builtin.shell: /mnt/VBoxLinuxAdditions.run install 2>&1 > /root/vbox_addon_install.log + changed_when: false + failed_when: _cmd.rc not in [0, 2] + register: _cmd + + - name: Unmount ISO file + ansible.posix.mount: + path: /mnt + state: absent + + - name: Remove packages + become: true + ansible.builtin.package: + name: "{{ virtualbox_remove_packages | default([]) }}" + state: absent + when: virtualbox_remove_packages + + - name: Remove file + ansible.builtin.file: + path: "{{ virtualbox_iso_location }}" state: absent -- name: Remove packages - become: true - ansible.builtin.package: - name: "{{ virtualbox_remove_packages | default([]) }}" - state: absent - when: virtualbox_remove_packages +############################################################################### +############################################################################### +############################################################################### +############################################################################### +############################################################################### -- name: Remove file - ansible.builtin.file: - path: "{{ virtualbox_iso_location }}" - state: absent +- when: ansible_facts.distribution == 'NixOS' + block: + - name: Tell the configuration to pick up guest agent + ansible.builtin.replace: + path: /etc/nixos/configuration.nix + regexp: "\\./hardware-configuration\\.nix" + replace: | + ./hardware-configuration.nix + ./guest-agent.nix + + - name: Create guest additions configuration + ansible.builtin.copy: + dest: /etc/nixos/guest-agent.nix + owner: vagrant + content: | + {...}: + { + virtualisation.virtualbox.guest = { + enable = true; + x11 = false; + }; + } + notify: Rebuild nixos diff --git a/distros/nixos/23.05/http/configuration.nix b/distros/nixos/23.05/http/configuration.nix new file mode 100644 index 0000000..4de06e9 --- /dev/null +++ b/distros/nixos/23.05/http/configuration.nix @@ -0,0 +1,55 @@ +{config, pkgs, lib, ...}: + +{ + imports = [ + ./hardware-configuration.nix + ]; + + # Packages installed on the whole system + environment.systemPackages = with pkgs; [ + curl + nano + python3 + ]; + # Services that are running + services = { + openssh.enable = true; + #xserver.enable = true; + }; + # User setup + users.users.vagrant = { + isNormalUser = true; + extraGroups = [ "wheel" ]; + password = "vagrant"; + }; + security.sudo.extraRules = [ + { + users = [ "vagrant" ]; + groups = [ "vagrant" ]; + commands = [ + { command = "ALL"; options = [ "NOPASSWD" ]; } + ]; + } + ]; + + boot.loader.grub = { + enable = true; + devices = [ "@BOOT_DEVICE@" ]; + }; + networking = { + hostName = "vagrant"; + networkmanager.enable = true; + #proxy.default = "http://user:password@proxy:port/"; + #proxy.noProxy = "127.0.0.1,localhost,internal.domain"; + }; + time.timeZone = "UTC"; + + i18n.defaultLocale = "en_US.UTF-8"; + console = { + font = "Lat2-Terminux16"; + keyMap = lib.mkForce "us"; + useXkbConfig = true; + }; + + system.stateVersion = "23.05"; +} diff --git a/distros/nixos/23.05/http/in-chroot.sh b/distros/nixos/23.05/http/in-chroot.sh new file mode 100644 index 0000000..15ab2b9 --- /dev/null +++ b/distros/nixos/23.05/http/in-chroot.sh @@ -0,0 +1,15 @@ +#!/usr/bin/env bash +set -ex + +# Set passwords +echo "vagrant:vagrant" | chpasswd +echo "root:vagrant" | chpasswd + +# Configure vagrant user's SSH key +mkdir -m 0700 -p ~vagrant/.ssh +curl -o /home/vagrant/.ssh/authorized_keys https://raw.githubusercontent.com/hashicorp/vagrant/master/keys/vagrant.pub +chmod 600 ~vagrant/.ssh/authorized_keys + +# Set ownership of things vagrant should own +chown -R vagrant:wheel ~vagrant/ +chown -R vagrant:wheel /etc/nixos diff --git a/distros/nixos/23.05/http/install.sh b/distros/nixos/23.05/http/install.sh new file mode 100644 index 0000000..daabde9 --- /dev/null +++ b/distros/nixos/23.05/http/install.sh @@ -0,0 +1,47 @@ +#!/usr/bin/env bash +#vim: set ft=bash: +set -ex + +port="${1}" # HTTP port that packer is running on + +if [ -e /dev/vda ]; then + disk="/dev/vda" +elif [ -e /dev/sda ]; then + disk="/dev/sda" +else + exit 1 # Need to teach the script which device to use in this case +fi + +# The sed bit is just to strip out the extra fluff, like comments +sed -e 's/\s*\([\+0-9a-zA-Z]*\).*/\1/' << EOF | fdisk ${disk} + o # create new DOS partition table + n # new + p # primary partition + 1 # part number + # default start + # default to full disk + p # print, for debugging + w # write the partition table and exit +EOF + #t # set partition type + #1 # on partition 1 + #4 # BIOS boot + +# Format and mount partitions +mkfs.ext4 -L root "${disk}1" + +mount "${disk}1" /mnt + +# Bootstrap system +nixos-generate-config --root /mnt +curl -o /mnt/etc/nixos/configuration.nix http://10.0.2.2:"${port}"/configuration.nix +sed -i -E -e "s,@BOOT_DEVICE@,${disk}," /mnt/etc/nixos/configuration.nix +sed -i -E -e 's,(.*device = "/dev/disk/).*(".*),\1by-label/root\2,' /mnt/etc/nixos/hardware-configuration.nix +nixos-install --no-root-password + +# Run stuff in the chroot +curl -o /mnt/root/in-chroot.sh http://10.0.2.2:"${port}"/in-chroot.sh +nixos-enter --root /mnt -c 'bash /root/in-chroot.sh' +rm /mnt/root/in-chroot.sh + +reboot diff --git a/distros/nixos/23.05/x86_64.pkrvars.hcl b/distros/nixos/23.05/x86_64.pkrvars.hcl new file mode 100644 index 0000000..af218f0 --- /dev/null +++ b/distros/nixos/23.05/x86_64.pkrvars.hcl @@ -0,0 +1,15 @@ +distro = "nixos" +version = "23.05" +iso = { + url = "https://channels.nixos.org/nixos-23.05/latest-nixos-minimal-x86_64-linux.iso" + checksum = "f5df994324bc474e834200c8d641ba32492474112e95b63df3153a906ad0bca8" +} +boot_command = [ + " net.ifnames=0 biosdevnames=0", + "", # Wait for system to come up? + "curl -o /tmp/install.sh http://{{ .HTTPIP }}:{{ .HTTPPort }}/install.sh", + "", + "sudo bash /tmp/install.sh {{ .HTTPPort }}" +] +http_directory = "distros/nixos/23.05/http/" +boot_wait = "5s" diff --git a/distros/nixos/supports.yml b/distros/nixos/supports.yml new file mode 100644 index 0000000..1469f18 --- /dev/null +++ b/distros/nixos/supports.yml @@ -0,0 +1,5 @@ +23.05: +- arch: x86_64 + provider: qemu +- arch: x86_64 + provider: virtualbox-iso