Skip to content
Permalink
Browse files

[CMK-2245] - correct upgrade of the Legacy Agent

- two distributions are supported: Packaged Agent and WATO Agent(baked and vanilla )
- the distribution type is automatically discovered by content of check_mk.ini in root/install
- the conversion is described the in ticket
- fiercely tested
- refactored many pieces of the internal code related to this commit
- added https://tribe29.com to the GUI of Control Panel, support link and help link
- improved possibility to test using internal global variables(not used in production)

Change-Id: I40166af705f337bb8888bd33dacca85462826435
  • Loading branch information
s-kipnis committed Jun 27, 2019
1 parent 6c337d1 commit b6edd42d60599288fe790f856a93efe78e0dc5a3
@@ -49,6 +49,16 @@ just to signal that real build script was not called -->
<!-- Property Id="ALLUSERS" Value="1" /<- This option already set -->
<Property Id="REINSTALLMODE" Value="amus" />

<!-- Help Link in the Control Panel -->
<Property Id="ARPHELPLINK" Value="https://tribe29.com" />
<!-- Support Link in the Control Panel -->
<Property Id="ARPURLINFOABOUT" Value="https://tribe29.com" />

<!-- Other links
<Property Id="ARPURLUPDATEINFO" Value="https://tribe29.com" />
<Property Id="ARPAUTHORIZEDCDFPREFIX" Value="https://tribe29.com/ARPAUTHORIZEDCDFPREFIX" />
-->

<!--
<MajorUpgrade DowngradeErrorMessage="A newer version of [ProductName] is already installed. Stopping installation" />
this code is disabled, because bakery/msi-update is not able to upgrade versions correctly
@@ -301,25 +301,33 @@ bool ReinstallIni(const std::filesystem::path target_ini,
namespace fs = std::filesystem;
std::error_code ec;

auto packaged_agent = IsIniFileFromInstaller(source_ini);
if (packaged_agent)
XLOG::l.i(
"This is PACKAGED AGENT,"
"upgrading ini to the bakery.yml skipped");

// remove old files
auto bakery_yml = cma::cfg::GetBakeryFile();
fs::remove(bakery_yml, ec);
if (!packaged_agent) fs::remove(bakery_yml, ec);
fs::remove(target_ini, ec);

// generate new
if (!fs::exists(source_ini)) return true;

cma::cfg::cvt::Parser p;
p.prepare();
p.readIni(source_ini.u8string(), false);
auto yaml = p.emitYaml();

std::ofstream ofs(bakery_yml, std::ios::binary);
if (ofs) {
ofs << cma::cfg::upgrade::MakeComments(source_ini, true);
ofs << yaml;
if (!fs::exists(source_ini, ec)) return true;

if (!packaged_agent) {
cma::cfg::cvt::Parser p;
p.prepare();
p.readIni(source_ini.u8string(), false);
auto yaml = p.emitYaml();

std::ofstream ofs(bakery_yml, std::ios::binary);
if (ofs) {
ofs << cma::cfg::upgrade::MakeComments(source_ini, true);
ofs << yaml;
}
ofs.close();
}
ofs.close();
fs::copy_file(source_ini, target_ini, ec);

return true;
@@ -361,19 +369,6 @@ static void InstallIniFile() {
"Installing of INI file is not required, the file is already installed");
}

bool IsIniFileFromInstaller(const std::filesystem::path &filename) {
namespace fs = std::filesystem;

auto data = cma::tools::ReadFileInVector(filename);
if (!data.has_value()) return false;

constexpr std::string_view base = kIniFromInstallMarker;
if (data->size() < base.length()) return false;

auto content = data->data();
return !memcmp(content, base.data(), base.length());
}

static void PrintInstallCopyLog(std::string_view info_on_error,
std::filesystem::path in_file,
std::filesystem::path out_file,
@@ -10,13 +10,12 @@
#include <string_view>
#include <tuple>

#include "cfg.h"
#include "common/cfg_info.h"
#include "common/wtools.h"
#include "logger.h"

namespace cma::cfg::cap {
constexpr std::string_view kIniFromInstallMarker =
"# Created by Check_MK Agent Installer";

// main API
void Install();
@@ -36,8 +35,6 @@ bool ReinstallCaps(const std::filesystem::path TargetCap,
bool ReinstallIni(const std::filesystem::path TargetIni,
const std::filesystem::path SrcIni);

bool IsIniFileFromInstaller(const std::filesystem::path &filename);

// data structures to use
enum class ProcMode { install, remove, list };

@@ -28,14 +28,30 @@ namespace details {
// internal and hidden variables
// #TODO to be relocated in the application parameters global
bool G_Service = false; // set to true only when we run service
bool G_Test = false; // set to true only when we run watest
} // namespace details

bool IsService() { return details::G_Service; }
bool IsTest() { return details::G_Test; }

}; // namespace cma

namespace cma::cfg {

InstallationType G_TestInstallationType = InstallationType::packaged;
void SetTestInstallationType(InstallationType installation_type) {
G_TestInstallationType = installation_type;
}

InstallationType DetermineInstallationType() noexcept {
if (cma::IsTest()) return G_TestInstallationType;

std::filesystem::path source_ini = cma::cfg::GetFileInstallDir();
source_ini /= files::kIniFile;
return IsIniFileFromInstaller(source_ini) ? InstallationType::packaged
: InstallationType::wato;
}

std::wstring WinPerf::buildCmdLine() const {
std::unique_lock lk(lock_);
auto counters = counters_;
@@ -1366,3 +1382,19 @@ bool ConfigInfo::loadDirect(const std::filesystem::path& FullPath) {
}

} // namespace cma::cfg::details

namespace cma::cfg {
bool IsIniFileFromInstaller(const std::filesystem::path& filename) {
namespace fs = std::filesystem;

auto data = cma::tools::ReadFileInVector(filename);
if (!data.has_value()) return false;

constexpr std::string_view base = kIniFromInstallMarker;
if (data->size() < base.length()) return false;

auto content = data->data();
return !memcmp(content, base.data(), base.length());
}

} // namespace cma::cfg
@@ -15,6 +15,7 @@
namespace cma {
// set only when executable works as a service
bool IsService();
bool IsTest();
} // namespace cma

namespace cma::cfg {
@@ -980,4 +981,16 @@ inline bool LogMrpeOutput() { return false; }

} // namespace cma::cfg

namespace cma::cfg {
constexpr std::string_view kIniFromInstallMarker =
"# Created by Check_MK Agent Installer";

bool IsIniFileFromInstaller(const std::filesystem::path& filename);

enum class InstallationType { packaged, wato, unknown };
InstallationType DetermineInstallationType() noexcept;
void SetTestInstallationType(cma::cfg::InstallationType installation_type);

} // namespace cma::cfg

#include "cfg_details.h"
@@ -11,6 +11,10 @@
#include "common/cfg_info.h"
#include "windows_service_api.h"

namespace cma::details {
extern bool G_Test;
}

namespace cma {

// internal global variables:
@@ -91,6 +95,7 @@ bool DetermineWorkingFolders(AppType Type) {
bool OnStart(AppType Type, YamlCacheOp UpdateCacheOnSuccess,
const std::wstring& ConfigFile) {
if (Type == AppType::automatic) Type = AppDefaultType();
if (Type == AppType::test) cma::details::G_Test = true;

wtools::InitWindowsCom();

@@ -99,7 +104,7 @@ bool OnStart(AppType Type, YamlCacheOp UpdateCacheOnSuccess,

auto old_value = S_OnStartCalled.exchange(true);
if (old_value) {
details::KillDefaultConfig();
cfg::details::KillDefaultConfig();
}

// false is possible only for watest

0 comments on commit b6edd42

Please sign in to comment.
You can’t perform that action at this time.