1
0
mirror of https://github.com/ohwgiles/laminar.git synced 2026-10-13 14:41:02 +00:00

13 Commits
0.1 ... 0.2

Author SHA1 Message Date
Oliver Giles
9521ba0bab zlib dep, build script fixes, v0.2 2015-12-06 14:07:16 +01:00
Oliver Giles
82b39c2961 compress logs in database 2015-12-06 13:47:43 +01:00
Oliver Giles
1eb6a9138e better message on execl failure 2015-12-06 12:41:38 +01:00
Oliver Giles
e7fe117426 don't log full file paths, remove use of KJ_DBG 2015-12-06 12:36:12 +01:00
Oliver Giles
99fd47de68 order recent builds in job page chronologically 2015-12-06 12:20:14 +01:00
Oliver Giles
f181c87d3b report running state, only show spinner when actually running 2015-12-06 12:15:05 +01:00
Oliver Giles
87ebf91f1e don't show previous build button for first job run 2015-12-06 11:54:34 +01:00
Oliver Giles
10d7ad8960 create db with primary key and index 2015-12-06 11:53:06 +01:00
Oliver Giles
a83cc6c7a5 correct postinst dir install path, force bash on ubuntu 2015-12-06 11:41:46 +01:00
Oliver Giles
7b010fdaf6 add missing maintainer 2015-12-06 11:39:17 +01:00
Oliver Giles
645ed81aea use boost 1.55 for compatibility with debian jessie 2015-12-06 11:38:49 +01:00
Oliver Giles
e40fb52554 output a warning when archive exists instead of failing 2015-12-06 11:37:24 +01:00
Oliver Giles
1273b36260 add docker scripts 2015-11-26 08:41:06 +01:00
13 changed files with 274 additions and 52 deletions

View File

@@ -84,7 +84,7 @@ generate_compressed_bins(${CMAKE_BINARY_DIR} js/angular.min.js js/angular-route.
add_executable(laminard src/database.cpp src/main.cpp src/server.cpp src/laminar.cpp
src/conf.cpp src/resources.cpp src/run.cpp laminar.capnp.c++ ${COMPRESSED_BINS})
# TODO: some alternative to boost::filesystem?
target_link_libraries(laminard capnp-rpc capnp kj-async kj pthread boost_filesystem boost_system sqlite3)
target_link_libraries(laminard capnp-rpc capnp kj-async kj pthread boost_filesystem boost_system sqlite3 z)
## Client
add_executable(laminarc src/client.cpp laminar.capnp.c++)

80
docker-build-centos.sh Executable file
View File

@@ -0,0 +1,80 @@
#!/bin/bash
VERSION=0.2
OUTPUT_DIR=$PWD
SOURCE_DIR=$(readlink -f $(dirname ${BASH_SOURCE[0]}))
docker run --rm -i -v $SOURCE_DIR:/root/rpmbuild/SOURCES/laminar-$VERSION:ro -v $OUTPUT_DIR:/output centos bash -xe <<EOS
yum -y install rpm-build cmake make gcc gcc-c++ wget sqlite-devel boost-devel zlib-devel
mkdir /build
cd /build
wget -O capnproto.tar.gz https://github.com/sandstorm-io/capnproto/archive/v0.5.3.tar.gz
wget -O websocketpp.tar.gz https://github.com/zaphoyd/websocketpp/archive/0.6.0.tar.gz
wget -O rapidjson.tar.gz https://github.com/miloyip/rapidjson/archive/v1.0.2.tar.gz
md5sum -c <<EOF
909bd13ad6b8bc840ac78ab8f5bcb0a4 capnproto.tar.gz
5a485884c01f881aafbf1e055d851b82 websocketpp.tar.gz
97cc60d01282a968474c97f60714828c rapidjson.tar.gz
EOF
tar xzf capnproto.tar.gz
tar xzf websocketpp.tar.gz
tar xzf rapidjson.tar.gz
cd /build/capnproto-0.5.3/c++/
cmake -DCMAKE_BUILD_TYPE=Release -DBUILD_TESTING=off .
make -j4
make install
cd /build/websocketpp-0.6.0/
cmake .
make install
cd /build/rapidjson-1.0.2/
cmake -DRAPIDJSON_BUILD_EXAMPLES=off .
make install
cd
cat <<EOF > laminar.spec
Summary: Lightweight Continuous Integration Service
Name: laminar
Version: $VERSION
Release: 1
License: GPL
BuildRequires: systemd-units
Requires: boost-filesystem zlib
%description
Lightweight Continuous Integration Service
%prep
%build
cmake -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=/ %{_sourcedir}/laminar-$VERSION
pwd
make
%install
%make_install
%files
%{_bindir}/laminarc
%{_bindir}/laminard
%{_unitdir}/laminar.service
%config(noreplace) %{_sysconfdir}/laminar.conf
%post
echo Creating laminar user with home in %{_sharedstatedir}/laminar
useradd -r -d %{_sharedstatedir}/laminar -s %{_sbindir}/nologin laminar
mkdir -p %{_sharedstatedir}/laminar/cfg/{jobs,nodes,scripts}
chown -R laminar: %{_sharedstatedir}/laminar
EOF
rpmbuild -ba laminar.spec
mv rpmbuild/RPMS/x86_64/laminar-$VERSION-1.x86_64.rpm /output/
EOS

71
docker-build-ubuntu.sh Executable file
View File

@@ -0,0 +1,71 @@
#!/bin/bash
VERSION=0.2
OUTPUT_DIR=$PWD
SOURCE_DIR=$(readlink -f $(dirname ${BASH_SOURCE[0]}))
docker run --rm -i -v $SOURCE_DIR:/laminar:ro -v $OUTPUT_DIR:/output ubuntu bash -xe <<EOS
apt-get update
apt-get install -y wget cmake g++ libsqlite3-dev libboost-filesystem1.55-dev zlib1g-dev
mkdir /build
cd /build
wget -O capnproto.tar.gz https://github.com/sandstorm-io/capnproto/archive/v0.5.3.tar.gz
wget -O websocketpp.tar.gz https://github.com/zaphoyd/websocketpp/archive/0.6.0.tar.gz
wget -O rapidjson.tar.gz https://github.com/miloyip/rapidjson/archive/v1.0.2.tar.gz
md5sum -c <<EOF
909bd13ad6b8bc840ac78ab8f5bcb0a4 capnproto.tar.gz
5a485884c01f881aafbf1e055d851b82 websocketpp.tar.gz
97cc60d01282a968474c97f60714828c rapidjson.tar.gz
EOF
tar xzf capnproto.tar.gz
tar xzf websocketpp.tar.gz
tar xzf rapidjson.tar.gz
cd /build/capnproto-0.5.3/c++/
cmake -DCMAKE_BUILD_TYPE=Release -DBUILD_TESTING=off .
make -j4
make install
cd /build/websocketpp-0.6.0/
cmake .
make install
cd /build/rapidjson-1.0.2/
cmake -DRAPIDJSON_BUILD_EXAMPLES=off .
make install
cd /build
cmake -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=/ /laminar
make -j4
mkdir laminar
make DESTDIR=laminar install/strip
mkdir laminar/DEBIAN
cat <<EOF > laminar/DEBIAN/control
Package: laminar
Version: $VERSION
Section:
Priority: optional
Architecture: amd64
Maintainer: Oliver Giles <web ohwg net>
Depends: libboost-filesystem1.55.0, zlib1g
Description: Lightweight Continuous Integration Service
EOF
cat <<EOF > laminar/DEBIAN/postinst
#!/bin/bash
echo Creating laminar user with home in /var/lib/laminar
useradd -r -d /var/lib/laminar -s /usr/sbin/nologin laminar
mkdir -p /var/lib/laminar/cfg/{jobs,nodes,scripts}
chown -R laminar: /var/lib/laminar
EOF
chmod +x laminar/DEBIAN/postinst
dpkg-deb --build laminar
mv laminar.deb /output/laminar_$VERSION-1_amd64.deb
EOS

View File

@@ -19,6 +19,7 @@
#include "database.h"
#include <sqlite3.h>
#include <string.h>
Database::Database(const char *path) {
sqlite3_open(path, &hdl);
@@ -47,15 +48,17 @@ void Database::Statement::bindValue(int i, int e) {
void Database::Statement::bindValue(int i, const char* e) {
sqlite3_bind_text(stmt, i, e, -1, NULL);
}
void Database::Statement::bindValue(int i, std::string e) {
sqlite3_bind_text(stmt, i, e.c_str(), e.length(), NULL);
sqlite3_bind_blob(stmt, i, e.data(), e.size(), NULL);
}
template<> std::string Database::Statement::fetchColumn(int col) {
return (char*)sqlite3_column_text(stmt, col);
int sz = sqlite3_column_bytes(stmt, col);
std::string res(sz, '\0');
memcpy(&res[0], sqlite3_column_blob(stmt, col), sz);
return res;
}
template<> const char* Database::Statement::fetchColumn(int col) {

View File

@@ -19,10 +19,11 @@
#include "laminar.h"
#include "server.h"
#include "conf.h"
#include "log.h"
#include <sys/wait.h>
#include <fstream>
#include <kj/debug.h>
#include <zlib.h>
#include <boost/filesystem.hpp>
namespace fs = boost::filesystem;
@@ -69,7 +70,12 @@ Laminar::Laminar() {
// Prepare database for first use
// TODO: error handling
db->exec("CREATE TABLE IF NOT EXISTS builds("
"name TEXT, number INT UNSIGNED, node TEXT, queuedAt INT, startedAt INT, completedAt INT, result INT, output TEXT, parentJob TEXT, parentBuild INT, reason TEXT)");
"name TEXT, number INT UNSIGNED, node TEXT, queuedAt INT, "
"startedAt INT, completedAt INT, result INT, output TEXT, "
"outputLen INT, parentJob TEXT, parentBuild INT, reason TEXT, "
"PRIMARY KEY (name, number))");
db->exec("CREATE INDEX IF NOT EXISTS idx_completion_time ON builds("
"completedAt DESC)");
// retrieve the last build numbers
db->stmt("SELECT name, MAX(number) FROM builds GROUP BY name")
@@ -123,10 +129,16 @@ void Laminar::sendStatus(LaminarClient* client) {
if(const Run* run = activeRun(client->scope.job, client->scope.num)) {
client->sendMessage(run->log.c_str());
} else { // it must be finished, fetch it from the database
db->stmt("SELECT output FROM builds WHERE name = ? AND number = ?")
db->stmt("SELECT output, outputLen FROM builds WHERE name = ? AND number = ?")
.bind(client->scope.job, client->scope.num)
.fetch<const char*>([=](const char* log) {
client->sendMessage(log);
.fetch<str,int>([=](str zipped, unsigned long sz) {
std::string log(sz+1,'\0');
int res = ::uncompress((unsigned char*)&log[0], &sz,
(unsigned char*)zipped.data(), zipped.size());
if(res == Z_OK)
client->sendMessage(log);
else
LLOG(ERROR, "Failed to uncompress log", res);
});
}
return;
@@ -151,6 +163,7 @@ void Laminar::sendStatus(LaminarClient* client) {
j.set("queued", run->startedAt - run->queuedAt);
j.set("started", run->startedAt);
j.set("reason", run->reason());
j.set("result", to_string(RunState::RUNNING));
db->stmt("SELECT completedAt - startedAt FROM builds WHERE name = ? ORDER BY completedAt DESC LIMIT 1")
.bind(run->name)
.fetch<int>([&](int etc){
@@ -183,6 +196,7 @@ void Laminar::sendStatus(LaminarClient* client) {
j.set("number", run->build);
j.set("node", run->node->name);
j.set("started", run->startedAt);
j.set("result", to_string(RunState::RUNNING));
j.set("reason", run->reason());
j.EndObject();
}
@@ -397,14 +411,14 @@ bool Laminar::loadConfiguration() {
std::shared_ptr<Run> Laminar::queueJob(std::string name, ParamMap params) {
if(!fs::exists(fs::path(homeDir)/"cfg"/"jobs"/name)) {
KJ_LOG(ERROR, "Non-existent job", name);
LLOG(ERROR, "Non-existent job", name);
return nullptr;
}
// attempt to create a workspace for this job if it doesn't exist
if(!fs::exists(fs::path(homeDir)/"run"/name/"workspace")) {
if(!fs::create_directories(fs::path(homeDir)/"run"/name/"workspace")) {
KJ_LOG(ERROR, "Could not create job workspace", name);
LLOG(ERROR, "Could not create job workspace", name);
return nullptr;
}
}
@@ -421,7 +435,7 @@ std::shared_ptr<Run> Laminar::queueJob(std::string name, ParamMap params) {
} else if(it->first == "=reason") {
run->reasonMsg = it->second;
} else {
KJ_LOG(ERROR, "Unknown internal job parameter", it->first);
LLOG(ERROR, "Unknown internal job parameter", it->first);
}
it = params.erase(it);
} else
@@ -479,7 +493,7 @@ void Laminar::reapAdvance() {
pid_t pid = waitpid(-1, &ret, 0);
// TODO: handle signalled child processes
if(pid > 0) {
KJ_LOG(INFO, "Reaping", pid);
LLOG(INFO, "Reaping", pid);
auto it = activeJobs.get<0>().find(pid);
std::shared_ptr<Run> run = *it;
bool completed = true;
@@ -530,14 +544,16 @@ void Laminar::assignNewJobs() {
// create a working directory (different to a workspace!)
fs::path wd = fs::path(homeDir)/"run"/run->name/std::to_string(buildNum);
if(!fs::create_directory(wd)) {
KJ_LOG(ERROR, "Could not create working directory", wd.string());
LLOG(ERROR, "Could not create working directory", wd.string());
break;
}
run->wd = wd.string();
// create an archive directory
fs::path archive = fs::path(homeDir)/"archive"/run->name/std::to_string(buildNum);
if(!fs::create_directories(archive)) {
KJ_LOG(ERROR, "Could not create archive directory", archive.string());
if(fs::is_directory(archive)) {
LLOG(WARNING, "Archive directory already exists", archive.string());
} else if(!fs::create_directories(archive)) {
LLOG(ERROR, "Could not create archive directory", archive.string());
break;
}
@@ -587,7 +603,7 @@ void Laminar::assignNewJobs() {
// update next build number
buildNums[run->name] = buildNum;
KJ_LOG(INFO, "Queued job to node", run->name, run->build, node.name);
LLOG(INFO, "Queued job to node", run->name, run->build, node.name);
// notify clients
Json j;
@@ -616,12 +632,12 @@ void Laminar::assignNewJobs() {
}
// setup run completion handler
run->notifyCompletion = [this](const Run* r) { runFinished(r); };
run->notifyCompletion = [this](Run* r) { runFinished(r); };
// trigger the first step of the run
if(stepRun(run)) {
// should never happen
KJ_LOG(INFO, "No steps for run");
LLOG(INFO, "No steps for run");
run->complete();
}
@@ -638,15 +654,24 @@ void Laminar::assignNewJobs() {
}
}
void Laminar::runFinished(const Run * r) {
void Laminar::runFinished(Run * r) {
Node* node = r->node;
node->busyExecutors--;
KJ_LOG(INFO, "Run completed", r->name, to_string(r->result));
LLOG(INFO, "Run completed", r->name, to_string(r->result));
time_t completedAt = time(0);
db->stmt("INSERT INTO builds VALUES(?,?,?,?,?,?,?,?,?,?,?)")
// compress log
std::string zipped(r->log.size(), '\0');
size_t logsize = r->log.length();
size_t zippedSize = zipped.size();
::compress((unsigned char*)&zipped[0], &zippedSize,
(unsigned char*)&r->log[0], logsize);
zipped.resize(zippedSize);
db->stmt("INSERT INTO builds VALUES(?,?,?,?,?,?,?,?,?,?,?,?)")
.bind(r->name, r->build, node->name, r->queuedAt, r->startedAt, completedAt, int(r->result),
r->log, r->parentName, r->parentBuild, r->reason())
zipped, logsize, r->parentName, r->parentBuild, r->reason())
.exec();
// notify clients

View File

@@ -61,7 +61,7 @@ private:
void reapAdvance();
void assignNewJobs();
bool stepRun(std::shared_ptr<Run> run);
void runFinished(const Run*);
void runFinished(Run*);
bool nodeCanQueue(const Node&, const Run&) const;
// expects that Json has started an array
void populateArtifacts(Json& out, std::string job, int num) const;

37
src/log.h Normal file
View File

@@ -0,0 +1,37 @@
///
/// Copyright 2015 Oliver Giles
///
/// This file is part of Laminar
///
/// Laminar is free software: you can redistribute it and/or modify
/// it under the terms of the GNU General Public License as published by
/// the Free Software Foundation, either version 3 of the License, or
/// (at your option) any later version.
///
/// Laminar is distributed in the hope that it will be useful,
/// but WITHOUT ANY WARRANTY; without even the implied warranty of
/// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
/// GNU General Public License for more details.
///
/// You should have received a copy of the GNU General Public License
/// along with Laminar. If not, see <http://www.gnu.org/licenses/>
///
#ifndef _LAMINAR_LOG_H_
#define _LAMINAR_LOG_H_
#include <kj/debug.h>
// Simple override to prevent full paths to source files from
// appearing in log messages. Assumes / is the path separator.
// @see kj/debug.h
#define _LBASENAME(path) strrchr(path, '/') ? strrchr(path, '/') + 1 : path
#define LLOG(severity, ...) \
if (!::kj::_::Debug::shouldLog(::kj::_::Debug::Severity::severity)) {} else \
::kj::_::Debug::log(_LBASENAME(__FILE__), __LINE__, ::kj::_::Debug::Severity::severity, \
#__VA_ARGS__, __VA_ARGS__)
#endif // _LAMINAR_LOG_H_

View File

@@ -17,9 +17,9 @@
/// along with Laminar. If not, see <http://www.gnu.org/licenses/>
///
#include "laminar.h"
#include "log.h"
#include <signal.h>
#include <kj/debug.h>
std::function<void()> sigHandler;
static void __sigHandler(int) { sigHandler(); }
@@ -34,7 +34,7 @@ int main(int argc, char** argv) {
do {
Laminar laminar;
sigHandler = [&](){
KJ_LOG(INFO, "Received SIGINT");
LLOG(INFO, "Received SIGINT");
laminar.stop();
};
signal(SIGINT, &__sigHandler);
@@ -43,7 +43,7 @@ int main(int argc, char** argv) {
laminar.run();
} while(false);
KJ_DBG("end of main");
LLOG(INFO, "end of main");
return 0;
}

View File

@@ -213,20 +213,20 @@ angular.module('laminar',['ngRoute','ngSanitize'])
$scope.$apply();
var chtBt = new Chart(document.getElementById("chartBt").getContext("2d")).Bar({
labels: data.recent.map(function(e){return '#' + e.number;}),
labels: data.recent.map(function(e){return '#' + e.number;}).reverse(),
datasets: [{
fillColor: "darkseagreen",
strokeColor: "forestgreen",
data: data.recent.map(function(e){return e.duration;})
data: data.recent.map(function(e){return e.duration;}).reverse()
}]
},
{barValueSpacing: 1,barStrokeWidth: 1,barDatasetSpacing:0}
);
for(var i = 0; i < data.recent.length; ++i) {
for(var i = 0, n = data.recent.length; i < n; ++i) {
if(data.recent[i].result != "success") {
chtBt.datasets[0].bars[i].fillColor = "darksalmon";
chtBt.datasets[0].bars[i].strokeColor = "crimson";
chtBt.datasets[0].bars[n-i-1].fillColor = "darksalmon";
chtBt.datasets[0].bars[n-i-1].strokeColor = "crimson";
}
}
chtBt.update();
@@ -306,7 +306,10 @@ angular.module('laminar',['ngRoute','ngSanitize'])
.run(function($rootScope) {
angular.extend($rootScope, {
runIcon: function(result) {
return result === "success" ? '<span style="color:forestgreen;font-family:\'Zapf Dingbats\';">✔</span>' : result === "failed" ? '<span style="color:crimson;">✘</span>' : '';
return result === "success" ? '<span style="color:forestgreen;font-family:\'Zapf Dingbats\';">✔</span>' : result === "failed" || result === "aborted" ? '<span style="color:crimson;">✘</span>' : '';
},
runComplete: function(run) {
return !!run && (run.result === 'aborted' || run.result === 'failed' || run.result === 'success');
},
formatDate: function(unix) {
// TODO reimplement when toLocaleDateString() accepts formatting

View File

@@ -1,10 +1,10 @@
<div class="container-fluid">
<div class="row">
<div class="col-sm-5 col-md-6 col-lg-7">
<h3 style="float:left"><img class="spin" src="/progress.png" ng-hide="job.result"><span ng-bind-html="runIcon(job.result)"></span> {{name}} #{{num}}</h3>
<h3 style="float:left"><img class="spin" src="/progress.png" ng-show="job.result === 'running'"><span ng-bind-html="runIcon(job.result)"></span> {{name}} #{{num}}</h3>
<nav class="pull-left">
<ul class="pagination" style="margin:15px 20px">
<li><a href="jobs/{{name}}/{{num-1}}">&laquo;</a></li>
<li ng-show="num > 1"><a href="jobs/{{name}}/{{num-1}}">&laquo;</a></li>
<li ng-show="latestNum > num"><a ng-href="jobs/{{name}}/{{num+1}}">&raquo;</a></li>
</ul>
</nav>
@@ -13,12 +13,12 @@
<dt>Reason</dt><dd>{{job.reason}}</dd>
<dt>Queued for</dt><dd>{{job.queued}}s</dd>
<dt>Started</dt><dd>{{formatDate(job.started)}}</dd>
<dt ng-show="job.result">Completed</dt><dd ng-show="job.result">{{formatDate(job.completed)}}</dd>
<dt ng-show="job.result">Duration</dt><dd ng-show="job.result">{{job.duration}}s</dd>
<dt ng-show="runComplete(job)">Completed</dt><dd ng-show="runComplete(job)">{{formatDate(job.completed)}}</dd>
<dt ng-show="runComplete(job)">Duration</dt><dd ng-show="runComplete(job)">{{job.duration}}s</dd>
</dl>
</div>
<div class="col-sm-7 col-md-6 col-lg-5">
<div class="progress" ng-hide="job.result">
<div class="progress" ng-show="job.result == 'running'">
<div class="progress-bar progress-bar-{{job.overtime?'warning':'info'}} progress-bar-striped {{job.etc?'':'active'}}" style="width:{{!job.etc?'100':job.progress}}%;"></div>
</div>
<div class="panel panel-default" ng-show="job.artifacts.length">

View File

@@ -19,9 +19,9 @@
#include "run.h"
#include "node.h"
#include "conf.h"
#include <iostream>
#include <kj/debug.h>
#include "log.h"
#include <iostream>
#include <unistd.h>
#include <boost/filesystem.hpp>
@@ -30,6 +30,7 @@ namespace fs = boost::filesystem;
std::string to_string(const RunState& rs) {
switch(rs) {
case RunState::PENDING: return "pending";
case RunState::RUNNING: return "running";
case RunState::ABORTED: return "aborted";
case RunState::FAILED: return "failed";
case RunState::SUCCESS: return "success";
@@ -46,7 +47,7 @@ Run::Run() {
}
Run::~Run() {
KJ_DBG("Run destroyed");
LLOG(INFO, "Run destroyed");
}
std::string Run::reason() const {
@@ -100,13 +101,14 @@ bool Run::step() {
for(auto& pair : params) {
setenv(pair.first.c_str(), pair.second.c_str(), false);
}
printf("[laminar] Executing %s\n", currentScript.c_str());
fprintf(stderr, "[laminar] Executing %s\n", currentScript.c_str());
execl(currentScript.c_str(), currentScript.c_str(), NULL);
KJ_LOG(FATAL, "execl returned", strerror(errno));
// cannot use LLOG because stdout/stderr are captured
fprintf(stderr, "[laminar] Failed to execute %s\n", currentScript.c_str());
_exit(1);
}
KJ_LOG(INFO, "Forked", currentScript, pid);
LLOG(INFO, "Forked", currentScript, pid);
close(pfd[1]);
fd = pfd[0];
this->pid = pid;

View File

@@ -29,6 +29,7 @@
enum class RunState {
UNKNOWN,
PENDING,
RUNNING,
ABORTED,
FAILED,
SUCCESS
@@ -67,7 +68,7 @@ public:
std::string reason() const;
std::function<void(const Run*)> notifyCompletion;
std::function<void(Run*)> notifyCompletion;
Node* node;
RunState result;
RunState lastResult;

View File

@@ -20,12 +20,12 @@
#include "interface.h"
#include "laminar.capnp.h"
#include "resources.h"
#include "log.h"
#include <capnp/ez-rpc.h>
#include <capnp/rpc-twoparty.h>
#include <capnp/rpc.capnp.h>
#include <kj/async-io.h>
#include <kj/debug.h>
#include <kj/threadlocal.h>
#include <websocketpp/config/core.hpp>
@@ -58,9 +58,9 @@ namespace {
LaminarCi::JobResult fromRunState(RunState state) {
switch(state) {
case RunState::SUCCESS: return LaminarCi::JobResult::SUCCESS;
case RunState::FAILED: return LaminarCi::JobResult::FAILED;
case RunState::FAILED: return LaminarCi::JobResult::FAILED;
case RunState::ABORTED: return LaminarCi::JobResult::ABORTED;
default:
KJ_DBG("TODO log state", to_string(state));
return LaminarCi::JobResult::UNKNOWN;
}
}
@@ -81,7 +81,7 @@ public:
// Start a job, without waiting for it to finish
kj::Promise<void> trigger(TriggerContext context) override {
std::string jobName = context.getParams().getJobName();
KJ_LOG(INFO, "RPC trigger", jobName);
LLOG(INFO, "RPC trigger", jobName);
ParamMap params;
for(auto p : context.getParams().getParams()) {
params[p.getName().cStr()] = p.getValue().cStr();
@@ -96,7 +96,7 @@ public:
// Start a job and wait for the result
kj::Promise<void> start(StartContext context) override {
std::string jobName = context.getParams().getJobName();
KJ_LOG(INFO, "RPC start", jobName);
LLOG(INFO, "RPC start", jobName);
ParamMap params;
for(auto p : context.getParams().getParams()) {
params[p.getName().cStr()] = p.getValue().cStr();
@@ -116,7 +116,7 @@ public:
kj::Promise<void> pend(PendContext context) override {
std::string jobName = context.getParams().getJobName();
int buildNum = context.getParams().getBuildNum();
KJ_LOG(INFO, "RPC pend", jobName, buildNum);
LLOG(INFO, "RPC pend", jobName, buildNum);
kj::Promise<RunState> promise = laminar.waitForRun(jobName, buildNum);
@@ -129,7 +129,7 @@ public:
kj::Promise<void> set(SetContext context) override {
std::string jobName = context.getParams().getJobName();
int buildNum = context.getParams().getBuildNum();
KJ_LOG(INFO, "RPC set", jobName, buildNum);
LLOG(INFO, "RPC set", jobName, buildNum);
LaminarCi::MethodResult result = laminar.setParam(jobName, buildNum,
context.getParams().getParam().getName(), context.getParams().getParam().getValue())