Commit 39fd092f authored by jan.koester's avatar jan.koester
Browse files

test

parent 518f9e39
Loading
Loading
Loading
Loading
+7 −0
Changes for include/sysbus/client.h: 7 added lines, 0 removed lines.
Original line number Diff line number Diff line
@@ -31,6 +31,11 @@ constexpr const char *ListUnits = "ListUnits";
constexpr const char *Reload = "Reload";
constexpr const char *Subscribe = "Subscribe";

// Power: stop all services, sync, unmount, reboot or power off -- after
// a second, so the caller can still pass its reply on. Root only.
constexpr const char *Reboot = "Reboot";
constexpr const char *PowerOff = "PowerOff";

// Network interfaces. Configurations are .network files in
// /etc/syslite/network; Create/Edit/Delete change only the files, Start,
// Reload and Restart apply them.
@@ -138,6 +143,8 @@ public:
    bool enableUnit(const std::string &name);
    bool disableUnit(const std::string &name);
    bool reload();
    bool reboot();    // the system goes down about a second after the reply
    bool powerOff();
    bool getUnit(const std::string &name, UnitInfo &out);
    std::vector<UnitInfo> listUnits();

+8 −0
Changes for src/sysbus/client.cpp: 8 added lines, 0 removed lines.
Original line number Diff line number Diff line
@@ -284,6 +284,14 @@ bool Client::startInterface(const std::string &n) { return checkedCall(method::S
bool Client::stopInterface(const std::string &n) { return checkedCall(method::StopInterface, {{"interface", n}}); }
bool Client::restartInterface(const std::string &n) { return checkedCall(method::RestartInterface, {{"interface", n}}); }

bool Client::reboot() {
    return checkedCall(method::Reboot, {});
}

bool Client::powerOff() {
    return checkedCall(method::PowerOff, {});
}

bool Client::reloadInterface(const std::string &n) {
    std::vector<std::pair<std::string, std::string>> a;
    if (!n.empty()) a.emplace_back("interface", n);
+18 −1
Changes for src/syslite.cpp: 18 added lines, 1 removed line.
Original line number Diff line number Diff line
@@ -218,13 +218,24 @@ namespace syslite {
        }

        bool known = op == m::StartUnit || op == m::StopUnit || op == m::RestartUnit ||
                     op == m::EnableUnit || op == m::DisableUnit || op == m::Reload;
                     op == m::EnableUnit || op == m::DisableUnit || op == m::Reload ||
                     op == m::Reboot || op == m::PowerOff;
        if (!known) return sysbus::Message::error(call, err::UnknownMethod, "unknown method " + op);

        // changes: root only
        if (peer.uid != 0)
            return sysbus::Message::error(call, err::AccessDenied, op + " needs root");

        if (op == m::Reboot || op == m::PowerOff) {
            // after a second: the caller (systemctl, webctl, ...) still
            // gets to pass its reply on before its service is stopped
            _powerRequest = op == m::Reboot ? 2 : 1;
            _powerAt = std::chrono::steady_clock::now() + std::chrono::seconds(1);
            std::cout << "[syslite] " << (op == m::Reboot ? "Reboot" : "Power off")
                      << " requested over sysbus (uid " << peer.uid << ")" << std::endl;
            return sysbus::Message::reply(call);
        }

        if (op == m::Reload) {
            std::cout << "[syslite] Reloading unit files" << std::endl;
            _services.reload(unitDirs());
@@ -460,6 +471,12 @@ namespace syslite {

            emitStateChanges();

            if (_powerRequest && std::chrono::steady_clock::now() >= _powerAt) {
                if (_powerRequest == 2) reboot();
                else shutdown();
                _powerRequest = 0;
            }

            // Serve sysbus for up to 200ms (also the loop's pacing)
            _bus.poll(200);
        }
+6 −0
Changes for src/syslite.h: 6 added lines, 0 removed lines.
Original line number Diff line number Diff line
@@ -7,6 +7,7 @@

#include <string>
#include <atomic>
#include <chrono>

namespace syslite {

@@ -56,6 +57,11 @@ namespace syslite {
        BusServer      _bus;
        std::map<std::string, std::pair<ServiceState, pid_t>> _lastStates;

        // Reboot/PowerOff over sysbus: 0 none, 1 power off, 2 reboot;
        // carried out once _powerAt has passed
        int _powerRequest = 0;
        std::chrono::steady_clock::time_point _powerAt;

        std::string _hostname;
        std::string _unitDir;
        std::string _defaultTarget;
+9 −2
Changes for src/syslitectl.cpp: 9 added lines, 2 removed lines.
Original line number Diff line number Diff line
@@ -34,7 +34,9 @@ void usage(const char *prog) {
        << "  disable [--now] UNIT...   Don't start units at boot\n"
        << "  is-active UNIT...         Exit 0 if all units are running\n"
        << "  is-enabled UNIT...        Exit 0 if all units are enabled\n"
        << "  daemon-reload             Re-read unit files\n\n"
        << "  daemon-reload             Re-read unit files\n"
        << "  reboot                    Stop all services and reboot\n"
        << "  poweroff                  Stop all services and power off\n\n"
        << "Network interfaces:\n"
        << "  interfaces                          List interfaces\n"
        << "  interface status IFACE              Show state and configuration\n"
@@ -243,7 +245,7 @@ int main(int argc, char **argv) {
    }
    if (cmd.empty()) cmd = "list-units";

    bool needsUnits = cmd != "list-units" && cmd != "daemon-reload";
    bool needsUnits = cmd != "list-units" && cmd != "daemon-reload" && cmd != "reboot" && cmd != "poweroff";
    if (needsUnits && units.empty()) {
        std::cerr << "Too few arguments: " << cmd << " needs a unit name.\n";
        return 1;
@@ -286,6 +288,11 @@ int main(int argc, char **argv) {
        if (!bus.reload()) { std::cerr << "Failed to reload: " << bus.lastError() << "\n"; return 1; }
        return 0;
    }
    if (cmd == "reboot" || cmd == "poweroff") {
        bool ok = cmd == "reboot" ? bus.reboot() : bus.powerOff();
        if (!ok) { std::cerr << "Failed to " << cmd << ": " << bus.lastError() << "\n"; return 1; }
        return 0;
    }

    int rc = 0;
    for (auto &u : units) {