Skip to content

Commit

Permalink
ensure requirements in packageInstall and not only on `fetchDnpRequ…
Browse files Browse the repository at this point in the history
…est`
  • Loading branch information
pablomendezroyo committed Nov 5, 2024
1 parent 5457e78 commit ba0e08e
Show file tree
Hide file tree
Showing 3 changed files with 64 additions and 1 deletion.
4 changes: 3 additions & 1 deletion packages/installer/src/calls/packageInstall.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,8 @@ import {
rollbackPackages,
writeAndValidateFiles,
postInstallClean,
afterInstall
afterInstall,
checkInstallRequirements
} from "../installer/index.js";
import { logs, getLogUi, logUiClear } from "@dappnode/logger";
import { Routes } from "@dappnode/types";
Expand Down Expand Up @@ -53,6 +54,7 @@ export async function packageInstall(
if (!release.signedSafe && !options.BYPASS_SIGNED_RESTRICTION) {
throw Error(`Package ${release.dnpName} is from untrusted origin and is not signed`);
}
if (!release.isCore) await checkInstallRequirements({ manifest: release.manifest });
}

// Gather all data necessary for the install
Expand Down
60 changes: 60 additions & 0 deletions packages/installer/src/installer/checkInstallRequirements.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
import { listPackages, getDockerVersion } from "@dappnode/dockerapi";
import { params } from "@dappnode/params";
import { Manifest, InstalledPackageData } from "@dappnode/types";
import { valid, gt } from "semver";

/**
* Get the install requirements and throw an error if they are not met
*/
export async function checkInstallRequirements({ manifest }: { manifest: Manifest }): Promise<void> {
const installedPackages = await listPackages();
const packagesRequiredToBeUninstalled = getRequiresUninstallPackages({ manifest, installedPackages });
const requiresCoreUpdate = getRequiresCoreUpdate({ manifest, installedPackages });
const requiresDockerUpdate = await getRequiresDockerUpdate({ manifest });

const errors: string[] = [];
if (packagesRequiredToBeUninstalled.length > 0)
errors.push(`The following packages must be uninstalled: ${packagesRequiredToBeUninstalled.join(", ")}`);
if (requiresCoreUpdate) errors.push("The core package must be updated");
if (requiresDockerUpdate) errors.push("Docker must be updated");
if (errors.length > 0)
throw new Error(`The package cannot be installed because of the following requirements:
${errors.join("\n")}`);
}

function getRequiresUninstallPackages({
manifest,
installedPackages
}: {
manifest: Manifest;
installedPackages: InstalledPackageData[];
}): string[] {
const { notInstalledPackages } = manifest.requirements || {};
if (!notInstalledPackages || notInstalledPackages.length === 0) return [];
return notInstalledPackages.filter((dnpName) => installedPackages.find((dnp) => dnp.dnpName === dnpName));
}

function getRequiresCoreUpdate({
manifest,
installedPackages
}: {
manifest: Manifest;
installedPackages: InstalledPackageData[];
}): boolean {
const coreDnp = installedPackages.find((dnp) => dnp.dnpName === params.coreDnpName);
if (!coreDnp) return false;
const coreVersion = coreDnp.version;
const minDnVersion = manifest.requirements ? manifest.requirements.minimumDappnodeVersion : "";
return Boolean(minDnVersion && valid(minDnVersion) && valid(coreVersion) && gt(minDnVersion, coreVersion));
}
async function getRequiresDockerUpdate({ manifest }: { manifest: Manifest }): Promise<boolean> {
const minDockerVersion = manifest.requirements?.minimumDockerVersion;
if (!minDockerVersion) return false;
const currentDockerVersion = await getDockerVersion();
return Boolean(
minDockerVersion &&
valid(minDockerVersion) &&
valid(currentDockerVersion) &&
gt(minDockerVersion, currentDockerVersion)
);
}
1 change: 1 addition & 0 deletions packages/installer/src/installer/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,3 +7,4 @@ export * from "./rollbackPackages.js";
export * from "./runPackages.js";
export * from "./restartPatch.js";
export * from "./writeAndValidateFiles.js";
export * from "./checkInstallRequirements.js";

0 comments on commit ba0e08e

Please sign in to comment.