Skip to content

Commit a20e9ab

Browse files
committed
Stop filling service install on device service environment variable
Change-type: patch
1 parent b2059b8 commit a20e9ab

File tree

6 files changed

+126
-97
lines changed

6 files changed

+126
-97
lines changed

src/features/service-install/hooks/backfill-device-service-environment-variable.ts

-35
This file was deleted.
+1-1
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
import './backfill-device-service-environment-variable.js';
1+
import './nullify-si-on-device-service-environment-variable.js';
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
import { hooks, type sbvrUtils } from '@balena/pinejs';
2+
3+
// TODO: Drop this once `device_service_environment_variable.service_install` gets removed from the sbvr
4+
function backfillDeviceAndService({ request }: sbvrUtils.HookArgs<'resin'>) {
5+
delete request.values.service_install;
6+
}
7+
8+
hooks.addPureHook('POST', 'resin', 'device_service_environment_variable', {
9+
POSTPARSE: backfillDeviceAndService,
10+
});
11+
12+
hooks.addPureHook('PATCH', 'resin', 'device_service_environment_variable', {
13+
POSTPARSE: backfillDeviceAndService,
14+
});

src/translations/v7/hooks.ts

+46
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,52 @@
11
import { addDeleteHookForDependents } from '../../infra/cascade-delete/index.js';
2+
import { hooks, sbvrUtils, errors } from '@balena/pinejs';
3+
4+
const addReadOnlyHook = (
5+
methods: Array<Parameters<typeof hooks.addHook>[0]>,
6+
resource: string,
7+
hook: sbvrUtils.Hooks<'v7'>,
8+
) => {
9+
methods.map((method) => {
10+
hooks.addHook(method, 'v7', resource, {
11+
...hook,
12+
sideEffects: false,
13+
readOnlyTx: true,
14+
});
15+
});
16+
};
217

318
// Service install resource should only be used for <= v7 translations
419
addDeleteHookForDependents('v7', 'service_install', {
520
device_service_environment_variable: 'service_install',
621
});
22+
23+
addReadOnlyHook(
24+
['POST', 'PATCH', 'PUT'],
25+
'device_service_environment_variable',
26+
{
27+
POSTPARSE: async ({ request, api }) => {
28+
const { service_install: siId } = request.values;
29+
30+
if (siId == null) {
31+
return;
32+
}
33+
34+
const si = await sbvrUtils.api.resin.get({
35+
resource: 'service_install',
36+
passthrough: api.passthrough,
37+
id: siId,
38+
options: {
39+
$select: ['device', 'service'],
40+
},
41+
});
42+
43+
if (si == null) {
44+
throw new errors.UnauthorizedError();
45+
}
46+
47+
request.values.device = si.device.__id;
48+
request.values.service = si.service.__id;
49+
delete request.values.service_install;
50+
},
51+
},
52+
);

test/25_service-installs.ts

+60-56
Original file line numberDiff line numberDiff line change
@@ -317,7 +317,9 @@ export default () => {
317317
.post({
318318
resource: 'device_service_environment_variable',
319319
body: {
320-
service_install: serviceInstall.id,
320+
...(versions.lte(version, 'v7')
321+
? { service_install: serviceInstall.id }
322+
: { device: ctx.device.id, service: ctx.app2Service1.id }),
321323
name: 'test',
322324
value: '123',
323325
},
@@ -341,68 +343,70 @@ export default () => {
341343
);
342344
});
343345

344-
it('should be able to update device_service_environment_variable service_install', async () => {
345-
const { body: serviceInstallService1 } = await pineUser
346-
.get({
347-
resource: 'service_install',
348-
id: {
349-
device: ctx.device.id,
350-
installs__service: ctx.app2Service1.id,
351-
},
352-
})
353-
.expect(200);
354-
assertExists(serviceInstallService1);
346+
if (versions.lte(version, 'v7')) {
347+
it('should be able to update device_service_environment_variable service_install', async () => {
348+
const { body: serviceInstallService1 } = await pineUser
349+
.get({
350+
resource: 'service_install',
351+
id: {
352+
device: ctx.device.id,
353+
installs__service: ctx.app2Service1.id,
354+
},
355+
})
356+
.expect(200);
357+
assertExists(serviceInstallService1);
355358

356-
const { body: serviceInstallService2 } = await pineUser
357-
.get({
358-
resource: 'service_install',
359-
id: {
360-
device: ctx.device.id,
361-
installs__service: ctx.app2Service2.id,
362-
},
363-
})
364-
.expect(200);
365-
assertExists(serviceInstallService2);
359+
const { body: serviceInstallService2 } = await pineUser
360+
.get({
361+
resource: 'service_install',
362+
id: {
363+
device: ctx.device.id,
364+
installs__service: ctx.app2Service2.id,
365+
},
366+
})
367+
.expect(200);
368+
assertExists(serviceInstallService2);
366369

367-
const {
368-
body: [deviceServiceEnvVar],
369-
} = await pineUser
370-
.get({
371-
resource: 'device_service_environment_variable',
372-
options: {
373-
$filter: {
374-
service_install: serviceInstallService1.id,
370+
const {
371+
body: [deviceServiceEnvVar],
372+
} = await pineUser
373+
.get({
374+
resource: 'device_service_environment_variable',
375+
options: {
376+
$filter: {
377+
service_install: serviceInstallService1.id,
378+
},
375379
},
376-
},
377-
})
378-
.expect(200);
379-
assertExists(deviceServiceEnvVar);
380+
})
381+
.expect(200);
382+
assertExists(deviceServiceEnvVar);
383+
384+
await pineUser
385+
.patch({
386+
resource: 'device_service_environment_variable',
387+
id: deviceServiceEnvVar.id,
388+
body: {
389+
service_install: serviceInstallService2.id,
390+
},
391+
})
392+
.expect(200);
380393

381-
await pineUser
382-
.patch({
383-
resource: 'device_service_environment_variable',
384-
id: deviceServiceEnvVar.id,
394+
const {
385395
body: {
386-
service_install: serviceInstallService2.id,
396+
d: [dbDeviceServiceEnvVar],
387397
},
388-
})
389-
.expect(200);
390-
391-
const {
392-
body: {
393-
d: [dbDeviceServiceEnvVar],
394-
},
395-
} = await supertest(ctx.admin)
396-
.get(
397-
`/resin/device_service_environment_variable(${deviceServiceEnvVar.id})?$select=device,service`,
398-
)
399-
.expect(200);
398+
} = await supertest(ctx.admin)
399+
.get(
400+
`/resin/device_service_environment_variable(${deviceServiceEnvVar.id})?$select=device,service`,
401+
)
402+
.expect(200);
400403

401-
expect(dbDeviceServiceEnvVar.device.__id).to.equal(ctx.device.id);
402-
expect(dbDeviceServiceEnvVar.service.__id).to.equal(
403-
ctx.app2Service2.id,
404-
);
405-
});
404+
expect(dbDeviceServiceEnvVar.device.__id).to.equal(ctx.device.id);
405+
expect(dbDeviceServiceEnvVar.service.__id).to.equal(
406+
ctx.app2Service2.id,
407+
);
408+
});
409+
}
406410
});
407411
});
408412
});

test/test-lib/fixtures.ts

+5-5
Original file line numberDiff line numberDiff line change
@@ -508,23 +508,23 @@ const loaders: types.Dictionary<LoaderFunc> = {
508508
logErrorAndThrow(`Could not find service: ${jsonData.service}`);
509509
}
510510

511-
const si = await expectToEventually(async () => {
512-
const $si = await api.resin.get({
511+
await expectToEventually(async () => {
512+
const si = await api.resin.get({
513513
resource: 'service_install',
514514
passthrough: { req: permissions.rootRead },
515515
id: {
516516
device: device.id,
517517
installs__service: service.id,
518518
},
519519
});
520-
assertExists($si);
521-
return $si;
520+
assertExists(si);
522521
});
523522

524523
return await createResource({
525524
resource: 'device_service_environment_variable',
526525
body: {
527-
service_install: si.id,
526+
device: device.id,
527+
service: service.id,
528528
name: jsonData.name,
529529
value: jsonData.value,
530530
},

0 commit comments

Comments
 (0)