summaryrefslogtreecommitdiff
path: root/apt-private
diff options
context:
space:
mode:
authorJulian Andres Klode <julian.klode@canonical.com>2025-03-20 15:03:23 +0100
committerJulian Andres Klode <julian.klode@canonical.com>2025-03-20 15:09:56 +0100
commita2cb87afcbc89d1f8e770c26121a75d9c1654458 (patch)
treeae9708cbc7a21788074b8d2a0ebbfb19284115f1 /apt-private
parent109fdcac9a16ffa06b06366134dcaaef7e2b3379 (diff)
solver3: Use zstd-compressed, base64-encoded dumps
Store the solver dumps with zstd compression and base64-encode them in the crash report; such that they take up significantly less space and can fit in cassandra's schema. Base64 is wrapped at 76 characters as the base64 tool does. Do some magic std::string_view conversion to avoid string copies for the substr() used to get 76 characters at a time. Note we can rely on substr(i, 76) to handle less than 76 characters just fine; it uses std::min(76, size() - i) characters.
Diffstat (limited to 'apt-private')
-rw-r--r--apt-private/private-install.cc19
1 files changed, 14 insertions, 5 deletions
diff --git a/apt-private/private-install.cc b/apt-private/private-install.cc
index e3d176ffe..cf92f91ad 100644
--- a/apt-private/private-install.cc
+++ b/apt-private/private-install.cc
@@ -89,7 +89,7 @@ bool CheckNothingBroken(CacheFile &Cache)
// ---------------------------------------------------------------------
static void WriteApportReport(pkgCacheFile &Cache, std::string &title, std::vector<std::string> const &errors, int mode, bool distUpgrade)
{
- auto dumpfile = flCombine(_config->FindDir("Dir::Log"), "edsp.log");
+ auto dumpfile = flCombine(_config->FindDir("Dir::Log"), "edsp.log.zst");
auto crashfile = flCombine(_config->FindDir("Dir::Apport", "/var/crash"), "apt-edsp." + std::to_string(getuid()) + ".crash");
auto apt = Cache->FindPkg("apt");
if (access(flNotFile(dumpfile).c_str(), W_OK) != 0 || access(flNotFile(crashfile).c_str(), W_OK) != 0)
@@ -97,7 +97,8 @@ static void WriteApportReport(pkgCacheFile &Cache, std::string &title, std::vect
OpTextProgress Progress(*_config);
Progress.OverallProgress(0, 100, 50, _("Writing error report"));
FileFd edspDump(dumpfile,
- FileFd::Exclusive | FileFd::Create | FileFd::WriteOnly | FileFd::BufferedWrite);
+ FileFd::Exclusive | FileFd::Create | FileFd::WriteOnly | FileFd::BufferedWrite,
+ FileFd::Extension);
int edspFlags = 0;
if (mode || distUpgrade)
edspFlags |= EDSP::Request::UPGRADE_ALL;
@@ -127,10 +128,18 @@ static void WriteApportReport(pkgCacheFile &Cache, std::string &title, std::vect
for (auto &error : errors)
crash << " " << error << "\n";
- crash << "AptSolverDump:\n";
std::ifstream toCopy(edspDump.Name());
- for (std::string line; std::getline(toCopy, line);)
- crash << " " << line << "\n";
+ std::ostringstream readStream;
+ readStream << toCopy.rdbuf();
+ const auto base64 = Base64Encode(readStream.str());
+ if (not base64.empty())
+ {
+ crash << "AptSolverDump:\n";
+ // Print the base64, with line wrapping, indented by one space; substr(i, 76)
+ // returns at most 76 characters or as many as are left.
+ for (size_t i=0; i < base64.size(); i += 76)
+ crash << " " << std::string_view{base64}.substr(i, 76) << "\n";
+ }
crash.close();
}