Skip to content
Draft
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
31 changes: 31 additions & 0 deletions agents/cpp-node-exporter/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
cmake_minimum_required(VERSION 3.16)
project(orcs_cpp_node_exporter VERSION 0.1.0 LANGUAGES CXX)

set(CMAKE_CXX_STANDARD 20)
set(CMAKE_CXX_STANDARD_REQUIRED ON)

add_library(orcs_process STATIC
src/core/process_discovery.cpp
src/core/process_terminator.cpp
)
target_include_directories(orcs_process PUBLIC include)

add_library(orcs_telemetry STATIC
src/core/system_telemetry.cpp
)
target_include_directories(orcs_telemetry PUBLIC include)

add_library(orcs_platform STATIC
src/platform/linux/os_adapter_linux.cpp
src/platform/windows/os_adapter_windows.cpp
src/platform/macos/os_adapter_macos.cpp
)
target_include_directories(orcs_platform PUBLIC include)

add_executable(orcs-node-agent src/main.cpp)
target_link_libraries(orcs-node-agent PRIVATE orcs_process orcs_telemetry orcs_platform)

enable_testing()
add_executable(orcs_cpp_tests tests/smoke_test.cpp)
target_link_libraries(orcs_cpp_tests PRIVATE orcs_process orcs_telemetry orcs_platform)
add_test(NAME orcs_cpp_smoke COMMAND orcs_cpp_tests)
28 changes: 28 additions & 0 deletions agents/cpp-node-exporter/include/orcs/os_adapter.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
#pragma once

#include <string>

namespace orcs {

class OSAdapter {
public:
virtual ~OSAdapter() = default;
virtual std::string platform_name() const = 0;
};

class LinuxAdapter : public OSAdapter {
public:
std::string platform_name() const override;
};

class WindowsAdapter : public OSAdapter {
public:
std::string platform_name() const override;
};

class MacOSAdapter : public OSAdapter {
public:
std::string platform_name() const override;
};

} // namespace orcs
18 changes: 18 additions & 0 deletions agents/cpp-node-exporter/include/orcs/process_discovery.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
#pragma once

#include <string>
#include <vector>

namespace orcs {

struct ProcessInfo {
int pid;
std::string name;
};

class ProcessDiscovery {
public:
std::vector<ProcessInfo> list_by_name(const std::string& process_name) const;
};

} // namespace orcs
10 changes: 10 additions & 0 deletions agents/cpp-node-exporter/include/orcs/process_terminator.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
#pragma once

namespace orcs {

class ProcessTerminator {
public:
bool kill_pid(int pid) const;
};

} // namespace orcs
19 changes: 19 additions & 0 deletions agents/cpp-node-exporter/include/orcs/system_telemetry.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
#pragma once

#include <string>

namespace orcs {

struct TelemetrySnapshot {
std::string os_type;
double cpu_load;
unsigned long long total_mem_bytes;
unsigned long long free_mem_bytes;
};

class SystemTelemetry {
public:
TelemetrySnapshot sample() const;
};

} // namespace orcs
35 changes: 35 additions & 0 deletions agents/cpp-node-exporter/src/core/process_discovery.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
#include "orcs/process_discovery.hpp"

#include <algorithm>
#include <filesystem>
#include <fstream>

namespace orcs {

std::vector<ProcessInfo> ProcessDiscovery::list_by_name(const std::string& process_name) const {
std::vector<ProcessInfo> out;
#ifdef __linux__
for (const auto& entry : std::filesystem::directory_iterator("/proc")) {
if (!entry.is_directory()) {
continue;
}
const auto name = entry.path().filename().string();
if (!std::all_of(name.begin(), name.end(), ::isdigit)) {
continue;
}
std::ifstream cmdline(entry.path() / "comm");
std::string comm;
if (!cmdline.good() || !std::getline(cmdline, comm)) {
continue;
}
if (comm == process_name) {
out.push_back(ProcessInfo{std::stoi(name), comm});
}
}
#else
(void)process_name;
#endif
return out;
}

} // namespace orcs
18 changes: 18 additions & 0 deletions agents/cpp-node-exporter/src/core/process_terminator.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
#include "orcs/process_terminator.hpp"

#ifdef __linux__
#include <signal.h>
#endif

namespace orcs {

bool ProcessTerminator::kill_pid(int pid) const {
#ifdef __linux__
return ::kill(pid, SIGKILL) == 0;
#else
(void)pid;
return false;
#endif
}

} // namespace orcs
34 changes: 34 additions & 0 deletions agents/cpp-node-exporter/src/core/system_telemetry.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
#include "orcs/system_telemetry.hpp"

#include <fstream>
#include <string>

namespace orcs {

TelemetrySnapshot SystemTelemetry::sample() const {
TelemetrySnapshot snapshot{};
#ifdef __linux__
snapshot.os_type = "linux";
snapshot.cpu_load = 0;
std::ifstream meminfo("/proc/meminfo");
std::string key;
unsigned long long value;
std::string unit;
while (meminfo >> key >> value >> unit) {
if (key == "MemTotal:") {
snapshot.total_mem_bytes = value * 1024;
}
if (key == "MemAvailable:") {
snapshot.free_mem_bytes = value * 1024;
}
}
#else
snapshot.os_type = "unknown";
snapshot.cpu_load = 0;
snapshot.total_mem_bytes = 0;
snapshot.free_mem_bytes = 0;
#endif
return snapshot;
}

} // namespace orcs
30 changes: 30 additions & 0 deletions agents/cpp-node-exporter/src/main.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
#include <iostream>
#include <string>
#include <vector>

#include "orcs/os_adapter.hpp"
#include "orcs/process_discovery.hpp"
#include "orcs/process_terminator.hpp"
#include "orcs/system_telemetry.hpp"

int main(int argc, char** argv) {
std::string banned = argc > 1 ? argv[1] : "firefox";

orcs::SystemTelemetry telemetry;
const auto snapshot = telemetry.sample();

orcs::ProcessDiscovery discovery;
const auto matches = discovery.list_by_name(banned);

std::cout << "platform=" << snapshot.os_type << " total_mem=" << snapshot.total_mem_bytes
<< " free_mem=" << snapshot.free_mem_bytes << " matched_processes=" << matches.size()
<< "\n";

orcs::ProcessTerminator terminator;
for (const auto& proc : matches) {
std::cout << "restricted process found: pid=" << proc.pid << " name=" << proc.name << "\n";
(void)terminator;
}

return 0;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
#include "orcs/os_adapter.hpp"

namespace orcs {

std::string LinuxAdapter::platform_name() const { return "linux"; }

} // namespace orcs
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
#include "orcs/os_adapter.hpp"

namespace orcs {

std::string MacOSAdapter::platform_name() const { return "macos"; }

} // namespace orcs
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
#include "orcs/os_adapter.hpp"

namespace orcs {

std::string WindowsAdapter::platform_name() const { return "windows"; }

} // namespace orcs
15 changes: 15 additions & 0 deletions agents/cpp-node-exporter/tests/smoke_test.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
#include <cassert>

#include "orcs/os_adapter.hpp"
#include "orcs/system_telemetry.hpp"

int main() {
orcs::LinuxAdapter adapter;
assert(adapter.platform_name() == "linux");

orcs::SystemTelemetry telemetry;
auto snapshot = telemetry.sample();
assert(!snapshot.os_type.empty());

return 0;
}
8 changes: 8 additions & 0 deletions contracts/MIGRATION_POLICY.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
# ORCS Internal Package Ownership and Versioning

- Core backend logic must live in this repository under `/services` and `/agents`.
- Shared contracts must live under `/contracts` and act as the source of truth.
- No external npm package is allowed for core backend logic.
- Go internal packages are versioned with semantic tags from this repository.
- C++ reusable libraries (`orcs_process`, `orcs_telemetry`, `orcs_platform`) are versioned together with repository releases.
- Contract-breaking changes require a new contract version and compatibility tests before release.
43 changes: 43 additions & 0 deletions contracts/rest-api.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
openapi: 3.0.3
info:
title: ORCS REST Contract
version: 1.0.0
paths:
/auth/register:
post: {}
/auth/login:
post: {}
/auth/currentuser:
get: {}
/auth/logout:
get: {}
/user/getAllUsers:
get: {}
/user/getUser/{id}:
get: {}
/user/updateUser/{id}:
post: {}
/user/deleteUser/{id}:
post: {}
/policy/getPolicies:
get: {}
/policy/getPolicy/{id}:
get: {}
/policy/getRolePolicy/{role}:
get: {}
/policy/getRoleWisePolicy:
get: {}
/policy/getFavoriteProcesses:
get: {}
/policy/setPolicy:
post: {}
/policy/updatePolicy:
post: {}
/policy/updateSinglePolicy:
post: {}
/policy/addSingleProcess:
post: {}
/policy/deletePolicy/{id}:
post: {}
/logs:
get: {}
24 changes: 24 additions & 0 deletions contracts/socket-events.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
{
"listen": {
"CLIENT_AUTH": "clientAuth",
"ADMIN": "admin",
"LOGOUT": "logout",
"DISCONNECT": "disconnect",
"INIT_PERF_DATA": "initPerfData",
"PERF_DATA": "perfData",
"UPDATE_BAN_LIST": "updatedBanList",
"UPDATED_BAN": "updated:Ban",
"NODE_LOGS": "node:logs",
"LOGS": "logs"
},
"emit": {
"LOGS": "logs",
"UPDATED_BAN": "updated:Ban",
"UPDATE_BAN_LIST": "updatedBanList",
"ADMIN": "admin",
"DATA": "data",
"INIT_PERF_DATA": "initPerfData",
"PERF_DATA": "perfData",
"NODE_LOGS": "node:logs"
}
}
Loading