Compare commits

...

11 Commits

Author SHA1 Message Date
Graham Christensen de22e16c47 DETERMINATE_NIX_KVM fixup, support Magic Nix Cache + FlakeHub Cache on Namespace runners (#72)
* Share /bin with nix for post-build-hooks

* test the magic nix cache

* wtf

* permissions

* Share /home and the network namespace too

* test the devshell

* Don't force-set kvm to 0 ... d'oh!

* dev shell support for aarch64-linux

* ?

* More testing /  debug

* Make it run anyway

* Bind /lib too so /bin/sh works ... sigh

* Disable gha-cache for tesing

* Kill the magic nix cache before reinstalling

* Don't set the extra environment variables extraniously

* Enable gha cache again
2024-03-11 19:53:25 -04:00
Ana Hobden e279ba56d8 Merge pull request #67 from DeterminateSystems/hoverbear/fh-161-after-running-in-act-hosts-nix-daemon-is-unusable
Don't use docker shim if only using a mounted docker.sock instead of docker-in-docker
2024-01-11 07:55:46 -08:00
Ana Hobden f4a0ffe230 Don't use docker shim if only using a mounted docker.sock instead of docker-in-docker 2024-01-10 11:45:04 -08:00
Ana Hobden ffea801f30 Merge pull request #66 from DeterminateSystems/hoverbear/fh-160-action-should-work-under-nektosact-in-the-absence-of-systemd
Handle docker not existing.
2024-01-10 08:36:26 -08:00
Ana Hobden 4126bb83b3 Merge branch 'main' into hoverbear/fh-160-action-should-work-under-nektosact-in-the-absence-of-systemd 2024-01-09 10:38:56 -08:00
Ana Hobden 81ee88fd4a Handle docker not existing 2024-01-09 10:36:54 -08:00
Ana Hobden 0f8fa3d242 Merge pull request #64 from DeterminateSystems/hoverbear/fh-156-installer-action-shouldnt-require-sudo
No longer require sudo
2024-01-09 09:50:39 -08:00
Ana Hobden f576e90e2d Fix logic inversion 2024-01-08 13:29:15 -08:00
Ana Hobden 161c1f6904 Use uid not username 2024-01-08 13:06:51 -08:00
Ana Hobden 0e5b724979 No longer require sudo 2024-01-08 10:50:02 -08:00
Cole Mickens 21affdd5d3 action: post-run-job: try clean daemon container, warn on failure (#61)
* flake: add typescript LSP tool

* action: post-run-job: try clean daemon container, warn on failure
2023-12-19 11:01:56 -05:00
5 changed files with 370 additions and 59 deletions
+24 -5
View File
@@ -16,15 +16,18 @@ jobs:
- run: npm run all
- run: git status --porcelain=v1
- run: test $(git status --porcelain=v1 2>/dev/null | wc -l) -eq 0
run-x86_64-linux:
name: Run x86_64 Linux
run-test-suite:
name: Run test suite
strategy:
matrix:
runner:
- ubuntu-latest
- nscloud-ubuntu-22.04-amd64-4x16
- namespace-profile-default-arm64
- ubuntu-latest
- nscloud-ubuntu-22.04-amd64-4x16
- namespace-profile-default-arm64
runs-on: ${{ matrix.runner }}
permissions:
contents: read
id-token: write
steps:
- uses: actions/checkout@v3
- name: Install Nix
@@ -33,8 +36,15 @@ jobs:
logger: pretty
log-directives: nix_installer=trace
backtrace: full
- uses: DeterminateSystems/magic-nix-cache-action@main
- name: echo $PATH
run: echo $PATH
- name: Render the devshell
if: success() || failure()
run: |
nix develop --command date
- name: Test `nix` with `$GITHUB_PATH`
if: success() || failure()
run: |
@@ -43,6 +53,7 @@ jobs:
hello
nix store gc
nix run nixpkgs#hello
- name: Test bash
run: nix-instantiate -E 'builtins.currentTime' --eval
if: success() || failure()
@@ -91,6 +102,9 @@ jobs:
run-x86_64-darwin:
name: Run x86_64 Darwin
runs-on: macos-12
permissions:
contents: read
id-token: write
steps:
- uses: actions/checkout@v3
- name: Install Nix
@@ -99,6 +113,7 @@ jobs:
logger: pretty
log-directives: nix_installer=trace
backtrace: full
- uses: DeterminateSystems/magic-nix-cache-action@main
- name: echo $PATH
run: echo $PATH
- name: Test `nix` with `$GITHUB_PATH`
@@ -135,6 +150,10 @@ jobs:
hello
nix store gc
nix run nixpkgs#hello
- name: Terminate the magic nix cache pre-reinstall
if: success() || failure()
run: |
pkill magic-nix-cache
- name: Reinstall Nix
uses: ./
with:
Generated Vendored
+157 -25
View File
@@ -98,23 +98,30 @@ class NixInstallerAction {
}
}
_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);
}
let exit_code;
try {
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);
}
},
},
stderr: (data) => {
const trimmed = data.toString("utf-8").trimEnd();
if (trimmed.length >= 0) {
_actions_core__WEBPACK_IMPORTED_MODULE_0__.debug(trimmed);
}
},
},
});
});
}
catch (e) {
_actions_core__WEBPACK_IMPORTED_MODULE_0__.debug("Docker not detected, not enabling docker shim.");
return;
}
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.");
@@ -123,6 +130,11 @@ class NixInstallerAction {
return;
}
}
if (!this.force_docker_shim &&
(await this.detectDockerWithMountedDockerSocket())) {
_actions_core__WEBPACK_IMPORTED_MODULE_0__.debug("Detected a Docker container with a Docker socket mounted, not enabling docker shim.");
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'`);
@@ -135,6 +147,90 @@ class NixInstallerAction {
this.force_docker_shim = true;
_actions_core__WEBPACK_IMPORTED_MODULE_0__.endGroup();
}
// Detect if we are running under `act` or some other system which is not using docker-in-docker,
// and instead using a mounted docker socket.
// In the case of the socket mount solution, the shim will cause issues since the given mount paths will
// equate to mount paths on the host, not mount paths to the docker container in question.
async detectDockerWithMountedDockerSocket() {
let cgroups_buffer;
try {
// If we are inside a docker container, the last line of `/proc/self/cgroup` should be
// 0::/docker/$SOME_ID
//
// If we are not, the line will likely be `0::/`
cgroups_buffer = await (0,node_fs_promises__WEBPACK_IMPORTED_MODULE_4__.readFile)("/proc/self/cgroup", {
encoding: "utf-8",
});
}
catch (e) {
_actions_core__WEBPACK_IMPORTED_MODULE_0__.debug(`Did not detect \`/proc/self/cgroup\` existence, bailing on docker container ID detection:\n${e}`);
return false;
}
const cgroups = cgroups_buffer.trim().split("\n");
const last_cgroup = cgroups[cgroups.length - 1];
const last_cgroup_parts = last_cgroup.split(":");
const last_cgroup_path = last_cgroup_parts[last_cgroup_parts.length - 1];
if (!last_cgroup_path.includes("/docker/")) {
_actions_core__WEBPACK_IMPORTED_MODULE_0__.debug("Did not detect a container ID, bailing on docker.sock detection");
return false;
}
// We are in a docker container, now to determine if this container is visible from
// the `docker` command, and if so, if there is a `docker.socket` mounted.
const last_cgroup_path_parts = last_cgroup_path.split("/");
const container_id = last_cgroup_path_parts[last_cgroup_path_parts.length - 1];
// If we cannot `docker inspect` this discovered container ID, we'll fall through to the `catch` below.
let stdout_buffer = "";
let stderr_buffer = "";
let exit_code;
try {
exit_code = await _actions_exec__WEBPACK_IMPORTED_MODULE_3__.exec("docker", ["inspect", container_id], {
silent: true,
listeners: {
stdout: (data) => {
stdout_buffer += data.toString("utf-8");
},
stderr: (data) => {
stderr_buffer += data.toString("utf-8");
},
},
});
}
catch (e) {
_actions_core__WEBPACK_IMPORTED_MODULE_0__.debug(`Could not execute \`docker inspect ${container_id}\`, bailing on docker container inspection:\n${e}`);
return false;
}
if (exit_code !== 0) {
_actions_core__WEBPACK_IMPORTED_MODULE_0__.debug(`Unable to inspect detected docker container with id \`${container_id}\`, bailing on container inspection (exit ${exit_code}):\n${stderr_buffer}`);
return false;
}
const output = JSON.parse(stdout_buffer);
// `docker inspect $ID` prints an array containing objects.
// In our use case, we should only see 1 item in the array.
if (output.length !== 1) {
_actions_core__WEBPACK_IMPORTED_MODULE_0__.debug(`Got \`docker inspect ${container_id}\` output which was not one item (was ${output.length}), bailing on docker.sock detection.`);
return false;
}
const item = output[0];
// On this array item we want the `Mounts` field, which is an array
// containing `{ Type, Source, Destination, Mode}`.
// We are looking for a `Destination` ending with `docker.sock`.
const mounts = item["Mounts"];
if (typeof mounts !== "object") {
_actions_core__WEBPACK_IMPORTED_MODULE_0__.debug(`Got non-object in \`Mounts\` field of \`docker inspect ${container_id}\` output, bailing on docker.sock detection.`);
return false;
}
let found_docker_sock_mount = false;
for (const mount of mounts) {
const destination = mount["Destination"];
if (typeof destination === "string") {
if (destination.endsWith("docker.sock")) {
found_docker_sock_mount = true;
break;
}
}
}
return found_docker_sock_mount;
}
async executionEnvironment() {
const execution_env = {};
execution_env.NIX_INSTALLER_NO_CONFIRM = "true";
@@ -310,7 +406,6 @@ class NixInstallerAction {
_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");
@@ -368,9 +463,16 @@ class NixInstallerAction {
"run",
"--detach",
"--privileged",
"--network=host",
"--userns=host",
"--pid=host",
"--mount",
"type=bind,src=/bin,dst=/bin,readonly",
"--mount",
"type=bind,src=/lib,dst=/lib,readonly",
"--mount",
"type=bind,src=/home,dst=/home,readonly",
"--mount",
"type=bind,src=/tmp,dst=/tmp",
"--mount",
"type=bind,src=/nix,dst=/nix",
@@ -413,7 +515,27 @@ class NixInstallerAction {
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]);
let cleaned = false;
try {
await _actions_exec__WEBPACK_IMPORTED_MODULE_3__.exec("docker", ["rm", "--force", container_id]);
cleaned = true;
}
catch (_a) {
_actions_core__WEBPACK_IMPORTED_MODULE_0__.warning("failed to cleanup nix daemon container");
}
if (!cleaned) {
_actions_core__WEBPACK_IMPORTED_MODULE_0__.info("trying to pkill the container's shim process");
try {
await _actions_exec__WEBPACK_IMPORTED_MODULE_3__.exec("pkill", [container_id]);
cleaned = true;
}
catch (_b) {
_actions_core__WEBPACK_IMPORTED_MODULE_0__.warning("failed to forcibly kill the container's shim process");
}
}
if (!cleaned) {
_actions_core__WEBPACK_IMPORTED_MODULE_0__.warning("Giving up on cleaning up the nix daemon container");
}
_actions_core__WEBPACK_IMPORTED_MODULE_0__.endGroup();
}
}
@@ -468,11 +590,14 @@ class NixInstallerAction {
}
}
async setup_kvm() {
const current_user = (0,node_os__WEBPACK_IMPORTED_MODULE_8__.userInfo)();
const is_root = current_user.uid === 0;
const maybe_sudo = is_root ? "" : "sudo";
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`,
`echo 'KERNEL=="kvm", GROUP="kvm", MODE="0666", OPTIONS+="static_node=kvm"' | ${maybe_sudo} tee ${kvm_rules} > /dev/null`,
], {
silent: true,
listeners: {
@@ -493,7 +618,11 @@ class NixInstallerAction {
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 debug_root_run_throw = async (action, command, args) => {
if (!is_root) {
args = [command, ...args];
command = "sudo";
}
const reload_exit_code = await _actions_exec__WEBPACK_IMPORTED_MODULE_3__.exec(command, args, {
silent: true,
listeners: {
@@ -515,20 +644,23 @@ class NixInstallerAction {
throw new Error(`Non-zero exit code of \`${reload_exit_code}\` detected while ${action}.`);
}
};
await debug_run_throw("reloading udev rules", `sudo`, [
"udevadm",
await debug_root_run_throw("reloading udev rules", "udevadm", [
"control",
"--reload-rules",
]);
await debug_run_throw("triggering udev against kvm", `sudo`, [
"udevadm",
await debug_root_run_throw("triggering udev against kvm", "udevadm", [
"trigger",
"--name-match=kvm",
]);
return true;
}
catch (error) {
await _actions_exec__WEBPACK_IMPORTED_MODULE_3__.exec("sudo", ["rm", "-f", kvm_rules]);
if (is_root) {
await _actions_exec__WEBPACK_IMPORTED_MODULE_3__.exec("rm", ["-f", kvm_rules]);
}
else {
await _actions_exec__WEBPACK_IMPORTED_MODULE_3__.exec("sudo", ["rm", "-f", kvm_rules]);
}
return false;
}
}
Generated Vendored
+1 -1
View File
File diff suppressed because one or more lines are too long
+2 -1
View File
@@ -9,7 +9,7 @@
outputs = { self, flake-schemas, nixpkgs }:
let
supportedSystems = [ "x86_64-linux" "aarch64-darwin" ];
supportedSystems = [ "x86_64-linux" "aarch64-darwin" "aarch64-linux" "x86_64-darwin" ];
forEachSupportedSystem = f: nixpkgs.lib.genAttrs supportedSystems (system: f {
pkgs = import nixpkgs { inherit system; };
});
@@ -22,6 +22,7 @@
packages = with pkgs; [
nodejs_latest
nixpkgs-fmt
nodePackages_latest.typescript-language-server
];
};
});
+186 -27
View File
@@ -2,7 +2,7 @@ import * as actions_core from "@actions/core";
import * as github from "@actions/github";
import * as actions_tool_cache from "@actions/tool-cache";
import * as actions_exec from "@actions/exec";
import { chmod, access, writeFile } from "node:fs/promises";
import { chmod, access, writeFile, readFile } from "node:fs/promises";
import { randomUUID } from "node:crypto";
import { join } from "node:path";
import fs from "node:fs";
@@ -129,23 +129,30 @@ class NixInstallerAction {
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);
}
let exit_code;
try {
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);
}
},
},
stderr: (data: Buffer) => {
const trimmed = data.toString("utf-8").trimEnd();
if (trimmed.length >= 0) {
actions_core.debug(trimmed);
}
},
},
});
});
} catch (e) {
actions_core.debug("Docker not detected, not enabling docker shim.");
return;
}
if (exit_code !== 0) {
if (this.force_docker_shim) {
@@ -157,6 +164,16 @@ class NixInstallerAction {
}
}
if (
!this.force_docker_shim &&
(await this.detectDockerWithMountedDockerSocket())
) {
actions_core.debug(
"Detected a Docker container with a Docker socket mounted, not enabling docker shim.",
);
return;
}
actions_core.startGroup(
"Enabling the Docker shim for running Nix on Linux in CI without Systemd.",
);
@@ -175,6 +192,108 @@ class NixInstallerAction {
actions_core.endGroup();
}
// Detect if we are running under `act` or some other system which is not using docker-in-docker,
// and instead using a mounted docker socket.
// In the case of the socket mount solution, the shim will cause issues since the given mount paths will
// equate to mount paths on the host, not mount paths to the docker container in question.
async detectDockerWithMountedDockerSocket(): Promise<boolean> {
let cgroups_buffer;
try {
// If we are inside a docker container, the last line of `/proc/self/cgroup` should be
// 0::/docker/$SOME_ID
//
// If we are not, the line will likely be `0::/`
cgroups_buffer = await readFile("/proc/self/cgroup", {
encoding: "utf-8",
});
} catch (e) {
actions_core.debug(
`Did not detect \`/proc/self/cgroup\` existence, bailing on docker container ID detection:\n${e}`,
);
return false;
}
const cgroups = cgroups_buffer.trim().split("\n");
const last_cgroup = cgroups[cgroups.length - 1];
const last_cgroup_parts = last_cgroup.split(":");
const last_cgroup_path = last_cgroup_parts[last_cgroup_parts.length - 1];
if (!last_cgroup_path.includes("/docker/")) {
actions_core.debug(
"Did not detect a container ID, bailing on docker.sock detection",
);
return false;
}
// We are in a docker container, now to determine if this container is visible from
// the `docker` command, and if so, if there is a `docker.socket` mounted.
const last_cgroup_path_parts = last_cgroup_path.split("/");
const container_id =
last_cgroup_path_parts[last_cgroup_path_parts.length - 1];
// If we cannot `docker inspect` this discovered container ID, we'll fall through to the `catch` below.
let stdout_buffer = "";
let stderr_buffer = "";
let exit_code;
try {
exit_code = await actions_exec.exec("docker", ["inspect", container_id], {
silent: true,
listeners: {
stdout: (data: Buffer) => {
stdout_buffer += data.toString("utf-8");
},
stderr: (data: Buffer) => {
stderr_buffer += data.toString("utf-8");
},
},
});
} catch (e) {
actions_core.debug(
`Could not execute \`docker inspect ${container_id}\`, bailing on docker container inspection:\n${e}`,
);
return false;
}
if (exit_code !== 0) {
actions_core.debug(
`Unable to inspect detected docker container with id \`${container_id}\`, bailing on container inspection (exit ${exit_code}):\n${stderr_buffer}`,
);
return false;
}
const output = JSON.parse(stdout_buffer);
// `docker inspect $ID` prints an array containing objects.
// In our use case, we should only see 1 item in the array.
if (output.length !== 1) {
actions_core.debug(
`Got \`docker inspect ${container_id}\` output which was not one item (was ${output.length}), bailing on docker.sock detection.`,
);
return false;
}
const item = output[0];
// On this array item we want the `Mounts` field, which is an array
// containing `{ Type, Source, Destination, Mode}`.
// We are looking for a `Destination` ending with `docker.sock`.
const mounts = item["Mounts"];
if (typeof mounts !== "object") {
actions_core.debug(
`Got non-object in \`Mounts\` field of \`docker inspect ${container_id}\` output, bailing on docker.sock detection.`,
);
return false;
}
let found_docker_sock_mount = false;
for (const mount of mounts) {
const destination = mount["Destination"];
if (typeof destination === "string") {
if (destination.endsWith("docker.sock")) {
found_docker_sock_mount = true;
break;
}
}
}
return found_docker_sock_mount;
}
private async executionEnvironment(): Promise<ExecuteEnvironment> {
const execution_env: ExecuteEnvironment = {};
@@ -394,8 +513,6 @@ class NixInstallerAction {
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
@@ -468,9 +585,16 @@ class NixInstallerAction {
"run",
"--detach",
"--privileged",
"--network=host",
"--userns=host",
"--pid=host",
"--mount",
"type=bind,src=/bin,dst=/bin,readonly",
"--mount",
"type=bind,src=/lib,dst=/lib,readonly",
"--mount",
"type=bind,src=/home,dst=/home,readonly",
"--mount",
"type=bind,src=/tmp,dst=/tmp",
"--mount",
"type=bind,src=/nix,dst=/nix",
@@ -521,10 +645,35 @@ class NixInstallerAction {
}
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]);
let cleaned = false;
try {
await actions_exec.exec("docker", ["rm", "--force", container_id]);
cleaned = true;
} catch {
actions_core.warning("failed to cleanup nix daemon container");
}
if (!cleaned) {
actions_core.info("trying to pkill the container's shim process");
try {
await actions_exec.exec("pkill", [container_id]);
cleaned = true;
} catch {
actions_core.warning(
"failed to forcibly kill the container's shim process",
);
}
}
if (!cleaned) {
actions_core.warning(
"Giving up on cleaning up the nix daemon container",
);
}
actions_core.endGroup();
}
@@ -605,6 +754,10 @@ class NixInstallerAction {
}
private async setup_kvm(): Promise<boolean> {
const current_user = userInfo();
const is_root = current_user.uid === 0;
const maybe_sudo = is_root ? "" : "sudo";
const kvm_rules =
"/etc/udev/rules.d/99-determinate-nix-installer-kvm.rules";
try {
@@ -612,7 +765,7 @@ class NixInstallerAction {
"sh",
[
"-c",
`echo 'KERNEL=="kvm", GROUP="kvm", MODE="0666", OPTIONS+="static_node=kvm"' | sudo tee ${kvm_rules} > /dev/null`,
`echo 'KERNEL=="kvm", GROUP="kvm", MODE="0666", OPTIONS+="static_node=kvm"' | ${maybe_sudo} tee ${kvm_rules} > /dev/null`,
],
{
silent: true,
@@ -639,11 +792,15 @@ class NixInstallerAction {
);
}
const debug_run_throw = async (
const debug_root_run_throw = async (
action: string,
command: string,
args: string[],
): Promise<void> => {
if (!is_root) {
args = [command, ...args];
command = "sudo";
}
const reload_exit_code = await actions_exec.exec(command, args, {
silent: true,
listeners: {
@@ -669,21 +826,23 @@ class NixInstallerAction {
}
};
await debug_run_throw("reloading udev rules", `sudo`, [
"udevadm",
await debug_root_run_throw("reloading udev rules", "udevadm", [
"control",
"--reload-rules",
]);
await debug_run_throw("triggering udev against kvm", `sudo`, [
"udevadm",
await debug_root_run_throw("triggering udev against kvm", "udevadm", [
"trigger",
"--name-match=kvm",
]);
return true;
} catch (error) {
await actions_exec.exec("sudo", ["rm", "-f", kvm_rules]);
if (is_root) {
await actions_exec.exec("rm", ["-f", kvm_rules]);
} else {
await actions_exec.exec("sudo", ["rm", "-f", kvm_rules]);
}
return false;
}