From 331df52f0bf4d09bcd9624d1fefb1fcdaf42ce56 Mon Sep 17 00:00:00 2001 From: Martin Bauer Date: Sat, 19 Sep 2026 19:59:43 +0200 Subject: [PATCH] Download the uv build the Pi can actually run Raspberry Pi OS ships a 64-bit kernel with a 32-bit userland, so uname -m - and therefore ansible_architecture - reports aarch64 on a box whose /bin/ls is ELF32 ARM and which has no /lib/ld-linux-aarch64.so.1. The aarch64 uv tarball unpacked happily and then failed three tasks later with /usr/local/bin/uv: No such file or directory which is the dynamic loader missing, not the file, and points at entirely the wrong thing. Pick the target triple from ansible_userspace_bits instead, which is the fact that tells the truth, and key the install directory on the triple as well as the version - otherwise `creates:` would keep a wrong-architecture binary in place forever. Then run `uv --version` right after installing it, so a bad download fails where the cause is visible. Co-Authored-By: Claude Opus 5 --- roles/pi_musicmouse/defaults/main.yml | 15 +++++++++++++++ roles/pi_musicmouse/tasks/main.yml | 16 +++++++++++----- 2 files changed, 26 insertions(+), 5 deletions(-) diff --git a/roles/pi_musicmouse/defaults/main.yml b/roles/pi_musicmouse/defaults/main.yml index 1cd1d41..72ea230 100644 --- a/roles/pi_musicmouse/defaults/main.yml +++ b/roles/pi_musicmouse/defaults/main.yml @@ -8,6 +8,21 @@ pi_musicmouse_repo: "ssh://git@git.bauer.tech:2222/martin/musicmouse.git" pi_musicmouse_python_version: "3.13" pi_musicmouse_uv_version: "0.12.10" +# Which uv build to download. Raspberry Pi OS ships a 64-bit kernel with a 32-bit +# userland, so `uname -m` (and therefore ansible_architecture) says aarch64 on a box +# that can only run armhf binaries - the aarch64 build installs fine and then fails to +# exec with "No such file or directory", which is the dynamic loader missing, not the +# file. ansible_userspace_bits is the fact that tells the truth. +pi_musicmouse_uv_target: >- + {{ 'armv7-unknown-linux-gnueabihf' + if (ansible_architecture in ['aarch64', 'armv7l', 'armv6l'] and ansible_userspace_bits == '32') + else _pi_musicmouse_uv_targets[ansible_architecture] }} +_pi_musicmouse_uv_targets: + aarch64: aarch64-unknown-linux-gnu + armv7l: armv7-unknown-linux-gnueabihf + armv6l: armv7-unknown-linux-gnueabihf + x86_64: x86_64-unknown-linux-gnu + # Where to check out the repo on the *control machine* to build the frontend (npm isn't # installed on the Pi - see README). Keyed by version so different hosts on different # versions don't clobber each other's build. diff --git a/roles/pi_musicmouse/tasks/main.yml b/roles/pi_musicmouse/tasks/main.yml index 7a418ff..f9c4cc1 100644 --- a/roles/pi_musicmouse/tasks/main.yml +++ b/roles/pi_musicmouse/tasks/main.yml @@ -11,21 +11,21 @@ - name: Ensure uv install directory exists ansible.builtin.file: - path: "/opt/uv-{{ pi_musicmouse_uv_version }}" + path: "/opt/uv-{{ pi_musicmouse_uv_version }}-{{ pi_musicmouse_uv_target }}" state: directory mode: "0755" - name: Download and extract uv {{ pi_musicmouse_uv_version }} ansible.builtin.unarchive: - src: "https://github.com/astral-sh/uv/releases/download/{{ pi_musicmouse_uv_version }}/uv-aarch64-unknown-linux-gnu.tar.gz" - dest: "/opt/uv-{{ pi_musicmouse_uv_version }}" + src: "https://github.com/astral-sh/uv/releases/download/{{ pi_musicmouse_uv_version }}/uv-{{ pi_musicmouse_uv_target }}.tar.gz" + dest: "/opt/uv-{{ pi_musicmouse_uv_version }}-{{ pi_musicmouse_uv_target }}" remote_src: true extra_opts: ["--strip-components=1"] - creates: "/opt/uv-{{ pi_musicmouse_uv_version }}/uv" + creates: "/opt/uv-{{ pi_musicmouse_uv_version }}-{{ pi_musicmouse_uv_target }}/uv" - name: Symlink uv/uvx into /usr/local/bin ansible.builtin.file: - src: "/opt/uv-{{ pi_musicmouse_uv_version }}/{{ item }}" + src: "/opt/uv-{{ pi_musicmouse_uv_version }}-{{ pi_musicmouse_uv_target }}/{{ item }}" dest: "/usr/local/bin/{{ item }}" state: link force: true @@ -33,6 +33,12 @@ - uv - uvx +- name: Verify uv runs on this host + ansible.builtin.command: + cmd: /usr/local/bin/uv --version + register: pi_musicmouse_uv_version_out + changed_when: false + - name: Checkout Musicmouse repo ansible.builtin.git: repo: "{{ pi_musicmouse_repo }}"