Skip to content

Commit

Permalink
cli: Add json output mode for 'check' and 'list' commands
Browse files Browse the repository at this point in the history
Signed-off-by: Andre Detsch <[email protected]>
  • Loading branch information
detsch committed Aug 21, 2024
1 parent b89f5b0 commit 61ded57
Show file tree
Hide file tree
Showing 3 changed files with 69 additions and 16 deletions.
2 changes: 1 addition & 1 deletion include/aktualizr-lite/cli/cli.h
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ enum class CheckMode {
};

StatusCode CheckIn(AkliteClientExt &client, const LocalUpdateSource *local_update_source = nullptr,
CheckMode check_mode = CheckMode::Update);
CheckMode check_mode = CheckMode::Update, bool json_output = false);

StatusCode Pull(AkliteClientExt &client, int version = -1, const std::string &target_name = "",
bool force_downgrade = true, const LocalUpdateSource *local_update_source = nullptr,
Expand Down
61 changes: 55 additions & 6 deletions src/cli/cli.cc
Original file line number Diff line number Diff line change
@@ -1,11 +1,14 @@
#include "aktualizr-lite/cli/cli.h"

#include <algorithm>
#include <iostream>
#include <unordered_map>

#include "aktualizr-lite/api.h"

#include "aktualizr-lite/aklite_client_ext.h"
#include "json/reader.h"
#include "json/value.h"
#include "logging/logging.h"

namespace aklite::cli {
Expand Down Expand Up @@ -157,9 +160,59 @@ static CheckInResult checkIn(AkliteClientExt &client, CheckMode check_mode,
}
}

StatusCode CheckIn(AkliteClientExt &client, const LocalUpdateSource *local_update_source, CheckMode check_mode) {
static Json::Value getCheckInResultJson(AkliteClientExt &client, const CheckInResult &ci_res,
const GetTargetToInstallResult &gti_res) {
const auto current = client.GetCurrent();

Json::Value json_root;

auto app_shortlist = client.GetAppShortlist();
for (const auto &target : ci_res.Targets()) {
Json::Value json_target;
json_target["name"] = target.Name();
json_target["version"] = target.Version();
if (!gti_res.selected_target.IsUnknown() && gti_res.selected_target.Name() == target.Name()) {
json_target["selected"] = true;
json_target["reason"] = gti_res.reason;
}
if (client.IsRollback(target)) {
json_target["bad"] = true;
}
if (current.Version() == target.Version()) {
json_target["current"] = true;
} else if (current.Version() < target.Version()) {
json_target["newer"] = true;
}

Json::Value json_apps;
for (const auto &app : TufTarget::Apps(target)) {
Json::Value json_app;
json_app["name"] = app.name;
json_app["uri"] = app.uri;
json_app["on"] =
(!app_shortlist || std::find(app_shortlist->begin(), app_shortlist->end(), app.name) != app_shortlist->end());
json_apps.append(json_app);
}
json_target["apps"] = json_apps;

json_root.append(json_target);
}

return json_root;
}

StatusCode CheckIn(AkliteClientExt &client, const LocalUpdateSource *local_update_source, CheckMode check_mode,
bool json_output) {
auto cr = checkIn(client, check_mode, local_update_source);
if (cr) {
if (!cr) {
return res2StatusCode<CheckInResult::Status>(c2s, cr.status);
}

auto gti_res = client.GetTargetToInstall(cr);

if (json_output) {
std::cout << getCheckInResultJson(client, cr, gti_res) << "\n";
} else {
if (cr.Targets().empty()) {
std::cout << "\nNo Targets found"
<< "\n";
Expand All @@ -184,11 +237,7 @@ StatusCode CheckIn(AkliteClientExt &client, const LocalUpdateSource *local_updat
std::cout << "\n";
}
}
if (!cr) {
return res2StatusCode<CheckInResult::Status>(c2s, cr.status);
}

auto gti_res = client.GetTargetToInstall(cr);
if (gti_res && gti_res.selected_target.IsUnknown()) {
// Keep Ok vs OkCached differentiation in case of success and there is no target to install
return res2StatusCode<CheckInResult::Status>(c2s, cr.status);
Expand Down
22 changes: 13 additions & 9 deletions src/main.cc
Original file line number Diff line number Diff line change
Expand Up @@ -67,22 +67,25 @@ static int status_main(LiteClient& client, const bpo::variables_map& unused) {
return 0;
}

static int checkin(LiteClient& client, aklite::cli::CheckMode check_mode) {
static int checkin(LiteClient& client, aklite::cli::CheckMode check_mode, const bpo::variables_map& params) {
bool json_output = false;
if (params.count("json") > 0) {
json_output = params.at("json").as<bool>();
}

std::shared_ptr<LiteClient> client_ptr{&client, [](LiteClient* /*unused*/) {}};
AkliteClientExt akclient(client_ptr, false, true);

auto status = aklite::cli::CheckIn(akclient, nullptr, check_mode);
auto status = aklite::cli::CheckIn(akclient, nullptr, check_mode, json_output);
return static_cast<int>(status);
}

static int cli_list(LiteClient& client, const bpo::variables_map& unused) {
(void)unused;
return checkin(client, aklite::cli::CheckMode::Current);
static int cli_list(LiteClient& client, const bpo::variables_map& params) {
return checkin(client, aklite::cli::CheckMode::Current, params);
}

static int cli_check(LiteClient& client, const bpo::variables_map& unused) {
(void)unused;
return checkin(client, aklite::cli::CheckMode::Update);
static int cli_check(LiteClient& client, const bpo::variables_map& params) {
return checkin(client, aklite::cli::CheckMode::Update, params);
}

static int daemon_main(LiteClient& client, const bpo::variables_map& variables_map) {
Expand Down Expand Up @@ -223,7 +226,8 @@ bpo::variables_map parse_options(int argc, char** argv) {
("clear-installed-versions", "DANGER - clear the history of installed updates before applying the given update. This is handy when doing test/debug and you need to rollback to an old version manually.")
#endif
("interval", bpo::value<uint64_t>(), "Override uptane.polling_secs interval to poll for update when in daemon mode.")
("command", bpo::value<std::string>(), subs.c_str());
("command", bpo::value<std::string>(), subs.c_str())
("json", bpo::value<bool>(), "Output targets information as json ('check' and 'list' commands only)");
// clang-format on

// consider the first positional argument as the aktualizr run mode
Expand Down

0 comments on commit 61ded57

Please sign in to comment.