From fdbe2fc95d2b26d7b2f3f56b85cb8191df0e8653 Mon Sep 17 00:00:00 2001 From: "Hahn Axel (hahn)" <axel.hahn@iml.unibe.ch> Date: Mon, 15 Aug 2022 17:48:34 +0200 Subject: [PATCH] add docs; update readme --- README.md | 96 ++-------------------- docs/10_Installation.md | 38 +++++++++ docs/20_Usage.md | 51 ++++++++++++ docs/30_Service.md | 30 +++++++ docs/_index.md | 28 +++++++ docs/config.json | 25 ++++++ docs/style.css | 176 ++++++++++++++++++++++++++++++++++++++++ 7 files changed, 353 insertions(+), 91 deletions(-) create mode 100644 docs/10_Installation.md create mode 100644 docs/20_Usage.md create mode 100644 docs/30_Service.md create mode 100644 docs/_index.md create mode 100644 docs/config.json create mode 100644 docs/style.css diff --git a/README.md b/README.md index 313d50b..a4db14e 100644 --- a/README.md +++ b/README.md @@ -8,9 +8,11 @@ use it as systemd watcher daemon. It uses stat for wide compatibility but can enable inotifywatch to check a file change by an event. -licence: Free software GNU GPL 3.0 +Institute for Medical Education; University of Bern -Source: https://git-repo.iml.unibe.ch/iml-open-source/onfilechange +📄 Source: <https://git-repo.iml.unibe.ch/iml-open-source/onfilechange> \ +📜 License: GNU GPL 3.0 \ +📖 Docs: <https://os-docs.iml.unibe.ch/onfilechange/> ## Why? @@ -19,96 +21,8 @@ You can use it to trigger actions that are not allowed by another user. Scenario: A web developer has access with a non privileged user to maintain an -application ... and on an update you want to allow him to restart the -web service without sudo permissions. +application ... and on an update you want to allow him to restart the web service without sudo permissions. Start the onfilechange to watch a defined file as root: `onfilechange.sh -f /var/www/touch2restart_httpd -c "systemctl restart httpd"` - -## Installation - -* Copy the bash script somewhere you like. -* set execute permissions `chmod 0755 onfilechange.sh` - -## Usage - -start `./onfilechange.sh -h` to get the help - -``` -______________________________________________________________________________ - - T R I G G E R C O M M A N D O N A F I L E C H A N G E -______________________________________________________________________________ - v1.04 - -INFO: stat command detected -HELP: - This script checks the change of a given file and triggers - a command if it changes - -PRAMETERS: - -c [command] - command to execute on a file change - -f [filename(s)] - filenames to watch; separate multiple files with space and put all in quotes - -h - show this help - -i - force inotifywait command - -s - force stat command (default mode) - -v - verbose mode; enable showing debug output - -w [integer] - for stat mode: wait time in seconds betweeen each test or on missing file; default: 5 sec - -EXAMPLES: - onfilechange.sh -f /home/me/touchfile.txt -c "ls -l" - watch touchfile.txt and make a file listing on change - - onfilechange.sh -f "/home/me/touchfile.txt home/me/touchfile2.txt" -c "ls -l" - watch touchfile.txt and touchfile2.txt - - onfilechange.sh -f /home/me/touchfile.txt -s -w 10 -c "echo hello" - watch touchfile.txt every 10 sec with stat and show "hello" on a change -``` - -## Test on command line - -To make a test on commandline touch a testfile `touch /tmp/mytestfile`. -The start the script with enabled debugging (-d) in a 2nd terminal: - -`/usr/local/bin/onfilechange.sh -v -f "/tmp/mytestfile" -c 'echo "hello"'` - -Each time you touch the testfile it should show "hello". - -## Use as systemd service - -With running the script as a service can be helpful if you administrate servers and habe developer teams with limited access. Instead of giving sudo permissions you can watch a touchfile to execute something specific as root, i.e. restart Apache httpd. In the real world this file would be touched during an automated deploy process. - -Below is just an example service watching a dummy file in /tmp directory. - -In `/etc/systemd/system/` create a service config file **onfilechange-demo.service** - -``` -[Unit] -Description=Onfilechange demo -Wants=multi-user.target - -[Service] -ExecStart=/usr/local/bin/onfilechange.sh -f "/tmp/mytestfile" -c 'systemctl restart apache2' -Restart=on-failure -RestartSec=5s -SyslogIdentifier=onfilechange -User=root -Group=root -Type=simple - -[Install] -WantedBy=multi-user.target -``` - -Check if the service exists `systemctl status onfilechange-demo`. If so you can start and stop it with `systemctl [start|stop] onfilechange-demo` - -To start the service on reboot you additionally need to enable it: `systemctl enable onfilechange-demo`. \ No newline at end of file diff --git a/docs/10_Installation.md b/docs/10_Installation.md new file mode 100644 index 0000000..87785ce --- /dev/null +++ b/docs/10_Installation.md @@ -0,0 +1,38 @@ +# Installation + +# Manual installation + +In short a manual way: + +* Copy the bash script somewhere you like. +* set execute permissions `chmod 0755 onfilechange.sh` + +# Use git + +If you have git and want to update the files with a simple git pull +you can do it that way. + +## Get the files + +```shell +cd /opt +git clone https://gitlab.iml.unibe.ch/iml-open-source/onfilechange.git +``` + +## Make script available anywhere + +To have a single file in /usr/local/bin you can create a softlink + +```shell +cd /usr/local/bin +ln -s /opt/onfilechange/onfilechange +``` + +## Update + +To start an update you can use + +```shell +cd /opt/onfilechange/ +git pull +``` diff --git a/docs/20_Usage.md b/docs/20_Usage.md new file mode 100644 index 0000000..0c2be67 --- /dev/null +++ b/docs/20_Usage.md @@ -0,0 +1,51 @@ +# Usage + +Start `./onfilechange.sh -h` to get the help + +```txt +______________________________________________________________________________ + + T R I G G E R C O M M A N D O N A F I L E C H A N G E +______________________________________________________________________________ + v1.04 + +INFO: stat command detected +HELP: + This script checks the change of a given file and triggers + a command if it changes + +PRAMETERS: + -c [command] + command to execute on a file change + -f [filename(s)] + filenames to watch; separate multiple files with space and put all in quotes + -h + show this help + -i + force inotifywait command + -s + force stat command (default mode) + -v + verbose mode; enable showing debug output + -w [integer] + for stat mode: wait time in seconds betweeen each test or on missing file; default: 5 sec + +EXAMPLES: + onfilechange.sh -f /home/me/touchfile.txt -c "ls -l" + watch touchfile.txt and make a file listing on change + + onfilechange.sh -f "/home/me/touchfile.txt home/me/touchfile2.txt" -c "ls -l" + watch touchfile.txt and touchfile2.txt + + onfilechange.sh -f /home/me/touchfile.txt -s -w 10 -c "echo hello" + watch touchfile.txt every 10 sec with stat and show "hello" on a change +``` + +# Test on command line + +To make a test on commandline touch a testfile `touch /tmp/mytestfile`. +The start the script with enabled debugging (-d) in a 2nd terminal: + +`/usr/local/bin/onfilechange.sh -v -f "/tmp/mytestfile" -c 'echo "hello"'` + +Each time you touch the testfile in another terminal window it should show "hello". diff --git a/docs/30_Service.md b/docs/30_Service.md new file mode 100644 index 0000000..f7be693 --- /dev/null +++ b/docs/30_Service.md @@ -0,0 +1,30 @@ + +# Use as systemd service + +With running the script as a service can be helpful if you administrate servers and habe developer teams with limited access. Instead of giving sudo permissions you can watch a touchfile to execute something specific as root, i.e. restart Apache httpd. In the real world this file would be touched during an automated deploy process. + +Below is just an example service watching a dummy file in /tmp directory. + +In `/etc/systemd/system/` create a service config file **onfilechange-demo.service** + +```txt +[Unit] +Description=Onfilechange demo +Wants=multi-user.target + +[Service] +ExecStart=/usr/local/bin/onfilechange.sh -f "/tmp/mytestfile" -c 'systemctl restart apache2' +Restart=on-failure +RestartSec=5s +SyslogIdentifier=onfilechange +User=root +Group=root +Type=simple + +[Install] +WantedBy=multi-user.target +``` + +Check if the service exists `systemctl status onfilechange-demo`. If so you can start and stop it with `systemctl [start|stop] onfilechange-demo` + +To start the service on reboot you additionally need to enable it: `systemctl enable onfilechange-demo`. \ No newline at end of file diff --git a/docs/_index.md b/docs/_index.md new file mode 100644 index 0000000..a4db14e --- /dev/null +++ b/docs/_index.md @@ -0,0 +1,28 @@ +# onfilechange + +A Shell script that watches a given file or multiple files. +If one of the watched file changes then a given command will be exxecuted. +It loops permanently; you need to stop it by Ctrl + C and/ or can +use it as systemd watcher daemon. + +It uses stat for wide compatibility but can enable inotifywatch to +check a file change by an event. + +Institute for Medical Education; University of Bern + +📄 Source: <https://git-repo.iml.unibe.ch/iml-open-source/onfilechange> \ +📜 License: GNU GPL 3.0 \ +📖 Docs: <https://os-docs.iml.unibe.ch/onfilechange/> + +## Why? + +You can use it to trigger actions that are not allowed by another user. + +Scenario: + +A web developer has access with a non privileged user to maintain an +application ... and on an update you want to allow him to restart the web service without sudo permissions. + +Start the onfilechange to watch a defined file as root: + +`onfilechange.sh -f /var/www/touch2restart_httpd -c "systemctl restart httpd"` diff --git a/docs/config.json b/docs/config.json new file mode 100644 index 0000000..ca5f52a --- /dev/null +++ b/docs/config.json @@ -0,0 +1,25 @@ +{ + "title": "onfilechange", + "author": "Axel Hahn", + "tagline": "Trigger an action if a file changes", + "ignore": { + "files": ["30_PHP-client/Plugins/Checks/_skeleton.md"], + "folders": ["99_Not_Ready"] + }, + "html": { + "auto_toc": true, + "auto_landing": false, + "date_modified": false, + "jump_buttons": true, + "edit_on_github_": "iml-it/__PROJECT__/tree/master/docs", + "edit_on_": { + "name": "Gitlab", + "basepath": "https://git-repo.iml.unibe.ch/iml-open-source/__PROJECT__/tree/master/docs" + }, + "links": { + "Git Repo": "__GITURL__" + }, + "theme": "daux-blue", + "search": false + } +} \ No newline at end of file diff --git a/docs/style.css b/docs/style.css new file mode 100644 index 0000000..909562c --- /dev/null +++ b/docs/style.css @@ -0,0 +1,176 @@ +/* + + patch css elements of daux.io blue theme + version 2022-05-13 + +*/ + + +/* ---------- vars ---------- */ + +:root{ + + /* background colors */ + --bg:none; + --bg-body: #fff; + --bg-navlinkactive:#f4f4f4; + --bg-navlinkactive: linear-gradient(-90deg,rgba(0,0,0,0), rgba(40,60,80,0.05) 30%); + --bg-pre:#f8f8f8; + --bg-toc: #fff; + + /* foreground colors */ + --color: #234; + --navlinkactive:#f33; + --title: #aaa; + + --link:#12a; + --toclink:rgba(40,60,80,0.8); + + --h1: rgba(40,60,80,0.8); + --h1-bottom: 1px solid rgba(40,60,80,0.1); + --h2: #468; + --h3: #579; + +} + +/* ---------- tags ---------- */ + +a.Brand::before { + background: rgb(255,0,51); + color: #fff; + font-family: arial; + font-weight: bold; + padding: 0.5em 0.3em; + content: 'IML'; + margin-right: 0.4em; +} + +body, *{color: var(--color);} +body{background: var(--bg-body);} + + +a{color: var(--link);} +a:hover{opacity: 0.7;} + +h1>a{ color:var(--title);} +_h1:nth-child(1){position: fixed; background: var(--bg); box-shadow: 0 0 1em #ccc; padding: 0 1em} +h1:nth-child(1)>a{ color:var(--navlinkactive); } + +.s-content h1{color: var(--h1); font-size: 200%; font-weight:bold; margin-top: 2em; border-bottom: var(--h1-bottom);} +.s-content h2{color: var(--h2); font-size: 160%; } +.s-content h3{color: var(--h3); font-size: 140%; } +.s-content h4{margin: 0; font-size: 100%; text-align: center; background-color: rgba(0,0,0,0.05);padding: 0.3em;} + +.s-content pre{ + background: var(--bg-pre); +} + +/* ---------- classes ---------- */ + +.required{color:#a42;} +.optional{color:#888;} + + +/* ----- top left */ +.Brand, +.Columns__left { + background: var(--bg); + border-right: 0px solid #e7e7e9; + color: var(--color); +} +.Brand{font-size: 200%; + background_: linear-gradient(-10deg,#fff 50%, #ddd); + background: var(--bg); +} +.Columns__right__content { + background: var(--bg); +} + +/* ----- Navi left */ + +.Nav a:hover{ + background: none; + color: var(--navlinkactive) !important; +} + +.Nav__item--active { + border-right_: 0.3em solid var(--navlinkactive); +} +.Nav__item--active > a{ + background: var(--bg-navlinkactive); + color: var(--navlinkactive); +} +.Nav .Nav .Nav__item--active a { + color: var(--navlinkactive); +} +.Nav .Nav .Nav__item a { + opacity: 1; +} +.Nav__item--open > a { + background-color: var(--bg); +} + +.Nav a[href*="__Welcome"]{ + background: url("/icons/house.png") no-repeat 10px 4px ; + padding-left: 40px; +} +.Nav a[href*="__How_does_it_work"]{ + background: url("/icons/light-bulb.png") no-repeat 10px 4px ; + padding-left: 40px; +} + + + + +/* ---------- classes ---------- */ + +/* FIX smaller fnt size in tables */ +.s-content table { + font-size: 1em; +} + + +/* TOC */ +@media(min-width:1700px){ + .TableOfContentsContainer{ + position: fixed; + right: 2em; + top: 1em; + } +} + +.TableOfContentsContainer{ + border-top-left-radius: 1em; + background-color: var(--bg-toc); + border-left: 2px solid rgba(0,0,0,0.05); + padding: 0em; +} +.TableOfContentsContainer__content { + + border: none; + font-size: 0.5em; + +} +ul.TableOfContents ul{ + list-style-type: none; + padding-left: 1em; +} +.TableOfContentsContainer a{ color:var(--toclink);} + +.TableOfContentsContainer__content > .TableOfContents > li + li { + border-top: none; +} +.TableOfContentsContainer__content > .TableOfContents > li { + border-bottom: 1px dashed #ddd; +} + +/* pager - prev .. next */ +.s-content{ + margin-bottom: 6em; +} +.Pager{ + border-top: 1px dashed #aaa; margin: 0; padding: 1em; +} +.Pager a{ + color:var(--navlinkactive); +} -- GitLab