Loading include/containerd/api.h +4 −0 Changes for include/containerd/api.h: 4 added lines, 0 removed lines. Original line number Diff line number Diff line Loading @@ -122,6 +122,9 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * StopSignal (default SIGTERM) to the container, after timeout * everything in its cgroup is killed; replies at once (stopping) * RestartContainer {name} stop (if running), then start * RecreateContainer {name, timeout?} stop (if running), its changes go * (a fresh root file system from the image, as pulled now), then * start again if it was running; the settings stay * KillContainer {name, signal? (number or name, default KILL)} * ContainerLog {name, lines? (default 200, max 5000)} -> line (repeated) * Loading Loading @@ -152,6 +155,7 @@ constexpr const char *DeleteContainer = "DeleteContainer"; constexpr const char *StartContainer = "StartContainer"; constexpr const char *StopContainer = "StopContainer"; constexpr const char *RestartContainer = "RestartContainer"; constexpr const char *RecreateContainer = "RecreateContainer"; constexpr const char *KillContainer = "KillContainer"; constexpr const char *ContainerLog = "ContainerLog"; Loading src/containers.cpp +31 −14 Changes for src/containers.cpp: 31 added lines, 14 removed lines. Original line number Diff line number Diff line Loading @@ -71,7 +71,7 @@ struct Runtime { int exitCode = 0; std::string error; int restarts = 0, backoff = 1; bool stopRequested = false, startAfterStop = false; bool stopRequested = false, startAfterStop = false, discardAfterStop = false; time_t killAt = 0, restartAt = 0; }; Loading Loading @@ -134,6 +134,19 @@ void closeWatch(Runtime &r) { r.statusFd = r.pidfd = -1; } // the container's own files: out of the way now (a fresh root file system // at the next start), deleted in a job -- they may be many Result discard(const std::string &name) { std::string dir = containerDir(name); if (!exists(dir)) return ok(); std::string gone = std::string(StateDir) + "/tmp/deleted-" + name + "-" + std::to_string(time(nullptr)); mkdirs(std::string(StateDir) + "/tmp", 0700); if (rename(dir.c_str(), gone.c_str()) != 0) gone = dir; return jobs::run("Deleting the files of %1", "Dateien von %1 werden gelöscht", {name}, [gone] { return removeTree(gone) ? ok() : fail(sysErr(gone, errno), 500); }); } // the supervisor is gone: how it ended void ended(const std::string &name, Runtime &r) { // ours unless containerd was restarted (then ECHILD); it is exiting, Loading @@ -153,6 +166,11 @@ void ended(const std::string &name, Runtime &r) { std::cerr << "containerd: " << name << " ended (" << (failedStart ? r.error : "exit " + std::to_string(r.exitCode)) << ")" << std::endl; setState(name, r, failedStart ? "failed" : "exited"); if (r.discardAfterStop) { r.discardAfterStop = false; Result res = discard(name); if (res.failed()) std::cerr << "containerd: " << name << ": " << res.message << std::endl; } if (r.startAfterStop) { r.startAfterStop = false; r.restartAt = time(nullptr); Loading Loading @@ -353,12 +371,14 @@ void killCgroup(const std::string &name) { } } Result stopOne(const std::string &name, int timeout, bool startAfter) { Result stopOne(const std::string &name, int timeout, bool startAfter, bool discardAfter = false) { Runtime &r = table()[name]; if (!active(r) || r.pid <= 0) { if (startAfter) return startOne(name); if (r.state == "starting") return fail(tr("%1 is starting", "%1 startet gerade", {name}), 409); return ok().add("state", r.state); Result res = discardAfter ? discard(name) : ok(); if (res.failed()) return res; if (startAfter) return startOne(name); return res.add("state", r.state); } Settings s; std::string err; Loading @@ -369,6 +389,7 @@ Result stopOne(const std::string &name, int timeout, bool startAfter) { if (s.boot) sig = SIGRTMIN + 3; // systemd's "halt", as nspawn sends it r.stopRequested = true; r.startAfterStop = startAfter; r.discardAfterStop = discardAfter; r.restartAt = 0; if (kill(r.pid, sig) != 0 && errno != ESRCH) return fail(sysErr("kill", errno), 500); r.killAt = time(nullptr) + std::max(timeout, 0); Loading Loading @@ -481,15 +502,7 @@ Result remove(const std::string &name) { unlink((logPath(name) + ".1").c_str()); for (const char *ext : {".exit", ".state", ".layers", ".lease"}) unlink(runFile(name, ext).c_str()); table().erase(name); // its files may be many: out of the way now, deleted in a job std::string dir = containerDir(name); if (!exists(dir)) return ok(); std::string gone = std::string(StateDir) + "/tmp/deleted-" + name + "-" + std::to_string(time(nullptr)); mkdirs(std::string(StateDir) + "/tmp", 0700); if (rename(dir.c_str(), gone.c_str()) != 0) gone = dir; return jobs::run("Deleting the files of %1", "Dateien von %1 werden gelöscht", {name}, [gone] { return removeTree(gone) ? ok() : fail(sysErr(gone, errno), 500); }); return discard(name); } Result logOf(const std::string &name, long long lines) { Loading Loading @@ -658,7 +671,7 @@ bool handles(const std::string &m) { namespace mt = method; return m == mt::ListContainers || m == mt::GetContainer || m == mt::CreateContainer || m == mt::EditContainer || m == mt::DeleteContainer || m == mt::StartContainer || m == mt::StopContainer || m == mt::RestartContainer || m == mt::KillContainer || m == mt::ContainerLog; m == mt::RecreateContainer || m == mt::KillContainer || m == mt::ContainerLog; } Result handle(const sysbus::Message &call) { Loading Loading @@ -686,6 +699,10 @@ Result handle(const sysbus::Message &call) { } if (m == mt::StopContainer) return stopOne(name, (int)number(call, "timeout", 10), false); if (m == mt::RestartContainer) return stopOne(name, (int)number(call, "timeout", 10), true); if (m == mt::RecreateContainer) { bool wasActive = active(table()[name]); return stopOne(name, (int)number(call, "timeout", 10), wasActive, true); } // KillContainer Runtime &r = table()[name]; if (!active(r) || r.pid <= 0) return fail(tr("%1 isn't running", "%1 läuft nicht", {name}), 409); Loading Loading
include/containerd/api.h +4 −0 Changes for include/containerd/api.h: 4 added lines, 0 removed lines. Original line number Diff line number Diff line Loading @@ -122,6 +122,9 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * StopSignal (default SIGTERM) to the container, after timeout * everything in its cgroup is killed; replies at once (stopping) * RestartContainer {name} stop (if running), then start * RecreateContainer {name, timeout?} stop (if running), its changes go * (a fresh root file system from the image, as pulled now), then * start again if it was running; the settings stay * KillContainer {name, signal? (number or name, default KILL)} * ContainerLog {name, lines? (default 200, max 5000)} -> line (repeated) * Loading Loading @@ -152,6 +155,7 @@ constexpr const char *DeleteContainer = "DeleteContainer"; constexpr const char *StartContainer = "StartContainer"; constexpr const char *StopContainer = "StopContainer"; constexpr const char *RestartContainer = "RestartContainer"; constexpr const char *RecreateContainer = "RecreateContainer"; constexpr const char *KillContainer = "KillContainer"; constexpr const char *ContainerLog = "ContainerLog"; Loading
src/containers.cpp +31 −14 Changes for src/containers.cpp: 31 added lines, 14 removed lines. Original line number Diff line number Diff line Loading @@ -71,7 +71,7 @@ struct Runtime { int exitCode = 0; std::string error; int restarts = 0, backoff = 1; bool stopRequested = false, startAfterStop = false; bool stopRequested = false, startAfterStop = false, discardAfterStop = false; time_t killAt = 0, restartAt = 0; }; Loading Loading @@ -134,6 +134,19 @@ void closeWatch(Runtime &r) { r.statusFd = r.pidfd = -1; } // the container's own files: out of the way now (a fresh root file system // at the next start), deleted in a job -- they may be many Result discard(const std::string &name) { std::string dir = containerDir(name); if (!exists(dir)) return ok(); std::string gone = std::string(StateDir) + "/tmp/deleted-" + name + "-" + std::to_string(time(nullptr)); mkdirs(std::string(StateDir) + "/tmp", 0700); if (rename(dir.c_str(), gone.c_str()) != 0) gone = dir; return jobs::run("Deleting the files of %1", "Dateien von %1 werden gelöscht", {name}, [gone] { return removeTree(gone) ? ok() : fail(sysErr(gone, errno), 500); }); } // the supervisor is gone: how it ended void ended(const std::string &name, Runtime &r) { // ours unless containerd was restarted (then ECHILD); it is exiting, Loading @@ -153,6 +166,11 @@ void ended(const std::string &name, Runtime &r) { std::cerr << "containerd: " << name << " ended (" << (failedStart ? r.error : "exit " + std::to_string(r.exitCode)) << ")" << std::endl; setState(name, r, failedStart ? "failed" : "exited"); if (r.discardAfterStop) { r.discardAfterStop = false; Result res = discard(name); if (res.failed()) std::cerr << "containerd: " << name << ": " << res.message << std::endl; } if (r.startAfterStop) { r.startAfterStop = false; r.restartAt = time(nullptr); Loading Loading @@ -353,12 +371,14 @@ void killCgroup(const std::string &name) { } } Result stopOne(const std::string &name, int timeout, bool startAfter) { Result stopOne(const std::string &name, int timeout, bool startAfter, bool discardAfter = false) { Runtime &r = table()[name]; if (!active(r) || r.pid <= 0) { if (startAfter) return startOne(name); if (r.state == "starting") return fail(tr("%1 is starting", "%1 startet gerade", {name}), 409); return ok().add("state", r.state); Result res = discardAfter ? discard(name) : ok(); if (res.failed()) return res; if (startAfter) return startOne(name); return res.add("state", r.state); } Settings s; std::string err; Loading @@ -369,6 +389,7 @@ Result stopOne(const std::string &name, int timeout, bool startAfter) { if (s.boot) sig = SIGRTMIN + 3; // systemd's "halt", as nspawn sends it r.stopRequested = true; r.startAfterStop = startAfter; r.discardAfterStop = discardAfter; r.restartAt = 0; if (kill(r.pid, sig) != 0 && errno != ESRCH) return fail(sysErr("kill", errno), 500); r.killAt = time(nullptr) + std::max(timeout, 0); Loading Loading @@ -481,15 +502,7 @@ Result remove(const std::string &name) { unlink((logPath(name) + ".1").c_str()); for (const char *ext : {".exit", ".state", ".layers", ".lease"}) unlink(runFile(name, ext).c_str()); table().erase(name); // its files may be many: out of the way now, deleted in a job std::string dir = containerDir(name); if (!exists(dir)) return ok(); std::string gone = std::string(StateDir) + "/tmp/deleted-" + name + "-" + std::to_string(time(nullptr)); mkdirs(std::string(StateDir) + "/tmp", 0700); if (rename(dir.c_str(), gone.c_str()) != 0) gone = dir; return jobs::run("Deleting the files of %1", "Dateien von %1 werden gelöscht", {name}, [gone] { return removeTree(gone) ? ok() : fail(sysErr(gone, errno), 500); }); return discard(name); } Result logOf(const std::string &name, long long lines) { Loading Loading @@ -658,7 +671,7 @@ bool handles(const std::string &m) { namespace mt = method; return m == mt::ListContainers || m == mt::GetContainer || m == mt::CreateContainer || m == mt::EditContainer || m == mt::DeleteContainer || m == mt::StartContainer || m == mt::StopContainer || m == mt::RestartContainer || m == mt::KillContainer || m == mt::ContainerLog; m == mt::RecreateContainer || m == mt::KillContainer || m == mt::ContainerLog; } Result handle(const sysbus::Message &call) { Loading Loading @@ -686,6 +699,10 @@ Result handle(const sysbus::Message &call) { } if (m == mt::StopContainer) return stopOne(name, (int)number(call, "timeout", 10), false); if (m == mt::RestartContainer) return stopOne(name, (int)number(call, "timeout", 10), true); if (m == mt::RecreateContainer) { bool wasActive = active(table()[name]); return stopOne(name, (int)number(call, "timeout", 10), wasActive, true); } // KillContainer Runtime &r = table()[name]; if (!active(r) || r.pid <= 0) return fail(tr("%1 isn't running", "%1 läuft nicht", {name}), 409); Loading