diff --git a/docs/API.md b/docs/API.md index 992c1c1c..6e744221 100644 --- a/docs/API.md +++ b/docs/API.md @@ -793,6 +793,41 @@ Response: } ``` +### Container ID (GET /v2/containerId) + +Added in supervisor v8.6.0 + +Use this endpoint to match a service name to a container ID. + +From the user container: +``` +$ curl "$BALENA_SUPERVISOR_ADDRESS/v2/containerId?apikey=$BALENA_SUPERVISOR_API_KEY" +``` + +Response: +```json +{ + "status": "success", + "services": { + "service-one": "ad6d5d32576ad3cb1fcaa59b564b8f6f22b079631080ab1a3bbac9199953eb7d", + "service-two": "756535dc6e9ab9b560f84c85063f55952273a23192641fc2756aa9721d9d1000" + } +} +``` + +You can also specify a service, to return only that container id: +``` +$ curl "$BALENA_SUPERVISOR_ADDRESS/v2/containerId?apikey=$BALENA_SUPERVISOR_API_KEY&service=service-one" +``` + +Response: +```json +{ + "status": "sucess", + "containerId": "ad6d5d32576ad3cb1fcaa59b564b8f6f22b079631080ab1a3bbac9199953eb7d" +} +``` + ### Local mode endpoints These endpoints are mainly for use by the CLI, for working with a local mode device. diff --git a/src/compose/service-manager.d.ts b/src/compose/service-manager.d.ts index a8925046..28cc0ba4 100644 --- a/src/compose/service-manager.d.ts +++ b/src/compose/service-manager.d.ts @@ -1,3 +1,4 @@ +import * as Bluebird from 'bluebird'; import { EventEmitter } from 'events'; import { Service } from '../compose/service'; @@ -5,6 +6,7 @@ import { Service } from '../compose/service'; // FIXME: Unfinished definition for this class... declare class ServiceManager extends EventEmitter { public getStatus(): Service[]; + public getAll(): Bluebird; } export = ServiceManager; diff --git a/src/device-api/v2.ts b/src/device-api/v2.ts index 09f37dad..1fd776ca 100644 --- a/src/device-api/v2.ts +++ b/src/device-api/v2.ts @@ -337,4 +337,42 @@ export function createV2Api(router: Router, applications: ApplicationManager) { version: supervisorVersion, }); }); + + router.get('/v2/containerId', async (req, res) => { + try { + const services = await applications.services.getAll(); + + if (req.query.serviceName != null || req.query.service != null) { + const serviceName = req.query.serviceName || req.query.service; + const service = _.find( + services, + svc => svc.serviceName === serviceName, + ); + if (service != null) { + res.status(200).json({ + status: 'success', + containerId: service.containerId, + }); + } else { + res.status(503).json({ + status: 'failed', + message: 'Could not find service with that name', + }); + } + } else { + res.status(200).json({ + status: 'success', + services: _(services) + .keyBy('serviceName') + .mapValues('containerId') + .value(), + }); + } + } catch (e) { + res.status(503).json({ + status: 'failed', + message: messageFromError(e), + }); + } + }); }