diff --git a/src/files/compose/types.ts b/src/files/compose/types.ts index e886ec6e..a2fe3691 100644 --- a/src/files/compose/types.ts +++ b/src/files/compose/types.ts @@ -58,6 +58,7 @@ export interface ComposeService { pid?: string; privileged?: boolean; restart?: string; + security_opt?: string; stop_grace_period?: string; stop_signal?: string; user?: string; @@ -74,7 +75,7 @@ export interface ComposeServiceNetwork { aliases?: string[]; } -export type ComposeServiceNetworks = string[] | ComposeServiceNetworksObj[]; +export type ComposeServiceNetworks = string[] | ComposeServiceNetworksObj; export type ComposeServiceNetworksObj = { [networkName: string]: ComposeServiceNetwork; @@ -103,21 +104,27 @@ export interface Compose { services: { [dnpName: string]: ComposeService; }; - networks?: { - [networkName: string]: { - name?: string; - external?: boolean; - driver?: string; // "bridge"; - ipam?: { config: { subnet: string }[] }; // { subnet: "172.33.0.0/16" } - }; - }; + networks?: ComposeNetworks; // { dappmanagerdnpdappnodeeth_data: {} }; - volumes?: { - [volumeName: string]: { - // NOTE: Not allowed - external?: boolean | { name: string }; // name: "dncore_ipfsdnpdappnodeeth_data" - }; - }; + volumes?: ComposeVolumes; +} + +export interface ComposeVolumes { + /** volumeName: "dncore_ipfsdnpdappnodeeth_data" */ + [volumeName: string]: ComposeVolume | null; +} + +export interface ComposeVolume { + // FORBIDDEN + // external?: boolean | { name: string }; // name: "dncore_ipfsdnpdappnodeeth_data" + // NOT allowed to user, only used by DAppNode internally (if any) + external?: boolean; + name?: string; // Volumes can only be declared locally or be external + driver?: string; // Dangerous + driver_opts?: + | { type: "none"; device: string; o: "bind" } + | { [driverOptName: string]: string }; // driver_opts are passed down to whatever driver is being used, there's. No verification on docker's part nor detailed documentation + labels?: { [labelName: string]: string }; // User should not use this feature } export interface ComposePaths { diff --git a/src/files/compose/validateDappnodeCompose.ts b/src/files/compose/validateDappnodeCompose.ts index 8ba6e523..b769aee3 100644 --- a/src/files/compose/validateDappnodeCompose.ts +++ b/src/files/compose/validateDappnodeCompose.ts @@ -75,7 +75,8 @@ function validateComposeNetworks(compose: Compose): void { )} are allowed` ); // Check all networks are external - if (networks[networkName].external === false) + const network = networks[networkName]; + if (network && network.external === false) err( `The docker network ${networkName} is not allowed. Docker internal networks are not allowed` ); @@ -156,36 +157,34 @@ function validateComposeServiceNetworks( const serviceNetworks = service.networks; if (!serviceNetworks) return; - for (const serviceNetwork of serviceNetworks) { - if (typeof serviceNetwork === "string") { + if (Array.isArray(serviceNetworks)) { + for (const serviceNetwork of serviceNetworks) { // Check docker network is whitelisted when defined in array format if (!params.DOCKER_WHITELIST_NETWORKS.includes(serviceNetwork)) err( `service ${serviceName} has a non-whitelisted docker network: ${serviceNetwork}. Only docker networks ${DOCKER_WHITELIST_NETWORKS_STR} are allowed` ); - } else { - for (const serviceNetworkObjectName of Object.keys(serviceNetwork)) { - // Check docker network is whitelisted when defined in object format - if ( - !params.DOCKER_WHITELIST_NETWORKS.includes(serviceNetworkObjectName) + } + } else { + for (const serviceNetworkObjectName of Object.keys(serviceNetworks)) { + // Check docker network is whitelisted when defined in object format + if (!params.DOCKER_WHITELIST_NETWORKS.includes(serviceNetworkObjectName)) + err( + `service ${serviceName} has a non-whitelisted docker network: ${serviceNetworkObjectName}. Only docker networks ${DOCKER_WHITELIST_NETWORKS_STR} are allowed` + ); + + // Check core aliases are not used by non core packages + const { aliases } = serviceNetworks[serviceNetworkObjectName]; + if ( + !isCore && + aliases && + params.DOCKER_CORE_ALIASES.some(coreAlias => + aliases.includes(coreAlias) ) - err( - `service ${serviceName} has a non-whitelisted docker network: ${serviceNetworkObjectName}. Only docker networks ${DOCKER_WHITELIST_NETWORKS_STR} are allowed` - ); - - // Check core aliases are not used by non core packages - const { aliases } = serviceNetwork[serviceNetworkObjectName]; - if ( - !isCore && - aliases && - params.DOCKER_CORE_ALIASES.some(coreAlias => - aliases.includes(coreAlias) - ) - ) { - err( - `service ${serviceName} has the network ${serviceNetworkObjectName} with reserved docker alias. Aliases ${DOCKER_WHITELIST_ALIASES_STR} are reserved to core packages` - ); - } + ) { + err( + `service ${serviceName} has the network ${serviceNetworkObjectName} with reserved docker alias. Aliases ${DOCKER_WHITELIST_ALIASES_STR} are reserved to core packages` + ); } } } diff --git a/src/files/manifest/types.ts b/src/files/manifest/types.ts index e9ae85b8..0f43b04c 100644 --- a/src/files/manifest/types.ts +++ b/src/files/manifest/types.ts @@ -118,15 +118,15 @@ interface Dependencies { // Driver -type ChainDriver = ChainDriverType | ChainDriverSpecs; +export type ChainDriver = ChainDriverType | ChainDriverSpecs; -type ChainDriverSpecs = { +export type ChainDriverSpecs = { driver: ChainDriverType; serviceName?: string; portNumber?: number; }; -type ChainDriverType = +export type ChainDriverType = | "bitcoin" | "ethereum" | "ethereum-beacon-chain" diff --git a/test/files/compose/validateDappnodeCompose.test.ts b/test/files/compose/validateDappnodeCompose.test.ts index ef127fec..04924809 100644 --- a/test/files/compose/validateDappnodeCompose.test.ts +++ b/test/files/compose/validateDappnodeCompose.test.ts @@ -211,18 +211,16 @@ service validator has a non-whitelisted docker network: danger_network. Only doc ...compose.services, validator: { ...compose.services.validator, - networks: [ - { - danger_network: { - ipv4_address: "172.33.4.5", - aliases: ["dappmanager.dappnode"] - }, - other_network: { - ipv4_address: "", - aliases: ["core.dappnode"] - } + networks: { + danger_network: { + ipv4_address: "172.33.4.5", + aliases: ["dappmanager.dappnode"] + }, + other_network: { + ipv4_address: "", + aliases: ["core.dappnode"] } - ] + } } } },