Srv update (#97)

* Update to srv

* Hi, footgun

* Make sure we don't toString promises, update deps

* Update

* Pass - as the default diagnostic endpoint

* Specify the diagnostic suffix

* Update deps

* SRV update
This commit is contained in:
Graham Christensen 2024-05-31 12:30:37 -04:00 committed by GitHub
parent f51ebf9a6f
commit a2473ab552
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
5 changed files with 258 additions and 117 deletions

View File

@ -29,6 +29,7 @@
"accessibility": "no-public"
}
],
"@typescript-eslint/no-base-to-string": "error",
"@typescript-eslint/no-require-imports": "error",
"@typescript-eslint/array-type": "error",
"@typescript-eslint/await-thenable": "error",

View File

@ -114,7 +114,8 @@ inputs:
default: true
diagnostic-endpoint:
description: "Diagnostic endpoint url where the installer sends data to. To disable set this to an empty string."
default: "https://install.determinate.systems/nix-installer/diagnostic"
required: false
default: "-"
trust-runner-user:
description: Whether to make the runner user trusted by the Nix daemon
default: true

334
dist/index.js generated vendored
View File

@ -89321,6 +89321,8 @@ var external_node_util_ = __nccwpck_require__(7261);
var external_os_ = __nccwpck_require__(2037);
;// CONCATENATED MODULE: external "node:crypto"
const external_node_crypto_namespaceObject = __WEBPACK_EXTERNAL_createRequire(import.meta.url)("node:crypto");
;// CONCATENATED MODULE: external "node:dns/promises"
const external_node_dns_promises_namespaceObject = __WEBPACK_EXTERNAL_createRequire(import.meta.url)("node:dns/promises");
// EXTERNAL MODULE: ./node_modules/.pnpm/@actions+cache@3.2.4/node_modules/@actions/cache/lib/cache.js
var cache = __nccwpck_require__(6878);
;// CONCATENATED MODULE: ./node_modules/.pnpm/@sindresorhus+is@6.3.1/node_modules/@sindresorhus/is/dist/index.js
@ -96717,7 +96719,7 @@ const external_node_child_process_namespaceObject = __WEBPACK_EXTERNAL_createReq
const external_node_stream_promises_namespaceObject = __WEBPACK_EXTERNAL_createRequire(import.meta.url)("node:stream/promises");
;// CONCATENATED MODULE: external "node:zlib"
const external_node_zlib_namespaceObject = __WEBPACK_EXTERNAL_createRequire(import.meta.url)("node:zlib");
;// CONCATENATED MODULE: ./node_modules/.pnpm/github.com+DeterminateSystems+detsys-ts@5fcb0532d85556ebc2de286e483885976531339d_uqngfub4ls4loys67iy653x57e/node_modules/detsys-ts/dist/index.js
;// CONCATENATED MODULE: ./node_modules/.pnpm/github.com+DeterminateSystems+detsys-ts@9d66d2c89c150f796165fdcc20b3be538807c0f4_46ybmzqhaua4eiwu3nj2qm63te/node_modules/detsys-ts/dist/index.js
var __defProp = Object.defineProperty;
var __export = (target, all) => {
for (var name in all)
@ -96803,9 +96805,9 @@ async function readAsyncOsReleaseFile(fileList, options) {
${fileData}`);
}
break;
} catch (error2) {
} catch (error3) {
if (options.debug) {
console.error(error2);
console.error(error3);
}
}
}
@ -96827,9 +96829,9 @@ function readSyncOsreleaseFile(releaseFileList, options) {
${fileData}`);
}
break;
} catch (error2) {
} catch (error3) {
if (options.debug) {
console.error(error2);
console.error(error3);
}
}
}
@ -97021,6 +97023,192 @@ function hashEnvironmentVariables(prefix, variables) {
return `${prefix}-${hash.digest("hex")}`;
}
// src/errors.ts
function stringifyError(e) {
if (e instanceof Error) {
return e.message;
} else if (typeof e === "string") {
return e;
} else {
return JSON.stringify(e);
}
}
// src/ids-host.ts
var DEFAULT_LOOKUP = "_detsys_ids._tcp.install.determinate.systems.";
var ALLOWED_SUFFIXES = [
".install.determinate.systems",
".install.detsys.dev"
];
var DEFAULT_IDS_HOST = "https://install.determinate.systems";
var LOOKUP = process.env["IDS_LOOKUP"] ?? DEFAULT_LOOKUP;
var IdsHost = class {
constructor(idsProjectName, diagnosticsSuffix, runtimeDiagnosticsUrl) {
this.idsProjectName = idsProjectName;
this.diagnosticsSuffix = diagnosticsSuffix;
this.runtimeDiagnosticsUrl = runtimeDiagnosticsUrl;
}
markCurrentHostBroken() {
this.prioritizedURLs?.shift();
}
setPrioritizedUrls(urls) {
this.prioritizedURLs = urls;
}
async getRootUrl() {
const idsHost = process.env["IDS_HOST"];
if (idsHost !== void 0) {
try {
return new URL(idsHost);
} catch (err) {
core.error(
`IDS_HOST environment variable is not a valid URL. Ignoring. ${stringifyError(err)}`
);
}
}
let url = void 0;
try {
const urls = await this.getUrlsByPreference();
url = urls[0];
} catch (err) {
core.error(
`Error collecting IDS URLs by preference: ${stringifyError(err)}`
);
}
if (url === void 0) {
url = new URL(DEFAULT_IDS_HOST);
}
return new URL(url);
}
async getDiagnosticsUrl() {
if (this.runtimeDiagnosticsUrl === "") {
return void 0;
}
if (this.runtimeDiagnosticsUrl !== "-" && this.runtimeDiagnosticsUrl !== void 0) {
try {
return new URL(this.runtimeDiagnosticsUrl);
} catch (err) {
core.info(
`User-provided diagnostic endpoint ignored: not a valid URL: ${stringifyError(err)}`
);
}
}
try {
const diagnosticUrl = await this.getRootUrl();
diagnosticUrl.pathname += this.idsProjectName;
diagnosticUrl.pathname += "/";
diagnosticUrl.pathname += this.diagnosticsSuffix || "diagnostics";
return diagnosticUrl;
} catch (err) {
core.info(
`Generated diagnostic endpoint ignored, and diagnostics are disabled: not a valid URL: ${stringifyError(err)}`
);
return void 0;
}
}
async getUrlsByPreference() {
if (this.prioritizedURLs === void 0) {
this.prioritizedURLs = orderRecordsByPriorityWeight(
await discoverServiceRecords()
).flatMap((record) => recordToUrl(record) || []);
}
return this.prioritizedURLs;
}
};
function recordToUrl(record) {
const urlStr = `https://${record.name}:${record.port}`;
try {
return new URL(urlStr);
} catch (err) {
core.debug(
`Record ${JSON.stringify(record)} produced an invalid URL: ${urlStr} (${err})`
);
return void 0;
}
}
async function discoverServiceRecords() {
return await discoverServicesStub((0,external_node_dns_promises_namespaceObject.resolveSrv)(LOOKUP), 1e3);
}
async function discoverServicesStub(lookup, timeout) {
const defaultFallback = new Promise(
(resolve, _reject) => {
setTimeout(resolve, timeout, []);
}
);
let records;
try {
records = await Promise.race([lookup, defaultFallback]);
} catch (reason) {
core.debug(`Error resolving SRV records: ${stringifyError(reason)}`);
records = [];
}
const acceptableRecords = records.filter((record) => {
for (const suffix of ALLOWED_SUFFIXES) {
if (record.name.endsWith(suffix)) {
return true;
}
}
core.debug(
`Unacceptable domain due to an invalid suffix: ${record.name}`
);
return false;
});
if (acceptableRecords.length === 0) {
core.debug(`No records found for ${LOOKUP}`);
} else {
core.debug(
`Resolved ${LOOKUP} to ${JSON.stringify(acceptableRecords)}`
);
}
return acceptableRecords;
}
function orderRecordsByPriorityWeight(records) {
const byPriorityWeight = /* @__PURE__ */ new Map();
for (const record of records) {
const existing = byPriorityWeight.get(record.priority);
if (existing) {
existing.push(record);
} else {
byPriorityWeight.set(record.priority, [record]);
}
}
const prioritizedRecords = [];
const keys = Array.from(byPriorityWeight.keys()).sort(
(a, b) => a - b
);
for (const priority of keys) {
const recordsByPrio = byPriorityWeight.get(priority);
if (recordsByPrio === void 0) {
continue;
}
prioritizedRecords.push(...weightedRandom(recordsByPrio));
}
return prioritizedRecords;
}
function weightedRandom(records) {
const scratchRecords = records.slice();
const result = [];
while (scratchRecords.length > 0) {
const weights = [];
{
for (let i = 0; i < scratchRecords.length; i++) {
weights.push(
scratchRecords[i].weight + (i > 0 ? scratchRecords[i - 1].weight : 0)
);
}
}
const point = Math.random() * weights[weights.length - 1];
for (let selectedIndex = 0; selectedIndex < weights.length; selectedIndex++) {
if (weights[selectedIndex] > point) {
result.push(scratchRecords.splice(selectedIndex, 1)[0]);
break;
}
}
}
return result;
}
// src/inputs.ts
var inputs_exports = {};
__export(inputs_exports, {
@ -97181,21 +97369,6 @@ function noisilyGetInput(suffix, legacyPrefix) {
// src/errors.ts
function stringifyError(e) {
if (e instanceof Error) {
return e.message;
} else if (typeof e === "string") {
return e;
} else {
return JSON.stringify(e);
}
}
// src/index.ts
var DEFAULT_IDS_HOST = "https://install.determinate.systems";
var IDS_HOST = process.env["IDS_HOST"] ?? DEFAULT_IDS_HOST;
var EVENT_EXCEPTION = "exception";
var EVENT_ARTIFACT_CACHE_HIT = "artifact_cache_hit";
var EVENT_ARTIFACT_CACHE_MISS = "artifact_cache_miss";
@ -97229,6 +97402,13 @@ var DetSysAction = class {
}
constructor(actionOptions) {
this.actionOptions = makeOptionsConfident(actionOptions);
this.idsHost = new IdsHost(
this.actionOptions.idsProjectName,
actionOptions.diagnosticsSuffix,
// Note: we don't use actionsCore.getInput('diagnostic-endpoint') on purpose:
// getInput silently converts absent data to an empty string.
process.env["INPUT_DIAGNOSTIC-ENDPOINT"]
);
this.exceptionAttachments = /* @__PURE__ */ new Map();
this.nixStoreTrust = "unknown";
this.strictMode = getBool("_internal-strict-mode");
@ -97240,9 +97420,9 @@ var DetSysAction = class {
},
hooks: {
beforeRetry: [
(error2, retryCount) => {
(error3, retryCount) => {
core.info(
`Retrying after error ${error2.code}, retry #: ${retryCount}`
`Retrying after error ${error3.code}, retry #: ${retryCount}`
);
}
]
@ -97319,8 +97499,8 @@ var DetSysAction = class {
* Execute the Action as defined.
*/
execute() {
this.executeAsync().catch((error2) => {
console.log(error2);
this.executeAsync().catch((error3) => {
console.log(error3);
process.exitCode = 1;
});
}
@ -97331,8 +97511,8 @@ var DetSysAction = class {
addFact(key, value) {
this.facts[key] = value;
}
getDiagnosticsUrl() {
return this.actionOptions.diagnosticsUrl;
async getDiagnosticsUrl() {
return await this.idsHost.getDiagnosticsUrl();
}
getUniqueId() {
return this.identity.run_differentiator || process.env.RUNNER_TRACKING_ID || (0,external_node_crypto_namespaceObject.randomUUID)();
@ -97445,8 +97625,8 @@ var DetSysAction = class {
`Downloading ${this.actionOptions.name} for ${this.architectureFetchSuffix}`
);
try {
core.info(`Fetching from ${this.getSourceUrl()}`);
const correlatedUrl = this.getSourceUrl();
core.info(`Fetching from ${await this.getSourceUrl()}`);
const correlatedUrl = await this.getSourceUrl();
correlatedUrl.searchParams.set("ci", "github");
correlatedUrl.searchParams.set(
"correlation",
@ -97457,7 +97637,7 @@ var DetSysAction = class {
const v = versionCheckup.headers.etag;
this.addFact(FACT_SOURCE_URL_ETAG, v);
core.debug(
`Checking the tool cache for ${this.getSourceUrl()} at ${v}`
`Checking the tool cache for ${await this.getSourceUrl()} at ${v}`
);
const cached = await this.getCachedVersion(v);
if (cached) {
@ -97505,13 +97685,13 @@ var DetSysAction = class {
this.recordEvent(`complete_${this.executionPhase}`);
await this.submitEvents();
}
getSourceUrl() {
async getSourceUrl() {
const p = this.sourceParameters;
if (p.url) {
this.addFact(FACT_SOURCE_URL, p.url);
return new URL(p.url);
}
const fetchUrl = new URL(IDS_HOST);
const fetchUrl = await this.idsHost.getRootUrl();
fetchUrl.pathname += this.actionOptions.idsProjectName;
if (p.tag) {
fetchUrl.pathname += `/tag/${p.tag}`;
@ -97667,7 +97847,8 @@ var DetSysAction = class {
}
}
async submitEvents() {
if (this.actionOptions.diagnosticsUrl === void 0) {
const diagnosticsUrl = await this.idsHost.getDiagnosticsUrl();
if (diagnosticsUrl === void 0) {
core.debug(
"Diagnostics are disabled. Not sending the following events:"
);
@ -97680,7 +97861,7 @@ var DetSysAction = class {
events: this.events
};
try {
await this.client.post(this.actionOptions.diagnosticsUrl, {
await this.client.post(diagnosticsUrl, {
json: batch,
timeout: {
request: DIAGNOSTIC_ENDPOINT_TIMEOUT_MS
@ -97690,12 +97871,28 @@ var DetSysAction = class {
core.debug(
`Error submitting diagnostics event: ${stringifyError2(e)}`
);
this.idsHost.markCurrentHostBroken();
const secondaryDiagnosticsUrl = await this.idsHost.getDiagnosticsUrl();
if (secondaryDiagnosticsUrl !== void 0) {
try {
await this.client.post(secondaryDiagnosticsUrl, {
json: batch,
timeout: {
request: DIAGNOSTIC_ENDPOINT_TIMEOUT_MS
}
});
} catch (err) {
core.debug(
`Error submitting diagnostics event to secondary host (${secondaryDiagnosticsUrl}): ${stringifyError2(err)}`
);
}
}
}
this.events = [];
}
};
function stringifyError2(error2) {
return error2 instanceof Error || typeof error2 == "string" ? error2.toString() : JSON.stringify(error2);
function stringifyError2(error3) {
return error3 instanceof Error || typeof error3 == "string" ? error3.toString() : JSON.stringify(error3);
}
function makeOptionsConfident(actionOptions) {
const idsProjectName = actionOptions.idsProjectName ?? actionOptions.name;
@ -97705,72 +97902,12 @@ function makeOptionsConfident(actionOptions) {
eventPrefix: actionOptions.eventPrefix || "action:",
fetchStyle: actionOptions.fetchStyle,
legacySourcePrefix: actionOptions.legacySourcePrefix,
requireNix: actionOptions.requireNix,
diagnosticsUrl: determineDiagnosticsUrl(
idsProjectName,
actionOptions.diagnosticsUrl
)
requireNix: actionOptions.requireNix
};
core.debug("idslib options:");
core.debug(JSON.stringify(finalOpts, void 0, 2));
return finalOpts;
}
function determineDiagnosticsUrl(idsProjectName, urlOption) {
if (urlOption === null) {
return void 0;
}
if (urlOption !== void 0) {
return urlOption;
}
{
const providedDiagnosticEndpoint = process.env["INPUT_DIAGNOSTIC-ENDPOINT"];
if (providedDiagnosticEndpoint === "") {
return void 0;
}
if (providedDiagnosticEndpoint !== void 0) {
try {
return mungeDiagnosticEndpoint(new URL(providedDiagnosticEndpoint));
} catch (e) {
core.info(
`User-provided diagnostic endpoint ignored: not a valid URL: ${stringifyError2(e)}`
);
}
}
}
try {
const diagnosticUrl = new URL(IDS_HOST);
diagnosticUrl.pathname += idsProjectName;
diagnosticUrl.pathname += "/diagnostics";
return diagnosticUrl;
} catch (e) {
core.info(
`Generated diagnostic endpoint ignored: not a valid URL: ${stringifyError2(e)}`
);
}
return void 0;
}
function mungeDiagnosticEndpoint(inputUrl) {
if (DEFAULT_IDS_HOST === IDS_HOST) {
return inputUrl;
}
try {
const defaultIdsHost = new URL(DEFAULT_IDS_HOST);
const currentIdsHost = new URL(IDS_HOST);
if (inputUrl.origin !== defaultIdsHost.origin) {
return inputUrl;
}
inputUrl.protocol = currentIdsHost.protocol;
inputUrl.host = currentIdsHost.host;
inputUrl.username = currentIdsHost.username;
inputUrl.password = currentIdsHost.password;
return inputUrl;
} catch (e) {
core.info(
`Default or overridden IDS host isn't a valid URL: ${stringifyError2(e)}`
);
}
return inputUrl;
}
/*!
* linux-release-info
@ -97816,7 +97953,8 @@ var NixInstallerAction = class extends DetSysAction {
name: "nix-installer",
fetchStyle: "nix-style",
legacySourcePrefix: "nix-installer",
requireNix: "ignore"
requireNix: "ignore",
diagnosticsSuffix: "diagnostic"
});
this.platform = platform_exports.getNixPlatform(platform_exports.getArchOs());
this.nixPackageUrl = inputs_exports.getStringOrNull("nix-package-url");
@ -98085,7 +98223,7 @@ ${stderrBuffer}`
if (this.sslCertFile !== null) {
executionEnv.NIX_INSTALLER_SSL_CERT_FILE = this.sslCertFile;
}
executionEnv.NIX_INSTALLER_DIAGNOSTIC_ENDPOINT = this.getDiagnosticsUrl()?.toString() ?? "";
executionEnv.NIX_INSTALLER_DIAGNOSTIC_ENDPOINT = (await this.getDiagnosticsUrl())?.toString() ?? "";
if (this.macEncrypt !== null) {
if (!this.isMacOS) {
throw new Error("`mac-encrypt` while `$RUNNER_OS` was not `macOS`");

View File

@ -16,7 +16,7 @@ dependencies:
version: 5.1.1
detsys-ts:
specifier: github:DeterminateSystems/detsys-ts
version: github.com/DeterminateSystems/detsys-ts/5fcb0532d85556ebc2de286e483885976531339d
version: github.com/DeterminateSystems/detsys-ts/9d66d2c89c150f796165fdcc20b3be538807c0f4
string-argv:
specifier: ^0.3.2
version: 0.3.2
@ -444,7 +444,7 @@ packages:
"@babel/helper-split-export-declaration": 7.24.6
"@babel/parser": 7.24.6
"@babel/types": 7.24.6
debug: 4.3.4
debug: 4.3.5
globals: 11.12.0
transitivePeerDependencies:
- supports-color
@ -778,7 +778,7 @@ packages:
engines: { node: ^12.22.0 || ^14.17.0 || >=16.0.0 }
dependencies:
ajv: 6.12.6
debug: 4.3.4
debug: 4.3.5
espree: 9.6.1
globals: 13.24.0
ignore: 5.3.1
@ -821,7 +821,7 @@ packages:
engines: { node: ">=10.10.0" }
dependencies:
"@humanwhocodes/object-schema": 2.0.3
debug: 4.3.4
debug: 4.3.5
minimatch: 3.1.2
transitivePeerDependencies:
- supports-color
@ -1402,7 +1402,7 @@ packages:
"@typescript-eslint/types": 7.11.0
"@typescript-eslint/typescript-estree": 7.11.0(typescript@5.4.5)
"@typescript-eslint/visitor-keys": 7.11.0
debug: 4.3.4
debug: 4.3.5
eslint: 8.57.0
typescript: 5.4.5
transitivePeerDependencies:
@ -1435,7 +1435,7 @@ packages:
dependencies:
"@typescript-eslint/typescript-estree": 7.11.0(typescript@5.4.5)
"@typescript-eslint/utils": 7.11.0(eslint@8.57.0)(typescript@5.4.5)
debug: 4.3.4
debug: 4.3.5
eslint: 8.57.0
ts-api-utils: 1.3.0(typescript@5.4.5)
typescript: 5.4.5
@ -1465,7 +1465,7 @@ packages:
dependencies:
"@typescript-eslint/types": 7.11.0
"@typescript-eslint/visitor-keys": 7.11.0
debug: 4.3.4
debug: 4.3.5
globby: 11.1.0
is-glob: 4.0.3
minimatch: 9.0.4
@ -1832,7 +1832,7 @@ packages:
hasBin: true
dependencies:
caniuse-lite: 1.0.30001625
electron-to-chromium: 1.4.784
electron-to-chromium: 1.4.787
node-releases: 2.0.14
update-browserslist-db: 1.0.16(browserslist@4.23.0)
dev: true
@ -2078,10 +2078,10 @@ packages:
ms: 2.1.3
dev: true
/debug@4.3.4:
/debug@4.3.5:
resolution:
{
integrity: sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==,
integrity: sha512-pt0bNEmneDIvdL1Xsd9oDQ/wrQRkXDT4AUWlNZNPKvW5x/jyO9VFXkJUP07vQ2upmw5PlaITaPKc31jK13V+jg==,
}
engines: { node: ">=6.0" }
peerDependencies:
@ -2202,10 +2202,10 @@ packages:
}
dev: true
/electron-to-chromium@1.4.784:
/electron-to-chromium@1.4.787:
resolution:
{
integrity: sha512-9CZwh+sDrhDAeOEFh8s3PqwduzTyYIeYwZolc1b9ENAUt3ePu7R1sJSCWr/820ISssRxCJUyHI9Wb7j+0Uo1AA==,
integrity: sha512-d0EFmtLPjctczO3LogReyM2pbBiiZbnsKnGF+cdZhsYzHm/A0GV7W94kqzLD8SN4O3f3iHlgLUChqghgyznvCQ==,
}
dev: true
@ -2466,7 +2466,7 @@ packages:
eslint: "*"
eslint-plugin-import: "*"
dependencies:
debug: 4.3.4
debug: 4.3.5
enhanced-resolve: 5.16.1
eslint: 8.57.0
eslint-module-utils: 2.8.1(@typescript-eslint/parser@7.11.0)(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.1)(eslint@8.57.0)
@ -2746,7 +2746,7 @@ packages:
ajv: 6.12.6
chalk: 4.1.2
cross-spawn: 7.0.3
debug: 4.3.4
debug: 4.3.5
doctrine: 3.0.0
escape-string-regexp: 4.0.0
eslint-scope: 7.2.2
@ -5068,7 +5068,7 @@ packages:
bundle-require: 4.1.0(esbuild@0.19.12)
cac: 6.7.14
chokidar: 3.6.0
debug: 4.3.4
debug: 4.3.5
esbuild: 0.19.12
execa: 5.1.1
globby: 11.1.0
@ -5432,10 +5432,10 @@ packages:
engines: { node: ">=10" }
dev: true
github.com/DeterminateSystems/detsys-ts/5fcb0532d85556ebc2de286e483885976531339d:
github.com/DeterminateSystems/detsys-ts/9d66d2c89c150f796165fdcc20b3be538807c0f4:
resolution:
{
tarball: https://codeload.github.com/DeterminateSystems/detsys-ts/tar.gz/5fcb0532d85556ebc2de286e483885976531339d,
tarball: https://codeload.github.com/DeterminateSystems/detsys-ts/tar.gz/9d66d2c89c150f796165fdcc20b3be538807c0f4,
}
name: detsys-ts
version: 1.0.0

View File

@ -80,6 +80,7 @@ class NixInstallerAction extends DetSysAction {
fetchStyle: "nix-style",
legacySourcePrefix: "nix-installer",
requireNix: "ignore",
diagnosticsSuffix: "diagnostic",
});
this.platform = platform.getNixPlatform(platform.getArchOs());
@ -402,7 +403,7 @@ class NixInstallerAction extends DetSysAction {
}
executionEnv.NIX_INSTALLER_DIAGNOSTIC_ENDPOINT =
this.getDiagnosticsUrl()?.toString() ?? "";
(await this.getDiagnosticsUrl())?.toString() ?? "";
// TODO: Error if the user uses these on not-MacOS
if (this.macEncrypt !== null) {