Skip to content

Commit 666e451

Browse files
Merge pull request #2432 from balena-os/host-os-release-feature-label
Support io.balena.features.host-os.board-rev feature label
2 parents 616f6d5 + a813e24 commit 666e451

File tree

4 files changed

+73
-15
lines changed

4 files changed

+73
-15
lines changed

src/compose/utils.ts

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,8 +19,8 @@ import type {
1919
} from './types';
2020

2121
import log from '../lib/supervisor-console';
22-
2322
import * as apiKeys from '../lib/api-keys';
23+
import { getOSBoardRev } from '../lib/os-release';
2424

2525
export function camelCaseConfig(
2626
literalConfig: ConfigMap,
@@ -404,6 +404,12 @@ export async function addFeaturesFromLabels(
404404
Capabilities: [['gpu']],
405405
Options: {},
406406
} as Dockerode.DeviceRequest),
407+
'io.balena.features.host-os.board-rev': async () => {
408+
const osBoardRev = await getOSBoardRev(constants.hostOSVersionPath);
409+
if (osBoardRev) {
410+
setEnvVariables('HOST_OS_BOARD_REV', osBoardRev);
411+
}
412+
},
407413
};
408414

409415
for (const feature of Object.keys(features) as [keyof typeof features]) {

src/lib/os-release.ts

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
1-
import _ from 'lodash';
1+
import memoizee from 'memoizee';
22
import { promises as fs } from 'fs';
33

44
import { InternalInconsistencyError } from './errors';
55
import { exec } from './fs-utils';
66
import log from './supervisor-console';
77

88
// Retrieve the data for the OS once only per path
9-
const getOSReleaseData = _.memoize(
9+
const getOSReleaseData = memoizee(
1010
async (path: string): Promise<Dictionary<string>> => {
1111
const releaseItems: Dictionary<string> = {};
1212
try {
@@ -17,8 +17,11 @@ const getOSReleaseData = _.memoize(
1717
const [key, ...values] = line.split('=');
1818

1919
// Remove enclosing quotes: http://stackoverflow.com/a/19156197/2549019
20-
const value = _.trim(values.join('=')).replace(/^"(.+(?="$))"$/, '$1');
21-
releaseItems[_.trim(key)] = value;
20+
const value = values
21+
.join('=')
22+
.trim()
23+
.replace(/^"(.+(?="$))"$/, '$1');
24+
releaseItems[key.trim()] = value;
2225
}
2326
} catch (e: any) {
2427
throw new InternalInconsistencyError(
@@ -28,6 +31,7 @@ const getOSReleaseData = _.memoize(
2831

2932
return releaseItems;
3033
},
34+
{ promise: true },
3135
);
3236

3337
async function getOSReleaseField(
@@ -68,6 +72,10 @@ export function getOSSemver(path: string): Promise<string | undefined> {
6872
return getOSReleaseField(path, 'VERSION');
6973
}
7074

75+
export function getOSBoardRev(path: string): Promise<string | undefined> {
76+
return getOSReleaseField(path, 'BALENA_BOARD_REV');
77+
}
78+
7179
export async function getMetaOSRelease(
7280
path: string,
7381
): Promise<string | undefined> {

test/data/etc/os-release

Lines changed: 9 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,11 @@
11
ID="balena-os"
22
NAME="balenaOS"
3-
VERSION="2.0.6"
4-
VERSION_ID="2.0.6+rev1"
5-
PRETTY_NAME="balenaOS 2.0.6+rev1"
6-
MACHINE="raspberrypi4-64"
7-
VARIANT="Development"
8-
VARIANT_ID="dev"
9-
META_BALENA_VERSION="2.0.6"
10-
RESIN_BOARD_REV="b57b01a"
11-
META_RESIN_REV="ef55525"
12-
SLUG="raspberrypi4-64"
3+
VERSION="6.5.44+rev2"
4+
VERSION_ID="6.5.44+rev2"
5+
PRETTY_NAME="balenaOS 6.5.44+rev2"
6+
DISTRO_CODENAME="kirkstone"
7+
MACHINE="raspberrypi3-64"
8+
META_BALENA_VERSION="6.5.44"
9+
BALENA_BOARD_REV="a21c12f4"
10+
META_BALENA_REV="4e67673a"
11+
SLUG="raspberrypi3-64"

test/integration/compose/service.spec.ts

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,5 +64,50 @@ describe('compose/service: integration tests', () => {
6464
).to.be.equal(mykey);
6565
});
6666
});
67+
68+
describe('io.balena.features.host-os.board-rev', () => {
69+
it('should set BALENA_HOST_OS_BOARD_REV environment variable when the feature is enabled', async () => {
70+
const s = await Service.fromComposeObject(
71+
{
72+
appId: 123,
73+
serviceId: 123,
74+
serviceName: 'test',
75+
labels: {
76+
'io.balena.features.host-os.board-rev': '1',
77+
},
78+
},
79+
{ appName: 'test' } as any,
80+
);
81+
82+
expect(s.config.environment).to.have.property(
83+
'BALENA_HOST_OS_BOARD_REV',
84+
);
85+
expect(s.config.environment).to.have.property(
86+
'RESIN_HOST_OS_BOARD_REV',
87+
);
88+
expect(s.config.environment['BALENA_HOST_OS_BOARD_REV']).to.equal(
89+
'a21c12f4',
90+
);
91+
});
92+
93+
it('should not set BALENA_HOST_OS_BOARD_REV when the feature is not enabled', async () => {
94+
const s = await Service.fromComposeObject(
95+
{
96+
appId: 123,
97+
serviceId: 123,
98+
serviceName: 'test',
99+
labels: {},
100+
},
101+
{ appName: 'test' } as any,
102+
);
103+
104+
expect(s.config.environment).to.not.have.property(
105+
'BALENA_HOST_OS_BOARD_REV',
106+
);
107+
expect(s.config.environment).to.not.have.property(
108+
'RESIN_HOST_OS_BOARD_REV',
109+
);
110+
});
111+
});
67112
});
68113
});

0 commit comments

Comments
 (0)