diff --git a/CMakeLists.txt b/CMakeLists.txt index ff3b6f2..e2eb1fa 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -25,6 +25,19 @@ set(CMAKE_INCLUDE_CURRENT_DIR ON) add_definitions("-std=c++17 -Wall -Wextra -Wno-unused-parameter -Wno-sign-compare") set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -Werror -DDEBUG") +# Allow passing in the version string, for e.g. patched/packaged versions +if(NOT LAMINAR_VERSION AND EXISTS ${CMAKE_SOURCE_DIR}/.git) + execute_process(COMMAND git describe --tags --abbrev=8 --dirty + WORKING_DIRECTORY ${CMAKE_SOURCE_DIR} + OUTPUT_VARIABLE LAMINAR_VERSION + OUTPUT_STRIP_TRAILING_WHITESPACE) +endif() +if(NOT LAMINAR_VERSION) + set(LAMINAR_VERSION xx-unversioned) +endif() +set_source_files_properties(src/version.cpp PROPERTIES COMPILE_DEFINITIONS + LAMINAR_VERSION=${LAMINAR_VERSION}) + # This macro takes a list of files, gzips them and converts the output into # object files so they can be linked directly into the application. # ld generates symbols based on the string argument given to its executable, @@ -93,6 +106,7 @@ set(LAMINARD_CORE_SOURCES src/rpc.cpp src/run.cpp src/server.cpp + src/version.cpp laminar.capnp.c++ index_html_size.h ) @@ -102,7 +116,7 @@ add_executable(laminard ${LAMINARD_CORE_SOURCES} src/main.cpp ${COMPRESSED_BINS} target_link_libraries(laminard capnp-rpc capnp kj-http kj-async kj pthread sqlite3 z) ## Client -add_executable(laminarc src/client.cpp laminar.capnp.c++) +add_executable(laminarc src/client.cpp src/version.cpp laminar.capnp.c++) target_link_libraries(laminarc capnp-rpc capnp kj-async kj pthread) ## Tests diff --git a/pkg/centos7-x86_64.sh b/pkg/centos7-x86_64.sh index b72e6f4..77932c4 100755 --- a/pkg/centos7-x86_64.sh +++ b/pkg/centos7-x86_64.sh @@ -54,7 +54,7 @@ Lightweight Continuous Integration Service %prep %build -cmake3 -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=/usr -DSYSTEMD_UNITDIR=%{_unitdir} %{_sourcedir}/laminar-$VERSION +cmake3 -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=/usr -DLAMINAR_VERSION=$VERSION -DSYSTEMD_UNITDIR=%{_unitdir} %{_sourcedir}/laminar-$VERSION pwd make diff --git a/pkg/centos8-x86_64.sh b/pkg/centos8-x86_64.sh index a2f41c1..ac1e486 100755 --- a/pkg/centos8-x86_64.sh +++ b/pkg/centos8-x86_64.sh @@ -51,7 +51,7 @@ Lightweight Continuous Integration Service %prep %build -cmake -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=/usr -DSYSTEMD_UNITDIR=%{_unitdir} %{_sourcedir}/laminar-$VERSION +cmake -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=/usr -DLAMINAR_VERSION=$VERSION -DSYSTEMD_UNITDIR=%{_unitdir} %{_sourcedir}/laminar-$VERSION pwd make diff --git a/pkg/debian10-amd64.sh b/pkg/debian10-amd64.sh index 127ed36..3d4e41c 100755 --- a/pkg/debian10-amd64.sh +++ b/pkg/debian10-amd64.sh @@ -17,7 +17,7 @@ docker run --rm -i -v $SOURCE_DIR:/laminar:ro -v $OUTPUT_DIR:/output $DOCKER_TAG mkdir /build cd /build -cmake -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=/usr -DZSH_COMPLETIONS_DIR=/usr/share/zsh/functions/Completion/Unix /laminar +cmake -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=/usr -DLAMINAR_VERSION=$VERSION -DZSH_COMPLETIONS_DIR=/usr/share/zsh/functions/Completion/Unix /laminar make -j4 mkdir laminar make DESTDIR=laminar install/strip diff --git a/pkg/debian10-armhf.sh b/pkg/debian10-armhf.sh index 6010e3e..eac3063 100755 --- a/pkg/debian10-armhf.sh +++ b/pkg/debian10-armhf.sh @@ -31,6 +31,7 @@ cmake \ -DCMAKE_STRIP=/usr/bin/arm-linux-gnueabihf-strip \ -DCMAKE_BUILD_TYPE=Release \ -DCMAKE_INSTALL_PREFIX=/usr \ + -DLAMINAR_VERSION=$VERSION \ -DZSH_COMPLETIONS_DIR=/usr/share/zsh/functions/Completion/Unix \ /laminar make -j4 diff --git a/src/client.cpp b/src/client.cpp index d803e52..1ea9b8b 100644 --- a/src/client.cpp +++ b/src/client.cpp @@ -17,10 +17,12 @@ /// along with Laminar. If not, see /// #include "laminar.capnp.h" +#include "log.h" #include #include +#include #include #include #include @@ -77,11 +79,35 @@ static void printTriggerLink(const char* job, uint run) { printf("\033[{%s:%d\033\\\n", job, run); } +static void usage(std::ostream& out) { + out << "laminarc version " << laminar_version() << "\n"; + out << "Usage: laminarc [-h|--help] COMMAND [PARAMETERS...]]\n"; + out << " -h|--help show this help message\n"; + out << "where COMMAND is:\n"; + out << " queue JOB_LIST... queues one or more jobs for execution and returns immediately.\n"; + out << " start JOB_LIST... queues one or more jobs for execution and blocks until it starts.\n"; + out << " run JOB_LIST... queues one or more jobs for execution and blocks until it finishes.\n"; + out << " set PARAMETER_LIST... sets the given parameters as environment variables in the currently\n"; + out << " runing job. Fails if run outside of a job context.\n"; + out << " abort NAME NUMBER aborts the run identified by NAME and NUMBER.\n"; + out << " show-jobs lists all known jobs.\n"; + out << " show-queued lists currently queued jobs.\n"; + out << " show-running lists currently running jobs.\n"; + out << "JOB_LIST is of the form:\n"; + out << " [JOB_NAME [PARAMETER_LIST...]]...\n"; + out << "PARAMETER_LIST is of the form:\n"; + out << " [KEY=VALUE]...\n"; + out << "Example:\n"; + out << " laminarc start \\\n"; + out << " nightly-build branch=master type=release \\\n"; + out << " nightly-build branch=master type=debug\n"; +} + int main(int argc, char** argv) { - if(argc < 2) { - fprintf(stderr, "Usage: %s [parameters...]\n", argv[0]); - return EXIT_BAD_ARGUMENT; - } + if(argc < 2) + return usage(std::cerr), EXIT_BAD_ARGUMENT; + else if(strcmp("-h", argv[1]) == 0 || strcmp("--help", argv[1]) == 0) + return usage(std::cout), EXIT_SUCCESS; struct: public kj::TaskSet::ErrorHandler { void taskFailed(kj::Exception&& e) override { diff --git a/src/laminar.cpp b/src/laminar.cpp index 191d1bf..2ac59de 100644 --- a/src/laminar.cpp +++ b/src/laminar.cpp @@ -227,6 +227,7 @@ std::string Laminar::getStatus(MonitorScope scope) { Json j; j.set("type", "status"); j.set("title", getenv("LAMINAR_TITLE") ?: "Laminar"); + j.set("version", laminar_version()); j.set("time", time(nullptr)); j.startObject("data"); if(scope.type == MonitorScope::RUN) { diff --git a/src/log.h b/src/log.h index 54020c2..a0ccff4 100644 --- a/src/log.h +++ b/src/log.h @@ -1,5 +1,5 @@ /// -/// Copyright 2015-2019 Oliver Giles +/// Copyright 2015-2020 Oliver Giles /// /// This file is part of Laminar /// @@ -67,5 +67,7 @@ namespace _ { for (::kj::_::Debug::Fault f(__FILE_BASE__, __LINE__, \ _kjSyscallResult.getErrorNumber(), #call, #__VA_ARGS__, ##__VA_ARGS__);; f.fatal()) +const char* laminar_version(); + #endif // LAMINAR_LOG_H_ diff --git a/src/main.cpp b/src/main.cpp index 8b37e26..2b47993 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -20,7 +20,9 @@ #include "leader.h" #include "server.h" #include "log.h" + #include +#include #include #include #include @@ -44,6 +46,13 @@ constexpr const char* INTADDR_HTTP_DEFAULT = "*:8080"; constexpr const char* ARCHIVE_URL_DEFAULT = "/archive/"; } +static void usage(std::ostream& out) { + out << "laminard version " << laminar_version() << "\n"; + out << "Usage:\n"; + out << " -h|--help show this help message\n"; + out << " -v enable verbose output\n"; +} + int main(int argc, char** argv) { if(argv[0][0] == '{') return leader_main(); @@ -51,6 +60,11 @@ int main(int argc, char** argv) { for(int i = 1; i < argc; ++i) { if(strcmp(argv[i], "-v") == 0) { kj::_::Debug::setLogLevel(kj::_::Debug::Severity::INFO); + } else if(strcmp(argv[i], "-h") == 0 || strcmp(argv[i], "--help") == 0) { + return usage(std::cout), EXIT_SUCCESS; + } else { + std::cerr << "Unknown argument " << argv[i] << "\n"; + return usage(std::cerr), EXIT_FAILURE; } } @@ -79,6 +93,8 @@ int main(int argc, char** argv) { signal(SIGINT, &laminar_quit); signal(SIGTERM, &laminar_quit); + printf("laminard version %s started\n", laminar_version()); + server->start(); delete laminar; diff --git a/src/resources/index.html b/src/resources/index.html index f84ebea..cb5a57f 100644 --- a/src/resources/index.html +++ b/src/resources/index.html @@ -177,7 +177,7 @@
-