UVQJBDHNWHTGOAEL426F6RZPD67QABBRP73E6QB5ND5OV2S3267QC
LVQXQIYA7QMLVYOANYEFHDBTFAOSE3D2IYAVOG2DXURTASRCUNYQC
X4KYZJBQ7WULUWTHAPX5BZTZR7C6HRCC4N4J5K726PGZKSY6FQOQC
7LWB2J2ZFB4XJDN5MBL2WDKVBRYQD7Y6RQU7LUYKH7PZTXK2H7KQC
MHVIT4JYWUYD4UCGB2AHLXWLX6B5SYE22BREERNGANT7RGGDUFOAC
NTEDD7T4M7XXYCWNZN57EJOEH3KI3UYMHOANV4MY2LSUPWX3JRDQC
NJJ7H64SZOX5EGACDCQAUQ7R6UEWD5IIC35A2MWFOOJV55DJYPHAC
GS4BE6TB6GH2JUZJHDPHL6YG7J7YYESF3YOZJZ2CFABXUTO4VYPQC
24BMQDZAWDQ7VNIA7TIROXSOYLOJBNZ2E4264WHWNJAEN6ZB3UOAC
XCDTFZUYSOYEARMJCV4ORVQWG2VWZQ43HU2U63RBECP53OSCM2GQC
IE2PRAQUCQVFPJ4CAIJRPXXEFC5VBAE3EO5I5FG4XWEDRNONNHKQC
K5G5GZY7D7KWVR5RAGZFHH3ZPG5OCLZT4HZ6XIJJ7YYVUMC2CTZQC
XV4AEKJCFTNCOR52IRFYHORCNNFKIHOADIUARTC2U5Z6ZQBEEFYQC
HJOEIMLRDVQ2KZI5HGL2HKGBM3AHP7YIKGKDAGFUNKRUXVRB24NAC
B2L4T3X63XVYJQXEDU4WT5Y4R6PMDXGC6WN2KGOMHRQILSABNQOAC
5EQYVRWECBDJORGI5DRIOUEJXSXMRCQNT2562BM4Z4U52LT7JUHAC
/* Asynchronously compress the log. */
if (result.logFile != "") {
{
auto logCompressorQueue_(logCompressorQueue.lock());
assert(stepNr);
logCompressorQueue_->push({buildId, stepNr, result.logFile});
}
logCompressorWakeup.notify_one();
}
void State::logCompressor()
{
while (true) {
try {
CompressionItem item;
{
auto logCompressorQueue_(logCompressorQueue.lock());
while (logCompressorQueue_->empty())
logCompressorQueue_.wait(logCompressorWakeup);
item = logCompressorQueue_->front();
logCompressorQueue_->pop();
}
printMsg(lvlChatty, format("compressing log file ‘%1%’") % item.logPath);
Path dstPath = item.logPath + ".bz2";
Path tmpPath = dstPath + ".tmp";
AutoCloseFD fd = open(tmpPath.c_str(), O_CREAT | O_TRUNC | O_WRONLY, 0644);
// FIXME: use libbz2
Pid pid = startProcess([&]() {
if (dup2(fd.get(), STDOUT_FILENO) == -1)
throw SysError("cannot dup output pipe to stdout");
execlp("bzip2", "bzip2", "-c", item.logPath.c_str(), nullptr);
throw SysError("cannot start bzip2");
});
int res = pid.wait();
if (res != 0)
throw Error(format("bzip2 returned exit code %1% while compressing ‘%2%’")
% res % item.logPath);
if (rename(tmpPath.c_str(), dstPath.c_str()) != 0)
throw SysError(format("renaming ‘%1%’") % tmpPath);
if (unlink(item.logPath.c_str()) != 0)
throw SysError(format("unlinking ‘%1%’") % item.logPath);
/* Run plugins. We do this after log compression to ensure
that the log file doesn't change while the plugins may
be accessing it. */
enqueueNotificationItem({NotificationItem::Type::StepFinished, item.id, {}, item.stepNr, dstPath});
} catch (std::exception & e) {
printMsg(lvlError, format("log compressor: %1%") % e.what());
sleep(5);
}
}
}
/* Log compressor work queue. */
struct CompressionItem
{
BuildID id;
unsigned int stepNr;
nix::Path logPath;
};
nix::Sync<std::queue<CompressionItem>> logCompressorQueue;
std::condition_variable logCompressorWakeup;
package Hydra::Plugin::CompressLog;
use strict;
use utf8;
use parent 'Hydra::Plugin';
use Hydra::Helper::CatalystUtils;
sub stepFinished {
my ($self, $step, $logPath) = @_;
my $doCompress = $self->{config}->{'compress_build_logs'} // "1";
if ($doCompress eq "1" && -e $logPath) {
print STDERR "compressing ‘$logPath’...\n";
system("bzip2", "--force", $logPath);
}
}
1;