Git Product home page Git Product logo

arm-runner-action's Introduction

arm-runner-action

Run tests natively and build images directly from GitHub Actions using a chroot-based virtualized Raspberry Pi (raspios/raspbian) environment.

With this action, you can:

  • run tests in an environment closer to a real embedded system, using qemu userland Linux emulation;
  • build artifacts in such environment and upload them;
  • prepare images that are ready to run on Raspberry Pi and other ARM embedded devices.

This action works with both 32 bits (arm) and 64 bits (aarch64) images.

Usage

Minimal usage is as follows:

jobs:
  build:
    runs-on: ubuntu-latest
    steps:
    - uses: actions/checkout@v2
    - uses: pguyot/arm-runner-action@v2
      with:
        commands: |
            commands to run tests

Typical usage to upload an image as an artifact:

jobs:
  build:
    runs-on: ubuntu-latest
    steps:
    - uses: actions/checkout@v2
    - uses: pguyot/arm-runner-action@v2
      id: build_image
      with:
        base_image: raspios_lite:2022-04-04
        commands: |
            commands to build image
    - name: Compress the release image
      if: github.ref == 'refs/heads/releng' || startsWith(github.ref, 'refs/tags/')
      run: |
        mv ${{ steps.build_image.outputs.image }} my-release-image.img
        xz -0 -T 0 -v my-release-image.img
    - name: Upload release image
      uses: actions/upload-artifact@v2
      if: github.ref == 'refs/heads/releng' || startsWith(github.ref, 'refs/tags/')
      with:
        name: Release image
        path: my-release-image.img.xz

Several scenarios are actually implemented as tests.

Host and guest OS

The action has been tested with ubuntu-latest (currently equivalent to ubuntu-20.04) and ubuntu-22.04. It requires a Linux kernel that is compatible enough with the guest system as it uses qemu userland emulation. It relies on binfmt.

Commands

The repository is copied to the image before the commands script is executed in the chroot environment. The commands script is copied to /tmp/ and is deleted on cleanup.

Inputs

commands

Commands to execute. Written to a script within the image. Required.

base_image

Base image to use. By default, uses latest raspios_lite image. Please note that this is not necessarily well suited for continuous integration as the latest image can change with new releases.

The following values are allowed:

  • raspbian_lite:2020-02-13
  • raspbian_lite:latest
  • raspios_lite:2021-03-04
  • raspios_lite:2021-05-07
  • raspios_lite:2021-10-30
  • raspios_lite:2022-01-28
  • raspios_lite:2022-04-04
  • raspios_lite:2023-05-03
  • raspios_lite:latest (armhf build, default)
  • raspios_oldstable_lite:2023-05-03
  • raspios_lite_arm64:2022-01-28 (arm64)
  • raspios_lite_arm64:2022-04-04 (arm64)
  • raspios_lite_arm64:2023-05-03 (arm64)
  • raspios_lite_arm64:latest (arm64)
  • dietpi:rpi_armv6_bullseye
  • dietpi:rpi_armv7_bullseye
  • dietpi:rpi_armv8_bullseye (arm64)
  • raspi_1_bullseye:20220121 (armel)
  • raspi_2_bullseye:20230102 (armhf)
  • raspi_3_bullseye:20230102 (arm64)
  • raspi_4_bullseye:20230102 (arm64)
  • raspi_1_bookworm:20230612 (armel)
  • raspi_2_bookworm:20230102 (armhf)
  • raspi_2_bookworm:20230612 (armhf)
  • raspi_3_bookworm:20230102 (arm64)
  • raspi_3_bookworm:20230612 (arm64)
  • raspi_4_bookworm:20230101 (arm64)
  • raspi_4_bookworm:20230612 (arm64)

The input parameter also accepts any custom URL beginning in http(s)://...

It also accepts file:// URIs, which can be useful for caching steps in multistep builds. See cache test example.

More images will be added, eventually. Feel free to submit PRs.

image_additional_mb

Enlarge the image by this number of MB. Default is to not enlarge the image.

cpu

CPU to pass to qemu. Pass either a single CPU value or a pair <arm_cpu>:<aarch64_cpu>.

Default is arm1176:cortex-a53, i.e. arm1176 for arm and cortex-a53 for aarch64. This is the most compatible pair for Raspberry Pi. Indeed, arm1176 is the CPU of BCM2835 which is the SOC of first generation RaspberryPi and RaspberryPi Zero, while cortex-a53 is the 64 bits CPU of the first 64 bits Raspberry Pi models. Code compiled for arm1176 can be run on later 32 bits CPUs.

The following values are specially processed:

  • arm1176 equivalent to arm1176:cortex-a53.
  • cortex-a7 equivalent to cortex-a7:cortex-a53. Optimized for later Pi models (Pi 3/Pi 4 and Pi Zero 2). Not suitable for Pi 1/Pi 2/Pi Zero.
  • cortex-a8 equivalent to cortex-a8:max.
  • cortex-a53 equivalent to max:cortex-a53.

Some software uses the output of uname -m or equivalent. This command is directly driven by this cpu option. You might want to compile 32 bits binaries with both arm1176 which translates to armv6l and cortex-a7 which translates to armv7l.

For FPU and vector instruction sets, software usually automatically looks into /proc/cpuinfo or equivalent. This can be patched with cpu_info option.

Whether code is executed in 32 bits or 64 bits (and build generates 32 bits or 64 bits binaries) depend on the image. See 32 and 64 bits below.

copy_artifact_path

Source paths(s) inside the image to copy outside after the commands have executed. Relative to the /<repository_name> directory or the directory defined with copy_repository_path. Globs are allowed. To copy multiple paths, provide a list of paths, separated by semicolons. Default is not to copy.

copy_artifact_dest

Destination path to copy outside the image after the commands have executed. Relative to the working directory (outside the image). Defaults to .

copy_repository_path

Absolute path, inside the image, where the repository is copied or mounted. Defaults to /<repository_name>. It is also the working directory where commands are executed.

The repository is copied unless bind_mount_repository is set to true.

bind_mount_repository

Bind mount the repository within the image instead of copying it. Default is to copy files.

If mounted, any modification of files within the repository by the target emulated system will persist after execution. It does not accelerate execution significantly but can simplify the logic by avoiding the copy artifact step from the target system.

cpu_info

Path to a fake cpu_info file to be used instead of /proc/cpuinfo. Default is to not fake the CPU (/proc/cpuinfo will report amd64 CPU of GitHub runner).

Some software checks for features using /proc/cpuinfo and this option can be used to trick them. The path is relative to the action (to use pre-defined settings) or to the local repository.

Bundled with the action are the following 32 bits CPU infos:

  • cpuinfo/raspberrypi_zero_w
  • cpuinfo/raspberrypi_3b (requires cortex-a7 cpu)
  • cpuinfo/raspberrypi_zero2_w (requires cortex-a7 cpu)

As well as the following 64 bits CPU infos:

  • cpuinfo/raspberrypi_4b
  • cpuinfo/raspberrypi_zero2_w_arm64

On real hardware, the /proc/cpuinfo file content depends on the CPU being used in 32 bits or 64 bits mode, which in turn depends on the base image. Consequently, you may want to use cpuinfo/raspberrypi_zero2_w_arm64 for 64 bits builds and cpuinfo/raspberrypi_zero2_w for 32 bits builds.

To avoid illegal instruction crashes, the cpu_info option must match what is passed to cpu option. In particular, when using 32 bits cpu_info, the default emulated CPU for 32 bits may not work and you should set cpu option to cortex-a7.

optimize_image

Zero-fill unused filesystem blocks and shrink root filesystem during final clean-up, to make any later image compression more efficient. Default is to optimize image.

use_systemd_nspawn

Use systemd-nspawn instead of chroot to run commands. Default is to use chroot.

systemd_nspawn_options

Additional options passed to systemd-nspawn. For example, -E CI=${CI} to pass CI environment variable. See systemd-nspawn(1).

rootpartition

Index (starting with 1) of the root partition. Default is 2, which is suitable for Raspberry Pi. NVIDIA Jetson images require 1. This is the partition that is resized with image_additional_mb option.

bootpartition

Index (starting with 1) of the boot partition which gets mounted at /boot. Default is 1, which is suitable for Raspberry Pi. If the value is empty, the partition is not mounted.

shell

Path to shell or shell name to run the commands in. Defaults to /bin/sh. If missing, it will be installed. See shell_package. If defined as basename filename, it will be used as long as the shell binary exists under PATH after the package is installed.

Parameters can be passed to the shell, e.g.:

shell: /bin/bash -eo pipefail

shell_package

The shell package to install, if different from shell. It may be handy with some shells that come packaged under a different package name.

For example, to use ksh93 as shell, set shell to ksh93 and shell_package to ksh.

user

User to run commands within the image. It must exists. By default, commands are run with user 0 (root). Unless you are using systemd-nspawn, you can also specify the group with the user:group syntax.

exit_on_fail

Exit immediately if a command exits with a non-zero status. Default is to exit. Set to no or false to disable exiting on command failure. This only works with sh, bash and ksh shells.

copy_artifacts_on_fail

Copy artifacts if a command exits with a non-zero status. Default is to no copy. Set to yes to copy artifacts.

debug

Display executed commands as they are executed. Enabled by default.

import_github_env

Imports variables written so far to $GITHUB_ENV to the image. Default is not to import any environment. This may be useful for sharing external variables with the virtual environment. Set to yes or true to enable.

Practically, this setting allows constructs like ${VARIABLE_NAME} instead of ${{ env.VARIABLE_NAME }} within the command set.

export_github_env

Enables $GITHUB_ENV for commands in the image and exports its contents on completion to subsequent tasks. This option is an alternative to using a file-based artifact for passing the results of commands outside the image environment.

Note this parameter does not enable importing any contents written to $GITHUB_ENV ahead of running the commands. For that, use import_github_env.

Outputs

image

Path to the image, useful after the step to upload the image as an artifact.

32 and 64 bits

Many RaspberryPis and ARM boards are based on 64-bits chipsets than can run 32 bits and 64 bits kernels. RaspberryPi OS, as well as other distributions, are now provided in 32 bits and 64 bits flavors.

This action works for images built for 32 bits and 64 bits ARM architectures. Default input values imply 32 bits images. For 64 bits, the CPU and the base image should match.

The following matrix will build on armv6l, armv7l and aarch64 using the latest RaspberryPi OS images.

name: Test architecture matrix
on: [push, pull_request, workflow_dispatch]
jobs:
  build:
    runs-on: ubuntu-latest
    strategy:
      matrix:
        arch: [armv6l, armv7l, aarch64]
        include:
        - arch: armv6l
          cpu: arm1176
          base_image: raspios_lite:latest
          cpu_info: raspberrypi_zero_w
        - arch: armv7l
          cpu: cortex-a7
          base_image: raspios_lite:latest
          cpu_info: raspberrypi_3b
        - arch: aarch64
          cpu: cortex-a53
          base_image: raspios_lite_arm64:latest
          cpu_info: raspberrypi_zero2_w_arm64_w
    steps:
    - uses: pguyot/arm-runner-action@v2
      with:
        base_image: ${{ matrix.base_image }}
        cpu: ${{ matrix.cpu }}
        cpu_info: ${{ matrix.cpu_info }}
        commands: |
            test `uname -m` = ${{ matrix.arch }}
            grep Model /proc/cpuinfo

Internally, the cpu value is embedded in a wrapper for qemu-arm-static and qemu-aarch64-static. The actual qemu invoked depends on executables within the base image.

Examples

Real world examples include:

Releases

Releases are listed on dedicated page. Release numbers follow semantic versionning : incompatible changes in invocation will be reflected with major release upgrades.

arm-runner-action's People

Contributors

chetbox avatar cooked avatar dependabot[bot] avatar ericlemanissier avatar f-laurens avatar justingarfield avatar markpatterson27 avatar nandofw avatar pguyot avatar razr avatar twojstaryzdomu avatar vincent-stragier avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar

arm-runner-action's Issues

Error: Process completed with exit code 32.

Hello
I get following errors during sample pipeline:

mount: /home/actions/temp/arm-runner/mnt/proc/cpuinfo: special device /home/runner/work/_actions/pguyot/arm-runner-action/v2/raspberrypi_zero_w does not exist.
Error: Process completed with exit code 32.

Here is my pipeline.

name: Test architecture matrix
on: [push, pull_request, workflow_dispatch]
jobs:
  build:
    runs-on: ubuntu-latest
    strategy:
      matrix:
        arch: [armv6l, armv7l]
        include:
        - arch: armv6l
          cpu: arm1176
          base_image: raspios_lite:latest
          cpu_info: raspberrypi_zero_w
        - arch: armv7l
          cpu: cortex-a7
          base_image: raspios_lite:latest
          cpu_info: raspberrypi_zero2_w
    steps:
    - uses: pguyot/arm-runner-action@v2
      with:
        base_image: ${{ matrix.base_image }}
        cpu: ${{ matrix.cpu }}
        cpu_info: ${{ matrix.cpu_info }}
        commands: |
            test `uname -m` = ${{ matrix.arch }}
            grep Model /proc/cpuinfo

Could you please help me?
Thank you

Improvement: add the possibility to use any image from url or from path

Hi,

I'm currently trying to build userland (to build raspimjpeg) on the arm-runner-action, but cmake has a bug in the latest available version in Raspberry Pi OS, so I must download cmake from source and build it before building using cmake to build userland... and it takes around 3h 40min. So being able to have a cached image would be a great addition...

I do not have the knowledge to add this feature, but I suppose that the url or the path to the image could be passed using the base_image input.

Regards,
Vincent

P.S.: you can close this issue if it is not relevant.

Rust build possibly running out of RAM

Intro

I am creating a Tauri app. It has a frontend in Next.js and the backend in Rust. Using the Tauri command with cargo, I can build the project for different platforms like Ubuntu, Windows and Mac. Unfortunately, I am not able to compile the project for the Raspberry Pi because it has a different chip architecture. Therefore, I wanted to use your runner to try and build it using GitHub actions.

Problem

When I execute the GitHub action, everything seems to work fine, up until it tries to install tauri with the cargo command: cargo install tauri-cli. Then it starts compiling the needed dependencies and eventually fails because it doesn't have enough RAM to continue. It doesn't say that it doesn't have enough RAM, but when I tried to install tauri on my Raspberry Pi 3B+ with 1 GB of RAM, I encountered the same error. I solved it by increasing swap to 4 GB.

GitHub action

name: Raspberry Pi aarch64 cpu
on:
  workflow_dispatch:

jobs:
  build:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v3
      - uses: pguyot/[email protected]
        with:
          image_additional_mb: 10240
          base_image: https://dietpi.com/downloads/images/DietPi_RPi-ARMv8-Bullseye.7z
          cpu: cortex-a53
          commands: |
            apt-get update -y --allow-releaseinfo-change
            apt-get upgrade -y
            apt-get autoremove -y
            apt-get install curl
            curl https://sh.rustup.rs -sSf | sh -s -- -y
            . "$HOME/.cargo/env"
            curl -fsSL https://deb.nodesource.com/setup_lts.x | sudo -E bash
            apt-get install -y nodejs
            npm install next@latest react@latest react-dom@latest eslint-config-next@latest
            apt-get install -y libwebkit2gtk-4.0-dev build-essential wget libssl-dev libgtk-3-dev libayatana-appindicator3-dev librsvg2-dev
            cargo install tauri-cli
            npm install
            cargo tauri build

Action error

2023-05-11T22:24:23.0259502Z Processing triggers for libgdk-pixbuf-2.0-0:arm64 (2.42.2+dfsg-1+deb11u1) ...
2023-05-11T22:24:23.3381137Z + cargo install tauri-cli
2023-05-11T22:24:24.0772696Z     Updating crates.io index
2023-05-11T22:28:52.8116919Z  Downloading crates ...
2023-05-11T22:28:53.3288241Z   Downloaded tauri-cli v1.3.1
2023-05-11T22:28:54.7728017Z   Installing tauri-cli v1.3.1
2023-05-11T22:29:00.9936668Z  Downloading crates ...
2023-05-11T22:29:01.7668171Z   Downloaded aead v0.5.2
2023-05-11T22:29:01.8475646Z   Downloaded adler v1.0.2
...
2023-05-11T22:29:07.9532795Z   Downloaded ring v0.16.20
2023-05-11T22:29:10.0836555Z    Compiling libc v0.2.144
2023-05-11T22:29:10.0896293Z    Compiling proc-macro2 v1.0.56
2023-05-11T22:34:58.0055244Z ##[error]The runner has received a shutdown signal. This can happen when the runner service is stopped, or a manually started runner is canceled.
2023-05-11T22:34:58.0217639Z ##[error]Process completed with exit code 143.

Rootfs not included in the final image due to error during shrinking

Hello, I have an issue with building a simple image using this workflow:

name: arm-runner-workflow
on: [push]
jobs:
  build:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v2
      - uses: pguyot/arm-runner-action@main
        id: build_image
        with:
          base_image: "raspios_lite_arm64:2023-05-03"
          commands: |
            echo "#include <iostream>" > main.cpp
            echo "int main() {" >> main.cpp
            echo "  std::cout << \"Hello, World!\" << std::endl;" >> main.cpp
            echo "  return 0;" >> main.cpp
            echo "}" >> main.cpp
            g++ -o main main.cpp
            ./main
            uname -srm
      - name: Compress the release image
        run: |
          mv ${{ steps.build_image.outputs.image }} my-release-image.img
          xz -0 -T 0 -v my-release-image.img
      - name: Upload release image
        uses: actions/upload-artifact@v3
        with:
          name: Release image
          path: my-release-image.img.xz

During the build in the arm-runner-action I'm getting this error:

Resizing root filesystem to minimal size.
rootfs: 41861/111776 files (0.1% non-contiguous), 331116/446464 blocks
resize2fs 1.46.5 (30-Dec-2021)
The filesystem is already 446464 (4k) blocks long.  Nothing to do!

Resizing rootfs partition.
Error: The location 2101346304 is outside of the device /dev/loop3.
Shrinking image from 2101346304 to 272629760 bytes.

The uploaded and compressed artifact is only 19MB, which is too small as it should be over 300MB. It appears that the rootfs partition is not included in the final image. What can I do to fix this issue?

This is the repository I created to test the action: https://github.com/dloranc/arm-runner-test/actions

which cpu to configure for a Revolution PI?

Hi,

I'm failing to figure out how to configure arm-runner-action to compile for a Revolution Pi.

The output of lscpu tells me I have a Cortex-72 on an armv7l platform:

Architecture:        armv7l
Byte Order:          Little Endian
CPU(s):              4
On-line CPU(s) list: 0-3
Thread(s) per core:  1
Core(s) per socket:  4
Socket(s):           1
Vendor ID:           ARM
Model:               3
Model name:          Cortex-A72
Stepping:            r0p3
CPU max MHz:         1500.0000
CPU min MHz:         600.0000
BogoMIPS:            270.00
Flags:               half thumb fastmult vfp edsp neon vfpv3 tls vfpv4 idiva idivt vfpd32 lpae evtstrm crc32

And I'm currently using Raspbian buster: uname -a :

Linux RevPi 5.10.120-rt70-v7l #1 SMP PREEMPT_RT Thu, 28 Jul 2022 10:36:48 +0200 armv7l GNU/Linux

I've therefore tried to use raspbian_lite:2020-02-13 with cortex-a72:

      - name: building
        uses: pguyot/arm-runner-action@v2
        with:
          bind_mount_repository: true
          base_image: 'raspbian_lite:2020-02-13'
          cpu: cortex-a72
          commands: |
            apt update
            ...

But the process fails to resolve the CPU:

qemu-arm-static0: unable to find CPU model 'cortex-a72'

Would you have any suggestion what configuration might work?

Thanks!

Fix support for Nvidia Jetson (ARM64)

Hi, I just started using this awesome project and replace our self-hosted runners,
since you're basically emulating an ARM-cpu and download raspberry images, is there a possibility to also include Jetson images ?

rustup no space left error

Hello, I have a problem when using rustup. When it download the Rust toolchain (rustc, cargo etc.), it throws an error about no space left.

error: failed to extract package (perhaps you ran out of disk space?): No space left on device (os error 28)

The code is just this.

        with:
          base_image: ${{ matrix.image }}:2022-04-04
          shell: /bin/bash
          bind_mount_repository: true
          copy_repository_path: /opt/repo
          copy_artifact_path: artifacts
          copy_artifact_dest: $HOME/artifacts
          commands: |
            export PATH="/opt/repo/scripts:$PATH"

            # fix $HOME being no file or directory
            mkdir $HOME || printf '\x1b[1m$HOME exist!\x1b[0m\n'

            mkdir -p artifacts
            sudo apt-get update
            sudo apt-get install curl git -qy --no-install-recommends

            if ! ${{ github.event.inputs.skip-installing-deps }}; then
              [[ -e scripts/install-deps-${{ github.event.inputs.build }}.sh ]] &&
                bash scripts/install-deps-${{ github.event.inputs.build }}.sh
            fi

            ARTIFACTS=/opt/repo/artifacts bash scripts/build-${{ github.event.inputs.build }}.sh

For full code: https://github.com/UrNightmaree/build-things/blob/main/.github/workflows/build-v2.yml#L34

Installing apt packages

I would like to install some apt packages and I am running into a warning about unknown host type.

sudo apt update 
Unknown host QEMU_IFLA type: 54`

this is using a modified test example template from here

name: Test aarch64 cpu option
on:
  push:
    branches:
      - 'main'
      - 'releases/**'
  pull_request:
  workflow_dispatch:

jobs:
  build:
    runs-on: ubuntu-latest
    steps:
    - uses: actions/checkout@v2
    - uses: pguyot/arm-runner-action@HEAD
      with:
        base_image: https://dietpi.com/downloads/images/DietPi_RPi-ARMv8-Bullseye.7z
        cpu: cortex-a53
        commands: |
            echo "Minimal"
            test `uname -m` = 'aarch64'
            sudo apt update
            sudo apt-get install -y git python3-pip libgeos-c1v5 libatlas-base-dev python3-venv 

Is there a way to make sure of the correct apt package for each platform ?

Build in Docker on self-hosted agent.

Hello

Is there any possibilities to build on self-hosted agent in Docker? I can build without Docker on ubuntu-latest cloud github agent and on mine self-hosted.

Thank you.

Copy artifact inside image to outside

Is that possible ?
I did try to use the parameters copy_artifact_path, but it appears something outside the image to be inside, but I'm looking the other way around to output the binary.

qemu-aarch64-static0: unable to find CPU model 'cortex-a76'

Is there a way for this to include a newer (or patched) qemu to support cortex-a76, such as found in Raspberry Pi 5?

++ sudo chroot /home/actions/temp/arm-runner/mnt /bin/sh -c 'command -v /bin/sh'
qemu-aarch64-static0: unable to find CPU model 'cortex-a76'

See: this qemu patch

Thanks for any assistance,
Bill

problems on private runner

hi together, i've setted up a self hosted runner on an ubuntu 18.04 LTS azure machine because on the default runners my build exceeds the 6 hour job limit.
I got one working run on the self hosted runner and now it seems to don't work anymore.
Therefore i simplified the action to the minimum so only a echo is executed: https://github.com/Apfelwurm/cmake-raspberry/blob/main/.github/workflows/build_release.yml

Even with this minimal setup it results in the following behavior:

the action runs and executes sudo chroot /home/actions/temp/arm-runner/mnt /tmp/commands.sh, at this point qemu-arm-static begins to use between 99.3% and 100% cpu (top output) but nothing more happens.
If i wait around 15 minutes, chroot exits with code 255. So its possible that i encounter the same problem that is mentioned here but in a different situation. Sadly i only have that one self hosted runner, therefore different jobs would run on the same machine.

let me know when there is more information needed and how i can get it.

Ty!

Having difficulty copying build artefact from image into repository

I cannot figure out how to copy a built compiled binary from the image to the cloned repository. I am building statically linked tmux binaries for armv7l and aarch64. This is the relevant part of the action yaml:

jobs:
  build_and_upgrade:
    runs-on: ubuntu-latest
    strategy:
      matrix:
        arch: [armv7l, aarch64]
        include:
        - arch: armv7l
          cpu: cortex-a7
          base_image: raspios_lite:latest
        - arch: aarch64
          cpu: cortex-a53
          base_image: raspios_lite_arm64:latest

    steps:
    - uses: actions/checkout@v3
      with:
        token: ${{ secrets.github_token }}

    - name: Upgrade buildscript
      run: wget https://github.com/mjakob-gh/build-static-tmux/raw/master/build-static-tmux.sh -O bin/scripts/build-static-tmux.sh

    - name: Build on arm VM
      uses: pguyot/arm-runner-action@v2
      with:
        base_image: ${{ matrix.base_image }}
        cpu: ${{ matrix.cpu }}
        cpu_info: ${{ matrix.cpu_info }}
        copy_artifact_path: /tmp/tmux-static/bin/tmux
        copy_artifact_dest: bin/${{ matrix.arch }}
        image_additional_mb: 1024
        commands: |
            test $(uname -m) = ${{ matrix.arch }}
            /bin/sh bin/scripts/build-static-tmux.sh
            mv /tmp/tmux-static/bin/tmux bin/${{ matrix.arch }}

And here is the relevant part of the log:

2022-07-21T02:12:51.3566782Z tmux 3.3
2022-07-21T02:12:51.3567123Z ------------------
2022-07-21T02:12:51.8653604Z Downloading...�[0;32m[OK]�[0m
2022-07-21T02:12:52.0018275Z Extracting....�[0;32m[OK]�[0m
2022-07-21T02:14:31.1097454Z Configuring...�[0;32m[OK]�[0m
2022-07-21T02:22:51.7513307Z Compiling.....�[0;32m[OK]�[0m
2022-07-21T02:22:53.4481238Z Installing....�[0;32m[OK]�[0m
2022-07-21T02:22:53.5799107Z Stripping.....�[0;32m[OK]�[0m
2022-07-21T02:22:53.5800598Z 
2022-07-21T02:22:53.5800903Z Resulting files:
2022-07-21T02:22:53.5857343Z ----------------
2022-07-21T02:22:53.5860753Z Standard tmux binary:   /tmp/tmux-static/bin/tmux.linux-armv7l.gz
2022-07-21T02:22:53.5861215Z Stripped tmux binary:   /tmp/tmux-static/bin/tmux.linux-armv7l.stripped.gz
2022-07-21T02:22:54.2979121Z 
2022-07-21T02:22:54.2980214Z ----------------------------------------
2022-07-21T02:22:54.3311163Z Duration: 0h 59m 21s
2022-07-21T02:22:54.3311995Z 
2022-07-21T02:22:54.3321505Z + mv /tmp/tmux-static/bin/tmux bin/armv7l
2022-07-21T02:22:54.3694969Z + rc=0
2022-07-21T02:22:54.3695987Z + '[' -f /home/actions/temp/arm-runner/mnt/tmp/github_env.sh ']'
2022-07-21T02:22:54.3696606Z + exit 0
2022-07-21T02:22:54.3747430Z ##[group]Run case "yes" in
2022-07-21T02:22:54.3747710Z �[36;1mcase "yes" in�[0m
2022-07-21T02:22:54.3747906Z �[36;1myes|true)�[0m
2022-07-21T02:22:54.3748118Z �[36;1m    set -x�[0m
2022-07-21T02:22:54.3748315Z �[36;1m;;�[0m
2022-07-21T02:22:54.3748489Z �[36;1mesac�[0m
2022-07-21T02:22:54.3748703Z �[36;1mrepository_path=�[0m
2022-07-21T02:22:54.3748951Z �[36;1mif [ "${repository_path}x" = "x" ]; then�[0m
2022-07-21T02:22:54.3749259Z �[36;1m    repository_name=`basename /home/runner/work/.dotfiles/.dotfiles`�[0m
2022-07-21T02:22:54.3749578Z �[36;1m    repository_path=/${repository_name}�[0m
2022-07-21T02:22:54.3749889Z �[36;1mfi�[0m
2022-07-21T02:22:54.3750156Z �[36;1mif [ "/tmp/tmux-static/bin/tmuxx" != "x" ] && [ "bin/armv7lx" != "x" ]; then�[0m
2022-07-21T02:22:54.3750516Z �[36;1m    while read -d\; copy_artifact_path; do�[0m
2022-07-21T02:22:54.3750912Z �[36;1m        [ -z "${copy_artifact_path}" ] || sudo cp -Rp /home/actions/temp/arm-runner/mnt${repository_path}/${copy_artifact_path} bin/armv7l�[0m
2022-07-21T02:22:54.3751297Z �[36;1m    done <<< "/tmp/tmux-static/bin/tmux;"�[0m
2022-07-21T02:22:54.3751514Z �[36;1mfi�[0m
2022-07-21T02:22:54.3847394Z shell: /usr/bin/bash --noprofile --norc -e -o pipefail {0}
2022-07-21T02:22:54.3847659Z ##[endgroup]
2022-07-21T02:22:54.3951040Z + repository_path=
2022-07-21T02:22:54.3951851Z + '[' x = x ']'
2022-07-21T02:22:54.3954368Z ++ basename /home/runner/work/.dotfiles/.dotfiles
2022-07-21T02:22:54.3967979Z + repository_name=.dotfiles
2022-07-21T02:22:54.3968528Z + repository_path=/.dotfiles
2022-07-21T02:22:54.3969119Z + '[' /tmp/tmux-static/bin/tmuxx '!=' x ']'
2022-07-21T02:22:54.3975654Z + '[' bin/armv7lx '!=' x ']'
2022-07-21T02:22:54.4025753Z + read '-d;' copy_artifact_path
2022-07-21T02:22:54.4026704Z + '[' -z /tmp/tmux-static/bin/tmux ']'
2022-07-21T02:22:54.4027908Z + sudo cp -Rp /home/actions/temp/arm-runner/mnt/.dotfiles//tmp/tmux-static/bin/tmux bin/armv7l
2022-07-21T02:22:54.4111627Z cp: cannot stat '/home/actions/temp/arm-runner/mnt/.dotfiles//tmp/tmux-static/bin/tmux': No such file or directory
2022-07-21T02:22:54.4128230Z ##[error]Process completed with exit code 1.
2022-07-21T02:22:54.4362897Z Post job cleanup.

The buildscript is supposed to make a tmux binary at /tmp/tmux-static/tmux which I want to copy to bin/armv7l/ in the repository, but it cannot find it.

Thanks.

Cannot cd into repository directory and issue with ubuntu-18.04

When running your action on ubuntu-latest and ubuntu-18.04 I did encountered such issues.

Part of the github workflow file

  raspberry_pi-mod:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/[email protected]
        with:
          submodules: true
          fetch-depth: 0

      - uses: pguyot/arm-runner-action@v2
        with:
           image_additional_mb: 4096
           base_image: raspi_4_bullseye:20220121
           cpu: cortex-a53
           cpu_info: cpuinfo/raspberrypi_4b
           bind_mount_repository: /opt/etlegacy
           optimize_image: no
           commands: |
             sudo apt-get update
             sudo apt-get -y install build-essential libudev-dev automake zlib1g libraspberrypi0 \
             libraspberrypi-bin libraspberrypi-dev libx11-dev \
             nasm autoconf git cmake zip gcc g++ libtool ninja-build
             cd /opt/etlegacy
             git fetch --tags --force
             ./easybuild.sh build -RPI -mod -ninja

Ubuntu-latest

/tmp/commands.sh: 2: cd: can't cd to /etlegacy

Most of the log showing what happened during

Run case cortex-a53 in
Run bash /home/runner/work/_actions/pguyot/arm-runner-action/v2/download_image.sh raspi_4_bullseye:20220121
Warning: The `set-output` command is deprecated and will be disabled soon. Please upgrade to using Environment Files. For more information see: https://github.blog/changelog/2022-10-11-github-actions-deprecating-save-state-and-set-output-commands/
Run sudo bash /home/runner/work/_actions/pguyot/arm-runner-action/v2/mount_image.sh /home/runner/work/_temp/arm-runner/arm-runner.img 4096 no 2 1
4096+0 records in
4096+0 records out
4294967296 bytes (4.3 GB, 4.0 GiB) copied, 19.3924 s, 221 MB/s
Created loopback device /dev/loop3
Warning: The `set-output` command is deprecated and will be disabled soon. Please upgrade to using Environment Files. For more information see: https://github.blog/changelog/2022-10-11-github-actions-deprecating-save-state-and-set-output-commands/
RASPIROOT: 19851/102544 files (0.2% non-contiguous), 158239/409600 blocks
resize2fs 1.45.5 (07-Jan-2020)
Resizing the filesystem on /dev/loop3p2 to 1458176 (4k) blocks.
The filesystem on /dev/loop3p2 is now 1458176 (4k) blocks long.

Finished resizing disk image.
/dev/loop3: msdos partitions 1 2
Warning: The `set-output` command is deprecated and will be disabled soon. Please upgrade to using Environment Files. For more information see: https://github.blog/changelog/2022-10-11-github-actions-deprecating-save-state-and-set-output-commands/
mv: cannot stat '/home/actions/temp/arm-runner/mnt/etc/resolv.conf': No such file or directory
Run if [ -e /home/runner/work/etlegacy/etlegacy/cpuinfo/raspberrypi_4b ]; then
Run case "yes" in
+ repository_path=
+ '[' x = x ']'
++ basename /home/runner/work/etlegacy/etlegacy
+ repository_name=etlegacy
+ repository_path=/etlegacy
+ case "yes" in
+ exit_on_fail=e
+ shell_with_opts=/bin/sh
+ shell=/bin/sh
+ '[' /bin/sh '!=' /bin/sh ']'
+ shell_opts=
+ shell_package=
+ '[' -x /home/actions/temp/arm-runner/mnt//bin/sh ']'
++ sudo chroot /home/actions/temp/arm-runner/mnt /bin/sh -c 'command -v /bin/sh'
+ shell_path=/bin/sh
++ dirname /home/actions/temp/arm-runner/mnt/etlegacy
+ sudo mkdir -p /home/actions/temp/arm-runner/mnt
+ case /opt/etlegacy in
+ '[' nox '!=' x -a nox '!=' nox ']'
+ chroot_script_dir=/tmp
+ script_dir=/home/actions/temp/arm-runner/mnt/tmp
+ mkdir -p /home/actions/temp/arm-runner/mnt/tmp
+ script_path=/home/actions/temp/arm-runner/mnt/tmp/commands.sh
+ touch /home/actions/temp/arm-runner/mnt/tmp/commands.sh
+ '[' xe '!=' '' ']'
++ basename /bin/sh
+ shell_basename=sh
+ '[' sh = sh -o sh = bash -o sh = ksh -o '' = ksh ']'
+ echo 'set -xe'
+ case "no" in
+ case "no" in
+ echo 'cd /etlegacy'
+ cat
+ '[' nox '!=' x -a nox '!=' nox ']'
+ sudo chroot /home/actions/temp/arm-runner/mnt /bin/sh /tmp/commands.sh
+ cd /etlegacy
/tmp/commands.sh: 2: cd: can't cd to /etlegacy
Error: Process completed with exit code 2.
Run sudo umount /home/actions/temp/arm-runner/mnt/proc/cpuinfo
Run case /opt/etlegacy in
mv: cannot stat '/home/actions/temp/arm-runner/mnt/etc/_resolv.conf': No such file or directory
Run sudo rm /usr/bin/qemu-arm-static0
update-binfmts: warning: no executable /usr/bin/qemu-arm-static0 found, but continuing anyway as you request
update-binfmts: warning: current package is <local>, but binary format already installed by arm-runner-action; not removing.
update-binfmts: warning: no executable /usr/bin/qemu-aarch64-static0 found, but continuing anyway as you request
update-binfmts: warning: current package is <local>, but binary format already installed by arm-runner-action; not removing.
update-binfmts: warning: unable to enable binary format qemu-arm: another format with the same magic already exists and this is a fix-binary format: No such file or directory
update-binfmts: warning: unable to enable binary format qemu-arm
update-binfmts: warning: unable to enable binary format qemu-aarch64: another format with the same magic already exists and this is a fix-binary format: No such file or directory
update-binfmts: warning: unable to enable binary format qemu-aarch64

Ubuntu-18.04

Run case cortex-a53 in
update-binfmts: unrecognized option '--unimport'
Try 'update-binfmts --help' or 'update-binfmts --usage' for more information.
Error: Process completed with exit code 2.
Run sudo umount /proc/cpuinfo
umount: /proc/cpuinfo: not mounted.
Error: Process completed with exit code 32.
Run case /opt/etlegacy in
/home/runner/work/_actions/pguyot/arm-runner-action/v2/cleanup_image.sh: line 6: $3: unbound variable
Error: Process completed with exit code 1.
Run sudo rm /usr/bin/qemu-arm-static0
update-binfmts: warning: no executable /usr/bin/qemu-arm-static0 found, but continuing anyway as you request
update-binfmts: warning: /var/lib/binfmts/arm-runner-action-qemu-arm does not exist; nothing to do!
update-binfmts: warning: no executable /usr/bin/qemu-aarch64-static0 found, but continuing anyway as you request
update-binfmts: warning: /var/lib/binfmts/arm-runner-action-qemu-aarch64 does not exist; nothing to do!
update-binfmts: warning: unable to open /usr/share/binfmts/qemu-arm: No such file or directory
update-binfmts: warning: couldn't find information about 'qemu-arm' to import
update-binfmts: exiting due to previous errors
Error: Process completed with exit code 2.

Issue related to PiShrink removing logs files (not related to arm-runner-action, unlike anticipated)

Hello,

I am trying to build an image with the action. The installation script is working on a fresh installation on a RPi Zero, however, it is not working using the action. Indeed, I get the following errors on the used daemons:

pi@elab-birdhouse:~ $ systemctl status nginx
● nginx.service - A high performance web server and a reverse proxy server
   Loaded: loaded (/lib/systemd/system/nginx.service; enabled; vendor preset: enabled)
   Active: failed (Result: exit-code) since Thu 2021-08-19 21:22:01 BST; 3min 35s ago
     Docs: man:nginx(8)

May 07 16:01:05 elab-birdhouse systemd[1]: Starting A high performance web server and a reverse proxy server...
May 07 16:01:06 elab-birdhouse nginx[514]: nginx: [alert] could not open error log file: open() "/var/log/nginx/error.loMay 07 16:01:09 elab-birdhouse systemd[1]: nginx.service: Current command vanished from the unit file, execution of the
Aug 19 21:22:01 elab-birdhouse nginx[514]: 2021/05/07 16:01:06 [emerg] 514#514: open() "/var/log/nginx/access.log" faileAug 19 21:22:01 elab-birdhouse nginx[514]: nginx: configuration file /etc/nginx/nginx.conf test failed
Aug 19 21:22:01 elab-birdhouse systemd[1]: nginx.service: Control process exited, code=exited, status=1/FAILURE
Aug 19 21:22:01 elab-birdhouse systemd[1]: nginx.service: Failed with result 'exit-code'.
Aug 19 21:22:01 elab-birdhouse systemd[1]: Failed to start A high performance web server and a reverse proxy server.

pi@elab-birdhouse:~ $ systemctl status uwsgi
● uwsgi.service - uWSGI Service
   Loaded: loaded (/etc/systemd/system/uwsgi.service; enabled; vendor preset: enabled)
   Active: failed (Result: exit-code) since Fri 2021-05-07 16:01:11 BST; 3 months 12 days ago
 Main PID: 509 (code=exited, status=1/FAILURE)

May 07 16:01:05 elab-birdhouse systemd[1]: Started uWSGI Service.
May 07 16:01:11 elab-birdhouse uwsgi[509]: [uWSGI] getting INI configuration from /etc/elab_birdhouse/uwsgi.ini
May 07 16:01:11 elab-birdhouse uwsgi[509]: open("/var/log/uwsgi/uwsgi.log"): No such file or directory [core/logging.c lMay 07 16:01:11 elab-birdhouse systemd[1]: uwsgi.service: Main process exited, code=exited, status=1/FAILURE
May 07 16:01:11 elab-birdhouse systemd[1]: uwsgi.service: Failed with result 'exit-code'.
pi@elab-birdhouse:~ $

To repair it, I have to run the following commands (already present in the install script) and to restart the services:

# Add log folders
sudo rm -rf /var/log/uwsgi > /dev/null 2>&1
sudo mkdir /var/log/uwsgi
sudo touch /var/log/uwsgi/uwsgi.log
sudo chown -R www-data:www-data /var/log/uwsgi

sudo rm -rf /var/log/nginx > /dev/null 2>&1
sudo mkdir /var/log/nginx
sudo touch /var/log/nginx/error.log
sudo chown -R www-data:www-data /var/log/nginx        

It's like the command do not have any effect (/var/log/uwsgi/uwsgi.log and /var/log/nginx/error.log) do not exist in the generated image...

Any idea why?

Maven fails to launch

Hi,

I'm working on experimenting with some automation with this action to build Maven projects designed for the Raspberry Pi, however attempting to run maven returns java.lang.ClassNotFoundException: org.apache.maven.cli.MavenCli if I try to run any maven command, whether that's mvn -v, mvn package, etc.

I've tried using maven from source and apt but both result in the same error. Running Bellsoft JDK 17.

I've attached the full runner logs in a gist here
YML file: https://gist.github.com/dev-sda1/886932435d773670c30647bbf14d5bd6

Docker Daemon Not Running

I am looking to use this GitHub action to build, test, and deploy the ARM version of one of the @ubcuas projects. This is the workflow file I have right now (see "build-arm"). I was able to get Docker to install but when I try to run something it says that the daemon is not running (example of a failed job). Doing some research online it seems that this is caused by being inside chroot. Is there any way to get around this to run Docker commands?

Arm actions running runs as root and not the runner user

github actions runs with passwordless sudo as a non-root user.

arm-runner-action runs as root (uid=0(root) gid=0(root) groups=0(root) root) and makes performing commands not the same as if it were run within the standard ubuntu actions (uid=1001(runner) gid=121(docker) groups=121(docker),4(adm),101(systemd-journal) runner).

this should be corrected so that arm-runner-action runs as the runner user with passwordless sudo enabled.

shell files under profile.d are not sourced

Hi @pguyot , thanks for this useful action.

I'm creating some ARM images with built python and rust inside them, but when I'll use them seems shell files under /etc/profile.d/ , that contain environment variables with paths of just built languages, are not "sourced", so the execution ends with error.

This is what I do:

     - name: Create release image
        uses: pguyot/[email protected]
        id: arm_runner_install
        with:
          base_image: ${{ matrix.base_image }}
          cpu: ${{ matrix.cpu }}
          cpu_info: ${{ matrix.cpu_info }}
          shell: bash
          copy_repository_path: /opt/repo
          image_additional_mb: 4096
          commands: |
            echo "------------------ INSTALL RUST ------------------"
            export CARGO_HOME=$CARGO_PATH
            export RUSTUP_HOME=$RUSTUP_PATH
            curl https://sh.rustup.rs -sSf | bash -s -- -y --no-modify-path
            echo "------------------ INSTALL PYTHON ------------------"
            mkdir -p $PYTHON_INSTALL_PATH 
....
            echo "------------------ CHECK ------------------"
            export PATH=$CARGO_PATH/bin:$PYTHON_INSTALL_PATH/bin:$PIPX_BIN_PATH:$PATH
            export LD_LIBRARY_PATH=$PYTHON_INSTALL_PATH/lib:$LD_LIBRARY_PATH
            source $CARGO_HOME/env
            rustc --version
            python3 --version
            echo "------------------ EXPORT ENV ------------------"
            echo "export PATH=$CARGO_PATH/bin:$PYTHON_INSTALL_PATH/bin:$PIPX_BIN_PATH:$PATH" >> /etc/profile.d/env.sh
            echo "export LD_LIBRARY_PATH=$PYTHON_INSTALL_PATH/lib:$LD_LIBRARY_PATH" >> /etc/profile.d/env.sh
            cat $CARGO_HOME/env >> /etc/profile.d/rust.sh
            echo "export CARGO_HOME=$CARGO_PATH" >> /etc/profile.d/rust.sh
            echo "export RUSTUP_HOME=$RUSTUP_PATH" >> /etc/profile.d/rust.sh

this is the full build script , and this is its execution that builds correctly all the images to release.

As you can see, I do a "CHECK" phase after python and rust were installed, and they correctly print the version.

Then I do export the environment variables into those two /etc/profile.d files, that are present when I use that image, so I can easily run the tools due the fact /etc/profile.d shell files should be automatically sourced when opening a shell.

When the image is then used here (another repository, that uses released images from the first one) I expect that those two shell files should be "sourced", so running

rustc --version
python3 --version

should print the version.

This does not happen, and I've to "source" those file manually, to have the above command works.

Is it possible to have the files under /etc/profile.d automatically sourced when running the image ? Or should I put the source command manually on user workflow (creating a strong bind between build workflow and user workflow because the need of knowing those paths where tools were installed) ?

Sorry for this long issue, thanks for all.

Illegal Instruction

Hi, I'm hoping you can help me figure out this issue. I cannot seem to get any of the armv6l images to work, always ending up with some variation on an Illegal Instruction being reported by QEMU. For example (from here):

+ cd /usql
+ sudo apt install -y git upx tar bzip2 golang

WARNING: apt does not have a stable CLI interface. Use with caution in scripts.

Reading package lists...
Building dependency tree...
Reading state information...
bzip2 is already the newest version (1.0.8-4).
bzip2 set to manually installed.
tar is already the newest version (1.34+dfsg-1).
The following additional packages will be installed:
  git-man golang-1.15 golang-1.15-doc golang-1.15-go golang-1.15-src
  golang-doc golang-go golang-src liberror-perl libucl1
Suggested packages:
  git-daemon-run | git-daemon-sysvinit git-doc git-el git-email git-gui gitk
  gitweb git-cvs git-mediawiki git-svn bzr | brz mercurial subversion
The following NEW packages will be installed:
  git git-man golang golang-1.15 golang-1.15-doc golang-1.15-go
  golang-1.15-src golang-doc golang-go golang-src liberror-perl libucl1
  upx-ucl
0 upgraded, 13 newly installed, 0 to remove and 0 not upgraded.
Need to get 66.5 MB of archives.
After this operation, 371 MB of additional disk space will be used.
Get:2 http://raspbian.raspberrypi.org/raspbian bullseye/main armhf git-man all 1:2.30.2-1+deb11u2 [1828 kB]
qemu: uncaught target signal 4 (Illegal instruction) - core dumped
qemu: uncaught target signal 4 (Illegal instruction) - core dumped
E: Method http has died unexpectedly!
E: Sub-process http received signal 4.
Error: Process completed with exit code 100.

Is this an issue with the current Raspberry PI images? Any help would be appreciated, as I'd like to start producing armv6l and arm64 release binaries for `usql.

The workflow I'm trying to use is here: https://github.com/xo/usql/blob/master/.github/workflows/arm.yml

I was able to compile usql for arm64 (aarch64), but cannot figure out what needs to be done to get this runner working. I will try to do it with QEMU locally, but thought I would reach out here to see if there was any insight you might have into this specific issue.

Really appreciate your work on this project, and thanks in advance!

add support for ubuntu raspi

thanks for your great project, I have tried to use it with ubuntu raspi as:

jobs:
  build:
    runs-on: ubuntu-22.04
    steps:
    - uses: actions/checkout@v2
    - uses: pguyot/arm-runner-action@v2
      with:
        base_image: https://cdimage.ubuntu.com/releases/22.04.1/release/ubuntu-22.04.1-preinstalled-server-arm64+raspi.img.xz
        commands: |
            uname -a

and get

cp: cannot stat '/home/actions/temp/arm-runner/mnt/etc/resolv.conf': No such file or directory
cp: not writing through dangling symlink '/home/actions/temp/arm-runner/mnt/etc/resolv.conf'

I think this is because:

ls -la /etc/resolv.conf
/etc/resolv.conf -> ../run/resolvconf/resolv.conf

Apple silicon ?

More of a question than an issue, can this action can be modified/altered in a way that will allow compiling into Apple silicon ARM architecture (M1/2 cpus etc)?

Filesystem is full on NVidia Orin image

I try to run the Nvidia Orin image.

It turned out there is not enough space inside the docker container to unzip it.

-rw-rw-r--  1 user user 11156299681 Mar 20 04:51 jp511-orin-nano-sd-card-image.zip
-rw-r--r--  1 user user 22144876544 May  4 15:18 sd-blob.img

I have removed Android and dotnet as

    - name: Increase free space
      # Remove Android and dotnet
      run: |
        sudo rm -rf /usr/local/lib/android
        sudo rm -rf /usr/share/dotnet
        df -h

After that unzip works, but it fails to mount it.

Created loopback device /dev/loop3
/dev/loop3: gpt partitions 2 3 4 5 6 7 8 9 10 11 12 13 14 1
mount: /home/actions/temp/arm-runner/mnt: wrong fs type, bad option, bad superblock on /dev/loop3p2, missing codepage or helper program, or other error.
~/tmp$ fdisk -l sd-blob.img 
Disk sd-blob.img: 20.62 GiB, 22144876544 bytes, 43251712 sectors
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disklabel type: gpt
Disk identifier: E078F7E2-0752-4DF8-8B74-6A5CD5C5AE8B

Device          Start      End  Sectors   Size Type
sd-blob.img1  3057664 43233279 40175616  19.2G Linux filesystem
sd-blob.img2     2048   264191   262144   128M Linux filesystem
sd-blob.img3   264192   265727     1536   768K Linux filesystem
sd-blob.img4   266240   331007    64768  31.6M Linux filesystem
sd-blob.img5   331776   593919   262144   128M Linux filesystem
sd-blob.img6   593920   595455     1536   768K Linux filesystem
sd-blob.img7   595968   660735    64768  31.6M Linux filesystem
sd-blob.img8   661504   825343   163840    80M Linux filesystem
sd-blob.img9   825344   826367     1024   512K Linux filesystem
sd-blob.img10  827392   958463   131072    64M EFI System
sd-blob.img11  958464  1122303   163840    80M Linux filesystem
sd-blob.img12 1122304  1123327     1024   512K Linux filesystem
sd-blob.img13 1124352  1255423   131072    64M Linux filesystem
sd-blob.img14 1255424  3056639  1801216 879.5M Linux filesystem

It works, if I do mount manually as

sudo mount -v -o offset=$((512 * 3057664)) -t ext4 sd-blob.img ~/tmp/arm-runner/
/tmp$ ls arm-runner
bin  boot  dev  etc  home  lib  lost+found  media  mnt  opt  proc  README.txt  root  run  sbin  snap  srv  sys  tmp  usr  var

Build x64 image?

Is it possible to build a x64 image?

This GitHub Action is great for dealing with all the things one might need to think about to create an ARM system image that's ready to go. We also need to create images (with the same setup!) for Intel x64 machines and it would be great if we could use this action to run with QEMU using x86_64 so that we're using the same setup.

The README doesn't mention this so I wondered if it's possible as is or with a straightforward modification?

tips for caching apt packages or modified build

Thank you for this action.
It works super well and is a real help for our @openframeworks CI.

We're using it to test our C++ code so we basically apt-get install libs/packages needed and then run our make command with our code.

The additional packages installation is taking up the bulk of the time (30 mins or so) and I'd love a way to restore a modified version of one of your images with the additional packages added. Is there a mechanism for doing that? Either via actions/cache or another means?

Many thanks!

Some of the Enviroment Variables imported by import_github_env are not set

When I did set import_github_env to true I did noticed that particular env variable is not set from github workflow.
I am speaking of CI that my code depends on.

		if("$ENV{CI}" STREQUAL "true")
		/// more code

This part of code was never reached. I had to manually set in commands to make it work as expected
export CI=true

PS: I had tried setting env variable using the worklow itselt

env:
    CI: true

Running the action twice in the same job doesn't seem to work

As shown by tests, second run eventually exits with error 255 on chroot line, even if cleanup seems complete.
Let me now here if this bug is an issue.
A workaround consists in defining several jobs which eventually could be executed in parallel.

No networking inside DietPi image

Hi there. I'm trying to make a custom DietPi image with some pre-installed software, but apparently there is no network connectivity during the commands execution. How do I fix this?

Reproducible Example

jobs:
  build:
    runs-on: ubuntu-latest

    steps:
      - uses: pguyot/arm-runner-action@v2
        id: build_image
        with:
          base_image: dietpi:rpi_armv8_bullseye
          cpu: cortex-a53
          image_additional_mb: 500
          commands: |
            ping -4nc 1 -W 10 9.9.9.9

Expected output

I expect the ping to succeed and thus show that there is network connectivity in the emulated DietPi image during commands execution.

Actual output

 PING 9.9.9.9 (9.9.9.9) 56(84) bytes of data.

--- 9.9.9.9 ping statistics ---
1 packets transmitted, 0 received, 100% packet loss, time 0ms

`use_systemd_nspawn` does not seem to work

My job looks like this:

    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v2
      - name: Build image
        uses: pguyot/arm-runner-action@v2
        id: build_image
        with:
          base_image: https://downloads.raspberrypi.org/raspios_arm64/images/raspios_arm64-2022-01-28/2022-01-28-raspios-bullseye-arm64.zip
          cpu: cortex-a53 # arm64
          image_additional_mb: 4096
          bind_mount_repository: true
          use_systemd_nspawn: true
          shell: /bin/bash
          commands: ...

But I get this error:

 + sudo systemd-nspawn -D /home/actions/temp/arm-runner/mnt /tmp/commands.sh
Spawning container mnt on /home/actions/temp/arm-runner/mnt.
Press ^] three times within 1s to kill container.
/home/actions/temp/arm-runner/mnt/dev is pre-mounted and pre-populated. If a pre-mounted /dev is provided it needs to be an unpopulated file system.
mknod(/home/actions/temp/arm-runner/mnt/dev/null) failed: File exists

I'm not familiar with systemd-nspawn but it seems we should be using it given our commands include systemctl enable ....

Issue with CPU cortex-a8 and raspi_4_bullseye:20220121

Hello!
I'm trying to get work runner for RPI4 with 64bit OS

My workflow is:

steps:
    - uses: actions/checkout@v2
    - uses: pguyot/arm-runner-action@HEAD
      id: build_image
      with:
        cpu: cortex-a8
        base_image: raspi_4_bullseye:20220121
        copy_repository_path: /home/pi/app
        image_additional_mb: 2048
        commands: |
            sudo cat /etc/os-release
            sudo lscpu

And it fails with error:
2022-02-21T11:22:18.7910107Z qemu-aarch64-static: unable to find CPU model 'cortex-a8'

What did I do wrong?
Thanks.

Cleanup mounts and loop devices

Hi, thank you for this great project :)

I'm running this action under a self hosted runner (with a job, mostly failing 😄) and my machine gets a little bit flooded with loop devices and mounts.
It would be great, if there is a way to clean these things up at the end of a (failed) run.

How to update repository files inside a cached image?

Hello.

Thanks for the great action tool, we are planning to use this extensively. However, we've been struggling with a minor issue.

Our workflow consists of two jobs:

  1. (Optional) Build an image and install requirements, cache after
  2. Use cached image to run tests.

However, second job does not update the repo files according to the latest commit. How can we achieve that? I'm providing a minimal workflow below:

name: rpi4-armhf

on:
  push:
  pull_request:


jobs:
  build-cache-image:
    runs-on: ubuntu-latest
    if: ${{ false }}
    steps:
      - uses: actions/checkout@v4
        name: Checkout
      - uses: pguyot/arm-runner-action@HEAD
        name: build-image
        id: build_image
        with:
          cpu: cortex-a7
          base_image: https://downloads.raspberrypi.com/raspios_armhf/images/raspios_armhf-2022-09-26/2022-09-22-raspios-bullseye-armhf.img.xz
          image_additional_mb: 4096
          commands: |
               ...
      - name: Cache OS image
        uses: actions/cache@v3
        id: rpi4-bullseye-armhf

  unit-tests:
    runs-on: ubuntu-latest
    name: rpi4-armhf
    timeout-minutes: 35
    needs: [ build-cache-image ]
    if: ${{ !cancelled() }}
    steps:
      - name: Checkout
        uses: actions/checkout@v4

      - name: Restore cache
        uses: actions/cache/restore@v3

      - uses: pguyot/arm-runner-action@HEAD
        name: Install studio and test
        with:
          base_image: file://${{ runner.temp }}//rpi4-armhf.img
          cpu: cortex-a7
          image_additional_mb: 4096
          import_github_env: true
          commands: |
            python3 run_tests.py

issue: unexpected input(s) "user"

Hi @pguyot . Thank you for your awesome work on this github action.
For my use-case, I am trying to install the latest release of Raspberry Pi OS lite and download one of my repos from Github. So far, this action is doing it's work pretty well. Just a short info, the URL to the latest version of Raspberry Pi OS has changed. Maybe this could be updated?

For the next step, I am trying to create a new user, navigate to the home directory of the new user and clone the repo.
First I tried the user parameter, but this did not work:

Warning: Unexpected input(s) 'user', valid inputs are ['base_image', 'image_additional_mb', 'bind_mount_repository', 'cpu', 'cpu_info', 'commands', 'copy_artifact_path', 'copy_artifact_dest', 'copy_repository_path', 'optimize_image', 'use_systemd_nspawn', 'systemd_nspawn_options', 'bootpartition', 'rootpartition', 'shell', 'shell_package', 'exit_on_fail', 'debug', 'import_github_env', 'export_github_env']

I then tried to add a user with the useradd command, like this:

sudo useradd -p my-super-secure-password test

This works, but I cannot cd into the working directory of the user test:
warning: cannot change directory to /home/test: No such file or directory

I am testing the same setup on the same OS with an Raspberry Pi Zero W. But this seems to work fine. How can I navigate to the user "test's" home directory to clone a repo?

This is the full section of the code:

- name: run-tests-on-arm
  uses: pguyot/arm-runner-action@v2
  with:
    # Set the base_image to the desired Raspberry Pi OS version
    base_image: https://downloads.raspberrypi.org/raspios_lite_armhf/images/raspios_lite_armhf-2023-05-03/2023-05-03-raspios-bullseye-armhf-lite.img.xz
    image_additional_mb: 1500 # enlarge free space to 1.5 GB
    optimize_image: true
    user: test
    commands: |
      echo $PWD && ls
      sudo useradd -p my-super-secure-password test
      sudo usermod -a -G adm,dialout,cdrom,sudo,audio,video,plugdev,games,users,input,netdev,gpio,i2c,spi test
      su - test
      cd /home/test

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.