Skip to content

Commit

Permalink
feat: Address comments and improve the code
Browse files Browse the repository at this point in the history
  • Loading branch information
lchico committed Jan 25, 2025
1 parent 0f79501 commit 3ba8fa9
Show file tree
Hide file tree
Showing 12 changed files with 130 additions and 96 deletions.
30 changes: 30 additions & 0 deletions docs/ref/commands.md
Original file line number Diff line number Diff line change
Expand Up @@ -63,3 +63,33 @@ Executing this command triggers a reload of the configuration and modules to ens
}
}
```


## Restart Handler

The restart handler is responsible for restarting the agent. This command does not require any arguments.

Executing this command triggers a restart, which can be processed in two ways:

- If the service was started by systemd, it will use the same command to restart the agent.
- If it was called manually, it will use the same command with the same arguments that were used to call it.

```json
{
"action":
{
"args":
{},
"name": "restart",
"version": "5.0.0"
},
"source": "Users/Services",
"document_id": "A8-62pMBBmC6Jrvqj9kW",
"user": "Management API",
"target":
{
"id": "d5b250c4-dfa1-4d94-827f-9f99210dbe6c",
"type": "agent"
}
}
```
4 changes: 2 additions & 2 deletions src/agent/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ add_subdirectory(configuration_parser)
add_subdirectory(multitype_queue)
add_subdirectory(persistence)
add_subdirectory(task_manager)
add_subdirectory(restart)
add_subdirectory(restart_handler)

find_package(OpenSSL REQUIRED)
find_package(Boost REQUIRED COMPONENTS asio beast system program_options)
Expand Down Expand Up @@ -66,7 +66,7 @@ target_link_libraries(Agent
MultiTypeQueue
ModuleManager
Boost::asio
Restart
RestartHandler
sysinfo
PRIVATE
OpenSSL::SSL
Expand Down
13 changes: 11 additions & 2 deletions src/agent/command_handler/src/command_handler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -135,8 +135,17 @@ namespace command_handler
{
for (auto& cmd : cmds.value())
{
cmd.ExecutionResult.ErrorCode = module_command::Status::FAILURE;
cmd.ExecutionResult.Message = "Agent stopped during execution";
if (cmd.Command == module_command::RESTART_COMMAND)
{
LogInfo("Agent restarted successfully");
cmd.ExecutionResult.ErrorCode = module_command::Status::SUCCESS;
cmd.ExecutionResult.Message = "Agent restarted successfully";
}
else
{
cmd.ExecutionResult.ErrorCode = module_command::Status::FAILURE;
cmd.ExecutionResult.Message = "Agent stopped during execution";
}
reportCommandResult(cmd);
m_commandStore->UpdateCommand(cmd);
}
Expand Down
28 changes: 0 additions & 28 deletions src/agent/restart/CMakeLists.txt

This file was deleted.

19 changes: 0 additions & 19 deletions src/agent/restart/include/restart.hpp

This file was deleted.

27 changes: 27 additions & 0 deletions src/agent/restart_handler/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
cmake_minimum_required(VERSION 3.22)

project(RestartHandler)

include(../../cmake/CommonSettings.cmake)
set_common_settings()

find_package(Boost REQUIRED COMPONENTS asio)


if(WIN32)
set(SOURCES src/restart_handler_win.cpp)
else()
set(SOURCES src/restart_handler_unix.cpp)
endif()

add_library(RestartHandler ${SOURCES})
target_include_directories(RestartHandler PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/include)
target_link_libraries(RestartHandler PUBLIC Boost::asio CommandEntry PRIVATE Logger)

include(../../cmake/ConfigureTarget.cmake)
configure_target(RestartHandler)

# if(BUILD_TESTS)
# enable_testing()
# add_subdirectory(tests)
# endif()
35 changes: 35 additions & 0 deletions src/agent/restart_handler/include/restart_handler.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
#pragma once
#include <command_entry.hpp>

#include <boost/asio/awaitable.hpp>

#include <vector>

namespace restart_handler
{
/// @brief Class for handling service restarts.
class RestartHandler
{
public:
/// @brief Command-line arguments for the service.
static std::vector<char*> cmd_line;
explicit RestartHandler();

/// @brief Stores the command-line arguments passed to the agent.
/// @param argc Number of arguments.
/// @param argv Array of arguments.
static void SetCommandLineArguments(int argc, char* argv[])
{
for (int i = 0; i < argc; ++i)
{
// NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic)
RestartHandler::cmd_line.emplace_back(argv[i]);
}
RestartHandler::cmd_line.emplace_back(nullptr);
}

/// @brief Executes the restart command.
/// @return Result of the restart command execution.
static boost::asio::awaitable<module_command::CommandExecutionResult> RestartCommand();
};
} // namespace restart_handler
Original file line number Diff line number Diff line change
@@ -1,30 +1,14 @@
#include "restart_unix.hpp"
#include "restart_handler_unix.hpp"
#include <fstream>
#include <logger.hpp>

namespace restart
{
std::vector<char*> GetCommandLineArgs()
{
std::vector<char*> args;
std::ifstream cmdline_file("/proc/self/cmdline");

if (!cmdline_file)
{
LogError("Failed to open /proc/self/cmdline.");
return args;
}
#include <chrono>
#include <thread>

std::string arg;
while (getline(cmdline_file, arg, '\0'))
{
args.push_back(strdup(arg.c_str()));
}

args.push_back(nullptr);
namespace restart_handler
{

return args;
}
std::vector<char*> RestartHandler::cmd_line;

bool UsingSystemctl()
{
Expand All @@ -49,7 +33,7 @@ namespace restart

void StopAgent()
{
const int timeout = 30; // Timeout duration (in seconds) for killing the agent child process
const int timeout = 30;
time_t start_time = time(nullptr); // Record the start time to track the timeout duration

pid_t pid = getppid();
Expand Down Expand Up @@ -88,10 +72,9 @@ namespace restart
// Child process
StopAgent();

std::vector<char*> args = GetCommandLineArgs();
LogInfo("Starting wazuh agent in a new process.");

if (execve(args[0], args.data(), nullptr) == -1)
if (execve(RestartHandler::cmd_line[0], RestartHandler::cmd_line.data(), nullptr) == -1)
{
LogError("Failed to spawn new Wazuh agent process.");
}
Expand All @@ -101,7 +84,7 @@ namespace restart
"Pending restart execution"};
}

boost::asio::awaitable<module_command::CommandExecutionResult> Restart::HandleRestartCommand()
boost::asio::awaitable<module_command::CommandExecutionResult> RestartHandler::RestartCommand()
{

if (UsingSystemctl())
Expand All @@ -114,4 +97,4 @@ namespace restart
}
}

} // namespace restart
} // namespace restart_handler
Original file line number Diff line number Diff line change
@@ -1,23 +1,16 @@
#pragma once
#include <boost/asio/awaitable.hpp>
#include <command_entry.hpp>
#include <restart.hpp>
#include <string>
#include <restart_handler.hpp>
#include <vector>

namespace restart
namespace restart_handler
{

/// @brief Retrieves command-line arguments for `execve()`.
///
/// Parses `/proc/self/cmdline` to extract arguments.
/// @return A vector of null-terminated strings.
std::vector<char*> GetCommandLineArgs();

/// @brief Checks if systemctl is available and running as a systemd service.
///
/// Determines if systemctl can be used in the current environment.
/// @return Returns true if systemctl is available and running as a systemd service, otherwise returns false.
/// @return true if systemctl is available and running as a systemd service, otherwise returns false.
bool UsingSystemctl();

/// @brief Stops the agent by terminating the child process.
Expand All @@ -41,4 +34,4 @@ namespace restart
/// @return A boost::asio::awaitable containing the result of the command execution.
boost::asio::awaitable<module_command::CommandExecutionResult> RestartWithSystemd();

} // namespace restart
} // namespace restart_handler
Original file line number Diff line number Diff line change
@@ -1,15 +1,17 @@
#include <boost/asio/awaitable.hpp>
#include <logger.hpp>
#include <restart.hpp>
#include <restart_handler.hpp>

namespace restart
namespace restart_handler
{

boost::asio::awaitable<module_command::CommandExecutionResult> Restart::HandleRestartCommand()
std::vector<char*> RestartHandler::cmd_line;

boost::asio::awaitable<module_command::CommandExecutionResult> RestartHandler::RestartCommand()
{
// TODO
co_return module_command::CommandExecutionResult {module_command::Status::FAILURE,
"Restart is not implemented yet"};
"RestartHandler is not implemented yet"};
}

} // namespace restart
} // namespace restart_handler
4 changes: 2 additions & 2 deletions src/agent/src/agent.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
#include <message.hpp>
#include <message_queue_utils.hpp>
#include <multitype_queue.hpp>
#include <restart.hpp>
#include <restart_handler.hpp>

#include <filesystem>
#include <memory>
Expand Down Expand Up @@ -156,7 +156,7 @@ void Agent::Run()
else if (cmd.Module == module_command::RESTART_MODULE)
{
LogInfo("Restart: Initiating restart");
return restart::Restart::HandleRestartCommand();
return restart_handler::RestartHandler::RestartCommand();
}
return DispatchCommand(cmd, m_moduleManager.GetModule(cmd.Module), m_messageQueue);
}),
Expand Down
2 changes: 2 additions & 0 deletions src/agent/src/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

#include <boost/program_options.hpp>
#include <iostream>
#include <restart_handler.hpp>
#include <string>

namespace program_options = boost::program_options;
Expand Down Expand Up @@ -94,6 +95,7 @@ int main(int argc, char* argv[])
}
else
{
restart_handler::RestartHandler::SetCommandLineArguments(argc, argv);
StartAgent(validOptions.count(OPT_CONFIG_FILE) ? validOptions[OPT_CONFIG_FILE].as<std::string>() : "");
}

Expand Down

0 comments on commit 3ba8fa9

Please sign in to comment.