Skip to content

Commit

Permalink
Implement config object sync
Browse files Browse the repository at this point in the history
Adds object version.

refs #9927
  • Loading branch information
gunnarbeutner authored and Michael Friedrich committed Sep 17, 2015
1 parent 1d1d2ce commit 6fa58a5
Show file tree
Hide file tree
Showing 32 changed files with 367 additions and 221 deletions.
6 changes: 3 additions & 3 deletions icinga-app/icinga.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -321,7 +321,7 @@ int Main(void)

std::cout << appName << " " << "- The Icinga 2 network monitoring daemon (version: "
<< ConsoleColorTag(vm.count("version") ? Console_ForegroundRed : Console_Normal)
<< Application::GetVersion()
<< Application::GetAppVersion()
#ifdef I2_DEBUG
<< "; debug"
#endif /* I2_DEBUG */
Expand Down Expand Up @@ -384,10 +384,10 @@ int Main(void)
Logger::DisableTimestamp(true);
#ifndef _WIN32
if (command->GetImpersonationLevel() == ImpersonateRoot) {
if (getuid() != 0) {
/*if (getuid() != 0) {
Log(LogCritical, "cli", "This command must be run as root.");
return 0;
}
}*/
} else if (command && command->GetImpersonationLevel() == ImpersonateIcinga) {
String group = Application::GetRunAsGroup();
String user = Application::GetRunAsUser();
Expand Down
2 changes: 1 addition & 1 deletion lib/base/application-version.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@

using namespace icinga;

String Application::GetVersion(void)
String Application::GetAppVersion(void)
{
return VERSION;
}
Expand Down
2 changes: 1 addition & 1 deletion lib/base/application.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -591,7 +591,7 @@ void Application::DisplayInfoMessage(std::ostream& os, bool skipVersion)
os << "Application information:" << "\n";

if (!skipVersion)
os << " Application version: " << GetVersion() << "\n";
os << " Application version: " << GetAppVersion() << "\n";

os << " Installation root: " << GetPrefixDir() << "\n"
<< " Sysconf directory: " << GetSysconfDir() << "\n"
Expand Down
2 changes: 1 addition & 1 deletion lib/base/application.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -129,7 +129,7 @@ class I2_BASE_API Application : public ObjectImpl<Application> {

static ThreadPool& GetTP(void);

static String GetVersion(void);
static String GetAppVersion(void);

static double GetStartTime(void);
static void SetStartTime(double ts);
Expand Down
1 change: 1 addition & 0 deletions lib/base/configobject.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -184,6 +184,7 @@ void ConfigObject::ModifyAttribute(const String& attr, const Value& value)
ValidateField(fid, newValue, utils);

SetField(fid, newValue);
SetVersion(GetVersion() + 1);

if (updated_original_attributes)
NotifyOriginalAttributes();
Expand Down
3 changes: 3 additions & 0 deletions lib/base/configobject.ti
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,9 @@ abstract class ConfigObject : ConfigObjectBase

[protected] bool state_loaded;
Dictionary::Ptr original_attributes;
[state] int version {
default {{{ return 1; }}}
};
};

}
2 changes: 1 addition & 1 deletion lib/cli/consolecommand.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -186,7 +186,7 @@ int ConsoleCommand::Run(const po::variables_map& vm, const std::vector<std::stri
scriptFrame.Sandboxed = true;
}

std::cout << "Icinga (version: " << Application::GetVersion() << ")\n";
std::cout << "Icinga (version: " << Application::GetAppVersion() << ")\n";

while (std::cin.good()) {
String fileName = "<" + Convert::ToString(next_line) + ">";
Expand Down
2 changes: 1 addition & 1 deletion lib/cli/daemoncommand.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -209,7 +209,7 @@ int DaemonCommand::Run(const po::variables_map& vm, const std::vector<std::strin
Logger::DisableTimestamp(false);

Log(LogInformation, "cli")
<< "Icinga application loader (version: " << Application::GetVersion()
<< "Icinga application loader (version: " << Application::GetAppVersion()
#ifdef I2_DEBUG
<< "; debug"
#endif /* I2_DEBUG */
Expand Down
2 changes: 1 addition & 1 deletion lib/cli/troubleshootcommand.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -148,7 +148,7 @@ bool TroubleshootCommand::GeneralInfo(InfoLog& log, const boost::program_options

//Application::DisplayInfoMessage() but formatted
InfoLogLine(log)
<< "\tApplication version: " << Application::GetVersion() << '\n'
<< "\tApplication version: " << Application::GetAppVersion() << '\n'
<< "\tInstallation root: " << Application::GetPrefixDir() << '\n'
<< "\tSysconf directory: " << Application::GetSysconfDir() << '\n'
<< "\tRun directory: " << Application::GetRunDir() << '\n'
Expand Down
2 changes: 1 addition & 1 deletion lib/compat/statusdatawriter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -800,7 +800,7 @@ void StatusDataWriter::StatusTimerHandler(void)

statusfp << "info {" "\n"
"\t" "created=" << Utility::GetTime() << "\n"
"\t" "version=" << Application::GetVersion() << "\n"
"\t" "version=" << Application::GetAppVersion() << "\n"
"\t" "}" "\n"
"\n";

Expand Down
9 changes: 7 additions & 2 deletions lib/config/configitem.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,11 @@ Dictionary::Ptr ConfigItem::GetScope(void) const
return m_Scope;
}

ConfigObject::Ptr ConfigItem::GetObject(void) const
{
return m_Object;
}

/**
* Retrieves the expression list for the configuration item.
*
Expand All @@ -140,7 +145,7 @@ class DefaultValidationUtils : public ValidationUtils
public:
virtual bool ValidateName(const String& type, const String& name) const override
{
return ConfigItem::GetObject(type, name) != ConfigItem::Ptr();
return ConfigItem::GetByTypeAndName(type, name) != ConfigItem::Ptr();
}
};

Expand Down Expand Up @@ -302,7 +307,7 @@ void ConfigItem::Unregister(void)
* @param name The name of the ConfigItem that is to be looked up.
* @returns The configuration item.
*/
ConfigItem::Ptr ConfigItem::GetObject(const String& type, const String& name)
ConfigItem::Ptr ConfigItem::GetByTypeAndName(const String& type, const String& name)
{
boost::mutex::scoped_lock lock(m_Mutex);

Expand Down
4 changes: 3 additions & 1 deletion lib/config/configitem.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,9 @@ class I2_CONFIG_API ConfigItem : public Object {
DebugInfo GetDebugInfo(void) const;
Dictionary::Ptr GetScope(void) const;

static ConfigItem::Ptr GetObject(const String& type,
ConfigObject::Ptr GetObject(void) const;

static ConfigItem::Ptr GetByTypeAndName(const String& type,
const String& name);

static bool CommitItems(WorkQueue& upq);
Expand Down
148 changes: 73 additions & 75 deletions lib/config/configwriter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -30,38 +30,34 @@

using namespace icinga;

ConfigWriter::ConfigWriter(const String& fileName)
: m_FP(fileName.CStr(), std::ofstream::out | std::ostream::trunc)
{ }

void ConfigWriter::EmitBoolean(bool val)
void ConfigWriter::EmitBoolean(std::ostream& fp, bool val)
{
m_FP << (val ? "true" : "false");
fp << (val ? "true" : "false");
}

void ConfigWriter::EmitNumber(double val)
void ConfigWriter::EmitNumber(std::ostream& fp, double val)
{
m_FP << val;
fp << val;
}

void ConfigWriter::EmitString(const String& val)
void ConfigWriter::EmitString(std::ostream& fp, const String& val)
{
m_FP << "\"" << EscapeIcingaString(val) << "\"";
fp << "\"" << EscapeIcingaString(val) << "\"";
}

void ConfigWriter::EmitEmpty(void)
void ConfigWriter::EmitEmpty(std::ostream& fp)
{
m_FP << "null";
fp << "null";
}

void ConfigWriter::EmitArray(const Array::Ptr& val)
void ConfigWriter::EmitArray(std::ostream& fp, const Array::Ptr& val)
{
m_FP << "[ ";
EmitArrayItems(val);
m_FP << " ]";
fp << "[ ";
EmitArrayItems(fp, val);
fp << " ]";
}

void ConfigWriter::EmitArrayItems(const Array::Ptr& val)
void ConfigWriter::EmitArrayItems(std::ostream& fp, const Array::Ptr& val)
{
bool first = true;

Expand All @@ -70,80 +66,82 @@ void ConfigWriter::EmitArrayItems(const Array::Ptr& val)
if (first)
first = false;
else
m_FP << ", ";
fp << ", ";

EmitValue(0, item);
EmitValue(fp, 0, item);
}
}

void ConfigWriter::EmitScope(int indentLevel, const Dictionary::Ptr& val, const Array::Ptr& imports)
void ConfigWriter::EmitScope(std::ostream& fp, int indentLevel, const Dictionary::Ptr& val, const Array::Ptr& imports)
{
m_FP << "{";
fp << "{";

if (imports && imports->GetLength() > 0) {
ObjectLock xlock(imports);
BOOST_FOREACH(const Value& import, imports) {
m_FP << "\n";
EmitIndent(indentLevel);
m_FP << "import \"" << import << "\"";
fp << "\n";
EmitIndent(fp, indentLevel);
fp << "import \"" << import << "\"";
}

m_FP << "\n";
fp << "\n";
}

ObjectLock olock(val);
BOOST_FOREACH(const Dictionary::Pair& kv, val) {
m_FP << "\n";
EmitIndent(indentLevel);

std::vector<String> tokens;
boost::algorithm::split(tokens, kv.first, boost::is_any_of("."));

EmitIdentifier(tokens[0], true);

for (std::vector<String>::size_type i = 1; i < tokens.size(); i++) {
m_FP << "[";
EmitString(tokens[i]);
m_FP << "]";
if (val) {
ObjectLock olock(val);
BOOST_FOREACH(const Dictionary::Pair& kv, val) {
fp << "\n";
EmitIndent(fp, indentLevel);

std::vector<String> tokens;
boost::algorithm::split(tokens, kv.first, boost::is_any_of("."));

EmitIdentifier(fp, tokens[0], true);

for (std::vector<String>::size_type i = 1; i < tokens.size(); i++) {
fp << "[";
EmitString(fp, tokens[i]);
fp << "]";
}

fp << " = ";
EmitValue(fp, indentLevel + 1, kv.second);
}

m_FP << " = ";
EmitValue(indentLevel + 1, kv.second);
}

m_FP << "\n";
EmitIndent(indentLevel - 1);
m_FP << "}";
fp << "\n";
EmitIndent(fp, indentLevel - 1);
fp << "}";
}

void ConfigWriter::EmitValue(int indentLevel, const Value& val)
void ConfigWriter::EmitValue(std::ostream& fp, int indentLevel, const Value& val)
{
if (val.IsObjectType<Array>())
EmitArray(val);
EmitArray(fp, val);
else if (val.IsObjectType<Dictionary>())
EmitScope(indentLevel, val);
EmitScope(fp, indentLevel, val);
else if (val.IsString())
EmitString(val);
EmitString(fp, val);
else if (val.IsNumber())
EmitNumber(val);
EmitNumber(fp, val);
else if (val.IsBoolean())
EmitBoolean(val);
EmitBoolean(fp, val);
else if (val.IsEmpty())
EmitEmpty();
EmitEmpty(fp);
}

void ConfigWriter::EmitRaw(const String& val)
void ConfigWriter::EmitRaw(std::ostream& fp, const String& val)
{
m_FP << val;
fp << val;
}

void ConfigWriter::EmitIndent(int indentLevel)
void ConfigWriter::EmitIndent(std::ostream& fp, int indentLevel)
{
for (int i = 0; i < indentLevel; i++)
m_FP << "\t";
fp << "\t";
}

void ConfigWriter::EmitIdentifier(const String& identifier, bool inAssignment)
void ConfigWriter::EmitIdentifier(std::ostream& fp, const String& identifier, bool inAssignment)
{
static std::set<String> keywords;
if (keywords.empty()) {
Expand All @@ -152,46 +150,46 @@ void ConfigWriter::EmitIdentifier(const String& identifier, bool inAssignment)
}

if (keywords.find(identifier) != keywords.end()) {
m_FP << "@" << identifier;
fp << "@" << identifier;
return;
}

boost::regex expr("^[a-zA-Z_][a-zA-Z0-9\\_]*$");
boost::smatch what;
if (boost::regex_search(identifier.GetData(), what, expr))
m_FP << identifier;
fp << identifier;
else if (inAssignment)
EmitString(identifier);
EmitString(fp, identifier);
else
BOOST_THROW_EXCEPTION(std::invalid_argument("Invalid identifier"));
}

void ConfigWriter::EmitConfigItem(const String& type, const String& name, bool isTemplate,
void ConfigWriter::EmitConfigItem(std::ostream& fp, const String& type, const String& name, bool isTemplate,
const Array::Ptr& imports, const Dictionary::Ptr& attrs)
{
if (isTemplate)
m_FP << "template ";
fp << "template ";
else
m_FP << "object ";
fp << "object ";

EmitIdentifier(type, false);
m_FP << " ";
EmitString(name);
m_FP << " ";
EmitScope(1, attrs, imports);
EmitIdentifier(fp, type, false);
fp << " ";
EmitString(fp, name);
fp << " ";
EmitScope(fp, 1, attrs, imports);
}

void ConfigWriter::EmitComment(const String& text)
void ConfigWriter::EmitComment(std::ostream& fp, const String& text)
{
m_FP << "/* " << text << " */\n";
fp << "/* " << text << " */\n";
}

void ConfigWriter::EmitFunctionCall(const String& name, const Array::Ptr& arguments)
void ConfigWriter::EmitFunctionCall(std::ostream& fp, const String& name, const Array::Ptr& arguments)
{
EmitIdentifier(name, false);
m_FP << "(";
EmitArrayItems(arguments);
m_FP << ")";
EmitIdentifier(fp, name, false);
fp << "(";
EmitArrayItems(fp, arguments);
fp << ")";
}

String ConfigWriter::EscapeIcingaString(const String& str)
Expand Down
Loading

0 comments on commit 6fa58a5

Please sign in to comment.