From b77d855ce721abe6dce436124c468c939be78ecc Mon Sep 17 00:00:00 2001 From: pablomendezroyo Date: Mon, 9 Feb 2026 10:37:40 +0100 Subject: [PATCH] await normalizeIpfsProvider in IPFS functions and tests for improved async handling --- .../ipfsNode/addDirFromUrls.ts | 3 +- src/releaseUploader/ipfsNode/addFromFs.ts | 2 +- src/releaseUploader/ipfsNode/ipfsProvider.ts | 53 +++++++++++++++++-- src/releaseUploader/ipfsNode/ipfsVersion.ts | 2 +- test/commands/build.test.ts | 2 +- 5 files changed, 54 insertions(+), 8 deletions(-) diff --git a/src/releaseUploader/ipfsNode/addDirFromUrls.ts b/src/releaseUploader/ipfsNode/addDirFromUrls.ts index 66b5757d..54873e69 100644 --- a/src/releaseUploader/ipfsNode/addDirFromUrls.ts +++ b/src/releaseUploader/ipfsNode/addDirFromUrls.ts @@ -28,8 +28,9 @@ export async function ipfsAddDirFromUrls( } // Parse the ipfsProvider the a full base apiUrl + const apiUrl = await normalizeIpfsProvider(ipfsProvider); const res = await got({ - prefixUrl: normalizeIpfsProvider(ipfsProvider), + prefixUrl: apiUrl, url: "api/v0/add", method: "POST", headers: form.getHeaders(), diff --git a/src/releaseUploader/ipfsNode/addFromFs.ts b/src/releaseUploader/ipfsNode/addFromFs.ts index 1a338db3..cba274d1 100644 --- a/src/releaseUploader/ipfsNode/addFromFs.ts +++ b/src/releaseUploader/ipfsNode/addFromFs.ts @@ -19,7 +19,7 @@ export async function ipfsAddFromFs( // Parse the ipfsProvider the a full base apiUrl let lastPercent = -1; - const apiUrl = normalizeIpfsProvider(ipfsProvider); + const apiUrl = await normalizeIpfsProvider(ipfsProvider); const res = await got({ prefixUrl: apiUrl, url: "api/v0/add", diff --git a/src/releaseUploader/ipfsNode/ipfsProvider.ts b/src/releaseUploader/ipfsNode/ipfsProvider.ts index 33b38335..3f1bb036 100644 --- a/src/releaseUploader/ipfsNode/ipfsProvider.ts +++ b/src/releaseUploader/ipfsNode/ipfsProvider.ts @@ -1,8 +1,53 @@ import { URL } from "url"; +import dns from "dns"; +import { promisify } from "util"; +import { shell } from "../../utils/shell.js"; -function getIpfsProviderUrl(provider = "dappnode"): string { +const dnsLookup = promisify(dns.lookup); + +const DAPPNODE_IPFS_HOST = "ipfs.dappnode"; +const DAPPNODE_IPFS_CONTAINER = "DAppNodeCore-ipfs.dnp.dappnode.eth"; + +/** + * Check if a hostname can be resolved via DNS + */ +async function canResolveHost(hostname: string): Promise { + try { + await dnsLookup(hostname); + return true; + } catch { + return false; + } +} + +/** + * Get the IP address of the IPFS container from Docker + * @throws If the container does not exist or has no IP + */ +async function getIpfsContainerIp(): Promise { + const ip = await shell( + `docker inspect ${DAPPNODE_IPFS_CONTAINER} --format '{{.NetworkSettings.Networks.dncore_network.IPAddress}}'` + ); + + if (!ip || ip.trim() === "") { + throw new Error( + `Could not get IP address for container ${DAPPNODE_IPFS_CONTAINER}` + ); + } + + return ip.trim(); +} + +async function getIpfsProviderUrl(provider = "dappnode"): Promise { if (provider === "dappnode") { - return "http://ipfs.dappnode"; + // Try to resolve ipfs.dappnode first + if (await canResolveHost(DAPPNODE_IPFS_HOST)) { + return `http://${DAPPNODE_IPFS_HOST}`; + } + + // Fallback to Docker container IP + const containerIp = await getIpfsContainerIp(); + return `http://${containerIp}`; } else if (provider === "remote") { return "https://api.ipfs.dappnode.io"; } else if (provider === "infura") { @@ -28,8 +73,8 @@ function parseIpfsProviderUrl(provider: string) { } } -export function normalizeIpfsProvider(provider: string): string { - const providerUrl = getIpfsProviderUrl(provider); +export async function normalizeIpfsProvider(provider: string): Promise { + const providerUrl = await getIpfsProviderUrl(provider); const { host, port, protocol } = parseIpfsProviderUrl(providerUrl); const fullUrl = `${protocol}://${host}:${port}`; // #### TEMP: Make sure the URL is correct diff --git a/src/releaseUploader/ipfsNode/ipfsVersion.ts b/src/releaseUploader/ipfsNode/ipfsVersion.ts index c8d60c3b..c2b10527 100644 --- a/src/releaseUploader/ipfsNode/ipfsVersion.ts +++ b/src/releaseUploader/ipfsNode/ipfsVersion.ts @@ -17,7 +17,7 @@ export async function ipfsVersion( ipfsProvider: string ): Promise { // Parse the ipfsProvider the a full base apiUrl - const apiUrl = normalizeIpfsProvider(ipfsProvider); + const apiUrl = await normalizeIpfsProvider(ipfsProvider); const res = await got({ prefixUrl: apiUrl, url: "api/v0/version", diff --git a/test/commands/build.test.ts b/test/commands/build.test.ts index 220d8214..691181ca 100644 --- a/test/commands/build.test.ts +++ b/test/commands/build.test.ts @@ -10,7 +10,7 @@ import { } from "../../src/params.js"; import { normalizeIpfsProvider } from "../../src/releaseUploader/ipfsNode/ipfsProvider.js"; -const contentProvider = normalizeIpfsProvider("remote"); +const contentProvider = await normalizeIpfsProvider("remote"); // This test will create the following fake files // ./dappnode_package.json => fake manifest