这是indexloc提供的服务,不要输入任何密码
Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
78 changes: 76 additions & 2 deletions index.js
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,7 @@ app.all('/container/:containerId', function (req, res) {
state: "stopped"
});
});
}
}
}, function (status, message) {
if (config.get("debug"))
console.log("Failed to get status of Docker container");
Expand Down Expand Up @@ -165,6 +165,80 @@ app.get('/container/:containerId/restart', function (req, res) {
})
});

app.post('/container/:containerId/exec', function(req, res) {
var containerId = req.params.containerId;
console.log("Exec " + containerId);

var command = req.body.command ? req.body.command : false;
if (command == "" || !command) {
res.send({
status: false,
error: "No command specified"
});
res.status(400);
return;
}

getContainer(containerId, function (container) {
if (config.get("debug"))
console.log("Attempting to execute command in container " + container.Id);
var options = {
Cmd: command.split(" "),
AttachStdout: true,
AttachStderr: true
};
if (config.get('debug'))
console.log(options);

var container = docker.getContainer(container.Id);
container.exec(options, function (err, exec) {
if (err) {
if (config.get("debug")) {
console.log("Failed to get container " + container.Id);
console.log(err);
}

res.status(500);
res.send(err);
return;
}

exec.start(function (err, stream) {
if (err) {
if (config.get("debug")) {
console.log("Failed to execute in container " + container.Id);
console.log(err);
}

res.status(500);
res.send(err);
return;
}
console.log("executed query");
const chunks = [];
stream.on("data", function (chunk) {
chunks.push(chunk.toString());
});

// Send the buffer or you can put it into a var
stream.on("end", function () {
// We remove the first 8 chars as the contain a unicode START OF HEADING followed by ENQUIRY.
res.send({
status: true,
result: chunks.join('').substr(8)
});
});
});
return;
});
}, function (status, message) {
res.status(status);
if (message) {
res.send(message);
}
});
})

//Attempt to connect to the Docker daemon
switch (config.get("docker_connection:type")) {
case "http":
Expand Down Expand Up @@ -222,4 +296,4 @@ function getContainer(name, cb, error)

return cb(containers[0]);
});
}
}
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "ha-dockermon",
"version": "0.0.1",
"version": "0.0.2",
"description": "A RESTful HTTP endpoint which can return the status of Docker containers for Home Automation controllers like Home Assistant",
"main": "index.js",
"scripts": {
Expand Down
15 changes: 15 additions & 0 deletions readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,21 @@ Calls to this URL will issue a `docker restart <container name>` on the host mac

Useful in a Home Assistant script to restart containers (including Home Assistant itself).

#### POST /container/{container name}/exec

Allows you to execute commands inside a running container. When making a call to this endpoint you must send the correct `Content-Type` headers and JSON as the body. An example request with cURL is below.

You must also send a `command` variable which contains the command you would like to run in the container.

```bash
curl --request POST \
--url http://127.0.0.1:8126/container/grafana/exec \
--header 'content-type: application/octet-stream' \
--data '{"command": "ls -a"}'
```

The response will be a json object with a `result` key containing the output from the command executed.

### Home Assistant RESTful Switch

You can use this service as a [RESTful switch](https://home-assistant.io/components/switch.rest/) inside Home Assistant.
Expand Down