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:
parent
f4c4ba98be
commit
21d651b897
1 changed files with 116 additions and 106 deletions
|
@ -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,
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue