move: Include fleets of discontinued device types in the fleet selection

Change-type: patch
This commit is contained in:
Thodoris Greasidis 2023-07-19 19:22:17 +03:00
parent 1bf8c1bfe7
commit b011af89ad
2 changed files with 37 additions and 39 deletions

View File

@ -20,7 +20,6 @@ import type { IArg } from '@oclif/parser/lib/args';
import type {
BalenaSDK,
Device,
DeviceType,
PineOptions,
PineTypedResult,
} from 'balena-sdk';
@ -138,7 +137,6 @@ export default class DeviceMoveCmd extends Command {
balena: BalenaSDK,
devices: Awaited<ReturnType<typeof this.getDevices>>,
) {
const { getExpandedProp } = await import('../../utils/pine');
// deduplicate the slugs
const deviceCpuArchs = Array.from(
new Set(
@ -148,48 +146,44 @@ export default class DeviceMoveCmd extends Command {
),
);
const deviceTypeOptions = {
$select: 'slug',
$expand: {
is_of__cpu_architecture: {
$select: 'slug',
},
const allCpuArches = await balena.pine.get({
resource: 'cpu_architecture',
options: {
$select: ['id', 'slug'],
},
} satisfies PineOptions<DeviceType>;
const deviceTypes = (await balena.models.deviceType.getAllSupported(
deviceTypeOptions,
)) as Array<PineTypedResult<DeviceType, typeof deviceTypeOptions>>;
});
const compatibleDeviceTypeSlugs = new Set(
deviceTypes
.filter((deviceType) => {
const deviceTypeArch = getExpandedProp(
deviceType.is_of__cpu_architecture,
'slug',
)!;
return deviceCpuArchs.every((deviceCpuArch) =>
balena.models.os.isArchitectureCompatibleWith(
deviceCpuArch,
deviceTypeArch,
),
);
})
.map((deviceType) => deviceType.slug),
);
const compatibleCpuArchIds = allCpuArches
.filter((cpuArch) => {
return deviceCpuArchs.every((deviceCpuArch) =>
balena.models.os.isArchitectureCompatibleWith(
deviceCpuArch,
cpuArch.slug,
),
);
})
.map((deviceType) => deviceType.id);
const patterns = await import('../../utils/patterns');
try {
const application = await patterns.selectApplication(
(app) =>
compatibleDeviceTypeSlugs.has(app.is_for__device_type[0].slug) &&
devices.some(
(device) => device.belongs_to__application.__id !== app.id,
),
{
is_for__device_type: {
$any: {
$alias: 'dt',
$expr: {
dt: {
is_of__cpu_architecture: { $in: compatibleCpuArchIds },
},
},
},
},
},
true,
);
return application;
} catch (err) {
if (!compatibleDeviceTypeSlugs.size) {
if (!compatibleCpuArchIds.length) {
throw new ExpectedError(
`${err.message}\nDo all devices have a compatible architecture?`,
);

View File

@ -19,6 +19,7 @@ import type {
BalenaSDK,
Device,
Organization,
PineFilter,
PineOptions,
PineTypedResult,
} from 'balena-sdk';
@ -178,19 +179,22 @@ type SelectApplicationResult = PineTypedResult<
>;
export async function selectApplication(
filter?: (app: SelectApplicationResult) => boolean,
filter?:
| PineFilter<Application>
| ((app: SelectApplicationResult) => boolean),
errorOnEmptySelection = false,
) {
const balena = getBalenaSdk();
let apps = (await balena.models.application.getAllDirectlyAccessible(
selectApplicationPineOptions,
)) as SelectApplicationResult[];
let apps = (await balena.models.application.getAllDirectlyAccessible({
...selectApplicationPineOptions,
...(filter != null && typeof filter === 'object' && { $filter: filter }),
})) as SelectApplicationResult[];
if (!apps.length) {
throw new ExpectedError('No fleets found');
}
if (filter != null) {
if (filter != null && typeof filter === 'function') {
apps = apps.filter(filter);
}