diff --git a/apt-hook/json-hook.cc b/apt-hook/json-hook.cc index 45650c5961..ed04d067e8 100644 --- a/apt-hook/json-hook.cc +++ b/apt-hook/json-hook.cc @@ -98,6 +98,32 @@ bool version_from_origin_and_archive_ends_with(json_object *version, std::string return false; } +release_info get_release_info() { + release_info info = {"", "", false}; + std::ifstream machine_series_file("/etc/lsb-release"); + if (machine_series_file.is_open()) { + std::string currentLine; + while(std::getline(machine_series_file, currentLine)) { + size_t position = currentLine.find("="); // Find position of equals sign as separator + std::string key = currentLine.substr(0, position); + std::string value = currentLine.substr(position + 1); + + if (!value.empty() && value.front() == '"' && value.back() == '"') { + value = value.substr(1, value.length() - 2); + } + + if (key=="DISTRIB_RELEASE") { + info.release = value; + } else if (key == "DISTRIB_CODENAME") { + info.series = value; + } else if (key == "DISTRIB_DESCRIPTION" && value.find("LTS") != std::string::npos) { + info.is_lts = true; + } + } + } + return info; +} + bool count_security_packages_from_apt_stats_json(json_object *stats, security_package_counts &result) { bool has_key = false; result.standard = 0; @@ -193,7 +219,7 @@ bool collect_pro_packages_from_pre_prompt_json(json_object *pre_prompt, std::vec continue; } std::string package_mode(json_object_get_string(tmp)); - + has_key = json_object_object_get_ex(package, "name", &tmp); if (!has_key) { continue; @@ -236,18 +262,20 @@ bool collect_pro_packages_from_pre_prompt_json(json_object *pre_prompt, std::vec #define MAX_COUNT_MESSAGE_LEN 256 std::string create_count_message(security_package_counts &counts) { char buf[MAX_COUNT_MESSAGE_LEN] = {0}; + release_info info = get_release_info(); + std::string lts_text = info.is_lts ? "LTS " : ""; if (counts.esm_apps == 0) { if (counts.esm_infra == 0) { if (counts.standard == 0) { return ""; } else if (counts.standard == 1) { - return std::string(gettext("1 standard LTS security update")); + return std::string(gettext("1 standard ")) + lts_text + gettext("security update"); } else if (counts.standard > 1) { std::snprintf( buf, MAX_COUNT_MESSAGE_LEN, - gettext("%lu standard LTS security updates"), + (std::string(gettext("%lu standard ")) + lts_text + gettext("security updates")).c_str(), counts.standard ); return std::string(buf); @@ -256,12 +284,12 @@ std::string create_count_message(security_package_counts &counts) { if (counts.standard == 0) { return std::string(gettext("1 esm-infra security update")); } else if (counts.standard == 1) { - return std::string(gettext("1 standard LTS security update and 1 esm-infra security update")); + return std::string(gettext("1 standard ")) + lts_text + gettext("security update and 1 esm-infra security update"); } else if (counts.standard > 1) { std::snprintf( buf, MAX_COUNT_MESSAGE_LEN, - gettext("%lu standard LTS security updates and 1 esm-infra security update"), + (std::string(gettext("%lu standard ")) + lts_text + gettext("security updates and 1 esm-infra security update")).c_str(), counts.standard ); return std::string(buf); @@ -279,7 +307,7 @@ std::string create_count_message(security_package_counts &counts) { std::snprintf( buf, MAX_COUNT_MESSAGE_LEN, - gettext("1 standard LTS security update and %lu esm-infra security updates"), + (std::string(gettext("1 standard ")) + lts_text + gettext("security update and %lu esm-infra security updates")).c_str(), counts.esm_infra ); return std::string(buf); @@ -287,7 +315,7 @@ std::string create_count_message(security_package_counts &counts) { std::snprintf( buf, MAX_COUNT_MESSAGE_LEN, - gettext("%lu standard LTS security updates and %lu esm-infra security updates"), + (std::string(gettext("%lu standard ")) + lts_text + gettext("security updates and %lu esm-infra security updates")).c_str(), counts.standard, counts.esm_infra ); @@ -299,12 +327,12 @@ std::string create_count_message(security_package_counts &counts) { if (counts.standard == 0) { return std::string(gettext("1 esm-apps security update")); } else if (counts.standard == 1) { - return std::string(gettext("1 standard LTS security update and 1 esm-apps security update")); + return std::string(gettext("1 standard ")) + lts_text + gettext("security update and 1 esm-apps security update"); } else if (counts.standard > 1) { std::snprintf( buf, MAX_COUNT_MESSAGE_LEN, - gettext("%lu standard LTS security updates and 1 esm-apps security update"), + (std::string(gettext("%lu standard ")) + lts_text + gettext("security updates and 1 esm-apps security update")).c_str(), counts.standard ); return std::string(buf); @@ -313,12 +341,12 @@ std::string create_count_message(security_package_counts &counts) { if (counts.standard == 0) { return std::string(gettext("1 esm-infra security update and 1 esm-apps security update")); } else if (counts.standard == 1) { - return std::string(gettext("1 standard LTS security update, 1 esm-infra security update and 1 esm-apps security update")); + return std::string(gettext("1 standard ")) + lts_text + gettext("security update, 1 esm-infra security update and 1 esm-apps security update"); } else if (counts.standard > 1) { std::snprintf( buf, MAX_COUNT_MESSAGE_LEN, - gettext("%lu standard LTS security updates, 1 esm-infra security update and 1 esm-apps security update"), + (std::string(gettext("%lu standard ")) + lts_text + gettext("security updates, 1 esm-infra security update and 1 esm-apps security update")).c_str(), counts.standard ); return std::string(buf); @@ -336,7 +364,7 @@ std::string create_count_message(security_package_counts &counts) { std::snprintf( buf, MAX_COUNT_MESSAGE_LEN, - gettext("1 standard LTS security update, %lu esm-infra security updates and 1 esm-apps security update"), + (std::string(gettext("1 standard ")) + lts_text + gettext("security update, %lu esm-infra security updates and 1 esm-apps security update")).c_str(), counts.esm_infra ); return std::string(buf); @@ -344,7 +372,7 @@ std::string create_count_message(security_package_counts &counts) { std::snprintf( buf, MAX_COUNT_MESSAGE_LEN, - gettext("%lu standard LTS security updates, %lu esm-infra security updates and 1 esm-apps security update"), + (std::string(gettext("%lu standard ")) + lts_text + gettext("security updates, %lu esm-infra security updates and 1 esm-apps security update")).c_str(), counts.standard, counts.esm_infra ); @@ -365,7 +393,7 @@ std::string create_count_message(security_package_counts &counts) { std::snprintf( buf, MAX_COUNT_MESSAGE_LEN, - gettext("1 standard LTS security update and %lu esm-apps security updates"), + (std::string(gettext("1 standard ")) + lts_text + gettext("security update and %lu esm-apps security updates")).c_str(), counts.esm_apps ); return std::string(buf); @@ -373,7 +401,7 @@ std::string create_count_message(security_package_counts &counts) { std::snprintf( buf, MAX_COUNT_MESSAGE_LEN, - gettext("%lu standard LTS security updates and %lu esm-apps security updates"), + (std::string(gettext("%lu standard ")) + lts_text + gettext("security updates and %lu esm-apps security updates")).c_str(), counts.standard, counts.esm_apps ); @@ -392,7 +420,7 @@ std::string create_count_message(security_package_counts &counts) { std::snprintf( buf, MAX_COUNT_MESSAGE_LEN, - gettext("1 standard LTS security update, 1 esm-infra security update and %lu esm-apps security updates"), + (std::string(gettext("1 standard ")) + lts_text + gettext("security update, 1 esm-infra security update and %lu esm-apps security updates")).c_str(), counts.esm_apps ); return std::string(buf); @@ -400,7 +428,7 @@ std::string create_count_message(security_package_counts &counts) { std::snprintf( buf, MAX_COUNT_MESSAGE_LEN, - gettext("%lu standard LTS security updates, 1 esm-infra security update and %lu esm-apps security updates"), + (std::string(gettext("%lu standard ")) + lts_text + gettext("security updates, 1 esm-infra security update and %lu esm-apps security updates")).c_str(), counts.standard, counts.esm_apps ); @@ -420,7 +448,7 @@ std::string create_count_message(security_package_counts &counts) { std::snprintf( buf, MAX_COUNT_MESSAGE_LEN, - gettext("1 standard LTS security update, %lu esm-infra security updates and %lu esm-apps security updates"), + (std::string(gettext("1 standard ")) + lts_text + gettext("security update, %lu esm-infra security updates and %lu esm-apps security updates")).c_str(), counts.esm_infra, counts.esm_apps ); @@ -429,7 +457,7 @@ std::string create_count_message(security_package_counts &counts) { std::snprintf( buf, MAX_COUNT_MESSAGE_LEN, - gettext("%lu standard LTS security updates, %lu esm-infra security updates and %lu esm-apps security updates"), + (std::string(gettext("%lu standard ")) + lts_text + gettext("security updates, %lu esm-infra security updates and %lu esm-apps security updates")).c_str(), counts.standard, counts.esm_infra, counts.esm_apps @@ -564,7 +592,11 @@ void print_learn_more_with_context() { } void print_package_names(std::vector package_names) { + release_info info = get_release_info(); std::string curr_line = " "; + if (info.release != "" && info.release >= "24.10") { + curr_line = " "; + } for (std::string &name : package_names) { if ((curr_line.length() + 1 + name.length()) >= 79) { std::cout << curr_line << std::endl; @@ -690,9 +722,15 @@ int run() security_package_counts counts; success = count_security_packages_from_apt_stats_json(hook_req.params, counts); if (success) { + release_info info = get_release_info(); std::string message = create_count_message(counts); if (message != "") { - std::cout << message << std::endl; + if (info.release != "" && info.release >= "24.10") { + std::cout << " " << message << std::endl; + } + else { + std::cout << message << std::endl; + } } } } else if (hook_req.method == "org.debian.apt.hooks.install.pre-prompt") { diff --git a/apt-hook/json-hook.hh b/apt-hook/json-hook.hh index b6ed5048b5..fc1ca16b43 100644 --- a/apt-hook/json-hook.hh +++ b/apt-hook/json-hook.hh @@ -13,10 +13,16 @@ struct security_package_counts { long unsigned int esm_infra; long unsigned int esm_apps; }; +struct release_info { + std::string release; // e.g. "24.04" + std::string series; // e.g. "noble" + bool is_lts; // true for LTS releases +}; enum ESMType {APPS, INFRA}; bool read_jsonrpc_request(std::istream &in, jsonrpc_request &req); +release_info get_release_info(); bool string_ends_with(std::string str, std::string ends_with); bool version_from_origin_and_archive_ends_with(json_object *version, std::string from_origin, std::string archive_ends_with); bool count_security_packages_from_apt_stats_json(json_object *stats, security_package_counts &result); diff --git a/features/apt_messages.feature b/features/apt_messages.feature index cb18f96eaa..480329d03a 100644 --- a/features/apt_messages.feature +++ b/features/apt_messages.feature @@ -702,7 +702,8 @@ Feature: APT Messages Reading state information... Calculating upgrade... - one + APT news: + one Summary: Upgrading: 0, Installing: 0, Removing: 0, Not Upgrading: 0 diff --git a/uaclient/apt_news.py b/uaclient/apt_news.py index 68ea36e279..3e6340273f 100644 --- a/uaclient/apt_news.py +++ b/uaclient/apt_news.py @@ -263,11 +263,14 @@ def local_apt_news(cfg: UAConfig) -> Optional[str]: def format_news_for_apt_update(news: str) -> str: - prefix = "" if system.get_release_info().series == "oracular" else "#" - lines = [ - (prefix + " " + line) if prefix else line for line in news.split("\n") - ] - return "{0}\n{1}\n{0}\n".format(prefix, "\n".join(lines)) + if system.get_release_info().series == "oracular": + prefix = "\nAPT news:" + lines = [" " + line for line in news.split("\n")] + return "{0}\n{1}\n\n".format(prefix, "\n".join(lines)) + else: + prefix = "#" + lines = [prefix + " " + line for line in news.split("\n")] + return "{0}\n{1}\n{0}\n".format(prefix, "\n".join(lines)) def update_apt_news(cfg: UAConfig):