Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(raspberry_pi): introduce homelab_ops.raspberry_pi collection #33

Merged
merged 2 commits into from
Apr 28, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
85 changes: 85 additions & 0 deletions .github/workflows/test-raspberry_pi.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
---
name: "test collection: raspberry_pi"

# yamllint disable-line rule:truthy
on:
pull_request:
paths:
- 'raspberry_pi/**'
- 'requirements.txt'
- '.github/workflows/test-raspberry_pi.yaml'
workflow_dispatch:
inputs:
log_verbosity:
description: 'Log Verbosity'
required: true
default: 2
type: choice
options:
- '0'
- '1'
- '2'
- '3'
- '4'
schedule:
- cron: '0 10 */30 * *'

env:
non_workflow_dispatch_log_verbosity: 0

concurrency:
group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
cancel-in-progress: true

jobs:
test:
runs-on: ubuntu-latest
timeout-minutes: 15
steps:
- name: Checkout
uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4

- name: Set up python
uses: actions/setup-python@0a5c61591373683505ea898e09a3ea4f39ef2b9c # v5
with:
python-version: '3.11'
cache: 'pip'
cache-dependency-path: |
requirements.txt

- name: Install python requirements
run: |
python -m pip install -r requirements.txt

- name: Install ansible collections
run: |
ansible-galaxy collection install ./raspberry_pi/
ansible-galaxy collection install ./block_device/
ansible-galaxy collection install ./configure/
ansible-galaxy collection install ./archive/

- name: Determine molecule verbosity
# yamllint disable-line rule:indentation
run: |
set -eo pipefail

MOLECULE_PARAMS="--no-debug"
if [[ $LOG_VERBOSITY -gt 2 ]]; then
MOLECULE_PARAMS="--debug"
fi
if [[ $LOG_VERBOSITY -gt 0 ]]; then
VERBOSE_FLAG=$(printf "v"'%.s' $(eval "echo {1.."$(($LOG_VERBOSITY))"}"))
MOLECULE_PARAMS="$MOLECULE_PARAMS -$VERBOSE_FLAG"
fi
echo "Setting molecule params to [$MOLECULE_PARAMS]..."
echo "MOLECULE_PARAMS=$MOLECULE_PARAMS" >> $GITHUB_ENV
shell: bash
env:
LOG_VERBOSITY: ${{ github.event.inputs.log_verbosity || env.non_workflow_dispatch_log_verbosity }}

- name: Molecule Test
run: molecule $MOLECULE_PARAMS test --all --no-parallel
working-directory: ./raspberry_pi
env:
ANSIBLE_FORCE_COLOR: 1
PY_COLORS: 1
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,3 +10,4 @@
| [homelab_ops.k3s](k3s/) | ![k3s](https://github.com/ppat/homelab-ops-ansible/actions/workflows/test-k3s.yaml/badge.svg) |
| [homelab_ops.os](os/) | ![os](https://github.com/ppat/homelab-ops-ansible/actions/workflows/test-os.yaml/badge.svg) |
| [homelab_ops.packages](packages/) | ![packages](https://github.com/ppat/homelab-ops-ansible/actions/workflows/test-packages.yaml/badge.svg) |
| [homelab_ops.raspberry_pi](raspberry_pi/) | ![raspberry_pi](https://github.com/ppat/homelab-ops-ansible/actions/workflows/test-raspberry_pi.yaml/badge.svg) |
13 changes: 13 additions & 0 deletions raspberry_pi/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
# Ansible Collection - homelab_ops.raspberry_pi

![raspberry_pi](https://github.com/ppat/homelab-ops-ansible/actions/workflows/test-raspberry_pi.yaml/badge.svg)

This collection supplies roles for provisioning raspberry_pi devices.

## Roles

| role | description |
| --- | --- |
| [homelab_ops.raspberry_pi.kernel_cmdline](roles/kernel_cmdline/) | Configure the kernel cmdline of a raspberry pi device |
| [homelab_ops.raspberry_pi.kernel_config](roles/kernel_config/) | Create kernel config.txt for a raspberry pi device |
| [homelab_ops.raspberry_pi.provision](roles/provision/) | Provision a raspberry pi device's empty root device from an os image and configure it to boot |
23 changes: 23 additions & 0 deletions raspberry_pi/galaxy.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
---
namespace: homelab_ops
name: raspberry_pi
version: 0.0.0
readme: README.md
authors:
- [email protected]

description: ""
license:
- AGPL-3.0-only
tags: [homelab, raspberry_pi, kernel]
dependencies:
ansible.posix: ">1.5.0"
homelab_ops.packages: ">=0.1.0"

repository: https://github.com/ppat/homelab-ops-ansible
documentation: https://github.com/ppat/homelab-ops-ansible/blob/main/raspberry_pi/README.md
homepage: https://github.com/ppat/homelab-ops-ansible/blob/main/raspberry_pi/README.md
issues: https://github.com/ppat/homelab-ops-ansible/issues

build_ignore:
- molecule
2 changes: 2 additions & 0 deletions raspberry_pi/meta/runtime.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
---
requires_ansible: '>=2.12.0'
18 changes: 18 additions & 0 deletions raspberry_pi/molecule/kernel_cmdline/converge.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
---
- name: Converge
hosts: all
gather_facts: false
vars:
boot_path: "/mnt/boot"
root_partition_uuid: "{{ 'anything-goes-here' | ansible.builtin.to_uuid }}"
tasks:
- name: "Configure raspberry pi kernel cmdline.txt"
ansible.builtin.include_role:
name: homelab_ops.raspberry_pi.kernel_cmdline
vars:
ubuntu_distribution_release: jammy
root_filesystem:
uuid: "{{ root_partition_uuid }}"
fstype: btrfs
partlabel: root
name: /dev/something
21 changes: 21 additions & 0 deletions raspberry_pi/molecule/kernel_cmdline/molecule.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
---
dependency:
name: galaxy
driver:
name: docker
platforms:
- name: instance
image: ${MOLECULE_IMAGE:-"geerlingguy/docker-ubuntu2204-ansible:latest"}
pre_build_image: true
privileged: true
user: root
volumes:
- /dev:/dev
- /proc:/proc
- /sys:/sys
provisioner:
name: ansible
playbooks:
prepare: prepare.yml
verifier:
name: ansible
14 changes: 14 additions & 0 deletions raspberry_pi/molecule/kernel_cmdline/prepare.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
---
- name: Prepare
hosts: all
gather_facts: false
vars:
boot_path: "/mnt/boot"
tasks:
- name: "Create needed directories"
ansible.builtin.file:
path: "{{ boot_path }}"
owner: root
group: root
mode: '0750'
state: directory
28 changes: 28 additions & 0 deletions raspberry_pi/molecule/kernel_cmdline/verify.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
---
- name: Verify
hosts: all
gather_facts: false
vars:
boot_path: "/mnt/boot"
kernel_cmdline_path: "{{ boot_path }}/cmdline.txt"
tasks:
- name: Stat for generated kernel cmdline
ansible.builtin.stat:
path: "{{ kernel_cmdline_path }}"
register: kernel_cmdline_stat

- name: Assert that kernel cmdline exists at destination
ansible.builtin.assert:
that:
- "{{ kernel_cmdline_stat.stat.exists }}"
fail_msg: "{{ kernel_cmdline_path }} does NOT exist at expected location"
success_msg: "{{ kernel_cmdline_path }} has been generated"

- name: "Read generated cmdline.txt"
ansible.builtin.slurp:
src: "{{ kernel_cmdline_path }}"
register: cmdline_generated

- name: "Display generated cmdline.txt"
ansible.builtin.debug:
msg: "{{ cmdline_generated['content'] | b64decode }}"
20 changes: 20 additions & 0 deletions raspberry_pi/molecule/kernel_config/converge.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
---
- name: Converge
hosts: all
gather_facts: false
vars:
boot_path: "/mnt/boot"
tasks:
- name: "Configure raspberry pi kernel config.txt"
ansible.builtin.include_role:
name: homelab_ops.raspberry_pi.kernel_config
vars:
kernel:
config:
disabled_features:
- bluetooth
- wifi
- act_led
autodetect:
- display
filename: vmlinux
21 changes: 21 additions & 0 deletions raspberry_pi/molecule/kernel_config/molecule.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
---
dependency:
name: galaxy
driver:
name: docker
platforms:
- name: instance
image: ${MOLECULE_IMAGE:-"geerlingguy/docker-ubuntu2204-ansible:latest"}
pre_build_image: true
privileged: true
user: root
volumes:
- /dev:/dev
- /proc:/proc
- /sys:/sys
provisioner:
name: ansible
playbooks:
prepare: prepare.yml
verifier:
name: ansible
14 changes: 14 additions & 0 deletions raspberry_pi/molecule/kernel_config/prepare.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
---
- name: Prepare
hosts: all
gather_facts: false
vars:
boot_path: "/mnt/boot"
tasks:
- name: "Create needed directories"
ansible.builtin.file:
path: "{{ boot_path }}"
owner: root
group: root
mode: '0750'
state: directory
28 changes: 28 additions & 0 deletions raspberry_pi/molecule/kernel_config/verify.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
---
- name: Verify
hosts: all
gather_facts: false
vars:
boot_path: "/mnt/boot"
kernel_config_path: "{{ boot_path }}/config.txt"
tasks:
- name: Stat for generated kernel config
ansible.builtin.stat:
path: "{{ kernel_config_path }}"
register: kernel_config_stat

- name: Assert that kernel config exists at destination
ansible.builtin.assert:
that:
- "{{ kernel_config_stat.stat.exists }}"
fail_msg: "{{ kernel_config_path }} does NOT exist at expected location"
success_msg: "{{ kernel_config_path }} has been generated"

- name: "Read generated config.txt"
ansible.builtin.slurp:
src: "{{ kernel_config_path }}"
register: config_generated

- name: "Display generated config.txt"
ansible.builtin.debug:
msg: "{{ config_generated['content'] | b64decode }}"
91 changes: 91 additions & 0 deletions raspberry_pi/molecule/provision/converge.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
---
- name: Converge
hosts: all
gather_facts: false
vars:
block_device_file: /tmp/test_block_device.img
sysroot_mount: /mnt/sysroot
tasks:
- name: Detect loopback device by file
ansible.builtin.shell: |
#!/bin/bash
set -eo pipefail
losetup --associated {{ block_device_file }} | cut -d':' -f1
args:
executable: /bin/bash
become: true
register: loopback_device_detect_register
changed_when: false

- name: Extract detected loopback device
ansible.builtin.set_fact:
loopback_device: "{{ loopback_device_detect_register.stdout }}"

- name: "Provision raspberry pi"
ansible.builtin.include_role:
name: homelab_ops.raspberry_pi.provision
vars:
provision:
block_device:
additional_bind_mounts:
- src: /srv/longhorn
target: /var/lib/longhorn
- src: /tmp
target: /var/tmp
partitions:
boot:
size: 100
root:
size: 200
filesystem_type: btrfs
filesystem_options:
subvolumes:
- name: home
path: home
copy_on_write: true
- name: snapshots
path: .snapshots
copy_on_write: true
- name: tmp
path: tmp
copy_on_write: false
- name: var
path: var
copy_on_write: false
data:
size: ~
filesystem_type: ext4
root_mount_point: "{{ sysroot_mount }}"
selector:
include:
type: loop
path: "{{ loopback_device }}"
size_unit: MiB
os_image:
url: https://cdimage.ubuntu.com/ubuntu-base/releases/jammy/release/ubuntu-base-22.04-base-amd64.tar.gz
distribution_release: jammy
raspberry_pi:
serial: '12345678'
kernel:
config:
arm_boost_supported: true
disabled_features:
- bluetooth
- wifi
- act_led
cloudinit:
ansible:
# renovate: datasource=pypi depName=ansible-core
core_version: "2.16.2"
dependencies:
- name: jmespath
# renovate: datasource=pypi depName=jmespath
version: "1.0.1"
params: []
collections_requirements_file: "{{ MOLECULE_SCENARIO_DIR }}/input/requirements.yaml"
playbook: "{{ MOLECULE_SCENARIO_DIR }}/input/playbook.yaml"
vars_file: /root/.secrets/cloudinit-playbook-vars
ssh_users:
- name: test-user
authorized_keys:
- ssh-ed25519 AAAABBBBCCCCDDDDEEEEFFFF [email protected]
Loading