Skip to content

Commit

Permalink
Merge pull request #5 from dfpc-coe/config-cron
Browse files Browse the repository at this point in the history
Config Cron
  • Loading branch information
ingalls authored Nov 1, 2024
2 parents 19903ea + b30530c commit 1254d07
Show file tree
Hide file tree
Showing 8 changed files with 2,720 additions and 1,408 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,10 @@

### Pending Release

### v2.11.0

- :rocket: Add persistance script

### v2.10.0

- :rocket: Add KMS Key Alias
Expand Down
14 changes: 10 additions & 4 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -1,11 +1,17 @@
FROM bluenviron/mediamtx:1.9.0-ffmpeg

ENV MEDIA_VERSION=1.9.1
ENV MEDIA_VERSION=1.9.3

RUN apk add bash vim yq
RUN apk add bash vim yq nodejs npm

COPY mediamtx.yml /mediamtx.base.yml
ADD mediamtx.yml /mediamtx.base.yml
ADD start /

COPY start /
ADD package.json /
ADD package-lock.json /

RUN npm install

ADD persist.ts /

ENTRYPOINT [ "/start" ]
23 changes: 23 additions & 0 deletions cloudformation/lib/api.js
Original file line number Diff line number Diff line change
Expand Up @@ -158,6 +158,7 @@ const Resources = {
Environment: [
{ Name: 'StackName', Value: cf.stackName },
{ Name: 'MANAGEMENT_PASSWORD', Value: cf.sub('{{resolve:secretsmanager:${AWS::StackName}/api/secret:SecretString::AWSCURRENT}}') },
{ Name: 'FORCE_NEW_CONFIG', Value: cf.ref('ForceNewConfig') },
{ Name: 'AWS_DEFAULT_REGION', Value: cf.region }
],
LogConfiguration: {
Expand Down Expand Up @@ -268,6 +269,15 @@ const Resources = {
PolicyName: cf.join('-', [cf.stackName, 'api-policy']),
PolicyDocument: {
Statement: [{
Effect: 'Allow',
Action: [
'ssmmessages:CreateControlChannel',
'ssmmessages:CreateDataChannel',
'ssmmessages:OpenControlChannel',
'ssmmessages:OpenDataChannel'
],
Resource: '*'
},{
Effect: 'Allow',
Action: [
'logs:CreateLogGroup',
Expand All @@ -289,6 +299,7 @@ const Resources = {
TaskDefinition: cf.ref('ServiceTaskDefinition'),
LaunchType: 'FARGATE',
PropagateTags: 'SERVICE',
EnableExecuteCommand: cf.ref('EnableExecute'),
DesiredCount: 1,
NetworkConfiguration: {
AwsvpcConfiguration: {
Expand Down Expand Up @@ -368,6 +379,18 @@ for (const p of PORTS) {

export default cf.merge({
Parameters: {
EnableExecute: {
Description: 'Allow SSH into docker container - should only be enabled for limited debugging',
Type: 'String',
AllowedValues: ['true', 'false'],
Default: 'false'
},
ForceNewConfig: {
Description: 'Force a blank config file - permanently deleting current config',
Type: 'String',
AllowedValues: ['true', 'false'],
Default: 'false'
},
SSLCertificateIdentifier: {
Description: 'ACM SSL Certificate for HTTP Protocol',
Type: 'String'
Expand Down
3 changes: 3 additions & 0 deletions eslint.config.js
Original file line number Diff line number Diff line change
@@ -1,11 +1,14 @@
import js from "@eslint/js";
import nodePlugin from "eslint-plugin-n";
import tseslint from 'typescript-eslint';

export default [
js.configs.recommended,
nodePlugin.configs["flat/recommended-module"],
...tseslint.configs.recommended,
{
"rules": {
"@typescript-eslint/no-explicit-any": "warn",
"no-console": 0,
"arrow-parens": [ "error", "always" ],
"no-var": "error",
Expand Down
3,969 changes: 2,570 additions & 1,399 deletions package-lock.json

Large diffs are not rendered by default.

16 changes: 11 additions & 5 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,15 @@
"name": "@tak-ps/media-infra",
"type": "module",
"private": true,
"version": "2.10.0",
"version": "2.11.0",
"description": "Infrastructure to support LDAP based auth in TAK",
"scripts": {
"lint": "eslint cloudformation/*.js cloudformation/lib/*.js",
"check": "tsx persist.ts",
"lint": "eslint persist.ts cloudformation/",
"test": "echo \"Error: no test specified\" && exit 1"
},
"engines": {
"node": ">= 18"
"node": ">= 22"
},
"repository": {
"type": "git",
Expand All @@ -24,10 +25,15 @@
"dependencies": {
"@openaddresses/batch-alarms": "^4.0.0",
"@openaddresses/cloudfriend": "^7.0.0",
"@openaddresses/deploy": "^8.0.0"
"@openaddresses/deploy": "^9.1.0",
"node-cron": "^3.0.3",
"tsx": "^4.19.2",
"yaml": "^2.6.0"
},
"devDependencies": {
"eslint": "^9.9.0",
"eslint-plugin-n": "^17.10.2"
"eslint-plugin-n": "^17.10.2",
"typescript": "^5.6.3",
"typescript-eslint": "^8.12.2"
}
}
93 changes: 93 additions & 0 deletions persist.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
import fs from 'node:fs/promises';
import cron from 'node-cron';
import YAML from 'yaml';

cron.schedule('0,10,20,30,40,50 * * * * *', async () => {
try {
const base = await globalConfig();
const paths = (await globalPaths()).map((path) => {
return {
name: path.name,
source: path.source,
sourceOnDemand: path.sourceOnDemand
};
});

base.paths = {};

for (const path of paths) {
base.paths[path.name] = path;
}

console.error('PATHS', JSON.stringify(base.paths));

let config = YAML.stringify(base, (key, value) => {
if (typeof value === 'boolean') {
return value === true ? 'yes' : 'no';
} else {
return value;
}
});

// This is janky but MediaMTX wants `no` as a string and not a boolean
// and I can't get the YAML library to respect that...
config = config.split('\n').map((line) => {
line = line.replace(/^encryption: no/, 'encryption: "no"');
line = line.replace(/^rtmpEncryption: no/, 'rtmpEncryption: "no"');
return line;
}).join('\n');

await fs.writeFile('/opt/mediamtx/mediamtx.yml.new', config);

// Ref: https://github.com/bluenviron/mediamtx/issues/937
await fs.rename(
'/opt/mediamtx/mediamtx.yml.new',
'/opt/mediamtx/mediamtx.yml'
);
} catch (err) {
console.error(err);
}
});

async function globalPaths(): any {

Check warning on line 52 in persist.ts

View workflow job for this annotation

GitHub Actions / test

Unexpected any. Specify a different type
let total = 0;
let page = -1;

const paths = [];

do {
++page;

const url = new URL('http://localhost:9997/v3/config/paths/list');
url.searchParams.append('itemsPerPage', '1000');
url.searchParams.append('page', String(page));

const res = await fetch(url, {
method: 'GET',
headers: {
Authorization: `Basic ${Buffer.from('management:' + process.env.MANAGEMENT_PASSWORD).toString('base64')}`
}
});

const body = await res.json();

total = body.itemCount;

paths.push(...body.items);
} while (total > page * 1000);

return paths;
}

async function globalConfig(): any {

Check warning on line 82 in persist.ts

View workflow job for this annotation

GitHub Actions / test

Unexpected any. Specify a different type
const res = await fetch('http://localhost:9997/v3/config/global/get', {
method: 'GET',
headers: {
Authorization: `Basic ${Buffer.from('management:' + process.env.MANAGEMENT_PASSWORD).toString('base64')}`
}
});

const body = await res.json();

return body;
}
6 changes: 6 additions & 0 deletions start
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,10 @@ set -euo pipefail
echo "Contents:"
ls /opt/mediamtx/

if [[ ${FORCE_NEW_CONFIG} == "true" ]]; then
rm /opt/mediamtx/mediamtx.yml || true
fi

# Copy EFS Persisted certs to Let's Encrypt Dir
if [ ! -f "/opt/mediamtx/mediamtx.yml" ]; then
echo "NO CONFIG FOUND"
Expand All @@ -19,4 +23,6 @@ yq e -i ".authInternalUsers[0].pass = \"$MANAGEMENT_PASSWORD\"" "/opt/mediamtx/m

rm /mediamtx.yml

npx tsx persist.ts &

/mediamtx /opt/mediamtx/mediamtx.yml

0 comments on commit 1254d07

Please sign in to comment.