mirror of
https://github.com/balena-io/balena-cli.git
synced 2024-12-19 21:57:51 +00:00
Update balena-sdk to 14.x
Update balena-sdk from 13.6.0 to 14.8.0 Change-type: patch
This commit is contained in:
parent
bf22d9eaa8
commit
e1c42405a1
@ -86,6 +86,7 @@ export default class AppCreateCmd extends Command {
|
||||
application = await balena.models.application.create({
|
||||
name: params.name,
|
||||
deviceType,
|
||||
organization: (await balena.auth.whoami())!,
|
||||
});
|
||||
} catch (err) {
|
||||
// BalenaRequestError: Request error: Unique key constraint violated
|
||||
@ -97,7 +98,7 @@ export default class AppCreateCmd extends Command {
|
||||
throw err;
|
||||
}
|
||||
console.info(
|
||||
`Application created: ${application.slug} (${application.device_type}, id ${application.id})`,
|
||||
`Application created: ${application.slug} (${deviceType}, id ${application.id})`,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -20,6 +20,7 @@ import Command from '../../command';
|
||||
import * as cf from '../../utils/common-flags';
|
||||
import { getBalenaSdk, getVisuals, stripIndent } from '../../utils/lazy';
|
||||
import { tryAsInteger } from '../../utils/validation';
|
||||
import { Release } from 'balena-sdk';
|
||||
|
||||
interface FlagsDef {
|
||||
help: void;
|
||||
@ -57,10 +58,22 @@ export default class AppCmd extends Command {
|
||||
public async run() {
|
||||
const { args: params } = this.parse<FlagsDef, ArgsDef>(AppCmd);
|
||||
|
||||
const application = await getBalenaSdk().models.application.get(
|
||||
const application = (await getBalenaSdk().models.application.get(
|
||||
tryAsInteger(params.name),
|
||||
);
|
||||
{
|
||||
$expand: {
|
||||
is_for__device_type: { $select: 'slug' },
|
||||
should_be_running__release: { $select: 'commit' },
|
||||
},
|
||||
},
|
||||
)) as ApplicationWithDeviceType & {
|
||||
should_be_running__release: [Release?];
|
||||
};
|
||||
|
||||
// @ts-expect-error
|
||||
application.device_type = application.is_for__device_type[0].slug;
|
||||
// @ts-expect-error
|
||||
application.commit = application.should_be_running__release[0]?.commit;
|
||||
console.log(
|
||||
getVisuals().table.vertical(application, [
|
||||
`$${application.app_name}$`,
|
||||
|
@ -16,13 +16,12 @@
|
||||
*/
|
||||
|
||||
import { flags } from '@oclif/command';
|
||||
import type { Application } from 'balena-sdk';
|
||||
import Command from '../command';
|
||||
import * as cf from '../utils/common-flags';
|
||||
import { getBalenaSdk, getVisuals, stripIndent } from '../utils/lazy';
|
||||
import { isV12 } from '../utils/version';
|
||||
|
||||
interface ExtendedApplication extends Application {
|
||||
interface ExtendedApplication extends ApplicationWithDeviceType {
|
||||
device_count?: number;
|
||||
online_devices?: number;
|
||||
}
|
||||
@ -64,12 +63,13 @@ export default class AppsCmd extends Command {
|
||||
const balena = getBalenaSdk();
|
||||
|
||||
// Get applications
|
||||
const applications: ExtendedApplication[] = await balena.models.application.getAll(
|
||||
{
|
||||
$select: ['id', 'app_name', 'slug', 'device_type'],
|
||||
$expand: { owns__device: { $select: 'is_online' } },
|
||||
const applications = (await balena.models.application.getAll({
|
||||
$select: ['id', 'app_name', 'slug'],
|
||||
$expand: {
|
||||
is_for__device_type: { $select: 'slug' },
|
||||
owns__device: { $select: 'is_online' },
|
||||
},
|
||||
);
|
||||
})) as ExtendedApplication[];
|
||||
|
||||
const _ = await import('lodash');
|
||||
// Add extended properties
|
||||
@ -78,6 +78,8 @@ export default class AppsCmd extends Command {
|
||||
application.online_devices = _.sumBy(application.owns__device, (d) =>
|
||||
d.is_online === true ? 1 : 0,
|
||||
);
|
||||
// @ts-expect-error
|
||||
application.device_type = application.is_for__device_type[0].slug;
|
||||
});
|
||||
|
||||
// Display
|
||||
|
@ -189,7 +189,7 @@ ${dockerignoreHelp}
|
||||
const { getAppWithArch } = await import('../utils/helpers');
|
||||
const app = await getAppWithArch(opts.application);
|
||||
opts.arch = app.arch;
|
||||
opts.deviceType = app.device_type;
|
||||
opts.deviceType = app.is_for__device_type[0].slug;
|
||||
return app;
|
||||
}
|
||||
}
|
||||
|
@ -19,7 +19,7 @@ import { flags } from '@oclif/command';
|
||||
import Command from '../../command';
|
||||
import * as cf from '../../utils/common-flags';
|
||||
import { getBalenaSdk, getCliForm, stripIndent } from '../../utils/lazy';
|
||||
import type { Device, Application, PineDeferred } from 'balena-sdk';
|
||||
import type { Application, PineDeferred } from 'balena-sdk';
|
||||
|
||||
interface FlagsDef {
|
||||
version: string; // OS version
|
||||
@ -130,27 +130,34 @@ export default class ConfigGenerateCmd extends Command {
|
||||
|
||||
await this.validateOptions(options);
|
||||
|
||||
let deviceType = options.deviceType;
|
||||
// Get device | application
|
||||
let resource;
|
||||
if (options.device != null) {
|
||||
const { tryAsInteger } = await import('../../utils/validation');
|
||||
resource = (await balena.models.device.get(
|
||||
tryAsInteger(options.device),
|
||||
)) as Device & { belongs_to__application: PineDeferred };
|
||||
resource = (await balena.models.device.get(tryAsInteger(options.device), {
|
||||
$expand: {
|
||||
is_of__device_type: { $select: 'slug' },
|
||||
},
|
||||
})) as DeviceWithDeviceType & { belongs_to__application: PineDeferred };
|
||||
deviceType = deviceType || resource.is_of__device_type[0].slug;
|
||||
} else {
|
||||
resource = await balena.models.application.get(options.application!);
|
||||
resource = (await balena.models.application.get(options.application!, {
|
||||
$expand: {
|
||||
is_for__device_type: { $select: 'slug' },
|
||||
},
|
||||
})) as ApplicationWithDeviceType;
|
||||
deviceType = deviceType || resource.is_for__device_type[0].slug;
|
||||
}
|
||||
|
||||
const deviceType = options.deviceType || resource.device_type;
|
||||
|
||||
const deviceManifest = await balena.models.device.getManifestBySlug(
|
||||
deviceType,
|
||||
deviceType!,
|
||||
);
|
||||
|
||||
// Check compatibility if application and deviceType provided
|
||||
if (options.application && options.deviceType) {
|
||||
const appDeviceManifest = await balena.models.device.getManifestBySlug(
|
||||
resource.device_type,
|
||||
deviceType!,
|
||||
);
|
||||
|
||||
const helpers = await import('../../utils/helpers');
|
||||
|
@ -22,11 +22,12 @@ import * as cf from '../../utils/common-flags';
|
||||
import { expandForAppName } from '../../utils/helpers';
|
||||
import { getBalenaSdk, getVisuals, stripIndent } from '../../utils/lazy';
|
||||
import { tryAsInteger } from '../../utils/validation';
|
||||
import type { Application, Device } from 'balena-sdk';
|
||||
import type { Application, Release } from 'balena-sdk';
|
||||
|
||||
interface ExtendedDevice extends Device {
|
||||
interface ExtendedDevice extends DeviceWithDeviceType {
|
||||
dashboard_url?: string;
|
||||
application_name?: string;
|
||||
device_type?: string;
|
||||
commit?: string;
|
||||
last_seen?: string;
|
||||
}
|
||||
@ -70,25 +71,23 @@ export default class DeviceCmd extends Command {
|
||||
|
||||
const balena = getBalenaSdk();
|
||||
|
||||
const device: ExtendedDevice = await balena.models.device.get(params.uuid, {
|
||||
const device = (await balena.models.device.get(params.uuid, {
|
||||
$select: [
|
||||
'device_name',
|
||||
'id',
|
||||
'device_type',
|
||||
'overall_status',
|
||||
'is_online',
|
||||
'ip_address',
|
||||
'mac_address',
|
||||
'last_connectivity_event',
|
||||
'uuid',
|
||||
'is_on__commit',
|
||||
'supervisor_version',
|
||||
'is_web_accessible',
|
||||
'note',
|
||||
'os_version',
|
||||
],
|
||||
...expandForAppName,
|
||||
});
|
||||
})) as ExtendedDevice;
|
||||
device.status = device.overall_status;
|
||||
|
||||
device.dashboard_url = balena.models.device.getDashboardUrl(device.uuid);
|
||||
@ -98,8 +97,9 @@ export default class DeviceCmd extends Command {
|
||||
? belongsToApplication[0].app_name
|
||||
: 'N/a';
|
||||
|
||||
device.commit = device.is_on__commit;
|
||||
device.last_seen = device.last_connectivity_event;
|
||||
device.device_type = device.is_of__device_type[0].slug;
|
||||
device.commit = (device.is_running__release as Release[])[0].commit;
|
||||
device.last_seen = device.last_connectivity_event ?? undefined;
|
||||
|
||||
console.log(
|
||||
getVisuals().table.vertical(device, [
|
||||
|
@ -95,10 +95,17 @@ export default class DeviceInitCmd extends Command {
|
||||
delete options.app;
|
||||
|
||||
// Get application and
|
||||
const application = await balena.models.application.get(
|
||||
const application = (await balena.models.application.get(
|
||||
options['application'] ||
|
||||
(await (await import('../../utils/patterns')).selectApplication()),
|
||||
);
|
||||
{
|
||||
$expand: {
|
||||
is_for__device_type: {
|
||||
$select: 'slug',
|
||||
},
|
||||
},
|
||||
},
|
||||
)) as ApplicationWithDeviceType;
|
||||
|
||||
// Register new device
|
||||
const deviceUuid = balena.models.device.generateUniqueKey();
|
||||
@ -111,13 +118,14 @@ export default class DeviceInitCmd extends Command {
|
||||
try {
|
||||
logger.logDebug(`Downloading OS image...`);
|
||||
const osVersion = options['os-version'] || 'default';
|
||||
await downloadOSImage(application.device_type, tmpPath, osVersion);
|
||||
const deviceType = application.is_for__device_type[0].slug;
|
||||
await downloadOSImage(deviceType, tmpPath, osVersion);
|
||||
|
||||
logger.logDebug(`Configuring OS image...`);
|
||||
await this.configureOsImage(tmpPath, device.uuid, options);
|
||||
|
||||
logger.logDebug(`Writing OS image...`);
|
||||
await this.writeOsImage(tmpPath, application.device_type, options);
|
||||
await this.writeOsImage(tmpPath, deviceType, options);
|
||||
} catch (e) {
|
||||
// Remove device in failed cases
|
||||
try {
|
||||
|
@ -17,7 +17,7 @@
|
||||
|
||||
import { flags } from '@oclif/command';
|
||||
import type { IArg } from '@oclif/parser/lib/args';
|
||||
import type { Application, Device } from 'balena-sdk';
|
||||
import type { Application } from 'balena-sdk';
|
||||
import Command from '../../command';
|
||||
import * as cf from '../../utils/common-flags';
|
||||
import { expandForAppName } from '../../utils/helpers';
|
||||
@ -25,7 +25,7 @@ import { getBalenaSdk, stripIndent } from '../../utils/lazy';
|
||||
import { tryAsInteger } from '../../utils/validation';
|
||||
import { ExpectedError } from '../../errors';
|
||||
|
||||
interface ExtendedDevice extends Device {
|
||||
interface ExtendedDevice extends DeviceWithDeviceType {
|
||||
application_name?: string;
|
||||
}
|
||||
|
||||
@ -85,10 +85,15 @@ export default class DeviceMoveCmd extends Command {
|
||||
options.application = options.application || options.app;
|
||||
delete options.app;
|
||||
|
||||
const devices: ExtendedDevice[] = await Promise.all(
|
||||
const devices = await Promise.all(
|
||||
params.uuid
|
||||
.split(',')
|
||||
.map((uuid) => balena.models.device.get(uuid, expandForAppName)),
|
||||
.map(
|
||||
(uuid) =>
|
||||
balena.models.device.get(uuid, expandForAppName) as Promise<
|
||||
ExtendedDevice
|
||||
>,
|
||||
),
|
||||
);
|
||||
|
||||
for (const device of devices) {
|
||||
@ -106,7 +111,9 @@ export default class DeviceMoveCmd extends Command {
|
||||
const [deviceDeviceTypes, deviceTypes] = await Promise.all([
|
||||
Promise.all(
|
||||
devices.map((device) =>
|
||||
balena.models.device.getManifestBySlug(device.device_type),
|
||||
balena.models.device.getManifestBySlug(
|
||||
device.is_of__device_type[0].slug,
|
||||
),
|
||||
),
|
||||
),
|
||||
balena.models.config.getDeviceTypes(),
|
||||
@ -127,8 +134,10 @@ export default class DeviceMoveCmd extends Command {
|
||||
const patterns = await import('../../utils/patterns');
|
||||
try {
|
||||
application = await patterns.selectApplication(
|
||||
(app: Application) =>
|
||||
compatibleDeviceTypes.some((dt) => dt.slug === app.device_type) &&
|
||||
(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,
|
||||
|
@ -81,12 +81,17 @@ export default class DeviceOsUpdateCmd extends Command {
|
||||
// Get device info
|
||||
const {
|
||||
uuid,
|
||||
device_type,
|
||||
is_of__device_type,
|
||||
os_version,
|
||||
os_variant,
|
||||
} = await sdk.models.device.get(params.uuid, {
|
||||
$select: ['uuid', 'device_type', 'os_version', 'os_variant'],
|
||||
});
|
||||
} = (await sdk.models.device.get(params.uuid, {
|
||||
$select: ['uuid', 'os_version', 'os_variant'],
|
||||
$expand: {
|
||||
is_of__device_type: {
|
||||
$select: 'slug',
|
||||
},
|
||||
},
|
||||
})) as DeviceWithDeviceType;
|
||||
|
||||
// Get current device OS version
|
||||
const currentOsVersion = sdk.models.device.getOsVersion({
|
||||
@ -101,7 +106,7 @@ export default class DeviceOsUpdateCmd extends Command {
|
||||
|
||||
// Get supported OS update versions
|
||||
const hupVersionInfo = await sdk.models.os.getSupportedOsUpdateVersions(
|
||||
device_type,
|
||||
is_of__device_type[0].slug,
|
||||
currentOsVersion,
|
||||
);
|
||||
if (hupVersionInfo.versions.length === 0) {
|
||||
|
@ -21,9 +21,9 @@ import * as cf from '../../utils/common-flags';
|
||||
import { expandForAppName } from '../../utils/helpers';
|
||||
import { getBalenaSdk, getVisuals, stripIndent } from '../../utils/lazy';
|
||||
import { tryAsInteger } from '../../utils/validation';
|
||||
import type { Device, Application } from 'balena-sdk';
|
||||
import type { Application } from 'balena-sdk';
|
||||
|
||||
interface ExtendedDevice extends Device {
|
||||
interface ExtendedDevice extends DeviceWithDeviceType {
|
||||
dashboard_url?: string;
|
||||
application_name?: string;
|
||||
}
|
||||
@ -80,15 +80,17 @@ export default class DevicesCmd extends Command {
|
||||
options.application = options.application || options.app;
|
||||
delete options.app;
|
||||
|
||||
let devices: ExtendedDevice[];
|
||||
let devices;
|
||||
|
||||
if (options.application != null) {
|
||||
devices = await balena.models.device.getAllByApplication(
|
||||
devices = (await balena.models.device.getAllByApplication(
|
||||
tryAsInteger(options.application),
|
||||
expandForAppName,
|
||||
);
|
||||
)) as ExtendedDevice[];
|
||||
} else {
|
||||
devices = await balena.models.device.getAll(expandForAppName);
|
||||
devices = (await balena.models.device.getAll(
|
||||
expandForAppName,
|
||||
)) as ExtendedDevice[];
|
||||
}
|
||||
|
||||
devices = devices.map(function (device) {
|
||||
@ -100,6 +102,9 @@ export default class DevicesCmd extends Command {
|
||||
: 'N/a';
|
||||
|
||||
device.uuid = device.uuid.slice(0, 7);
|
||||
|
||||
// @ts-ignore
|
||||
device.device_type = device.is_of__device_type[0].slug;
|
||||
return device;
|
||||
});
|
||||
|
||||
|
@ -76,7 +76,9 @@ export default class DevicesSupportedCmd extends Command {
|
||||
|
||||
public async run() {
|
||||
const { flags: options } = this.parse<FlagsDef, {}>(DevicesSupportedCmd);
|
||||
let deviceTypes: Array<Partial<SDK.DeviceType>> = await getBalenaSdk()
|
||||
let deviceTypes: Array<Partial<
|
||||
SDK.DeviceTypeJson.DeviceType
|
||||
>> = await getBalenaSdk()
|
||||
.models.config.getDeviceTypes()
|
||||
.map((d) => {
|
||||
if (d.aliases && d.aliases.length) {
|
||||
@ -100,7 +102,7 @@ export default class DevicesSupportedCmd extends Command {
|
||||
: ['slug', 'aliases', 'arch', 'name'];
|
||||
deviceTypes = _.sortBy(
|
||||
deviceTypes.map((d) => {
|
||||
const picked = _.pick<Partial<SDK.DeviceType>>(d, fields);
|
||||
const picked = _.pick(d, fields);
|
||||
// 'BETA' renamed to 'NEW'
|
||||
picked.state = picked.state === 'BETA' ? 'NEW' : picked.state;
|
||||
return picked;
|
||||
|
@ -317,7 +317,7 @@ async function getAppVars(
|
||||
appVars.push(...vars);
|
||||
}
|
||||
if (!options.config && (options.service || options.all)) {
|
||||
const pineOpts: SDK.PineOptionsFor<SDK.ServiceEnvironmentVariable> = {
|
||||
const pineOpts: SDK.PineOptions<SDK.ServiceEnvironmentVariable> = {
|
||||
$expand: {
|
||||
service: {},
|
||||
},
|
||||
@ -359,7 +359,7 @@ async function getDeviceVars(
|
||||
deviceVars.push(...deviceConfigVars);
|
||||
} else {
|
||||
if (options.service || options.all) {
|
||||
const pineOpts: SDK.PineOptionsFor<SDK.DeviceServiceEnvironmentVariable> = {
|
||||
const pineOpts: SDK.PineOptions<SDK.DeviceServiceEnvironmentVariable> = {
|
||||
$expand: {
|
||||
service_install: {
|
||||
$expand: 'installs__service',
|
||||
|
@ -20,7 +20,7 @@ import Command from '../../command';
|
||||
import * as cf from '../../utils/common-flags';
|
||||
import { getCliForm, stripIndent } from '../../utils/lazy';
|
||||
import * as _ from 'lodash';
|
||||
import type { DeviceType } from 'balena-sdk';
|
||||
import type { DeviceTypeJson } from 'balena-sdk';
|
||||
|
||||
interface FlagsDef {
|
||||
advanced: boolean;
|
||||
@ -104,7 +104,7 @@ export default class OsBuildConfigCmd extends Command {
|
||||
}
|
||||
|
||||
async buildConfigForDeviceType(
|
||||
deviceTypeManifest: DeviceType,
|
||||
deviceTypeManifest: DeviceTypeJson.DeviceType,
|
||||
advanced: boolean,
|
||||
) {
|
||||
if (advanced == null) {
|
||||
|
@ -51,10 +51,6 @@ interface ArgsDef {
|
||||
image: string;
|
||||
}
|
||||
|
||||
interface DeferredDevice extends BalenaSdk.Device {
|
||||
belongs_to__application: BalenaSdk.PineDeferred;
|
||||
}
|
||||
|
||||
interface Answers {
|
||||
appUpdatePollInterval: number; // in minutes
|
||||
deviceType: string; // e.g. "raspberrypi3"
|
||||
@ -192,18 +188,29 @@ export default class OsConfigureCmd extends Command {
|
||||
'../../utils/config'
|
||||
);
|
||||
const helpers = await import('../../utils/helpers');
|
||||
let app: BalenaSdk.Application | undefined;
|
||||
let device: BalenaSdk.Device | undefined;
|
||||
let app: ApplicationWithDeviceType | undefined;
|
||||
let device;
|
||||
let deviceTypeSlug: string;
|
||||
|
||||
const balena = getBalenaSdk();
|
||||
if (options.device) {
|
||||
device = await balena.models['device'].get(options.device);
|
||||
deviceTypeSlug = device.device_type;
|
||||
device = (await balena.models.device.get(options.device, {
|
||||
$expand: {
|
||||
is_of__device_type: { $select: 'slug' },
|
||||
},
|
||||
})) as DeviceWithDeviceType & {
|
||||
belongs_to__application: BalenaSdk.PineDeferred;
|
||||
};
|
||||
deviceTypeSlug = device.is_of__device_type[0].slug;
|
||||
} else {
|
||||
app = await balena.models['application'].get(options.application!);
|
||||
app = (await balena.models.application.get(options.application!, {
|
||||
$expand: {
|
||||
is_for__device_type: { $select: 'slug' },
|
||||
},
|
||||
})) as ApplicationWithDeviceType;
|
||||
await checkDeviceTypeCompatibility(balena, options, app);
|
||||
deviceTypeSlug = options['device-type'] || app.device_type;
|
||||
deviceTypeSlug =
|
||||
options['device-type'] || app.is_for__device_type[0].slug;
|
||||
}
|
||||
|
||||
const deviceTypeManifest = await helpers.getManifest(
|
||||
@ -232,7 +239,7 @@ export default class OsConfigureCmd extends Command {
|
||||
if (_.isEmpty(configJson)) {
|
||||
if (device) {
|
||||
configJson = await generateDeviceConfig(
|
||||
device as DeferredDevice,
|
||||
device,
|
||||
options['device-api-key'],
|
||||
answers,
|
||||
);
|
||||
@ -335,7 +342,7 @@ async function validateOptions(options: FlagsDef) {
|
||||
*/
|
||||
async function getOsVersionFromImage(
|
||||
imagePath: string,
|
||||
deviceTypeManifest: BalenaSdk.DeviceType,
|
||||
deviceTypeManifest: BalenaSdk.DeviceTypeJson.DeviceType,
|
||||
devInit: typeof import('balena-device-init'),
|
||||
): Promise<string> {
|
||||
const osVersion = await devInit.getImageOsVersion(
|
||||
@ -361,11 +368,11 @@ async function getOsVersionFromImage(
|
||||
async function checkDeviceTypeCompatibility(
|
||||
sdk: BalenaSdk.BalenaSDK,
|
||||
options: FlagsDef,
|
||||
app: BalenaSdk.Application,
|
||||
app: ApplicationWithDeviceType,
|
||||
) {
|
||||
if (options['device-type']) {
|
||||
const [appDeviceType, optionDeviceType] = await Promise.all([
|
||||
sdk.models.device.getManifestBySlug(app.device_type),
|
||||
sdk.models.device.getManifestBySlug(app.is_for__device_type[0].slug),
|
||||
sdk.models.device.getManifestBySlug(options['device-type']),
|
||||
]);
|
||||
const helpers = await import('../../utils/helpers');
|
||||
@ -392,7 +399,7 @@ async function checkDeviceTypeCompatibility(
|
||||
* The questions are extracted from the given deviceType "manifest".
|
||||
*/
|
||||
async function askQuestionsForDeviceType(
|
||||
deviceType: BalenaSdk.DeviceType,
|
||||
deviceType: BalenaSdk.DeviceTypeJson.DeviceType,
|
||||
options: FlagsDef,
|
||||
configJson?: import('../../utils/config').ImgConfig,
|
||||
): Promise<Answers> {
|
||||
@ -460,14 +467,17 @@ async function askQuestionsForDeviceType(
|
||||
* [ 'network', 'wifiSsid', 'wifiKey', 'appUpdatePollInterval' ]
|
||||
*/
|
||||
function getQuestionNames(
|
||||
deviceType: BalenaSdk.DeviceType,
|
||||
deviceType: BalenaSdk.DeviceTypeJson.DeviceType,
|
||||
): Array<keyof Answers> {
|
||||
const questionNames: string[] = _.chain(deviceType.options)
|
||||
.flatMap(
|
||||
(group: BalenaSdk.DeviceTypeOptions) =>
|
||||
(group: BalenaSdk.DeviceTypeJson.DeviceTypeOptions) =>
|
||||
(group.isGroup && group.options) || [],
|
||||
)
|
||||
.map((groupOption: BalenaSdk.DeviceTypeOptionsGroup) => groupOption.name)
|
||||
.map(
|
||||
(groupOption: BalenaSdk.DeviceTypeJson.DeviceTypeOptionsGroup) =>
|
||||
groupOption.name,
|
||||
)
|
||||
.filter()
|
||||
.value();
|
||||
return questionNames as Array<keyof Answers>;
|
||||
|
@ -20,7 +20,7 @@ import Command from '../command';
|
||||
import * as cf from '../utils/common-flags';
|
||||
import { getBalenaSdk, stripIndent } from '../utils/lazy';
|
||||
import { dockerignoreHelp, registrySecretsHelp } from '../utils/messages';
|
||||
import type { BalenaSDK } from 'balena-sdk';
|
||||
import type { BalenaSDK, Application, Organization } from 'balena-sdk';
|
||||
import { ExpectedError, instanceOf } from '../errors';
|
||||
|
||||
enum BuildTarget {
|
||||
@ -362,17 +362,21 @@ export default class PushCmd extends Command {
|
||||
async getAppOwner(sdk: BalenaSDK, appName: string) {
|
||||
const _ = await import('lodash');
|
||||
|
||||
const applications = await sdk.models.application.getAll({
|
||||
const applications = (await sdk.models.application.getAll({
|
||||
$expand: {
|
||||
user: {
|
||||
$select: ['username'],
|
||||
organization: {
|
||||
$select: ['handle'],
|
||||
},
|
||||
},
|
||||
$filter: {
|
||||
$eq: [{ $tolower: { $: 'app_name' } }, appName.toLowerCase()],
|
||||
},
|
||||
$select: ['id'],
|
||||
});
|
||||
})) as Array<
|
||||
Application & {
|
||||
organization: [Organization];
|
||||
}
|
||||
>;
|
||||
|
||||
if (applications == null || applications.length === 0) {
|
||||
throw new ExpectedError(
|
||||
@ -385,7 +389,7 @@ export default class PushCmd extends Command {
|
||||
}
|
||||
|
||||
if (applications.length === 1) {
|
||||
return _.get(applications, '[0].user[0].username');
|
||||
return applications[0].organization[0].handle;
|
||||
}
|
||||
|
||||
// If we got more than one application with the same name it means that the
|
||||
@ -393,7 +397,7 @@ export default class PushCmd extends Command {
|
||||
// present a list to the user which shows the fully qualified application
|
||||
// name (user/appname) and allows them to select
|
||||
const entries = _.map(applications, (app) => {
|
||||
const username = _.get(app, 'user[0].username');
|
||||
const username = app.organization[0].handle;
|
||||
return {
|
||||
name: `${username}/${appName}`,
|
||||
extra: username,
|
||||
|
@ -94,7 +94,7 @@ const deployProject = function (docker, logger, composeOpts, opts) {
|
||||
project.name,
|
||||
compositionToBuild,
|
||||
opts.app.arch,
|
||||
opts.app.device_type,
|
||||
opts.app.is_for__device_type[0].slug,
|
||||
opts.buildEmulated,
|
||||
opts.buildOpts,
|
||||
composeOpts.inlineLogs,
|
||||
|
@ -39,6 +39,9 @@ const applicationExpandOptions = {
|
||||
status: 'success',
|
||||
},
|
||||
},
|
||||
should_be_running__release: {
|
||||
$select: 'commit',
|
||||
},
|
||||
};
|
||||
|
||||
let allDeviceTypes;
|
||||
@ -69,11 +72,18 @@ const getApplicationsWithSuccessfulBuilds = function (deviceType) {
|
||||
const balena = getBalenaSdk();
|
||||
|
||||
return getDeviceTypesWithSameArch(deviceType).then((deviceTypes) => {
|
||||
/** @type {import('balena-sdk').PineOptionsFor<import('balena-sdk').Application>} */
|
||||
/** @type {import('balena-sdk').PineOptions<ApplicationWithDeviceType & { should_be_running__release: [import('balena-sdk').Release?] }>} */
|
||||
const options = {
|
||||
$filter: {
|
||||
device_type: {
|
||||
$in: deviceTypes,
|
||||
is_for__device_type: {
|
||||
$any: {
|
||||
$alias: 'dt',
|
||||
$expr: {
|
||||
dt: {
|
||||
slug: { $in: deviceTypes },
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
owns__release: {
|
||||
$any: {
|
||||
@ -87,13 +97,7 @@ const getApplicationsWithSuccessfulBuilds = function (deviceType) {
|
||||
},
|
||||
},
|
||||
$expand: applicationExpandOptions,
|
||||
$select: [
|
||||
'id',
|
||||
'app_name',
|
||||
'device_type',
|
||||
'commit',
|
||||
'should_track_latest_release',
|
||||
],
|
||||
$select: ['id', 'app_name', 'should_track_latest_release'],
|
||||
$orderby: 'app_name asc',
|
||||
};
|
||||
return balena.pine.get({
|
||||
@ -209,9 +213,10 @@ Would you like to disable automatic updates for this application now?\
|
||||
/**
|
||||
* @param {import('balena-sdk').BalenaSDK} balenaSdk
|
||||
* @param {string | number} appId
|
||||
* @returns {Promise<import('balena-sdk').Application>}
|
||||
* @returns {Promise<import('balena-sdk').Application & { should_be_running__release: [import('balena-sdk').Release?] }>}
|
||||
*/
|
||||
async function getAppWithReleases(balenaSdk, appId) {
|
||||
// @ts-ignore
|
||||
return balenaSdk.models.application.get(appId, {
|
||||
$expand: applicationExpandOptions,
|
||||
});
|
||||
@ -229,10 +234,12 @@ async function prepareAndPreload(preloader, balenaSdk, options) {
|
||||
/** @type {string} commit hash or the strings 'latest' or 'current' */
|
||||
let commit;
|
||||
|
||||
const appCommit = application.should_be_running__release[0]?.commit;
|
||||
|
||||
// Use the commit given as --commit or show an interactive commit selection menu
|
||||
if (options.commit) {
|
||||
if (isCurrent(options.commit)) {
|
||||
if (!application.commit) {
|
||||
if (!appCommit) {
|
||||
throw new Error(
|
||||
`Unexpected empty commit hash for app ID "${application.id}"`,
|
||||
);
|
||||
@ -257,7 +264,7 @@ async function prepareAndPreload(preloader, balenaSdk, options) {
|
||||
|
||||
await preloader.setAppIdAndCommit(
|
||||
application.id,
|
||||
isCurrent(commit) ? application.commit : commit,
|
||||
isCurrent(commit) ? appCommit : commit,
|
||||
);
|
||||
|
||||
// Propose to disable automatic app updates if the commit is not the current release
|
||||
|
@ -92,7 +92,7 @@ export const getDeviceAndMaybeAppFromUUID = _.memoize(
|
||||
$expand: selectAppFields
|
||||
? { belongs_to__application: { $select: selectAppFields } }
|
||||
: 'belongs_to__application',
|
||||
} as SDK.PineOptionsFor<SDK.Device>;
|
||||
} as SDK.PineOptions<SDK.Device>;
|
||||
if (selectDeviceFields) {
|
||||
pineOpts.$select = selectDeviceFields as any;
|
||||
}
|
||||
|
@ -102,7 +102,7 @@ export async function generateApplicationConfig(
|
||||
}
|
||||
|
||||
export function generateDeviceConfig(
|
||||
device: BalenaSdk.Device & {
|
||||
device: DeviceWithDeviceType & {
|
||||
belongs_to__application: BalenaSdk.PineDeferred;
|
||||
},
|
||||
deviceApiKey: string | true | undefined,
|
||||
@ -113,7 +113,7 @@ export function generateDeviceConfig(
|
||||
.then(async (application) => {
|
||||
const baseConfigOpts = {
|
||||
...options,
|
||||
deviceType: device.device_type,
|
||||
deviceType: device.is_of__device_type[0].slug,
|
||||
};
|
||||
const config = await generateBaseConfig(application, baseConfigOpts);
|
||||
|
||||
|
@ -21,7 +21,7 @@ import * as _ from 'lodash';
|
||||
import * as os from 'os';
|
||||
import type * as ShellEscape from 'shell-escape';
|
||||
|
||||
import type { Device, PineOptionsFor } from 'balena-sdk';
|
||||
import type { Device, PineOptions } from 'balena-sdk';
|
||||
import { ExpectedError } from '../errors';
|
||||
import { getBalenaSdk, getChalk, getVisuals } from './lazy';
|
||||
import { promisify } from 'util';
|
||||
@ -121,7 +121,7 @@ export function runCommand<T>(commandArgs: string[]): Promise<T> {
|
||||
export async function getManifest(
|
||||
image: string,
|
||||
deviceType: string,
|
||||
): Promise<BalenaSdk.DeviceType> {
|
||||
): Promise<BalenaSdk.DeviceTypeJson.DeviceType> {
|
||||
const init = await import('balena-device-init');
|
||||
const manifest = await init.getImageManifest(image);
|
||||
if (manifest != null) {
|
||||
@ -131,8 +131,8 @@ export async function getManifest(
|
||||
}
|
||||
|
||||
export const areDeviceTypesCompatible = (
|
||||
appDeviceType: BalenaSdk.DeviceType,
|
||||
osDeviceType: BalenaSdk.DeviceType,
|
||||
appDeviceType: BalenaSdk.DeviceTypeJson.DeviceType,
|
||||
osDeviceType: BalenaSdk.DeviceTypeJson.DeviceType,
|
||||
) =>
|
||||
getBalenaSdk().models.os.isArchitectureCompatibleWith(
|
||||
osDeviceType.arch,
|
||||
@ -166,13 +166,13 @@ export async function osProgressHandler(step: InitializeEmitter) {
|
||||
|
||||
export function getAppWithArch(
|
||||
applicationName: string,
|
||||
): Promise<BalenaSdk.Application & { arch: string }> {
|
||||
): Promise<ApplicationWithDeviceType & { arch: string }> {
|
||||
return Promise.all([
|
||||
getApplication(applicationName),
|
||||
getBalenaSdk().models.config.getDeviceTypes(),
|
||||
]).then(function ([app, deviceTypes]) {
|
||||
const config = _.find<BalenaSdk.DeviceType>(deviceTypes, {
|
||||
slug: app.device_type,
|
||||
const config = _.find<BalenaSdk.DeviceTypeJson.DeviceType>(deviceTypes, {
|
||||
slug: app.is_for__device_type[0].slug,
|
||||
});
|
||||
|
||||
if (!config) {
|
||||
@ -183,16 +183,21 @@ export function getAppWithArch(
|
||||
});
|
||||
}
|
||||
|
||||
function getApplication(applicationName: string) {
|
||||
function getApplication(
|
||||
applicationName: string,
|
||||
): Promise<ApplicationWithDeviceType> {
|
||||
// Check for an app of the form `user/application`, and send
|
||||
// that off to a special handler (before importing any modules)
|
||||
const match = applicationName.split('/');
|
||||
|
||||
const extraOptions: BalenaSdk.PineOptionsFor<BalenaSdk.Application> = {
|
||||
const extraOptions: BalenaSdk.PineOptions<BalenaSdk.Application> = {
|
||||
$expand: {
|
||||
application_type: {
|
||||
$select: ['name', 'slug', 'supports_multicontainer', 'is_legacy'],
|
||||
},
|
||||
is_for__device_type: {
|
||||
$select: 'slug',
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
@ -487,6 +492,10 @@ export function getProxyConfig(): ProxyConfig | undefined {
|
||||
}
|
||||
}
|
||||
|
||||
export const expandForAppName: PineOptionsFor<Device> = {
|
||||
$expand: { belongs_to__application: { $select: 'app_name' } },
|
||||
export const expandForAppName: PineOptions<Device> = {
|
||||
$expand: {
|
||||
belongs_to__application: { $select: 'app_name' },
|
||||
is_of__device_type: { $select: 'slug' },
|
||||
is_running__release: { $select: 'commit' },
|
||||
},
|
||||
};
|
||||
|
@ -168,7 +168,7 @@ export async function confirm(
|
||||
}
|
||||
|
||||
export function selectApplication(
|
||||
filter?: (app: BalenaSdk.Application) => boolean,
|
||||
filter?: (app: ApplicationWithDeviceType) => boolean,
|
||||
errorOnEmptySelection = false,
|
||||
) {
|
||||
const balena = getBalenaSdk();
|
||||
@ -179,7 +179,7 @@ export function selectApplication(
|
||||
throw new ExpectedError("You don't have any applications");
|
||||
}
|
||||
|
||||
return balena.models.application.getAll();
|
||||
return balena.models.application.getAll() as Promise<ApplicationWithDeviceType[]>;
|
||||
})
|
||||
.filter(filter || _.constant(true))
|
||||
.then((applications) => {
|
||||
@ -190,7 +190,7 @@ export function selectApplication(
|
||||
message: 'Select an application',
|
||||
type: 'list',
|
||||
choices: _.map(applications, (application) => ({
|
||||
name: `${application.app_name} (${application.device_type})`,
|
||||
name: `${application.app_name} (${application.is_for__device_type[0].slug})`,
|
||||
value: application.app_name,
|
||||
})),
|
||||
});
|
||||
@ -207,14 +207,20 @@ export function selectOrCreateApplication() {
|
||||
return Promise.resolve(undefined);
|
||||
}
|
||||
|
||||
return balena.models.application.getAll().then((applications) => {
|
||||
const appOptions = _.map<
|
||||
BalenaSdk.Application,
|
||||
{ name: string; value: string | null }
|
||||
>(applications, (application) => ({
|
||||
name: `${application.app_name} (${application.device_type})`,
|
||||
value: application.app_name,
|
||||
}));
|
||||
return (balena.models.application.getAll({
|
||||
$expand: {
|
||||
is_for__device_type: {
|
||||
$select: 'slug',
|
||||
},
|
||||
},
|
||||
}) as Promise<ApplicationWithDeviceType[]>).then((applications) => {
|
||||
const appOptions: Array<{ name: string; value: string | null }> = _.map(
|
||||
applications,
|
||||
(application) => ({
|
||||
name: `${application.app_name} (${application.is_for__device_type[0].slug})`,
|
||||
value: application.app_name,
|
||||
}),
|
||||
);
|
||||
|
||||
appOptions.unshift({
|
||||
name: 'Create a new application',
|
||||
|
@ -40,10 +40,12 @@ export async function join(
|
||||
|
||||
logger.logDebug('Determining application...');
|
||||
const app = await getOrSelectApplication(sdk, deviceType, appName);
|
||||
logger.logDebug(`Using application: ${app.app_name} (${app.device_type})`);
|
||||
if (app.device_type !== deviceType) {
|
||||
logger.logDebug(
|
||||
`Using application: ${app.app_name} (${app.is_for__device_type[0].slug})`,
|
||||
);
|
||||
if (app.is_for__device_type[0].slug !== deviceType) {
|
||||
logger.logDebug(`Forcing device type to: ${deviceType}`);
|
||||
app.device_type = deviceType;
|
||||
app.is_for__device_type[0].slug = deviceType;
|
||||
}
|
||||
|
||||
logger.logDebug('Determining device OS version...');
|
||||
@ -186,7 +188,9 @@ async function getOrSelectLocalDevice(deviceIp?: string): Promise<string> {
|
||||
return ip;
|
||||
}
|
||||
|
||||
async function selectAppFromList(applications: BalenaSdk.Application[]) {
|
||||
async function selectAppFromList(
|
||||
applications: ApplicationWithDeviceType[],
|
||||
): Promise<ApplicationWithDeviceType> {
|
||||
const _ = await import('lodash');
|
||||
const { selectFromList } = await import('../utils/patterns');
|
||||
|
||||
@ -204,7 +208,7 @@ async function getOrSelectApplication(
|
||||
sdk: BalenaSdk.BalenaSDK,
|
||||
deviceType: string,
|
||||
appName?: string,
|
||||
): Promise<BalenaSdk.Application> {
|
||||
): Promise<ApplicationWithDeviceType> {
|
||||
const _ = await import('lodash');
|
||||
|
||||
const allDeviceTypes = await sdk.models.config.getDeviceTypes();
|
||||
@ -229,7 +233,11 @@ async function getOrSelectApplication(
|
||||
return createOrSelectAppOrExit(sdk, compatibleDeviceTypes, deviceType);
|
||||
}
|
||||
|
||||
const options: BalenaSdk.PineOptionsFor<BalenaSdk.Application> = {};
|
||||
const options: BalenaSdk.PineOptions<BalenaSdk.Application> = {
|
||||
$expand: {
|
||||
is_for__device_type: { $select: 'slug' },
|
||||
},
|
||||
};
|
||||
|
||||
// Check for an app of the form `user/application` and update the API query.
|
||||
let name: string;
|
||||
@ -245,7 +253,9 @@ async function getOrSelectApplication(
|
||||
name = appName;
|
||||
}
|
||||
|
||||
const applications = await sdk.models.application.getAll(options);
|
||||
const applications = (await sdk.models.application.getAll(
|
||||
options,
|
||||
)) as ApplicationWithDeviceType[];
|
||||
|
||||
if (applications.length === 0) {
|
||||
const shouldCreateApp = await getCliForm().ask({
|
||||
@ -264,7 +274,7 @@ async function getOrSelectApplication(
|
||||
// We've found at least one app with the given name.
|
||||
// Filter out apps for non-matching device types and see what we're left with.
|
||||
const validApplications = applications.filter((app) =>
|
||||
_.includes(compatibleDeviceTypes, app.device_type),
|
||||
_.includes(compatibleDeviceTypes, app.is_for__device_type[0].slug),
|
||||
);
|
||||
|
||||
if (validApplications.length === 0) {
|
||||
@ -285,13 +295,19 @@ async function createOrSelectAppOrExit(
|
||||
sdk: BalenaSdk.BalenaSDK,
|
||||
compatibleDeviceTypes: string[],
|
||||
deviceType: string,
|
||||
) {
|
||||
const options = {
|
||||
$filter: { device_type: { $in: compatibleDeviceTypes } },
|
||||
};
|
||||
|
||||
): Promise<ApplicationWithDeviceType> {
|
||||
// No application specified, show a list to select one.
|
||||
const applications = await sdk.models.application.getAll(options);
|
||||
const applications = (await sdk.models.application.getAll({
|
||||
$expand: { is_for__device_type: { $select: 'slug' } },
|
||||
$filter: {
|
||||
is_for__device_type: {
|
||||
$any: {
|
||||
$alias: 'dt',
|
||||
$expr: { dt: { slug: { $in: compatibleDeviceTypes } } },
|
||||
},
|
||||
},
|
||||
},
|
||||
})) as ApplicationWithDeviceType[];
|
||||
|
||||
if (applications.length === 0) {
|
||||
const shouldCreateApp = await getCliForm().ask({
|
||||
@ -314,14 +330,13 @@ async function createApplication(
|
||||
sdk: BalenaSdk.BalenaSDK,
|
||||
deviceType: string,
|
||||
name?: string,
|
||||
): Promise<BalenaSdk.Application> {
|
||||
): Promise<ApplicationWithDeviceType> {
|
||||
const validation = await import('./validation');
|
||||
|
||||
let username = await sdk.auth.whoami();
|
||||
const username = await sdk.auth.whoami();
|
||||
if (!username) {
|
||||
throw new sdk.errors.BalenaNotLoggedIn();
|
||||
}
|
||||
username = username.toLowerCase();
|
||||
|
||||
const applicationName = await new Promise<string>(async (resolve, reject) => {
|
||||
while (true) {
|
||||
@ -337,7 +352,7 @@ async function createApplication(
|
||||
await sdk.models.application.get(appName, {
|
||||
$filter: {
|
||||
$or: [
|
||||
{ slug: { $startswith: `${username}/` } },
|
||||
{ slug: { $startswith: `${username!.toLowerCase()}/` } },
|
||||
{ $not: { slug: { $contains: '/' } } },
|
||||
],
|
||||
},
|
||||
@ -357,20 +372,28 @@ async function createApplication(
|
||||
}
|
||||
});
|
||||
|
||||
return sdk.models.application.create({
|
||||
const app = await sdk.models.application.create({
|
||||
name: applicationName,
|
||||
deviceType,
|
||||
organization: username,
|
||||
});
|
||||
return (await sdk.models.application.get(app.id, {
|
||||
$expand: {
|
||||
is_for__device_type: { $select: 'slug' },
|
||||
},
|
||||
})) as ApplicationWithDeviceType;
|
||||
}
|
||||
|
||||
async function generateApplicationConfig(
|
||||
sdk: BalenaSdk.BalenaSDK,
|
||||
app: BalenaSdk.Application,
|
||||
app: ApplicationWithDeviceType,
|
||||
options: { version: string },
|
||||
) {
|
||||
const { generateApplicationConfig: configGen } = await import('./config');
|
||||
|
||||
const manifest = await sdk.models.device.getManifestBySlug(app.device_type);
|
||||
const manifest = await sdk.models.device.getManifestBySlug(
|
||||
app.is_for__device_type[0].slug,
|
||||
);
|
||||
const opts =
|
||||
manifest.options &&
|
||||
manifest.options.filter((opt) => opt.name !== 'network');
|
||||
|
165
npm-shrinkwrap.json
generated
165
npm-shrinkwrap.json
generated
@ -2243,44 +2243,6 @@
|
||||
"resin-image-fs": "^5.0.9"
|
||||
},
|
||||
"dependencies": {
|
||||
"balena-sdk": {
|
||||
"version": "14.1.0",
|
||||
"resolved": "https://registry.npmjs.org/balena-sdk/-/balena-sdk-14.1.0.tgz",
|
||||
"integrity": "sha512-J/T1F3zQI6GChK0zZp5YKdNhBSynx3VaXk7tGcGykNnLuN4ZVeApHPZ7vVLUuyN/hvckax55iKSPO5JSEYA0sg==",
|
||||
"requires": {
|
||||
"@balena/es-version": "^1.0.0",
|
||||
"@types/bluebird": "^3.5.30",
|
||||
"@types/lodash": "^4.14.150",
|
||||
"@types/memoizee": "^0.4.3",
|
||||
"@types/node": "^10.17.20",
|
||||
"abortcontroller-polyfill": "^1.4.0",
|
||||
"balena-auth": "^3.1.0",
|
||||
"balena-errors": "^4.4.0",
|
||||
"balena-hup-action-utils": "~4.0.1",
|
||||
"balena-pine": "^11.2.0",
|
||||
"balena-register-device": "^6.1.1",
|
||||
"balena-request": "^10.0.9",
|
||||
"balena-semver": "^2.3.0",
|
||||
"balena-settings-client": "^4.0.4",
|
||||
"bluebird": "^3.7.2",
|
||||
"lodash": "^4.17.15",
|
||||
"memoizee": "^0.4.14",
|
||||
"moment": "~2.24.0 || ^2.25.1",
|
||||
"ndjson": "^1.5.0",
|
||||
"semver": "^7.3.2"
|
||||
},
|
||||
"dependencies": {
|
||||
"balena-errors": {
|
||||
"version": "4.4.0",
|
||||
"resolved": "https://registry.npmjs.org/balena-errors/-/balena-errors-4.4.0.tgz",
|
||||
"integrity": "sha512-w5Zje97Gl0veNKpAhH4OQ3R7ACt0MYNUBfb37o1/Yq7EeeB7HsVFsvXNhZwBn8DIBvJamxZWSIbqjw53GKjUzQ==",
|
||||
"requires": {
|
||||
"tslib": "^1.11.1",
|
||||
"typed-error": "^3.0.0"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"balena-semver": {
|
||||
"version": "2.3.0",
|
||||
"resolved": "https://registry.npmjs.org/balena-semver/-/balena-semver-2.3.0.tgz",
|
||||
@ -2354,44 +2316,6 @@
|
||||
"rimraf": "^3.0.2"
|
||||
},
|
||||
"dependencies": {
|
||||
"balena-sdk": {
|
||||
"version": "14.1.0",
|
||||
"resolved": "https://registry.npmjs.org/balena-sdk/-/balena-sdk-14.1.0.tgz",
|
||||
"integrity": "sha512-J/T1F3zQI6GChK0zZp5YKdNhBSynx3VaXk7tGcGykNnLuN4ZVeApHPZ7vVLUuyN/hvckax55iKSPO5JSEYA0sg==",
|
||||
"requires": {
|
||||
"@balena/es-version": "^1.0.0",
|
||||
"@types/bluebird": "^3.5.30",
|
||||
"@types/lodash": "^4.14.150",
|
||||
"@types/memoizee": "^0.4.3",
|
||||
"@types/node": "^10.17.20",
|
||||
"abortcontroller-polyfill": "^1.4.0",
|
||||
"balena-auth": "^3.1.0",
|
||||
"balena-errors": "^4.4.0",
|
||||
"balena-hup-action-utils": "~4.0.1",
|
||||
"balena-pine": "^11.2.0",
|
||||
"balena-register-device": "^6.1.1",
|
||||
"balena-request": "^10.0.9",
|
||||
"balena-semver": "^2.3.0",
|
||||
"balena-settings-client": "^4.0.4",
|
||||
"bluebird": "^3.7.2",
|
||||
"lodash": "^4.17.15",
|
||||
"memoizee": "^0.4.14",
|
||||
"moment": "~2.24.0 || ^2.25.1",
|
||||
"ndjson": "^1.5.0",
|
||||
"semver": "^7.3.2"
|
||||
},
|
||||
"dependencies": {
|
||||
"balena-errors": {
|
||||
"version": "4.4.0",
|
||||
"resolved": "https://registry.npmjs.org/balena-errors/-/balena-errors-4.4.0.tgz",
|
||||
"integrity": "sha512-w5Zje97Gl0veNKpAhH4OQ3R7ACt0MYNUBfb37o1/Yq7EeeB7HsVFsvXNhZwBn8DIBvJamxZWSIbqjw53GKjUzQ==",
|
||||
"requires": {
|
||||
"tslib": "^1.11.1",
|
||||
"typed-error": "^3.0.0"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"balena-semver": {
|
||||
"version": "2.3.0",
|
||||
"resolved": "https://registry.npmjs.org/balena-semver/-/balena-semver-2.3.0.tgz",
|
||||
@ -2474,34 +2398,6 @@
|
||||
"typed-error": "^3.0.0"
|
||||
}
|
||||
},
|
||||
"balena-sdk": {
|
||||
"version": "14.8.0",
|
||||
"resolved": "https://registry.npmjs.org/balena-sdk/-/balena-sdk-14.8.0.tgz",
|
||||
"integrity": "sha512-GptB/Ju8BtE1E9NODHioScdF4HW8svcDhfdMHPrDjMFWbs38KOoTgiKogDjLlvEjoAg5FIvz8DaUeH27EtZ1Rg==",
|
||||
"requires": {
|
||||
"@balena/es-version": "^1.0.0",
|
||||
"@types/bluebird": "^3.5.30",
|
||||
"@types/lodash": "^4.14.150",
|
||||
"@types/memoizee": "^0.4.3",
|
||||
"@types/node": "^10.17.20",
|
||||
"abortcontroller-polyfill": "^1.4.0",
|
||||
"balena-auth": "^3.1.0",
|
||||
"balena-errors": "^4.4.0",
|
||||
"balena-hup-action-utils": "~4.0.1",
|
||||
"balena-pine": "^11.2.0",
|
||||
"balena-register-device": "^6.1.1",
|
||||
"balena-request": "^10.0.9",
|
||||
"balena-semver": "^2.3.0",
|
||||
"balena-settings-client": "^4.0.4",
|
||||
"bluebird": "^3.7.2",
|
||||
"lodash": "^4.17.15",
|
||||
"memoizee": "^0.4.14",
|
||||
"moment": "~2.24.0 || ^2.25.1",
|
||||
"ndjson": "^1.5.0",
|
||||
"semver": "^7.3.2",
|
||||
"tslib": "^2.0.0"
|
||||
}
|
||||
},
|
||||
"balena-semver": {
|
||||
"version": "2.3.0",
|
||||
"resolved": "https://registry.npmjs.org/balena-semver/-/balena-semver-2.3.0.tgz",
|
||||
@ -2638,19 +2534,20 @@
|
||||
}
|
||||
},
|
||||
"balena-sdk": {
|
||||
"version": "13.8.0",
|
||||
"resolved": "https://registry.npmjs.org/balena-sdk/-/balena-sdk-13.8.0.tgz",
|
||||
"integrity": "sha512-EhaXZq7kNCewhp0oSMeeTslvRIhvaV0QxlS7u3SWmdMoDjH1gdg01sG2I3b20DkN8oDAIoNkaD14eo2eTf0C8w==",
|
||||
"version": "14.8.0",
|
||||
"resolved": "https://registry.npmjs.org/balena-sdk/-/balena-sdk-14.8.0.tgz",
|
||||
"integrity": "sha512-GptB/Ju8BtE1E9NODHioScdF4HW8svcDhfdMHPrDjMFWbs38KOoTgiKogDjLlvEjoAg5FIvz8DaUeH27EtZ1Rg==",
|
||||
"requires": {
|
||||
"@balena/es-version": "^1.0.0",
|
||||
"@types/bluebird": "^3.5.30",
|
||||
"@types/lodash": "^4.14.150",
|
||||
"@types/memoizee": "^0.4.3",
|
||||
"@types/node": "^10.17.20",
|
||||
"abortcontroller-polyfill": "^1.4.0",
|
||||
"balena-auth": "^3.0.1",
|
||||
"balena-auth": "^3.1.0",
|
||||
"balena-errors": "^4.4.0",
|
||||
"balena-hup-action-utils": "~4.0.1",
|
||||
"balena-pine": "^11.0.1",
|
||||
"balena-pine": "^11.2.0",
|
||||
"balena-register-device": "^6.1.1",
|
||||
"balena-request": "^10.0.9",
|
||||
"balena-semver": "^2.3.0",
|
||||
@ -2660,15 +2557,16 @@
|
||||
"memoizee": "^0.4.14",
|
||||
"moment": "~2.24.0 || ^2.25.1",
|
||||
"ndjson": "^1.5.0",
|
||||
"semver": "^7.3.2"
|
||||
"semver": "^7.3.2",
|
||||
"tslib": "^2.0.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"balena-errors": {
|
||||
"version": "4.4.0",
|
||||
"resolved": "https://registry.npmjs.org/balena-errors/-/balena-errors-4.4.0.tgz",
|
||||
"integrity": "sha512-w5Zje97Gl0veNKpAhH4OQ3R7ACt0MYNUBfb37o1/Yq7EeeB7HsVFsvXNhZwBn8DIBvJamxZWSIbqjw53GKjUzQ==",
|
||||
"version": "4.4.1",
|
||||
"resolved": "https://registry.npmjs.org/balena-errors/-/balena-errors-4.4.1.tgz",
|
||||
"integrity": "sha512-912lPp1LyBjkpxRg6m/EpOCssqMhgkzyYbrKwtT2uRvixm89WOlJrj5sPkxnbPnp5IoMNaoRONxFt1jtiQf50Q==",
|
||||
"requires": {
|
||||
"tslib": "^1.11.1",
|
||||
"tslib": "^2.0.0",
|
||||
"typed-error": "^3.0.0"
|
||||
}
|
||||
},
|
||||
@ -2689,9 +2587,9 @@
|
||||
"integrity": "sha512-OrOb32TeeambH6UrhtShmF7CRDqhL6/5XpPNp2DuRH6+9QLw/orhp72j87v8Qa1ScDkvrrBNpZcDejAirJmfXQ=="
|
||||
},
|
||||
"tslib": {
|
||||
"version": "1.13.0",
|
||||
"resolved": "https://registry.npmjs.org/tslib/-/tslib-1.13.0.tgz",
|
||||
"integrity": "sha512-i/6DQjL8Xf3be4K/E6Wgpekn5Qasl1usyw++dAA35Ue5orEn65VIxOA+YvNNl9HV3qv70T7CNwjODHZrLwvd1Q=="
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.0.0.tgz",
|
||||
"integrity": "sha512-lTqkx847PI7xEDYJntxZH89L2/aXInsyF2luSafe/+0fHOMjlBNXdH6th7f70qxLDhul7KZK0zC8V5ZIyHl0/g=="
|
||||
}
|
||||
}
|
||||
},
|
||||
@ -2794,33 +2692,6 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"balena-sdk": {
|
||||
"version": "14.1.0",
|
||||
"resolved": "https://registry.npmjs.org/balena-sdk/-/balena-sdk-14.1.0.tgz",
|
||||
"integrity": "sha512-J/T1F3zQI6GChK0zZp5YKdNhBSynx3VaXk7tGcGykNnLuN4ZVeApHPZ7vVLUuyN/hvckax55iKSPO5JSEYA0sg==",
|
||||
"requires": {
|
||||
"@balena/es-version": "^1.0.0",
|
||||
"@types/bluebird": "^3.5.30",
|
||||
"@types/lodash": "^4.14.150",
|
||||
"@types/memoizee": "^0.4.3",
|
||||
"@types/node": "^10.17.20",
|
||||
"abortcontroller-polyfill": "^1.4.0",
|
||||
"balena-auth": "^3.1.0",
|
||||
"balena-errors": "^4.4.0",
|
||||
"balena-hup-action-utils": "~4.0.1",
|
||||
"balena-pine": "^11.2.0",
|
||||
"balena-register-device": "^6.1.1",
|
||||
"balena-request": "^10.0.9",
|
||||
"balena-semver": "^2.3.0",
|
||||
"balena-settings-client": "^4.0.4",
|
||||
"bluebird": "^3.7.2",
|
||||
"lodash": "^4.17.15",
|
||||
"memoizee": "^0.4.14",
|
||||
"moment": "~2.24.0 || ^2.25.1",
|
||||
"ndjson": "^1.5.0",
|
||||
"semver": "^7.3.2"
|
||||
}
|
||||
},
|
||||
"balena-semver": {
|
||||
"version": "2.3.0",
|
||||
"resolved": "https://registry.npmjs.org/balena-semver/-/balena-semver-2.3.0.tgz",
|
||||
@ -12604,9 +12475,9 @@
|
||||
}
|
||||
},
|
||||
"ref-napi": {
|
||||
"version": "2.0.3",
|
||||
"resolved": "https://registry.npmjs.org/ref-napi/-/ref-napi-2.0.3.tgz",
|
||||
"integrity": "sha512-zsAhPhh9gUlk0pP5iR9nhvwFeC/E9G1X0cdH/qQRTwx3VDgVi40Aflq/EdbobcVg++RNaMxZsbaQV+/E2u57LQ==",
|
||||
"version": "2.0.4",
|
||||
"resolved": "https://registry.npmjs.org/ref-napi/-/ref-napi-2.0.4.tgz",
|
||||
"integrity": "sha512-Ees+O+abgS4skRDU/RyICk9gbSaVjYCN1FXivAlcxdj/yW9N+GFKbB9fYACa+lgBjjqjSGHw5SkoP5GU0anwwQ==",
|
||||
"optional": true,
|
||||
"requires": {
|
||||
"debug": "^4.1.1",
|
||||
|
@ -26,6 +26,7 @@
|
||||
"pkg": {
|
||||
"scripts": [
|
||||
"build/**/*.js",
|
||||
"node_modules/balena-sdk/es2018/index.js",
|
||||
"node_modules/balena-sync/build/capitano/*.js",
|
||||
"node_modules/balena-sync/build/sync/*.js",
|
||||
"node_modules/pinejs-client-request/node_modules/pinejs-client-core/es2018/index.js",
|
||||
@ -192,7 +193,7 @@
|
||||
"balena-image-manager": "^7.0.1",
|
||||
"balena-preload": "^10.2.0",
|
||||
"balena-release": "^3.0.0",
|
||||
"balena-sdk": "^13.6.0",
|
||||
"balena-sdk": "^14.8.0",
|
||||
"balena-semver": "^2.2.0",
|
||||
"balena-settings-client": "^4.0.5",
|
||||
"balena-settings-storage": "^6.0.0",
|
||||
|
@ -35,26 +35,6 @@ export class BalenaAPIMock extends NockMock {
|
||||
notFound = false,
|
||||
optional = false,
|
||||
persist = false,
|
||||
} = {}) {
|
||||
const interceptor = this.optGet(/^\/v5\/application($|[(?])/, {
|
||||
optional,
|
||||
persist,
|
||||
});
|
||||
if (notFound) {
|
||||
interceptor.reply(200, { d: [] });
|
||||
} else {
|
||||
interceptor.replyWithFile(
|
||||
200,
|
||||
path.join(apiResponsePath, 'application-GET-v5-expanded-app-type.json'),
|
||||
jHeader,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
public expectGetApplicationV6({
|
||||
notFound = false,
|
||||
optional = false,
|
||||
persist = false,
|
||||
} = {}) {
|
||||
const interceptor = this.optGet(/^\/v6\/application($|[(?])/, {
|
||||
optional,
|
||||
@ -99,10 +79,10 @@ export class BalenaAPIMock extends NockMock {
|
||||
}
|
||||
|
||||
public expectGetMyApplication(opts: ScopeOpts = {}) {
|
||||
this.optGet(/^\/v5\/my_application($|[(?])/, opts).reply(
|
||||
this.optGet(/^\/v6\/my_application($|[(?])/, opts).reply(
|
||||
200,
|
||||
JSON.parse(`{"d": [{
|
||||
"user": [{ "username": "bob", "__metadata": {} }],
|
||||
"organization": [{ "handle": "bob", "__metadata": {} }],
|
||||
"id": 1301645,
|
||||
"__metadata": { "uri": "/resin/my_application(@id)?@id=1301645" }}]}
|
||||
`),
|
||||
@ -116,13 +96,16 @@ export class BalenaAPIMock extends NockMock {
|
||||
}
|
||||
|
||||
public expectGetRelease(opts: ScopeOpts = {}) {
|
||||
this.optGet(/^\/v5\/release($|[(?])/, opts).replyWithFile(
|
||||
this.optGet(/^\/v6\/release($|[(?])/, opts).replyWithFile(
|
||||
200,
|
||||
path.join(apiResponsePath, 'release-GET-v5.json'),
|
||||
path.join(apiResponsePath, 'release-GET-v6.json'),
|
||||
jHeader,
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Mocks balena-release call
|
||||
*/
|
||||
public expectPatchRelease({
|
||||
replyBody = 'OK',
|
||||
statusCode = 200,
|
||||
@ -136,6 +119,9 @@ export class BalenaAPIMock extends NockMock {
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Mocks balena-release call
|
||||
*/
|
||||
public expectPostRelease(opts: ScopeOpts = {}) {
|
||||
this.optPost(/^\/v6\/release($|[(?])/, opts).replyWithFile(
|
||||
200,
|
||||
@ -144,6 +130,9 @@ export class BalenaAPIMock extends NockMock {
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Mocks balena-release call
|
||||
*/
|
||||
public expectPatchImage({
|
||||
replyBody = 'OK',
|
||||
statusCode = 200,
|
||||
@ -157,6 +146,9 @@ export class BalenaAPIMock extends NockMock {
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Mocks balena-release call
|
||||
*/
|
||||
public expectPostImage(opts: ScopeOpts = {}) {
|
||||
this.optPost(/^\/v6\/image($|[(?])/, opts).replyWithFile(
|
||||
201,
|
||||
@ -165,6 +157,9 @@ export class BalenaAPIMock extends NockMock {
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Mocks balena-release call
|
||||
*/
|
||||
public expectPostImageLabel(opts: ScopeOpts = {}) {
|
||||
this.optPost(/^\/v6\/image_label($|[(?])/, opts).replyWithFile(
|
||||
201,
|
||||
@ -173,6 +168,9 @@ export class BalenaAPIMock extends NockMock {
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Mocks balena-release call
|
||||
*/
|
||||
public expectPostImageIsPartOfRelease(opts: ScopeOpts = {}) {
|
||||
this.optPost(
|
||||
/^\/v6\/image__is_part_of__release($|[(?])/,
|
||||
@ -350,23 +348,10 @@ export class BalenaAPIMock extends NockMock {
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Mocks balena-release call
|
||||
*/
|
||||
public expectGetUser(opts: ScopeOpts = {}) {
|
||||
this.optGet(/^\/v5\/user/, opts).reply(200, {
|
||||
d: [
|
||||
{
|
||||
id: 99999,
|
||||
actor: 1234567,
|
||||
username: 'gh_user',
|
||||
created_at: '2018-08-19T13:55:04.485Z',
|
||||
__metadata: {
|
||||
uri: '/resin/user(@id)?@id=43699',
|
||||
},
|
||||
},
|
||||
],
|
||||
});
|
||||
}
|
||||
|
||||
public expectGetUserV6(opts: ScopeOpts = {}) {
|
||||
this.optGet(/^\/v6\/user/, opts).reply(200, {
|
||||
d: [
|
||||
{
|
||||
|
@ -80,10 +80,9 @@ describe('balena deploy', function () {
|
||||
api.expectGetMixpanel({ optional: true });
|
||||
api.expectGetDeviceTypes();
|
||||
api.expectGetApplication();
|
||||
api.expectGetApplicationV6();
|
||||
api.expectPostRelease();
|
||||
api.expectGetRelease();
|
||||
api.expectGetUserV6();
|
||||
api.expectGetUser();
|
||||
api.expectGetService({ serviceName: 'main' });
|
||||
api.expectPostService409();
|
||||
api.expectGetAuth();
|
||||
|
@ -74,7 +74,7 @@ describe('balena device', function () {
|
||||
it('should list device details for provided uuid', async () => {
|
||||
api.scope
|
||||
.get(
|
||||
/^\/v5\/device\?.+&\$expand=belongs_to__application\(\$select=app_name\)/,
|
||||
/^\/v6\/device\?.+&\$expand=belongs_to__application\(\$select=app_name\)/,
|
||||
)
|
||||
.replyWithFile(200, path.join(apiResponsePath, 'device.json'), {
|
||||
'Content-Type': 'application/json',
|
||||
@ -96,7 +96,7 @@ describe('balena device', function () {
|
||||
// e.g. When user has a device associated with app that user is no longer a collaborator of.
|
||||
api.scope
|
||||
.get(
|
||||
/^\/v5\/device\?.+&\$expand=belongs_to__application\(\$select=app_name\)/,
|
||||
/^\/v6\/device\?.+&\$expand=belongs_to__application\(\$select=app_name\)/,
|
||||
)
|
||||
.replyWithFile(
|
||||
200,
|
||||
|
@ -75,7 +75,7 @@ describe('balena devices', function () {
|
||||
it('should list devices from own and collaborator apps', async () => {
|
||||
api.scope
|
||||
.get(
|
||||
'/v5/device?$orderby=device_name%20asc&$expand=belongs_to__application($select=app_name)',
|
||||
'/v6/device?$orderby=device_name%20asc&$expand=belongs_to__application($select=app_name),is_of__device_type($select=slug),is_running__release($select=commit)',
|
||||
)
|
||||
.replyWithFile(200, path.join(apiResponsePath, 'devices.json'), {
|
||||
'Content-Type': 'application/json',
|
||||
|
@ -1,35 +0,0 @@
|
||||
{
|
||||
"d": [
|
||||
{
|
||||
"application_type": [
|
||||
{
|
||||
"name": "Starter",
|
||||
"slug": "microservices-starter",
|
||||
"supports_multicontainer": true,
|
||||
"is_legacy": false,
|
||||
"__metadata": {}
|
||||
}
|
||||
],
|
||||
"id": 1301645,
|
||||
"user": {
|
||||
"__deferred": {
|
||||
"uri": "/resin/user(43699)"
|
||||
},
|
||||
"__id": 43699
|
||||
},
|
||||
"depends_on__application": null,
|
||||
"actor": 3423895,
|
||||
"app_name": "testApp",
|
||||
"slug": "gh_user/testApp",
|
||||
"commit": "96eec431d57e6976d3a756df33fde7e2",
|
||||
"device_type": "raspberrypi3",
|
||||
"should_track_latest_release": true,
|
||||
"is_accessible_by_support_until__date": null,
|
||||
"is_public": false,
|
||||
"is_host": false,
|
||||
"__metadata": {
|
||||
"uri": "/resin/application(@id)?@id=1301645"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
@ -21,8 +21,16 @@
|
||||
"actor": 3423895,
|
||||
"app_name": "testApp",
|
||||
"slug": "gh_user/testApp",
|
||||
"commit": "96eec431d57e6976d3a756df33fde7e2",
|
||||
"device_type": "raspberrypi3",
|
||||
"should_be__running_release": [
|
||||
{
|
||||
"commit": "96eec431d57e6976d3a756df33fde7e2"
|
||||
}
|
||||
],
|
||||
"is_for__device_type": [
|
||||
{
|
||||
"slug": "raspberrypi3"
|
||||
}
|
||||
],
|
||||
"should_track_latest_release": true,
|
||||
"is_accessible_by_support_until__date": null,
|
||||
"is_public": false,
|
||||
|
@ -1,26 +1,25 @@
|
||||
{
|
||||
"d": [
|
||||
{
|
||||
"belongs_to__application": [
|
||||
],
|
||||
"id": 1747415,
|
||||
"is_managed_by__device": null,
|
||||
"device_name": "sparkling-wood",
|
||||
"device_type": "raspberrypi4-64",
|
||||
"uuid": "fda508c8583011b8466c26abdd5159f2",
|
||||
"is_on__commit": "18756d3386c25a044db66b89e0409804",
|
||||
"note": null,
|
||||
"is_online": false,
|
||||
"last_connectivity_event": "2019-11-23T00:26:35.074Z",
|
||||
"ip_address": "192.168.0.112",
|
||||
"mac_address": null,
|
||||
"os_version": "balenaOS 2.44.0+rev3",
|
||||
"supervisor_version": "10.3.7",
|
||||
"is_web_accessible": false,
|
||||
"overall_status": "idle",
|
||||
"__metadata": {
|
||||
"uri": "/resin/device(@id)?@id=1747415"
|
||||
}
|
||||
}
|
||||
]
|
||||
"d": [
|
||||
{
|
||||
"belongs_to__application": [],
|
||||
"id": 1747415,
|
||||
"is_managed_by__device": null,
|
||||
"device_name": "sparkling-wood",
|
||||
"is_of__device_type": [{ "slug": "raspberrypi4-64" }],
|
||||
"uuid": "fda508c8583011b8466c26abdd5159f2",
|
||||
"is_running__release": [{ "commit": "18756d3386c25a044db66b89e0409804" }],
|
||||
"note": null,
|
||||
"is_online": false,
|
||||
"last_connectivity_event": "2019-11-23T00:26:35.074Z",
|
||||
"ip_address": "192.168.0.112",
|
||||
"mac_address": null,
|
||||
"os_version": "balenaOS 2.44.0+rev3",
|
||||
"supervisor_version": "10.3.7",
|
||||
"is_web_accessible": false,
|
||||
"overall_status": "idle",
|
||||
"__metadata": {
|
||||
"uri": "/resin/device(@id)?@id=1747415"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
|
@ -1,30 +1,30 @@
|
||||
{
|
||||
"d": [
|
||||
{
|
||||
"belongs_to__application": [
|
||||
"d": [
|
||||
{
|
||||
"app_name": "test app",
|
||||
"__metadata": {}
|
||||
"belongs_to__application": [
|
||||
{
|
||||
"app_name": "test app",
|
||||
"__metadata": {}
|
||||
}
|
||||
],
|
||||
"id": 1747415,
|
||||
"is_managed_by__device": null,
|
||||
"device_name": "sparkling-wood",
|
||||
"is_of__device_type": [{ "slug": "raspberrypi4-64" }],
|
||||
"uuid": "fda508c8583011b8466c26abdd5159f2",
|
||||
"is_running__release": [{ "commit": "18756d3386c25a044db66b89e0409804" }],
|
||||
"note": null,
|
||||
"is_online": false,
|
||||
"last_connectivity_event": "2019-11-23T00:26:35.074Z",
|
||||
"ip_address": "192.168.0.112",
|
||||
"mac_address": null,
|
||||
"os_version": "balenaOS 2.44.0+rev3",
|
||||
"supervisor_version": "10.3.7",
|
||||
"is_web_accessible": false,
|
||||
"overall_status": "offline",
|
||||
"__metadata": {
|
||||
"uri": "/resin/device(@id)?@id=1747415"
|
||||
}
|
||||
}
|
||||
],
|
||||
"id": 1747415,
|
||||
"is_managed_by__device": null,
|
||||
"device_name": "sparkling-wood",
|
||||
"device_type": "raspberrypi4-64",
|
||||
"uuid": "fda508c8583011b8466c26abdd5159f2",
|
||||
"is_on__commit": "18756d3386c25a044db66b89e0409804",
|
||||
"note": null,
|
||||
"is_online": false,
|
||||
"last_connectivity_event": "2019-11-23T00:26:35.074Z",
|
||||
"ip_address": "192.168.0.112",
|
||||
"mac_address": null,
|
||||
"os_version": "balenaOS 2.44.0+rev3",
|
||||
"supervisor_version": "10.3.7",
|
||||
"is_web_accessible": false,
|
||||
"overall_status": "offline",
|
||||
"__metadata": {
|
||||
"uri": "/resin/device(@id)?@id=1747415"
|
||||
}
|
||||
}
|
||||
]
|
||||
]
|
||||
}
|
||||
|
@ -16,11 +16,14 @@
|
||||
},
|
||||
"is_managed_by__device": null,
|
||||
"actor": 4180757,
|
||||
"should_be_running__release": null,
|
||||
"device_name": "sparkling-wood",
|
||||
"device_type": "raspberrypi4-64",
|
||||
"is_of__device_type": [{ "slug": "raspberrypi4-64" }],
|
||||
"uuid": "fda508c8583011b8466c26abdd5159f2",
|
||||
"is_on__commit": "18756d3386c25a044db66b89e0409804",
|
||||
"is_running__release": [
|
||||
{
|
||||
"commit": "18756d3386c25a044db66b89e0409804"
|
||||
}
|
||||
],
|
||||
"note": null,
|
||||
"local_id": null,
|
||||
"status": "Idle",
|
||||
@ -61,8 +64,7 @@
|
||||
}
|
||||
},
|
||||
{
|
||||
"belongs_to__application": [
|
||||
],
|
||||
"belongs_to__application": [],
|
||||
"id": 1747416,
|
||||
"belongs_to__user": {
|
||||
"__deferred": {
|
||||
@ -72,11 +74,14 @@
|
||||
},
|
||||
"is_managed_by__device": null,
|
||||
"actor": 4180757,
|
||||
"should_be_running__release": null,
|
||||
"device_name": "dashing-spruce",
|
||||
"device_type": "raspberrypi4-64",
|
||||
"is_of__device_type": [{ "slug": "raspberrypi4-64" }],
|
||||
"uuid": "fda508c8583011b8466c26abdd5159f3",
|
||||
"is_on__commit": "18756d3386c25a044db66b89e0409804",
|
||||
"is_running__release": [
|
||||
{
|
||||
"commit": "18756d3386c25a044db66b89e0409804"
|
||||
}
|
||||
],
|
||||
"note": null,
|
||||
"local_id": null,
|
||||
"status": "Idle",
|
||||
|
12
typings/balena-device-init/index.d.ts
vendored
12
typings/balena-device-init/index.d.ts
vendored
@ -16,7 +16,7 @@
|
||||
*/
|
||||
|
||||
declare module 'balena-device-init' {
|
||||
import { DeviceType } from 'balena-sdk';
|
||||
import { DeviceTypeJson } from 'balena-sdk';
|
||||
import * as Bluebird from 'bluebird';
|
||||
import { EventEmitter } from 'events';
|
||||
|
||||
@ -81,21 +81,23 @@ declare module 'balena-device-init' {
|
||||
|
||||
export function configure(
|
||||
image: string,
|
||||
manifest: DeviceType,
|
||||
manifest: BalenaSdk.DeviceTypeJson.DeviceType.DeviceType,
|
||||
config: {},
|
||||
options?: {},
|
||||
): Bluebird<InitializeEmitter>;
|
||||
|
||||
export function initialize(
|
||||
image: string,
|
||||
manifest: DeviceType,
|
||||
manifest: BalenaSdk.DeviceTypeJson.DeviceType.DeviceType,
|
||||
config: {},
|
||||
): Bluebird<InitializeEmitter>;
|
||||
|
||||
export function getImageOsVersion(
|
||||
image: string,
|
||||
manifest: DeviceType,
|
||||
manifest: BalenaSdk.DeviceTypeJson.DeviceType.DeviceType,
|
||||
): Bluebird<string | null>;
|
||||
|
||||
export function getImageManifest(image: string): Bluebird<DeviceType | null>;
|
||||
export function getImageManifest(
|
||||
image: string,
|
||||
): Bluebird<BalenaSdk.DeviceTypeJson.DeviceType.DeviceType | null>;
|
||||
}
|
||||
|
10
typings/global.d.ts
vendored
Normal file
10
typings/global.d.ts
vendored
Normal file
@ -0,0 +1,10 @@
|
||||
import { Application, DeviceType, Device } from 'balena-sdk';
|
||||
|
||||
declare global {
|
||||
type ApplicationWithDeviceType = Application & {
|
||||
is_for__device_type: [DeviceType];
|
||||
};
|
||||
type DeviceWithDeviceType = Device & {
|
||||
is_of__device_type: [DeviceType];
|
||||
};
|
||||
}
|
Loading…
Reference in New Issue
Block a user