From 952d74207d9caa5a3fabbb86c3a8130154ffabb5 Mon Sep 17 00:00:00 2001 From: Thodoris Greasidis Date: Fri, 14 Dec 2018 12:55:35 +0200 Subject: [PATCH] Check that the provided device type option is of the same arch Signed-off-by: Thodoris Greasidis --- lib/actions/config.coffee | 16 ++++++++++++++-- lib/actions/os.coffee | 12 ++++++++++++ lib/utils/config.ts | 12 ++++++++---- lib/utils/helpers.ts | 7 +++++++ 4 files changed, 41 insertions(+), 6 deletions(-) diff --git a/lib/actions/config.coffee b/lib/actions/config.coffee index 38b48d3d..bc6cc975 100644 --- a/lib/actions/config.coffee +++ b/lib/actions/config.coffee @@ -293,6 +293,7 @@ exports.generate = prettyjson = require('prettyjson') { generateDeviceConfig, generateApplicationConfig } = require('../utils/config') + helpers = require('../utils/helpers') { exitWithExpectedError } = require('../utils/patterns') if not options.device? and not options.application? @@ -323,8 +324,19 @@ exports.generate = return balena.models.application.get(options.application) .then (resource) -> deviceType = options.deviceType || resource.device_type - balena.models.device.getManifestBySlug(deviceType) - .get('options') + manifestPromise = balena.models.device.getManifestBySlug(deviceType) + + if options.application && options.deviceType + app = resource + appManifestPromise = balena.models.device.getManifestBySlug(app.device_type) + manifestPromise = manifestPromise.tap (paramDeviceType) -> + appManifestPromise.then (appDeviceType) -> + if not helpers.areDeviceTypesCompatible(appDeviceType, paramDeviceType) + throw new balena.errors.BalenaInvalidDeviceType( + "Device type #{options.deviceType} is incompatible with application #{options.application}" + ) + + manifestPromise.get('options') .then (formOptions) -> # Pass params as an override: if there is any param with exactly the same name as a # required option, that value is used (and the corresponding question is not asked) diff --git a/lib/actions/os.coffee b/lib/actions/os.coffee index c46dad12..ca13e905 100644 --- a/lib/actions/os.coffee +++ b/lib/actions/os.coffee @@ -289,6 +289,18 @@ exports.configure = .then (appOrDevice) -> deviceType = options.deviceType || appOrDevice.device_type manifestPromise = helpers.getManifest(params.image, deviceType) + + if options.application && options.deviceType + app = appOrDevice + appManifestPromise = balena.models.device.getManifestBySlug(app.device_type) + paramManifestPromise = balena.models.device.getManifestBySlug(options.deviceType) + manifestPromise = Promise.resolve(manifestPromise).tap -> + Promise.join appManifestPromise, paramManifestPromise, (appDeviceType, paramDeviceType) -> + if not helpers.areDeviceTypesCompatible(appDeviceType, paramDeviceType) + throw new balena.errors.BalenaInvalidDeviceType( + "Device type #{options.deviceType} is incompatible with application #{options.application}" + ) + answersPromise = Promise.try -> if options.config return readFileAsync(options.config, 'utf8') diff --git a/lib/utils/config.ts b/lib/utils/config.ts index cfd3fd55..8bad954c 100644 --- a/lib/utils/config.ts +++ b/lib/utils/config.ts @@ -50,7 +50,11 @@ type ImgConfig = { export function generateBaseConfig( application: BalenaSdk.Application, - options: { version: string; appUpdatePollInterval?: number; deviceType?: string; }, + options: { + version: string; + appUpdatePollInterval?: number; + deviceType?: string; + }, ): Promise { options = { ...options, @@ -69,7 +73,7 @@ export function generateBaseConfig( export function generateApplicationConfig( application: BalenaSdk.Application, - options: { version: string; deviceType?: string; }, + options: { version: string; deviceType?: string }, ) { return generateBaseConfig(application, options).tap(config => { if (semver.satisfies(options.version, '<2.7.8')) { @@ -84,7 +88,7 @@ export function generateDeviceConfig( belongs_to__application: BalenaSdk.PineDeferred; }, deviceApiKey: string | true | null, - options: { version: string; }, + options: { version: string }, ) { return balena.models.application .get(device.belongs_to__application.__id) @@ -92,7 +96,7 @@ export function generateDeviceConfig( const baseConfigOpts = { ...options, deviceType: device.device_type, - } + }; return generateBaseConfig(application, baseConfigOpts).tap(config => { if ( deviceApiKey == null && diff --git a/lib/utils/helpers.ts b/lib/utils/helpers.ts index 5a37da81..a02b0b20 100644 --- a/lib/utils/helpers.ts +++ b/lib/utils/helpers.ts @@ -92,6 +92,13 @@ export async function getManifest( return balena.models.device.getManifestBySlug(deviceType); } +export const areDeviceTypesCompatible = ( + deviceTypeA: BalenaSdk.DeviceType, + deviceTypeB: BalenaSdk.DeviceType, +) => + deviceTypeA.arch === deviceTypeB.arch && + !!deviceTypeA.isDependent === !!deviceTypeB.isDependent; + export async function getOsVersion( image: string, manifest: BalenaSdk.DeviceType,