Loading include/containerd/api.h +4 −4 Changes for include/containerd/api.h: 4 added lines, 4 removed lines. Original line number Diff line number Diff line Loading @@ -62,10 +62,10 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * ones, and those its credentials there may read. Asking a registry can * take long, so a job reads them into a cache: * * ListApps -> registry, updated (0: never read), then per app: app * (repository), image (without tag), description, owner, tag * (repeated, newest first, latest before the others), icon? (base64 * webp) * ListApps {from? (default 0)} -> registry, updated (0: never read), * then per app: app (repository), image (without tag), description, * owner, tag (repeated, newest first, latest before the others), * icon? (base64 webp); next if there are more (from for the next call) * RefreshApps -> a job * InstallApp {name, image, settings as CreateContainer} -> a job: pulls * the image, creates the container and starts it; the settings are Loading src/apps.cpp +20 −19 Changes for src/apps.cpp: 20 added lines, 19 removed lines. Original line number Diff line number Diff line Loading @@ -49,8 +49,8 @@ namespace containerd { namespace { const size_t MaxIcon = 128 * 1024; const size_t MaxReply = 900 * 1024; // of sysbus's 1 MiB; icons go first const size_t MaxIcon = 48 * 1024; const size_t PageSize = 128 * 1024; // well below a socket buffer: sysbus drops a client it can't write to const int MaxApps = 500; std::string cachePath() { return std::string(StateDir) + "/apps.json"; } Loading Loading @@ -86,38 +86,39 @@ json_object *sortedTags(json_object *repo) { } // namespace Result listApps() { Result listApps(size_t from) { Result r; std::string registry = appRegistry(), body; json_object *j = readFile(cachePath(), body) ? json_tokener_parse(body.c_str()) : nullptr; r.add("registry", registry); // a cache of another registry says nothing about this one if (!j || text(j, "registry") != registry) { if (j) json_object_put(j); r.add("registry", registry); r.add("updated", 0LL); return r; } r.add("registry", registry); r.add("updated", (long long)json_object_get_int64(member(j, "updated"))); json_object *apps = member(j, "apps"); size_t total = 0, icons = 0; for (size_t i = 0; apps && i < json_object_array_length(apps); ++i) { size_t count = apps ? json_object_array_length(apps) : 0, size = 0; for (size_t i = from; i < count; ++i) { json_object *a = json_object_array_get_idx(apps, i); total += text(a, "name").size() * 2 + text(a, "description").size() + text(a, "owner").size() + 256; if (json_object *tags = member(a, "tags")) total += 64 * json_object_array_length(tags); if (total > MaxReply) break; r.add("app", text(a, "name")); r.add("image", registry + "/" + text(a, "name")); r.add("description", text(a, "description")); r.add("owner", text(a, "owner")); Result one; one.add("app", text(a, "name")); one.add("image", registry + "/" + text(a, "name")); one.add("description", text(a, "description")); one.add("owner", text(a, "owner")); json_object *tags = member(a, "tags"); for (size_t t = 0; tags && t < json_object_array_length(tags); ++t) r.add("tag", json_object_get_string(json_object_array_get_idx(tags, t))); // the text of all apps comes before the icons of the first if (!text(a, "icon").empty() && total + icons + text(a, "icon").size() <= MaxReply / 2) { icons += text(a, "icon").size(); r.add("icon", text(a, "icon")); one.add("tag", json_object_get_string(json_object_array_get_idx(tags, t))); if (!text(a, "icon").empty()) one.add("icon", text(a, "icon")); size_t bytes = 0; for (auto &f : one.fields) bytes += f.first.size() + f.second.size() + 8; if (size && size + bytes > PageSize) { r.add("next", (long long)i); break; } size += bytes; r.fields.insert(r.fields.end(), one.fields.begin(), one.fields.end()); } json_object_put(j); return r; Loading src/apps.h +3 −1 Changes for src/apps.h: 3 added lines, 1 removed line. Original line number Diff line number Diff line Loading @@ -31,13 +31,15 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #pragma once #include <cstddef> #include <string> #include "result.h" namespace containerd { Result listApps(); // from: the page's first app Result listApps(size_t from); // the work of RefreshApps and InstallApp (each in a job) Result refreshApps(); Result installApp(const std::string &ref, const std::string &name, const Fields &fields); Loading src/containerctl.cpp +5 −1 Changes for src/containerctl.cpp: 5 added lines, 1 removed line. Original line number Diff line number Diff line Loading @@ -274,10 +274,14 @@ int main(int argc, char **argv) { if (cmd == "pull" && !arg.empty()) return follow(call(m::PullImage, {{"image", arg}})); if (cmd == "rmi" && !arg.empty()) return call(m::RemoveImage, {{"image", arg}}), 0; if (cmd == "apps") { sysbus::Message r = call(m::ListApps); std::string from = "0"; while (!from.empty()) { sysbus::Message r = call(m::ListApps, {{"from", from}}); if (r.get("updated") == "0") std::cerr << "containerctl: never read; try refresh-apps\n"; for (auto &a : records(r, "app")) printf("%-50s %-16s %s\n", get(a, "image").c_str(), get(a, "tag").c_str(), get(a, "description").c_str()); from = r.get("next"); } return 0; } if (cmd == "refresh-apps") return follow(call(m::RefreshApps)); Loading src/main.cpp +2 −1 Changes for src/main.cpp: 2 added lines, 1 removed line. Original line number Diff line number Diff line Loading @@ -32,6 +32,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include <cerrno> #include <csignal> #include <cstdlib> #include <cstring> #include <ctime> #include <iostream> Loading Loading @@ -169,7 +170,7 @@ Result Daemon::images(const sysbus::Message &call) { Result Daemon::apps(const sysbus::Message &call) { namespace m = method; if (call.member == m::ListApps) return listApps(); if (call.member == m::ListApps) return listApps(std::strtoul(call.get("from", "0").c_str(), nullptr, 10)); if (call.member == m::RefreshApps) return jobs::run("Reading the apps of %1", "Apps von %1 werden gelesen", {appRegistry()}, [] { return refreshApps(); }); std::string ref = normalizeRef(call.get("image")); Loading Loading
include/containerd/api.h +4 −4 Changes for include/containerd/api.h: 4 added lines, 4 removed lines. Original line number Diff line number Diff line Loading @@ -62,10 +62,10 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * ones, and those its credentials there may read. Asking a registry can * take long, so a job reads them into a cache: * * ListApps -> registry, updated (0: never read), then per app: app * (repository), image (without tag), description, owner, tag * (repeated, newest first, latest before the others), icon? (base64 * webp) * ListApps {from? (default 0)} -> registry, updated (0: never read), * then per app: app (repository), image (without tag), description, * owner, tag (repeated, newest first, latest before the others), * icon? (base64 webp); next if there are more (from for the next call) * RefreshApps -> a job * InstallApp {name, image, settings as CreateContainer} -> a job: pulls * the image, creates the container and starts it; the settings are Loading
src/apps.cpp +20 −19 Changes for src/apps.cpp: 20 added lines, 19 removed lines. Original line number Diff line number Diff line Loading @@ -49,8 +49,8 @@ namespace containerd { namespace { const size_t MaxIcon = 128 * 1024; const size_t MaxReply = 900 * 1024; // of sysbus's 1 MiB; icons go first const size_t MaxIcon = 48 * 1024; const size_t PageSize = 128 * 1024; // well below a socket buffer: sysbus drops a client it can't write to const int MaxApps = 500; std::string cachePath() { return std::string(StateDir) + "/apps.json"; } Loading Loading @@ -86,38 +86,39 @@ json_object *sortedTags(json_object *repo) { } // namespace Result listApps() { Result listApps(size_t from) { Result r; std::string registry = appRegistry(), body; json_object *j = readFile(cachePath(), body) ? json_tokener_parse(body.c_str()) : nullptr; r.add("registry", registry); // a cache of another registry says nothing about this one if (!j || text(j, "registry") != registry) { if (j) json_object_put(j); r.add("registry", registry); r.add("updated", 0LL); return r; } r.add("registry", registry); r.add("updated", (long long)json_object_get_int64(member(j, "updated"))); json_object *apps = member(j, "apps"); size_t total = 0, icons = 0; for (size_t i = 0; apps && i < json_object_array_length(apps); ++i) { size_t count = apps ? json_object_array_length(apps) : 0, size = 0; for (size_t i = from; i < count; ++i) { json_object *a = json_object_array_get_idx(apps, i); total += text(a, "name").size() * 2 + text(a, "description").size() + text(a, "owner").size() + 256; if (json_object *tags = member(a, "tags")) total += 64 * json_object_array_length(tags); if (total > MaxReply) break; r.add("app", text(a, "name")); r.add("image", registry + "/" + text(a, "name")); r.add("description", text(a, "description")); r.add("owner", text(a, "owner")); Result one; one.add("app", text(a, "name")); one.add("image", registry + "/" + text(a, "name")); one.add("description", text(a, "description")); one.add("owner", text(a, "owner")); json_object *tags = member(a, "tags"); for (size_t t = 0; tags && t < json_object_array_length(tags); ++t) r.add("tag", json_object_get_string(json_object_array_get_idx(tags, t))); // the text of all apps comes before the icons of the first if (!text(a, "icon").empty() && total + icons + text(a, "icon").size() <= MaxReply / 2) { icons += text(a, "icon").size(); r.add("icon", text(a, "icon")); one.add("tag", json_object_get_string(json_object_array_get_idx(tags, t))); if (!text(a, "icon").empty()) one.add("icon", text(a, "icon")); size_t bytes = 0; for (auto &f : one.fields) bytes += f.first.size() + f.second.size() + 8; if (size && size + bytes > PageSize) { r.add("next", (long long)i); break; } size += bytes; r.fields.insert(r.fields.end(), one.fields.begin(), one.fields.end()); } json_object_put(j); return r; Loading
src/apps.h +3 −1 Changes for src/apps.h: 3 added lines, 1 removed line. Original line number Diff line number Diff line Loading @@ -31,13 +31,15 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #pragma once #include <cstddef> #include <string> #include "result.h" namespace containerd { Result listApps(); // from: the page's first app Result listApps(size_t from); // the work of RefreshApps and InstallApp (each in a job) Result refreshApps(); Result installApp(const std::string &ref, const std::string &name, const Fields &fields); Loading
src/containerctl.cpp +5 −1 Changes for src/containerctl.cpp: 5 added lines, 1 removed line. Original line number Diff line number Diff line Loading @@ -274,10 +274,14 @@ int main(int argc, char **argv) { if (cmd == "pull" && !arg.empty()) return follow(call(m::PullImage, {{"image", arg}})); if (cmd == "rmi" && !arg.empty()) return call(m::RemoveImage, {{"image", arg}}), 0; if (cmd == "apps") { sysbus::Message r = call(m::ListApps); std::string from = "0"; while (!from.empty()) { sysbus::Message r = call(m::ListApps, {{"from", from}}); if (r.get("updated") == "0") std::cerr << "containerctl: never read; try refresh-apps\n"; for (auto &a : records(r, "app")) printf("%-50s %-16s %s\n", get(a, "image").c_str(), get(a, "tag").c_str(), get(a, "description").c_str()); from = r.get("next"); } return 0; } if (cmd == "refresh-apps") return follow(call(m::RefreshApps)); Loading
src/main.cpp +2 −1 Changes for src/main.cpp: 2 added lines, 1 removed line. Original line number Diff line number Diff line Loading @@ -32,6 +32,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include <cerrno> #include <csignal> #include <cstdlib> #include <cstring> #include <ctime> #include <iostream> Loading Loading @@ -169,7 +170,7 @@ Result Daemon::images(const sysbus::Message &call) { Result Daemon::apps(const sysbus::Message &call) { namespace m = method; if (call.member == m::ListApps) return listApps(); if (call.member == m::ListApps) return listApps(std::strtoul(call.get("from", "0").c_str(), nullptr, 10)); if (call.member == m::RefreshApps) return jobs::run("Reading the apps of %1", "Apps von %1 werden gelesen", {appRegistry()}, [] { return refreshApps(); }); std::string ref = normalizeRef(call.get("image")); Loading