diff --git a/src/lib/contracts.ts b/src/lib/contracts.ts index 7216a404..a2c58e14 100644 --- a/src/lib/contracts.ts +++ b/src/lib/contracts.ts @@ -25,7 +25,8 @@ export interface ServiceContracts { type PotentialContractRequirements = | 'sw.supervisor' | 'sw.l4t' - | 'hw.device-type'; + | 'hw.device-type' + | 'arch.sw'; type ContractRequirements = { [key in PotentialContractRequirements]?: string; }; @@ -35,11 +36,13 @@ const contractRequirementVersions: ContractRequirements = {}; export function initializeContractRequirements(opts: { supervisorVersion: string; deviceType: string; + deviceArch: string; l4tVersion?: string; }) { contractRequirementVersions['sw.supervisor'] = opts.supervisorVersion; contractRequirementVersions['sw.l4t'] = opts.l4tVersion; contractRequirementVersions['hw.device-type'] = opts.deviceType; + contractRequirementVersions['arch.sw'] = opts.deviceArch; } function isValidRequirementType( @@ -162,11 +165,10 @@ const contractObjectValidator = t.type({ function getContractsFromVersions(components: ContractRequirements) { return _.map(components, (value, component) => { - if (component === 'hw.device-type') { + if (component === 'hw.device-type' || component === 'arch.sw') { return { type: component, slug: value, - name: value, }; } else { diff --git a/src/supervisor.ts b/src/supervisor.ts index bdd03168..03d5becf 100644 --- a/src/supervisor.ts +++ b/src/supervisor.ts @@ -45,6 +45,7 @@ export class Supervisor { initializeContractRequirements({ supervisorVersion: version, deviceType: await config.get('deviceType'), + deviceArch: await config.get('deviceArch'), l4tVersion: await osRelease.getL4tVersion(), }); diff --git a/test/integration/device-state.spec.ts b/test/integration/device-state.spec.ts index e698c9ec..29f24bb6 100644 --- a/test/integration/device-state.spec.ts +++ b/test/integration/device-state.spec.ts @@ -25,6 +25,7 @@ describe('device-state', () => { initializeContractRequirements({ supervisorVersion: '11.0.0', deviceType: 'intel-nuc', + deviceArch: 'amd64', }); }); @@ -406,8 +407,8 @@ describe('device-state', () => { name: 'Enforce supervisor version', requires: [ { - type: 'sw.supervisor', - version: '>=12.0.0', + type: 'arch.sw', + version: 'armv7hf', }, ], }, diff --git a/test/unit/lib/contracts.spec.ts b/test/unit/lib/contracts.spec.ts index 7b9b723f..d18c489f 100644 --- a/test/unit/lib/contracts.spec.ts +++ b/test/unit/lib/contracts.spec.ts @@ -13,6 +13,7 @@ describe('lib/contracts', () => { contracts.initializeContractRequirements({ supervisorVersion, deviceType: 'intel-nuc', + deviceArch: 'amd64', l4tVersion: '32.2', }); }); @@ -55,6 +56,7 @@ describe('lib/contracts', () => { type: 'sw.supervisor', }, { type: 'hw.device-type', slug: 'raspberrypi3' }, + { type: 'arch.sw', slug: 'aarch64' }, ], }), ).to.not.throw()); @@ -167,7 +169,8 @@ describe('lib/contracts', () => { type: 'sw.supervisor', version: `<${supervisorVersionGreater}`, }, - { type: 'hw.device-type', name: 'intel-nuc' }, + { type: 'sw.arch', name: 'amd64' }, + { type: 'hw.device-type', slug: 'intel-nuc' }, ], }, optional: false, @@ -189,6 +192,7 @@ describe('lib/contracts', () => { type: 'sw.supervisor', version: `>${supervisorVersionLesser}`, }, + { type: 'sw.arch', slug: 'amd64' }, ], }, optional: false, @@ -305,6 +309,27 @@ describe('lib/contracts', () => { .to.have.property('unmetServices') .that.deep.equals(['service']); + fulfilled = contracts.containerContractsFulfilled({ + service: { + contract: { + type: 'sw.container', + name: 'user-container', + slug: 'user-container', + requires: [ + { + type: 'arch.sw', + slug: 'armv7hf', + }, + ], + }, + optional: false, + }, + }); + expect(fulfilled).to.have.property('valid').that.equals(false); + expect(fulfilled) + .to.have.property('unmetServices') + .that.deep.equals(['service']); + fulfilled = contracts.containerContractsFulfilled({ service: { contract: { @@ -442,9 +467,26 @@ describe('lib/contracts', () => { }, optional: true, }, + service4: { + contract: { + type: 'sw.container', + slug: 'service3', + requires: [ + { + type: 'arch.sw', + slug: 'armv7hf', + }, + ], + }, + optional: true, + }, }); expect(valid).to.equal(true); - expect(unmetServices).to.deep.equal(['service1', 'service3']); + expect(unmetServices).to.deep.equal([ + 'service1', + 'service3', + 'service4', + ]); expect(fulfilledServices).to.deep.equal(['service2']); }); }); @@ -494,6 +536,7 @@ describe('lib/contracts', () => { engine.initializeContractRequirements({ supervisorVersion, deviceType: 'intel-nuc', + deviceArch: 'amd64', l4tVersion: await osRelease.getL4tVersion(), });