Check that the provided device type option is of the same arch

Signed-off-by: Thodoris Greasidis <thodoris@balena.io>
This commit is contained in:
Thodoris Greasidis 2018-12-14 12:55:35 +02:00
parent 853d146457
commit 952d74207d
4 changed files with 41 additions and 6 deletions

View File

@ -293,6 +293,7 @@ exports.generate =
prettyjson = require('prettyjson') prettyjson = require('prettyjson')
{ generateDeviceConfig, generateApplicationConfig } = require('../utils/config') { generateDeviceConfig, generateApplicationConfig } = require('../utils/config')
helpers = require('../utils/helpers')
{ exitWithExpectedError } = require('../utils/patterns') { exitWithExpectedError } = require('../utils/patterns')
if not options.device? and not options.application? if not options.device? and not options.application?
@ -323,8 +324,19 @@ exports.generate =
return balena.models.application.get(options.application) return balena.models.application.get(options.application)
.then (resource) -> .then (resource) ->
deviceType = options.deviceType || resource.device_type deviceType = options.deviceType || resource.device_type
balena.models.device.getManifestBySlug(deviceType) manifestPromise = balena.models.device.getManifestBySlug(deviceType)
.get('options')
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) -> .then (formOptions) ->
# Pass params as an override: if there is any param with exactly the same name as a # 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) # required option, that value is used (and the corresponding question is not asked)

View File

@ -289,6 +289,18 @@ exports.configure =
.then (appOrDevice) -> .then (appOrDevice) ->
deviceType = options.deviceType || appOrDevice.device_type deviceType = options.deviceType || appOrDevice.device_type
manifestPromise = helpers.getManifest(params.image, deviceType) 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 -> answersPromise = Promise.try ->
if options.config if options.config
return readFileAsync(options.config, 'utf8') return readFileAsync(options.config, 'utf8')

View File

@ -50,7 +50,11 @@ type ImgConfig = {
export function generateBaseConfig( export function generateBaseConfig(
application: BalenaSdk.Application, application: BalenaSdk.Application,
options: { version: string; appUpdatePollInterval?: number; deviceType?: string; }, options: {
version: string;
appUpdatePollInterval?: number;
deviceType?: string;
},
): Promise<ImgConfig> { ): Promise<ImgConfig> {
options = { options = {
...options, ...options,
@ -69,7 +73,7 @@ export function generateBaseConfig(
export function generateApplicationConfig( export function generateApplicationConfig(
application: BalenaSdk.Application, application: BalenaSdk.Application,
options: { version: string; deviceType?: string; }, options: { version: string; deviceType?: string },
) { ) {
return generateBaseConfig(application, options).tap(config => { return generateBaseConfig(application, options).tap(config => {
if (semver.satisfies(options.version, '<2.7.8')) { if (semver.satisfies(options.version, '<2.7.8')) {
@ -84,7 +88,7 @@ export function generateDeviceConfig(
belongs_to__application: BalenaSdk.PineDeferred; belongs_to__application: BalenaSdk.PineDeferred;
}, },
deviceApiKey: string | true | null, deviceApiKey: string | true | null,
options: { version: string; }, options: { version: string },
) { ) {
return balena.models.application return balena.models.application
.get(device.belongs_to__application.__id) .get(device.belongs_to__application.__id)
@ -92,7 +96,7 @@ export function generateDeviceConfig(
const baseConfigOpts = { const baseConfigOpts = {
...options, ...options,
deviceType: device.device_type, deviceType: device.device_type,
} };
return generateBaseConfig(application, baseConfigOpts).tap(config => { return generateBaseConfig(application, baseConfigOpts).tap(config => {
if ( if (
deviceApiKey == null && deviceApiKey == null &&

View File

@ -92,6 +92,13 @@ export async function getManifest(
return balena.models.device.getManifestBySlug(deviceType); 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( export async function getOsVersion(
image: string, image: string,
manifest: BalenaSdk.DeviceType, manifest: BalenaSdk.DeviceType,