Unable to run x86-_64 workloads on Apple Silicon using Rosetta on a self-managed runner

Overview

Customer is trying to run x86-64 workloads on a self-managed runner installed on Apple Silicon but is running into an issue where the runner process does not see the $ARCH variable when starting the shell process.

Current setup

Customer tried adding a "special" /usr/local/bin/bash to the runner instance, which reacts on the environment variable ARCH=x86_64 to restart itself inside a Rosetta-enabled bash:


#include <unistd.h>
#include <stdlib.h>
#include <string.h>
int main(int argc, char** argv)
{
  char * arch = getenv("ARCH");
  if (arch && strcmp(arch, "x86_64") == 0) {
    char ** rosetta_argv = malloc(argc + 3);
    char ** rosetta_arg = rosetta_argv;
    *rosetta_arg++ = "/usr/bin/arch";
    *rosetta_arg++ = "-x86_64";
    *rosetta_arg++ = "/bin/bash";
    char** arg = argv + 1;
    while(*arg) *rosetta_arg++ = *arg++;
    *rosetta_arg = NULL;
    return execv("/usr/bin/arch", rosetta_argv);
  }
  argv[0] = "bash";
  return execv("/bin/bash", argv);
}

Locally, this allows to transparently run a shell script inside Rosetta, when the environment variable ARCH=x86_64 is set.

Having the GitLab runners registered with two tags:

  • macos-arm64:<release>
  • macos-x86_64:<release>

allows jobs to run like:


job:
  tags:
    - macos-${ARCH}:${MACOS}
  parallel:
    matrix:
      - ARCH: [arm64, x86_64]
        MACOS: <release>

Error

This configuration is not working. The runner process does not yet see the $ARCH variable when starting the shell process, instead the variable seems to be set by injecting an export statement into the script process itself.

support ticket

Edited by Darren Eastman