Fixed the duplicate portmappings caused by Docker's /containers/json API returning two Ports entries for every bound port
This commit is contained in:
parent
d26b4f284a
commit
c3419524e5
5 changed files with 24 additions and 5 deletions
11
DEVLOG.md
11
DEVLOG.md
|
|
@ -1,5 +1,16 @@
|
|||
# Tux-Dock Development Log
|
||||
|
||||
## 0.4.1-beta
|
||||
|
||||
### TUI stability
|
||||
|
||||
- Fixed duplicate port mappings shown in the container list TUI. Docker's `/containers/json` API returns separate `Ports` entries for IPv4 (`0.0.0.0`) and IPv6 (`::`) bindings of the same host port; the container parser now deduplicates these into a single `public:private` display string.
|
||||
- Added a container parser regression test covering IPv4/IPv6 duplicate port bindings.
|
||||
|
||||
### Version
|
||||
|
||||
- Bumped version to `0.4.1-beta`.
|
||||
|
||||
## 0.4-beta
|
||||
|
||||
### ARM64 / tuxreaperd fixes
|
||||
|
|
|
|||
|
|
@ -251,7 +251,7 @@ ctest --test-dir build --output-on-failure
|
|||
|
||||
## About / Version
|
||||
|
||||
- Version: `0.4-beta`
|
||||
- Version: `0.4.1-beta`
|
||||
- Created by: `markmental`
|
||||
- GitHub: https://github.com/MARKMENTAL/tuxdock
|
||||
- Forgejo: https://mentalnet.xyz/forgejo-v2/markmental/tuxdock
|
||||
|
|
|
|||
2
main.cpp
2
main.cpp
|
|
@ -717,7 +717,7 @@ void TuxDockApp::ActionExecDetachedCommand() {
|
|||
}
|
||||
|
||||
void TuxDockApp::ActionAbout() {
|
||||
OpenMessage("About Tux-Dock", "Tux-Dock 0.4-beta | Created by markmental");
|
||||
OpenMessage("About Tux-Dock", "Tux-Dock 0.4.1-beta | Created by markmental");
|
||||
}
|
||||
|
||||
void TuxDockApp::ExecuteSelectedAction() {
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@
|
|||
#include <nlohmann/json.hpp>
|
||||
|
||||
#include <sstream>
|
||||
#include <unordered_set>
|
||||
|
||||
using json = nlohmann::json;
|
||||
|
||||
|
|
@ -17,6 +18,7 @@ std::string portsFor(const json& item) {
|
|||
const auto it = item.find("Ports");
|
||||
if (it == item.end() || !it->is_array()) return {};
|
||||
std::ostringstream result;
|
||||
std::unordered_set<std::string> seen;
|
||||
bool first = true;
|
||||
for (const auto& port : *it) {
|
||||
if (!port.is_object()) continue;
|
||||
|
|
@ -24,8 +26,11 @@ std::string portsFor(const json& item) {
|
|||
const auto private_it = port.find("PrivatePort");
|
||||
if (public_it == port.end() || private_it == port.end() ||
|
||||
!public_it->is_number() || !private_it->is_number()) continue;
|
||||
const std::string mapping = std::to_string(public_it->get<int>()) + ":" +
|
||||
std::to_string(private_it->get<int>());
|
||||
if (!seen.insert(mapping).second) continue;
|
||||
if (!first) result << ", ";
|
||||
result << *public_it << ":" << *private_it;
|
||||
result << mapping;
|
||||
first = false;
|
||||
}
|
||||
return result.str();
|
||||
|
|
|
|||
|
|
@ -7,15 +7,18 @@ int main() {
|
|||
const auto result = parseContainerList(R"([
|
||||
{"Id":"running-id","Names":["/web"],"State":"running","Status":"Up 2 minutes","Ports":[]},
|
||||
{"Id":"exited-id","Names":["/old"],"State":"exited","Status":"Exited (0) 1 minute ago","Ports":[{"PrivatePort":80,"Type":"tcp"}]},
|
||||
{"Id":"odd-id","Names":["/odd"],"State":"exited","Ports":"unexpected"}
|
||||
{"Id":"odd-id","Names":["/odd"],"State":"exited","Ports":"unexpected"},
|
||||
{"Id":"mapped-id","Names":["/mapped"],"State":"running","Status":"Up 1 minute","Ports":[{"IP":"0.0.0.0","PrivatePort":80,"PublicPort":8080,"Type":"tcp"},{"IP":"::","PrivatePort":80,"PublicPort":8080,"Type":"tcp"}]}
|
||||
])");
|
||||
assert(result.ok());
|
||||
assert(result.items.size() == 3);
|
||||
assert(result.items.size() == 4);
|
||||
assert(result.items[0].running);
|
||||
assert(!result.items[1].running);
|
||||
assert(result.items[1].name == "old");
|
||||
assert(result.items[1].ports.empty());
|
||||
assert(result.items[2].name == "odd");
|
||||
assert(result.items[3].name == "mapped");
|
||||
assert(result.items[3].ports == "8080:80");
|
||||
|
||||
const auto empty = parseContainerList("[]");
|
||||
assert(empty.ok());
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue