Skip to content
Open
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
3 changes: 2 additions & 1 deletion src/releaseUploader/ipfsNode/addDirFromUrls.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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(),
Expand Down
2 changes: 1 addition & 1 deletion src/releaseUploader/ipfsNode/addFromFs.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand Down
53 changes: 49 additions & 4 deletions src/releaseUploader/ipfsNode/ipfsProvider.ts
Original file line number Diff line number Diff line change
@@ -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<boolean> {
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<string> {
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<string> {
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") {
Expand All @@ -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<string> {
const providerUrl = await getIpfsProviderUrl(provider);
const { host, port, protocol } = parseIpfsProviderUrl(providerUrl);
const fullUrl = `${protocol}://${host}:${port}`;
// #### TEMP: Make sure the URL is correct
Expand Down
2 changes: 1 addition & 1 deletion src/releaseUploader/ipfsNode/ipfsVersion.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ export async function ipfsVersion(
ipfsProvider: string
): Promise<IpfsApiVersionResponse> {
// Parse the ipfsProvider the a full base apiUrl
const apiUrl = normalizeIpfsProvider(ipfsProvider);
const apiUrl = await normalizeIpfsProvider(ipfsProvider);
const res = await got<IpfsApiVersionResponse>({
prefixUrl: apiUrl,
url: "api/v0/version",
Expand Down
2 changes: 1 addition & 1 deletion test/commands/build.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
Loading