Compare commits
5 Commits
v7
...
colemickens/debug
| Author | SHA1 | Date | |
|---|---|---|---|
| 46001031de | |||
| 19c5492b89 | |||
| cd46bde16a | |||
| 84fe9e450f | |||
| 07b8bcba1b |
@@ -0,0 +1,2 @@
|
||||
dist/* linguist-generated=true
|
||||
|
||||
@@ -18,9 +18,19 @@ jobs:
|
||||
- run: test $(git status --porcelain=v1 2>/dev/null | wc -l) -eq 0
|
||||
run-x86_64-linux:
|
||||
name: Run x86_64 Linux
|
||||
runs-on: ubuntu-22.04
|
||||
strategy:
|
||||
matrix:
|
||||
runner:
|
||||
- ubuntu-latest
|
||||
- nscloud-ubuntu-22.04-amd64-4x16
|
||||
- namespace-profile-default-arm64
|
||||
runs-on: ${{ matrix.runner }}
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- name: Sanity Checls
|
||||
run: |
|
||||
set -x
|
||||
uname -a
|
||||
- name: Install Nix
|
||||
uses: ./
|
||||
with:
|
||||
|
||||
@@ -1,6 +1,22 @@
|
||||
# Nix Installer Action
|
||||
# The Determinate Nix Installer Action
|
||||
|
||||
You can use [`nix-installer`](https://github.com/DeterminateSystems/nix-installer) as a Github action like so:
|
||||
Based on the [Determinate Nix Installer](https://github.com/DeterminateSystems/nix-installer), responsible for over tens of thousands of Nix installs daily.
|
||||
The fast, friendly, and reliable GitHub Action to install Nix with Flakes.
|
||||
|
||||
## Supports
|
||||
|
||||
* ✅ **Accelerated KVM** on open source projects and larger runners. See [GitHub's announcement](https://github.blog/changelog/2023-02-23-hardware-accelerated-android-virtualization-on-actions-windows-and-linux-larger-hosted-runners/) for more info.
|
||||
* ✅ Linux, x86_64, aarch64, and i686
|
||||
* ✅ macOS, x86_64 and aarch64
|
||||
* ✅ WSL2, x86_64 and aarch64
|
||||
* ✅ Containers
|
||||
* ✅ Valve's SteamOS
|
||||
* ✅ GitHub Enterprise Server
|
||||
* ✅ GitHub Hosted, self-hosted, and long running Actions Runners
|
||||
|
||||
|
||||
|
||||
## Usage
|
||||
|
||||
```yaml
|
||||
on:
|
||||
@@ -11,18 +27,16 @@ on:
|
||||
jobs:
|
||||
lints:
|
||||
name: Build
|
||||
runs-on: ubuntu-22.04
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- name: Install Nix
|
||||
uses: DeterminateSystems/nix-installer-action@main
|
||||
- name: Run `nix build`
|
||||
run: nix build .
|
||||
- uses: DeterminateSystems/nix-installer-action@main
|
||||
- run: nix build .
|
||||
```
|
||||
|
||||
See [`.github/workflows/ci.yml`](.github/workflows/ci.yml) for a full example.
|
||||
### With FlakeHub
|
||||
|
||||
To use private flakes from FlakeHub, use a configuration like this:
|
||||
To fetch private flakes from FlakeHub, update the `permissions` block and pass `flakehub: true`:
|
||||
|
||||
```yaml
|
||||
on:
|
||||
@@ -33,56 +47,81 @@ on:
|
||||
jobs:
|
||||
lints:
|
||||
name: Build
|
||||
runs-on: ubuntu-22.04
|
||||
runs-on: ubuntu-latest
|
||||
permissions:
|
||||
id-token: "write"
|
||||
contents: "read"
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- name: Install Nix
|
||||
uses: DeterminateSystems/nix-installer-action@main
|
||||
- uses: DeterminateSystems/nix-installer-action@main
|
||||
with:
|
||||
flakehub: true
|
||||
- name: Run `nix build`
|
||||
run: nix build .
|
||||
- run: nix build .
|
||||
```
|
||||
|
||||
See [`.github/workflows/ci.yml`](.github/workflows/ci.yml) for a full example.
|
||||
|
||||
### Advanced Usage
|
||||
|
||||
* If KVM is available, the installer sets up KVM so that Nix can use it ,and exports the `DETERMINATE_NIX_KVM` environment variable set to 1.
|
||||
If KVM is not available, `DETERMINATE_NIX_KVM` is set to 0.
|
||||
This can be used in combination with GitHub Actions' `if` syntax for turning on and off steps.
|
||||
|
||||
## Installation Differences
|
||||
|
||||
Differing from the upstream [Nix](https://github.com/NixOS/nix) installer scripts:
|
||||
|
||||
* In `nix.conf`:
|
||||
+ the `nix-command` and `flakes` features are enabled
|
||||
+ `bash-prompt-prefix` is set
|
||||
+ `auto-optimise-store` is set to `true` (On Linux only)
|
||||
* `extra-nix-path` is set to `nixpkgs=flake:nixpkgs`
|
||||
* `max-jobs` is set to `auto`
|
||||
* KVM is enabled by default.
|
||||
* an installation receipt (for uninstalling) is stored at `/nix/receipt.json` as well as a copy of the install binary at `/nix/nix-installer`
|
||||
* `nix-channel --update` is not run, `~/.nix-channels` is not provisioned
|
||||
* `ssl-cert-file` is set in `/etc/nix/nix.conf` if the `ssl-cert-file` argument is used.
|
||||
|
||||
|
||||
## Configuration
|
||||
|
||||
| Parameter | Description | Type | Default |
|
||||
| :----------------------- | :---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | :----------------------------------------- | :--------------------------------------------------- |
|
||||
| `backtrace` | The setting for [`RUST_BACKTRACE`][backtrace] | string | |
|
||||
| `extra-args` | Extra arguments to pass to the planner (prefer using structured `with:` arguments unless using a custom [planner]!) | string | |
|
||||
| `extra-conf` | Extra configuration lines for `/etc/nix/nix.conf` (includes `access-tokens` with `secrets.GITHUB_TOKEN` automatically if `github-token` is set) | string | |
|
||||
| `flakehub` | Log in to FlakeHub to pull private flakes using the GitHub Actions [JSON Web Token](https://jwt.io) (JWT), which is bound to the `api.flakehub.com` audience. | Boolean | `false` |
|
||||
| `github-token` | A [GitHub token] for making authenticated requests (which have a higher rate-limit quota than unauthenticated requests) | string | `${{ github.token }}` |
|
||||
| `init` | The init system to configure (requires `planner: linux-multi`) | enum (`none` or `systemd`) | |
|
||||
| `local-root` | A local `nix-installer` binary root. Overrides the `nix-installer-url` setting (a `nix-installer.sh` should exist, binaries should be named `nix-installer-$ARCH`, eg. `nix-installer-x86_64-linux`). | Boolean | `false` |
|
||||
| `log-directives` | A list of [tracing directives], comma separated with `-`s replaced with `_` (eg. `nix_installer=trace`) | string | |
|
||||
| `logger` | The logger to use during installation | enum (`pretty`, `json`, `full`, `compact`) | |
|
||||
| `mac-case-sensitive` | Use a case-sensitive volume (`planner: macos` only) | Boolean | `false` |
|
||||
| `mac-encrypt` | Force encryption on the volume (`planner: macos` only) | Boolean | `false` |
|
||||
| `mac-root-disk` | The root disk of the target (`planner: macos` only) | string | |
|
||||
| `mac-volume-label` | The label for the created [APFS] volume (`planner: macos` only) | string | |
|
||||
| `modify-profile` | Modify the user [profile] to automatically load Nix | Boolean | `false` |
|
||||
| `nix-build-group-id` | The Nix build group GID | integer | |
|
||||
| `nix-build-group-name` | The Nix build group name | string | |
|
||||
| `nix-build-user-base` | The Nix build user base UID (ascending) | integer | |
|
||||
| `nix-build-user-count` | The number of build users to create | integer | 32 |
|
||||
| `nix-build-user-prefix` | The Nix build user prefix (user numbers will be postfixed) | string | |
|
||||
| `nix-installer-branch` | The branch of `nix-installer` to use (conflicts with the `nix-installer-tag`, `nix-installer-revision`, and `nix-installer-branch`) | string | |
|
||||
| `nix-installer-pr` | The pull request of `nix-installer` to use (conflicts with `nix-installer-tag`, `nix-installer-revision`, and `nix-installer-branch`) | integer | |
|
||||
| `nix-installer-revision` | The revision of `nix-installer` to use (conflicts with `nix-installer-tag`, `nix-installer-branch`, and `nix-installer-pr`) | string | |
|
||||
| `nix-installer-tag` | The tag of `nix-installer` to use (conflicts with `nix-installer-revision`, `nix-installer-branch`, `nix-installer-pr`) | string | |
|
||||
| `nix-installer-url` | A URL pointing to a `nix-installer.sh` script | URL | `https://install.determinate.systems/nix` |
|
||||
| `nix-package-url` | The Nix package URL | URL | |
|
||||
| `planner` | The installation [planner] to use | enum (`linux` or `macos`) | |
|
||||
| `reinstall` | Force a reinstall if an existing installation is detected (consider backing up `/nix/store`) | Boolean | `false` |
|
||||
| `start-daemon` | If the daemon should be started, requires `planner: linux-multi` | Boolean | `false` |
|
||||
| `trust-runner-user` | Whether to make the runner user trusted by the Nix daemon | Boolean | `true` |
|
||||
| `diagnostic-endpoint` | Diagnostic endpoint url where the installer sends install [diagnostic reports](https://github.com/DeterminateSystems/nix-installer#diagnostics) to, to disable set this to an empty string | string | `https://install.determinate.systems/nix/diagnostic` |
|
||||
| `proxy` | The proxy to use (if any), valid proxy bases are `https://$URL`, `http://$URL` and `socks5://$URL` | string | |
|
||||
| `ssl-cert-file` | An SSL cert to use (if any), used for fetching Nix and sets `NIX_SSL_CERT_FILE` for Nix | string | |
|
||||
| Parameter | Description | Type | Default |
|
||||
| :----------------------- | :----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | :----------------------------------------- | :--------------------------------------------------- |
|
||||
| `backtrace` | The setting for [`RUST_BACKTRACE`][backtrace] | string | |
|
||||
| `extra-args` | Extra arguments to pass to the planner (prefer using structured `with:` arguments unless using a custom [planner]!) | string | |
|
||||
| `extra-conf` | Extra configuration lines for `/etc/nix/nix.conf` (includes `access-tokens` with `secrets.GITHUB_TOKEN` automatically if `github-token` is set) | string | |
|
||||
| `flakehub` | Log in to FlakeHub to pull private flakes using the GitHub Actions [JSON Web Token](https://jwt.io) (JWT), which is bound to the `api.flakehub.com` audience. | Boolean | `false` |
|
||||
| `force-docker-shim` | Force the use of Docker as a process supervisor. This setting is automatically enabled when necessary. | Boolean | `false` |
|
||||
| `github-token` | A [GitHub token] for making authenticated requests (which have a higher rate-limit quota than unauthenticated requests) | string | `${{ github.token }}` |
|
||||
| `github-server-url` | The URL for the GitHub server, to use with the `github-token` token. Defaults to the current GitHub server, supporting GitHub Enterprise Server automatically. Only change this value if the provided `github-token` is for a different GitHub server than the current server. | string | `${{ github.server }}` |
|
||||
| `init` | The init system to configure (requires `planner: linux-multi`) | enum (`none` or `systemd`) | |
|
||||
| `kvm` | Automatically configure the GitHub Actions Runner for NixOS test support, if the host supports it. | Boolean | `true` |
|
||||
| `local-root` | A local `nix-installer` binary root. Overrides the `nix-installer-url` setting (a `nix-installer.sh` should exist, binaries should be named `nix-installer-$ARCH`, eg. `nix-installer-x86_64-linux`). | Boolean | `false` |
|
||||
| `log-directives` | A list of [tracing directives], comma separated with `-`s replaced with `_` (eg. `nix_installer=trace`) | string | |
|
||||
| `logger` | The logger to use during installation | enum (`pretty`, `json`, `full`, `compact`) | |
|
||||
| `mac-case-sensitive` | Use a case-sensitive volume (`planner: macos` only) | Boolean | `false` |
|
||||
| `mac-encrypt` | Force encryption on the volume (`planner: macos` only) | Boolean | `false` |
|
||||
| `mac-root-disk` | The root disk of the target (`planner: macos` only) | string | |
|
||||
| `mac-volume-label` | The label for the created [APFS] volume (`planner: macos` only) | string | |
|
||||
| `modify-profile` | Modify the user [profile] to automatically load Nix | Boolean | `false` |
|
||||
| `nix-build-group-id` | The Nix build group GID | integer | |
|
||||
| `nix-build-group-name` | The Nix build group name | string | |
|
||||
| `nix-build-user-base` | The Nix build user base UID (ascending) | integer | |
|
||||
| `nix-build-user-count` | The number of build users to create | integer | 32 |
|
||||
| `nix-build-user-prefix` | The Nix build user prefix (user numbers will be postfixed) | string | |
|
||||
| `nix-installer-branch` | The branch of `nix-installer` to use (conflicts with the `nix-installer-tag`, `nix-installer-revision`, and `nix-installer-branch`) | string | |
|
||||
| `nix-installer-pr` | The pull request of `nix-installer` to use (conflicts with `nix-installer-tag`, `nix-installer-revision`, and `nix-installer-branch`) | integer | |
|
||||
| `nix-installer-revision` | The revision of `nix-installer` to use (conflicts with `nix-installer-tag`, `nix-installer-branch`, and `nix-installer-pr`) | string | |
|
||||
| `nix-installer-tag` | The tag of `nix-installer` to use (conflicts with `nix-installer-revision`, `nix-installer-branch`, `nix-installer-pr`) | string | |
|
||||
| `nix-installer-url` | A URL pointing to a `nix-installer.sh` script | URL | `https://install.determinate.systems/nix` |
|
||||
| `nix-package-url` | The Nix package URL | URL | |
|
||||
| `planner` | The installation [planner] to use | enum (`linux` or `macos`) | |
|
||||
| `reinstall` | Force a reinstall if an existing installation is detected (consider backing up `/nix/store`) | Boolean | `false` |
|
||||
| `start-daemon` | If the daemon should be started, requires `planner: linux-multi` | Boolean | `false` |
|
||||
| `trust-runner-user` | Whether to make the runner user trusted by the Nix daemon | Boolean | `true` |
|
||||
| `diagnostic-endpoint` | Diagnostic endpoint url where the installer sends install [diagnostic reports](https://github.com/DeterminateSystems/nix-installer#diagnostics) to, to disable set this to an empty string | string | `https://install.determinate.systems/nix/diagnostic` |
|
||||
| `proxy` | The proxy to use (if any), valid proxy bases are `https://$URL`, `http://$URL` and `socks5://$URL` | string | |
|
||||
| `ssl-cert-file` | An SSL cert to use (if any), used for fetching Nix and sets `NIX_SSL_CERT_FILE` for Nix | string | |
|
||||
|
||||
[apfs]: https://en.wikipedia.org/wiki/Apple_File_System
|
||||
[backtrace]: https://doc.rust-lang.org/std/backtrace/index.html#environment-variables
|
||||
|
||||
+14
-1
@@ -17,12 +17,22 @@ inputs:
|
||||
description: Automatically log in to your [FlakeHub](https://flakehub.com) account, for accessing private flakes.
|
||||
required: false
|
||||
default: false
|
||||
force-docker-shim:
|
||||
description: Force the use of Docker as a process supervisor. This setting is automatically enabled when necessary.
|
||||
default: false
|
||||
github-token:
|
||||
description: A GitHub token for making authenticated requests (which have a higher rate-limit quota than unauthenticated requests)
|
||||
default: ${{ github.token }}
|
||||
github-server-url:
|
||||
description: The URL for the GitHub server, to use with the `github-token` token. Defaults to the current GitHub server, supporting GitHub Enterprise Server automatically. Only change this value if the provided `github-token` is for a different GitHub server than the current server.
|
||||
default: ${{ github.server_url }}
|
||||
init:
|
||||
description: "The init system to configure, requires `planner: linux-multi` (allowing the choice between `none` or `systemd`)"
|
||||
required: false
|
||||
kvm:
|
||||
description: Automatically configure the GitHub Actions Runner for NixOS test supports, if the host supports it.
|
||||
required: false
|
||||
default: true
|
||||
local-root:
|
||||
description: A local `nix-installer` binary root, overrides any settings which change the `nix-installer` used (binaries should be named `nix-installer-$ARCH-$OS`, eg. `nix-installer-x86_64-linux`)
|
||||
required: false
|
||||
@@ -107,5 +117,8 @@ inputs:
|
||||
|
||||
runs:
|
||||
using: "node20"
|
||||
env:
|
||||
UV_USE_IO_URING: 0
|
||||
main: 'dist/index.js'
|
||||
post: 'dist/index.js'
|
||||
post: 'dist/index.js'
|
||||
|
||||
|
||||
-453
@@ -1,453 +0,0 @@
|
||||
"use strict";
|
||||
exports.id = 37;
|
||||
exports.ids = [37];
|
||||
exports.modules = {
|
||||
|
||||
/***/ 4037:
|
||||
/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => {
|
||||
|
||||
__webpack_require__.r(__webpack_exports__);
|
||||
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
|
||||
/* harmony export */ "toFormData": () => (/* binding */ toFormData)
|
||||
/* harmony export */ });
|
||||
/* harmony import */ var fetch_blob_from_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(2185);
|
||||
/* harmony import */ var formdata_polyfill_esm_min_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(8010);
|
||||
|
||||
|
||||
|
||||
let s = 0;
|
||||
const S = {
|
||||
START_BOUNDARY: s++,
|
||||
HEADER_FIELD_START: s++,
|
||||
HEADER_FIELD: s++,
|
||||
HEADER_VALUE_START: s++,
|
||||
HEADER_VALUE: s++,
|
||||
HEADER_VALUE_ALMOST_DONE: s++,
|
||||
HEADERS_ALMOST_DONE: s++,
|
||||
PART_DATA_START: s++,
|
||||
PART_DATA: s++,
|
||||
END: s++
|
||||
};
|
||||
|
||||
let f = 1;
|
||||
const F = {
|
||||
PART_BOUNDARY: f,
|
||||
LAST_BOUNDARY: f *= 2
|
||||
};
|
||||
|
||||
const LF = 10;
|
||||
const CR = 13;
|
||||
const SPACE = 32;
|
||||
const HYPHEN = 45;
|
||||
const COLON = 58;
|
||||
const A = 97;
|
||||
const Z = 122;
|
||||
|
||||
const lower = c => c | 0x20;
|
||||
|
||||
const noop = () => {};
|
||||
|
||||
class MultipartParser {
|
||||
/**
|
||||
* @param {string} boundary
|
||||
*/
|
||||
constructor(boundary) {
|
||||
this.index = 0;
|
||||
this.flags = 0;
|
||||
|
||||
this.onHeaderEnd = noop;
|
||||
this.onHeaderField = noop;
|
||||
this.onHeadersEnd = noop;
|
||||
this.onHeaderValue = noop;
|
||||
this.onPartBegin = noop;
|
||||
this.onPartData = noop;
|
||||
this.onPartEnd = noop;
|
||||
|
||||
this.boundaryChars = {};
|
||||
|
||||
boundary = '\r\n--' + boundary;
|
||||
const ui8a = new Uint8Array(boundary.length);
|
||||
for (let i = 0; i < boundary.length; i++) {
|
||||
ui8a[i] = boundary.charCodeAt(i);
|
||||
this.boundaryChars[ui8a[i]] = true;
|
||||
}
|
||||
|
||||
this.boundary = ui8a;
|
||||
this.lookbehind = new Uint8Array(this.boundary.length + 8);
|
||||
this.state = S.START_BOUNDARY;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {Uint8Array} data
|
||||
*/
|
||||
write(data) {
|
||||
let i = 0;
|
||||
const length_ = data.length;
|
||||
let previousIndex = this.index;
|
||||
let {lookbehind, boundary, boundaryChars, index, state, flags} = this;
|
||||
const boundaryLength = this.boundary.length;
|
||||
const boundaryEnd = boundaryLength - 1;
|
||||
const bufferLength = data.length;
|
||||
let c;
|
||||
let cl;
|
||||
|
||||
const mark = name => {
|
||||
this[name + 'Mark'] = i;
|
||||
};
|
||||
|
||||
const clear = name => {
|
||||
delete this[name + 'Mark'];
|
||||
};
|
||||
|
||||
const callback = (callbackSymbol, start, end, ui8a) => {
|
||||
if (start === undefined || start !== end) {
|
||||
this[callbackSymbol](ui8a && ui8a.subarray(start, end));
|
||||
}
|
||||
};
|
||||
|
||||
const dataCallback = (name, clear) => {
|
||||
const markSymbol = name + 'Mark';
|
||||
if (!(markSymbol in this)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (clear) {
|
||||
callback(name, this[markSymbol], i, data);
|
||||
delete this[markSymbol];
|
||||
} else {
|
||||
callback(name, this[markSymbol], data.length, data);
|
||||
this[markSymbol] = 0;
|
||||
}
|
||||
};
|
||||
|
||||
for (i = 0; i < length_; i++) {
|
||||
c = data[i];
|
||||
|
||||
switch (state) {
|
||||
case S.START_BOUNDARY:
|
||||
if (index === boundary.length - 2) {
|
||||
if (c === HYPHEN) {
|
||||
flags |= F.LAST_BOUNDARY;
|
||||
} else if (c !== CR) {
|
||||
return;
|
||||
}
|
||||
|
||||
index++;
|
||||
break;
|
||||
} else if (index - 1 === boundary.length - 2) {
|
||||
if (flags & F.LAST_BOUNDARY && c === HYPHEN) {
|
||||
state = S.END;
|
||||
flags = 0;
|
||||
} else if (!(flags & F.LAST_BOUNDARY) && c === LF) {
|
||||
index = 0;
|
||||
callback('onPartBegin');
|
||||
state = S.HEADER_FIELD_START;
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
if (c !== boundary[index + 2]) {
|
||||
index = -2;
|
||||
}
|
||||
|
||||
if (c === boundary[index + 2]) {
|
||||
index++;
|
||||
}
|
||||
|
||||
break;
|
||||
case S.HEADER_FIELD_START:
|
||||
state = S.HEADER_FIELD;
|
||||
mark('onHeaderField');
|
||||
index = 0;
|
||||
// falls through
|
||||
case S.HEADER_FIELD:
|
||||
if (c === CR) {
|
||||
clear('onHeaderField');
|
||||
state = S.HEADERS_ALMOST_DONE;
|
||||
break;
|
||||
}
|
||||
|
||||
index++;
|
||||
if (c === HYPHEN) {
|
||||
break;
|
||||
}
|
||||
|
||||
if (c === COLON) {
|
||||
if (index === 1) {
|
||||
// empty header field
|
||||
return;
|
||||
}
|
||||
|
||||
dataCallback('onHeaderField', true);
|
||||
state = S.HEADER_VALUE_START;
|
||||
break;
|
||||
}
|
||||
|
||||
cl = lower(c);
|
||||
if (cl < A || cl > Z) {
|
||||
return;
|
||||
}
|
||||
|
||||
break;
|
||||
case S.HEADER_VALUE_START:
|
||||
if (c === SPACE) {
|
||||
break;
|
||||
}
|
||||
|
||||
mark('onHeaderValue');
|
||||
state = S.HEADER_VALUE;
|
||||
// falls through
|
||||
case S.HEADER_VALUE:
|
||||
if (c === CR) {
|
||||
dataCallback('onHeaderValue', true);
|
||||
callback('onHeaderEnd');
|
||||
state = S.HEADER_VALUE_ALMOST_DONE;
|
||||
}
|
||||
|
||||
break;
|
||||
case S.HEADER_VALUE_ALMOST_DONE:
|
||||
if (c !== LF) {
|
||||
return;
|
||||
}
|
||||
|
||||
state = S.HEADER_FIELD_START;
|
||||
break;
|
||||
case S.HEADERS_ALMOST_DONE:
|
||||
if (c !== LF) {
|
||||
return;
|
||||
}
|
||||
|
||||
callback('onHeadersEnd');
|
||||
state = S.PART_DATA_START;
|
||||
break;
|
||||
case S.PART_DATA_START:
|
||||
state = S.PART_DATA;
|
||||
mark('onPartData');
|
||||
// falls through
|
||||
case S.PART_DATA:
|
||||
previousIndex = index;
|
||||
|
||||
if (index === 0) {
|
||||
// boyer-moore derrived algorithm to safely skip non-boundary data
|
||||
i += boundaryEnd;
|
||||
while (i < bufferLength && !(data[i] in boundaryChars)) {
|
||||
i += boundaryLength;
|
||||
}
|
||||
|
||||
i -= boundaryEnd;
|
||||
c = data[i];
|
||||
}
|
||||
|
||||
if (index < boundary.length) {
|
||||
if (boundary[index] === c) {
|
||||
if (index === 0) {
|
||||
dataCallback('onPartData', true);
|
||||
}
|
||||
|
||||
index++;
|
||||
} else {
|
||||
index = 0;
|
||||
}
|
||||
} else if (index === boundary.length) {
|
||||
index++;
|
||||
if (c === CR) {
|
||||
// CR = part boundary
|
||||
flags |= F.PART_BOUNDARY;
|
||||
} else if (c === HYPHEN) {
|
||||
// HYPHEN = end boundary
|
||||
flags |= F.LAST_BOUNDARY;
|
||||
} else {
|
||||
index = 0;
|
||||
}
|
||||
} else if (index - 1 === boundary.length) {
|
||||
if (flags & F.PART_BOUNDARY) {
|
||||
index = 0;
|
||||
if (c === LF) {
|
||||
// unset the PART_BOUNDARY flag
|
||||
flags &= ~F.PART_BOUNDARY;
|
||||
callback('onPartEnd');
|
||||
callback('onPartBegin');
|
||||
state = S.HEADER_FIELD_START;
|
||||
break;
|
||||
}
|
||||
} else if (flags & F.LAST_BOUNDARY) {
|
||||
if (c === HYPHEN) {
|
||||
callback('onPartEnd');
|
||||
state = S.END;
|
||||
flags = 0;
|
||||
} else {
|
||||
index = 0;
|
||||
}
|
||||
} else {
|
||||
index = 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (index > 0) {
|
||||
// when matching a possible boundary, keep a lookbehind reference
|
||||
// in case it turns out to be a false lead
|
||||
lookbehind[index - 1] = c;
|
||||
} else if (previousIndex > 0) {
|
||||
// if our boundary turned out to be rubbish, the captured lookbehind
|
||||
// belongs to partData
|
||||
const _lookbehind = new Uint8Array(lookbehind.buffer, lookbehind.byteOffset, lookbehind.byteLength);
|
||||
callback('onPartData', 0, previousIndex, _lookbehind);
|
||||
previousIndex = 0;
|
||||
mark('onPartData');
|
||||
|
||||
// reconsider the current character even so it interrupted the sequence
|
||||
// it could be the beginning of a new sequence
|
||||
i--;
|
||||
}
|
||||
|
||||
break;
|
||||
case S.END:
|
||||
break;
|
||||
default:
|
||||
throw new Error(`Unexpected state entered: ${state}`);
|
||||
}
|
||||
}
|
||||
|
||||
dataCallback('onHeaderField');
|
||||
dataCallback('onHeaderValue');
|
||||
dataCallback('onPartData');
|
||||
|
||||
// Update properties for the next call
|
||||
this.index = index;
|
||||
this.state = state;
|
||||
this.flags = flags;
|
||||
}
|
||||
|
||||
end() {
|
||||
if ((this.state === S.HEADER_FIELD_START && this.index === 0) ||
|
||||
(this.state === S.PART_DATA && this.index === this.boundary.length)) {
|
||||
this.onPartEnd();
|
||||
} else if (this.state !== S.END) {
|
||||
throw new Error('MultipartParser.end(): stream ended unexpectedly');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function _fileName(headerValue) {
|
||||
// matches either a quoted-string or a token (RFC 2616 section 19.5.1)
|
||||
const m = headerValue.match(/\bfilename=("(.*?)"|([^()<>@,;:\\"/[\]?={}\s\t]+))($|;\s)/i);
|
||||
if (!m) {
|
||||
return;
|
||||
}
|
||||
|
||||
const match = m[2] || m[3] || '';
|
||||
let filename = match.slice(match.lastIndexOf('\\') + 1);
|
||||
filename = filename.replace(/%22/g, '"');
|
||||
filename = filename.replace(/&#(\d{4});/g, (m, code) => {
|
||||
return String.fromCharCode(code);
|
||||
});
|
||||
return filename;
|
||||
}
|
||||
|
||||
async function toFormData(Body, ct) {
|
||||
if (!/multipart/i.test(ct)) {
|
||||
throw new TypeError('Failed to fetch');
|
||||
}
|
||||
|
||||
const m = ct.match(/boundary=(?:"([^"]+)"|([^;]+))/i);
|
||||
|
||||
if (!m) {
|
||||
throw new TypeError('no or bad content-type header, no multipart boundary');
|
||||
}
|
||||
|
||||
const parser = new MultipartParser(m[1] || m[2]);
|
||||
|
||||
let headerField;
|
||||
let headerValue;
|
||||
let entryValue;
|
||||
let entryName;
|
||||
let contentType;
|
||||
let filename;
|
||||
const entryChunks = [];
|
||||
const formData = new formdata_polyfill_esm_min_js__WEBPACK_IMPORTED_MODULE_1__/* .FormData */ .Ct();
|
||||
|
||||
const onPartData = ui8a => {
|
||||
entryValue += decoder.decode(ui8a, {stream: true});
|
||||
};
|
||||
|
||||
const appendToFile = ui8a => {
|
||||
entryChunks.push(ui8a);
|
||||
};
|
||||
|
||||
const appendFileToFormData = () => {
|
||||
const file = new fetch_blob_from_js__WEBPACK_IMPORTED_MODULE_0__/* .File */ .$B(entryChunks, filename, {type: contentType});
|
||||
formData.append(entryName, file);
|
||||
};
|
||||
|
||||
const appendEntryToFormData = () => {
|
||||
formData.append(entryName, entryValue);
|
||||
};
|
||||
|
||||
const decoder = new TextDecoder('utf-8');
|
||||
decoder.decode();
|
||||
|
||||
parser.onPartBegin = function () {
|
||||
parser.onPartData = onPartData;
|
||||
parser.onPartEnd = appendEntryToFormData;
|
||||
|
||||
headerField = '';
|
||||
headerValue = '';
|
||||
entryValue = '';
|
||||
entryName = '';
|
||||
contentType = '';
|
||||
filename = null;
|
||||
entryChunks.length = 0;
|
||||
};
|
||||
|
||||
parser.onHeaderField = function (ui8a) {
|
||||
headerField += decoder.decode(ui8a, {stream: true});
|
||||
};
|
||||
|
||||
parser.onHeaderValue = function (ui8a) {
|
||||
headerValue += decoder.decode(ui8a, {stream: true});
|
||||
};
|
||||
|
||||
parser.onHeaderEnd = function () {
|
||||
headerValue += decoder.decode();
|
||||
headerField = headerField.toLowerCase();
|
||||
|
||||
if (headerField === 'content-disposition') {
|
||||
// matches either a quoted-string or a token (RFC 2616 section 19.5.1)
|
||||
const m = headerValue.match(/\bname=("([^"]*)"|([^()<>@,;:\\"/[\]?={}\s\t]+))/i);
|
||||
|
||||
if (m) {
|
||||
entryName = m[2] || m[3] || '';
|
||||
}
|
||||
|
||||
filename = _fileName(headerValue);
|
||||
|
||||
if (filename) {
|
||||
parser.onPartData = appendToFile;
|
||||
parser.onPartEnd = appendFileToFormData;
|
||||
}
|
||||
} else if (headerField === 'content-type') {
|
||||
contentType = headerValue;
|
||||
}
|
||||
|
||||
headerValue = '';
|
||||
headerField = '';
|
||||
};
|
||||
|
||||
for await (const chunk of Body) {
|
||||
parser.write(chunk);
|
||||
}
|
||||
|
||||
parser.end();
|
||||
|
||||
return formData;
|
||||
}
|
||||
|
||||
|
||||
/***/ })
|
||||
|
||||
};
|
||||
;
|
||||
//# sourceMappingURL=37.index.js.map
|
||||
-1
File diff suppressed because one or more lines are too long
BIN
Binary file not shown.
BIN
Binary file not shown.
+280
-43
@@ -23,7 +23,13 @@ __nccwpck_require__.r(__webpack_exports__);
|
||||
/* harmony import */ var node_path__WEBPACK_IMPORTED_MODULE_6___default = /*#__PURE__*/__nccwpck_require__.n(node_path__WEBPACK_IMPORTED_MODULE_6__);
|
||||
/* harmony import */ var node_fs__WEBPACK_IMPORTED_MODULE_7__ = __nccwpck_require__(7561);
|
||||
/* harmony import */ var node_fs__WEBPACK_IMPORTED_MODULE_7___default = /*#__PURE__*/__nccwpck_require__.n(node_fs__WEBPACK_IMPORTED_MODULE_7__);
|
||||
/* harmony import */ var string_argv__WEBPACK_IMPORTED_MODULE_8__ = __nccwpck_require__(1810);
|
||||
/* harmony import */ var node_os__WEBPACK_IMPORTED_MODULE_8__ = __nccwpck_require__(612);
|
||||
/* harmony import */ var node_os__WEBPACK_IMPORTED_MODULE_8___default = /*#__PURE__*/__nccwpck_require__.n(node_os__WEBPACK_IMPORTED_MODULE_8__);
|
||||
/* harmony import */ var string_argv__WEBPACK_IMPORTED_MODULE_10__ = __nccwpck_require__(1810);
|
||||
/* harmony import */ var path__WEBPACK_IMPORTED_MODULE_9__ = __nccwpck_require__(1017);
|
||||
/* harmony import */ var path__WEBPACK_IMPORTED_MODULE_9___default = /*#__PURE__*/__nccwpck_require__.n(path__WEBPACK_IMPORTED_MODULE_9__);
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -34,14 +40,17 @@ __nccwpck_require__.r(__webpack_exports__);
|
||||
|
||||
|
||||
class NixInstallerAction {
|
||||
constructor() {
|
||||
constructor(correlation) {
|
||||
this.platform = get_nix_platform();
|
||||
this.nix_package_url = action_input_string_or_null("nix-package-url");
|
||||
this.backtrace = action_input_string_or_null("backtrace");
|
||||
this.extra_args = action_input_string_or_null("extra-args");
|
||||
this.extra_conf = action_input_multiline_string_or_null("extra-conf");
|
||||
this.flakehub = action_input_bool("flakehub");
|
||||
this.kvm = action_input_bool("kvm");
|
||||
this.force_docker_shim = action_input_bool("force-docker-shim");
|
||||
this.github_token = action_input_string_or_null("github-token");
|
||||
this.github_server_url = action_input_string_or_null("github-server-url");
|
||||
this.init = action_input_string_or_null("init");
|
||||
this.local_root = action_input_string_or_null("local-root");
|
||||
this.log_directives = action_input_string_or_null("log-directives");
|
||||
@@ -63,9 +72,69 @@ class NixInstallerAction {
|
||||
this.start_daemon = action_input_bool("start-daemon");
|
||||
this.diagnostic_endpoint = action_input_string_or_null("diagnostic-endpoint");
|
||||
this.trust_runner_user = action_input_bool("trust-runner-user");
|
||||
this.correlation = process.env["STATE_correlation"];
|
||||
this.correlation = correlation;
|
||||
this.nix_installer_url = resolve_nix_installer_url(this.platform, this.correlation);
|
||||
}
|
||||
async detectAndForceDockerShim() {
|
||||
// Detect if we're in a GHA runner which is Linux, doesn't have Systemd, and does have Docker.
|
||||
// This is a common case in self-hosted runners, providers like [Namespace](https://namespace.so/),
|
||||
// and especially GitHub Enterprise Server.
|
||||
if (process.env.RUNNER_OS !== "Linux") {
|
||||
if (this.force_docker_shim) {
|
||||
_actions_core__WEBPACK_IMPORTED_MODULE_0__.warning("Ignoring force-docker-shim which is set to true, as it is only supported on Linux.");
|
||||
this.force_docker_shim = false;
|
||||
}
|
||||
return;
|
||||
}
|
||||
const systemdCheck = node_fs__WEBPACK_IMPORTED_MODULE_7___default().statSync("/run/systemd/system", {
|
||||
throwIfNoEntry: false,
|
||||
});
|
||||
if (systemdCheck === null || systemdCheck === void 0 ? void 0 : systemdCheck.isDirectory()) {
|
||||
if (this.force_docker_shim) {
|
||||
_actions_core__WEBPACK_IMPORTED_MODULE_0__.warning("Systemd is detected, but ignoring it since force-docker-shim is enabled.");
|
||||
}
|
||||
else {
|
||||
return;
|
||||
}
|
||||
}
|
||||
_actions_core__WEBPACK_IMPORTED_MODULE_0__.debug("Linux detected without systemd, testing for Docker with `docker info` as an alternative daemon supervisor.");
|
||||
const exit_code = await _actions_exec__WEBPACK_IMPORTED_MODULE_3__.exec("docker", ["info"], {
|
||||
silent: true,
|
||||
listeners: {
|
||||
stdout: (data) => {
|
||||
const trimmed = data.toString("utf-8").trimEnd();
|
||||
if (trimmed.length >= 0) {
|
||||
_actions_core__WEBPACK_IMPORTED_MODULE_0__.debug(trimmed);
|
||||
}
|
||||
},
|
||||
stderr: (data) => {
|
||||
const trimmed = data.toString("utf-8").trimEnd();
|
||||
if (trimmed.length >= 0) {
|
||||
_actions_core__WEBPACK_IMPORTED_MODULE_0__.debug(trimmed);
|
||||
}
|
||||
},
|
||||
},
|
||||
});
|
||||
if (exit_code !== 0) {
|
||||
if (this.force_docker_shim) {
|
||||
_actions_core__WEBPACK_IMPORTED_MODULE_0__.warning("docker info check failed, but trying anyway since force-docker-shim is enabled.");
|
||||
}
|
||||
else {
|
||||
return;
|
||||
}
|
||||
}
|
||||
_actions_core__WEBPACK_IMPORTED_MODULE_0__.startGroup("Enabling the Docker shim for running Nix on Linux in CI without Systemd.");
|
||||
if (this.init !== "none") {
|
||||
_actions_core__WEBPACK_IMPORTED_MODULE_0__.info(`Changing init from '${this.init}' to 'none'`);
|
||||
this.init = "none";
|
||||
}
|
||||
if (this.planner !== "linux") {
|
||||
_actions_core__WEBPACK_IMPORTED_MODULE_0__.info(`Changing planner from '${this.planner}' to 'linux'`);
|
||||
this.planner = "linux";
|
||||
}
|
||||
this.force_docker_shim = true;
|
||||
_actions_core__WEBPACK_IMPORTED_MODULE_0__.endGroup();
|
||||
}
|
||||
async executionEnvironment() {
|
||||
const execution_env = {};
|
||||
execution_env.NIX_INSTALLER_NO_CONFIRM = "true";
|
||||
@@ -158,12 +227,19 @@ class NixInstallerAction {
|
||||
}
|
||||
}
|
||||
let extra_conf = "";
|
||||
if (this.github_token !== null) {
|
||||
extra_conf += `access-tokens = github.com=${this.github_token}`;
|
||||
if (this.github_server_url !== null && this.github_token !== null) {
|
||||
const server_url = this.github_server_url.replace("https://", "");
|
||||
extra_conf += `access-tokens = ${server_url}=${this.github_token}`;
|
||||
extra_conf += "\n";
|
||||
}
|
||||
if (this.trust_runner_user !== null) {
|
||||
extra_conf += `trusted-users = root ${process.env.USER}`;
|
||||
const user = (0,node_os__WEBPACK_IMPORTED_MODULE_8__.userInfo)().username;
|
||||
if (user) {
|
||||
extra_conf += `trusted-users = root ${user}`;
|
||||
}
|
||||
else {
|
||||
extra_conf += `trusted-users = root`;
|
||||
}
|
||||
extra_conf += "\n";
|
||||
}
|
||||
if (this.flakehub) {
|
||||
@@ -187,7 +263,7 @@ class NixInstallerAction {
|
||||
}
|
||||
async execute_install(binary_path) {
|
||||
const execution_env = await this.executionEnvironment();
|
||||
_actions_core__WEBPACK_IMPORTED_MODULE_0__.info(`Execution environment: ${JSON.stringify(execution_env, null, 4)}`);
|
||||
_actions_core__WEBPACK_IMPORTED_MODULE_0__.debug(`Execution environment: ${JSON.stringify(execution_env, null, 4)}`);
|
||||
const args = ["install"];
|
||||
if (this.planner) {
|
||||
args.push(this.planner);
|
||||
@@ -196,25 +272,11 @@ class NixInstallerAction {
|
||||
args.push(get_default_planner());
|
||||
}
|
||||
if (this.extra_args) {
|
||||
const extra_args = (0,string_argv__WEBPACK_IMPORTED_MODULE_8__/* ["default"] */ .Z)(this.extra_args);
|
||||
const extra_args = (0,string_argv__WEBPACK_IMPORTED_MODULE_10__/* ["default"] */ .Z)(this.extra_args);
|
||||
args.concat(extra_args);
|
||||
}
|
||||
const exit_code = await _actions_exec__WEBPACK_IMPORTED_MODULE_3__.exec(binary_path, args, {
|
||||
env: Object.assign(Object.assign({}, execution_env), process.env),
|
||||
listeners: {
|
||||
stdout: (data) => {
|
||||
const trimmed = data.toString("utf-8").trimEnd();
|
||||
if (trimmed.length >= 0) {
|
||||
_actions_core__WEBPACK_IMPORTED_MODULE_0__.info(trimmed);
|
||||
}
|
||||
},
|
||||
stderr: (data) => {
|
||||
const trimmed = data.toString("utf-8").trimEnd();
|
||||
if (trimmed.length >= 0) {
|
||||
_actions_core__WEBPACK_IMPORTED_MODULE_0__.info(trimmed);
|
||||
}
|
||||
},
|
||||
},
|
||||
});
|
||||
if (exit_code !== 0) {
|
||||
throw new Error(`Non-zero exit code of \`${exit_code}\` detected`);
|
||||
@@ -236,11 +298,125 @@ class NixInstallerAction {
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (this.kvm) {
|
||||
_actions_core__WEBPACK_IMPORTED_MODULE_0__.startGroup("Configuring KVM");
|
||||
if (await this.setup_kvm()) {
|
||||
_actions_core__WEBPACK_IMPORTED_MODULE_0__.endGroup();
|
||||
_actions_core__WEBPACK_IMPORTED_MODULE_0__.info("\u001b[32m Accelerated KVM is enabled \u001b[33m⚡️");
|
||||
_actions_core__WEBPACK_IMPORTED_MODULE_0__.exportVariable("DETERMINATE_NIX_KVM", "1");
|
||||
}
|
||||
else {
|
||||
_actions_core__WEBPACK_IMPORTED_MODULE_0__.endGroup();
|
||||
_actions_core__WEBPACK_IMPORTED_MODULE_0__.info("KVM is not available.");
|
||||
_actions_core__WEBPACK_IMPORTED_MODULE_0__.exportVariable("DETERMINATE_NIX_KVM", "0");
|
||||
}
|
||||
_actions_core__WEBPACK_IMPORTED_MODULE_0__.exportVariable("DETERMINATE_NIX_KVM", "0");
|
||||
}
|
||||
// Normal just doing of the install
|
||||
_actions_core__WEBPACK_IMPORTED_MODULE_0__.startGroup("Installing Nix");
|
||||
const binary_path = await this.fetch_binary();
|
||||
await this.execute_install(binary_path);
|
||||
_actions_core__WEBPACK_IMPORTED_MODULE_0__.endGroup();
|
||||
if (this.force_docker_shim) {
|
||||
await this.spawnDockerShim();
|
||||
}
|
||||
await this.set_github_path();
|
||||
}
|
||||
async spawnDockerShim() {
|
||||
_actions_core__WEBPACK_IMPORTED_MODULE_0__.startGroup("Configuring the Docker shim as the Nix Daemon's process supervisor");
|
||||
const images = {
|
||||
X64: __nccwpck_require__.ab + "amd64.tar.gz",
|
||||
ARM64: __nccwpck_require__.ab + "arm64.tar.gz",
|
||||
};
|
||||
let arch;
|
||||
if (process.env.RUNNER_ARCH === "X64") {
|
||||
arch = "X64";
|
||||
}
|
||||
else if (process.env.RUNNER_ARCH === "ARM64") {
|
||||
arch = "ARM64";
|
||||
}
|
||||
else {
|
||||
throw Error("Architecture not supported in Docker shim mode.");
|
||||
}
|
||||
_actions_core__WEBPACK_IMPORTED_MODULE_0__.debug("Loading image: determinate-nix-shim:latest...");
|
||||
{
|
||||
const exit_code = await _actions_exec__WEBPACK_IMPORTED_MODULE_3__.exec("docker", ["image", "load", "--input", images[arch]], {
|
||||
silent: true,
|
||||
listeners: {
|
||||
stdout: (data) => {
|
||||
const trimmed = data.toString("utf-8").trimEnd();
|
||||
if (trimmed.length >= 0) {
|
||||
_actions_core__WEBPACK_IMPORTED_MODULE_0__.debug(trimmed);
|
||||
}
|
||||
},
|
||||
stderr: (data) => {
|
||||
const trimmed = data.toString("utf-8").trimEnd();
|
||||
if (trimmed.length >= 0) {
|
||||
_actions_core__WEBPACK_IMPORTED_MODULE_0__.debug(trimmed);
|
||||
}
|
||||
},
|
||||
},
|
||||
});
|
||||
if (exit_code !== 0) {
|
||||
throw new Error(`Failed to build the shim image, exit code: \`${exit_code}\``);
|
||||
}
|
||||
}
|
||||
{
|
||||
_actions_core__WEBPACK_IMPORTED_MODULE_0__.debug("Starting the Nix daemon through Docker...");
|
||||
const exit_code = await _actions_exec__WEBPACK_IMPORTED_MODULE_3__.exec("docker", [
|
||||
"--log-level=debug",
|
||||
"run",
|
||||
"--detach",
|
||||
"--privileged",
|
||||
"--userns=host",
|
||||
"--pid=host",
|
||||
"--mount",
|
||||
"type=bind,src=/tmp,dst=/tmp",
|
||||
"--mount",
|
||||
"type=bind,src=/nix,dst=/nix",
|
||||
"--mount",
|
||||
"type=bind,src=/etc,dst=/etc,readonly",
|
||||
"--restart",
|
||||
"always",
|
||||
"--init",
|
||||
"--name",
|
||||
`determinate-nix-shim-${this.correlation}`,
|
||||
"determinate-nix-shim:latest",
|
||||
], {
|
||||
silent: true,
|
||||
listeners: {
|
||||
stdline: (data) => {
|
||||
_actions_core__WEBPACK_IMPORTED_MODULE_0__.saveState("docker_shim_container_id", data.trimEnd());
|
||||
},
|
||||
stdout: (data) => {
|
||||
const trimmed = data.toString("utf-8").trimEnd();
|
||||
if (trimmed.length >= 0) {
|
||||
_actions_core__WEBPACK_IMPORTED_MODULE_0__.debug(trimmed);
|
||||
}
|
||||
},
|
||||
stderr: (data) => {
|
||||
const trimmed = data.toString("utf-8").trimEnd();
|
||||
if (trimmed.length >= 0) {
|
||||
_actions_core__WEBPACK_IMPORTED_MODULE_0__.debug(trimmed);
|
||||
}
|
||||
},
|
||||
},
|
||||
});
|
||||
if (exit_code !== 0) {
|
||||
throw new Error(`Failed to start the Nix daemon through Docker, exit code: \`${exit_code}\``);
|
||||
}
|
||||
}
|
||||
_actions_core__WEBPACK_IMPORTED_MODULE_0__.endGroup();
|
||||
return;
|
||||
}
|
||||
async cleanupDockerShim() {
|
||||
const container_id = _actions_core__WEBPACK_IMPORTED_MODULE_0__.getState("docker_shim_container_id");
|
||||
if (container_id !== "") {
|
||||
_actions_core__WEBPACK_IMPORTED_MODULE_0__.startGroup("Cleaning up the Nix daemon's Docker shim");
|
||||
await _actions_exec__WEBPACK_IMPORTED_MODULE_3__.exec("docker", ["rm", "--force", container_id]);
|
||||
_actions_core__WEBPACK_IMPORTED_MODULE_0__.endGroup();
|
||||
}
|
||||
}
|
||||
async set_github_path() {
|
||||
// Interim versions of the `nix-installer` crate may have already manipulated `$GITHUB_PATH`, as root even! Accessing that will be an error.
|
||||
try {
|
||||
@@ -273,20 +449,6 @@ class NixInstallerAction {
|
||||
async execute_uninstall() {
|
||||
const exit_code = await _actions_exec__WEBPACK_IMPORTED_MODULE_3__.exec(`/nix/nix-installer`, ["uninstall"], {
|
||||
env: Object.assign({ NIX_INSTALLER_NO_CONFIRM: "true" }, process.env),
|
||||
listeners: {
|
||||
stdout: (data) => {
|
||||
const trimmed = data.toString("utf-8").trimEnd();
|
||||
if (trimmed.length >= 0) {
|
||||
_actions_core__WEBPACK_IMPORTED_MODULE_0__.info(trimmed);
|
||||
}
|
||||
},
|
||||
stderr: (data) => {
|
||||
const trimmed = data.toString("utf-8").trimEnd();
|
||||
if (trimmed.length >= 0) {
|
||||
_actions_core__WEBPACK_IMPORTED_MODULE_0__.info(trimmed);
|
||||
}
|
||||
},
|
||||
},
|
||||
});
|
||||
if (exit_code !== 0) {
|
||||
throw new Error(`Non-zero exit code of \`${exit_code}\` detected`);
|
||||
@@ -305,6 +467,71 @@ class NixInstallerAction {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
async setup_kvm() {
|
||||
const kvm_rules = "/etc/udev/rules.d/99-determinate-nix-installer-kvm.rules";
|
||||
try {
|
||||
const write_file_exit_code = await _actions_exec__WEBPACK_IMPORTED_MODULE_3__.exec("sh", [
|
||||
"-c",
|
||||
`echo 'KERNEL=="kvm", GROUP="kvm", MODE="0666", OPTIONS+="static_node=kvm"' | sudo tee ${kvm_rules} > /dev/null`,
|
||||
], {
|
||||
silent: true,
|
||||
listeners: {
|
||||
stdout: (data) => {
|
||||
const trimmed = data.toString("utf-8").trimEnd();
|
||||
if (trimmed.length >= 0) {
|
||||
_actions_core__WEBPACK_IMPORTED_MODULE_0__.debug(trimmed);
|
||||
}
|
||||
},
|
||||
stderr: (data) => {
|
||||
const trimmed = data.toString("utf-8").trimEnd();
|
||||
if (trimmed.length >= 0) {
|
||||
_actions_core__WEBPACK_IMPORTED_MODULE_0__.debug(trimmed);
|
||||
}
|
||||
},
|
||||
},
|
||||
});
|
||||
if (write_file_exit_code !== 0) {
|
||||
throw new Error(`Non-zero exit code of \`${write_file_exit_code}\` detected while writing '${kvm_rules}'`);
|
||||
}
|
||||
const debug_run_throw = async (action, command, args) => {
|
||||
const reload_exit_code = await _actions_exec__WEBPACK_IMPORTED_MODULE_3__.exec(command, args, {
|
||||
silent: true,
|
||||
listeners: {
|
||||
stdout: (data) => {
|
||||
const trimmed = data.toString("utf-8").trimEnd();
|
||||
if (trimmed.length >= 0) {
|
||||
_actions_core__WEBPACK_IMPORTED_MODULE_0__.debug(trimmed);
|
||||
}
|
||||
},
|
||||
stderr: (data) => {
|
||||
const trimmed = data.toString("utf-8").trimEnd();
|
||||
if (trimmed.length >= 0) {
|
||||
_actions_core__WEBPACK_IMPORTED_MODULE_0__.debug(trimmed);
|
||||
}
|
||||
},
|
||||
},
|
||||
});
|
||||
if (reload_exit_code !== 0) {
|
||||
throw new Error(`Non-zero exit code of \`${reload_exit_code}\` detected while ${action}.`);
|
||||
}
|
||||
};
|
||||
await debug_run_throw("reloading udev rules", `sudo`, [
|
||||
"udevadm",
|
||||
"control",
|
||||
"--reload-rules",
|
||||
]);
|
||||
await debug_run_throw("triggering udev against kvm", `sudo`, [
|
||||
"udevadm",
|
||||
"trigger",
|
||||
"--name-match=kvm",
|
||||
]);
|
||||
return true;
|
||||
}
|
||||
catch (error) {
|
||||
await _actions_exec__WEBPACK_IMPORTED_MODULE_3__.exec("sudo", ["rm", "-f", kvm_rules]);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
async fetch_binary() {
|
||||
if (!this.local_root) {
|
||||
_actions_core__WEBPACK_IMPORTED_MODULE_0__.info(`Fetching binary from ${this.nix_installer_url}`);
|
||||
@@ -479,18 +706,20 @@ function action_input_bool(name) {
|
||||
}
|
||||
async function main() {
|
||||
try {
|
||||
if (!process.env["STATE_correlation"]) {
|
||||
const correlation = `GH-${(0,node_crypto__WEBPACK_IMPORTED_MODULE_5__.randomUUID)()}`;
|
||||
let correlation = _actions_core__WEBPACK_IMPORTED_MODULE_0__.getState("correlation");
|
||||
if (correlation === "") {
|
||||
correlation = `GH-${(0,node_crypto__WEBPACK_IMPORTED_MODULE_5__.randomUUID)()}`;
|
||||
_actions_core__WEBPACK_IMPORTED_MODULE_0__.saveState("correlation", correlation);
|
||||
process.env["STATE_correlation"] = correlation;
|
||||
}
|
||||
const installer = new NixInstallerAction();
|
||||
const isPost = !!process.env["STATE_isPost"];
|
||||
if (!isPost) {
|
||||
_actions_core__WEBPACK_IMPORTED_MODULE_0__.saveState("isPost", "true");
|
||||
const installer = new NixInstallerAction(correlation);
|
||||
const isPost = _actions_core__WEBPACK_IMPORTED_MODULE_0__.getState("isPost");
|
||||
if (isPost !== "true") {
|
||||
await installer.detectAndForceDockerShim();
|
||||
await installer.install();
|
||||
_actions_core__WEBPACK_IMPORTED_MODULE_0__.saveState("isPost", "true");
|
||||
}
|
||||
else {
|
||||
await installer.cleanupDockerShim();
|
||||
await installer.report_overall();
|
||||
}
|
||||
}
|
||||
@@ -17210,6 +17439,14 @@ module.exports = require("node:fs/promises");
|
||||
|
||||
/***/ }),
|
||||
|
||||
/***/ 612:
|
||||
/***/ ((module) => {
|
||||
|
||||
"use strict";
|
||||
module.exports = require("node:os");
|
||||
|
||||
/***/ }),
|
||||
|
||||
/***/ 9411:
|
||||
/***/ ((module) => {
|
||||
|
||||
|
||||
+1
-1
File diff suppressed because one or more lines are too long
@@ -0,0 +1,19 @@
|
||||
# Determinate Nix Installer: Docker Shim
|
||||
#
|
||||
# This empty image exists to lean on Docker as a process supervisor when
|
||||
# systemd isn't available. Specifically intended for self-hosted GitHub
|
||||
# Actions runners using Docker-in-Docker.
|
||||
#
|
||||
# See: https://github.com/DeterminateSystems/nix-installer-action
|
||||
|
||||
FROM scratch
|
||||
|
||||
ENTRYPOINT [ "/nix/var/nix/profiles/default/bin/nix-daemon"]
|
||||
CMD []
|
||||
|
||||
HEALTHCHECK \
|
||||
--interval=5m \
|
||||
--timeout=3s \
|
||||
CMD ["/nix/var/nix/profiles/default/bin/nix", "store", "ping", "--store", "daemon"]
|
||||
|
||||
COPY ./Dockerfile /README.md
|
||||
@@ -0,0 +1,52 @@
|
||||
# Determinate Nix Installer Action: Docker Shim
|
||||
|
||||
The image in this repository is a product of the contained Dockerfile.
|
||||
It is an otherwise empty image with a configuration layer.
|
||||
|
||||
This image is to be used in GitHub Actions runners which don't have systemd available, like self-hosted ARC runners.
|
||||
|
||||
The image would have no layers / content at all, however Docker has a bug and refuses to export those images.
|
||||
This isn't a technical limitation preventing us from creating and distributing that image, but an ease-of-use limitation.
|
||||
Since some of Docker's inspection tools break on an empty image, the image contains a single layer containing a README.
|
||||
|
||||
To build:
|
||||
|
||||
```shell
|
||||
docker build . --tag determinate-nix-shim:latest
|
||||
docker image save determinate-nix-shim:latest | gzip --best > amd64.tar
|
||||
```
|
||||
|
||||
Then, extract the tarball:
|
||||
|
||||
```
|
||||
mkdir extract
|
||||
cd extract
|
||||
tar -xf ../amd64.tar
|
||||
```
|
||||
|
||||
It'll look like this, though the hashes will be different.
|
||||
|
||||
```
|
||||
.
|
||||
├── 771204abb853cdde06bbbc680001a02642050a1db1a7b0a48cf5f20efa8bdc5d.json
|
||||
├── c4088111818e553e834adfc81bda8fe6da281afa9a40012eaa82796fb5476e98
|
||||
│ ├── VERSION
|
||||
│ ├── json
|
||||
│ └── layer.tar
|
||||
├── manifest.json
|
||||
└── repositories
|
||||
```
|
||||
|
||||
Ignore `manifest.json`, and edit the other two JSON documents to replace `amd64` with `arm64`, both in a key named "architecture:
|
||||
|
||||
```
|
||||
"architecture":"amd64"
|
||||
```
|
||||
|
||||
Then re-create the tar, from within the `extract` directory:
|
||||
|
||||
```
|
||||
tar --options gzip:compression-level=9 -zcf ../arm64.tar.gz .
|
||||
```
|
||||
|
||||
Then `git add` the two .tar.gz's and you're done.
|
||||
Binary file not shown.
Binary file not shown.
+336
-43
@@ -6,7 +6,9 @@ import { chmod, access, writeFile } from "node:fs/promises";
|
||||
import { randomUUID } from "node:crypto";
|
||||
import { join } from "node:path";
|
||||
import fs from "node:fs";
|
||||
import { userInfo } from "node:os";
|
||||
import stringArgv from "string-argv";
|
||||
import * as path from "path";
|
||||
|
||||
class NixInstallerAction {
|
||||
platform: string;
|
||||
@@ -15,8 +17,10 @@ class NixInstallerAction {
|
||||
extra_args: string | null;
|
||||
extra_conf: string[] | null;
|
||||
flakehub: boolean;
|
||||
kvm: boolean;
|
||||
github_server_url: string | null;
|
||||
github_token: string | null;
|
||||
// TODO: linux_init
|
||||
force_docker_shim: boolean | null;
|
||||
init: string | null;
|
||||
local_root: string | null;
|
||||
log_directives: string | null;
|
||||
@@ -44,16 +48,19 @@ class NixInstallerAction {
|
||||
// This is for monitoring the real impact of Nix updates, to avoid breaking large
|
||||
// swaths of users at once with botched Nix releases. For example:
|
||||
// https://github.com/NixOS/nix/issues/9052.
|
||||
correlation: string | undefined;
|
||||
correlation: string;
|
||||
|
||||
constructor() {
|
||||
constructor(correlation: string) {
|
||||
this.platform = get_nix_platform();
|
||||
this.nix_package_url = action_input_string_or_null("nix-package-url");
|
||||
this.backtrace = action_input_string_or_null("backtrace");
|
||||
this.extra_args = action_input_string_or_null("extra-args");
|
||||
this.extra_conf = action_input_multiline_string_or_null("extra-conf");
|
||||
this.flakehub = action_input_bool("flakehub");
|
||||
this.kvm = action_input_bool("kvm");
|
||||
this.force_docker_shim = action_input_bool("force-docker-shim");
|
||||
this.github_token = action_input_string_or_null("github-token");
|
||||
this.github_server_url = action_input_string_or_null("github-server-url");
|
||||
this.init = action_input_string_or_null("init");
|
||||
this.local_root = action_input_string_or_null("local-root");
|
||||
this.log_directives = action_input_string_or_null("log-directives");
|
||||
@@ -85,13 +92,89 @@ class NixInstallerAction {
|
||||
"diagnostic-endpoint",
|
||||
);
|
||||
this.trust_runner_user = action_input_bool("trust-runner-user");
|
||||
this.correlation = process.env["STATE_correlation"];
|
||||
this.correlation = correlation;
|
||||
this.nix_installer_url = resolve_nix_installer_url(
|
||||
this.platform,
|
||||
this.correlation,
|
||||
);
|
||||
}
|
||||
|
||||
async detectAndForceDockerShim(): Promise<void> {
|
||||
// Detect if we're in a GHA runner which is Linux, doesn't have Systemd, and does have Docker.
|
||||
// This is a common case in self-hosted runners, providers like [Namespace](https://namespace.so/),
|
||||
// and especially GitHub Enterprise Server.
|
||||
if (process.env.RUNNER_OS !== "Linux") {
|
||||
if (this.force_docker_shim) {
|
||||
actions_core.warning(
|
||||
"Ignoring force-docker-shim which is set to true, as it is only supported on Linux.",
|
||||
);
|
||||
this.force_docker_shim = false;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
const systemdCheck = fs.statSync("/run/systemd/system", {
|
||||
throwIfNoEntry: false,
|
||||
});
|
||||
if (systemdCheck?.isDirectory()) {
|
||||
if (this.force_docker_shim) {
|
||||
actions_core.warning(
|
||||
"Systemd is detected, but ignoring it since force-docker-shim is enabled.",
|
||||
);
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
actions_core.debug(
|
||||
"Linux detected without systemd, testing for Docker with `docker info` as an alternative daemon supervisor.",
|
||||
);
|
||||
const exit_code = await actions_exec.exec("docker", ["info"], {
|
||||
silent: true,
|
||||
listeners: {
|
||||
stdout: (data: Buffer) => {
|
||||
const trimmed = data.toString("utf-8").trimEnd();
|
||||
if (trimmed.length >= 0) {
|
||||
actions_core.debug(trimmed);
|
||||
}
|
||||
},
|
||||
stderr: (data: Buffer) => {
|
||||
const trimmed = data.toString("utf-8").trimEnd();
|
||||
if (trimmed.length >= 0) {
|
||||
actions_core.debug(trimmed);
|
||||
}
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
if (exit_code !== 0) {
|
||||
if (this.force_docker_shim) {
|
||||
actions_core.warning(
|
||||
"docker info check failed, but trying anyway since force-docker-shim is enabled.",
|
||||
);
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
actions_core.startGroup(
|
||||
"Enabling the Docker shim for running Nix on Linux in CI without Systemd.",
|
||||
);
|
||||
|
||||
if (this.init !== "none") {
|
||||
actions_core.info(`Changing init from '${this.init}' to 'none'`);
|
||||
this.init = "none";
|
||||
}
|
||||
if (this.planner !== "linux") {
|
||||
actions_core.info(`Changing planner from '${this.planner}' to 'linux'`);
|
||||
this.planner = "linux";
|
||||
}
|
||||
|
||||
this.force_docker_shim = true;
|
||||
|
||||
actions_core.endGroup();
|
||||
}
|
||||
|
||||
private async executionEnvironment(): Promise<ExecuteEnvironment> {
|
||||
const execution_env: ExecuteEnvironment = {};
|
||||
|
||||
@@ -208,12 +291,18 @@ class NixInstallerAction {
|
||||
}
|
||||
|
||||
let extra_conf = "";
|
||||
if (this.github_token !== null) {
|
||||
extra_conf += `access-tokens = github.com=${this.github_token}`;
|
||||
if (this.github_server_url !== null && this.github_token !== null) {
|
||||
const server_url = this.github_server_url.replace("https://", "");
|
||||
extra_conf += `access-tokens = ${server_url}=${this.github_token}`;
|
||||
extra_conf += "\n";
|
||||
}
|
||||
if (this.trust_runner_user !== null) {
|
||||
extra_conf += `trusted-users = root ${process.env.USER}`;
|
||||
const user = userInfo().username;
|
||||
if (user) {
|
||||
extra_conf += `trusted-users = root ${user}`;
|
||||
} else {
|
||||
extra_conf += `trusted-users = root`;
|
||||
}
|
||||
extra_conf += "\n";
|
||||
}
|
||||
if (this.flakehub) {
|
||||
@@ -245,7 +334,7 @@ class NixInstallerAction {
|
||||
|
||||
private async execute_install(binary_path: string): Promise<number> {
|
||||
const execution_env = await this.executionEnvironment();
|
||||
actions_core.info(
|
||||
actions_core.debug(
|
||||
`Execution environment: ${JSON.stringify(execution_env, null, 4)}`,
|
||||
);
|
||||
|
||||
@@ -266,20 +355,6 @@ class NixInstallerAction {
|
||||
...execution_env,
|
||||
...process.env, // To get $PATH, etc
|
||||
},
|
||||
listeners: {
|
||||
stdout: (data: Buffer) => {
|
||||
const trimmed = data.toString("utf-8").trimEnd();
|
||||
if (trimmed.length >= 0) {
|
||||
actions_core.info(trimmed);
|
||||
}
|
||||
},
|
||||
stderr: (data: Buffer) => {
|
||||
const trimmed = data.toString("utf-8").trimEnd();
|
||||
if (trimmed.length >= 0) {
|
||||
actions_core.info(trimmed);
|
||||
}
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
if (exit_code !== 0) {
|
||||
@@ -305,12 +380,156 @@ class NixInstallerAction {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (this.kvm) {
|
||||
actions_core.startGroup("Configuring KVM");
|
||||
if (await this.setup_kvm()) {
|
||||
actions_core.endGroup();
|
||||
actions_core.info(
|
||||
"\u001b[32m Accelerated KVM is enabled \u001b[33m⚡️",
|
||||
);
|
||||
actions_core.exportVariable("DETERMINATE_NIX_KVM", "1");
|
||||
} else {
|
||||
actions_core.endGroup();
|
||||
actions_core.info("KVM is not available.");
|
||||
actions_core.exportVariable("DETERMINATE_NIX_KVM", "0");
|
||||
}
|
||||
|
||||
actions_core.exportVariable("DETERMINATE_NIX_KVM", "0");
|
||||
}
|
||||
|
||||
// Normal just doing of the install
|
||||
actions_core.startGroup("Installing Nix");
|
||||
const binary_path = await this.fetch_binary();
|
||||
await this.execute_install(binary_path);
|
||||
actions_core.endGroup();
|
||||
|
||||
if (this.force_docker_shim) {
|
||||
await this.spawnDockerShim();
|
||||
}
|
||||
await this.set_github_path();
|
||||
}
|
||||
|
||||
async spawnDockerShim(): Promise<void> {
|
||||
actions_core.startGroup(
|
||||
"Configuring the Docker shim as the Nix Daemon's process supervisor",
|
||||
);
|
||||
|
||||
const images: { [key: string]: string } = {
|
||||
X64: path.join(__dirname, "/../docker-shim/amd64.tar.gz"),
|
||||
ARM64: path.join(__dirname, "/../docker-shim/arm64.tar.gz"),
|
||||
};
|
||||
|
||||
let arch;
|
||||
if (process.env.RUNNER_ARCH === "X64") {
|
||||
arch = "X64";
|
||||
} else if (process.env.RUNNER_ARCH === "ARM64") {
|
||||
arch = "ARM64";
|
||||
} else {
|
||||
throw Error("Architecture not supported in Docker shim mode.");
|
||||
}
|
||||
actions_core.debug("Loading image: determinate-nix-shim:latest...");
|
||||
{
|
||||
const exit_code = await actions_exec.exec(
|
||||
"docker",
|
||||
["image", "load", "--input", images[arch]],
|
||||
{
|
||||
silent: true,
|
||||
listeners: {
|
||||
stdout: (data: Buffer) => {
|
||||
const trimmed = data.toString("utf-8").trimEnd();
|
||||
if (trimmed.length >= 0) {
|
||||
actions_core.debug(trimmed);
|
||||
}
|
||||
},
|
||||
stderr: (data: Buffer) => {
|
||||
const trimmed = data.toString("utf-8").trimEnd();
|
||||
if (trimmed.length >= 0) {
|
||||
actions_core.debug(trimmed);
|
||||
}
|
||||
},
|
||||
},
|
||||
},
|
||||
);
|
||||
|
||||
if (exit_code !== 0) {
|
||||
throw new Error(
|
||||
`Failed to build the shim image, exit code: \`${exit_code}\``,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
actions_core.debug("Starting the Nix daemon through Docker...");
|
||||
const exit_code = await actions_exec.exec(
|
||||
"docker",
|
||||
[
|
||||
"--log-level=debug",
|
||||
"run",
|
||||
"--detach",
|
||||
"--privileged",
|
||||
"--userns=host",
|
||||
"--pid=host",
|
||||
"--mount",
|
||||
"type=bind,src=/tmp,dst=/tmp",
|
||||
"--mount",
|
||||
"type=bind,src=/nix,dst=/nix",
|
||||
"--mount",
|
||||
"type=bind,src=/etc,dst=/etc,readonly",
|
||||
"--restart",
|
||||
"always",
|
||||
"--init",
|
||||
"--name",
|
||||
`determinate-nix-shim-${this.correlation}`,
|
||||
"determinate-nix-shim:latest",
|
||||
],
|
||||
{
|
||||
silent: true,
|
||||
listeners: {
|
||||
stdline: (data: string) => {
|
||||
actions_core.saveState(
|
||||
"docker_shim_container_id",
|
||||
data.trimEnd(),
|
||||
);
|
||||
},
|
||||
stdout: (data: Buffer) => {
|
||||
const trimmed = data.toString("utf-8").trimEnd();
|
||||
if (trimmed.length >= 0) {
|
||||
actions_core.debug(trimmed);
|
||||
}
|
||||
},
|
||||
stderr: (data: Buffer) => {
|
||||
const trimmed = data.toString("utf-8").trimEnd();
|
||||
if (trimmed.length >= 0) {
|
||||
actions_core.debug(trimmed);
|
||||
}
|
||||
},
|
||||
},
|
||||
},
|
||||
);
|
||||
|
||||
if (exit_code !== 0) {
|
||||
throw new Error(
|
||||
`Failed to start the Nix daemon through Docker, exit code: \`${exit_code}\``,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
actions_core.endGroup();
|
||||
|
||||
return;
|
||||
}
|
||||
async cleanupDockerShim(): Promise<void> {
|
||||
const container_id = actions_core.getState("docker_shim_container_id");
|
||||
if (container_id !== "") {
|
||||
actions_core.startGroup("Cleaning up the Nix daemon's Docker shim");
|
||||
|
||||
await actions_exec.exec("docker", ["rm", "--force", container_id]);
|
||||
|
||||
actions_core.endGroup();
|
||||
}
|
||||
}
|
||||
|
||||
async set_github_path(): Promise<void> {
|
||||
// Interim versions of the `nix-installer` crate may have already manipulated `$GITHUB_PATH`, as root even! Accessing that will be an error.
|
||||
try {
|
||||
@@ -363,20 +582,6 @@ class NixInstallerAction {
|
||||
NIX_INSTALLER_NO_CONFIRM: "true",
|
||||
...process.env, // To get $PATH, etc
|
||||
},
|
||||
listeners: {
|
||||
stdout: (data: Buffer) => {
|
||||
const trimmed = data.toString("utf-8").trimEnd();
|
||||
if (trimmed.length >= 0) {
|
||||
actions_core.info(trimmed);
|
||||
}
|
||||
},
|
||||
stderr: (data: Buffer) => {
|
||||
const trimmed = data.toString("utf-8").trimEnd();
|
||||
if (trimmed.length >= 0) {
|
||||
actions_core.info(trimmed);
|
||||
}
|
||||
},
|
||||
},
|
||||
},
|
||||
);
|
||||
|
||||
@@ -399,6 +604,91 @@ class NixInstallerAction {
|
||||
}
|
||||
}
|
||||
|
||||
private async setup_kvm(): Promise<boolean> {
|
||||
const kvm_rules =
|
||||
"/etc/udev/rules.d/99-determinate-nix-installer-kvm.rules";
|
||||
try {
|
||||
const write_file_exit_code = await actions_exec.exec(
|
||||
"sh",
|
||||
[
|
||||
"-c",
|
||||
`echo 'KERNEL=="kvm", GROUP="kvm", MODE="0666", OPTIONS+="static_node=kvm"' | sudo tee ${kvm_rules} > /dev/null`,
|
||||
],
|
||||
{
|
||||
silent: true,
|
||||
listeners: {
|
||||
stdout: (data: Buffer) => {
|
||||
const trimmed = data.toString("utf-8").trimEnd();
|
||||
if (trimmed.length >= 0) {
|
||||
actions_core.debug(trimmed);
|
||||
}
|
||||
},
|
||||
stderr: (data: Buffer) => {
|
||||
const trimmed = data.toString("utf-8").trimEnd();
|
||||
if (trimmed.length >= 0) {
|
||||
actions_core.debug(trimmed);
|
||||
}
|
||||
},
|
||||
},
|
||||
},
|
||||
);
|
||||
|
||||
if (write_file_exit_code !== 0) {
|
||||
throw new Error(
|
||||
`Non-zero exit code of \`${write_file_exit_code}\` detected while writing '${kvm_rules}'`,
|
||||
);
|
||||
}
|
||||
|
||||
const debug_run_throw = async (
|
||||
action: string,
|
||||
command: string,
|
||||
args: string[],
|
||||
): Promise<void> => {
|
||||
const reload_exit_code = await actions_exec.exec(command, args, {
|
||||
silent: true,
|
||||
listeners: {
|
||||
stdout: (data: Buffer) => {
|
||||
const trimmed = data.toString("utf-8").trimEnd();
|
||||
if (trimmed.length >= 0) {
|
||||
actions_core.debug(trimmed);
|
||||
}
|
||||
},
|
||||
stderr: (data: Buffer) => {
|
||||
const trimmed = data.toString("utf-8").trimEnd();
|
||||
if (trimmed.length >= 0) {
|
||||
actions_core.debug(trimmed);
|
||||
}
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
if (reload_exit_code !== 0) {
|
||||
throw new Error(
|
||||
`Non-zero exit code of \`${reload_exit_code}\` detected while ${action}.`,
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
await debug_run_throw("reloading udev rules", `sudo`, [
|
||||
"udevadm",
|
||||
"control",
|
||||
"--reload-rules",
|
||||
]);
|
||||
|
||||
await debug_run_throw("triggering udev against kvm", `sudo`, [
|
||||
"udevadm",
|
||||
"trigger",
|
||||
"--name-match=kvm",
|
||||
]);
|
||||
|
||||
return true;
|
||||
} catch (error) {
|
||||
await actions_exec.exec("sudo", ["rm", "-f", kvm_rules]);
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
private async fetch_binary(): Promise<string> {
|
||||
if (!this.local_root) {
|
||||
actions_core.info(`Fetching binary from ${this.nix_installer_url}`);
|
||||
@@ -642,18 +932,21 @@ function action_input_bool(name: string): boolean {
|
||||
|
||||
async function main(): Promise<void> {
|
||||
try {
|
||||
if (!process.env["STATE_correlation"]) {
|
||||
const correlation = `GH-${randomUUID()}`;
|
||||
let correlation: string = actions_core.getState("correlation");
|
||||
if (correlation === "") {
|
||||
correlation = `GH-${randomUUID()}`;
|
||||
actions_core.saveState("correlation", correlation);
|
||||
process.env["STATE_correlation"] = correlation;
|
||||
}
|
||||
const installer = new NixInstallerAction();
|
||||
|
||||
const isPost = !!process.env["STATE_isPost"];
|
||||
if (!isPost) {
|
||||
actions_core.saveState("isPost", "true");
|
||||
const installer = new NixInstallerAction(correlation);
|
||||
|
||||
const isPost = actions_core.getState("isPost");
|
||||
if (isPost !== "true") {
|
||||
await installer.detectAndForceDockerShim();
|
||||
await installer.install();
|
||||
actions_core.saveState("isPost", "true");
|
||||
} else {
|
||||
await installer.cleanupDockerShim();
|
||||
await installer.report_overall();
|
||||
}
|
||||
} catch (error) {
|
||||
|
||||
Reference in New Issue
Block a user