[grade=B urn:ump:szxhoevzog44pvl3sz6n6qp2edv6wj6dcs3ajpi3kxbpbz7kikqa] DC-137: shipdeck engine branch for App Selector catalog installs
Opt-in (config.engine='shipdeck' + SHIPDECK_BRIDGE_URL configured + template compatible): catalog installs go through the bridge's validated image-install pipeline (digest-pinned OCI image, systemd release, Caddy gate, DNS, verify) instead of Docker. Port semantics: engine is host-networked, so the app LISTEN port (container side of the mapping, protocol suffix stripped) is gated — never the Docker host port; no mapping falls back to defaultPort. Volumes: absolute binds only, :ro preserved, named volumes and placeholders skipped. Engine installs skip panel DNS + Caddy (pipeline did them), record an engine=shipdeck manifest with the Shipdeckfile path, and removal runs shipdeck rm via the registry. Failures return 502 with stage detail and never fall back to Docker. Bridge unset = Docker path unchanged. 10 new tests (gating, payload mapping, route integration); full suite 138/138 suites 2933/2933 green. Judge: C -> C -> B zero-blockers.
This commit is contained in:
@@ -45,7 +45,29 @@ module.exports = function({
|
||||
try {
|
||||
log.info('deploy', 'Removing app', { appId, containerId, subdomain, deleteContainer: shouldDeleteContainer });
|
||||
|
||||
if (containerId && shouldDeleteContainer) {
|
||||
// DC-137: engine-installed apps run as shipdeck services (no Docker
|
||||
// container). Detect via the services registry BEFORE touching Docker.
|
||||
let engineService = null;
|
||||
try {
|
||||
const svcList = await servicesStateManager.read();
|
||||
const svc = (Array.isArray(svcList) ? svcList : []).find(s => s.id === subdomain);
|
||||
if (svc && svc.deploymentManifest && svc.deploymentManifest.engine === 'shipdeck') {
|
||||
engineService = svc.deploymentManifest.shipdeck && svc.deploymentManifest.shipdeck.service;
|
||||
}
|
||||
} catch (_) { /* registry read failure falls through to legacy path */ }
|
||||
|
||||
if (engineService && shouldDeleteContainer) {
|
||||
// Engine path: `shipdeck rm` removes unit + releases (Caddy/DNS are
|
||||
// handled below by the shared removal code, same as Docker apps).
|
||||
try {
|
||||
const { call } = require('../../src/shipdeck-bridge-client');
|
||||
const { status, body } = await call('POST', '/api/rm', { name: engineService }, 120000);
|
||||
results.container = (status === 200 && body.ok) ? 'removed (shipdeck)' : `shipdeck rm failed: ${body.error || status}`;
|
||||
log.info('deploy', 'shipdeck service removal', { engineService, result: results.container });
|
||||
} catch (error) {
|
||||
results.container = `shipdeck bridge unreachable: ${error.message}`;
|
||||
}
|
||||
} else if (containerId && shouldDeleteContainer) {
|
||||
try {
|
||||
const container = docker.client.getContainer(containerId);
|
||||
try { await container.stop(); log.info('docker', 'Container stopped', { containerId }); }
|
||||
|
||||
Reference in New Issue
Block a user