Skip to content

Commit

Permalink
move: Include fleets of discontinued device types in the fleet selection
Browse files Browse the repository at this point in the history
Change-type: patch
  • Loading branch information
thgreasi committed Jul 20, 2023
1 parent 1bf8c1b commit b011af8
Show file tree
Hide file tree
Showing 2 changed files with 38 additions and 40 deletions.
64 changes: 29 additions & 35 deletions lib/commands/device/move.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@ import type { IArg } from '@oclif/parser/lib/args';
import type {
BalenaSDK,
Device,
DeviceType,
PineOptions,
PineTypedResult,
} from 'balena-sdk';
Expand Down Expand Up @@ -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(
Expand All @@ -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?`,
);
Expand Down
14 changes: 9 additions & 5 deletions lib/utils/patterns.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import type {
BalenaSDK,
Device,
Organization,
PineFilter,
PineOptions,
PineTypedResult,
} from 'balena-sdk';
Expand Down Expand Up @@ -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);
}

Expand Down

0 comments on commit b011af8

Please sign in to comment.