avahi: Control with HOST_DISCOVERABILITY

The host config variable HOST_DISCOVERABILITY can be set to
true or false, controlling the state of the avahi service. This
determines if the device advertises it's presence over mDNS.

Change-type: patch
Signed-off-by: Cameron Diver <cameron@balena.io>
Signed-off-by: Rich Bayliss <rich@balena.io>
This commit is contained in:
Cameron Diver 2020-07-06 11:13:45 +01:00 committed by Rich Bayliss
parent 75c2e6c81e
commit 03ca0ee9ad
No known key found for this signature in database
GPG Key ID: E53C4B4D18499E1A
8 changed files with 74 additions and 7 deletions

View File

@ -170,6 +170,10 @@ export const schemaTypes = {
type: t.string,
default: NullOrUndefined,
},
hostDiscoverability: {
type: PermissiveBoolean,
default: true,
},
// Function schema types
// The type should be the value that the promise resolves

View File

@ -190,6 +190,11 @@ export const schema = {
mutable: true,
removeIfNull: false,
},
hostDiscoverability: {
source: 'db',
mutable: true,
removeIfNull: false,
},
};
export type Schema = typeof schema;

View File

@ -127,6 +127,11 @@ export class DeviceConfig {
varType: 'string',
defaultValue: 'off',
},
hostDiscoverability: {
envVarName: 'HOST_DISCOVERABILITY',
varType: 'bool',
defaultValue: 'true',
},
};
public static validKeys = [

32
src/lib/avahi.ts Normal file
View File

@ -0,0 +1,32 @@
import * as config from '../config';
import * as dbus from './dbus';
import log from './supervisor-console';
export const initialized = (async () => {
await config.initialized;
config.on('change', (conf) => {
if (conf.hostDiscoverability != null) {
switchDiscoverability(conf.hostDiscoverability);
}
});
await switchDiscoverability(await config.get('hostDiscoverability'));
})();
async function switchDiscoverability(discoverable: boolean) {
try {
if (discoverable) {
log.info('Setting host to discoverable');
await dbus.startService('avahi-daemon');
await dbus.startSocket('avahi-daemon');
} else {
log.info('Setting host to undiscoverable');
await dbus.stopService('avahi-daemon');
await dbus.stopSocket('avahi-daemon');
}
} catch (e) {
log.error('There was an error switching host discoverability:', e);
}
}

View File

@ -35,6 +35,15 @@ export async function getLoginManagerInterface() {
}
}
async function startUnit(unitName: string) {
const systemd = await getSystemdInterface();
try {
systemd.StartUnit(unitName, 'fail');
} catch (e) {
throw new DbusError(e);
}
}
export async function restartService(serviceName: string) {
const systemd = await getSystemdInterface();
try {
@ -45,21 +54,28 @@ export async function restartService(serviceName: string) {
}
export async function startService(serviceName: string) {
return startUnit(`${serviceName}.service`);
}
export async function startSocket(socketName: string) {
return startUnit(`${socketName}.socket`);
}
async function stopUnit(unitName: string) {
const systemd = await getSystemdInterface();
try {
systemd.StartUnit(`${serviceName}.service`, 'fail');
systemd.StopUnit(unitName, 'fail');
} catch (e) {
throw new DbusError(e);
}
}
export async function stopService(serviceName: string) {
const systemd = await getSystemdInterface();
try {
systemd.StopUnit(`${serviceName}.service`, 'fail');
} catch (e) {
throw new DbusError(e);
}
return stopUnit(`${serviceName}.service`);
}
export async function stopSocket(socketName: string) {
return stopUnit(`${socketName}.socket`);
}
export async function enableService(serviceName: string) {

View File

@ -12,6 +12,7 @@ import SupervisorAPI from './supervisor-api';
import log from './lib/supervisor-console';
import version = require('./lib/supervisor-version');
import * as avahi from './lib/avahi';
import * as firewall from './lib/firewall';
const startupConfigFields: config.ConfigKey[] = [
@ -61,6 +62,7 @@ export class Supervisor {
await db.initialized;
await config.initialized;
await eventTracker.initialized;
await avahi.initialized;
log.debug('Starting logging infrastructure');
await logger.initialized;

View File

@ -42,6 +42,7 @@ const testTarget1 = {
config: {
HOST_CONFIG_gpu_mem: '256',
HOST_FIREWALL_MODE: 'off',
HOST_DISCOVERABILITY: 'true',
SUPERVISOR_CONNECTIVITY_CHECK: 'true',
SUPERVISOR_DELTA: 'false',
SUPERVISOR_DELTA_APPLY_TIMEOUT: '0',
@ -129,6 +130,7 @@ const testTargetWithDefaults2 = {
config: {
HOST_CONFIG_gpu_mem: '512',
HOST_FIREWALL_MODE: 'off',
HOST_DISCOVERABILITY: 'true',
SUPERVISOR_CONNECTIVITY_CHECK: 'true',
SUPERVISOR_DELTA: 'false',
SUPERVISOR_DELTA_APPLY_TIMEOUT: '0',

View File

@ -192,6 +192,7 @@ describe('Device Backend Config', () => {
const conf = deviceConfig.getDefaults();
return expect(conf).to.deep.equal({
HOST_FIREWALL_MODE: 'off',
HOST_DISCOVERABILITY: 'true',
SUPERVISOR_VPN_CONTROL: 'true',
SUPERVISOR_POLL_INTERVAL: '60000',
SUPERVISOR_LOCAL_MODE: 'false',