mirror of
https://github.com/11notes/docker-traefik-labels.git
synced 2026-04-29 19:39:18 -05:00
149 lines
3.6 KiB
JavaScript
149 lines
3.6 KiB
JavaScript
const fs = require('fs');
|
|
const Docker = require('dockerode');
|
|
const args = process.argv.slice(2);
|
|
|
|
process
|
|
.on('unhandledRejection', (e, p) => {
|
|
console.error(e, p);
|
|
process.send({error:e.toString()});
|
|
})
|
|
.on('uncaughtException', e => {
|
|
console.error(e);
|
|
process.send({error:e.toString()});
|
|
});
|
|
|
|
class Worker{
|
|
#config;
|
|
#docker;
|
|
#interval = {poll:false, ping:false};
|
|
|
|
constructor(config){
|
|
this.#config = config;
|
|
this.#docker = new Docker({
|
|
protocol:'https',
|
|
host:this.#config.node,
|
|
port:this.#config.port,
|
|
ca:fs.readFileSync(this.#config.tls.ca),
|
|
cert:fs.readFileSync(this.#config.tls.crt),
|
|
key:fs.readFileSync(this.#config.tls.key),
|
|
timeout:parseInt(this.#config.timeout*1000)
|
|
});
|
|
}
|
|
|
|
async run(){
|
|
try{
|
|
this.#docker.getEvents({}, (error, data) => {
|
|
if(!error){
|
|
data.on('data', async(chunk) =>{
|
|
const response = chunk.toString('utf8').replace(',"ti"', '');
|
|
try{
|
|
const event = JSON.parse(response);
|
|
if(/Container/i.test(event?.Type) && /^(start|die)$/i.test(event?.status)){
|
|
this.#labels(event.id, event.status);
|
|
}
|
|
}catch(e){
|
|
//JSON parse error
|
|
}
|
|
});
|
|
}else{
|
|
process.send({error:error.toString()});
|
|
}
|
|
});
|
|
|
|
setInterval(async()=>{
|
|
if(!this.#interval.poll){
|
|
this.#interval.poll = true;
|
|
try{
|
|
await this.#poll();
|
|
}catch(e){
|
|
process.send({error:e.toString()});
|
|
}finally{
|
|
this.#interval.poll = false;
|
|
}
|
|
}
|
|
}, this.#config.poll*1000);
|
|
|
|
setInterval(async()=>{
|
|
if(!this.#interval.ping){
|
|
this.#interval.ping = true;
|
|
try{
|
|
await this.#ping();
|
|
}catch(e){
|
|
process.send({error:e.toString()});
|
|
}finally{
|
|
this.#interval.ping = false;
|
|
}
|
|
}
|
|
}, this.#config.ping*1000);
|
|
|
|
await this.#ping();
|
|
await this.#poll();
|
|
|
|
}catch(e){
|
|
process.send({error:e.toString()});
|
|
}
|
|
}
|
|
|
|
async #poll(){
|
|
try{
|
|
await this.#docker.listContainers((error, containers) => {
|
|
if(!error){
|
|
containers.forEach(async(container) => {
|
|
this.#labels(container.Id, 'poll');
|
|
});
|
|
}else{
|
|
process.send({error:e.toString()});
|
|
}
|
|
});
|
|
}catch(e){
|
|
process.send({error:e.toString()});
|
|
}
|
|
}
|
|
|
|
async #ping(){
|
|
try{
|
|
await this.#docker.ping();
|
|
}catch(e){
|
|
process.exit(1);
|
|
}
|
|
}
|
|
|
|
async #labels(id, event){
|
|
try{
|
|
const container = this.#docker.getContainer(id);
|
|
container.inspect(async(error, data) => {
|
|
if(!error){
|
|
const result = {
|
|
name:(data?.Name || data?.id).replace(/^\//i, ''),
|
|
event:event,
|
|
labels:{},
|
|
start:(/start|poll/i.test(event)) ? true : false,
|
|
worker:{
|
|
node:this.#config.node,
|
|
port:this.#config.port
|
|
},
|
|
};
|
|
for(const label in data?.Config?.Labels){
|
|
if(/traefik\/|rfc2136\//i.test(label)){
|
|
result.labels[label] = data.Config.Labels[label];
|
|
}
|
|
}
|
|
process.send(result);
|
|
}else{
|
|
throw(error);
|
|
}
|
|
});
|
|
}catch(e){
|
|
process.send({error:e.toString()});
|
|
}
|
|
}
|
|
}
|
|
|
|
if(Array.isArray(args) && args.length > 0){
|
|
try{
|
|
new Worker(JSON.parse(args)).run();
|
|
}catch(e){
|
|
process.send({error:e.toString()});
|
|
process.exit(1);
|
|
}
|
|
} |