Compare commits

..

2 Commits

Author SHA1 Message Date
52611337c2 Merge pull request 'fix(make): auto-detect docker/podman so Makefile works on either engine' (#4) from sprint/2-simulations into main
Reviewed-on: #4
2026-05-26 10:34:01 +00:00
Knacky
b3124ba4dd fix(make): auto-detect docker/podman so Makefile works on either engine
- Makefile: introduce CONTAINER_CMD ?= $(shell command -v docker || echo podman),
  replace all 12 hardcoded `docker` invocations with $(CONTAINER_CMD). User can
  override with `make <target> CONTAINER_CMD=podman` or env export.
- e2e/tests/us1-bootstrap-admin.spec.ts: AC-1.4 regex updated to match the new
  variable form `$(CONTAINER_CMD) exec … flask create-admin` (was hardcoded
  `docker exec`). RUNTIME default also auto-detects (same logic as Makefile)
  so the test exec'es the right engine without a MIMIC_CONTAINER_CMD export.
- e2e/tests/us6-deployment.spec.ts: same RUNTIME auto-detect so the make-dry-run
  regex assertions on lines 75 + 77 match what the Makefile actually emits on
  a podman-only host.
- README + CHANGELOG document the new behavior.

Fixes the user-reported issue: "Le makefile ne fonctionne pas sur ma machine
qui n'a que podman."

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-26 12:20:29 +02:00
5 changed files with 38 additions and 16 deletions

View File

@@ -33,6 +33,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/)
### Changed ### Changed
- 2026-05-26 — `make update-mitre` upgraded from no-op placeholder to a real `curl` + optional container restart (Sprint 1 marker resolved). - 2026-05-26 — `make update-mitre` upgraded from no-op placeholder to a real `curl` + optional container restart (Sprint 1 marker resolved).
- 2026-05-26 — `EngagementDetailPage` no longer renders the "Simulations à venir au Sprint 2" placeholder; it embeds `<SimulationList>` instead. - 2026-05-26 — `EngagementDetailPage` no longer renders the "Simulations à venir au Sprint 2" placeholder; it embeds `<SimulationList>` instead.
- 2026-05-26 — Makefile now auto-detects the container engine (`CONTAINER_CMD ?= docker || podman`) instead of hard-coding `docker`. Override with `make <target> CONTAINER_CMD=podman` or `export CONTAINER_CMD=…`. The matching e2e tests (`us1`, `us6`) were updated to mirror the same detection so they pass on podman-only machines without an explicit `MIMIC_CONTAINER_CMD` export.
--- ---

View File

@@ -3,16 +3,20 @@ IMAGE ?= mimic:latest
CONTAINER ?= mimic CONTAINER ?= mimic
VOLUME ?= mimic-data VOLUME ?= mimic-data
# Container engine: auto-detect docker first, fall back to podman.
# Override explicitly with `make <target> CONTAINER_CMD=podman` or `export CONTAINER_CMD=podman`.
CONTAINER_CMD ?= $(shell if command -v docker >/dev/null 2>&1; then echo docker; else echo podman; fi)
.PHONY: build start stop restart update logs create-admin update-mitre test-backend test-frontend test-e2e clean .PHONY: build start stop restart update logs create-admin update-mitre test-backend test-frontend test-e2e clean
build: build:
docker build -f docker/Dockerfile -t $(IMAGE) . $(CONTAINER_CMD) build -f docker/Dockerfile -t $(IMAGE) .
start: start:
docker run -d --name $(CONTAINER) -p $(PORT):5000 -v $(VOLUME):/data --env-file .env $(IMAGE) $(CONTAINER_CMD) run -d --name $(CONTAINER) -p $(PORT):5000 -v $(VOLUME):/data --env-file .env $(IMAGE)
stop: stop:
docker stop $(CONTAINER) && docker rm $(CONTAINER) $(CONTAINER_CMD) stop $(CONTAINER) && $(CONTAINER_CMD) rm $(CONTAINER)
restart: restart:
$(MAKE) stop && $(MAKE) start $(MAKE) stop && $(MAKE) start
@@ -21,7 +25,7 @@ update:
git pull && $(MAKE) build && $(MAKE) restart git pull && $(MAKE) build && $(MAKE) restart
logs: logs:
docker logs -f $(CONTAINER) $(CONTAINER_CMD) logs -f $(CONTAINER)
create-admin: create-admin:
ifndef USER ifndef USER
@@ -30,7 +34,7 @@ endif
ifndef PASS ifndef PASS
$(error PASS is required: make create-admin USER=alice PASS=p4ssw0rd) $(error PASS is required: make create-admin USER=alice PASS=p4ssw0rd)
endif endif
docker exec $(CONTAINER) flask create-admin $(USER) $(PASS) $(CONTAINER_CMD) exec $(CONTAINER) flask create-admin $(USER) $(PASS)
MITRE_URL ?= https://raw.githubusercontent.com/mitre/cti/master/enterprise-attack/enterprise-attack.json MITRE_URL ?= https://raw.githubusercontent.com/mitre/cti/master/enterprise-attack/enterprise-attack.json
@@ -38,13 +42,13 @@ update-mitre:
@mkdir -p backend/data/mitre @mkdir -p backend/data/mitre
@curl -fsSL "$(MITRE_URL)" -o backend/data/mitre/enterprise-attack.json @curl -fsSL "$(MITRE_URL)" -o backend/data/mitre/enterprise-attack.json
@echo "MITRE bundle updated" @echo "MITRE bundle updated"
@if docker ps --format '{{.Names}}' | grep -q "^$(CONTAINER)$$"; then \ @if $(CONTAINER_CMD) ps --format '{{.Names}}' | grep -q "^$(CONTAINER)$$"; then \
echo "Restarting $(CONTAINER) to reload MITRE bundle..."; \ echo "Restarting $(CONTAINER) to reload MITRE bundle..."; \
docker restart $(CONTAINER); \ $(CONTAINER_CMD) restart $(CONTAINER); \
fi fi
test-backend: test-backend:
docker exec $(CONTAINER) pytest -q backend/tests/ $(CONTAINER_CMD) exec $(CONTAINER) pytest -q backend/tests/
test-frontend: test-frontend:
cd frontend && npm run test -- --run cd frontend && npm run test -- --run
@@ -53,6 +57,6 @@ test-e2e:
cd e2e && npx playwright test cd e2e && npx playwright test
clean: clean:
-docker rm -f $(CONTAINER) 2>/dev/null -$(CONTAINER_CMD) rm -f $(CONTAINER) 2>/dev/null
-docker volume rm $(VOLUME) 2>/dev/null -$(CONTAINER_CMD) volume rm $(VOLUME) 2>/dev/null
rm -rf backend/__pycache__ frontend/node_modules frontend/dist rm -rf backend/__pycache__ frontend/node_modules frontend/dist

View File

@@ -98,7 +98,7 @@ mimic/
| Target | What it does | | Target | What it does |
|---|---| |---|---|
| `make build` | Build the `mimic:latest` Docker image (multistage: Node → Python) | | `make build` | Build the `mimic:latest` container image (multistage: Node → Python). Uses `docker` if installed, otherwise `podman` — override with `make build CONTAINER_CMD=podman` |
| `make start` | Start the container (port from `PORT`, default 5000; mounts `mimic-data` volume) | | `make start` | Start the container (port from `PORT`, default 5000; mounts `mimic-data` volume) |
| `make stop` | Stop and remove the container | | `make stop` | Stop and remove the container |
| `make restart` | `make stop && make start` — preserves the SQLite volume | | `make restart` | `make stop && make start` — preserves the SQLite volume |

View File

@@ -19,7 +19,15 @@ import { adminToken, deleteUserByUsername, login, makeClient } from '../fixtures
const __dirname = dirname(fileURLToPath(import.meta.url)); const __dirname = dirname(fileURLToPath(import.meta.url));
const RUNTIME = process.env.MIMIC_CONTAINER_CMD ?? 'docker'; function detectRuntime(): string {
try {
execSync('command -v docker', { stdio: 'ignore' });
return 'docker';
} catch {
return 'podman';
}
}
const RUNTIME = process.env.MIMIC_CONTAINER_CMD ?? detectRuntime();
const CONTAINER = process.env.MIMIC_CONTAINER ?? 'mimic'; const CONTAINER = process.env.MIMIC_CONTAINER ?? 'mimic';
function runCreateAdmin(user: string, pass: string): { function runCreateAdmin(user: string, pass: string): {
@@ -100,10 +108,11 @@ test.describe('US-1 — bootstrap first admin', () => {
const token = await adminToken(); const token = await adminToken();
expect(token).toBeTruthy(); expect(token).toBeTruthy();
// Defence-in-depth: assert the Makefile target literally invokes // Defence-in-depth: assert the Makefile target wraps an `exec … flask create-admin`
// `docker exec … flask create-admin`. This is a contract check. // through the container engine. Sprint 2 made the engine configurable via
// $(CONTAINER_CMD) (auto-detects docker or podman), so we assert the variable form.
const makefilePath = resolve(__dirname, '../..', 'Makefile'); const makefilePath = resolve(__dirname, '../..', 'Makefile');
const content = readFileSync(makefilePath, 'utf8'); const content = readFileSync(makefilePath, 'utf8');
expect(content).toMatch(/docker exec .+ flask create-admin/); expect(content).toMatch(/\$\(CONTAINER_CMD\) exec .+ flask create-admin/);
}); });
}); });

View File

@@ -24,7 +24,15 @@ import {
waitForHealth, waitForHealth,
} from '../fixtures/api'; } from '../fixtures/api';
const RUNTIME = process.env.MIMIC_CONTAINER_CMD ?? 'docker'; function detectRuntime(): string {
try {
execSync('command -v docker', { stdio: 'ignore' });
return 'docker';
} catch {
return 'podman';
}
}
const RUNTIME = process.env.MIMIC_CONTAINER_CMD ?? detectRuntime();
const CONTAINER = process.env.MIMIC_CONTAINER ?? 'mimic'; const CONTAINER = process.env.MIMIC_CONTAINER ?? 'mimic';
const IMAGE = process.env.MIMIC_IMAGE ?? 'mimic:latest'; const IMAGE = process.env.MIMIC_IMAGE ?? 'mimic:latest';
const __dirname = dirname(fileURLToPath(import.meta.url)); const __dirname = dirname(fileURLToPath(import.meta.url));