1
0
Fork 0
mirror of https://github.com/pawelmalak/flame.git synced 2025-08-06 03:15:18 +02:00

Use Promise.allSettled instead of Promise.all

This allows for any hosts that are able to be resolved to still function correctly while any that don't will throw an error
This commit is contained in:
Aaron Williams 2022-03-01 13:38:29 +10:00
parent f4c4ba98be
commit 21d651b897

View file

@ -4,135 +4,145 @@ const Logger = require('../../../utils/Logger');
const logger = new Logger(); const logger = new Logger();
const loadConfig = require('../../../utils/loadConfig'); const loadConfig = require('../../../utils/loadConfig');
async function getContainer ({ host }) {
const isLocalhost = host.includes('localhost');
try {
return await axios.get(
`http://${host}/containers/json?{"status":["running"]}`,
isLocalhost ? {
socketPath: '/var/run/docker.sock',
} : {}
)
} catch {
const error = `Can't connect to the Docker API on the host ${host}`;
logger.log(error, 'ERROR');
throw new Error(error)
}
}
const useDocker = async (apps) => { const useDocker = async (apps) => {
const { const {
useOrdering: orderType, useOrdering: orderType,
unpinStoppedApps, unpinStoppedApps,
dockerHost: host, dockerHost: host = '',
} = await loadConfig(); } = await loadConfig();
let containers = [] const hosts = host.split(';')
const hosts = host.split(';'); const hostRequests = await Promise.allSettled(hosts.map((host) => getContainer({ host })))
try { if (hostRequests.length > 0) {
// Get list of containers let containers = hostRequests
containers = (await Promise.all(hosts.reduce((acc, host) => { // Extract successful requests to docker socket
const isLocalhost = host.includes('localhost'); .reduce((acc, { status, value }) => {
acc.push(axios.get( if (status === 'fulfilled') {
`http://${host}/containers/json?{"status":["running"]}`, acc = acc.concat(value.data)
isLocalhost ? { }
socketPath: '/var/run/docker.sock', return acc;
} : {} }, [])
)) // Filter out containers without any annotations
return acc; .filter((e) => Object.keys(e.Labels).length !== 0)
}, []))).flatMap(({ data }) => data)
} catch (err) {
logger.log(`Can't connect to the Docker API on one of the hosts: ${hosts.join(', ')}`, 'ERROR');
}
if (containers.length > 0) { if (containers.length > 0) {
apps = await App.findAll({ apps = await App.findAll({
order: [[orderType, 'ASC']], order: [[orderType, 'ASC']],
}); });
// Filter out containers without any annotations const dockerApps = [];
containers = containers.filter((e) => Object.keys(e.Labels).length !== 0);
const dockerApps = []; for (const container of containers) {
let labels = container.Labels;
for (const container of containers) { // Traefik labels for URL configuration
let labels = container.Labels; if (!('flame.url' in labels)) {
for (const label of Object.keys(labels)) {
// Traefik labels for URL configuration if (/^traefik.*.frontend.rule/.test(label)) {
if (!('flame.url' in labels)) { // Traefik 1.x
for (const label of Object.keys(labels)) { let value = labels[label];
if (/^traefik.*.frontend.rule/.test(label)) {
// Traefik 1.x if (value.indexOf('Host') !== -1) {
let value = labels[label]; value = value.split('Host:')[1];
labels['flame.url'] =
if (value.indexOf('Host') !== -1) { 'https://' + value.split(',').join(';https://');
value = value.split('Host:')[1];
labels['flame.url'] =
'https://' + value.split(',').join(';https://');
}
} else if (/^traefik.*?\.rule/.test(label)) {
// Traefik 2.x
const value = labels[label];
if (value.indexOf('Host') !== -1) {
const regex = /\`([a-zA-Z0-9\.\-]+)\`/g;
const domains = [];
while ((match = regex.exec(value)) != null) {
domains.push('http://' + match[1]);
} }
} else if (/^traefik.*?\.rule/.test(label)) {
if (domains.length > 0) { // Traefik 2.x
labels['flame.url'] = domains.join(';'); const value = labels[label];
if (value.indexOf('Host') !== -1) {
const regex = /\`([a-zA-Z0-9\.\-]+)\`/g;
const domains = [];
while ((match = regex.exec(value)) != null) {
domains.push('http://' + match[1]);
}
if (domains.length > 0) {
labels['flame.url'] = domains.join(';');
}
} }
} }
} }
} }
}
// add each container as flame formatted app
// add each container as flame formatted app
if (
'flame.name' in labels &&
'flame.url' in labels &&
/^app/.test(labels['flame.type'])
) {
for (let i = 0; i < labels['flame.name'].split(';').length; i++) {
const names = labels['flame.name'].split(';');
const urls = labels['flame.url'].split(';');
let icons = '';
if ('flame.icon' in labels) {
icons = labels['flame.icon'].split(';');
}
dockerApps.push({
name: names[i] || names[0],
url: urls[i] || urls[0],
icon: icons[i] || 'docker',
});
}
}
}
if (unpinStoppedApps) {
for (const app of apps) {
await app.update({ isPinned: false });
}
}
for (const item of dockerApps) {
// If app already exists, update it
if (apps.some((app) => app.name === item.name)) {
const app = apps.find((a) => a.name === item.name);
if ( if (
item.icon === 'custom' || 'flame.name' in labels &&
(item.icon === 'docker' && app.icon != 'docker') 'flame.url' in labels &&
/^app/.test(labels['flame.type'])
) { ) {
// update without overriding icon for (let i = 0; i < labels['flame.name'].split(';').length; i++) {
await app.update({ const names = labels['flame.name'].split(';');
name: item.name, const urls = labels['flame.url'].split(';');
url: item.url, let icons = '';
isPinned: true,
}); if ('flame.icon' in labels) {
icons = labels['flame.icon'].split(';');
}
dockerApps.push({
name: names[i] || names[0],
url: urls[i] || urls[0],
icon: icons[i] || 'docker',
});
}
}
}
if (unpinStoppedApps) {
for (const app of apps) {
await app.update({ isPinned: false });
}
}
for (const item of dockerApps) {
// If app already exists, update it
if (apps.some((app) => app.name === item.name)) {
const app = apps.find((a) => a.name === item.name);
if (
item.icon === 'custom' ||
(item.icon === 'docker' && app.icon != 'docker')
) {
// update without overriding icon
await app.update({
name: item.name,
url: item.url,
isPinned: true,
});
} else {
await app.update({
...item,
isPinned: true,
});
}
} else { } else {
await app.update({ // else create new app
await App.create({
...item, ...item,
icon: item.icon === 'custom' ? 'docker' : item.icon,
isPinned: true, isPinned: true,
}); });
} }
} else {
// else create new app
await App.create({
...item,
icon: item.icon === 'custom' ? 'docker' : item.icon,
isPinned: true,
});
} }
} }
} }