1
0
Fork 0
mirror of https://github.com/pawelmalak/flame.git synced 2025-08-05 10:55:17 +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 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 {
useOrdering: orderType,
unpinStoppedApps,
dockerHost: host,
dockerHost: host = '',
} = await loadConfig();
let containers = []
const hosts = host.split(';');
const hosts = host.split(';')
const hostRequests = await Promise.allSettled(hosts.map((host) => getContainer({ host })))
try {
// Get list of containers
containers = (await Promise.all(hosts.reduce((acc, host) => {
const isLocalhost = host.includes('localhost');
acc.push(axios.get(
`http://${host}/containers/json?{"status":["running"]}`,
isLocalhost ? {
socketPath: '/var/run/docker.sock',
} : {}
))
return acc;
}, []))).flatMap(({ data }) => data)
} catch (err) {
logger.log(`Can't connect to the Docker API on one of the hosts: ${hosts.join(', ')}`, 'ERROR');
}
if (hostRequests.length > 0) {
let containers = hostRequests
// Extract successful requests to docker socket
.reduce((acc, { status, value }) => {
if (status === 'fulfilled') {
acc = acc.concat(value.data)
}
return acc;
}, [])
// Filter out containers without any annotations
.filter((e) => Object.keys(e.Labels).length !== 0)
if (containers.length > 0) {
apps = await App.findAll({
order: [[orderType, 'ASC']],
});
if (containers.length > 0) {
apps = await App.findAll({
order: [[orderType, 'ASC']],
});
// Filter out containers without any annotations
containers = containers.filter((e) => Object.keys(e.Labels).length !== 0);
const dockerApps = [];
const dockerApps = [];
for (const container of containers) {
let labels = container.Labels;
for (const container of containers) {
let labels = container.Labels;
// Traefik labels for URL configuration
if (!('flame.url' in labels)) {
for (const label of Object.keys(labels)) {
if (/^traefik.*.frontend.rule/.test(label)) {
// Traefik 1.x
let value = labels[label];
if (value.indexOf('Host') !== -1) {
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]);
// Traefik labels for URL configuration
if (!('flame.url' in labels)) {
for (const label of Object.keys(labels)) {
if (/^traefik.*.frontend.rule/.test(label)) {
// Traefik 1.x
let value = labels[label];
if (value.indexOf('Host') !== -1) {
value = value.split('Host:')[1];
labels['flame.url'] =
'https://' + value.split(',').join(';https://');
}
if (domains.length > 0) {
labels['flame.url'] = domains.join(';');
} 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]);
}
if (domains.length > 0) {
labels['flame.url'] = domains.join(';');
}
}
}
}
}
}
// 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);
// add each container as flame formatted app
if (
item.icon === 'custom' ||
(item.icon === 'docker' && app.icon != 'docker')
'flame.name' in labels &&
'flame.url' in labels &&
/^app/.test(labels['flame.type'])
) {
// update without overriding icon
await app.update({
name: item.name,
url: item.url,
isPinned: true,
});
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 (
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 {
await app.update({
// else create new app
await App.create({
...item,
icon: item.icon === 'custom' ? 'docker' : item.icon,
isPinned: true,
});
}
} else {
// else create new app
await App.create({
...item,
icon: item.icon === 'custom' ? 'docker' : item.icon,
isPinned: true,
});
}
}
}