Skip to content

Commit

Permalink
Merge pull request #39 from SkynetLabs/esm
Browse files Browse the repository at this point in the history
migrate codebase to esm
  • Loading branch information
kwypchlo authored Oct 5, 2022
2 parents 5f023d8 + c44b98c commit ad39ed0
Show file tree
Hide file tree
Showing 19 changed files with 314 additions and 430 deletions.
4 changes: 2 additions & 2 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
FROM node:16.14.2-alpine
FROM node:18.10.0-alpine

RUN apk add --no-cache dnsmasq~=2
RUN apk add --no-cache git~=2 dnsmasq~=2

WORKDIR /usr/app

Expand Down
86 changes: 2 additions & 84 deletions bin/cli
Original file line number Diff line number Diff line change
@@ -1,85 +1,3 @@
#!/usr/bin/env node
#!/bin/ash

process.env.NODE_ENV = process.env.NODE_ENV || "production";

require("yargs/yargs")(process.argv.slice(2))
.help()
.demandCommand()
.strict(true)
.command(
"enable",
"Mark portal as enabled",
() => {},
() => {
const db = require("../src/db");

db.set("disabled", false).write();
}
)
.command(
"disable <reason>",
"Mark portal as disabled (provide meaningful reason)",
() => {},
({ reason }) => {
const db = require("../src/db");

db.set("disabled", reason).write();
}
)
.command(
"run <type>",
"Skynet portal health checks",
(yargs) => {
yargs
.positional("type", {
describe: "Type of checks to run",
type: "string",
choices: ["critical", "extended"],
})
.option("portal-url", {
describe: "Skynet portal url",
default: process.env.PORTAL_DOMAIN ? `https://${process.env.PORTAL_DOMAIN}` : "https://siasky.net",
type: "string",
})
.option("state-dir", {
describe: "State directory",
default: process.env.STATE_DIR || "state",
type: "string",
});
},
async ({ type, portalUrl, stateDir }) => {
const { hostname: portalDomain } = new URL(portalUrl); // extract domain from portal url
process.env.PORTAL_DOMAIN = portalDomain;
process.env.STATE_DIR = stateDir;

const util = require("util");
const { getYesterdayISOString } = require("../src/utils");
const createMiddleware = require("../src/checks/middleware");
const db = require("../src/db");
const checks = require(`../src/checks/${type}`);
const middleware = await createMiddleware();

const entry = {
date: new Date().toISOString(),
// run all checks, filter empty responses (skipped) and pass the response through the middleware
checks: (await Promise.all(checks.map((check) => check()))).filter(Boolean).map(middleware),
};

db.read() // read before writing to make sure no external changes are overwritten
.get(type) // get the list of records of given type
.push(entry) // insert new record
.remove(({ date }) => date < getYesterdayISOString()) // drop old records
.write();

// exit with code 1 if any of the checks report failure
if (entry.checks.some(({ up }) => !up)) {
console.log(
util.inspect(
entry.checks.filter(({ up }) => !up),
{ colors: true, depth: 7 } // increase depth to ensure errors are printed
)
);
process.exit(1);
}
}
).argv;
node /usr/app/src/cli $@
13 changes: 6 additions & 7 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,22 +2,21 @@
"name": "health-check",
"version": "1.0.0",
"main": "index.js",
"type": "module",
"license": "MIT",
"dependencies": {
"blakejs": "^1.2.1",
"deep-object-diff": "^1.1.7",
"express": "^4.18.1",
"form-data": "^4.0.0",
"got": "^11.8.3",
"graceful-fs": "^4.2.10",
"got": "^12.5.1",
"hasha": "^5.2.2",
"http-status-codes": "^2.2.0",
"lodash": "^4.17.21",
"lowdb": "^1.0.0",
"pbkdf2-hmac": "^1.0.4",
"lodash-es": "^4.17.21",
"lowdb": "^3.0.0",
"pbkdf2-hmac": "https://github.com/juanelas/pbkdf2-hmac#3cdd22969f944ed47d77ba715677290c36ab1187",
"tus-js-client": "^3.0.1",
"tweetnacl": "^1.0.3",
"write-file-atomic": "^4.0.1",
"yargs": "^17.6.0"
},
"devDependencies": {
Expand All @@ -27,7 +26,7 @@
"scripts": {
"lint": "yarn prettier --check .",
"format": "yarn prettier --write .",
"test": "yarn jest",
"test": "node --experimental-vm-modules $(yarn bin jest)",
"build": "echo 'Warning: no build script specified'"
}
}
28 changes: 0 additions & 28 deletions src/adapters/FileSyncAtomic.js

This file was deleted.

59 changes: 21 additions & 38 deletions src/checks/critical.js
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
const util = require("node:util");
const got = require("got");
const FormData = require("form-data");
const { isEqual } = require("lodash");
const tus = require("tus-js-client");
const { calculateElapsedTime, getResponseErrorData, isPortalModuleEnabled } = require("../utils");
const { genKeyPairAndSeed, getRegistryEntry, setRegistryEntry } = require("../utils-registry");
import util from "node:util";
import got from "got";
import FormData from "form-data";
import { isEqual } from "lodash-es";
import tus from "tus-js-client";
import { calculateElapsedTime, getResponseErrorData, isPortalModuleEnabled } from "../utils.js";
import { genKeyPairAndSeed, getRegistryEntry, setRegistryEntry } from "../utils-registry.js";

const exampleSkylink = "AACogzrAimYPG42tDOKhS3lXZD8YvlF8Q8R17afe95iV2Q";
const exampleSkylinkBase32 = "000ah0pqo256c3orhmmgpol19dslep1v32v52v23ohqur9uuuuc9bm8";
Expand All @@ -15,7 +15,7 @@ const exampleSkylinkBase32 = "000ah0pqo256c3orhmmgpol19dslep1v32v52v23ohqur9uuuu
const exampleResolverSkylink = "AQCExZYFmmc75OPgjPpHuF4WVN0pc4FX2p09t4naLKfTLw";

// check that any relevant configuration is properly set in skyd
async function skydConfigCheck() {
export async function skydConfigCheck() {
const time = process.hrtime();
const data = { up: false };

Expand All @@ -39,7 +39,7 @@ async function skydConfigCheck() {
}

// check skyd for total number of workers on cooldown
async function skydWorkersCooldownCheck() {
export async function skydWorkersCooldownCheck() {
const workersCooldownThreshold = 0.6; // set to 60% initially, can be increased later
const time = process.hrtime();
const data = { up: false };
Expand Down Expand Up @@ -72,7 +72,7 @@ async function skydWorkersCooldownCheck() {
}

// uploadCheck returns the result of uploading a sample file
async function uploadCheck() {
export async function uploadCheck() {
const time = process.hrtime();
const form = new FormData();
const payload = Buffer.from(new Date()); // current date to ensure data uniqueness
Expand All @@ -97,7 +97,7 @@ async function uploadCheck() {
}

// uploadTusCheck returns the result of uploading a sample file through tus endpoint
async function uploadTusCheck() {
export async function uploadTusCheck() {
const time = process.hrtime();
const headers = { "Skynet-Api-Key": process.env.ACCOUNTS_TEST_USER_API_KEY ?? "" };
const payload = Buffer.from(new Date()); // current date to ensure data uniqueness
Expand Down Expand Up @@ -128,40 +128,40 @@ async function uploadTusCheck() {
}

// websiteCheck checks whether the main website is working
async function websiteCheck() {
export async function websiteCheck() {
return genericAccessCheck("website", `https://${process.env.PORTAL_DOMAIN}`);
}

// downloadSkylinkCheck returns the result of downloading the hard coded link
async function downloadSkylinkCheck() {
export async function downloadSkylinkCheck() {
const url = `https://${process.env.PORTAL_DOMAIN}/${exampleSkylink}`;

return genericAccessCheck("skylink", url);
}

// downloadResolverSkylinkCheck returns the result of downloading an example resolver skylink
async function downloadResolverSkylinkCheck() {
export async function downloadResolverSkylinkCheck() {
const url = `https://${process.env.PORTAL_DOMAIN}/${exampleResolverSkylink}`;

return genericAccessCheck("resolver_skylink", url);
}

// skylinkSubdomainCheck returns the result of downloading the hard coded link via subdomain
async function skylinkSubdomainCheck() {
export async function skylinkSubdomainCheck() {
const url = `https://${exampleSkylinkBase32}.${process.env.PORTAL_DOMAIN}`;

return genericAccessCheck("skylink_via_subdomain", url);
}

// handshakeSubdomainCheck returns the result of downloading the skylink via handshake domain
async function handshakeSubdomainCheck() {
export async function handshakeSubdomainCheck() {
const url = `https://note-to-self.hns.${process.env.PORTAL_DOMAIN}`;

return genericAccessCheck("hns_via_subdomain", url);
}

// accountWebsiteCheck returns the result of accessing account dashboard website
async function accountWebsiteCheck() {
export async function accountWebsiteCheck() {
if (!isPortalModuleEnabled("a")) return; // runs only when accounts are enabled

const url = `https://account.${process.env.PORTAL_DOMAIN}/auth/login`;
Expand All @@ -170,7 +170,7 @@ async function accountWebsiteCheck() {
}

// registryWriteAndReadCheck writes to registry and immediately reads and compares the data
async function registryWriteAndReadCheck() {
export async function registryWriteAndReadCheck() {
const time = process.hrtime();
const data = { name: "registry_write_and_read", up: false };
const { privateKey, publicKey } = await genKeyPairAndSeed();
Expand Down Expand Up @@ -202,7 +202,7 @@ async function registryWriteAndReadCheck() {
}

// directServerApiAccessCheck returns the basic server api check on direct server address
async function directServerApiAccessCheck() {
export async function directServerApiAccessCheck() {
// skip if SERVER_DOMAIN is not set or it equals PORTAL_DOMAIN (single server portals)
if (!process.env.SERVER_DOMAIN || process.env.SERVER_DOMAIN === process.env.PORTAL_DOMAIN) {
return;
Expand All @@ -229,7 +229,7 @@ async function directServerApiAccessCheck() {
}

// accountHealthCheck returns the result of accounts service health checks
async function accountHealthCheck(retries = 2) {
export async function accountHealthCheck(retries = 2) {
if (!isPortalModuleEnabled("a")) return; // runs only when accounts are enabled

const time = process.hrtime();
Expand All @@ -255,7 +255,7 @@ async function accountHealthCheck(retries = 2) {
}

// blockerHealthCheck returns the result of blocker container health endpoint
async function blockerHealthCheck(retries = 2) {
export async function blockerHealthCheck(retries = 2) {
if (!isPortalModuleEnabled("b")) return; // runs only when blocker is enabled

const time = process.hrtime();
Expand Down Expand Up @@ -297,20 +297,3 @@ async function genericAccessCheck(name, url) {

return { name, time: calculateElapsedTime(time), ...data };
}

module.exports = [
skydConfigCheck,
skydWorkersCooldownCheck,
uploadCheck,
uploadTusCheck,
websiteCheck,
downloadSkylinkCheck,
downloadResolverSkylinkCheck,
skylinkSubdomainCheck,
handshakeSubdomainCheck,
registryWriteAndReadCheck,
directServerApiAccessCheck,
accountHealthCheck,
accountWebsiteCheck,
blockerHealthCheck,
];
14 changes: 7 additions & 7 deletions src/checks/extended.js
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
const got = require("got");
const hasha = require("hasha");
const { detailedDiff } = require("deep-object-diff");
const { isEqual } = require("lodash");
const { calculateElapsedTime, ensureValidJSON, getResponseContent, parseHeaderString } = require("../utils");
const extendedChecks = require("../fixtures/extendedChecks.json");
import got from "got";
import hasha from "hasha";
import { detailedDiff } from "deep-object-diff";
import { isEqual } from "lodash-es";
import { calculateElapsedTime, ensureValidJSON, getResponseContent, parseHeaderString } from "../utils.js";
import extendedChecks from "../fixtures/extendedChecks.json" assert { type: "json" };

/**
*
Expand Down Expand Up @@ -110,6 +110,6 @@ async function executeExtendedCheck(name, expected, config = {}) {
}
}

module.exports = extendedChecks.map((extendedCheck) => {
export default extendedChecks.map((extendedCheck) => {
return () => executeExtendedCheck(extendedCheck.name, extendedCheck.data, extendedCheck.config);
});
8 changes: 4 additions & 4 deletions src/checks/middleware.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
const got = require("got");
const { ipCheckService, ipRegex } = require("../utils");
import got from "got";
import { ipCheckService, ipRegex } from "../utils.js";

/**
* Ask ip check service for current machine external ip address
Expand Down Expand Up @@ -29,7 +29,7 @@ async function getCurrentAddress() {
}
}

module.exports = async function middleware() {
export default async function middleware() {
const ip = await getCurrentAddress(); // get current machine ip address

return (check) => {
Expand All @@ -47,4 +47,4 @@ module.exports = async function middleware() {

return check;
};
};
}
Loading

0 comments on commit ad39ed0

Please sign in to comment.