Add instructions for self-hosted NixOS runners #42

Open
opened 2023-10-12 14:17:43 +00:00 by lovesegfault · 7 comments
lovesegfault commented 2023-10-12 14:17:43 +00:00 (Migrated from github.com)

I attempted the following:

  1. Set up a self-hosted runner on a NixOS host: services/github-runner.nix
  2. Changed by workflow to use that runner: https://github.com/lovesegfault/nix-config/pull/3052/files#diff-944291df2c9c06359d37cc8833d182d705c9e8c3108e7cfe132d61a06e9133ddR85-R86
  3. Kicked off CI: https://github.com/lovesegfault/nix-config/actions/runs/6496771196

But this action failed: https://github.com/lovesegfault/nix-config/actions/runs/6496771196/job/17644474420

I could just guard the action with an if, and expose the host's Nix to the runner, but I wanted to keep things identical to the GitHub-hosted runners, if at all possible.

Error

Error: 
   0: Executing `nix-installer` as `root` via `sudo`
   1: ENOENT: No such file or directory

Metadata

key value
version 0.13.1
os linux
arch x86_64
I attempted the following: 1. Set up a self-hosted runner on a NixOS host: [services/github-runner.nix](https://github.com/lovesegfault/nix-config/pull/3052/files#diff-45b44ff9871b30cf95c23e698ddf4d096c03fef49d783516218a672b0719ab21) 2. Changed by workflow to use that runner: https://github.com/lovesegfault/nix-config/pull/3052/files#diff-944291df2c9c06359d37cc8833d182d705c9e8c3108e7cfe132d61a06e9133ddR85-R86 3. Kicked off CI: https://github.com/lovesegfault/nix-config/actions/runs/6496771196 But this action failed: https://github.com/lovesegfault/nix-config/actions/runs/6496771196/job/17644474420 I could just guard the action with an `if`, and expose the host's Nix to the runner, but I wanted to keep things identical to the GitHub-hosted runners, if at all possible. ## Error ``` Error: 0: Executing `nix-installer` as `root` via `sudo` 1: ENOENT: No such file or directory ``` ## Metadata |key|value| |--|--| |**version**|0.13.1| |**os**|linux| |**arch**|x86_64|
grahamc commented 2023-10-12 14:23:05 +00:00 (Migrated from github.com)

I understand you want to keep your actions the same, and presumably you don't actually want our installer to install Nix. Despite that, can you check to see if sudo is installed and in your runner's PATH?

Next... what behavior would you like and expect out of this action when Nix is already installed / you're already on NixOS?

I understand you want to keep your actions the same, and presumably you don't actually want our installer to install Nix. Despite that, can you check to see if `sudo` is installed and in your runner's PATH? Next... what behavior would you like and expect out of this action when Nix is already installed / you're already on NixOS?
lovesegfault commented 2023-10-12 14:28:48 +00:00 (Migrated from github.com)

I think what I'm asking for might be either impossible or unwise without placing the runner inside a container.

I tried just adding nix to the runner PATH, but the action still fails: https://github.com/lovesegfault/nix-config/actions/runs/6496992160/job/17645257639

What about making the action check whether Nix is already installed/available, and do nothing in that case?

I think what I'm asking for might be either impossible or unwise without placing the runner inside a container. I tried just adding `nix` to the runner PATH, but the action still fails: https://github.com/lovesegfault/nix-config/actions/runs/6496992160/job/17645257639 What about making the action check whether Nix is already installed/available, and do nothing in that case?
grahamc commented 2023-10-12 14:32:34 +00:00 (Migrated from github.com)

Ah, so it is trying to run sudo. Specifically the one from security wrappers which is setuid. I'll check with the team and see what is reasonable!

Ah, so it is trying to run `sudo`. Specifically the one from security wrappers which is setuid. I'll check with the team and see what is reasonable!
lovesegfault commented 2023-10-12 14:33:33 +00:00 (Migrated from github.com)

Sounds good, please redeem this beer ticket next time we meet: 🎟️

Sounds good, please redeem this beer ticket next time we meet: 🎟️
grahamc commented 2023-10-12 14:36:12 +00:00 (Migrated from github.com)

So we've done some work already to detect an existing Nix install, but it is really only looking for a Nix installed by the Determinate Nix Installer:

  async detect_existing(): Promise<boolean> {
    const receipt_path = "/nix/receipt.json";
    try {
      await access(receipt_path);
      // There is a /nix/receipt.json
      return true;
    } catch {
      // No /nix/receipt.json
      return false;
    }
  }

I think we could add a second check there, like look to see if you're on NixOS or if the nix binary is in your PATH. If we do this we should also check to see if flakes are enabled or not, and emit a warning about it if they aren't.

So we've done some work already to detect an existing Nix install, but it is really only looking for a Nix installed by the Determinate Nix Installer: ```ts async detect_existing(): Promise<boolean> { const receipt_path = "/nix/receipt.json"; try { await access(receipt_path); // There is a /nix/receipt.json return true; } catch { // No /nix/receipt.json return false; } } ``` I think we could add a second check there, like look to see if you're on NixOS or if the `nix` binary is in your PATH. If we do this we should also check to see if flakes are enabled or not, and emit a warning about it if they aren't.
lovesegfault commented 2023-10-12 14:55:40 +00:00 (Migrated from github.com)

That sounds good, I guess checking whether things are enabled is just nix show-config and then looking at the experimental-features key.

That sounds good, I guess checking whether things are enabled is just `nix show-config` and then looking at the `experimental-features` key.
Hoverbear commented 2023-10-23 20:48:01 +00:00 (Migrated from github.com)

I believe there are two issues at play here. I'm going to try to tease them apart.

Issue 1: Installer requires sudo

I'm trying to read between the lines of this issue and it appears you are unwilling or unable to give the runner user sudo access.

Github Actions, according to it's documentation, conventionally has passwordless sudo access. Actions are generally allowed to have this expectation:

The Linux and macOS virtual machines both run using passwordless sudo. When you need to execute commands or install tools that require more privileges than the current user, you can use sudo without needing to provide a password.

Since your runner does not appear to conform to this, it is likely you'll experience issues with some other actions as well. I do not think this represents a bug in the nix-installer or this action. All our supported Nix install methods require root and check for it quite early.

My suggestion here is to do something like:

on:
  pull_request:
  push:
    branches: [main]

jobs:
  lints:
    name: Build
    runs-on: ubuntu-22.04
    steps:
      - uses: actions/checkout@v3
      - if: ${{ runner.name != 'my-nixos-box-hostname' }}
        name: Install Nix
        uses: DeterminateSystems/nix-installer-action@main
      - name: Run `nix build`
        run: nix build .

Alternatively you could set some environment in the runner user and check that (eg NIXOS=true).

Even if you did add sudo the nix-installer would fail on NixOS. (See issue 2)

Issue 2: Installer will exit with failure on NixOS

Normally the installer (on the ostree and linux plans) will validate that it is not running on NixOS and error if it is:

c79dcb91ae/src/planner/linux.rs (L174-L180)

We could consider creating a nixos planner however it would be difficult to define what exactly that did. Many modern flakes-only systems do not actually contain a configuration.nix or similar, and editing NixOS definitions that may be part of some flake is of considerable complexity.

As Graham mentioned, in this case it may be easier for the action to detect it's running on NixOS and essentially do a noop.

I believe there are two issues at play here. I'm going to try to tease them apart. # Issue 1: Installer requires `sudo` I'm trying to read between the lines of this issue and it appears you are unwilling or unable to give the `runner` user `sudo` access. Github Actions, according to it's [documentation](https://docs.github.com/en/actions/using-github-hosted-runners/about-github-hosted-runners/about-github-hosted-runners#administrative-privileges), conventionally has passwordless `sudo` access. Actions are generally allowed to have this expectation: > The Linux and macOS virtual machines both run using passwordless sudo. When you need to execute commands or install tools that require more privileges than the current user, you can use sudo without needing to provide a password. Since your runner **does not appear to conform to this**, it is likely you'll experience issues with some other actions as well. I do not think this represents a bug in the `nix-installer` or this action. All our supported Nix install methods require `root` and check for it quite early. My suggestion here is to do something like: ```yaml on: pull_request: push: branches: [main] jobs: lints: name: Build runs-on: ubuntu-22.04 steps: - uses: actions/checkout@v3 - if: ${{ runner.name != 'my-nixos-box-hostname' }} name: Install Nix uses: DeterminateSystems/nix-installer-action@main - name: Run `nix build` run: nix build . ``` Alternatively you could set some environment in the `runner` user and check that (eg `NIXOS=true`). - https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#jobsjob_idstepsif - https://docs.github.com/en/actions/learn-github-actions/contexts#runner-context Even if you did add `sudo` the `nix-installer` would fail on NixOS. (See issue 2) # Issue 2: Installer will exit with failure on NixOS Normally the installer (on the `ostree` and `linux` plans) will validate that it is not running on NixOS and error if it is: https://github.com/DeterminateSystems/nix-installer/blob/c79dcb91aea8da32f5c982e8d366846d26035829/src/planner/linux.rs#L174-L180 We could consider creating a `nixos` planner however it would be difficult to define what exactly that did. Many modern flakes-only systems do not actually contain a `configuration.nix` or similar, and editing NixOS definitions that may be part of some flake is of considerable complexity. As Graham mentioned, in this case it may be easier for the action to detect it's running on NixOS and essentially do a noop.
Sign in to join this conversation.
No labels
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference: lix-project/lix-install-action#42
No description provided.