MHO/Docker Swarm

feat: add docker swarm services
This commit is contained in:
Matthew Horwood 2021-11-18 20:59:57 +00:00
parent 1220c56fc5
commit b60bd3120b

View file

@ -11,20 +11,62 @@ const useDocker = async (apps) => {
dockerHost: host,
} = await loadConfig();
const dockerApps = [];
let containers = null;
let containers_swarm = null;
function addApp(dockerApps, labels){
// 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',
});
}
}
}
// Get list of containers
try {
if (host.includes('localhost')) {
// Use default host
let { data } = await axios.get(
`http://${host}/containers/json?{"status":["running"]}`,
{
socketPath: '/var/run/docker.sock',
}
);
function getDocker(){
return axios.get(
`http://${host}/containers/json?{"status":["running"]}`,
{
socketPath: '/var/run/docker.sock',
}
);
}
function getSwarm(){
return axios.get(
`http://${host}/services`,
{
socketPath: '/var/run/docker.sock',
}
);
}
[ containers, containers_swarm ] = await Promise.all(
[getDocker(),
getSwarm()
]);
containers = data;
} else {
// Use custom host
let { data } = await axios.get(
@ -37,20 +79,17 @@ const useDocker = async (apps) => {
logger.log(`Can't connect to the Docker API on ${host}`, 'ERROR');
}
if (containers) {
if (containers_swarm) {
apps = await App.findAll({
order: [[orderType, 'ASC']],
});
// Filter out containers without any annotations
containers = containers.filter((e) => Object.keys(e.Labels).length !== 0);
services = containers_swarm.data;
for (const service of services) {
let labels = service.Spec.Labels;
const dockerApps = [];
for (const container of containers) {
let labels = container.Labels;
// Traefik labels for URL configuration
labels['flame.name'] = service.Spec.Name;
labels['flame.type'] = 'application';
if (!('flame.url' in labels)) {
for (const label of Object.keys(labels)) {
if (/^traefik.*.frontend.rule/.test(label)) {
@ -81,68 +120,96 @@ const useDocker = async (apps) => {
}
}
}
addApp(dockerApps, labels);
}
}
// 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 (containers) {
apps = await App.findAll({
order: [[orderType, 'ASC']],
});
if ('flame.icon' in labels) {
icons = labels['flame.icon'].split(';');
// Filter out containers without any annotations
containers = containers.data.filter((e) => Object.keys(e.Labels).length !== 0);
for (const container of containers) {
let labels = container.Labels;
if(!('com.docker.stack.namespace' in labels)){
console.log(container)
labels['flame.name'] = container.Names[0];
labels['flame.type'] = 'application';
// 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]);
}
if (domains.length > 0) {
labels['flame.url'] = domains.join(';');
}
}
}
}
dockerApps.push({
name: names[i] || names[0],
url: urls[i] || urls[0],
icon: icons[i] || 'docker',
});
}
}
addApp(dockerApps, labels);
}
}
if (unpinStoppedApps) {
for (const app of apps) {
await app.update({ isPinned: false });
}
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);
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,
});
}
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 {
// else create new app
await App.create({
await app.update({
...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,
});
}
}
};
module.exports = useDocker;