From 935ed5606fba5d10b2fca59593a64cf5aaee1038 Mon Sep 17 00:00:00 2001 From: Thodoris Greasidis Date: Thu, 18 Apr 2024 12:00:57 +0300 Subject: [PATCH] Drop the /device-types/v1/:deviceType/images route in favor of hostApps Change-type: major See: https://balena.fibery.io/Work/Improvement/Stop-relying-on-device-types-v1-device-type.json-for-unrelated-things-257 --- src/features/device-types/device-types.ts | 45 +--------- src/features/device-types/index.ts | 12 +-- src/features/device-types/routes.ts | 15 ---- test/02_device-types.ts | 102 ---------------------- 4 files changed, 4 insertions(+), 170 deletions(-) diff --git a/src/features/device-types/device-types.ts b/src/features/device-types/device-types.ts index cddc1ecc8..d91197e73 100644 --- a/src/features/device-types/device-types.ts +++ b/src/features/device-types/device-types.ts @@ -3,7 +3,6 @@ import _ from 'lodash'; import type { DeviceTypeJson } from './device-type-json.js'; import type { sbvrUtils } from '@balena/pinejs'; import { errors } from '@balena/pinejs'; -const { InternalRequestError } = errors; import { captureException } from '../../infra/error-handling/index.js'; @@ -123,11 +122,11 @@ export const getImageSize = async ( buildId: string, ): Promise => { const deviceTypeInfo = await findDeviceTypeInfoBySlug(resinApi, slug); - const deviceType = deviceTypeInfo.latest; - const normalizedSlug = deviceType.slug; + const deviceTypeJson = deviceTypeInfo.latest; + const normalizedSlug = deviceTypeJson.slug; if (buildId === 'latest') { - buildId = deviceType.buildId; + buildId = deviceTypeJson.buildId; } if (!deviceTypeInfo.versions.includes(buildId)) { @@ -150,41 +149,3 @@ export const getImageSize = async ( throw err; } }; - -export interface ImageVersions { - versions: string[]; - latest: string; -} - -export const getImageVersions = async ( - resinApi: typeof sbvrUtils.api.resin, - slug: string, -): Promise => { - const deviceTypeInfo = await findDeviceTypeInfoBySlug(resinApi, slug); - const deviceType = deviceTypeInfo.latest; - const normalizedSlug = deviceType.slug; - - const buildIds = ( - await Promise.all( - deviceTypeInfo.versions.map(async (buildId) => { - try { - if ((await getDeviceTypeJson(normalizedSlug, buildId)) != null) { - return buildId; - } - } catch { - return; - } - }), - ) - ).filter((buildId) => buildId != null); - if (_.isEmpty(buildIds) && !_.isEmpty(deviceTypeInfo.versions)) { - throw new InternalRequestError( - `Could not retrieve any image version for device type ${slug}`, - ); - } - - return { - versions: buildIds, - latest: buildIds[0], - }; -}; diff --git a/src/features/device-types/index.ts b/src/features/device-types/index.ts index db43d24b6..da5aee1d1 100644 --- a/src/features/device-types/index.ts +++ b/src/features/device-types/index.ts @@ -1,11 +1,6 @@ import type { Application } from 'express'; import { middleware } from '../../infra/auth/index.js'; -import { - downloadImageSize, - getDeviceType, - getDeviceTypes, - listAvailableImageVersions, -} from './routes.js'; +import { downloadImageSize, getDeviceType, getDeviceTypes } from './routes.js'; export const setup = (app: Application) => { app.get( @@ -18,11 +13,6 @@ export const setup = (app: Application) => { middleware.resolveCredentialsAndUser, getDeviceType, ); - app.get( - '/device-types/v1/:deviceType/images', - middleware.resolveCredentialsAndUser, - listAvailableImageVersions, - ); app.get( '/device-types/v1/:deviceType/images/:version/download-size', middleware.resolveCredentialsAndUser, diff --git a/src/features/device-types/routes.ts b/src/features/device-types/routes.ts index 9e8a52b5d..f03fe714c 100644 --- a/src/features/device-types/routes.ts +++ b/src/features/device-types/routes.ts @@ -44,21 +44,6 @@ export const getDeviceType: RequestHandler = async (req, res) => { } }; -export const listAvailableImageVersions: RequestHandler = async (req, res) => { - try { - const resinApi = api.resin.clone({ passthrough: { req } }); - const slug = deviceTypesLib.validateSlug(req.params.deviceType); - const data = await deviceTypesLib.getImageVersions(resinApi, slug); - res.json(data); - } catch (err) { - captureException(err, 'Error getting image versions', { req }); - if (handleHttpErrors(req, res, err)) { - return; - } - res.status(500).send(translateError(err)); - } -}; - const DOWNLOAD_TIMEOUT = 30000; // we must respond within this time export const downloadImageSize: RequestHandler = async (req, res) => { diff --git a/test/02_device-types.ts b/test/02_device-types.ts index a961a2248..8e39ef361 100644 --- a/test/02_device-types.ts +++ b/test/02_device-types.ts @@ -277,107 +277,5 @@ export default () => { expect(rpiConfig).to.not.have.property('logoUrl'); }); }); - - describe('/device-types/v1/:deviceType/images', () => { - it('should return a proper result', async () => { - const res = await supertest() - .get('/device-types/v1/raspberrypi3-64/images') - .expect(200); - expect(res.body).to.deep.equal({ - versions: [ - '2.0.2+rev2', - '2.0.2+rev2.dev', - '2.0.2+rev1', - '2.0.2+rev1.dev', - ], - latest: '2.0.2+rev2', - }); - }); - - it('should return a proper result for an alias', async () => { - const res = await supertest() - .get('/device-types/v1/raspberrypi364/images') - .expect(200); - expect(res.body).to.deep.equal({ - versions: [ - '2.0.2+rev2', - '2.0.2+rev2.dev', - '2.0.2+rev1', - '2.0.2+rev1.dev', - ], - latest: '2.0.2+rev2', - }); - }); - - it('should omit releases that have an IGNORE file', async () => { - const res = await supertest() - .get('/device-types/v1/dt-with-ignored-release/images') - .expect(200); - expect(res.body).to.deep.equal({ - versions: ['2.0.1+rev1.prod', '2.0.0+rev1.prod'], - latest: '2.0.1+rev1.prod', - }); - }); - - it('should omit releases that have an IGNORE file that gives an unauthorized error', async () => { - const res = await supertest() - .get('/device-types/v1/dt-with-403-ignore-file-release/images') - .expect(200); - expect(res.body).to.deep.equal({ - versions: ['2.0.1+rev1.prod', '2.0.0+rev1.prod'], - latest: '2.0.1+rev1.prod', - }); - }); - - it('should omit releases that have an empty device-type.json', async () => { - const res = await supertest() - .get('/device-types/v1/dt-with-empty-device-type-json-release/images') - .expect(200); - expect(res.body).to.deep.equal({ - versions: ['2.0.1+rev1.prod', '2.0.0+rev1.prod'], - latest: '2.0.1+rev1.prod', - }); - }); - - it('should omit releases that do not have a device-type.json', async () => { - const res = await supertest() - .get('/device-types/v1/dt-with-404-device-type-json-release/images') - .expect(200); - expect(res.body).to.deep.equal({ - versions: ['2.0.1+rev1.prod', '2.0.0+rev1.prod'], - latest: '2.0.1+rev1.prod', - }); - }); - - it('should succeed and omit releases that the retrieval of the IGNORE file fails', async () => { - const res = await supertest() - .get('/device-types/v1/dt-with-500-ignore-file-release/images') - .expect(200); - expect(res.body).to.deep.equal({ - versions: ['2.0.1+rev1.prod', '2.0.0+rev1.prod'], - latest: '2.0.1+rev1.prod', - }); - }); - - it('should succeed and omit releases that the retrieval of device-type.json fails', async () => { - const res = await supertest() - .get('/device-types/v1/dt-with-500-device-type-json-release/images') - .expect(200); - expect(res.body).to.deep.equal({ - versions: ['2.0.1+rev1.prod', '2.0.0+rev1.prod'], - latest: '2.0.1+rev1.prod', - }); - }); - - it('should succeed and omit device types whose details fail to be retrieved', async () => { - const res = await supertest() - .get('/device-types/v1/dt-with-500-device-type-json-release/images') - .expect(200); - expect(res.body).to.deep.equal({ - versions: ['2.0.1+rev1.prod', '2.0.0+rev1.prod'], - latest: '2.0.1+rev1.prod', - }); - }); - }); }); };