From 84406f594f557bf18f90e05ee0dd443a8cc69359 Mon Sep 17 00:00:00 2001 From: Salih Muhammed Date: Fri, 27 Feb 2026 05:14:56 +0200 Subject: [PATCH] Show image hash and add tests --- src/client/cli/formatter/csv_formatter.cpp | 5 +++-- src/client/cli/formatter/json_formatter.cpp | 1 + src/client/cli/formatter/table_formatter.cpp | 14 ++++++++++++-- src/client/cli/formatter/yaml_formatter.cpp | 1 + src/daemon/daemon.cpp | 1 + src/rpc/multipass.proto | 1 + .../test_data/formatters/csv/empty_find_reply.csv | 2 +- .../formatters/csv/find_multiple_reply.csv | 8 ++++---- .../csv/find_multiple_reply_duplicate_image.csv | 6 +++--- .../test_data/formatters/csv/find_one_reply.csv | 4 ++-- .../formatters/json/find_multiple_reply.json | 3 +++ .../json/find_multiple_reply_duplicate_image.json | 2 ++ .../test_data/formatters/json/find_one_reply.json | 1 + .../formatters/table/find_multiple_reply.txt | 8 ++++---- .../table/find_multiple_reply_duplicate_image.txt | 6 +++--- .../test_data/formatters/table/find_one_reply.txt | 4 ++-- .../formatters/table/find_one_reply_no_os.txt | 4 ++-- .../formatters/yaml/find_multiple_reply.yaml | 3 +++ .../yaml/find_multiple_reply_duplicate_image.yaml | 2 ++ .../test_data/formatters/yaml/find_one_reply.yaml | 1 + 20 files changed, 52 insertions(+), 25 deletions(-) diff --git a/src/client/cli/formatter/csv_formatter.cpp b/src/client/cli/formatter/csv_formatter.cpp index d629e84626b..3fb46062e92 100644 --- a/src/client/cli/formatter/csv_formatter.cpp +++ b/src/client/cli/formatter/csv_formatter.cpp @@ -38,13 +38,14 @@ void format_images(Dest&& dest, auto image_id = mp::format::image_string_for(image.remote_name(), aliases[0]); fmt::format_to(dest, - "{},{},{},{},{},{},{}\n", + "{},{},{},{},{},{},{},{}\n", image_id, image.remote_name(), fmt::join(aliases.cbegin() + 1, aliases.cend(), ";"), image.os(), image.release(), image.version(), + image.image_hash(), type); } } @@ -220,7 +221,7 @@ std::string mp::CSVFormatter::format(const FindReply& reply) const { fmt::memory_buffer buf; - fmt::format_to(std::back_inserter(buf), "Image,Remote,Aliases,OS,Release,Version,Type\n"); + fmt::format_to(std::back_inserter(buf), "Image,Remote,Aliases,OS,Release,Version,Hash,Type\n"); format_images(std::back_inserter(buf), reply.images_info(), "Cloud Image"); return fmt::to_string(buf); diff --git a/src/client/cli/formatter/json_formatter.cpp b/src/client/cli/formatter/json_formatter.cpp index da777e2314f..bf5781655f0 100644 --- a/src/client/cli/formatter/json_formatter.cpp +++ b/src/client/cli/formatter/json_formatter.cpp @@ -51,6 +51,7 @@ QJsonObject format_images( image_obj.insert("aliases", aliases_arr); image_obj.insert("remote", QString::fromStdString(image.remote_name())); + image_obj.insert("image_hash", QString::fromStdString(image.image_hash())); images_obj.insert( QString::fromStdString(mp::format::image_string_for(image.remote_name(), aliases[0])), diff --git a/src/client/cli/formatter/table_formatter.cpp b/src/client/cli/formatter/table_formatter.cpp index 363dc713ed4..cce4c3f6079 100644 --- a/src/client/cli/formatter/table_formatter.cpp +++ b/src/client/cli/formatter/table_formatter.cpp @@ -36,7 +36,13 @@ template void format_images(Dest&& dest, const google::protobuf::RepeatedPtrField& images_info) { - fmt::format_to(dest, "{:<28}{:<18}{:<17}{:<}\n", "Image", "Aliases", "Version", "Description"); + fmt::format_to(dest, + "{:<28}{:<18}{:<17}{:<15}{:<}\n", + "Image", + "Aliases", + "Version", + "Hash", + "Description"); auto sorted_images = images_info; std::sort(sorted_images.begin(), @@ -56,12 +62,16 @@ void format_images(Dest&& dest, auto aliases = image.aliases(); mp::format::filter_aliases(aliases); + auto hash = image.image_hash(); + auto short_hash = hash.size() > 12 ? hash.substr(0, 12) : hash; + fmt::format_to( dest, - "{:<28}{:<18}{:<17}{:<}\n", + "{:<28}{:<18}{:<17}{:<15}{:<}\n", mp::format::image_string_for(image.remote_name(), aliases[0]), fmt::format("{}", fmt::join(aliases.cbegin() + 1, aliases.cend(), ",")), image.version(), + short_hash, fmt::format("{}{}", image.os().empty() ? "" : image.os() + " ", image.release())); } fmt::format_to(dest, "\n"); diff --git a/src/client/cli/formatter/yaml_formatter.cpp b/src/client/cli/formatter/yaml_formatter.cpp index a72fae2e5ad..e2835bec077 100644 --- a/src/client/cli/formatter/yaml_formatter.cpp +++ b/src/client/cli/formatter/yaml_formatter.cpp @@ -53,6 +53,7 @@ std::map format_images(const ImageInfo& images_info) image_node["release"] = image.release(); image_node["version"] = image.version(); image_node["remote"] = image.remote_name(); + image_node["image_hash"] = image.image_hash(); images_node[mp::format::image_string_for(image.remote_name(), aliases[0])] = image_node; } diff --git a/src/daemon/daemon.cpp b/src/daemon/daemon.cpp index bb55e48d11c..7c0945f2919 100644 --- a/src/daemon/daemon.cpp +++ b/src/daemon/daemon.cpp @@ -1121,6 +1121,7 @@ void add_aliases(google::protobuf::RepeatedPtrField* co entry->set_version(info.version.toStdString()); entry->set_codename(info.release_codename.toStdString()); entry->set_remote_name(remote_name); + entry->set_image_hash(info.id.toStdString()); } } diff --git a/src/rpc/multipass.proto b/src/rpc/multipass.proto index 529c4d1a15c..9495dcd84df 100644 --- a/src/rpc/multipass.proto +++ b/src/rpc/multipass.proto @@ -151,6 +151,7 @@ message FindReply { repeated string aliases = 4; string codename = 5; string remote_name = 6; + string image_hash = 7; } repeated ImageInfo images_info = 1; string log_line = 2; diff --git a/tests/unit/test_data/formatters/csv/empty_find_reply.csv b/tests/unit/test_data/formatters/csv/empty_find_reply.csv index cb199062acf..ed2f30966b7 100644 --- a/tests/unit/test_data/formatters/csv/empty_find_reply.csv +++ b/tests/unit/test_data/formatters/csv/empty_find_reply.csv @@ -1 +1 @@ -Image,Remote,Aliases,OS,Release,Version,Type +Image,Remote,Aliases,OS,Release,Version,Hash,Type diff --git a/tests/unit/test_data/formatters/csv/find_multiple_reply.csv b/tests/unit/test_data/formatters/csv/find_multiple_reply.csv index 945448c3705..458ade419c9 100644 --- a/tests/unit/test_data/formatters/csv/find_multiple_reply.csv +++ b/tests/unit/test_data/formatters/csv/find_multiple_reply.csv @@ -1,4 +1,4 @@ -Image,Remote,Aliases,OS,Release,Version,Type -19.04,release,disco,Ubuntu,19.04,20190516,Cloud Image -18.04,release,bionic;lts,Ubuntu,18.04 LTS,20180421,Cloud Image -daily:19.10,daily,eoan;devel,Ubuntu,19.10,20190516,Cloud Image +Image,Remote,Aliases,OS,Release,Version,Hash,Type +19.04,release,disco,Ubuntu,19.04,20190516,,Cloud Image +18.04,release,bionic;lts,Ubuntu,18.04 LTS,20180421,,Cloud Image +daily:19.10,daily,eoan;devel,Ubuntu,19.10,20190516,,Cloud Image diff --git a/tests/unit/test_data/formatters/csv/find_multiple_reply_duplicate_image.csv b/tests/unit/test_data/formatters/csv/find_multiple_reply_duplicate_image.csv index 6d0f5c514bf..517a1a7b948 100644 --- a/tests/unit/test_data/formatters/csv/find_multiple_reply_duplicate_image.csv +++ b/tests/unit/test_data/formatters/csv/find_multiple_reply_duplicate_image.csv @@ -1,3 +1,3 @@ -Image,Remote,Aliases,OS,Release,Version,Type -core:core18,core,,Ubuntu,Core 18,20190520,Cloud Image -snapcraft:core18,snapcraft,,,Snapcraft builder for core18,20190520,Cloud Image +Image,Remote,Aliases,OS,Release,Version,Hash,Type +core:core18,core,,Ubuntu,Core 18,20190520,,Cloud Image +snapcraft:core18,snapcraft,,,Snapcraft builder for core18,20190520,,Cloud Image diff --git a/tests/unit/test_data/formatters/csv/find_one_reply.csv b/tests/unit/test_data/formatters/csv/find_one_reply.csv index 94012423f7a..6f373c3b5e8 100644 --- a/tests/unit/test_data/formatters/csv/find_one_reply.csv +++ b/tests/unit/test_data/formatters/csv/find_one_reply.csv @@ -1,2 +1,2 @@ -Image,Remote,Aliases,OS,Release,Version,Type -ubuntu,,,Ubuntu,18.04 LTS,20190516,Cloud Image +Image,Remote,Aliases,OS,Release,Version,Hash,Type +ubuntu,,,Ubuntu,18.04 LTS,20190516,,Cloud Image diff --git a/tests/unit/test_data/formatters/json/find_multiple_reply.json b/tests/unit/test_data/formatters/json/find_multiple_reply.json index d09590d55a8..e2330809bbc 100644 --- a/tests/unit/test_data/formatters/json/find_multiple_reply.json +++ b/tests/unit/test_data/formatters/json/find_multiple_reply.json @@ -7,6 +7,7 @@ "bionic", "lts" ], + "image_hash": "", "os": "Ubuntu", "release": "18.04 LTS", "remote": "release", @@ -16,6 +17,7 @@ "aliases": [ "disco" ], + "image_hash": "", "os": "Ubuntu", "release": "19.04", "remote": "release", @@ -26,6 +28,7 @@ "eoan", "devel" ], + "image_hash": "", "os": "Ubuntu", "release": "19.10", "remote": "daily", diff --git a/tests/unit/test_data/formatters/json/find_multiple_reply_duplicate_image.json b/tests/unit/test_data/formatters/json/find_multiple_reply_duplicate_image.json index 692c0986053..a64fd141b57 100644 --- a/tests/unit/test_data/formatters/json/find_multiple_reply_duplicate_image.json +++ b/tests/unit/test_data/formatters/json/find_multiple_reply_duplicate_image.json @@ -5,6 +5,7 @@ "core:core18": { "aliases": [ ], + "image_hash": "", "os": "Ubuntu", "release": "Core 18", "remote": "core", @@ -13,6 +14,7 @@ "snapcraft:core18": { "aliases": [ ], + "image_hash": "", "os": "", "release": "Snapcraft builder for core18", "remote": "snapcraft", diff --git a/tests/unit/test_data/formatters/json/find_one_reply.json b/tests/unit/test_data/formatters/json/find_one_reply.json index 5e1cc89ddb2..669abd33437 100644 --- a/tests/unit/test_data/formatters/json/find_one_reply.json +++ b/tests/unit/test_data/formatters/json/find_one_reply.json @@ -5,6 +5,7 @@ "ubuntu": { "aliases": [ ], + "image_hash": "", "os": "Ubuntu", "release": "18.04 LTS", "remote": "", diff --git a/tests/unit/test_data/formatters/table/find_multiple_reply.txt b/tests/unit/test_data/formatters/table/find_multiple_reply.txt index 830d386645e..43c2909fdff 100644 --- a/tests/unit/test_data/formatters/table/find_multiple_reply.txt +++ b/tests/unit/test_data/formatters/table/find_multiple_reply.txt @@ -1,5 +1,5 @@ -Image Aliases Version Description -18.04 bionic,lts 20180421 Ubuntu 18.04 LTS -19.04 disco 20190516 Ubuntu 19.04 -daily:19.10 eoan,devel 20190516 Ubuntu 19.10 +Image Aliases Version Hash Description +18.04 bionic,lts 20180421 Ubuntu 18.04 LTS +19.04 disco 20190516 Ubuntu 19.04 +daily:19.10 eoan,devel 20190516 Ubuntu 19.10 diff --git a/tests/unit/test_data/formatters/table/find_multiple_reply_duplicate_image.txt b/tests/unit/test_data/formatters/table/find_multiple_reply_duplicate_image.txt index b31fc2b236a..f5bb5e5cab4 100644 --- a/tests/unit/test_data/formatters/table/find_multiple_reply_duplicate_image.txt +++ b/tests/unit/test_data/formatters/table/find_multiple_reply_duplicate_image.txt @@ -1,4 +1,4 @@ -Image Aliases Version Description -snapcraft:core18 20190520 Snapcraft builder for core18 -core:core18 20190520 Ubuntu Core 18 +Image Aliases Version Hash Description +snapcraft:core18 20190520 Snapcraft builder for core18 +core:core18 20190520 Ubuntu Core 18 diff --git a/tests/unit/test_data/formatters/table/find_one_reply.txt b/tests/unit/test_data/formatters/table/find_one_reply.txt index f242b4b7936..f01b110ac08 100644 --- a/tests/unit/test_data/formatters/table/find_one_reply.txt +++ b/tests/unit/test_data/formatters/table/find_one_reply.txt @@ -1,3 +1,3 @@ -Image Aliases Version Description -ubuntu 20190516 Ubuntu 18.04 LTS +Image Aliases Version Hash Description +ubuntu 20190516 Ubuntu 18.04 LTS diff --git a/tests/unit/test_data/formatters/table/find_one_reply_no_os.txt b/tests/unit/test_data/formatters/table/find_one_reply_no_os.txt index dfe4be6d780..ebb150861c3 100644 --- a/tests/unit/test_data/formatters/table/find_one_reply_no_os.txt +++ b/tests/unit/test_data/formatters/table/find_one_reply_no_os.txt @@ -1,3 +1,3 @@ -Image Aliases Version Description -snapcraft:core18 20190520 Snapcraft builder for core18 +Image Aliases Version Hash Description +snapcraft:core18 20190520 Snapcraft builder for core18 diff --git a/tests/unit/test_data/formatters/yaml/find_multiple_reply.yaml b/tests/unit/test_data/formatters/yaml/find_multiple_reply.yaml index c8ae1eb4776..1bf31db7b91 100644 --- a/tests/unit/test_data/formatters/yaml/find_multiple_reply.yaml +++ b/tests/unit/test_data/formatters/yaml/find_multiple_reply.yaml @@ -9,6 +9,7 @@ images: release: 18.04 LTS version: 20180421 remote: release + image_hash: "" 19.04: aliases: - disco @@ -16,6 +17,7 @@ images: release: 19.04 version: 20190516 remote: release + image_hash: "" "daily:19.10": aliases: - eoan @@ -24,3 +26,4 @@ images: release: 19.10 version: 20190516 remote: daily + image_hash: "" diff --git a/tests/unit/test_data/formatters/yaml/find_multiple_reply_duplicate_image.yaml b/tests/unit/test_data/formatters/yaml/find_multiple_reply_duplicate_image.yaml index cb01c766e9f..14f1adf2341 100644 --- a/tests/unit/test_data/formatters/yaml/find_multiple_reply_duplicate_image.yaml +++ b/tests/unit/test_data/formatters/yaml/find_multiple_reply_duplicate_image.yaml @@ -8,6 +8,7 @@ images: release: Core 18 version: 20190520 remote: core + image_hash: "" "snapcraft:core18": aliases: [] @@ -15,3 +16,4 @@ images: release: Snapcraft builder for core18 version: 20190520 remote: snapcraft + image_hash: "" diff --git a/tests/unit/test_data/formatters/yaml/find_one_reply.yaml b/tests/unit/test_data/formatters/yaml/find_one_reply.yaml index 83d8531618d..c51ff87c7c0 100644 --- a/tests/unit/test_data/formatters/yaml/find_one_reply.yaml +++ b/tests/unit/test_data/formatters/yaml/find_one_reply.yaml @@ -8,3 +8,4 @@ images: release: 18.04 LTS version: 20190516 remote: "" + image_hash: ""