diff --git a/src/conf.cpp b/src/conf.cpp
index 4fa58ad..ca791c3 100644
--- a/src/conf.cpp
+++ b/src/conf.cpp
@@ -30,8 +30,8 @@ StringMap parseConfFile(const char* path) {
while(std::getline(f, line)) {
if(line[0] == '#')
continue;
- int p = line.find('=');
- if(p > 0) {
+ size_t p = line.find('=');
+ if(p != std::string::npos) {
result.emplace(line.substr(0, p), line.substr(p+1));
}
}
diff --git a/src/conf.h b/src/conf.h
index 152a908..cdabf95 100644
--- a/src/conf.h
+++ b/src/conf.h
@@ -16,8 +16,8 @@
/// You should have received a copy of the GNU General Public License
/// along with Laminar. If not, see
///
-#ifndef _LAMINAR_CONF_H_
-#define _LAMINAR_CONF_H_
+#ifndef LAMINAR_CONF_H_
+#define LAMINAR_CONF_H_
#include
@@ -41,4 +41,4 @@ int StringMap::convert(std::string e);
StringMap parseConfFile(const char* path);
-#endif // _LAMINAR_CONF_H_
+#endif // LAMINAR_CONF_H_
diff --git a/src/database.cpp b/src/database.cpp
index 9052875..f5632a9 100644
--- a/src/database.cpp
+++ b/src/database.cpp
@@ -29,8 +29,10 @@ Database::~Database() {
sqlite3_close(hdl);
}
-Database::Statement::Statement(sqlite3 *db, const char *query) {
- sqlite3_prepare_v2(db, query, -1, &stmt, NULL);
+Database::Statement::Statement(sqlite3 *db, const char *query) :
+ stmt(nullptr)
+{
+ sqlite3_prepare_v2(db, query, -1, &stmt, nullptr);
}
Database::Statement::~Statement() {
@@ -46,33 +48,54 @@ void Database::Statement::bindValue(int i, int e) {
sqlite3_bind_int(stmt, i, e);
}
+void Database::Statement::bindValue(int i, uint e) {
+ sqlite3_bind_int(stmt, i, static_cast(e));
+}
+
+void Database::Statement::bindValue(int i, int64_t e) {
+ sqlite3_bind_int64(stmt, i, e);
+}
+
+void Database::Statement::bindValue(int i, uint64_t e) {
+ sqlite3_bind_int64(stmt, i, static_cast(e));
+}
+
void Database::Statement::bindValue(int i, const char* e) {
- sqlite3_bind_text(stmt, i, e, -1, NULL);
+ sqlite3_bind_text(stmt, i, e, -1, nullptr);
}
void Database::Statement::bindValue(int i, const std::string& e) {
- sqlite3_bind_text(stmt, i, e.data(), e.size(), NULL);
+ sqlite3_bind_text(stmt, i, e.data(), static_cast(e.size()), nullptr);
}
template<> std::string Database::Statement::fetchColumn(int col) {
- int sz = sqlite3_column_bytes(stmt, col);
+ uint sz = static_cast(sqlite3_column_bytes(stmt, col)); // according to documentation will never be negative
std::string res(sz, '\0');
memcpy(&res[0], sqlite3_column_text(stmt, col), sz);
return res;
}
template<> const char* Database::Statement::fetchColumn(int col) {
- return (char*)sqlite3_column_text(stmt, col);
+ // while sqlite3_column_text maybe more correctly returns an unsigned const char*, signed const char* is more consistent
+ return reinterpret_cast(sqlite3_column_text(stmt, col));
}
template<> int Database::Statement::fetchColumn(int col) {
return sqlite3_column_int(stmt, col);
}
-template<> time_t Database::Statement::fetchColumn(int col) {
+template<> uint Database::Statement::fetchColumn(int col) {
+ return static_cast(sqlite3_column_int(stmt, col));
+}
+
+template<> int64_t Database::Statement::fetchColumn(int col) {
return sqlite3_column_int64(stmt, col);
}
+template<> uint64_t Database::Statement::fetchColumn(int col) {
+ return static_cast(sqlite3_column_int64(stmt, col));
+}
+
bool Database::Statement::row() {
return sqlite3_step(stmt) == SQLITE_ROW;
}
diff --git a/src/database.h b/src/database.h
index c5b3224..26df3c8 100644
--- a/src/database.h
+++ b/src/database.h
@@ -16,8 +16,8 @@
/// You should have received a copy of the GNU General Public License
/// along with Laminar. If not, see
///
-#ifndef _LAMINAR_DATABASE_H_
-#define _LAMINAR_DATABASE_H_
+#ifndef LAMINAR_DATABASE_H_
+#define LAMINAR_DATABASE_H_
#include
#include
@@ -52,6 +52,11 @@ private:
public:
Statement(sqlite3* db, const char* query);
+ Statement(const Statement&) =delete;
+ Statement(Statement&& other) {
+ stmt = other.stmt;
+ other.stmt = nullptr;
+ }
~Statement();
// Bind several parameters in a single call. They are bound
@@ -98,7 +103,7 @@ private:
}
};
template
- friend class FetchMarshaller;
+ friend struct FetchMarshaller;
bool row();
@@ -114,6 +119,9 @@ private:
// Bind value specializations
void bindValue(int i, int e);
+ void bindValue(int i, uint e);
+ void bindValue(int i, int64_t e);
+ void bindValue(int i, uint64_t e);
void bindValue(int i, const char* e);
void bindValue(int i, const std::string& e);
@@ -140,6 +148,8 @@ private:
template<> std::string Database::Statement::fetchColumn(int col);
template<> const char* Database::Statement::fetchColumn(int col);
template<> int Database::Statement::fetchColumn(int col);
-template<> time_t Database::Statement::fetchColumn(int col);
+template<> uint Database::Statement::fetchColumn(int col);
+template<> int64_t Database::Statement::fetchColumn(int col);
+template<> uint64_t Database::Statement::fetchColumn(int col);
-#endif // _LAMINAR_DATABASE_H_
+#endif // LAMINAR_DATABASE_H_
diff --git a/src/interface.h b/src/interface.h
index e430f6d..748dc59 100644
--- a/src/interface.h
+++ b/src/interface.h
@@ -16,8 +16,8 @@
/// You should have received a copy of the GNU General Public License
/// along with Laminar. If not, see
///
-#ifndef INTERFACE_H
-#define INTERFACE_H
+#ifndef LAMINAR_INTERFACE_H_
+#define LAMINAR_INTERFACE_H_
#include "run.h"
@@ -39,33 +39,34 @@ struct MonitorScope {
LOG // a run's log page
};
- MonitorScope(Type type = HOME, std::string job = std::string(), int num = 0) :
+ MonitorScope(Type type = HOME, std::string job = std::string(), uint num = 0) :
type(type),
job(job),
num(num)
{}
// whether this scope wants status information about the given job or run
- bool wantsStatus(std::string ajob, int anum = 0) const {
+ bool wantsStatus(std::string ajob, uint anum = 0) const {
if(type == HOME || type == ALL) return true;
if(type == JOB) return ajob == job;
if(type == RUN) return ajob == job && anum == num;
return false;
}
- bool wantsLog(std::string ajob, int anum) const {
+ bool wantsLog(std::string ajob, uint anum) const {
return type == LOG && ajob == job && anum == num;
}
Type type;
std::string job;
- int num = 0;
+ uint num = 0;
};
// Represents a (websocket) client that wants to be notified about events
// matching the supplied scope. Pass instances of this to LaminarInterface
// registerClient and deregisterClient
struct LaminarClient {
+ virtual ~LaminarClient() =default;
virtual void sendMessage(std::string payload) = 0;
MonitorScope scope;
};
@@ -74,6 +75,7 @@ struct LaminarClient {
// Pass instances of this to LaminarInterface registerWaiter and
// deregisterWaiter
struct LaminarWaiter {
+ virtual ~LaminarWaiter() =default;
virtual void complete(const Run*) = 0;
};
@@ -81,6 +83,8 @@ struct LaminarWaiter {
// logic. These methods fulfil the requirements of both the HTTP/Websocket
// and RPC interfaces.
struct LaminarInterface {
+ virtual ~LaminarInterface() =default;
+
// Queues a job, returns immediately. Return value will be nullptr if
// the supplied name is not a known job.
virtual std::shared_ptr queueJob(std::string name, ParamMap params = ParamMap()) = 0;
@@ -110,7 +114,7 @@ struct LaminarInterface {
// Implements the laminar client interface allowing the setting of
// arbitrary parameters on a run (usually itself) to be available in
// the environment of subsequent scripts.
- virtual bool setParam(std::string job, int buildNum, std::string param, std::string value) = 0;
+ virtual bool setParam(std::string job, uint buildNum, std::string param, std::string value) = 0;
// Fetches the content of an artifact given its filename relative to
// $LAMINAR_HOME/archive. This shouldn't be used, because the sysadmin
@@ -118,5 +122,5 @@ struct LaminarInterface {
virtual bool getArtefact(std::string path, std::string& result) = 0;
};
-#endif // INTERFACE_H
+#endif // LAMINAR_INTERFACE_H_
diff --git a/src/laminar.cpp b/src/laminar.cpp
index 0c18f31..459d482 100644
--- a/src/laminar.cpp
+++ b/src/laminar.cpp
@@ -51,6 +51,7 @@ private:
template<> Json& Json::set(const char* key, const char* value) { String(key); String(value); return *this; }
template<> Json& Json::set(const char* key, std::string value) { String(key); String(value.c_str()); return *this; }
template<> Json& Json::set(const char* key, int value) { String(key); Int(value); return *this; }
+template<> Json& Json::set(const char* key, uint value) { String(key); Int(static_cast(value)); return *this; }
template<> Json& Json::set(const char* key, time_t value) { String(key); Int64(value); return *this; }
namespace {
@@ -89,7 +90,7 @@ Laminar::Laminar() {
// retrieve the last build numbers
db->stmt("SELECT name, MAX(number) FROM builds GROUP BY name")
- .fetch([this](str name, int build){
+ .fetch([this](str name, uint build){
buildNums[name] = build;
});
@@ -116,7 +117,7 @@ void Laminar::deregisterWaiter(LaminarWaiter *waiter) {
waiters.erase(waiter);
}
-bool Laminar::setParam(std::string job, int buildNum, std::string param, std::string value) {
+bool Laminar::setParam(std::string job, uint buildNum, std::string param, std::string value) {
if(Run* run = activeRun(job, buildNum)) {
run->params[param] = value;
return true;
@@ -125,11 +126,11 @@ bool Laminar::setParam(std::string job, int buildNum, std::string param, std::st
}
-void Laminar::populateArtifacts(Json &j, std::string job, int num) const {
+void Laminar::populateArtifacts(Json &j, std::string job, uint num) const {
fs::path dir(fs::path(homeDir)/"archive"/job/std::to_string(num));
if(fs::is_directory(dir)) {
- int prefixLen = (fs::path(homeDir)/"archive").string().length();
- int scopeLen = dir.string().length();
+ size_t prefixLen = (fs::path(homeDir)/"archive").string().length();
+ size_t scopeLen = dir.string().length();
for(fs::recursive_directory_iterator it(dir); it != fs::recursive_directory_iterator(); ++it) {
if(!fs::is_regular_file(*it))
continue;
@@ -150,10 +151,10 @@ void Laminar::sendStatus(LaminarClient* client) {
db->stmt("SELECT output, outputLen FROM builds WHERE name = ? AND number = ?")
.bind(client->scope.job, client->scope.num)
.fetch([=](str maybeZipped, unsigned long sz) {
- std::string log(sz+1,'\0');
+ str log(sz+1,'\0');
if(sz >= COMPRESS_LOG_MIN_SIZE) {
- int res = ::uncompress((unsigned char*)&log[0], &sz,
- (unsigned char*)maybeZipped.data(), maybeZipped.size());
+ int res = ::uncompress((uint8_t*) log.data(), &sz,
+ (const uint8_t*) maybeZipped.data(), maybeZipped.size());
if(res == Z_OK)
client->sendMessage(log);
else
@@ -187,7 +188,7 @@ void Laminar::sendStatus(LaminarClient* client) {
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 lastRuntime){
+ .fetch([&](uint lastRuntime){
j.set("etc", run->startedAt + lastRuntime);
});
}
@@ -199,7 +200,7 @@ void Laminar::sendStatus(LaminarClient* client) {
j.startArray("recent");
db->stmt("SELECT number,startedAt,completedAt,result,reason FROM builds WHERE name = ? ORDER BY completedAt DESC LIMIT 25")
.bind(client->scope.job)
- .fetch([&](int build,time_t started,time_t completed,int result,str reason){
+ .fetch([&](uint build,time_t started,time_t completed,int result,str reason){
j.StartObject();
j.set("number", build)
.set("completed", completed)
@@ -210,7 +211,7 @@ void Laminar::sendStatus(LaminarClient* client) {
});
j.EndArray();
j.startArray("running");
- auto p = activeJobs.get<4>().equal_range(client->scope.job);
+ auto p = activeJobs.byJobName().equal_range(client->scope.job);
for(auto it = p.first; it != p.second; ++it) {
const std::shared_ptr run = *it;
j.StartObject();
@@ -223,7 +224,7 @@ void Laminar::sendStatus(LaminarClient* client) {
}
j.EndArray();
int nQueued = 0;
- for(const std::shared_ptr run : queuedJobs) {
+ for(const auto& run : queuedJobs) {
if (run->name == client->scope.job) {
nQueued++;
}
@@ -247,7 +248,7 @@ void Laminar::sendStatus(LaminarClient* client) {
} else if(client->scope.type == MonitorScope::ALL) {
j.startArray("jobs");
db->stmt("SELECT name,number,startedAt,completedAt,result FROM builds GROUP BY name ORDER BY number DESC")
- .fetch([&](str name,int number, time_t started, time_t completed, int result){
+ .fetch([&](str name,uint number, time_t started, time_t completed, int result){
j.StartObject();
j.set("name", name);
j.set("number", number);
@@ -263,7 +264,7 @@ void Laminar::sendStatus(LaminarClient* client) {
});
j.EndArray();
j.startArray("running");
- for(const std::shared_ptr run : activeJobs.get<3>()) {
+ for(const auto& run : activeJobs.byStartedAt()) {
j.StartObject();
j.set("name", run->name);
j.set("number", run->build);
@@ -280,7 +281,7 @@ void Laminar::sendStatus(LaminarClient* client) {
} else { // Home page
j.startArray("recent");
db->stmt("SELECT * FROM builds ORDER BY completedAt DESC LIMIT 15")
- .fetch([&](str name,int build,str node,time_t,time_t started,time_t completed,int result){
+ .fetch([&](str name,uint build,str node,time_t,time_t started,time_t completed,int result){
j.StartObject();
j.set("name", name)
.set("number", build)
@@ -292,7 +293,7 @@ void Laminar::sendStatus(LaminarClient* client) {
});
j.EndArray();
j.startArray("running");
- for(const std::shared_ptr run : activeJobs.get<3>()) {
+ for(const auto& run : activeJobs.byStartedAt()) {
j.StartObject();
j.set("name", run->name);
j.set("number", run->build);
@@ -300,14 +301,14 @@ void Laminar::sendStatus(LaminarClient* client) {
j.set("started", run->startedAt);
db->stmt("SELECT completedAt - startedAt FROM builds WHERE name = ? ORDER BY completedAt DESC LIMIT 1")
.bind(run->name)
- .fetch([&](int lastRuntime){
+ .fetch([&](uint lastRuntime){
j.set("etc", run->startedAt + lastRuntime);
});
j.EndObject();
}
j.EndArray();
j.startArray("queued");
- for(const std::shared_ptr run : queuedJobs) {
+ for(const auto& run : queuedJobs) {
j.StartObject();
j.set("name", run->name);
j.EndObject();
@@ -326,7 +327,7 @@ void Laminar::sendStatus(LaminarClient* client) {
for(int i = 6; i >= 0; --i) {
j.StartObject();
db->stmt("SELECT result, COUNT(*) FROM builds WHERE completedAt > ? AND completedAt < ? GROUP by result")
- .bind(86400*(time(0)/86400 - i), 86400*(time(0)/86400 - (i-1)))
+ .bind(86400*(time(nullptr)/86400 - i), 86400*(time(nullptr)/86400 - (i-1)))
.fetch([&](int result, int num){
j.set(to_string(RunState(result)).c_str(), num);
});
@@ -335,15 +336,15 @@ void Laminar::sendStatus(LaminarClient* client) {
j.EndArray();
j.startObject("buildsPerJob");
db->stmt("SELECT name, COUNT(*) FROM builds WHERE completedAt > ? GROUP BY name")
- .bind(time(0) - 86400)
+ .bind(time(nullptr) - 86400)
.fetch([&](str job, int count){
j.set(job.c_str(), count);
});
j.EndObject();
j.startObject("timePerJob");
db->stmt("SELECT name, AVG(completedAt-startedAt) FROM builds WHERE completedAt > ? GROUP BY name")
- .bind(time(0) - 7 * 86400)
- .fetch([&](str job, int time){
+ .bind(time(nullptr) - 7 * 86400)
+ .fetch([&](str job, uint time){
j.set(job.c_str(), time);
});
j.EndObject();
@@ -369,10 +370,10 @@ void Laminar::run() {
sigset_t mask;
sigemptyset(&mask);
sigaddset(&mask, SIGCHLD);
- sigprocmask(SIG_BLOCK, &mask, NULL);
+ sigprocmask(SIG_BLOCK, &mask, nullptr);
int sigchld = signalfd(-1, &mask, SFD_NONBLOCK|SFD_CLOEXEC);
- srv->addDescriptor(sigchld, [this](const char* buf, size_t sz){
- struct signalfd_siginfo* siginfo = (struct signalfd_siginfo*) buf;
+ srv->addDescriptor(sigchld, [this](const char* buf, size_t){
+ const struct signalfd_siginfo* siginfo = reinterpret_cast(buf);
// TODO: re-enable assertion when the cause for its triggering
// is discovered and solved
//KJ_ASSERT(siginfo->ssi_signo == SIGCHLD);
@@ -394,7 +395,7 @@ void Laminar::stop() {
bool Laminar::loadConfiguration() {
if(const char* ndirs = getenv("LAMINAR_KEEP_RUNDIRS"))
- numKeepRunDirs = atoi(ndirs);
+ numKeepRunDirs = static_cast(atoi(ndirs));
NodeMap nm;
@@ -467,7 +468,7 @@ std::shared_ptr Laminar::queueJob(std::string name, ParamMap params) {
std::shared_ptr run = std::make_shared();
run->name = name;
- run->queuedAt = time(0);
+ run->queuedAt = time(nullptr);
for(auto it = params.begin(); it != params.end();) {
if(it->first[0] == '=') {
if(it->first == "=parentJob") {
@@ -525,21 +526,22 @@ void Laminar::handleRunLog(std::shared_ptr run, std::string s) {
void Laminar::reapAdvance() {
int ret = 0;
pid_t pid;
- static thread_local char buf[1024];
+ constexpr int bufsz = 1024;
+ static thread_local char buf[bufsz];
while((pid = waitpid(-1, &ret, WNOHANG)) > 0) {
LLOG(INFO, "Reaping", pid);
- auto it = activeJobs.get<0>().find(pid);
+ auto it = activeJobs.byPid().find(pid);
std::shared_ptr run = *it;
// The main event loop might schedule this SIGCHLD handler before the final
// output handler (from addDescriptor). In that case, because it keeps a
// shared_ptr to the run it would successfully add to the log output buffer,
// but by then reapAdvance would have stored the log and ensured no-one cares.
// Preempt this case by forcing a final (non-blocking) read here.
- for(ssize_t n = read(run->fd, buf, 1024); n > 0; n = read(run->fd, buf, 1024)) {
- handleRunLog(run, std::string(buf, n));
+ for(ssize_t n = read(run->fd, buf, bufsz); n > 0; n = read(run->fd, buf, bufsz)) {
+ handleRunLog(run, std::string(buf, static_cast(n)));
}
bool completed = true;
- activeJobs.get<0>().modify(it, [&](std::shared_ptr run){
+ activeJobs.byPid().modify(it, [&](std::shared_ptr run){
run->reaped(ret);
completed = stepRun(run);
});
@@ -594,7 +596,7 @@ void Laminar::assignNewJobs() {
run->addScript((cfgDir/"jobs"/run->name+".init").string(), ws.string());
}
- int buildNum = buildNums[run->name] + 1;
+ uint buildNum = buildNums[run->name] + 1;
// create the run directory
fs::path rd = fs::path(homeDir)/"run"/run->name/std::to_string(buildNum);
bool createWorkdir = true;
@@ -654,7 +656,7 @@ void Laminar::assignNewJobs() {
// start the job
node.busyExecutors++;
run->node = &node;
- run->startedAt = time(0);
+ run->startedAt = time(nullptr);
run->laminarHome = homeDir;
run->build = buildNum;
// set the last known result if exists
@@ -680,8 +682,8 @@ void Laminar::assignNewJobs() {
.set("reason", run->reason());
db->stmt("SELECT completedAt - startedAt FROM builds WHERE name = ? ORDER BY completedAt DESC LIMIT 1")
.bind(run->name)
- .fetch([&](int etc){
- j.set("etc", time(0) + etc);
+ .fetch([&](uint etc){
+ j.set("etc", time(nullptr) + etc);
});
j.EndObject();
const char* msg = j.str();
@@ -722,7 +724,7 @@ void Laminar::runFinished(Run * r) {
node->busyExecutors--;
LLOG(INFO, "Run completed", r->name, to_string(r->result));
- time_t completedAt = time(0);
+ time_t completedAt = time(nullptr);
// compress log
std::string maybeZipped = r->log;
@@ -730,8 +732,8 @@ void Laminar::runFinished(Run * r) {
if(r->log.length() >= COMPRESS_LOG_MIN_SIZE) {
std::string zipped(r->log.size(), '\0');
unsigned long zippedSize = zipped.size();
- if(::compress((unsigned char*)&zipped[0], &zippedSize,
- (unsigned char*)&r->log[0], logsize) == Z_OK) {
+ if(::compress((uint8_t*) zipped.data(), &zippedSize,
+ (const uint8_t*) r->log.data(), logsize) == Z_OK) {
zipped.resize(zippedSize);
std::swap(maybeZipped, zipped);
}
@@ -770,7 +772,7 @@ void Laminar::runFinished(Run * r) {
}
// erase reference to run from activeJobs
- activeJobs.get<2>().erase(r);
+ activeJobs.byRunPtr().erase(r);
// remove old run directories
// We cannot count back the number of directories to keep from the currently
@@ -780,9 +782,9 @@ void Laminar::runFinished(Run * r) {
// from the oldest among them. If there are none, count back from the latest
// known build number of this job, which may not be that of the run that
// finished here.
- auto it = activeJobs.get<4>().equal_range(r->name);
+ auto it = activeJobs.byJobName().equal_range(r->name);
uint oldestActive = (it.first == it.second)? buildNums[r->name] : (*it.first)->build - 1;
- for(int i = oldestActive - numKeepRunDirs; i > 0; i--) {
+ for(int i = static_cast(oldestActive - numKeepRunDirs); i > 0; i--) {
fs::path d = fs::path(homeDir)/"run"/r->name/std::to_string(i);
// Once the directory does not exist, it's probably not worth checking
// any further. 99% of the time this loop should only ever have 1 iteration
@@ -806,9 +808,9 @@ bool Laminar::getArtefact(std::string path, std::string& result) {
return false;
std::ifstream fstr(file.string());
fstr.seekg(0, std::ios::end);
- size_t sz = fstr.tellg();
- if(fstr.rdstate() == 0) {
- result.resize(sz);
+ ssize_t sz = fstr.tellg();
+ if(fstr.good()) {
+ result.resize(static_cast(sz));
fstr.seekg(0);
fstr.read(&result[0], sz);
return true;
diff --git a/src/laminar.h b/src/laminar.h
index 4419d7a..00fe9fa 100644
--- a/src/laminar.h
+++ b/src/laminar.h
@@ -16,8 +16,8 @@
/// You should have received a copy of the GNU General Public License
/// along with Laminar. If not, see
///
-#ifndef _LAMINAR_LAMINAR_H_
-#define _LAMINAR_LAMINAR_H_
+#ifndef LAMINAR_LAMINAR_H_
+#define LAMINAR_LAMINAR_H_
#include "interface.h"
#include "run.h"
@@ -39,7 +39,7 @@ class Json;
class Laminar final : public LaminarInterface {
public:
Laminar();
- ~Laminar();
+ ~Laminar() override;
// Runs the application forever
void run();
@@ -54,7 +54,7 @@ public:
void deregisterWaiter(LaminarWaiter* waiter) override;
void sendStatus(LaminarClient* client) override;
- bool setParam(std::string job, int buildNum, std::string param, std::string value) override;
+ bool setParam(std::string job, uint buildNum, std::string param, std::string value) override;
bool getArtefact(std::string path, std::string& result) override;
private:
@@ -66,11 +66,11 @@ private:
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;
+ void populateArtifacts(Json& out, std::string job, uint num) const;
- Run* activeRun(std::string name, int num) {
- auto it = activeJobs.get<1>().find(boost::make_tuple(name, num));
- return it == activeJobs.get<1>().end() ? nullptr : it->get();
+ Run* activeRun(std::string name, uint num) {
+ auto it = activeJobs.byRun().find(boost::make_tuple(name, num));
+ return it == activeJobs.byRun().end() ? nullptr : it->get();
}
std::list> queuedJobs;
@@ -90,4 +90,4 @@ private:
std::string archiveUrl;
};
-#endif // _LAMINAR_LAMINAR_H_
+#endif // LAMINAR_LAMINAR_H_
diff --git a/src/log.h b/src/log.h
index 1632f62..8cc3a2c 100644
--- a/src/log.h
+++ b/src/log.h
@@ -16,8 +16,8 @@
/// You should have received a copy of the GNU General Public License
/// along with Laminar. If not, see
///
-#ifndef _LAMINAR_LOG_H_
-#define _LAMINAR_LOG_H_
+#ifndef LAMINAR_LOG_H_
+#define LAMINAR_LOG_H_
#include
@@ -33,5 +33,5 @@
#__VA_ARGS__, __VA_ARGS__)
-#endif // _LAMINAR_LOG_H_
+#endif // LAMINAR_LOG_H_
diff --git a/src/node.h b/src/node.h
index e414ddc..342a39c 100644
--- a/src/node.h
+++ b/src/node.h
@@ -16,8 +16,8 @@
/// You should have received a copy of the GNU General Public License
/// along with Laminar. If not, see
///
-#ifndef _LAMINAR_NODE_H_
-#define _LAMINAR_NODE_H_
+#ifndef LAMINAR_NODE_H_
+#define LAMINAR_NODE_H_
#include
#include
@@ -40,4 +40,4 @@ public:
};
-#endif // _LAMINAR_NODE_H_
+#endif // LAMINAR_NODE_H_
diff --git a/src/resources.h b/src/resources.h
index 4eeaf05..969a228 100644
--- a/src/resources.h
+++ b/src/resources.h
@@ -16,8 +16,8 @@
/// You should have received a copy of the GNU General Public License
/// along with Laminar. If not, see
///
-#ifndef _LAMINAR_RESOURCES_H_
-#define _LAMINAR_RESOURCES_H_
+#ifndef LAMINAR_RESOURCES_H_
+#define LAMINAR_RESOURCES_H_
#include
#include
@@ -43,4 +43,4 @@ private:
std::unordered_map resources;
};
-#endif // _LAMINAR_RESOURCES_H_
+#endif // LAMINAR_RESOURCES_H_
diff --git a/src/resources/js/app.js b/src/resources/js/app.js
index 40667f0..57e45f2 100644
--- a/src/resources/js/app.js
+++ b/src/resources/js/app.js
@@ -430,7 +430,7 @@ const Run = function() {
};
var firstLog = false;
var logHandler = function(vm, d) {
- state.log += ansi_up.ansi_to_html(d);
+ state.log += ansi_up.ansi_to_html(d.replace(//g,'>'));
vm.$forceUpdate();
if (!firstLog) {
firstLog = true;
diff --git a/src/run.cpp b/src/run.cpp
index 26ba65b..f660195 100644
--- a/src/run.cpp
+++ b/src/run.cpp
@@ -35,7 +35,6 @@ std::string to_string(const RunState& rs) {
case RunState::ABORTED: return "aborted";
case RunState::FAILED: return "failed";
case RunState::SUCCESS: return "success";
- case RunState::UNKNOWN:
default:
return "unknown";
}
@@ -74,7 +73,7 @@ bool Run::step() {
sigset_t mask;
sigemptyset(&mask);
sigaddset(&mask, SIGCHLD);
- sigprocmask(SIG_UNBLOCK, &mask, NULL);
+ sigprocmask(SIG_UNBLOCK, &mask, nullptr);
close(pfd[0]);
dup2(pfd[1], 1);
diff --git a/src/run.h b/src/run.h
index 551744a..def04e3 100644
--- a/src/run.h
+++ b/src/run.h
@@ -16,8 +16,8 @@
/// You should have received a copy of the GNU General Public License
/// along with Laminar. If not, see
///
-#ifndef _LAMINAR_RUN_H_
-#define _LAMINAR_RUN_H_
+#ifndef LAMINAR_RUN_H_
+#define LAMINAR_RUN_H_
#include
#include
@@ -81,7 +81,7 @@ public:
std::string parentName;
int parentBuild = 0;
std::string reasonMsg;
- int build = 0;
+ uint build = 0;
std::string log;
pid_t pid;
int fd;
@@ -132,7 +132,7 @@ struct _run_index : bmi::indexed_by<
std::shared_ptr,
// a combination of their job name and build number
bmi::member,
- bmi::member
+ bmi::member
>>,
// or a pointer to a Run object.
bmi::hashed_unique<_run_same>,
@@ -147,7 +147,20 @@ struct RunSet: public boost::multi_index_container<
std::shared_ptr,
_run_index
> {
- // TODO: getters for each index
+ typename bmi::nth_index::type& byPid() { return get<0>(); }
+ typename bmi::nth_index::type const& byPid() const { return get<0>(); }
+
+ typename bmi::nth_index::type& byRun() { return get<1>(); }
+ typename bmi::nth_index::type const& byRun() const { return get<1>(); }
+
+ typename bmi::nth_index::type& byRunPtr() { return get<2>(); }
+ typename bmi::nth_index::type const& byRunPtr() const { return get<2>(); }
+
+ typename bmi::nth_index::type& byStartedAt() { return get<3>(); }
+ typename bmi::nth_index::type const& byStartedAt() const { return get<3>(); }
+
+ typename bmi::nth_index::type& byJobName() { return get<4>(); }
+ typename bmi::nth_index::type const& byJobName() const { return get<4>(); }
};
-#endif // _LAMINAR_RUN_H_
+#endif // LAMINAR_RUN_H_
diff --git a/src/server.cpp b/src/server.cpp
index 8a4c09b..e22d44e 100644
--- a/src/server.cpp
+++ b/src/server.cpp
@@ -83,7 +83,7 @@ public:
laminar.registerWaiter(this);
}
- ~RpcImpl() {
+ ~RpcImpl() override {
laminar.deregisterWaiter(this);
}
@@ -125,7 +125,7 @@ public:
// Set a parameter on a running build
kj::Promise set(SetContext context) override {
std::string jobName = context.getParams().getJobName();
- int buildNum = context.getParams().getBuildNum();
+ uint buildNum = context.getParams().getBuildNum();
LLOG(INFO, "RPC set", jobName, buildNum);
LaminarCi::MethodResult result = laminar.setParam(jobName, buildNum,
@@ -170,7 +170,6 @@ private:
}
private:
LaminarInterface& laminar;
- kj::LowLevelAsyncIoProvider* asyncio;
std::unordered_map>> locks;
std::unordered_map>> runWaiters;
};
@@ -235,17 +234,17 @@ public:
c->lc->scope.type = MonitorScope::ALL;
} else {
res = res.substr(5);
- int split = res.find('/',1);
+ size_t split = res.find('/',1);
std::string job = res.substr(1,split-1);
if(!job.empty()) {
c->lc->scope.job = job;
c->lc->scope.type = MonitorScope::JOB;
}
if(split != std::string::npos) {
- int split2 = res.find('/', split+1);
+ size_t split2 = res.find('/', split+1);
std::string run = res.substr(split+1, split2-split);
if(!run.empty()) {
- c->lc->scope.num = atoi(run.c_str());
+ c->lc->scope.num = static_cast(atoi(run.c_str()));
c->lc->scope.type = MonitorScope::RUN;
}
if(split2 != std::string::npos && res.compare(split2, 4, "/log") == 0) {
@@ -311,8 +310,7 @@ struct Server::WebsocketConnection : public LaminarClient {
cn->start();
}
- virtual ~WebsocketConnection() noexcept(true) {
- }
+ virtual ~WebsocketConnection() noexcept(true) override {}
kj::Promise pend() {
return stream->tryRead(ibuf, 1, sizeof(ibuf)).then([this](size_t sz){
@@ -413,8 +411,8 @@ void Server::acceptHttpClient(kj::Own&& listener) {
acceptHttpClient(kj::mv(listener));
auto conn = kj::heap(kj::mv(connection), *httpInterface);
auto promises = kj::heapArrayBuilder>(2);
- promises.add(std::move(conn->pend()));
- promises.add(std::move(conn->writeTask()));
+ promises.add(conn->pend());
+ promises.add(conn->writeTask());
return kj::joinPromises(promises.finish()).attach(std::move(conn));
}))
);
diff --git a/src/server.h b/src/server.h
index 63b4169..ffc70a4 100644
--- a/src/server.h
+++ b/src/server.h
@@ -16,8 +16,8 @@
/// You should have received a copy of the GNU General Public License
/// along with Laminar. If not, see
///
-#ifndef _LAMINAR_SERVER_H_
-#define _LAMINAR_SERVER_H_
+#ifndef LAMINAR_SERVER_H_
+#define LAMINAR_SERVER_H_
#include
#include
@@ -54,7 +54,7 @@ private:
private:
struct WebsocketConnection;
- struct HttpImpl;
+ class HttpImpl;
int efd_quit;
capnp::Capability::Client rpcInterface;
@@ -63,4 +63,4 @@ private:
kj::TaskSet tasks;
};
-#endif // _LAMINAR_SERVER_H_
+#endif // LAMINAR_SERVER_H_