RSS

Repeatable Deployments 5 – NVMe Base Duo

NVMe Base Duo Banner

A few weeks ago we looked at using the Pimoroni NVMe Base to add 500 GBytes of storage to a Raspberry Pi, first manually and then using Ansible.

A few days ago I started to look at doing the same but this time with the NVMe Base Duo. This would allow the addition of two drives to the Raspberry Pi. Should be simple, right?

TL;DR The scripts and instructions for running them can be found in the AnsibleNVMe GitHub repository.

Setting up the Hardware

As with the NVMe Base, setting up the NVMe Base Duo was simple, just follow the installation instructions on theproduct page. Again, the most difficult part was connecting the NVMe Base Duo board to the Raspberry Pi using the flat flex connector.

A quick check of the /dev directory shows the two drives as devices:

clusteruser@TestServer:~ $ ls /dev/nv*
/dev/nvme0  /dev/nvme0n1  /dev/nvme1  /dev/nvme1n1

Setting up the two drives should be a case of running the configuration script from the previous post with two different device / mount point names, namely:

  • nvme0 / nvme0n1
  • nvme1 / nvme1n1

Ansible tasks should allow us to reuse the commands used to mount a single drive on the NVMe Base without repeating the instructions with copy/paste.

Ansible Tasks

First thing to do is identify the tasks that should be executed on both drives. These are found in the ConfigureNVMeBase.yml file. They make up the bulk of the file. These tasks are:

- name: Format the NVMe drive {{ nvmebase_device_name }}
  command: mkfs.ext4 /dev/{{ nvmebase_device_name }} -L Data
  when: format_nvmebase | bool

- name: Make the mount point for {{ nvmebase_device_name }}
  command: mkdir /mnt/{{ nvmebase_device_name }}

- name: Mount the newly formatted drive ({{ nvmebase_device_name }})
  command: mount /dev/{{ nvmebase_device_name }} /mnt/{{ nvmebase_device_name }}

- name: Make sure that {{ ansible_user }} can read and write to the mount point
  command: chown -R {{ ansible_user }}:{{ ansible_user }} /mnt/{{ nvmebase_device_name }}

- name: Get the UUID of {{ nvmebase_device_name }}
  command: blkid /dev/{{ nvmebase_device_name }}
  register: blkid_output

- name: Extract UUID from blkid output
  set_fact:
    device_uuid: "{{ blkid_output.stdout | regex_search('UUID=\"([^\"]+)\"', '\\1') }}"

- name: Clean the extracted UUID
  set_fact:
    clean_uuid: "{{ device_uuid | regex_replace('\\[', '') | regex_replace(']', '') |  regex_replace(\"'\" '') }}"

- name: Add UUID entry for {{ nvmebase_device_name }} to /etc/fstab
  lineinfile:
    path: /etc/fstab
    line: "UUID={{ clean_uuid }} /mnt/{{ nvmebase_device_name }} ext4 defaults,auto,users,rw,nofail,noatime 0 0"
    state: present
    create: yes

Breaking these instruction out into a new file, ConfigureNVMeBaseTasks.yml file gives us the consolidated tasks list. The device and drive mount point are derived from the Ansible variable nvmebase_device_name which is set in the calling script as follows:

- include_tasks: ConfigureNVMeDriveTasks.yml
  vars:
	  nvmebase_device_name: nvme0n1

The ansible_user variable (used in the chown command in the tasks file) is taken from the group_vars/all.yml file.

And for the second drive we would use:

- include_tasks: ConfigureNVMeDriveTasks.yml
  vars:
	  nvmebase_device_name: nvme1n1
  when: nvme_duo == true

Note the addition of the when clause to only execute the tasks in the ConfigureNVMeDriveTasks.yml if the nvme_duo variable is true. This clause will also be used when Samba is configured.

Install Samba (Optional)

The installation of Samba follows similar steps as detailed in the Adding NVMe Base using Ansible post. The only addition is to add the second drive to the configuration section of the script.

Change Hostname (Optional)

One final, optional step is to change the name of the Raspberry Pi. This is useful when a number of devices are being configured. This step requires the hostname variable being set in the group_vars/all.yml file. Execute the ChangeHostname.yml script once the variable has been changed. Note that the script may fail following the reboot step as Ansible tries to reconnect with the Raspberry Pi using the old host name.

Lessons Learned

For some reason which was never tracked down, the installation of the sometimes failed on the NVMe Base Duo with access permission issues. The access issue presents itself on the Samba shares and also when attempting to use the drive when logged into the Raspberry Pi. This was resolved by setting the ansible_user variable in the group_vars/all.yml file.

The first installation of the NVMe Base Duo added the PCIe Generation 3 support. This caused some issues accessing the devices in the /dev directory. Removing this support allowed both of the drives to be accessed.

Conclusion

Breaking the drive installation and configuration into a new tasks file allows Ansible to reuse the same steps for two different devices. Couple this with when clauses allows changes to the control flow when deploying to two different types of devices.

Leave a Reply

*