1
0
mirror of https://github.com/ohwgiles/laminar.git synced 2026-03-02 03:40:21 +00:00

resolves #67: laminarc list jobs

Implements the following laminarc commands:
- show-jobs
- show-running
- show-queued
- abort
This commit is contained in:
Oliver Giles
2018-10-12 17:22:21 +03:00
parent 21284731a3
commit 7cee824cee
8 changed files with 161 additions and 6 deletions

View File

@@ -173,8 +173,8 @@ int main(int argc, char** argv) {
char* name = argv[2];
*eq++ = '\0';
char* val = eq;
req.setJobName(job);
req.setBuildNum(atoi(num));
req.getRun().setJob(job);
req.getRun().setBuildNum(atoi(num));
req.getParam().setName(name);
req.getParam().setValue(val);
req.send().wait(waitScope);
@@ -182,6 +182,40 @@ int main(int argc, char** argv) {
fprintf(stderr, "Missing $JOB or $RUN or param is not in the format key=value\n");
return EINVAL;
}
} else if(strcmp(argv[1], "abort") == 0) {
if(argc != 4) {
fprintf(stderr, "Usage %s abort <jobName> <jobNumber>\n", argv[0]);
return EINVAL;
}
auto req = laminar.abortRequest();
req.getRun().setJob(argv[2]);
req.getRun().setBuildNum(atoi(argv[3]));
if(req.send().wait(waitScope).getResult() != LaminarCi::MethodResult::SUCCESS)
ret = EFAILED;
} else if(strcmp(argv[1], "show-jobs") == 0) {
if(argc != 2) {
fprintf(stderr, "Usage: %s show-jobs\n", argv[0]);
return EINVAL;
}
for(auto it : laminar.listKnownRequest().send().wait(waitScope).getResult()) {
printf("%s\n", it.cStr());
}
} else if(strcmp(argv[1], "show-queued") == 0) {
if(argc != 2) {
fprintf(stderr, "Usage: %s show-queued\n", argv[0]);
return EINVAL;
}
for(auto it : laminar.listQueuedRequest().send().wait(waitScope).getResult()) {
printf("%s\n", it.cStr());
}
} else if(strcmp(argv[1], "show-running") == 0) {
if(argc != 2) {
fprintf(stderr, "Usage: %s show-running\n", argv[0]);
return EINVAL;
}
for(auto it : laminar.listRunningRequest().send().wait(waitScope).getResult()) {
printf("%s:%d\n", it.getJob().cStr(), it.getBuildNum());
}
} else {
fprintf(stderr, "Unknown command %s\n", argv[1]);
return EINVAL;

View File

@@ -128,6 +128,15 @@ struct LaminarInterface {
// the environment of subsequent scripts.
virtual bool setParam(std::string job, uint buildNum, std::string param, std::string value) = 0;
// Gets the list of jobs currently waiting in the execution queue
virtual const std::list<std::shared_ptr<Run>>& listQueuedJobs() = 0;
// Gets the list of currently executing jobs
virtual const RunSet& listRunningJobs() = 0;
// Gets the list of known jobs - scans cfg/jobs for *.run files
virtual std::list<std::string> listKnownJobs() = 0;
// Fetches the content of an artifact given its filename relative to
// $LAMINAR_HOME/archive. Ideally, this would instead be served by a
// proper web server which handles this url.
@@ -143,6 +152,9 @@ struct LaminarInterface {
// which handles this url.
virtual std::string getCustomCss() = 0;
// Aborts a single job
virtual bool abort(std::string job, uint buildNum) = 0;
// Abort all running jobs
virtual void abortAll() = 0;

View File

@@ -5,7 +5,16 @@ interface LaminarCi {
queue @0 (jobName :Text, params :List(JobParam)) -> (result :MethodResult);
start @1 (jobName :Text, params :List(JobParam)) -> (result :MethodResult, buildNum :UInt32);
run @2 (jobName :Text, params :List(JobParam)) -> (result :JobResult, buildNum :UInt32);
set @3 (jobName :Text, buildNum :UInt32, param :JobParam) -> (result :MethodResult);
set @3 (run :Run, param :JobParam) -> (result :MethodResult);
listQueued @4 () -> (result :List(Text));
listRunning @5 () -> (result :List(Run));
listKnown @6 () -> (result :List(Text));
abort @7 (run :Run) -> (result :MethodResult);
struct Run {
job @0 :Text;
buildNum @1 :UInt32;
}
struct JobParam {
name @0 :Text;

View File

@@ -130,6 +130,25 @@ bool Laminar::setParam(std::string job, uint buildNum, std::string param, std::s
return false;
}
const std::list<std::shared_ptr<Run>>& Laminar::listQueuedJobs() {
return queuedJobs;
}
const RunSet& Laminar::listRunningJobs() {
return activeJobs;
}
std::list<std::string> Laminar::listKnownJobs() {
std::list<std::string> res;
KJ_IF_MAYBE(dir, fsHome->tryOpenSubdir(kj::Path{"cfg","jobs"})) {
for(kj::Directory::Entry& entry : (*dir)->listEntries()) {
if(entry.type == kj::FsNode::Type::FILE && entry.name.endsWith(".run")) {
res.emplace_back(entry.name.cStr(), entry.name.findLast('.').orDefault(0));
}
}
}
return res;
}
void Laminar::populateArtifacts(Json &j, std::string job, uint num) const {
kj::Path runArchive{job,std::to_string(num)};
@@ -575,6 +594,14 @@ void Laminar::notifyConfigChanged()
assignNewJobs();
}
bool Laminar::abort(std::string job, uint buildNum) {
if(Run* run = activeRun(job, buildNum)) {
run->abort(true);
return true;
}
return false;
}
void Laminar::abortAll() {
for(std::shared_ptr<Run> run : activeJobs) {
run->abort(false);

View File

@@ -56,9 +56,13 @@ public:
void sendStatus(LaminarClient* client) override;
bool setParam(std::string job, uint buildNum, std::string param, std::string value) override;
const std::list<std::shared_ptr<Run>>& listQueuedJobs() override;
const RunSet& listRunningJobs() override;
std::list<std::string> listKnownJobs() override;
kj::Maybe<kj::Own<const kj::ReadableFile>> getArtefact(std::string path) override;
bool handleBadgeRequest(std::string job, std::string& badge) override;
std::string getCustomCss() override;
bool abort(std::string job, uint buildNum) override;
void abortAll() override;
void notifyConfigChanged() override;

View File

@@ -117,8 +117,8 @@ public:
// Set a parameter on a running build
kj::Promise<void> set(SetContext context) override {
std::string jobName = context.getParams().getJobName();
uint buildNum = context.getParams().getBuildNum();
std::string jobName = context.getParams().getRun().getJob();
uint buildNum = context.getParams().getRun().getBuildNum();
LLOG(INFO, "RPC set", jobName, buildNum);
LaminarCi::MethodResult result = laminar.setParam(jobName, buildNum,
@@ -129,6 +129,52 @@ public:
return kj::READY_NOW;
}
// List jobs in queue
kj::Promise<void> listQueued(ListQueuedContext context) override {
const std::list<std::shared_ptr<Run>>& queue = laminar.listQueuedJobs();
auto res = context.getResults().initResult(queue.size());
int i = 0;
for(auto it : queue) {
res.set(i++, it->name);
}
return kj::READY_NOW;
}
// List running jobs
kj::Promise<void> listRunning(ListRunningContext context) override {
const RunSet& active = laminar.listRunningJobs();
auto res = context.getResults().initResult(active.size());
int i = 0;
for(auto it : active) {
res[i].setJob(it->name);
res[i].setBuildNum(it->build);
i++;
}
return kj::READY_NOW;
}
// List known jobs
kj::Promise<void> listKnown(ListKnownContext context) override {
std::list<std::string> known = laminar.listKnownJobs();
auto res = context.getResults().initResult(known.size());
int i = 0;
for(auto it : known) {
res.set(i++, it);
}
return kj::READY_NOW;
}
kj::Promise<void> abort(AbortContext context) override {
std::string jobName = context.getParams().getRun().getJob();
uint buildNum = context.getParams().getRun().getBuildNum();
LLOG(INFO, "RPC abort", jobName, buildNum);
LaminarCi::MethodResult result = laminar.abort(jobName, buildNum)
? LaminarCi::MethodResult::SUCCESS
: LaminarCi::MethodResult::FAILED;
context.getResults().setResult(result);
return kj::READY_NOW;
}
private:
// Helper to convert an RPC parameter list to a hash map
ParamMap params(const capnp::List<LaminarCi::JobParam>::Reader& paramReader) {