Merge pull request #2032 from balena-io/misc-bugfixes

Misc bugfixes
This commit is contained in:
bulldozer-balena[bot] 2020-09-10 12:07:33 +00:00 committed by GitHub
commit e755d9f03f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 70 additions and 61 deletions

View File

@ -17,7 +17,7 @@
import { flags } from '@oclif/command'; import { flags } from '@oclif/command';
import type { IArg } from '@oclif/parser/lib/args'; import type { IArg } from '@oclif/parser/lib/args';
import type { Application } from 'balena-sdk'; import type { Application, BalenaSDK } from 'balena-sdk';
import Command from '../../command'; import Command from '../../command';
import * as cf from '../../utils/common-flags'; import * as cf from '../../utils/common-flags';
import { expandForAppName } from '../../utils/helpers'; import { expandForAppName } from '../../utils/helpers';
@ -59,7 +59,6 @@ export default class DeviceMoveCmd extends Command {
name: 'uuid', name: 'uuid',
description: description:
'comma-separated list (no blank spaces) of device UUIDs to be moved', 'comma-separated list (no blank spaces) of device UUIDs to be moved',
parse: (dev) => tryAsInteger(dev),
required: true, required: true,
}, },
]; ];
@ -81,21 +80,25 @@ export default class DeviceMoveCmd extends Command {
const balena = getBalenaSdk(); const balena = getBalenaSdk();
// Consolidate application options
options.application = options.application || options.app; options.application = options.application || options.app;
delete options.app; delete options.app;
// Parse ids string into array of correct types
const deviceIds: Array<string | number> = params.uuid
.split(',')
.map((id) => tryAsInteger(id));
// Get devices
const devices = await Promise.all( const devices = await Promise.all(
params.uuid deviceIds.map(
.split(',') (uuid) =>
.map( balena.models.device.get(uuid, expandForAppName) as Promise<
(uuid) => ExtendedDevice
balena.models.device.get(uuid, expandForAppName) as Promise< >,
ExtendedDevice ),
>,
),
); );
// Map application name for each device
for (const device of devices) { for (const device of devices) {
const belongsToApplication = device.belongs_to__application as Application[]; const belongsToApplication = device.belongs_to__application as Application[];
device.application_name = belongsToApplication?.[0] device.application_name = belongsToApplication?.[0]
@ -104,55 +107,12 @@ export default class DeviceMoveCmd extends Command {
} }
// Get destination application // Get destination application
let application; const application =
if (options.application) { options.application ||
application = options.application; (await this.interactivelySelectApplication(balena, devices));
} else {
const [deviceDeviceTypes, deviceTypes] = await Promise.all([
Promise.all(
devices.map((device) =>
balena.models.device.getManifestBySlug(
device.is_of__device_type[0].slug,
),
),
),
balena.models.config.getDeviceTypes(),
]);
const compatibleDeviceTypes = deviceTypes.filter((dt) => // Move each device
deviceDeviceTypes.every( for (const uuid of deviceIds) {
(deviceDeviceType) =>
balena.models.os.isArchitectureCompatibleWith(
deviceDeviceType.arch,
dt.arch,
) &&
!!dt.isDependent === !!deviceDeviceType.isDependent &&
dt.state !== 'DISCONTINUED',
),
);
const patterns = await import('../../utils/patterns');
try {
application = await patterns.selectApplication(
(app) =>
compatibleDeviceTypes.some(
(dt) => dt.slug === app.is_for__device_type[0].slug,
) &&
// @ts-ignore using the extended device object prop
devices.some((device) => device.application_name !== app.app_name),
true,
);
} catch (err) {
if (deviceDeviceTypes.length) {
throw new ExpectedError(
`${err.message}\nDo all devices have a compatible architecture?`,
);
}
throw err;
}
}
for (const uuid of params.uuid.split(',')) {
try { try {
await balena.models.device.move(uuid, tryAsInteger(application)); await balena.models.device.move(uuid, tryAsInteger(application));
console.info(`${uuid} was moved to ${application}`); console.info(`${uuid} was moved to ${application}`);
@ -162,4 +122,53 @@ export default class DeviceMoveCmd extends Command {
} }
} }
} }
async interactivelySelectApplication(
balena: BalenaSDK,
devices: ExtendedDevice[],
) {
const [deviceDeviceTypes, deviceTypes] = await Promise.all([
Promise.all(
devices.map((device) =>
balena.models.device.getManifestBySlug(
device.is_of__device_type[0].slug,
),
),
),
balena.models.config.getDeviceTypes(),
]);
const compatibleDeviceTypes = deviceTypes.filter((dt) =>
deviceDeviceTypes.every(
(deviceDeviceType) =>
balena.models.os.isArchitectureCompatibleWith(
deviceDeviceType.arch,
dt.arch,
) &&
!!dt.isDependent === !!deviceDeviceType.isDependent &&
dt.state !== 'DISCONTINUED',
),
);
const patterns = await import('../../utils/patterns');
try {
const application = await patterns.selectApplication(
(app) =>
compatibleDeviceTypes.some(
(dt) => dt.slug === app.is_for__device_type[0].slug,
) &&
// @ts-ignore using the extended device object prop
devices.some((device) => device.application_name !== app.app_name),
true,
);
return application;
} catch (err) {
if (deviceDeviceTypes.length) {
throw new ExpectedError(
`${err.message}\nDo all devices have a compatible architecture?`,
);
}
throw err;
}
}
} }

View File

@ -51,7 +51,6 @@ export default class DeviceRmCmd extends Command {
name: 'uuid', name: 'uuid',
description: description:
'comma-separated list (no blank spaces) of device UUIDs to be removed', 'comma-separated list (no blank spaces) of device UUIDs to be removed',
parse: (dev) => tryAsInteger(dev),
required: true, required: true,
}, },
]; ];
@ -85,7 +84,7 @@ export default class DeviceRmCmd extends Command {
// Remove // Remove
for (const uuid of params.uuid.split(',')) { for (const uuid of params.uuid.split(',')) {
try { try {
await balena.models.device.remove(uuid); await balena.models.device.remove(tryAsInteger(uuid));
} catch (err) { } catch (err) {
console.info(`${err.message}, uuid: ${uuid}`); console.info(`${err.message}, uuid: ${uuid}`);
process.exitCode = 1; process.exitCode = 1;

View File

@ -42,6 +42,7 @@ export default class OsVersionsCmd extends Command {
{ {
name: 'type', name: 'type',
description: 'device type', description: 'device type',
required: true,
}, },
]; ];