Skip to content

Commit

Permalink
Merge pull request #414 from bareos/dev/franku/master/messages_resource
Browse files Browse the repository at this point in the history
dev/franku/master/messages resource
  • Loading branch information
franku committed Feb 10, 2020
2 parents 29ac88a + 04e108a commit cf046c8
Show file tree
Hide file tree
Showing 29 changed files with 476 additions and 29 deletions.
4 changes: 3 additions & 1 deletion core/src/dird/dird.cc
Expand Up @@ -157,7 +157,9 @@ static void ReloadJobEndCb(JobControlRecord* jcr, void* ctx)
* access to the database. If the pointer is not defined (other daemons), then
* writing the database is disabled.
*/
static bool DirDbLogInsert(JobControlRecord* jcr, utime_t mtime, char* msg)
static bool DirDbLogInsert(JobControlRecord* jcr,
utime_t mtime,
const char* msg)
{
int length;
char ed1[50];
Expand Down
27 changes: 16 additions & 11 deletions core/src/lib/message.cc
Expand Up @@ -3,7 +3,7 @@
Copyright (C) 2000-2012 Free Software Foundation Europe e.V.
Copyright (C) 2011-2012 Planets Communications B.V.
Copyright (C) 2013-2019 Bareos GmbH & Co. KG
Copyright (C) 2013-2020 Bareos GmbH & Co. KG
This program is Free Software; you can redistribute it and/or
modify it under the terms of version three of the GNU Affero General Public
Expand Down Expand Up @@ -43,8 +43,6 @@
#include "lib/message_queue_item.h"
#include "lib/thread_specific_data.h"

static db_log_insert_func p_db_log_insert = NULL;

// globals
const char* working_directory = NULL; /* working directory path stored here */
const char* assert_msg = (char*)NULL; /* ASSERT2 error message */
Expand All @@ -70,7 +68,7 @@ job_code_callback_t message_job_code_callback = NULL; // Only used by director
static MessagesResource* daemon_msgs; /* Global messages */
static char* catalog_db = NULL; /* Database type */
static const char* log_timestamp_format = "%d-%b %H:%M";
static void (*message_callback)(int type, char* msg) = NULL;
static void (*message_callback)(int type, const char* msg) = NULL;
static FILE* trace_fd = NULL;
#if defined(HAVE_WIN32)
static bool trace = true;
Expand Down Expand Up @@ -135,7 +133,7 @@ static void DeliveryError(const char* fmt, ...)
FreeMemory(pool_buf);
}

void RegisterMessageCallback(void msg_callback(int type, char* msg))
void RegisterMessageCallback(void msg_callback(int type, const char* msg))
{
message_callback = msg_callback;
}
Expand Down Expand Up @@ -597,7 +595,7 @@ static inline bool SetSyslogFacility(JobControlRecord* jcr,
* Split the output for syslog (it converts \n to ' ' and is
* limited to 1024 characters per syslog message
*/
static inline void SendToSyslog(int mode, const char* msg)
static void SendToSyslog_(int mode, const char* msg)
{
int len;
char buf[1024];
Expand All @@ -616,10 +614,19 @@ static inline void SendToSyslog(int mode, const char* msg)
}
}

static SyslogCallback SendToSyslog{SendToSyslog_};
void RegisterSyslogCallback(SyslogCallback c) { SendToSyslog = c; }

static DbLogInsertCallback SendToDbLog = NULL;
void SetDbLogInsertCallback(DbLogInsertCallback f) { SendToDbLog = f; }

/*
* Handle sending the message to the appropriate place
*/
void DispatchMessage(JobControlRecord* jcr, int type, utime_t mtime, char* msg)
void DispatchMessage(JobControlRecord* jcr,
int type,
utime_t mtime,
const char* msg)
{
char dt[MAX_TIME_LENGTH];
POOLMEM* mcmd;
Expand Down Expand Up @@ -734,8 +741,8 @@ void DispatchMessage(JobControlRecord* jcr, int type, utime_t mtime, char* msg)
case MessageDestinationCode::kCatalog:
if (!jcr || !jcr->db) { break; }

if (p_db_log_insert) {
if (!p_db_log_insert(jcr, mtime, msg)) {
if (SendToDbLog) {
if (!SendToDbLog(jcr, mtime, msg)) {
DeliveryError(
_("Msg delivery error: Unable to store data in database.\n"));
}
Expand Down Expand Up @@ -1675,5 +1682,3 @@ void SetLogTimestampFormat(const char* format)
{
log_timestamp_format = format;
}

void SetDbLogInsertCallback(db_log_insert_func f) { p_db_log_insert = f; }
18 changes: 12 additions & 6 deletions core/src/lib/message.h
Expand Up @@ -37,6 +37,7 @@
#include "lib/message_destination_info.h"

#include <string>
#include <functional>

class JobControlRecord;

Expand All @@ -50,10 +51,9 @@ bool GetTrace(void);
const char* get_basename(const char* pathname);
void SetLogTimestampFormat(const char* format);

typedef bool (*db_log_insert_func)(JobControlRecord* jcr,
utime_t mtime,
char* msg);
void SetDbLogInsertCallback(db_log_insert_func f);
using DbLogInsertCallback =
std::function<bool(JobControlRecord* jcr, utime_t mtime, const char* msg)>;
void SetDbLogInsertCallback(DbLogInsertCallback f);

class MessagesResource;

Expand All @@ -77,7 +77,10 @@ void InitMsg(JobControlRecord* jcr,
void TermMsg(void);
void CloseMsg(JobControlRecord* jcr);
void Jmsg(JobControlRecord* jcr, int type, utime_t mtime, const char* fmt, ...);
void DispatchMessage(JobControlRecord* jcr, int type, utime_t mtime, char* buf);
void DispatchMessage(JobControlRecord* jcr,
int type,
utime_t mtime,
const char* buf);
void InitConsoleMsg(const char* wd);
void DequeueMessages(JobControlRecord* jcr);
void SetTrace(int trace_flag);
Expand All @@ -87,6 +90,9 @@ bool GetHangup(void);
void SetTimestamp(int timestamp_flag);
bool GetTimestamp(void);
void SetDbType(const char* name);
void RegisterMessageCallback(void msg_callback(int type, char* msg));
void RegisterMessageCallback(void msg_callback(int type, const char* msg));

using SyslogCallback = std::function<void(int mode, const char* msg)>;
void RegisterSyslogCallback(SyslogCallback c);

#endif /* BAREOS_LIB_MESSAGE_H_ */
8 changes: 4 additions & 4 deletions core/src/lib/res.cc
Expand Up @@ -313,14 +313,14 @@ void ConfigurationParser::StoreMsgs(LEX* lc,
token = LexGetToken(lc, BCT_SKIP_EOL);

ScanTypes(lc, message_resource,
static_cast<MessageDestinationCode>(item->code), dest, NULL,
NULL);
static_cast<MessageDestinationCode>(item->code), dest,
std::string(), std::string());
FreePoolMemory(dest);
Dmsg0(900, "done with dest codes\n");
} else {
ScanTypes(lc, message_resource,
static_cast<MessageDestinationCode>(item->code), NULL, NULL,
NULL);
static_cast<MessageDestinationCode>(item->code),
std::string(), std::string(), std::string());
}
break;
}
Expand Down
6 changes: 6 additions & 0 deletions core/src/lib/util.cc
Expand Up @@ -1104,3 +1104,9 @@ void SortCaseInsensitive(std::vector<std::string>& v)
return x < y;
});
}

std::string getenv_std_string(std::string env_var)
{
const char* v = (std::getenv(env_var.c_str()));
return v ? std::string(v) : std::string();
}
1 change: 1 addition & 0 deletions core/src/lib/util.h
Expand Up @@ -67,5 +67,6 @@ POOLMEM* edit_job_codes(JobControlRecord* jcr,
void SetWorkingDirectory(const char* wd);
const char* last_path_separator(const char* str);
void SortCaseInsensitive(std::vector<std::string>& v);
std::string getenv_std_string(std::string env_var);

#endif // BAREOS_LIB_UTIL_H_
17 changes: 17 additions & 0 deletions core/src/tests/CMakeLists.txt
Expand Up @@ -392,3 +392,20 @@ if(NOT client-only)
${GTEST_MAIN_LIBRARIES}
)
endif() # NOT client-only

if(NOT client-only)
bareos_add_test(
messages_resource
LINK_LIBRARIES
bareos
dird_objects
bareosfind
bareoscats
bareossql
$<$<BOOL:HAVE_PAM>:${PAM_LIBRARIES}>
${LMDB_LIBS}
${GTEST_LIBRARIES}
${GTEST_MAIN_LIBRARIES}
SKIP_GTEST
)
endif() # NOT client-only
6 changes: 0 additions & 6 deletions core/src/tests/catalog.cc
Expand Up @@ -67,12 +67,6 @@ class CatalogTest : public ::testing::Test {
void TearDown() override;
};

static std::string getenv_std_string(std::string env_var)
{
const char* v = (std::getenv(env_var.c_str()));
return v ? std::string(v) : std::string();
}

void CatalogTest::SetUp()
{
InitMsg(nullptr, nullptr);
Expand Down
155 changes: 155 additions & 0 deletions core/src/tests/messages_resource.cc
@@ -0,0 +1,155 @@
/*
BAREOS® - Backup Archiving REcovery Open Sourced
Copyright (C) 2020-2020 Bareos GmbH & Co. KG
This program is Free Software; you can redistribute it and/or
modify it under the terms of version three of the GNU Affero General Public
License as published by the Free Software Foundation and included
in the file LICENSE.
This program is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301, USA.
*/

#if defined(HAVE_MINGW)
#include "include/bareos.h"
#include "gtest/gtest.h"
#else
#include "gtest/gtest.h"
#include "include/bareos.h"
#endif

#include "dird/dird_conf.h"
#include "dird/dird_globals.h"
#include "dird/get_database_connection.h"
#include "dird/job.h"
#include "dird/jcr_private.h"
#include "lib/messages_resource.h"
#include "lib/parse_conf.h"
#include "lib/util.h"

#include <memory>
#include <vector>

using directordaemon::InitDirConfig;
using directordaemon::my_config;

namespace directordaemon {
bool DoReloadConfig() { return false; }
} // namespace directordaemon

class LogFiles {
public:
static FILE* Open(const std::string& dir, std::string filename)
{
std::string fullpath = dir + "/" + filename;
FILE* fp = fopen(fullpath.c_str(), "w");
if (!fp) {
std::cout << "Could not open syslog file " << fullpath << std::endl;
return nullptr;
}
list_of_filepointers.insert(std::pair<std::string, FILE*>(filename, fp));
return fp;
}

LogFiles() = default;

~LogFiles()
{
for (auto fp : list_of_filepointers) {
fflush(fp.second);
fclose(fp.second);
}
list_of_filepointers.clear();
}

static std::map<std::string, FILE*> list_of_filepointers;
};

std::map<std::string, FILE*> LogFiles::list_of_filepointers;

static void SyslogCallback_(int mode, const char* msg)
{
try {
FILE* fp = LogFiles::list_of_filepointers.at("syslog");
// fake-write a syslog entry
if (fp) { fputs(msg, fp); }
} catch (const std::out_of_range& e) {
std::cout << "Could not find <syslog> filepointer";
}
}

static bool DbLogInsertCallback_(JobControlRecord* jcr,
utime_t mtime,
const char* msg)
{
try {
FILE* fp = LogFiles::list_of_filepointers.at("dblog");
// fake-write a db log entry
if (fp) { fputs(msg, fp); }
} catch (const std::out_of_range& e) {
std::cout << "Could not find <dblog> filepointer";
}

return true;
}

TEST(messages_resource, send_message_to_all_configured_destinations)
{
std::string config_dir = getenv_std_string("BAREOS_CONFIG_DIR");
std::string working_dir = getenv_std_string("BAREOS_WORKING_DIR");
std::string log_dir = getenv_std_string("BAREOS_LOG_DIR");
std::string backend_dir = getenv_std_string("backenddir");

ASSERT_FALSE(config_dir.empty());
ASSERT_FALSE(working_dir.empty());
ASSERT_FALSE(log_dir.empty());
ASSERT_FALSE(backend_dir.empty());

std::string regress_debug = getenv_std_string("REGRESS_DEBUG");

if (!regress_debug.empty()) {
if (regress_debug == "1") { debug_level = 200; }
}

SetWorkingDirectory(working_dir.c_str());
InitConsoleMsg(log_dir.c_str());

// parse config
std::unique_ptr<ConfigurationParser> p{
InitDirConfig(config_dir.c_str(), M_ERROR_TERM)};
directordaemon::my_config = p.get();
ASSERT_TRUE(directordaemon::my_config->ParseConfig());

// get message resource
MessagesResource* messages =
dynamic_cast<MessagesResource*>(directordaemon::my_config->GetResWithName(
directordaemon::R_MSGS, "Standard"));
ASSERT_NE(messages, nullptr);

// initialize message handler
InitMsg(NULL, messages);

// this object cleans up all files at exit
LogFiles cleanup;

// init syslog mock-up
ASSERT_NE(LogFiles::Open(log_dir, "syslog"), nullptr);
RegisterSyslogCallback(SyslogCallback_);

// init catalog mock-up
JobControlRecord jcr;
jcr.db = reinterpret_cast<BareosDb*>(0xdeadbeef);
ASSERT_NE(LogFiles::Open(log_dir, "dblog"), nullptr);
SetDbLogInsertCallback(DbLogInsertCallback_);

DispatchMessage(&jcr, M_ERROR, 0, "\n!!!This is a test error message!!!\n");
}
1 change: 1 addition & 0 deletions systemtests/CMakeLists.txt
Expand Up @@ -616,6 +616,7 @@ set(SYSTEM_TESTS
reload-works-on-adding-second-director-resource
reload-works-on-adding-client-resource
backup-bareos-client-initiated-test
messages-resource
)

set(SYSTEM_TESTS_DISABLED # initially empty
Expand Down
2 changes: 1 addition & 1 deletion systemtests/environment.in
Expand Up @@ -12,7 +12,6 @@ current_test_directory=${PROJECT_BINARY_DIR}/tests/@TEST_NAME@
conf=${current_test_directory}/etc/bareos
export confdir=${conf}
configs=${conf}
BAREOS_CONFIG_DIR=${conf}

export config_directory_dir_additional_test_config=@config_directory_dir_additional_test_config@

Expand Down Expand Up @@ -44,6 +43,7 @@ export fd_password=@fd_password@
# exported variables used by start/stop and other bareos scripts
# to override the defaults
export BAREOS_CONFIG_DIR=${conf}
export BAREOS_LOG_DIR=${logdir}
export BAREOS_SCRIPTS_DIR=${scripts}
export BAREOS_SBIN_DIR=${sbin}
export BAREOS_WORKING_DIR=${working}
Expand Down
@@ -0,0 +1,8 @@
Catalog {
Name = MyCatalog
#dbdriver = "@DEFAULT_DB_TYPE@"
dbdriver = "XXX_REPLACE_WITH_DATABASE_DRIVER_XXX"
dbname = "@db_name@"
dbuser = "@db_user@"
dbpassword = "@db_password@"
}

0 comments on commit cf046c8

Please sign in to comment.