Provide a plugin hook for when build steps finish

[?]
May 27, 2016, 12:32 PM
NTEDD7T4M7XXYCWNZN57EJOEH3KI3UYMHOANV4MY2LSUPWX3JRDQC

Dependencies

  • [2] A2Z3ZJ66 Revert "Don't call buildFinished after we already know it failed"
  • [3] 7LWB2J2Z Periodically clear orphaned build steps
  • [4] NSRWW6LC Add a plugin to interact with the github status API.
  • [5] IDFJXJHW revert commit 26130, use hardcoded default value for HYDRA_DATA (/var/lib/hydra)
  • [6] YDVFPMKP Security: Ensure that a build product refers to the Nix store
  • [7] OOQ2D3KC * Refactoring: move fetchInput out of hydra_scheduler into a separate
  • [8] 6WRGCITD Enable declarative projects.
  • [9] 7VHPMFAG Use /usr/bin/env to find perl
  • [10] B2L4T3X6 Sync with Nix
  • [11] FQQRJUO4 Mark builds as busy
  • [12] 24BMQDZA Start of single-process hydra-queue-runner
  • [13] OG3Z3QGC Namespace cleanup
  • [14] 7VQ4ALFY Update "make check" for the new queue runner
  • [15] VQISTKOP hydra-queue-runner: Use substitutes
  • [16] PMNWRTGJ Add multiple output support
  • [17] BG6PEOB2 Make the output size limit configurable
  • [18] BRAESISH Warn if PostgreSQL appears stalled
  • [19] UYUVQWXQ Fix hydra-queue-runner --build-one
  • [20] IK2UBDAU Revive jobset scheduling
  • [21] 62MQPRXC Pass null values to libpqxx properly
  • [22] K5G5GZY7 Guard against concurrent invocations of hydra-queue-runner
  • [23] X6FOUYFJ int2String -> std::to_string
  • [24] YJKSGJPC Set a default value for `getHydraPath'.
  • [25] D5QIOJGP * Move everything up one directory.
  • [26] Z52T2BC4 Support passing a jobset evaluation as an input
  • [27] 5HFMGRVJ Don't call buildFinished after we already know it failed
  • [28] PLOZBRTR Add command ‘hydra-queue-runner --status’ to show current status
  • [29] PHNLYPKB Call buildFinished when a cached build is added
  • [30] ARD6Z67T Do incremental SVN checkouts
  • [31] NJJ7H64S Very basic multi-threaded queue runner
  • [32] RQUAATWB Add status dump facility
  • [33] IE2PRAQU hydra-queue-runner: Send build notifications
  • [34] FITVNQ2S Keep track of the time we spend copying to/from build machines
  • [35] UNVMKJV5 Unify build and step status codes
  • [36] FCTX433O Add buildStarted plugin hook
  • [37] RX5IIZMT Use Email::MIME instead of Email::Simple
  • [38] GS4BE6TB Asynchronously compress build logs
  • [39] MHVIT4JY Split hydra-queue-runner.cc more
  • [40] HJOEIMLR Refactor
  • [*] 5EQYVRWE Add a plugin mechanism
  • [*] BLVQGJ4L Use OO-style plugins
  • [*] JAH3UPWA Support revision control systems via plugins

Change contents

  • replacement in src/hydra-queue-runner/builder.cc at line 91
    [5.123][5.123:401]()
    {
    auto notificationSenderQueue_(notificationSenderQueue.lock());
    notificationSenderQueue_->push(NotificationItem{NotificationItem::Type::Started, build->id});
    }
    notificationSenderWakeup.notify_one();
    [5.123]
    [5.401]
    enqueueNotificationItem({NotificationItem::Type::BuildStarted, build->id});
  • replacement in src/hydra-queue-runner/builder.cc at line 106
    [5.3537][5.3537:3557]()
    int stepNr = 0;
    [5.3537]
    [3.23]
    unsigned int stepNr = 0;
  • replacement in src/hydra-queue-runner/builder.cc at line 168
    [5.4929][5.4929:4984]()
    logCompressorQueue_->push(result.logFile);
    [5.4929]
    [5.4984]
    assert(stepNr);
    logCompressorQueue_->push({build->id, stepNr, result.logFile});
  • replacement in src/hydra-queue-runner/builder.cc at line 269
    [5.8217][5.8217:8345](),[5.8345][5.426:530](),[5.530][5.8439:8514](),[5.8439][5.8439:8514]()
    for (auto id : buildIDs) {
    {
    auto notificationSenderQueue_(notificationSenderQueue.lock());
    notificationSenderQueue_->push(NotificationItem{NotificationItem::Type::Finished, id});
    }
    notificationSenderWakeup.notify_one();
    }
    [5.8217]
    [5.8514]
    for (auto id : buildIDs)
    enqueueNotificationItem({NotificationItem::Type::BuildFinished, id});
  • replacement in src/hydra-queue-runner/builder.cc at line 389
    [5.14020][5.531:652]()
    notificationSenderQueue_->push(NotificationItem{NotificationItem::Type::Finished, build->id, dependentIDs});
    [5.14020]
    [5.14107]
    notificationSenderQueue_->push(NotificationItem{NotificationItem::Type::BuildFinished, build->id, dependentIDs});
  • replacement in src/hydra-queue-runner/hydra-queue-runner.cc at line 216
    [5.8075][5.0:62]()
    int State::allocBuildStep(pqxx::work & txn, Build::ptr build)
    [5.8075]
    [5.8254]
    unsigned int State::allocBuildStep(pqxx::work & txn, Build::ptr build)
  • replacement in src/hydra-queue-runner/hydra-queue-runner.cc at line 227
    [5.129][5.129:226]()
    int State::createBuildStep(pqxx::work & txn, time_t startTime, Build::ptr build, Step::ptr step,
    [5.129]
    [5.452]
    unsigned int State::createBuildStep(pqxx::work & txn, time_t startTime, Build::ptr build, Step::ptr step,
  • replacement in src/hydra-queue-runner/hydra-queue-runner.cc at line 230
    [5.339][5.339:384]()
    int stepNr = allocBuildStep(txn, build);
    [5.339]
    [5.8431]
    unsigned int stepNr = allocBuildStep(txn, build);
  • replacement in src/hydra-queue-runner/hydra-queue-runner.cc at line 257
    [5.985][5.695:777]()
    BuildID buildId, int stepNr, const std::string & machine, BuildStatus status,
    [5.985]
    [5.1071]
    BuildID buildId, unsigned int stepNr, const std::string & machine, BuildStatus status,
  • replacement in src/hydra-queue-runner/hydra-queue-runner.cc at line 423
    [5.3180][5.1427:1453]()
    Path logPath;
    [5.3180]
    [5.1453]
    CompressionItem item;
  • replacement in src/hydra-queue-runner/hydra-queue-runner.cc at line 428
    [5.1656][5.1656:1712]()
    logPath = logCompressorQueue_->front();
    [5.1656]
    [5.1712]
    item = logCompressorQueue_->front();
  • replacement in src/hydra-queue-runner/hydra-queue-runner.cc at line 432
    [5.1771][5.1771:1819]()
    if (!pathExists(logPath)) continue;
    [5.1771]
    [5.1819]
    if (!pathExists(item.logPath)) continue;
  • replacement in src/hydra-queue-runner/hydra-queue-runner.cc at line 434
    [5.1820][5.1820:1905]()
    printMsg(lvlChatty, format("compressing log file ‘%1%’") % logPath);
    [5.1820]
    [5.1905]
    printMsg(lvlChatty, format("compressing log file ‘%1%’") % item.logPath);
  • replacement in src/hydra-queue-runner/hydra-queue-runner.cc at line 436
    [5.1906][5.1906:1955]()
    Path tmpPath = logPath + ".bz2.tmp";
    [5.1906]
    [5.1955]
    Path dstPath = item.logPath + ".bz2";
    Path tmpPath = dstPath + ".tmp";
  • replacement in src/hydra-queue-runner/hydra-queue-runner.cc at line 446
    [5.2245][5.2245:2319]()
    execlp("bzip2", "bzip2", "-c", logPath.c_str(), nullptr);
    [5.2245]
    [5.1292]
    execlp("bzip2", "bzip2", "-c", item.logPath.c_str(), nullptr);
  • replacement in src/hydra-queue-runner/hydra-queue-runner.cc at line 454
    [5.2548][5.2548:2586]()
    % res % logPath);
    [5.2548]
    [5.2586]
    % res % item.logPath);
  • replacement in src/hydra-queue-runner/hydra-queue-runner.cc at line 456
    [5.2587][5.2587:2661]()
    if (rename(tmpPath.c_str(), (logPath + ".bz2").c_str()) != 0)
    [5.2587]
    [5.2661]
    if (rename(tmpPath.c_str(), dstPath.c_str()) != 0)
  • replacement in src/hydra-queue-runner/hydra-queue-runner.cc at line 459
    [5.2734][5.2734:2853]()
    if (unlink(logPath.c_str()) != 0)
    throw SysError(format("unlinking ‘%1%’") % logPath);
    [5.2734]
    [5.2853]
    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});
  • replacement in src/hydra-queue-runner/hydra-queue-runner.cc at line 492
    [5.1940][5.745:951](),[5.951][5.156:212](),[5.2065][5.156:212]()
    Strings argv({"hydra-notify", item.type == NotificationItem::Type::Started ? "build-started" : "build-finished", std::to_string(item.id)});
    for (auto id : item.dependentIds)
    argv.push_back(std::to_string(id));
    [5.1940]
    [5.2117]
    Strings argv;
    switch (item.type) {
    case NotificationItem::Type::BuildStarted:
    argv = {"hydra-notify", "build-started", std::to_string(item.id)};
    for (auto id : item.dependentIds)
    argv.push_back(std::to_string(id));
    break;
    case NotificationItem::Type::BuildFinished:
    argv = {"hydra-notify", "build-finished", std::to_string(item.id)};
    for (auto id : item.dependentIds)
    argv.push_back(std::to_string(id));
    break;
    case NotificationItem::Type::StepFinished:
    argv = {"hydra-notify", "step-finished", std::to_string(item.id), std::to_string(item.stepNr), item.logPath};
    break;
    };
  • replacement in src/hydra-queue-runner/state.hh at line 314
    [5.6122][5.1990:2047]()
    nix::Sync<std::queue<nix::Path>> logCompressorQueue;
    [5.6122]
    [5.2047]
    struct CompressionItem
    {
    BuildID id;
    unsigned int stepNr;
    nix::Path logPath;
    };
    nix::Sync<std::queue<CompressionItem>> logCompressorQueue;
  • replacement in src/hydra-queue-runner/state.hh at line 330
    [5.1058][5.1058:1098]()
    Started,
    Finished
    [5.1058]
    [5.1098]
    BuildStarted,
    BuildFinished,
    StepFinished,
  • edit in src/hydra-queue-runner/state.hh at line 337
    [5.1191]
    [5.1191]
    unsigned int stepNr;
    nix::Path logPath;
  • edit in src/hydra-queue-runner/state.hh at line 343
    [5.6692]
    [5.6692]
    void enqueueNotificationItem(const NotificationItem && item)
    {
    {
    auto notificationSenderQueue_(notificationSenderQueue.lock());
    notificationSenderQueue_->emplace(item);
    }
    notificationSenderWakeup.notify_one();
    }
  • replacement in src/hydra-queue-runner/state.hh at line 418
    [5.3075][5.3075:3135]()
    int allocBuildStep(pqxx::work & txn, Build::ptr build);
    [5.3075]
    [5.7026]
    unsigned int allocBuildStep(pqxx::work & txn, Build::ptr build);
  • replacement in src/hydra-queue-runner/state.hh at line 420
    [5.7027][5.7027:7121]()
    int createBuildStep(pqxx::work & txn, time_t startTime, Build::ptr build, Step::ptr step,
    [5.7027]
    [5.1029]
    unsigned int createBuildStep(pqxx::work & txn, time_t startTime, Build::ptr build, Step::ptr step,
  • replacement in src/hydra-queue-runner/state.hh at line 425
    [5.1502][5.1502:1562]()
    unsigned int overhead, BuildID buildId, int stepNr,
    [5.1502]
    [5.1122]
    unsigned int overhead, BuildID buildId, unsigned int stepNr,
  • file deletion: PluginHooks.pm (----------)
    [5.339][5.732:770](),[5.770][5.306:306]()
    package Hydra::Helper::PluginHooks;
    use strict;
    use Exporter;
    our @ISA = qw(Exporter);
    our @EXPORT = qw(
    notifyBuildStarted
    notifyBuildFinished);
    sub notifyBuildStarted {
    my ($plugins, $build) = @_;
    foreach my $plugin (@{$plugins}) {
    eval {
    $plugin->buildStarted($build);
    };
    if ($@) {
    print STDERR "$plugin->buildStarted: $@\n";
    }
    }
    }
    sub notifyBuildFinished {
    my ($plugins, $build, $dependents) = @_;
    foreach my $plugin (@{$plugins}) {
    eval {
    $plugin->buildFinished($build, $dependents);
    };
    if ($@) {
    print STDERR "$plugin->buildFinished: $@\n";
    }
    }
    }
    1;
  • edit in src/lib/Hydra/Helper/AddBuilds.pm at line 19
    [5.4499][5.90:122]()
    use Hydra::Helper::PluginHooks;
  • edit in src/lib/Hydra/Plugin.pm at line 34
    [43.523]
    [44.19153]
    }
    # Called when step $step has finished. The build log is stored in the
    # file $logPath (bzip2-compressed).
    sub stepFinished {
    my ($self, $step, $logPath) = @_;
  • edit in src/script/hydra-notify at line 7
    [5.3096][5.3096:3128]()
    use Hydra::Helper::PluginHooks;
  • replacement in src/script/hydra-notify at line 18
    [5.3327][5.1574:1657]()
    my $cmd = shift @ARGV or die "Syntax: hydra-notify CMD BUILD-ID [BUILD-IDs...]\n";
    [5.3327]
    [5.3412]
    my $cmd = shift @ARGV or die "Syntax: hydra-notify build-started BUILD | build-finished BUILD-ID [BUILD-IDs...] | step-finished BUILD-ID STEP-NR LOG-PATH\n";
  • edit in src/script/hydra-notify at line 23
    [5.1791]
    [5.1791]
  • replacement in src/script/hydra-notify at line 36
    [5.3771][5.3771:3830](),[5.3830][5.1824:1903]()
    notifyBuildFinished(\@plugins, $build, [@dependents]);
    } elsif ($cmd eq "build-started") {
    notifyBuildStarted(\@plugins, $build);
    [5.3771]
    [5.3830]
    foreach my $plugin (@plugins) {
    eval { $plugin->buildFinished($build, [@dependents]); };
    if ($@) {
    print STDERR "$plugin->buildFinished: $@\n";
    }
    }
    }
    elsif ($cmd eq "build-started") {
    foreach my $plugin (@plugins) {
    eval { $plugin->buildStarted($build); };
    if ($@) {
    print STDERR "$plugin->buildStarted: $@\n";
    }
    }
    }
    elsif ($cmd eq "step-finished") {
    my $stepNr = shift @ARGV or die;
    my $step = $build->buildsteps->find({stepnr => $stepNr})
    or die "step $stepNr does not exist\n";
    my $logPath = shift @ARGV or die;
    foreach my $plugin (@plugins) {
    eval { $plugin->stepFinished($step, $logPath); };
    if ($@) {
    print STDERR "$plugin->stepFinished: $@\n";
    }
    }