|
1 | 1 | // @ts-nocheck |
2 | 2 | import fs from 'node:fs/promises'; |
| 3 | +import path from 'node:path'; |
3 | 4 | import yaml from 'yaml'; |
4 | 5 | import { getState } from '../../../registry/index.js'; |
5 | 6 | import { resolveConfiguredPath } from '../../../runtime/paths.js'; |
6 | 7 | import Docker from '../docker/Docker.js'; |
7 | 8 |
|
| 9 | +const COMPOSE_PROJECT_CONFIG_FILES_LABEL = 'com.docker.compose.project.config_files'; |
| 10 | +const COMPOSE_PROJECT_WORKING_DIR_LABEL = 'com.docker.compose.project.working_dir'; |
| 11 | +const DD_COMPOSE_NATIVE_LABEL = 'dd.compose.native'; |
| 12 | +const WUD_COMPOSE_NATIVE_LABEL = 'wud.compose.native'; |
| 13 | + |
| 14 | +function isNativeComposeEnabled(labels = {}) { |
| 15 | + const nativeLabel = labels[DD_COMPOSE_NATIVE_LABEL] ?? labels[WUD_COMPOSE_NATIVE_LABEL]; |
| 16 | + if (nativeLabel === undefined) { |
| 17 | + return false; |
| 18 | + } |
| 19 | + const normalizedNativeLabel = `${nativeLabel}`.trim().toLowerCase(); |
| 20 | + return normalizedNativeLabel === 'true'; |
| 21 | +} |
| 22 | + |
8 | 23 | function splitDigestReference(image) { |
9 | 24 | if (!image) { |
10 | 25 | return { |
@@ -220,6 +235,36 @@ class Dockercompose extends Docker { |
220 | 235 | } |
221 | 236 | } |
222 | 237 |
|
| 238 | + // Fall back to native Docker Compose labels when explicitly enabled |
| 239 | + const nativeComposeEnabled = isNativeComposeEnabled(container.labels); |
| 240 | + const composeConfigFiles = container.labels?.[COMPOSE_PROJECT_CONFIG_FILES_LABEL]; |
| 241 | + if (nativeComposeEnabled && composeConfigFiles && composeConfigFiles.trim() !== '') { |
| 242 | + const composeProjectWorkingDir = container.labels?.[COMPOSE_PROJECT_WORKING_DIR_LABEL]; |
| 243 | + const configFiles = composeConfigFiles |
| 244 | + .split(',') |
| 245 | + .map((configFile) => configFile.trim()) |
| 246 | + .filter((configFile) => configFile !== ''); |
| 247 | + |
| 248 | + const configFile = configFiles[0]; |
| 249 | + if (configFile) { |
| 250 | + const resolvedConfigFile = |
| 251 | + path.isAbsolute(configFile) || !composeProjectWorkingDir |
| 252 | + ? configFile |
| 253 | + : path.join(composeProjectWorkingDir.trim(), configFile); |
| 254 | + |
| 255 | + try { |
| 256 | + return resolveConfiguredPath(resolvedConfigFile, { |
| 257 | + label: `Native compose file labels ${COMPOSE_PROJECT_CONFIG_FILES_LABEL}/${COMPOSE_PROJECT_WORKING_DIR_LABEL}`, |
| 258 | + }); |
| 259 | + } catch (e) { |
| 260 | + this.log.warn( |
| 261 | + `Native compose file labels on container ${container.name} are invalid (${e.message})`, |
| 262 | + ); |
| 263 | + return null; |
| 264 | + } |
| 265 | + } |
| 266 | + } |
| 267 | + |
223 | 268 | // Fall back to default configuration file |
224 | 269 | if (!this.configuration.file) { |
225 | 270 | return null; |
|
0 commit comments