Skip to content

Commit

Permalink
Subscribe to Config Entities to delete invalid one #8
Browse files Browse the repository at this point in the history
  • Loading branch information
MichelFR committed Mar 9, 2023
1 parent 0c4ae34 commit 370820b
Show file tree
Hide file tree
Showing 4 changed files with 47 additions and 23 deletions.
4 changes: 2 additions & 2 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "mqdockerup",
"version": "0.13.4",
"version": "0.14.0",
"description": "A Node.js application that pushes information about running Docker containers to an MQTT server.",
"main": "index.js",
"scripts": {
Expand Down
31 changes: 22 additions & 9 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ const client = mqtt.connect(config.mqtt.connectionUri, {
});

client.subscribe(`${config.mqtt.topic}/update`);
client.subscribe('homeassistant/+/+/+/config');

const checkAndPublishUpdates = async (): Promise<void> => {
logger.info("Checking for image updates...");
Expand Down Expand Up @@ -44,34 +45,46 @@ client.on("connect", async () => {

client.on("message", async (topic: string, message: any) => {
const data = JSON.parse(message);
const containerId = data?.containerId;
const image = data?.image;

if ((topic = "mqdockerup/update" && containerId)) {
// Update-Handler for the /update message from MQTT
// This is triggered by the Home Assistant button in the UI to update a container
if ((topic = "mqdockerup/update" && data?.containerId)) {
const image = data?.image;
logger.info(`Got update message for ${image}`);
await DockerService.updateContainer(containerId, client);

await DockerService.updateContainer(data?.containerId, client);
logger.info("Updated container ");

await checkAndPublishUpdates();
}

// Missing Docker Container-Handler, removes the /config message from MQTT when the container is missing
// This removes the entity from Home Assistant if the container is not existing anymore
if (data?.device?.manufacturer === "MqDockerUp") {
const image = data?.device?.model;
const containerExists = await DockerService.checkIfContainerExists(image);

if (!containerExists) {
client.publish(topic, "");
logger.info(`Removed missing container ${image} from Home Assistant`);
}
}
});

const exitHandler = async (exitCode: number, error?: any) => {
const exitHandler = (exitCode: number, error?: any) => {
HomeassistantService.publishAvailability(client, false);

const now = new Date().toLocaleString();
let message = exitCode === 0 ? `MqDockerUp gracefully stopped` : `MqDockerUp stopped due to an error`;


if (error) {
logger.error(message);
logger.error(typeof error);
logger.error(error);
} else {
logger.info(message);
}

process.exit(exitCode);
};

Expand Down
33 changes: 22 additions & 11 deletions src/services/DockerService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ export default class DockerService {
if (response.status === 200) {
return { registry: "Docker Hub", response };
}
} catch (error) {}
} catch (error) { }

const registryList = [
{
Expand Down Expand Up @@ -179,7 +179,7 @@ export default class DockerService {
logger.error("Stream Error: " + err);
return;
}

logger.info("Image pulled successfully");
const containerConfig: any = {
...info,
Expand All @@ -189,21 +189,21 @@ export default class DockerService {
name: info.Name,
Image: image,
};

const mounts = info.Mounts;
const binds = mounts.map(
(mount) => `${mount.Source}:${mount.Destination}`
);
containerConfig.HostConfig.Binds = binds;

await container.stop();
await container.remove();

const newContainer = await DockerService.docker.createContainer(
containerConfig
);
await newContainer.start();

return newContainer;
},
function (event) {
Expand All @@ -213,20 +213,20 @@ export default class DockerService {
// get current, total and start values
const current = event.progressDetail.current || 0;
const total = event.progressDetail.total || 0;

// calculate percentage based on the difference between the current and last progress events
const percentage =
current > lastProgressEvent.progressDetail.current
? Math.round(((totalProgress + current - lastProgressEvent.progressDetail.current) / totalSize) * 100)
: Math.round((totalProgress / totalSize) * 100);

// update total progress and size
totalProgress += current - lastProgressEvent.progressDetail.current;
totalSize += total - lastProgressEvent.progressDetail.total;

// keep track of the last progress event
lastProgressEvent = event;

// print percentage
logger.info(`Total progress: ${totalProgress}/${totalSize} (${percentage}%)`);

Expand Down Expand Up @@ -308,8 +308,19 @@ export default class DockerService {
* @throws An error if the container could not be created.
*/
public static async createContainer(containerConfig: any): Promise<Docker.Container> {
const container = await DockerService.docker.createContainer({...containerConfig});
const container = await DockerService.docker.createContainer({ ...containerConfig });

return container;
}

/**
* Checks if a container exists.
* @param containerImage - The name of the Docker image to check.
* @returns A promise that resolves to true if the container exists.
*/
public static async checkIfContainerExists(containerImage: string): Promise<boolean> {
const containers = await DockerService.docker.listContainers({ all: true });
const container = containers.find((container) => container.Image === containerImage);
return container !== undefined;
}
}

0 comments on commit 370820b

Please sign in to comment.