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

Add instructions for self-hosted NixOS runners #42

Open
lovesegfault opened this issue Oct 12, 2023 · 7 comments
Open

Add instructions for self-hosted NixOS runners #42

lovesegfault opened this issue Oct 12, 2023 · 7 comments

Comments

@lovesegfault
Copy link

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
@grahamc
Copy link
Member

grahamc commented Oct 12, 2023

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
Copy link
Author

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
Copy link
Member

grahamc commented Oct 12, 2023

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
Copy link
Author

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

@grahamc
Copy link
Member

grahamc commented Oct 12, 2023

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.

@lovesegfault
Copy link
Author

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

@Hoverbear
Copy link
Contributor

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:

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 up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants