diff --git a/README.md b/README.md index 53b70fe..77c9701 100644 --- a/README.md +++ b/README.md @@ -66,7 +66,7 @@ For Apache, see [Apache Reverse Proxy](https://httpd.apache.org/docs/2.4/howto/r #### Set the page title -Change `LAMINAR_TITLE` in `/etc/laminar.conf` to your preferred page title. +Change `LAMINAR_TITLE` in `/etc/laminar.conf` to your preferred page title. For further WebUI customization, consider using a [custom style sheet](#customizing-the-webui). #### More configuration options @@ -483,6 +483,11 @@ cmake src make ``` +### Customizing the WebUI + +If it exists, the file `/var/lib/laminar/custom/style.css` will be served by laminar and may be used to change the appearance of Laminar's WebUI. + +This directory is also a good place to add any extra assets needed for this customization, but note that in this case you will need to serve this directory directly from your [HTTP reverse proxy](#service-configuration) (highly recommended). ## Reference diff --git a/src/interface.h b/src/interface.h index 748dc59..313894c 100644 --- a/src/interface.h +++ b/src/interface.h @@ -120,6 +120,11 @@ struct LaminarInterface { // $LAMINAR_HOME/archive. This shouldn't be used, because the sysadmin // should have configured a real webserver to serve these things. virtual bool getArtefact(std::string path, std::string& result) = 0; + + // Fetches the content of $LAMINAR_HOME/custom/style.css or an empty + // string. This shouldn't be used, because the sysadmin should have + // configured a real webserver to serve these things. + virtual std::string getCustomCss() = 0; }; #endif // LAMINAR_INTERFACE_H_ diff --git a/src/laminar.cpp b/src/laminar.cpp index 459d482..4ba989f 100644 --- a/src/laminar.cpp +++ b/src/laminar.cpp @@ -795,25 +795,38 @@ void Laminar::runFinished(Run * r) { } } -bool Laminar::getArtefact(std::string path, std::string& result) { - if(archiveUrl != ARCHIVE_URL_DEFAULT) { - // we shouldn't have got here. Probably an invalid link. - return false; - } - // Reads in the whole file into the given string reference. - // This is a terrible way to serve files (especially large ones). - fs::path file(fs::path(homeDir)/"archive"/path); - // no support for browsing archived directories - if(fs::is_directory(file)) +// Small helper function to return the full contents of a file given its path. +// It reads in the whole file into the given string reference. +// This is a terrible way to serve files (especially large ones). Hopefully +// no-one uses this function and configures their webservers appropriately. +static bool slurp(fs::path path, std::string& output) { + if(!fs::is_regular_file(path)) return false; - std::ifstream fstr(file.string()); + std::ifstream fstr(path.string()); fstr.seekg(0, std::ios::end); ssize_t sz = fstr.tellg(); if(fstr.good()) { - result.resize(static_cast(sz)); + output.resize(static_cast(sz)); fstr.seekg(0); - fstr.read(&result[0], sz); + fstr.read(&output[0], sz); return true; } return false; } + +bool Laminar::getArtefact(std::string path, std::string& result) { + if(archiveUrl != ARCHIVE_URL_DEFAULT) { + // we shouldn't have got here. Probably an invalid link. + return false; + } + fs::path file(fs::path(homeDir)/"archive"/path); + return slurp(file, result); +} + +std::string Laminar::getCustomCss() +{ + fs::path file(fs::path(homeDir)/"custom"/"style.css"); + std::string result; + slurp(file, result); + return result; +} diff --git a/src/laminar.h b/src/laminar.h index 00fe9fa..3a0cbcd 100644 --- a/src/laminar.h +++ b/src/laminar.h @@ -56,6 +56,7 @@ public: void sendStatus(LaminarClient* client) override; bool setParam(std::string job, uint buildNum, std::string param, std::string value) override; bool getArtefact(std::string path, std::string& result) override; + std::string getCustomCss() override; private: bool loadConfiguration(); diff --git a/src/resources/index.html b/src/resources/index.html index 0b01a2f..62bba13 100644 --- a/src/resources/index.html +++ b/src/resources/index.html @@ -14,6 +14,7 @@ +