Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

include tus endpoint in critical health checks #29

Merged
merged 5 commits into from
Aug 19, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
"lodash": "^4.17.21",
"lowdb": "^1.0.0",
"skynet-js": "^4.3.0",
"tus-js-client": "^3.0.0",
"write-file-atomic": "^4.0.1",
"yargs": "^17.5.1"
},
Expand Down
54 changes: 47 additions & 7 deletions src/checks/critical.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,17 @@ 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, getResponseContent, isPortalModuleEnabled } = require("../utils");
const { SkynetClient, stringToUint8ArrayUtf8, genKeyPairAndSeed } = require("skynet-js");
const { SkynetClient, genKeyPairAndSeed } = require("skynet-js");

const MODULE_BLOCKER = "b";

const skynetClient = new SkynetClient(`https://${process.env.PORTAL_DOMAIN}`, {
skynetApiKey: process.env.ACCOUNTS_TEST_USER_API_KEY,
});
const exampleSkylink = "AACogzrAimYPG42tDOKhS3lXZD8YvlF8Q8R17afe95iV2Q";
const exampleSkylinkBase32 = "000ah0pqo256c3orhmmgpol19dslep1v32v52v23ohqur9uuuuc9bm8";

// this resolver skylink points to latest release of webportal-website and
// is updated automatically on each merged pull request via github-actions
Expand All @@ -23,7 +25,10 @@ async function skydConfigCheck(done) {
const data = { up: false };

try {
const response = await got(`http://10.10.10.10:9980/renter`, { headers: { "User-Agent": "Sia-Agent" } }).json();
const response = await got(`http://10.10.10.10:9980/renter`, {
headers: { "User-Agent": "Sia-Agent" },
timeout: { connect: 5000 }, // timeout after 5 seconds when skyd is not available
kwypchlo marked this conversation as resolved.
Show resolved Hide resolved
}).json();

// make sure initial funding is set to 10SC
if (response.settings.allowance.paymentcontractinitialfunding !== "10000000000000000000000000") {
Expand All @@ -49,6 +54,7 @@ async function skydWorkersCooldownCheck(done) {
try {
const response = await got(`http://10.10.10.10:9980/renter/workers`, {
headers: { "User-Agent": "Sia-Agent" },
timeout: { connect: 5000 }, // timeout after 5 seconds when skyd is not available
}).json();

const workersCooldown =
Expand Down Expand Up @@ -102,35 +108,68 @@ async function uploadCheck(done) {
done({ name: "upload_file", time: calculateElapsedTime(time), ...data });
}

// uploadTusCheck returns the result of uploading a sample file through tus endpoint
async function uploadTusCheck(done) {
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
const data = { up: false };

try {
const upload = new tus.Upload(payload, {
endpoint: `https://${process.env.PORTAL_DOMAIN}/skynet/tus`,
headers,
onError: (error) => {
done({ name: "upload_file_tus", time: calculateElapsedTime(time), ...data, errorMessage: error.message });
},
onSuccess: async () => {
const response = await got.head(upload.url, { headers });
const skylink = response.headers["skynet-skylink"];

done({ name: "upload_file_tus", time: calculateElapsedTime(time), ...data, skylink, up: Boolean(skylink) });
},
});

upload.start();
} catch (error) {
data.statusCode = error.response?.statusCode || error.statusCode || error.status;
data.errorMessage = error.message;
data.errorResponseContent = getResponseContent(error.response);
data.ip = error?.response?.ip ?? null;

done({ name: "upload_file_tus", time: calculateElapsedTime(time), ...data });
}
}

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

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

return done(await genericAccessCheck("skylink", url));
}

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

return done(await genericAccessCheck("resolver_skylink", url));
}

// skylinkSubdomainCheck returns the result of downloading the hard coded link via subdomain
async function skylinkSubdomainCheck(done) {
const url = await skynetClient.getSkylinkUrl(exampleSkylink, { subdomain: true });
const url = `https://${exampleSkylinkBase32}.${process.env.PORTAL_DOMAIN}`;

return done(await genericAccessCheck("skylink_via_subdomain", url));
}

// handshakeSubdomainCheck returns the result of downloading the skylink via handshake domain
async function handshakeSubdomainCheck(done) {
const url = await skynetClient.getHnsUrl("note-to-self", { subdomain: true });
const url = `https://note-to-self.hns.${process.env.PORTAL_DOMAIN}`;

return done(await genericAccessCheck("hns_via_subdomain", url));
}
Expand All @@ -147,7 +186,7 @@ async function registryWriteAndReadCheck(done) {
const time = process.hrtime();
const data = { name: "registry_write_and_read", up: false };
const { privateKey, publicKey } = genKeyPairAndSeed();
const expected = { dataKey: "foo-key", data: stringToUint8ArrayUtf8("foo-data"), revision: BigInt(0) };
const expected = { dataKey: "foo-key", data: Uint8Array.from(Buffer.from("foo-data", "utf-8")), revision: BigInt(0) };

try {
await skynetClient.registry.setEntry(privateKey, expected);
Expand Down Expand Up @@ -278,6 +317,7 @@ const checks = [
skydConfigCheck,
skydWorkersCooldownCheck,
uploadCheck,
uploadTusCheck,
websiteCheck,
downloadSkylinkCheck,
downloadResolverSkylinkCheck,
Expand Down
10 changes: 4 additions & 6 deletions src/checks/extended.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ const hasha = require("hasha");
const { detailedDiff } = require("deep-object-diff");
const { isEqual } = require("lodash");
const { calculateElapsedTime, ensureValidJSON, getResponseContent } = require("../utils");
const { parseSkylink } = require("skynet-js");

// audioExampleCheck returns the result of trying to download the skylink
// for the Example audio file on siasky.net
Expand Down Expand Up @@ -690,7 +689,7 @@ function pdfExampleCheck(done) {
function skyBayCheck(done) {
const linkInfo = {
name: "SkyBay",
skylink: "EABkMjXzxJRpPz0eO0Or5fy2eo-rz3prdigGwRlyNd9mwA/",
skylink: "EABkMjXzxJRpPz0eO0Or5fy2eo-rz3prdigGwRlyNd9mwA",
bodyHash: "dfc0b1d3d1113254d7545d19f6118855ed9c778b",
metadata: {
filename: "skybay.html",
Expand Down Expand Up @@ -731,7 +730,7 @@ function skyBayRedirectCheck(done) {
function skyBinCheck(done) {
const linkInfo = {
name: "SkyBin",
skylink: "CAAVU14pB9GRIqCrejD7rlS27HltGGiiCLICzmrBV0wVtA/",
skylink: "CAAVU14pB9GRIqCrejD7rlS27HltGGiiCLICzmrBV0wVtA",
bodyHash: "858ff733c4cb06a80060b8a62cf303fd5a051651",
metadata: { filename: "skybin.html" },
headers: {
Expand Down Expand Up @@ -769,7 +768,7 @@ const skyGalleryMetadata = require("../fixtures/skygalleryMetadata.json");
function skyGalleryCheck(done) {
const linkInfo = {
name: "SkyGallery",
skylink: "AADW6GsQcetwDBaDYnGCSTbYjSKY743NtY1A5VRx5sj3Dg/",
skylink: "AADW6GsQcetwDBaDYnGCSTbYjSKY743NtY1A5VRx5sj3Dg",
bodyHash: skyGalleryBodyHash,
metadata: skyGalleryMetadata,
headers: {
Expand Down Expand Up @@ -1172,8 +1171,7 @@ async function skylinkVerification(done, expected, { followRedirect = true, meth
}

if (expected.metadata && expected.skylink) {
const skylink = parseSkylink(expected.skylink);
const url = `https://${process.env.PORTAL_DOMAIN}/skynet/metadata/${skylink}`;
const url = `https://${process.env.PORTAL_DOMAIN}/skynet/metadata/${expected.skylink}`;
try {
const metadata = await got(url, {
headers: { "Skynet-Api-Key": process.env.ACCOUNTS_TEST_USER_API_KEY },
Expand Down
Loading