Compare commits
435 Commits
Author | SHA1 | Date | |
---|---|---|---|
f43ddd2a5a | |||
1914f83128 | |||
8d1465ced9 | |||
25962beb02 | |||
f20043fd61 | |||
63338eb466 | |||
7a16eda8ad | |||
1dfe86e69b | |||
41c48407a8 | |||
db8d906ece | |||
57ac4acf79 | |||
b7e798eeca | |||
a1e0217759 | |||
cd19dfcc98 | |||
471da5f2d4 | |||
5b6fa2b59d | |||
d57d7b2c0b | |||
739a4b1e7c | |||
48b5965969 | |||
9c8e0ab741 | |||
15f537c90d | |||
992868b14d | |||
71612aef94 | |||
bb8b54597a | |||
fb67ff42f4 | |||
7b33585405 | |||
729f4923f9 | |||
eed4089f9e | |||
cf52eb3187 | |||
44b5482772 | |||
11198a3b46 | |||
0911473db6 | |||
86509453cc | |||
efac859fac | |||
57a986fe40 | |||
91327a2973 | |||
8cf808d70b | |||
3fc647aef8 | |||
1d6b4c3b53 | |||
c4c6007b00 | |||
b894a756ea | |||
56765a0884 | |||
9e81cd32fe | |||
3f93e6a846 | |||
ebcdbb88bd | |||
141b16e804 | |||
7c89c99a61 | |||
cddfeb43dd | |||
bc706fb121 | |||
cec9739372 | |||
4c032e6b5e | |||
78189e43e7 | |||
487c812364 | |||
4dfc6cdce9 | |||
1c99aee146 | |||
653d233586 | |||
dcdb6b45a3 | |||
1a44ab50f1 | |||
fdfcba54ee | |||
637c248b40 | |||
15ced9d2dc | |||
9a20a2d374 | |||
58a8ec6eae | |||
a9491aa84a | |||
d2fd71d5c9 | |||
dfa5804316 | |||
839d42c39b | |||
b34447ad9a | |||
6dd40bc6c2 | |||
e641373a57 | |||
38d635446e | |||
b6e4359965 | |||
b1acff2d70 | |||
9507922968 | |||
feed3076ba | |||
1edef40342 | |||
f30f2ea205 | |||
be54b5cfba | |||
c296c07373 | |||
06f960d96d | |||
51a3a8b593 | |||
f0e9bbe4e0 | |||
1f946cd9a2 | |||
80e2fadf12 | |||
e346a378c4 | |||
e686dbaf9d | |||
c861bb3a13 | |||
9525aed587 | |||
f1385197d8 | |||
2ddfefa646 | |||
867071eca0 | |||
5db0165c49 | |||
4f2d80bbc9 | |||
b7f41c4ec7 | |||
d6b11898a2 | |||
70b4056a7f | |||
37069952d4 | |||
2872901924 | |||
b2a851c4af | |||
b8586cfc7c | |||
c1eb864fb9 | |||
64abe2f28f | |||
d3b3a8d60b | |||
75663b3108 | |||
2b7bd987cb | |||
6f0227a6ee | |||
d2bf4d8677 | |||
84051c6b2a | |||
14668700a7 | |||
90bff659de | |||
a466615d3a | |||
9da7a80846 | |||
dfae33ff23 | |||
bb19a0f8ad | |||
b46c4b6302 | |||
04abf6c6b7 | |||
c75ec7ddeb | |||
52d03c3730 | |||
741d0c74c9 | |||
260daa009c | |||
86cee821ba | |||
881d8bbe3f | |||
65f8ab8dc8 | |||
e4a88178ae | |||
b4e297f7ab | |||
f6ccc54556 | |||
669247836a | |||
bb7d187d64 | |||
b88a69e68b | |||
936e58c72b | |||
7face5cd4a | |||
8e63bbe7df | |||
ab1f9f761e | |||
07828f0d6f | |||
c18be0b7ad | |||
c5c4623514 | |||
1ab8ec6296 | |||
98d8de1eee | |||
cd4313cbf1 | |||
52be30dc15 | |||
7d8c3c794f | |||
9839cf066a | |||
f3535f6b2c | |||
262b75fd8b | |||
12a2d52b05 | |||
3001515720 | |||
cccbc75c6d | |||
2295381a66 | |||
41fd3d3861 | |||
1a3fb55fbd | |||
9f9f684dd5 | |||
5539c6b78e | |||
505065bb3e | |||
aaf14ba332 | |||
660498ffea | |||
f104950cbd | |||
a485904c88 | |||
a4e453ee22 | |||
213180013a | |||
6dd7c0d00c | |||
88af37f925 | |||
548c0bfc1c | |||
e2c095eb7d | |||
ad18a2b8d5 | |||
e0daa360e9 | |||
3c132ed4e2 | |||
33775ffb1d | |||
4c7eae13c4 | |||
370a042c8b | |||
38c24693c9 | |||
b50b74235c | |||
b5e5bcba66 | |||
b29a5c3c2b | |||
784be2b850 | |||
d52fb92920 | |||
1f528e2c34 | |||
0534fd052a | |||
a1cc1c7f2d | |||
d4cdff72c4 | |||
a1c76d1f7a | |||
22e10edbad | |||
6c2dc20d1b | |||
9020e87561 | |||
9013f9224c | |||
e7b524ef2c | |||
f874b7f03a | |||
fcde8b8eba | |||
be84057358 | |||
c690c173eb | |||
9c9af7f7f4 | |||
688d1c871b | |||
9f262616fb | |||
6122b9d7ce | |||
4d925dbc4a | |||
066dcfcdcd | |||
afec7878a3 | |||
ca169beec6 | |||
fce45e26f5 | |||
0bddd5f1ce | |||
ae83eedec4 | |||
232b05aa95 | |||
805d543d3f | |||
aa8847af02 | |||
b33db9d357 | |||
4b4dce7f66 | |||
7e49facd4d | |||
8d96d7e38a | |||
0a92b49cc7 | |||
09300234fc | |||
0fe7eac8f3 | |||
30aef29aab | |||
3d85c1353d | |||
b4990b3668 | |||
ec93e655f3 | |||
a8838fa5da | |||
11f001ede0 | |||
f5d672f609 | |||
d714c6b7f9 | |||
5aba72ee49 | |||
84a798dea5 | |||
b163e53b37 | |||
1ff20e3918 | |||
44eb276b1c | |||
7a83a5f8a1 | |||
f1ef00d34f | |||
424fde64f8 | |||
c5c4c3a962 | |||
f28e4523a4 | |||
f58900be1f | |||
fd6628196d | |||
2cd478aae3 | |||
c0cfddb54a | |||
66bc680a16 | |||
74ec53ae18 | |||
c984905550 | |||
3dd31c51ea | |||
fe1318a7b2 | |||
adc3deba18 | |||
e0ba86d48f | |||
edeb3553a0 | |||
f3b774839c | |||
e348d0ffb7 | |||
a7a632523d | |||
7a61dcd718 | |||
4c50812346 | |||
d0cdd8d271 | |||
74b9ce31d2 | |||
59cc2c7b70 | |||
ab6283de9b | |||
027737103a | |||
d708ba8ab3 | |||
cd0e5b39a2 | |||
ffb04bdcb4 | |||
4b4b0531c7 | |||
7abb25ea05 | |||
8371eefa97 | |||
ff1a4eeb8f | |||
4bfeda23da | |||
6099b25517 | |||
c4a796851d | |||
b6e3b0d07a | |||
3c66148f28 | |||
a3d34cdc23 | |||
39e2597ba9 | |||
61284cf46f | |||
e28f71d320 | |||
b735606657 | |||
5f26548299 | |||
3d04a5ecc3 | |||
ab91cc1ab9 | |||
f3cd19e22e | |||
85c26b580b | |||
5adba4e61c | |||
a4c51b5ee3 | |||
8e3b0355ff | |||
809d40e8a2 | |||
317b2088f0 | |||
|
f83383cd51 | ||
e65b619ca7 | |||
0f037ec8a1 | |||
94f47d1cc8 | |||
916e7d55d2 | |||
259338ca83 | |||
cc9fd79693 | |||
a26a0db9ca | |||
e1bada678b | |||
0cded7c888 | |||
60f6d04c3b | |||
a657473871 | |||
31b85395d6 | |||
84855cded6 | |||
7826addc26 | |||
29ede5409b | |||
0ec36247f7 | |||
e883306fc9 | |||
4b4df3132a | |||
2e6984aac8 | |||
8d303bbcbc | |||
da30fc84b8 | |||
0cb059a58f | |||
d2691d4d93 | |||
99375dd4f3 | |||
2688d60f6d | |||
bff087d731 | |||
dab84f4d67 | |||
ac011b6564 | |||
d369913e9f | |||
02cccb71bd | |||
ef8af4b5b5 | |||
404646e6a2 | |||
b5447f6f06 | |||
49749cdeeb | |||
0575aad054 | |||
742fc70798 | |||
ef572f9d7e | |||
f90e95461e | |||
ebe2bee4fd | |||
be420094b5 | |||
d5274f159e | |||
4dd128d00f | |||
53d51f8cee | |||
c01371a21c | |||
c88ae510ab | |||
23924645cb | |||
bc5d30f400 | |||
91f9f8a8da | |||
2041621d2b | |||
0cf41c708d | |||
d182f5e0c6 | |||
358cff38b1 | |||
9a303b634f | |||
790ba88d7d | |||
6cfcee6d20 | |||
d1df177afb | |||
e761cbacdf | |||
7e3fb265c4 | |||
d6aba7d06f | |||
8d8779a58a | |||
68a16b2fdd | |||
1ceefcfe95 | |||
100f0f9db9 | |||
982d34815f | |||
07fcd28545 | |||
f514b73322 | |||
bf51d0ee11 | |||
3cad9c40c6 | |||
3d1097bb5d | |||
4feb26103b | |||
6d12f7aecd | |||
0d534be7a9 | |||
30fa3e3551 | |||
5f662828a2 | |||
be59c27224 | |||
d89dd8e6ab | |||
78de3db626 | |||
aaec21ae93 | |||
c7de26455b | |||
a2fc9e62c9 | |||
46b6839f50 | |||
f5193f46ee | |||
b79ae416e6 | |||
f5c5120fff | |||
e5678c9692 | |||
046f80f865 | |||
aafc1cb29c | |||
6a9464f0bb | |||
a5ac79cbcc | |||
94b3afafe1 | |||
bc12312101 | |||
dddc133ad4 | |||
e8b475d9f7 | |||
a9ff5e1478 | |||
a7646beeb0 | |||
49f009a387 | |||
72919548d2 | |||
9a408fa1d4 | |||
d206ee1a1d | |||
a67fb24212 | |||
67b785dd49 | |||
69740bf6ee | |||
519bc7aa92 | |||
a365260995 | |||
c8922f6c6d | |||
9a6901ee95 | |||
f126f9e1df | |||
844e5040d2 | |||
1ac923c774 | |||
8e370a0e56 | |||
e0a3c3d877 | |||
9d6e646c3e | |||
a3a051e38a | |||
56ea46c8c7 | |||
322eec18f3 | |||
50d3b98e0f | |||
ceba5f37c3 | |||
57fba73e8a | |||
4e8a3ddf9a | |||
223b9d7abe | |||
6cb5dc595b | |||
ddbc4657f7 | |||
e37f6269ee | |||
581c3d1ed6 | |||
48f6de3026 | |||
ab10ef6504 | |||
34966ddf79 | |||
50e4bf01c4 | |||
b6407c172e | |||
8413e2d518 | |||
77f8c63276 | |||
4e88850aba | |||
a1528de93e | |||
310f7d5a1e | |||
0be0629bd7 | |||
75d30a08d6 | |||
c877566b4e | |||
3b9e4bee89 | |||
9ad3d001d8 | |||
60bb0cb79a | |||
cb6ee47496 | |||
600667c25b | |||
eb20953214 | |||
b7edd7d6bc | |||
98469b1d20 | |||
4c50382428 | |||
3b23840277 | |||
a124608e36 | |||
4516bbb363 | |||
2a27608b14 | |||
9fad2a9121 | |||
0789a586d2 | |||
0f206660a6 | |||
60ee5d776f | |||
ac721ddac6 | |||
42aa8def70 | |||
e6313d2c32 |
6
.editorconfig
Normal file
6
.editorconfig
Normal file
@@ -0,0 +1,6 @@
|
||||
root = true
|
||||
|
||||
[*.{sh,bash,cfg,example}]
|
||||
charset = utf-8
|
||||
indent_style = space
|
||||
indent_size = 2
|
4
.gitignore
vendored
4
.gitignore
vendored
@@ -1 +1,3 @@
|
||||
/seqTemplateExample.sh
|
||||
seqTemplateExample.sh
|
||||
missingConf.log
|
||||
*.cfg
|
||||
|
71
README.md
71
README.md
@@ -15,6 +15,73 @@ Contains sequences (seqs) for different tools, servers or occasions.
|
||||
Sequencer include working on sh and bash.
|
||||
|
||||
[...]
|
||||
. ./sequencer.sh
|
||||
. /usr/local/bin/sequencer.sh
|
||||
|
||||
see [seqTemplate.sh](https://winklerfamilie.eu/git/efelon/shell_sequencer/src/branch/master/seqTemplate.sh)
|
||||
see seqTemplateExample.sh (which can be generated when calling sequencer.sh directly)
|
||||
|
||||
## Installation recommendation
|
||||
|
||||
To make all seqs avaialable to all user, follow the procedure below.
|
||||
|
||||
Run folloing commands as root:
|
||||
|
||||
```
|
||||
git clone https://winklerfamilie.eu/git/efelon/shell_sequencer.git /opt/sequencer
|
||||
ln -s /opt/sequencer/sequencer/sequencer.sh /usr/local/bin
|
||||
ln -s /opt/sequencer/seqs /opt
|
||||
```
|
||||
or
|
||||
|
||||
use the simple bash installation script in the repository which installs git and performs the steps above:
|
||||
|
||||
```
|
||||
curl -L https://winklerfamilie.eu/git/efelon/shell_sequencer/raw/branch/master/install.sh | bash
|
||||
```
|
||||
|
||||
You may override the default installation path `/opt/sequencer` by appending `-s /custom/path` to the command above:
|
||||
|
||||
e.g. `curl -L https://winklerfamilie.eu/git/efelon/shell_sequencer/raw/branch/master/install.sh | bash -s /usr/lib/sequencer`
|
||||
|
||||
## Bash-completion
|
||||
|
||||
The included optional bash-completion script `sqnall-completion.bash` provides aliases to all available sequences as well as completion for sequencer.sh options and steps (including aliases) individually for each sequence. The aliases have the prefix `sqn_` which stands for _sequence name_.
|
||||
|
||||
After executing
|
||||
|
||||
```
|
||||
source /opt/sequencer/sqnall-completion.bash
|
||||
```
|
||||
|
||||
e.g. `/opt/sequencer/seqs/kodi.sh` can be started anyhere with `sqn_kodi`
|
||||
|
||||
### Custom sequence directory
|
||||
|
||||
To control which seqs are available for bash-completion, copy `sequencer.cfg.dist` to `sequencer.cfg` and adjust the value of the variable `SEQUENCER_USER_SEQS`.
|
||||
|
||||
To make these changes active run the following commands. You don't need the last step if you already used `installCompletion.sh`.
|
||||
|
||||
```
|
||||
unalias -a
|
||||
source ~/.bashrc
|
||||
source /opt/sequencer/sqnall-completion.bash
|
||||
```
|
||||
|
||||
or simply logout from the current session and login again.
|
||||
|
||||
### Automatic setup after login
|
||||
|
||||
To automatically provide aliases and bash-completion after login, the following bash script needs to be executed once for each user separately:
|
||||
|
||||
```
|
||||
source /opt/sequencer/installCompletion.sh
|
||||
```
|
||||
|
||||
This sources the bash-completion script in the users .bashrc file.
|
||||
|
||||
## Default text editor
|
||||
|
||||
Sequencer uses the Debian alternatives system to select which editor to use. To change the default editor, which by default is most likely _nano_:
|
||||
|
||||
```
|
||||
update-alternatives --config editor
|
||||
```
|
||||
|
66
install.sh
Executable file
66
install.sh
Executable file
@@ -0,0 +1,66 @@
|
||||
#!/bin/bash
|
||||
# shellcheck disable=SC1090 # dynamically sourced file
|
||||
|
||||
SEQGITURL="https://winklerfamilie.eu/git/efelon/shell_sequencer.git"
|
||||
DEFAULT_DIR="/opt/sequencer"
|
||||
DEFAULT_USER_SEQS="/opt/seqs"
|
||||
SEQUENCER_DIR=
|
||||
|
||||
# Get script working directory
|
||||
WDIR="$(cd "$(dirname -- "${BASH_SOURCE[0]}")" >>/dev/null 2>&1 && pwd)"
|
||||
|
||||
SEQUENCER_DIR="$1"
|
||||
|
||||
# Installation directory was not set by argument -d
|
||||
if [ -z "$SEQUENCER_DIR" ]; then
|
||||
[ -w "$(dirname "$DEFAULT_DIR")" ] && SEQUENCER_DIR="$DEFAULT_DIR"
|
||||
# Fallback to working directory
|
||||
[ -z "$SEQUENCER_DIR" ] && SEQUENCER_DIR="${WDIR}/sequencer"
|
||||
fi
|
||||
|
||||
# Check if already installed
|
||||
if [ -d "$SEQUENCER_DIR" ]; then
|
||||
echo " [E] Sequencer seems to be already installed at:"
|
||||
echo " $SEQUENCER_DIR"
|
||||
exit 1
|
||||
fi
|
||||
if [ ! -w "$(dirname "$SEQUENCER_DIR")" ]; then
|
||||
echo " [E] Your user has no permission to write to $(dirname "$SEQUENCER_DIR")"
|
||||
exit 2
|
||||
fi
|
||||
|
||||
# Install git if neccessary
|
||||
if ! which git >>/dev/null 2>&1; then
|
||||
echo " [W] Git not found and will be installed"
|
||||
|
||||
if ! apt update; then
|
||||
echo " [W] Cannot update apt repositories"
|
||||
fi
|
||||
|
||||
if ! apt install git -y; then
|
||||
echo " [E] Cannot install git via apt"
|
||||
exit 3
|
||||
fi
|
||||
fi
|
||||
|
||||
# Clone sequncer to target directory
|
||||
if ! git clone $SEQGITURL "$SEQUENCER_DIR"; then
|
||||
echo " [E] Error cloning git repository:"
|
||||
echo " $SEQGITURL"
|
||||
exit 4
|
||||
fi
|
||||
|
||||
# If available use configuration
|
||||
. "${SEQUENCER_DIR}/sequencer.cfg" >/dev/null 2>&1
|
||||
|
||||
# Set to default if not configured
|
||||
[ -z "$SEQUENCER_USER_SEQS" ] && SEQUENCER_USER_SEQS="$DEFAULT_USER_SEQS"
|
||||
|
||||
# Install sequncer script
|
||||
ln -s "${SEQUENCER_DIR}/sequencer/sequencer.sh" "/usr/local/bin"
|
||||
if [ "$SEQUENCER_USER_SEQS" != "$SEQUENCER_DIR/seqs" ]; then
|
||||
ln -sT "${SEQUENCER_DIR}/seqs" "${SEQUENCER_USER_SEQS}"
|
||||
fi
|
||||
|
||||
echo " [I] Successfully installed shell sequencer"
|
||||
echo " to: $SEQUENCER_DIR"
|
21
installCompletion.sh
Executable file
21
installCompletion.sh
Executable file
@@ -0,0 +1,21 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
# Get script working directory
|
||||
sq_dir="$(cd "$(dirname -- "$(realpath "${BASH_SOURCE[0]}")")" >>/dev/null 2>&1 && pwd)"
|
||||
|
||||
_sequencerCompletion() {
|
||||
local SEQCOMP_LOC="${sq_dir}/sqn-completion.bash"
|
||||
local SEQCOMP_LOADER="$HOME/.bashrc"
|
||||
local SEQCOMP_SOURCE=". \"$SEQCOMP_LOC\""
|
||||
|
||||
if grep "$SEQCOMP_SOURCE" "$SEQCOMP_LOADER" >>/dev/null 2>&1; then
|
||||
echo " [I] Completion already installed ($SEQCOMP_LOADER)"
|
||||
else
|
||||
echo "$SEQCOMP_SOURCE" >>"$SEQCOMP_LOADER"
|
||||
echo " [I] Sequence bash-completion installed"
|
||||
fi
|
||||
# shellcheck source=sqn-completion.bash
|
||||
. "$SEQCOMP_LOC"
|
||||
}
|
||||
|
||||
_sequencerCompletion
|
@@ -1,46 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
##
|
||||
## Sequencer interface:
|
||||
## - step_[1 - 255]_info [STEP NUMBER]
|
||||
## functions providing short header for help and user interaction
|
||||
## - step_[1 - 255] [STEP NUMBER]
|
||||
## functions performing custom operations
|
||||
##
|
||||
|
||||
step_1_info() { echo "Step $1 header"; }
|
||||
step_1() {
|
||||
cat .nofile
|
||||
saveReturn $?
|
||||
}
|
||||
|
||||
step_2_info() { echo "Step $1 header"; }
|
||||
step_2() {
|
||||
echo -e "Zwei"
|
||||
endReturn
|
||||
echo zwo
|
||||
}
|
||||
|
||||
step_3_info() { echo "Step $1 header"; }
|
||||
step_3() {
|
||||
echo drei
|
||||
}
|
||||
|
||||
step_10_info() { echo "Step $1 header"; }
|
||||
step_10() {
|
||||
echo zehn
|
||||
}
|
||||
|
||||
step_11_info() { echo "Step $1 header"; }
|
||||
step_11() {
|
||||
echo elf
|
||||
}
|
||||
|
||||
# Sequence Revision
|
||||
VERSION_SEQREV=1
|
||||
|
||||
# Workaround when called from different directory
|
||||
# Not needed when path to sequencer is absolut
|
||||
DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >>/dev/null 2>&1 && pwd )"
|
||||
# Path to local sequencer.sh script
|
||||
. ${DIR}/./sequencer/sequencer.sh
|
8
seqs/aria2.cfg.example
Normal file
8
seqs/aria2.cfg.example
Normal file
@@ -0,0 +1,8 @@
|
||||
#!/bin/bash
|
||||
|
||||
ARIA2_RPC_SECRET=""
|
||||
ARIA2_CONF="dir=/var/lib/aria2
|
||||
file-allocation=none
|
||||
enable-rpc=true
|
||||
rpc-secret=$ARIA2_RPC_SECRET
|
||||
rpc-listen-all=true"
|
85
seqs/aria2.sh
Executable file
85
seqs/aria2.sh
Executable file
@@ -0,0 +1,85 @@
|
||||
#!/bin/bash
|
||||
|
||||
toolName=aria2
|
||||
toolDeps=aria2
|
||||
toolUser=aria2
|
||||
|
||||
# Get script working directory
|
||||
# (when called from a different directory)
|
||||
WDIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" >>/dev/null 2>&1 && pwd)"
|
||||
CONFIG=0
|
||||
SCRIPT_NAME=$(basename -- $0)
|
||||
SCRIPT_NAME=${SCRIPT_NAME%%.*}
|
||||
CONFIG_FILE_NAME="${SCRIPT_NAME}.cfg"
|
||||
CONFIG_FILE_TEMPLATE="$WDIR/${CONFIG_FILE_NAME}.example"
|
||||
|
||||
aptOpt=
|
||||
|
||||
step_config() {
|
||||
#echo "Called once before executing steps."
|
||||
## e.g. to source a config file manually:
|
||||
#. "$CONFIG_FILE"
|
||||
## or to use sequencer api with global config file:
|
||||
initSeqConfig "$CONFIG_FILE_NAME" "$CONFIG_FILE_TEMPLATE"
|
||||
## or to use sequencer api with profile config file support:
|
||||
#initSeqConfig -p "$SCRIPT_NAME" "$CONFIG_FILE_TEMPLATE"
|
||||
if [ $? -eq 0 ] ; then
|
||||
CONFIG=1
|
||||
else
|
||||
# End if no configuration file exists
|
||||
[ $DRY -eq 0 ] && return 1
|
||||
fi
|
||||
[ $QUIET -ne 0 ] && aptOpt="-y"
|
||||
return 0
|
||||
}
|
||||
|
||||
step_1_info() { echo "Install $toolName"; }
|
||||
step_1_alias() { ALIAS="install"; }
|
||||
step_1() {
|
||||
exe apt update
|
||||
exe apt install $toolDeps $aptOpt
|
||||
}
|
||||
|
||||
step_2_info() { echo "Create $toolName configuration"; }
|
||||
step_2() {
|
||||
exe adduser --system --quiet "$toolUser"
|
||||
if [ ! -e $ariaConfLoc ] ; then
|
||||
exe mkdir -p "$(dirname $ariaConfLoc)"
|
||||
addConf -s "$ARIA2_CONF" "$ariaConfLoc"
|
||||
exe chown $toolUser:root "$ariaConfLoc"
|
||||
exe chmod 770 "$ariaConfLoc"
|
||||
fi
|
||||
}
|
||||
ariaConfLoc="/etc/aria2/aria2.conf"
|
||||
|
||||
|
||||
step_3_info() { echo "Create $toolName service"; }
|
||||
step_3_alias() { ALIAS="service"; }
|
||||
step_3() {
|
||||
addConf -s "$ariaService" "$ariaServiceLoc"
|
||||
exe systemctl daemon-reload
|
||||
echoseq " [I] Serive not started or enabled"
|
||||
}
|
||||
ariaServiceLoc="/etc/systemd/system/aria2.service"
|
||||
ariaService="[Unit]
|
||||
Description=Aria2
|
||||
After=network-online.target
|
||||
|
||||
[Service]
|
||||
User=$toolUser
|
||||
Type=forking
|
||||
ExecStart=/usr/bin/aria2c --conf-path=${ariaConfLoc} --daemon
|
||||
ExecStop=/bin/kill -s STOP $MAINPID
|
||||
Restart=on-failure
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target"
|
||||
|
||||
step_10_info() { echo "Add ufw rule for rpc port 6800"; }
|
||||
step_10_alias() { ALIAS="ufw"; }
|
||||
step_10() {
|
||||
exe ufw allow in on eth0 to any port 6800 proto tcp comment "Aria2 rpc"
|
||||
}
|
||||
|
||||
VERSION_SEQREV=12
|
||||
. /usr/local/bin/sequencer.sh
|
25
seqs/backup.cfg.example
Normal file
25
seqs/backup.cfg.example
Normal file
@@ -0,0 +1,25 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Backup sequence definitions
|
||||
|
||||
# A running debian needs at least the following runtime directories created to start up successfully:
|
||||
## dev
|
||||
## proc
|
||||
## sys
|
||||
## run
|
||||
|
||||
BACKUP_TARGET="/backup"
|
||||
# Exclude notation "directory/*" creates the directory but NOT its content
|
||||
# Leading slash binds the rule to the "root" of the transfer operation
|
||||
BACKUP_EXCLUDES=(\
|
||||
"/backup*"\
|
||||
"/home/network/*"\
|
||||
"/dev/*"\
|
||||
"/proc/*"\
|
||||
"/sys/*"\
|
||||
"/tmp/*"\
|
||||
"/run/*"\
|
||||
"/mnt/*"\
|
||||
"/media/*"\
|
||||
"/lost+found"\
|
||||
)
|
193
seqs/backup.sh
Executable file
193
seqs/backup.sh
Executable file
@@ -0,0 +1,193 @@
|
||||
#!/bin/bash
|
||||
|
||||
toolName=backup
|
||||
toolBin=rsync
|
||||
|
||||
# Get script working directory
|
||||
# (when called from a different directory)
|
||||
WDIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >>/dev/null 2>&1 && pwd )"
|
||||
APTOPT=
|
||||
CONFIG=0
|
||||
CONFIG_FILE_NAME="${toolName}.cfg"
|
||||
CONFIG_FILE_TEMPLATE="$WDIR/${CONFIG_FILE_NAME}.example"
|
||||
|
||||
step_config() {
|
||||
initSeqConfig -t "$CONFIG_FILE_NAME" "$CONFIG_FILE_TEMPLATE"
|
||||
if [ $? -eq 0 ] ; then
|
||||
CONFIG=1
|
||||
else
|
||||
echoerr " [E] Check output for errors"
|
||||
# End if no configuration file exists
|
||||
[ $DRY -eq 0 ] && return -1
|
||||
fi
|
||||
|
||||
[ $QUIET -ne 0 ] && APTOPT="-y"
|
||||
return 0
|
||||
}
|
||||
|
||||
step_1_info() {
|
||||
echoinfoArgs "[ADDITIONAL_EXCLUDES...]"
|
||||
echo "Backup root"
|
||||
echoinfo "Essential excludes are provided in the configuration template."
|
||||
echoinfo "($CONFIG_FILE_TEMPLATE)"
|
||||
}
|
||||
step_1_alias() { ALIAS="buroot"; }
|
||||
step_1() {
|
||||
local buTarget="/backup"
|
||||
if [ $CONFIG -eq 0 ] ; then
|
||||
echoerr " [E] Cannot backup root without properly configured excludes"
|
||||
echoerr " (expected config: $SEQ_CONFIG_HOME/$CONFIG_FILE_NAME)"
|
||||
else
|
||||
buTarget="$BACKUP_TARGET"
|
||||
fi
|
||||
|
||||
# don't use step number
|
||||
shift
|
||||
|
||||
step budir / "$buTarget" "${BACKUP_EXCLUDES[@]}" "$@"
|
||||
}
|
||||
|
||||
step_3_info() {
|
||||
# Backup single directory recursively
|
||||
local opt="[OPTION]"
|
||||
local dir="<DIRECTORY>"
|
||||
local tar="<TARGET>"
|
||||
local exc="[EXCLUDES...]"
|
||||
shift
|
||||
if [ "$1" == "-t" ] ; then
|
||||
opt=" -t "
|
||||
tar=
|
||||
shift
|
||||
fi
|
||||
if [ ! -z "$1" ] ; then
|
||||
dir="$1"
|
||||
shift
|
||||
if [ ! -z $tar ] && [ ! -z "$1" ] ; then
|
||||
tar="$1"
|
||||
shift
|
||||
else
|
||||
tar="$BACKUP_TARGET"
|
||||
fi
|
||||
if [ ! -z "$1" ] ; then
|
||||
exc="$@"
|
||||
else
|
||||
exc="[NO EXCLUDES]"
|
||||
fi
|
||||
fi
|
||||
echo "Backup $opt $dir $tar $exc"
|
||||
echoinfo " -t : Using configuration value as TARGET"
|
||||
echoinfo " <DIRECTORY> [EXCLUDES...]"
|
||||
echoinfo "EXCLUDES path notation starts within $dir"
|
||||
echoinfo "e.g. to exclude $dir/a:"
|
||||
echoinfo " $0 budir $dir $tar /a"
|
||||
}
|
||||
step_3_alias() { ALIAS="budir"; }
|
||||
step_3() {
|
||||
local arg
|
||||
local configTarget=0
|
||||
local noRemount=0
|
||||
local buSource=
|
||||
local buTarget=
|
||||
local buExcludes=
|
||||
local buLog=
|
||||
# don't use step number
|
||||
shift
|
||||
|
||||
for arg in "$@"; do
|
||||
case "$1" in
|
||||
-t)
|
||||
configTarget=1
|
||||
shift;;
|
||||
-n)
|
||||
noRemount=1
|
||||
shift;;
|
||||
esac
|
||||
done
|
||||
|
||||
if [ -z "$1" ] ; then
|
||||
echoerr " [E] Nothing found to backup $1"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
buLog=$(basename $1)
|
||||
if [ "$buLog" == "/" ] ; then
|
||||
buLog="root"
|
||||
buSource="$1"
|
||||
else
|
||||
# remove trailing slashes
|
||||
buSource=$(echo "$1" | sed 's:/*$::')
|
||||
fi
|
||||
buLog="backup_${buLog}"
|
||||
shift
|
||||
|
||||
if [ $configTarget -ne 0 ] && [ $CONFIG -ne 0 ] ; then
|
||||
# Taking target from config
|
||||
buTarget=$(echo "$BACKUP_TARGET" | sed 's:/*$::')
|
||||
else
|
||||
if [ -z "$1" ] ; then
|
||||
echoerr " [E] No valid target found"
|
||||
exit 1
|
||||
fi
|
||||
buTarget=$(echo "$1" | sed 's:/*$::')
|
||||
shift
|
||||
fi
|
||||
if [ ! -d "${buTarget}" ] && [ ! -L "${buTarget}" ]
|
||||
then
|
||||
echoerr " [E] Backup target (${buTarget}) doesn't exist"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
for exclu in "$@"; do
|
||||
buExcludes+=("--exclude='$exclu'")
|
||||
done
|
||||
|
||||
echoseq " [I] Source : $buSource"
|
||||
echoseq " [I] Target : $buTarget"
|
||||
echoseq " [I] Excludes: $@"
|
||||
|
||||
#fix doubling trailing slash on verbose output when backing up root
|
||||
local tmpSource="$buSource/"
|
||||
local tmpTarget="${buTarget}/$(basename ${buSource})"
|
||||
if [ "$buSource" == "/" ] ; then
|
||||
tmpSource="/"
|
||||
tmpTarget="${buTarget}/"
|
||||
fi
|
||||
|
||||
if [ $noRemount -eq 0 ]; then
|
||||
# remount target to be writable
|
||||
exep "mount -o rw,remount '${buTarget}' >>/dev/null 2>&1"
|
||||
endReturn -o $? "Remount (${buTarget}) to be writable failed"
|
||||
fi
|
||||
|
||||
if [ ! -w "${buTarget}" ] ; then
|
||||
echoerr " [E] Backup target (${buTarget}) is not writable"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
checkInstalled
|
||||
exep "mv -f ${buTarget}/${buLog}0.log /tmp/${buLog}1.log 2>/dev/null"
|
||||
exep "$toolBin -avxHAX --delete --info=stats2 ${buExcludes[*]} ${tmpSource} ${tmpTarget} > /tmp/${buLog}0.log"
|
||||
|
||||
exe mv -f /tmp/${buLog}*.log ${buTarget}
|
||||
exe sync
|
||||
exep "mount -o ro,remount '${buTarget}' >>/dev/null 2>&1"
|
||||
}
|
||||
|
||||
step_100_info() { echo "Install $toolBin"; }
|
||||
step_100_alias() { ALIAS="install"; }
|
||||
step_100() {
|
||||
exe apt update
|
||||
exe apt install $toolBin $APTOPT
|
||||
}
|
||||
|
||||
checkInstalled() {
|
||||
command -v $toolBin >>/dev/null
|
||||
if [ $? -ne 0 ] ; then
|
||||
step install
|
||||
fi
|
||||
toolBin="$(command -v $toolBin)"
|
||||
}
|
||||
|
||||
VERSION_SEQREV=14
|
||||
. /usr/local/bin/sequencer.sh
|
||||
|
81
seqs/basics.sh
Executable file
81
seqs/basics.sh
Executable file
@@ -0,0 +1,81 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Collection of simple setup tasks
|
||||
# e.g. Ability to send mail (ssmtp)
|
||||
|
||||
# Get script working directory
|
||||
# (when called from a different directory)
|
||||
WDIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >>/dev/null 2>&1 && pwd )"
|
||||
WSUBDIR="${WDIR}/basics"
|
||||
|
||||
#step_config() {
|
||||
# echo "Called once before executing steps."
|
||||
# echo "e.g. to source a config file:"
|
||||
# #. "$CONFIG_FILE"
|
||||
#}
|
||||
|
||||
step_10_info() { echo "ssmtp installation"; }
|
||||
step_10_alias() { ALIAS="ssmtp"; }
|
||||
step_10() {
|
||||
exe apt update && apt install "$SSMTP_DEPS"
|
||||
endReturn -o $? "ssmtp installation failed"
|
||||
}
|
||||
SSMTP_DEPS="ssmtp"
|
||||
|
||||
step_11_info() { echo "ssmtp setup"; }
|
||||
step_11_alias() { ALIAS="ssmtpSetup"; }
|
||||
step_11() {
|
||||
if [ ! -f "$CONFIG_FILE_SSMTP" ] ; then
|
||||
echoerr " [E] User config ($CONFIG_FILE_SSMTP) not found"
|
||||
echoerr " See $CONFIG_FILE_SSMTP_TEMPLATE"
|
||||
return 1
|
||||
fi
|
||||
addConf -c -f "$CONFIG_FILE_SSMTP" "$CONFIG_LOC_SSMTP"
|
||||
endReturn -o $? "Could not write ssmtp configuration"
|
||||
|
||||
if [ ! -f "$CONFIG_FILE_SSMTP_AL" ] ; then
|
||||
echoerr " [W] User aliases ($CONFIG_FILE_SSMTP_AL) not found"
|
||||
echoerr " See $CONFIG_FILE_SSMTP_TEMPLATE or modify $CONFIG_LOC_SSMTP_AL directly"
|
||||
return 1
|
||||
fi
|
||||
addConf -c -f "$CONFIG_FILE_SSMTP_AL" "$CONFIG_LOC_SSMTP_AL"
|
||||
endReturn -o $? "Could not write ssmtp aliases"
|
||||
}
|
||||
CONFIG_LOC_SSMTP="/etc/ssmtp/ssmtp.conf"
|
||||
CONFIG_LOC_SSMTP_AL="/etc/ssmtp/revaliases"
|
||||
CONFIG_FILE_SSMTP="$WSUBDIR/ssmtp.cfg"
|
||||
CONFIG_FILE_SSMTP_TEMPLATE="${CONFIG_FILE_SSMTP}.example"
|
||||
CONFIG_FILE_SSMTP_AL="$WSUBDIR/revaliases.cfg"
|
||||
CONFIG_FILE_SSMTP_AL_TEMPLATE="${CONFIG_FILE_SSMTP}.example"
|
||||
|
||||
step_13_info() {
|
||||
echo -n "Send test E-Mail to "
|
||||
if [ -z $2 ] ; then echo "<MAILADDRESS>"; else echo "$2"; fi
|
||||
}
|
||||
step_13_alias() { ALIAS="ssmtpTest"; }
|
||||
step_13() {
|
||||
if [ ! -z "$2" ] || [ "$2" == "" ] ; then
|
||||
echoerr " [E] No mailaddress provided"
|
||||
fi
|
||||
|
||||
exep "echo \"Subject: sendmail test\" | sendmail -v $2"
|
||||
}
|
||||
|
||||
step_15_info() { echo "ssmtp help"; }
|
||||
step_15_alias() { ALIAS="ssmtpHelp"; }
|
||||
step_15() {
|
||||
echo " Configuration files expected by this seq:"
|
||||
echo
|
||||
echo " - $CONFIG_FILE_SSMTP"
|
||||
echo " (see template: $CONFIG_FILE_SSMTP_TEMPLATE)"
|
||||
echo " - $CONFIG_FILE_SSMTP_AL optional"
|
||||
echo " (see template: $CONFIG_FILE_SSMTP_AL_TEMPLATE)"
|
||||
echo
|
||||
echo " ssmtp configuration files"
|
||||
echo
|
||||
echo " - $CONFIG_LOC_SSMTP"
|
||||
echo " - $CONFIG_LOC_SSMTP_AL"
|
||||
}
|
||||
|
||||
VERSION_SEQREV=9
|
||||
. /usr/local/bin/sequencer.sh
|
6
seqs/basics/revaliases.cfg.example
Normal file
6
seqs/basics/revaliases.cfg.example
Normal file
@@ -0,0 +1,6 @@
|
||||
# sSMTP aliases
|
||||
#
|
||||
# Format: local_account:outgoing_address:mailhub
|
||||
#
|
||||
# Example: root:your_login@your.domain:mailhub.your.domain[:port]
|
||||
# where [:port] is an optional port number that defaults to 25.
|
24
seqs/basics/ssmtp.cfg.example
Normal file
24
seqs/basics/ssmtp.cfg.example
Normal file
@@ -0,0 +1,24 @@
|
||||
#
|
||||
# Config file for sSMTP sendmail
|
||||
#
|
||||
# The person who gets all mail for userids < 1000
|
||||
# Make this empty to disable rewriting.
|
||||
root=postmaster
|
||||
|
||||
# The place where the mail goes. The actual machine name is required no
|
||||
# MX records are consulted. Commonly mailhosts are named mail.domain.com
|
||||
mailhub=host:port
|
||||
#AuthUser=
|
||||
#AuthPass=
|
||||
UseTLS=YES
|
||||
|
||||
# Where will the mail seem to come from?
|
||||
rewriteDomain=mydomain.eu
|
||||
|
||||
# The full hostname
|
||||
hostname=mydomain.eu
|
||||
|
||||
# Are users allowed to set their own From: address?
|
||||
# YES - Allow the user to specify their own From: address
|
||||
# NO - Use the system generated From: address
|
||||
#FromLineOverride=YES
|
17
seqs/calibreweb.cfg.example
Normal file
17
seqs/calibreweb.cfg.example
Normal file
@@ -0,0 +1,17 @@
|
||||
#!/bin/bash
|
||||
|
||||
CALWEB_BASE="/opt/calibre-web"
|
||||
CALWEB_VENV_ROOT="$CALWEB_BASE/venv"
|
||||
CALWEB_USER_HOME="$CALWEB_BASE/home"
|
||||
CALWEB_USER="calibreweb"
|
||||
CALWEB_SERVICE="[Unit]
|
||||
Description=Calibre-Web
|
||||
After=network-online.target
|
||||
|
||||
[Service]
|
||||
Type=simple
|
||||
User=$CALWEB_USER
|
||||
ExecStart="$CALWEB_VENV_ROOT/bin/cps"
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target"
|
131
seqs/calibreweb.sh
Executable file
131
seqs/calibreweb.sh
Executable file
@@ -0,0 +1,131 @@
|
||||
#!/bin/bash
|
||||
|
||||
toolName=calibre-web
|
||||
toolPipName=calibreweb
|
||||
toolDeps="python3-pip python3-venv"
|
||||
toolFeatures=( metadata comics )
|
||||
|
||||
# Get script working directory
|
||||
# (when called from a different directory)
|
||||
WDIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" >>/dev/null 2>&1 && pwd)"
|
||||
APTOPT=
|
||||
CONFIG=0
|
||||
SCRIPT_FILE=$(basename -- $0)
|
||||
SCRIPT_NAME=${SCRIPT_FILE%%.*}
|
||||
CONFIG_FILE_NAME="${SCRIPT_NAME}.cfg"
|
||||
CONFIG_FILE_TEMPLATE="$WDIR/${CONFIG_FILE_NAME}.example"
|
||||
|
||||
step_config() {
|
||||
## or to use sequencer api with global config file:
|
||||
initSeqConfig "$CONFIG_FILE_NAME" "$CONFIG_FILE_TEMPLATE"
|
||||
if [ $? -eq 0 ] ; then
|
||||
CONFIG=1
|
||||
else
|
||||
# End if no configuration file exists
|
||||
[ $DRY -eq 0 ] && return -1
|
||||
fi
|
||||
|
||||
## Apt cmdline option to suppress user interaction
|
||||
[ $QUIET -ne 0 ] && APTOPT="-y"
|
||||
|
||||
## Return of non zero value will abort the sequence
|
||||
return 0
|
||||
}
|
||||
|
||||
step_1_info() { echo "Install dependencies"; }
|
||||
step_1_alias() { ALIAS="install"; }
|
||||
step_1() {
|
||||
exe apt install $toolDeps $APTOPT
|
||||
}
|
||||
|
||||
step_2_info() { echo "Setup python virtual environment"; }
|
||||
step_2() {
|
||||
if ! id $CALWEB_USER &>/dev/null; then
|
||||
exe adduser --disabled-password --disabled-login --home-dir "$CALWEB_USER_HOME" --gecos "" $CALWEB_USER
|
||||
exe usermod -aG users $CALWEB_USER
|
||||
else
|
||||
echoseq " [W] User $CALWEB_USER already exists"
|
||||
fi
|
||||
if [ ! -e "$CALWEB_VENV_ROOT/bin" ]; then
|
||||
exe python3 -m venv "$CALWEB_VENV_ROOT"
|
||||
endReturn -o $? "Creating virtual environment failed"
|
||||
exe chown -R ${CALWEB_USER}: "$CALWEB_BASE"
|
||||
else
|
||||
echoseq " [W] Virtual env. $CALWEB_VENV_ROOT already exists"
|
||||
fi
|
||||
}
|
||||
|
||||
step_3_info() { echo "Install $toolName using pip"; }
|
||||
step_3() {
|
||||
step upgradepip
|
||||
exe ${CALWEB_VENV_ROOT}/bin/pip install $toolPipName
|
||||
}
|
||||
|
||||
step_4_info() {
|
||||
echo "Install $toolName features"
|
||||
echoinfo ${toolFeatures[*]}
|
||||
}
|
||||
step_4() {
|
||||
for i in "${!toolFeatures[@]}"; do
|
||||
toolFeatures[$i]="$toolPipName[${toolFeatures[$i]}]"
|
||||
done
|
||||
exe ${CALWEB_VENV_ROOT}/bin/pip install "${toolFeatures[@]}"
|
||||
}
|
||||
|
||||
step_5_info() { echo "Install systemd service"; }
|
||||
step_5() {
|
||||
addConf -s "$CALWEB_SERVICE" "$calweb_service_loc"
|
||||
[ $? -eq 0 ] && exe systemctl daemon-reload
|
||||
}
|
||||
calweb_service_name="calibreweb.service"
|
||||
calweb_service_loc="/etc/systemd/system/$calweb_service_name"
|
||||
|
||||
step_6_info() { echo "Enable and start systemd service"; }
|
||||
step_6() {
|
||||
exe systemctl enable $calweb_service_name --now
|
||||
}
|
||||
|
||||
step_15_info() { echo "Upgrade python pip"; }
|
||||
step_15_alias() { ALIAS="upgradepip"; }
|
||||
step_15()
|
||||
{
|
||||
exe ${CALWEB_VENV_ROOT}/bin/pip install --upgrade pip
|
||||
}
|
||||
|
||||
step_100_info() { echo "Setup notes"; }
|
||||
step_100_alias() { ALIAS="notes"; }
|
||||
step_100() {
|
||||
outColor green
|
||||
cat <<NOTES_END
|
||||
# Default admin login:
|
||||
|
||||
Username: admin
|
||||
Password: admin123
|
||||
|
||||
# nginx reverse proxy
|
||||
|
||||
nginx configuration for a local server listening on port 8083:
|
||||
|
||||
server {
|
||||
client_max_body_size 20M;
|
||||
location / {
|
||||
proxy_bind \$server_addr;
|
||||
proxy_pass http://127.0.0.1:8083;
|
||||
proxy_set_header Host \$http_host;
|
||||
proxy_set_header X-Forwarded-For \$proxy_add_x_forwarded_for;
|
||||
proxy_set_header X-Scheme \$scheme;
|
||||
}
|
||||
}
|
||||
|
||||
## mapping Calibre-Web to a subfolder /calibre
|
||||
|
||||
Change/add the following lines in the configuration above:
|
||||
|
||||
location /calibre {
|
||||
proxy_set_header X-Script-Name /calibre; # IMPORTANT: path has NO trailing slash
|
||||
|
||||
NOTES_END
|
||||
}
|
||||
|
||||
VERSION_SEQREV=15
|
||||
. /usr/local/bin/sequencer.sh
|
22
seqs/certbot.cfg.example
Normal file
22
seqs/certbot.cfg.example
Normal file
@@ -0,0 +1,22 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Web root path where certbot will place the ACME challenge files
|
||||
#
|
||||
# A nginx example location which needs to placed in the server config listening on port 80
|
||||
# for the first time and also in the config listeing on port 443 for renewals:
|
||||
#
|
||||
# location ^~ /.well-known/acme-challenge/ {
|
||||
# default_type "text/plain";
|
||||
# root /var/www/letsencrypt;
|
||||
# }
|
||||
CERTBOT_WEBROOT="/var/www/letsencrypt"
|
||||
|
||||
# Email address for important account notifications
|
||||
CERTBOT_MAIL="postmaster@mydomain.eu"
|
||||
|
||||
# Uncomment and list your domains here.
|
||||
# The first will be the subject CN and all other will be listed as Subject Alternative Names.
|
||||
#CERTBOT_DOMAINS=(\
|
||||
# mydomain.eu \
|
||||
# www.mydomain.eu \
|
||||
# )
|
83
seqs/certbot.sh
Executable file
83
seqs/certbot.sh
Executable file
@@ -0,0 +1,83 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Certbot installation and creation supporting Raspbian and Ubuntu.
|
||||
# Certificate can be created/updated as "certonly" only.
|
||||
|
||||
toolName=certbot
|
||||
|
||||
# Get script working directory
|
||||
# (when called from a different directory)
|
||||
WDIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >>/dev/null 2>&1 && pwd )"
|
||||
CONFIG=0
|
||||
CONFIG_FILE_NAME="${toolName}.cfg"
|
||||
CONFIG_FILE_TEMPLATE="$WDIR/${CONFIG_FILE_NAME}.example"
|
||||
|
||||
step_config() {
|
||||
initSeqConfig "$CONFIG_FILE_NAME" "$CONFIG_FILE_TEMPLATE"
|
||||
local confReturn=$?
|
||||
if [ $confReturn -eq 0 ] ; then
|
||||
CONFIG=1
|
||||
fi
|
||||
}
|
||||
|
||||
step_1_info() { echo "Install $toolName for letsencrypt"; }
|
||||
step_1_alias() { ALIAS="install"; }
|
||||
step_1() {
|
||||
local osName=
|
||||
local distName=
|
||||
|
||||
if [ "$(which lsb_release)" == "" ] ; then
|
||||
echoerr " [W] Cannot detect OS. Assuming Ubuntu"
|
||||
osName="Ubuntu"
|
||||
else
|
||||
osName=$(lsb_release -is)
|
||||
distName=$(lsb_release -cs)
|
||||
fi
|
||||
|
||||
if [ "$osName" == "" ] ; then
|
||||
echoerr " [W] Error dedecting OS. Assuming Ubuntu"
|
||||
osName="Ubuntu"
|
||||
fi
|
||||
|
||||
echo " [I] Detected OS: $osName $distName"
|
||||
|
||||
local aptOption=
|
||||
if [ $QUIET -ne 0 ] ; then
|
||||
aptOption="-y"
|
||||
else
|
||||
aptOption=""
|
||||
fi
|
||||
|
||||
if [ "$osName" == "Ubuntu" ] ; then
|
||||
exe apt-get update
|
||||
exe apt-get install software-properties-common $aptOption
|
||||
saveReturn $?
|
||||
exe add-apt-repository universe $aptOption
|
||||
saveReturn $?
|
||||
exe add-apt-repository ppa:certbot/certbot $aptOption
|
||||
saveReturn $?
|
||||
exe apt-get update
|
||||
|
||||
exe apt-get install $toolName $aptOption
|
||||
saveReturn $?
|
||||
endReturn "$toolName installation for $osName failed"
|
||||
elif [ "$osName" == "Raspbian" ] ; then
|
||||
exe apt update
|
||||
exe apt install certbot
|
||||
endReturn "$toolName installation for $osName failed"
|
||||
fi
|
||||
}
|
||||
|
||||
step_2_info() { echo "Create or update letsencrypt certificate"; }
|
||||
step_2_alias() { ALIAS="update"; }
|
||||
step_2() {
|
||||
endCheckEmpty CERTBOT_DOMAINS "No domain list found. Check configuration"
|
||||
endCheckEmpty CERTBOT_WEBROOT "Invalid web root. Check configuration"
|
||||
endCheckEmpty CERTBOT_MAIL "Invalid mail address. Check configuration"
|
||||
|
||||
exe certbot certonly --webroot -w "$CERTBOT_WEBROOT" --rsa-key-size 4096 --expand --agree-tos \
|
||||
-m "$CERTBOT_MAIL" ${CERTBOT_DOMAINS[@]/#/-d }
|
||||
}
|
||||
|
||||
VERSION_SEQREV=11
|
||||
. /usr/local/bin/sequencer.sh
|
134
seqs/coturn.sh
Executable file
134
seqs/coturn.sh
Executable file
@@ -0,0 +1,134 @@
|
||||
#!/bin/bash
|
||||
|
||||
toolName=coturn
|
||||
toolDeps="coturn miniupnpc"
|
||||
toolConf="/etc/turnserver.conf"
|
||||
toolServiceName="coturn.service"
|
||||
publicIpRetry=20
|
||||
|
||||
# Get script working directory
|
||||
# (when called from a different directory)
|
||||
WDIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" >>/dev/null 2>&1 && pwd)"
|
||||
APTOPT=
|
||||
CONFIG=0
|
||||
SCRIPT_FILE=$(basename -- $0)
|
||||
SCRIPT_NAME=${SCRIPT_FILE%%.*}
|
||||
CONFIG_FILE_NAME="${SCRIPT_NAME}.cfg"
|
||||
CONFIG_FILE_TEMPLATE="$WDIR/${CONFIG_FILE_NAME}.example"
|
||||
|
||||
step_config() {
|
||||
#echo "Called once before executing steps."
|
||||
## e.g. to source a config file manually:
|
||||
#. "$CONFIG_FILE"
|
||||
## or to use sequencer api with global config file:
|
||||
#initSeqConfig "$CONFIG_FILE_NAME" "$CONFIG_FILE_TEMPLATE"
|
||||
## or to use sequencer api with profile config file support:
|
||||
#initSeqConfig -p "$SCRIPT_NAME" "$CONFIG_FILE_TEMPLATE"
|
||||
#if [ $? -eq 0 ] ; then
|
||||
# CONFIG=1
|
||||
#else
|
||||
# # End if no configuration file exists
|
||||
# [ $DRY -eq 0 ] && return -1
|
||||
#fi
|
||||
[ $QUIET -ne 0 ] && APTOPT="-y"
|
||||
return 0
|
||||
}
|
||||
|
||||
step_1_info() { echo "Install $toolName"; }
|
||||
step_1_alias() { ALIAS="install"; }
|
||||
step_1() {
|
||||
exe apt update
|
||||
exe apt install $toolDeps $APTOPT
|
||||
}
|
||||
|
||||
step_10_info() {
|
||||
echo "Update $toolName 'external-ip' using dig [OPTION] [CUSTOM DNS]"
|
||||
echoinfo " [OPTION]"
|
||||
echoinfo " -l : Always output update required and error information"
|
||||
echoinfo " (even with -qq)"
|
||||
}
|
||||
step_10_alias() { ALIAS="updateip"; }
|
||||
step_10() {
|
||||
exitIfRunning
|
||||
shift
|
||||
local retryCount=$publicIpRetry
|
||||
local ipUpdater
|
||||
local ipRegex='^[0-2]*[0-9]{1,2}\.[0-2]*[0-9]{1,2}\.[0-2]*[0-9]{1,2}\.[0-2]*[0-9]{1,2}\/*[0-9]*$'
|
||||
local dnsUrl="46.182.19.48" #digitalcourage.de/support/zensurfreier-dns-server
|
||||
local dnsFallbackUrl="194.150.168.168" #dns.as250.net; Berlin/Frankfurt
|
||||
local lecho="echoseq"
|
||||
if [ "$1" == "-l" ]; then
|
||||
lecho="echo"
|
||||
shift
|
||||
fi
|
||||
|
||||
local pubIp
|
||||
|
||||
while [ $retryCount -gt 0 ]; do
|
||||
pubIp=`"$(command -v upnpc)" -s | grep ^ExternalIPAddress | cut -c21-`
|
||||
[ $? -eq 0 ] && ipUpdater="upnpc" && break || "$lecho" "[$(date)] [W] Upnpc failed"
|
||||
pubIp=$(dig @$dnsUrl +short +timeout=1 cloud.imoff.de 2>>/dev/null)
|
||||
[ $? -eq 0 ] && ipUpdater="DNS" && break || "$lecho" "[$(date) [W] DNS lookup to $dnsUrl failed"
|
||||
pubIp=$(dig @$dnsFallbackUrl +short +timeout=1 cloud.imoff.de 2>>/dev/null)
|
||||
[ $? -eq 0 ] && ipUpdater="DNS Fallback" && break || "$lecho" "[$(date)] [W] DNS lookup to $dnsFallbackUrl failed"
|
||||
((retryCount--))
|
||||
done
|
||||
|
||||
if [[ ! $pubIp =~ $ipRegex ]]; then
|
||||
"$lecho" "[$(date)] [E] Couldn't aquire public IP. Giving up."
|
||||
return 1
|
||||
fi
|
||||
|
||||
local confIp=`cat "$toolConf" | grep "^external-ip" | cut -d'=' -f2`
|
||||
|
||||
if [ "$pubIp" != "$confIp" ]; then
|
||||
$lecho "[$(date)] [I] Update required (via $ipUpdater). New public ip: $pubIp"
|
||||
exe sed -i "s/^external-ip[[:space:]]*=.*/external-ip=${pubIp}/" "$toolConf"
|
||||
exe sleep 1
|
||||
$lecho "[$(date)] [I] Restarting $toolName"
|
||||
exe /bin/systemctl restart $toolServiceName
|
||||
else
|
||||
echoseq "[$(date)] [I] No update required (via $ipUpdater). Current ip: $confIp"
|
||||
fi
|
||||
}
|
||||
|
||||
step_12_info() { echo "Setup public ip update cron job every 5 minutes"; }
|
||||
step_12_alias() { ALIAS="cronip"; }
|
||||
step_12() {
|
||||
echoseq " [I] Setup $ipCronLoc"
|
||||
addConf -s "$ipCron" "$ipCronLoc"
|
||||
}
|
||||
ipCronLoc="/etc/cron.d/update_public_ip"
|
||||
ipCron="*/5 * * * * root $WDIR/$SCRIPT_FILE -qq updateip"
|
||||
|
||||
step_100_info() { echo "Installation notes"; }
|
||||
step_100_alias() { ALIAS="notes"; }
|
||||
step_100() {
|
||||
outColor green
|
||||
cat <<COTURN_EOF
|
||||
# Port forwarding
|
||||
|
||||
3478 tcp/udp
|
||||
5349 tcp/udp
|
||||
|
||||
# Permissions
|
||||
|
||||
When using letsencrypt certificates for transport security.
|
||||
|
||||
* Add user \`turnserver\` to group \`www-data\`
|
||||
|
||||
usermod -aG www-data turnserver
|
||||
|
||||
* In the renewal deploy script of cerbot add:
|
||||
|
||||
LOC_DOMAIN="yourdoma.in"
|
||||
chown root:www-data /etc/letsencrypt/archive
|
||||
chmod 750 /etc/letsencrypt/archive
|
||||
chown root:www-data /etc/letsencrypt/archive/\$LOC_DOMAIN/privkey*
|
||||
chmod g+r /etc/letsencrypt/archive/\$LOC_DOMAIN/privkey*
|
||||
|
||||
COTURN_EOF
|
||||
}
|
||||
|
||||
VERSION_SEQREV=13
|
||||
. /usr/local/bin/sequencer.sh
|
6
seqs/couchpotato.cfg.example
Normal file
6
seqs/couchpotato.cfg.example
Normal file
@@ -0,0 +1,6 @@
|
||||
#!/bin/bash
|
||||
|
||||
#CPO = couchpotato
|
||||
|
||||
CPO_USER="couchpotato"
|
||||
CPO_INSTALL_DIR="/var/lib/CouchPotatoServer"
|
65
seqs/couchpotato.sh
Executable file
65
seqs/couchpotato.sh
Executable file
@@ -0,0 +1,65 @@
|
||||
#!/bin/bash
|
||||
|
||||
toolName=couchpotato
|
||||
toolDeps="git python-lxml python-pip libssl-dev libffi-dev"
|
||||
toolGit="https://github.com/CouchPotato/CouchPotatoServer.git"
|
||||
|
||||
# Get script working directory
|
||||
# (when called from a different directory)
|
||||
WDIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" >>/dev/null 2>&1 && pwd)"
|
||||
APTOPT=
|
||||
CONFIG=0
|
||||
SCRIPT_NAME=$(basename -- $0)
|
||||
SCRIPT_NAME=${SCRIPT_NAME%%.*}
|
||||
CONFIG_FILE_NAME="${SCRIPT_NAME}.cfg"
|
||||
CONFIG_FILE_TEMPLATE="$WDIR/${CONFIG_FILE_NAME}.example"
|
||||
|
||||
step_config() {
|
||||
initSeqConfig "$CONFIG_FILE_NAME" "$CONFIG_FILE_TEMPLATE"
|
||||
if [ $? -eq 0 ] ; then
|
||||
CONFIG=1
|
||||
else
|
||||
[ $DRY -eq 0 ] && return -1
|
||||
fi
|
||||
[ $QUIET -ne 0 ] && APTOPT="-y"
|
||||
return 0
|
||||
}
|
||||
|
||||
step_1_info() {
|
||||
echo "Install $toolName"
|
||||
echoinfo "Default port: 5050"
|
||||
}
|
||||
step_1_alias() { ALIAS="install"; }
|
||||
step_1() {
|
||||
exe apt update
|
||||
exe apt install $toolDeps $APTOPT
|
||||
exe pip install --upgrade pyopenssl
|
||||
endReturn -o $? "Pip install pyopenssl failed"
|
||||
}
|
||||
|
||||
step_2_info() { echo "Clone git repository"; }
|
||||
step_2() {
|
||||
exe git clone $toolGit "$CPO_INSTALL_DIR"
|
||||
}
|
||||
|
||||
step_3_info() { echo "Create user $toolUser"; }
|
||||
step_3() {
|
||||
exe adduser --system --group --home "${CPO_INSTALL_DIR}" --no-create-home "$CPO_USER"
|
||||
exe chown -R ${CPO_USER}: "${CPO_INSTALL_DIR}"
|
||||
}
|
||||
|
||||
step_4_info() { echo "Create systemd service"; }
|
||||
step_4() {
|
||||
exe cp "$CPO_INSTALL_DIR/init/couchpotato.service" "/etc/systemd/system"
|
||||
endReturn -o $? "Creating service file failed"
|
||||
exe systemctl daemon-reload
|
||||
}
|
||||
|
||||
step_5_info() { echo "Add ufw rule for web interface"; }
|
||||
step_5_alias() { ALIAS="ufw"; }
|
||||
step_5() {
|
||||
exe ufw allow in on eth0 to any port 5050 proto tcp comment "couchpotato"
|
||||
}
|
||||
|
||||
VERSION_SEQREV=12
|
||||
. /usr/local/bin/sequencer.sh
|
300
seqs/debianrpi.sh
Executable file
300
seqs/debianrpi.sh
Executable file
@@ -0,0 +1,300 @@
|
||||
#!/bin/bash
|
||||
|
||||
#toolName=mytool
|
||||
toolDownSite="https://raspi.debian.net/tested-images"
|
||||
toolDownUrl=
|
||||
toolDownFile=
|
||||
|
||||
toolEssentialDeps="vim bash-completion man-db locales wget"
|
||||
|
||||
SDDEV=
|
||||
SDBOOT=
|
||||
SDBOOTPUUID=
|
||||
SDROOT=
|
||||
SDROOTDEV=
|
||||
SDROOTPUUID=
|
||||
|
||||
# Get script working directory
|
||||
# (when called from a different directory)
|
||||
WDIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >>/dev/null 2>&1 && pwd )"
|
||||
APTOPT=
|
||||
CONFIG=0
|
||||
SCRIPT_NAME=$(basename -- $0)
|
||||
SCRIPT_NAME=${SCRIPT_NAME%%.*}
|
||||
CONFIG_FILE_NAME="${SCRIPT_NAME}.cfg"
|
||||
CONFIG_FILE_TEMPLATE="$WDIR/${CONFIG_FILE_NAME}.example"
|
||||
|
||||
step_config() {
|
||||
[ $QUIET -ne 0 ] && APTOPT="-y"
|
||||
return 0
|
||||
}
|
||||
|
||||
step_1_info() {
|
||||
echo "Download latest xz-compressed image [IMAGE FILE URL] [SD CARD DEVICE]"
|
||||
echoinfo "$toolDownSite"
|
||||
}
|
||||
step_1_alias() { ALIAS="install"; }
|
||||
step_1() {
|
||||
shift
|
||||
SDDEV="$2"
|
||||
if [ -z "$1" ] && [ $QUIET -eq 0 ] ; then
|
||||
read -p "Provide image download url from $toolDownSite: " toolDownUrl
|
||||
elif [ ! -z "$1" ] ; then
|
||||
toolDownUrl="$1"
|
||||
else
|
||||
echoerr " [E] No image file provided for download"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
toolDownFile="/tmp/${toolDownUrl//*\//}"
|
||||
local downSha256="${toolDownUrl%.img.xz}.xz.sha256"
|
||||
local downShaFile="${toolDownFile%.img.xz}.xz.sha256"
|
||||
|
||||
echo Url: ${toolDownUrl}
|
||||
echo Sha256: $downSha256
|
||||
echo "Files: $toolDownFile"
|
||||
echo " $downShaFile"
|
||||
|
||||
if [ ! -f "$downShaFile" ] ; then
|
||||
exe wget -O "$downShaFile" "$downSha256"
|
||||
endReturn -o $? "Error downloading $downShaFile"
|
||||
fi
|
||||
|
||||
if [ ! -f "$toolDownFile" ] ; then
|
||||
exe wget -O "$toolDownFile" "$toolDownUrl"
|
||||
endReturn -o $? "Error downloading $downDownFile"
|
||||
fi
|
||||
|
||||
echoseq " [I] Checking SHA256 checksum"
|
||||
exe cd $(dirname "$toolDownFile")
|
||||
exe sha256sum -c "$downShaFile" >>/dev/null
|
||||
endReturn -o $? "SHA256 checksum error"
|
||||
}
|
||||
|
||||
step_2_info() { echo "Write image to device [DEVICE]"; }
|
||||
step_2() {
|
||||
shift
|
||||
if [ -z "$SDDEV" ] ; then
|
||||
SDDEV="$1"
|
||||
fi
|
||||
read_sd_dev "$SDDEV"
|
||||
# check if device was confirmed
|
||||
endReturn -o $? "SD card device not found"
|
||||
|
||||
echoseq " [I] Writing $(basename "$toolDownFile")"
|
||||
exep "xzcat \"$toolDownFile\" | dd of=$SDDEV bs=64k oflag=dsync status=progress"
|
||||
exe sync
|
||||
}
|
||||
|
||||
step_3_info() { echo "Prepare SD card for first run"; }
|
||||
step_3() {
|
||||
outColor green
|
||||
cat <<PREPARE_EOF
|
||||
[I] Setup static IP
|
||||
[etc/network/interfaces.d/eth0]
|
||||
#iface eth0 inet dhcp
|
||||
|
||||
iface eth0 inet static
|
||||
address 192.168.0.38/24
|
||||
gateway 192.168.0.1
|
||||
|
||||
iface eth0 inet6 static
|
||||
address fd00::38/72
|
||||
gateway fd00::1/64
|
||||
|
||||
[I] Disable ipv6
|
||||
[etc/sysctl.conf]
|
||||
net.ipv6.conf.eth0.disable_ipv6 = 1
|
||||
|
||||
[I] Setup dns nameserver
|
||||
[etc/resolv.conf]
|
||||
nameserver 192.168.0.1
|
||||
nameserver fd00::1
|
||||
|
||||
[I] Setup root ssh access
|
||||
[etc/ssh/sshd_config]
|
||||
PermitRootLogin yes
|
||||
|
||||
[root/.ssh/authorized_keys]
|
||||
# Root login only possible with an ssh key
|
||||
|
||||
PREPARE_EOF
|
||||
}
|
||||
|
||||
step_10_info() { echo "Essential debian setup"; }
|
||||
step_10_alias() { ALIAS="setup"; }
|
||||
step_10() {
|
||||
if [ -z "$(ls /etc/default | grep raspi)" ] ; then
|
||||
echoerr " [E] Not on a Raspberry pi"
|
||||
return 1
|
||||
fi
|
||||
|
||||
exe apt update
|
||||
exe apt full-upgrade $APTOPT
|
||||
exe apt install $toolEssentialDeps $APTOPT
|
||||
}
|
||||
|
||||
step_11_info() { echo "Set timezone"; }
|
||||
step_11() {
|
||||
exe dpkg-reconfigure tzdata
|
||||
}
|
||||
|
||||
step_12_info() { echo "Setup locales to en_US.UTF-8"; }
|
||||
step_12() {
|
||||
local localUs="en_US.UTF-8"
|
||||
local localUsDefault="$localUs UTF-8"
|
||||
if [ ! -f "$localesConfigLoc" ] ; then
|
||||
echoerr " [E] Install packages locales first"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
exe sed -i "s/#[[:space:]]*\($localUsDefault\)/\1/" "$localesConfigLoc"
|
||||
endReturn -o $? "Changing locales failed"
|
||||
exe locale-gen
|
||||
exe update-locale LANG=$localUs
|
||||
echoseq " [I] Logout and login for changes to be active"
|
||||
}
|
||||
localesConfigLoc="/etc/locale.gen"
|
||||
|
||||
step_14_info() { echo "Change hostname [HOSTNAME]"; }
|
||||
step_14_alias() { ALIAS="hostname"; }
|
||||
step_14() {
|
||||
shift
|
||||
local localHostname=$1
|
||||
endCheckEmpty localHostname "No hostname provided"
|
||||
if [ $(grep -r "$localHostname" "$hostsLoc">>/dev/null; echo $?) -eq 0 ] ; then
|
||||
echoseq " [I] Hostname $localHostname already defined"
|
||||
return 0
|
||||
fi
|
||||
exe hostnamectl set-hostname "$localHostname"
|
||||
endReturn -o $? "Couldn't set hostname"
|
||||
exe sed -i "s/^\(127\.0\.0\.1[[:space:]]*\)\(localhost.*\)/\1\2\n\1$localHostname/" "$hostsLoc"
|
||||
}
|
||||
hostsLoc="/etc/hosts"
|
||||
|
||||
step_16_info() { echo "Install cifs mounting requirements"; }
|
||||
step_16_alias() { ALIAS="cifs"; }
|
||||
step_16() {
|
||||
exe apt install cifs-utils $APTOPT
|
||||
}
|
||||
|
||||
step_17_info() { echo "Cifs notes"; }
|
||||
step_17() {
|
||||
outColor green
|
||||
cat <<CIFS_EOF
|
||||
# Example fstab entry
|
||||
[/etc/fstab]
|
||||
//192.168.0.10/Qdownload /mnt/Qdownload cifs vers=1.0,credentials=/root/.smbpasswd,uid=username,gid=groupname,file_mode=0775,dir_mode=0775 0 0
|
||||
|
||||
# Mounting during boot may fail on Rpi4. This changes the entry to automount
|
||||
(note "_netdev" and "comment=systemd.automount")
|
||||
//192.168.0.10/Qdownload /mnt/Qdownload cifs _netdev,vers=2.0,credentials=/root/.smbpasswd,uid=username,gid=groupname,file_mode=0775,dir_mode=0775,comment=systemd.automount 0 0
|
||||
|
||||
## Alternatively this options were reported to work
|
||||
auto,x-systemd.automount
|
||||
|
||||
# Example .smbpasswd
|
||||
Don't forget to chown 600 this file.
|
||||
[/root/.smbpasswd]
|
||||
username=REMOTEUSER
|
||||
password=REMOTEPASSWORD
|
||||
|
||||
CIFS_EOF
|
||||
}
|
||||
|
||||
step_19_info() { echo "Setup notes"; }
|
||||
step_19_alias() { ALIAS="setupnotes"; }
|
||||
step_19() {
|
||||
outColor green
|
||||
cat <<SETUPNOTES_EOF
|
||||
# Secure root with a password
|
||||
passwd
|
||||
|
||||
# Create a regular user
|
||||
adduser USERNAME
|
||||
|
||||
SETUPNOTES_EOF
|
||||
}
|
||||
|
||||
step_40_info() { echo "Boot from HD notes"; }
|
||||
step_40_alias() { ALIAS="hdboot"; }
|
||||
step_40() {
|
||||
outColor green
|
||||
cat <<HDBOOT_EOF
|
||||
[I] Raspberry pi 4 boots from USB automatically if there is no SD available
|
||||
(needs boot loader version September 3rd)
|
||||
|
||||
[I] Adding a swap partition
|
||||
|
||||
* [RASPIROOTSSD/etc/fstab]
|
||||
LABEL=RASPISWAP none swap sw 0 3
|
||||
* Debian enables a swap partition automatically
|
||||
because by default there is no swap file
|
||||
|
||||
[I] Procedure for raspi 3 is similar to the one for raspbian
|
||||
(boot on SD and root on SSD)
|
||||
|
||||
* Clone RAPSIROOT from SD to SSD
|
||||
rsync -axHAX RASPIROOT/ RASPIROOTSSD/
|
||||
* [/boot/firmware/cmdline.txt]
|
||||
root=LABEL=RASPIROOTSSD
|
||||
* [RASPIROOTSSD/etc/fstab]
|
||||
LABEL=RASPIROOTSSD / ...
|
||||
|
||||
HDBOOT_EOF
|
||||
}
|
||||
|
||||
read_sd_dev() {
|
||||
local partExt=""
|
||||
if [ ! -z "$1" ] ; then
|
||||
SDBOOT=
|
||||
SDROOT=
|
||||
SDROOTDEV=
|
||||
SDROOTPUUID=
|
||||
SDBOOTPUUID=
|
||||
SDDEV="$1"
|
||||
elif [ -z $SDDEV ] || [ ! -b "$SDDEV" ] ; then
|
||||
SDDEV=
|
||||
SDBOOT=
|
||||
SDROOT=
|
||||
SDROOTDEV=
|
||||
SDBOOTPUUID=
|
||||
SDROOTPUUID=
|
||||
echo " [I] Available devices:"
|
||||
echo
|
||||
exe lsblk -p
|
||||
echo
|
||||
exe read -p "Provide SD card device (e.g. /dev/sdb): " SDDEV
|
||||
fi
|
||||
|
||||
if [ ! -b "$SDDEV" ] ; then
|
||||
echoerr " [I] $SDDEV not a block device"
|
||||
SDDEV=
|
||||
return 1
|
||||
fi
|
||||
|
||||
if [[ "$SDDEV" =~ .*blk.* ]] ; then
|
||||
partExt="p"
|
||||
fi
|
||||
|
||||
if [ -z $SDBOOT ] ; then
|
||||
SDBOOT=$(findmnt -no TARGET "${SDDEV}${partExt}${SDBOOTPARTNO}")
|
||||
fi
|
||||
if [ -z $SDBOOTPUUID ] ; then
|
||||
IFS=\" read -r _ vPARTUUID _ < <(blkid "${SDDEV}${partExt}${SDBOOTPARTNO}" -s PARTUUID)
|
||||
SDBOOTPUUID=$vPARTUUID
|
||||
fi
|
||||
SDROOTDEV=${SDDEV}${partExt}${SDROOTPARTNO}
|
||||
if [ -z $SDROOT ] ; then
|
||||
SDROOT=$(findmnt -no TARGET "${SDROOTDEV}")
|
||||
fi
|
||||
if [ -z $SDROOTPUUID ] ; then
|
||||
SDROOTPUUID=$(findmnt -no PARTUUID "${SDROOTDEV}")
|
||||
fi
|
||||
|
||||
return 0
|
||||
}
|
||||
SDBOOTPARTNO=1
|
||||
SDROOTPARTNO=2
|
||||
VERSION_SEQREV=12
|
||||
. /usr/local/bin/sequencer.sh
|
5
seqs/downloader.cfg.example
Normal file
5
seqs/downloader.cfg.example
Normal file
@@ -0,0 +1,5 @@
|
||||
#!/bin/bash
|
||||
|
||||
DLD_USER="dluser"
|
||||
DLD_DIR="/opt/downloaders"
|
||||
DLD_CONFDIR="/opt/downloaders.conf"
|
617
seqs/downloader.sh
Executable file
617
seqs/downloader.sh
Executable file
@@ -0,0 +1,617 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Get script working directory
|
||||
# (when called from a different directory)
|
||||
WDIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" >>/dev/null 2>&1 && pwd)"
|
||||
APTOPT=
|
||||
CONFIG=0
|
||||
SCRIPT_NAME=$(basename -- $0)
|
||||
SCRIPT_NAME=${SCRIPT_NAME%%.*}
|
||||
CONFIG_FILE_NAME="${SCRIPT_NAME}.cfg"
|
||||
CONFIG_FILE_TEMPLATE="$WDIR/${CONFIG_FILE_NAME}.example"
|
||||
|
||||
step_config() {
|
||||
checkVpn
|
||||
|
||||
initSeqConfig -t "$CONFIG_FILE_NAME" "$CONFIG_FILE_TEMPLATE"
|
||||
if [ $? -eq 0 ] ; then
|
||||
CONFIG=1
|
||||
else
|
||||
# End if no configuration file exists
|
||||
[ $DRY -eq 0 ] && return -1
|
||||
fi
|
||||
[ $QUIET -ne 0 ] && APTOPT="-y"
|
||||
return 0
|
||||
}
|
||||
|
||||
step_1_info() { echo "Install mono"; }
|
||||
step_1_alias() { ALIAS="install"; }
|
||||
step_1() {
|
||||
exe apt install apt-transport-https dirmngr gnupg ca-certificates
|
||||
exe apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv-keys 3FA7E0328081BFF6A14DA29AA6A19B38D3D831EF
|
||||
|
||||
exep "echo \"deb https://download.mono-project.com/repo/debian stable-buster main\" | sudo tee /etc/apt/sources.list.d/mono-official-stable.list"
|
||||
|
||||
exe apt update
|
||||
# This will apparently be managed by the installation of sonarr later
|
||||
# (https://sonarr.tv/#downloads-v3-linux Chapter 1)
|
||||
#exe apt install mono-complete
|
||||
}
|
||||
|
||||
step_2_info() { echo "Install mediainfo"; }
|
||||
step_2() {
|
||||
exe wget https://mediaarea.net/repo/deb/repo-mediaarea_1.0-16_all.deb -O /tmp/repo-mediaarea_all.deb
|
||||
|
||||
exe dpkg -i /tmp/repo-mediaarea_all.deb
|
||||
|
||||
exe apt update
|
||||
exe apt install mediainfo
|
||||
}
|
||||
|
||||
step_3_info() { echo "Add system user"; }
|
||||
step_3() {
|
||||
exe adduser --system $DLD_USER --group --home "${DLD_CONFDIR}"
|
||||
}
|
||||
|
||||
step_4_info() {
|
||||
echo "Install sonarr"
|
||||
echoinfo "Default port: 8989"
|
||||
}
|
||||
step_4() {
|
||||
exe apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv-keys 2009837CBFFD68F45BC180471F4F90DE2A9B4BF8
|
||||
exep "echo \"deb https://apt.sonarr.tv/debian buster main\" | tee /etc/apt/sources.list.d/sonarr.list"
|
||||
exe apt update
|
||||
exe apt install sonarr
|
||||
# Start of sonar must be managed by VPN service
|
||||
exe service sonarr stop
|
||||
exe systemctl disable sonarr
|
||||
}
|
||||
|
||||
step_5_info() {
|
||||
echo "Install radarr for arm64"
|
||||
echoinfo "Default port: 7878"
|
||||
}
|
||||
step_5() {
|
||||
# nightly https://radarr.servarr.com/v1/update/nightly/updatefile?os=linux&runtime=netcore&arch=arm64
|
||||
# develop https://radarr.servarr.com/v1/update/develop/updatefile?os=linux&runtime=netcore&arch=arm64
|
||||
exe curl -sL "https://radarr.servarr.com/v1/update/master/updatefile?os=linux&runtime=netcore&arch=arm64" \
|
||||
-o /tmp/Radarr.tgz
|
||||
|
||||
exe tar xvzf /tmp/Radarr.tgz -C "${DLD_DIR}/"
|
||||
exe mv ${DLD_DIR}/Radarr "${DLD_DIR}/radarr"
|
||||
exe chown -R ${DLD_USER}:${DLD_USER} "${DLD_DIR}/radarr"
|
||||
}
|
||||
|
||||
step_6_info() { echo "Create radarr service"; }
|
||||
step_6() {
|
||||
local radarrConf="${DLD_CONFDIR}/radarr"
|
||||
local radarrServiceLoc="/etc/systemd/system/radarr.service"
|
||||
|
||||
exe mkdir -p "$radarrConf"
|
||||
exe chown -R $DLD_USER: "$radarrConf"
|
||||
|
||||
addConf -s "$radarrService" "$radarrServiceLoc"
|
||||
exe systemctl daemon-reload
|
||||
}
|
||||
radarrService="[Unit]
|
||||
Description=Radarr Daemon
|
||||
After=syslog.target network.target
|
||||
Wants=transmission.service jackett.service nzbget.service
|
||||
StartLimitIntervalSec=0
|
||||
|
||||
[Service]
|
||||
User=\$DLD_USER
|
||||
Group=\$DLD_USER
|
||||
|
||||
Type=simple
|
||||
|
||||
ExecStart=\${DLD_DIR}/radarr/Radarr -nobrowser -data=\$radarrConf
|
||||
TimeoutStopSec=20
|
||||
KillMode=process
|
||||
Restart=on-failure
|
||||
RestartSec=5
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
Alias=radarr.service"
|
||||
|
||||
step_7_info() {
|
||||
echo "Install jackett for arm64"
|
||||
echoinfo "Default port: 9117"
|
||||
}
|
||||
step_7() {
|
||||
local jTar="/tmp/Jackett.tgz"
|
||||
local jUrl="https://github.com/Jackett/Jackett/releases/latest/download/Jackett.Binaries.LinuxARM64.tar.gz"
|
||||
|
||||
[ ! -e "$jTar" ] && exe curl -sL "$jUrl" -o "$jTar"
|
||||
|
||||
exe tar xvzf "$jTar" -C "${DLD_DIR}"
|
||||
exe mv "${DLD_DIR}/Jackett" "${DLD_DIR}/jackett"
|
||||
exe chown -R ${DLD_USER}:${DLD_USER} "${DLD_DIR}/jackett"
|
||||
}
|
||||
|
||||
step_8_info() { echo "Create jackett service"; }
|
||||
step_8() {
|
||||
local jackettServiceLoc="/etc/systemd/system/jackett.service"
|
||||
local lService=`eval "echo \"$jackettService\""`
|
||||
addConf -s "$lService" "$jackettServiceLoc"
|
||||
exe systemctl daemon-reload
|
||||
}
|
||||
jackettService="[Unit]
|
||||
Description=Jackett Daemon
|
||||
After=syslog.target network.target
|
||||
StartLimitIntervalSec=0
|
||||
|
||||
[Service]
|
||||
User=\$DLD_USER
|
||||
Group=\$DLD_USER
|
||||
|
||||
Type=simple
|
||||
SyslogIdentifier=jackett
|
||||
Restart=on-failure
|
||||
RestartSec=5
|
||||
WorkingDirectory=\${DLD_DIR}/jackett
|
||||
ExecStart=/bin/sh \${DLD_DIR}/jackett/jackett_launcher.sh
|
||||
TimeoutStopSec=30
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
Alias=jackett.service"
|
||||
|
||||
step_9_info() {
|
||||
echo "Install NZBGet for arm64"
|
||||
echoinfo "Default port: 6789"
|
||||
}
|
||||
step_9() {
|
||||
exe wget -q https://nzbget.net/download/nzbget-latest-bin-linux.run -O /tmp/nzbget-latest-bin-linux.run
|
||||
|
||||
# you can skip --arch aarch64 to auto-detect the architecture
|
||||
exe sh /tmp/nzbget-latest-bin-linux.run --destdir "${DLD_DIR}/nzbget" --arch aarch64
|
||||
|
||||
exe chown -R ${DLD_USER}:${DLD_USER} "${DLD_DIR}/nzbget"
|
||||
}
|
||||
|
||||
step_10_info() { echo "Create NZBGet service"; }
|
||||
step_10() {
|
||||
local nzbServiceLoc="/etc/systemd/system/nzbget.service"
|
||||
local lService=`eval "echo \"$nzbService\""`
|
||||
local nzbConfOri="${DLD_DIR}/nzbget/nzbget.conf"
|
||||
local nzbConf="${DLD_CONFDIR}/nzbget/nzbget.conf"
|
||||
exe mkdir -p "$(dirname "$nzbConf")"
|
||||
exe chown -R $DLD_USER: "$(dirname "$nzbConf")"/..
|
||||
|
||||
addConf -s "$lService" "$nzbServiceLoc"
|
||||
exe systemctl daemon-reload
|
||||
|
||||
exe cp -n "$nzbConfOri" "$nzbConf"
|
||||
}
|
||||
nzbService="[Unit]
|
||||
Description=NZBGet Daemon
|
||||
After=syslog.target network.target
|
||||
StartLimitIntervalSec=0
|
||||
|
||||
[Service]
|
||||
# Change the user and group variables here.
|
||||
User=\$DLD_USER
|
||||
Group=\$DLD_USER
|
||||
|
||||
Type=forking
|
||||
|
||||
# Pass any command line arguments etc.
|
||||
ExecStart=\${DLD_DIR}/nzbget/nzbget -D -c \${DLD_CONFDIR}/nzbget/nzbget.conf
|
||||
ExecStop=\${DLD_DIR}/nzbget/nzbget -Q -c \${DLD_CONFDIR}/nzbget/nzbget.conf
|
||||
ExecReload=\${DLD_DIR}/nzbget/nzbget -O -c \${DLD_CONFDIR}/nzbget/nzbget.conf
|
||||
TimeoutStopSec=20
|
||||
KillMode=process
|
||||
Restart=on-failure
|
||||
RestartSec=5
|
||||
|
||||
# Sandboxing ... (see https://www.freedesktop.org/software/systemd/man/systemd.exec.html for more info)
|
||||
ReadWritePaths=\${DLD_DIR}/nzbget \${DLD_CONFDIR}/nzbget /mnt
|
||||
ProtectSystem=strict
|
||||
PrivateDevices=true
|
||||
ProtectHome=true
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target sonarr.service radarr.service
|
||||
Alias=nzbget.service
|
||||
#RequiredBy=sonarr.service radarr.service"
|
||||
|
||||
step_11_info() {
|
||||
echo "Install lidarr for arm64"
|
||||
echoinfo "Default port: 8686"
|
||||
}
|
||||
step_11() {
|
||||
local lidarrDeps="libchromaprint-tools"
|
||||
local lidarrUrl="https://lidarr.servarr.com/v1/update/develop/updatefile?os=linux&runtime=netcore&arch=arm64"
|
||||
exe curl -sL "$lidarrUrl" -o /tmp/Lidarr.tgz
|
||||
endReturn -o "Download failed"
|
||||
|
||||
exe apt install $lidarrDeps $APTOPT
|
||||
|
||||
exe tar xvzf /tmp/Lidarr.tgz -C "${DLD_DIR}/"
|
||||
exe mv "${DLD_DIR}/Lidarr" "${DLD_DIR}/lidarr"
|
||||
exe chown -R ${DLD_USER}:${DLD_USER} "${DLD_DIR}/lidarr"
|
||||
}
|
||||
|
||||
step_12_info() { echo "Create lidarr service"; }
|
||||
step_12() {
|
||||
local lidarrConf="${DLD_CONFDIR}/lidarr"
|
||||
local lidarrServiceLoc="/etc/systemd/system/lidarr.service"
|
||||
local lService=`eval "echo \"$lidarrService\""`
|
||||
exe mkdir -p "$lidarrConf"
|
||||
exe chown -R $DLD_USER: "$lidarrConf"
|
||||
|
||||
addConf -s "$lService" "$lidarrServiceLoc"
|
||||
exe systemctl daemon-reload
|
||||
}
|
||||
lidarrService="[Unit]
|
||||
Description=Lidarr Daemon
|
||||
After=syslog.target network.target
|
||||
Wants=transmission.service jackett.service nzbget.service
|
||||
StartLimitIntervalSec=0
|
||||
|
||||
[Service]
|
||||
User=\$DLD_USER
|
||||
Group=\$DLD_USER
|
||||
|
||||
Type=simple
|
||||
|
||||
ExecStart=\${DLD_DIR}/lidarr/Lidarr -nobrowser -data=\$lidarrConf
|
||||
TimeoutStopSec=20
|
||||
KillMode=process
|
||||
Restart=on-failure
|
||||
RestartSec=5
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
Alias=lidarr.service"
|
||||
|
||||
|
||||
step_13_info() { echo "Install bazarr dependencies"; }
|
||||
step_13() {
|
||||
local bazarrDeps="python3-pip python3-distutils python3-venv ffmpeg"
|
||||
#local bazarrDeps+=" libxml2-dev libxslt1-dev python3-libxml2 python3-lxml libatlas-base-dev"
|
||||
|
||||
exe apt install $bazarrDeps $APTOPT
|
||||
}
|
||||
|
||||
step_14_info() { echo "Install bazarr"; }
|
||||
step_14() {
|
||||
local bazarrServiceLoc="/etc/systemd/system/bazarr.service"
|
||||
local lService=`eval "echo \"$bazarrService\""`
|
||||
local bazarrVenv="${DLD_DIR}/bazarr"
|
||||
local bazarrDir="${bazarrVenv}/bazarr"
|
||||
|
||||
local bazarrGitUrl="https://github.com/morpheus65535/bazarr.git"
|
||||
|
||||
exe python3 -m venv "$bazarrVenv"
|
||||
endReturn -o $? "Creating virtual environment failed"
|
||||
|
||||
exe git clone $bazarrGitUrl "$bazarrDir"
|
||||
exe chown -R $DLD_USER: "$bazarrVenv"
|
||||
exe sudo -u $DLD_USER ${bazarrVenv}/bin/pip install --upgrade pip
|
||||
exe sudo -u $DLD_USER ${bazarrVenv}/bin/pip install -r ${bazarrDir}/requirements.txt
|
||||
|
||||
addConf -s "$lService" "$bazarrServiceLoc"
|
||||
exe systemctl daemon-reload
|
||||
}
|
||||
bazarrService="[Unit]
|
||||
Description=Bazarr
|
||||
After=syslog.target network.target
|
||||
Wants=sonarr.service radarr.service
|
||||
StartLimitIntervalSec=0
|
||||
|
||||
[Service]
|
||||
User=\$DLD_USER
|
||||
Group=\$DLD_USER
|
||||
|
||||
Type=simple
|
||||
|
||||
ExecStart=\${DLD_DIR}/bazarr/bin/python3 \${DLD_DIR}/bazarr/bazarr/bazarr.py
|
||||
TimeoutStopSec=20
|
||||
#KillMode=process
|
||||
Restart=always
|
||||
RestartSec=5
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
Alias=bazarr.service"
|
||||
|
||||
step_15_info() { echo "Create ufw rules for default ports"; }
|
||||
step_15_alias() { ALIAS="ufw"; }
|
||||
step_15() {
|
||||
exe ufw allow in on eth0 to any port 6789 proto tcp comment "NZBGet"
|
||||
exe ufw allow in on eth0 to any port 9117 proto tcp comment "Jackett. Rules for Sonarr und Radarr in /etc/ufw/rules.before"
|
||||
|
||||
outColor red
|
||||
echo
|
||||
echo "[W] Add the following lines before \"# drop INVALID packets\""
|
||||
echo " [/etc/ufw/before.rules]"
|
||||
echo
|
||||
outColor green
|
||||
echo "# Allow all packages to sonarr and radarr"
|
||||
echo "# ufw thinks that nzb360 sends messages after socket is closed"
|
||||
echo "-A ufw-before-input -i eth0 -p tcp --dport 7878 -j ACCEPT"
|
||||
echo "-A ufw-before-input -i eth0 -p tcp --dport 8989 -j ACCEPT"
|
||||
echo "-A ufw-before-output -o eth0 -p tcp --sport 7878 -j ACCEPT"
|
||||
echo "-A ufw-before-output -o eth0 -p tcp --sport 8989 -j ACCEPT"
|
||||
echo
|
||||
}
|
||||
|
||||
step_16_info() {
|
||||
echo "Build and install unrar-nonfree"
|
||||
echoinfo "Please provide a deb-src sources entry first"
|
||||
echoinfo "[/etc/apt/sources.list]"
|
||||
}
|
||||
step_16() {
|
||||
local buildPath="/tmp/unrarbuild"
|
||||
|
||||
cat /etc/apt/sources.list | grep -E "^deb-src" >>/dev/null 2>&1
|
||||
endReturn -o $? "No deb-src entry found in /etc/apt/sources.list"
|
||||
|
||||
exe mkdir -p "$buildPath"
|
||||
exe cd "$buildPath"
|
||||
exe apt build-dep unrar-nonfree $APTOPT
|
||||
exe apt source -b unrar-nonfree $APTOPT
|
||||
endReturn -o $? "unrar-nonfree build failed ($buildPath left untouched)"
|
||||
exe dpkg -i unrar*.deb
|
||||
endReturn -o $? "unrar-nonfree install failed ($buildPath left untouched)"
|
||||
|
||||
exe rm -rf "$buildPath"
|
||||
}
|
||||
|
||||
step_17_info() { echo "Install danted socks proxy"; }
|
||||
step_17_alias() { ALIAS="danted"; }
|
||||
step_17() {
|
||||
systemctl status danted.service >>/dev/null 2>&1
|
||||
if [ $? -eq 0 ]; then
|
||||
echoseq " [I] Danted already installed"
|
||||
return 0
|
||||
fi
|
||||
exe apt update
|
||||
exe apt install dante-server $APTOPT
|
||||
exe systemctl stop danted.service
|
||||
exe systemctl disable danted.service
|
||||
}
|
||||
|
||||
step_18_info() { echo "Danted installation notes"; }
|
||||
step_18() {
|
||||
cat <<DANTED_EOF
|
||||
[I] Debian fix systemd startup
|
||||
systemctl edit --full danted.service
|
||||
|
||||
# Change /lib64 to -/lib64
|
||||
ReadOnlyDirectories=/bin /etc /lib -/lib64 /sbin /usr /var
|
||||
|
||||
[I] Basic danted settings
|
||||
* Restrict to local network
|
||||
* Separate logfile
|
||||
[/etc/danted.conf]
|
||||
logoutput: stderr /var/log/dante.log
|
||||
internal: eth0 port = 1080
|
||||
external: tun0
|
||||
socksmethod: none
|
||||
clientmethod: none
|
||||
client pass {
|
||||
from: 192.168.0.0/24 port 1-65535 to: 0.0.0.0/0
|
||||
log: error
|
||||
}
|
||||
client block {
|
||||
from: 0.0.0.0/0 to: 0.0.0.0/0
|
||||
log: error
|
||||
}
|
||||
socks block {
|
||||
from: 0.0.0.0/0 to: 127.0.0.0/4
|
||||
log: error
|
||||
}
|
||||
socks pass {
|
||||
from: 192.168.23.0/24 to: 0.0.0.0/0
|
||||
protocol: tcp udp
|
||||
log: error
|
||||
}
|
||||
socks block {
|
||||
from: 0.0.0.0/0 to: 0.0.0.0/0
|
||||
log: connect error
|
||||
}
|
||||
|
||||
DANTED_EOF
|
||||
}
|
||||
|
||||
step_19_info() { echo "Disable apt-daily activities"; }
|
||||
step_19_alias() { ALIAS="aptdaily"; }
|
||||
step_19() {
|
||||
exe /usr/bin/systemctl stop apt-daily-upgrade.timer
|
||||
exe /usr/bin/systemctl stop apt-daily.timer
|
||||
exe /usr/bin/systemctl disable apt-daily-upgrade.timer
|
||||
exe /usr/bin/systemctl disable apt-daily.timer
|
||||
exe /usr/bin/systemctl mask apt-daily.service
|
||||
exe /usr/bin/systemctl daemon-reload
|
||||
}
|
||||
|
||||
step_21_info() {
|
||||
local pInstallDir="${DLD_DIR}/prowlarr"
|
||||
case $CONTEXT_HELP in
|
||||
0)
|
||||
if [ -e "$pInstallDir" ]; then
|
||||
echo -n "Upgrade "
|
||||
else
|
||||
echo -n "Install "
|
||||
fi
|
||||
;;
|
||||
*)
|
||||
echo -n "Install/Update ";;
|
||||
esac
|
||||
echo "prowlarr for arm64"
|
||||
echoinfo "Default port: 9696"
|
||||
}
|
||||
step_21_alias() { ALIAS="prowlarr"; }
|
||||
step_21() {
|
||||
# local pDownDir="/tmp"
|
||||
local pInstallDir="${DLD_DIR}/prowlarr"
|
||||
local pUrl="http://prowlarr.servarr.com/v1/update/develop/updatefile?os=linux&runtime=netcore&arch=arm64"
|
||||
|
||||
[ ! -e "$pTar" ] && exe wget --content-disposition "$pUrl" -O "$pTar"
|
||||
|
||||
if [ -e "$pInstallDir" ]; then
|
||||
prowlarrUpgrade=1
|
||||
echoseq " [I] Stopping prowlarr service"
|
||||
echoseq " Service will not be started automatically after update"
|
||||
exe service prowlarr stop
|
||||
echoseq " [I] Moving existing $pInstallDir as backup"
|
||||
exe mv "$pInstallDir" "${pInstallDir}_bu_"`date +%Y%m%d-%H%M%S`
|
||||
fi
|
||||
|
||||
exe tar xvzf "$pTar" -C "${DLD_DIR}"
|
||||
exe mv "${DLD_DIR}/Prowlarr" "${DLD_DIR}/prowlarr"
|
||||
exe chown -R ${DLD_USER}:${DLD_USER} "${DLD_DIR}/prowlarr"
|
||||
}
|
||||
pTar="/tmp/Prowlarr.tgz"
|
||||
prowlarrUpgrade=0
|
||||
|
||||
step_22_info() { echo "Clean prowlarr download"; }
|
||||
step_22_alias() { ALIAS="prowlarrclean"; }
|
||||
step_22() {
|
||||
exe rm -rf "$pTar"
|
||||
if [ $prowlarrUpgrade -ne 0 ]; then
|
||||
echoseq " [I] Stopping sequence here."
|
||||
echoseq " Following steps only exected for fresh installation."
|
||||
exit 0
|
||||
fi
|
||||
}
|
||||
|
||||
step_23_info() { echo "Create prowlarr service"; }
|
||||
step_23() {
|
||||
local prowlarrServiceLoc="/etc/systemd/system/prowlarr.service"
|
||||
local lService=`eval "echo \"$prowlarrService\""`
|
||||
addConf -s "$lService" "$prowlarrServiceLoc"
|
||||
exe systemctl daemon-reload
|
||||
}
|
||||
prowlarrService="[Unit]
|
||||
Description=Prowlarr Daemon
|
||||
After=syslog.target network.target
|
||||
|
||||
[Service]
|
||||
User=\$DLD_USER
|
||||
Group=\$DLD_USER
|
||||
Type=simple
|
||||
SyslogIdentifier=prowlarr
|
||||
Restart=on-failure
|
||||
RestartSec=5
|
||||
WorkingDirectory=\${DLD_DIR}/prowlarr
|
||||
ExecStart=/bin/sh \${DLD_DIR}/prowlarr/Prowlarr -nobrowser -data=\${DLD_CONFDIR}/prowlarr
|
||||
TimeoutStopSec=30
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
Alias=prowlarr.service"
|
||||
|
||||
step_24_info() { echo "Create ufw rule for prowlarr"; }
|
||||
step_24() {
|
||||
exe ufw allow in on eth0 to any port 9696 proto tcp comment "Prowlarr"
|
||||
}
|
||||
|
||||
step_30_info() {
|
||||
local pInstallDir="${DLD_DIR}/readarr"
|
||||
case $CONTEXT_HELP in
|
||||
0)
|
||||
if [ -e "$pInstallDir" ]; then
|
||||
echo -n "Upgrade "
|
||||
else
|
||||
echo -n "Install "
|
||||
fi
|
||||
;;
|
||||
*)
|
||||
echo -n "Install/Update ";;
|
||||
esac
|
||||
echo "readarr for arm64"
|
||||
echoinfo "Default port: 8787"
|
||||
}
|
||||
step_30_alias() { ALIAS="readarr"; }
|
||||
step_30() {
|
||||
# local pDownDir="/tmp"
|
||||
local lInstallDir="${DLD_DIR}/readarr"
|
||||
local lUrl="http://readarr.servarr.com/v1/update/nightly/updatefile?os=linux&runtime=netcore&arch=arm64"
|
||||
|
||||
[ ! -e "$readarrTar" ] && exe wget --content-disposition "$lUrl" -O "$readarrTar"
|
||||
|
||||
if [ -e "$lInstallDir" ]; then
|
||||
readarrUpgrade=1
|
||||
echoseq " [I] Stopping readarr service"
|
||||
echoseq " Service will not be started automatically after update"
|
||||
exe service readarr stop
|
||||
echoseq " [I] Moving existing $lInstallDir as backup"
|
||||
exe mv "$lInstallDir" "${lInstallDir}_bu_"`date +%Y%m%d-%H%M%S`
|
||||
fi
|
||||
|
||||
exe tar xvf "$readarrTar" -C "${DLD_DIR}"
|
||||
exe mv "${DLD_DIR}/Readarr" "${lInstallDir}"
|
||||
exe chown -R ${DLD_USER}:${DLD_USER} "${lInstallDir}"
|
||||
}
|
||||
readarrTar="/tmp/Readarr.tar.gz"
|
||||
readarrUpgrade=0
|
||||
|
||||
step_31_info() { echo "Clean readarr download"; }
|
||||
step_31_alias() { ALIAS="readarrclean"; }
|
||||
step_31() {
|
||||
exe rm -rf "$readarrTar"
|
||||
if [ $readarrUpgrade -ne 0 ]; then
|
||||
echoseq " [I] Stopping sequence here."
|
||||
echoseq " Following steps only exected for fresh installation."
|
||||
exit 0
|
||||
fi
|
||||
}
|
||||
|
||||
step_32_info() { echo "Create readarr service"; }
|
||||
step_32() {
|
||||
local readarrServiceLoc="/etc/systemd/system/readarr.service"
|
||||
local lService=`eval "echo \"$readarrService\""`
|
||||
addConf -s "$lService" "$readarrServiceLoc"
|
||||
exe systemctl daemon-reload
|
||||
}
|
||||
readarrService="[Unit]
|
||||
Description=Readarr Daemon
|
||||
After=syslog.target network.target
|
||||
|
||||
[Service]
|
||||
User=\$DLD_USER
|
||||
Group=\$DLD_USER
|
||||
Type=simple
|
||||
SyslogIdentifier=readarr
|
||||
RestartSec=5
|
||||
WorkingDirectory=\${DLD_DIR}/readarr
|
||||
ExecStart=\${DLD_DIR}/readarr/Readarr -nobrowser -data=\${DLD_CONFDIR}/readarr
|
||||
TimeoutStopSec=20
|
||||
KillMode=process
|
||||
Restart=on-failure
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
Alias=readarr.service"
|
||||
|
||||
step_33_info() { echo "Create ufw rule for readarr"; }
|
||||
step_33() {
|
||||
exe ufw allow in on eth0 to any port 8787 proto tcp comment "Readarr"
|
||||
}
|
||||
|
||||
step_50_info() { echo "Upgrade bazarr"; }
|
||||
step_50_alias() { ALIAS="upgradebazarr"; }
|
||||
step_50() {
|
||||
local bazarrServiceLoc="/etc/systemd/system/bazarr.service"
|
||||
local lService=`eval "echo \"$bazarrService\""`
|
||||
local bazarrVenv="${DLD_DIR}/bazarr"
|
||||
local bazarrDir="${bazarrVenv}/bazarr"
|
||||
|
||||
local bazarrGitUrl="https://github.com/morpheus65535/bazarr.git"
|
||||
|
||||
exe sudo -u $DLD_USER ${bazarrVenv}/bin/pip install --upgrade pip
|
||||
exe sudo -u $DLD_USER ${bazarrVenv}/bin/pip install -r ${bazarrDir}/requirements.txt
|
||||
}
|
||||
|
||||
checkVpn() {
|
||||
ip -br a | grep tun >>/dev/null 2>&1
|
||||
[ $? -eq 0 ] && echoseq " [W] A VPN connection is possibly active. Consider deactivating it befor any apt operation."
|
||||
}
|
||||
|
||||
VERSION_SEQREV=13
|
||||
. /usr/local/bin/sequencer.sh
|
85
seqs/ebackup.cfg.example
Normal file
85
seqs/ebackup.cfg.example
Normal file
@@ -0,0 +1,85 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Passphrase for symmetrical(default) or asymmetrical encryption
|
||||
EBU_PASSPHRASE=
|
||||
|
||||
# scheme://[user[:password]@]host[:port]/[/]path
|
||||
# e.g.
|
||||
# file://[relative|/absolute]/local/path
|
||||
# scp://user[:password]@other.host[:port]/[relative|/absolute]_path
|
||||
# webdav[s]://user[:password]@other.host[:port]/some_dir
|
||||
# alternatively try lftp+webdav[s]://
|
||||
EBU_TARGET_USER=
|
||||
EBU_TARGET_PASS=
|
||||
EBU_TARGET=
|
||||
|
||||
# base directory to backup
|
||||
EBU_SOURCE=
|
||||
|
||||
# Change the volume size to number MB. Default is 200MB.
|
||||
#EBU_VOLSIZE=
|
||||
|
||||
# a command that runs duplicity e.g.
|
||||
# shape bandwidth use via trickle
|
||||
# "trickle -s -u 640 -d 5120" # 5Mb up, 40Mb down"
|
||||
#EBU_PRECMD=""
|
||||
|
||||
# How often the backup job should be run
|
||||
# Default is to run every day at 02:01 am
|
||||
# (see man 5 crontab for syntax help)
|
||||
# .---------------- minute (0 - 59)
|
||||
# | .------------- hour (0 - 23)
|
||||
# | | .---------- day of month (1 - 31)
|
||||
# | | | .------- month (1 - 12) OR jan,feb,mar,apr ...
|
||||
# | | | | .---- day of week (0 - 6) (Sunday=0 or 7) OR sun,mon,tue,wed,thu,fri,sat
|
||||
# | | | | |
|
||||
# m h dom mon dow usercommand
|
||||
#EBU_CRONTIME='1 2 * * *'
|
||||
|
||||
# Uncomment to save the output of the cron run to a logfile
|
||||
# log file name will be "encBackup_profilename.log"
|
||||
#EBU_LOG_DIR='/var/log'
|
||||
|
||||
# Uncomment to log a message to syslog after
|
||||
# * backup run
|
||||
# * cron file update
|
||||
#EBU_SYSLOG=true
|
||||
|
||||
#
|
||||
## Age options
|
||||
|
||||
# activates duplicity --full-if-older-than option (since duplicity v0.4.4.RC3)
|
||||
# forces a full backup if last full backup reaches a specified age
|
||||
# (see duplicity man page, chapter TIME_FORMATS)
|
||||
#EBU_MAX_FULLBKP_AGE=1M
|
||||
|
||||
#
|
||||
## Purge options
|
||||
|
||||
# Time frame for old backups to keep "remove-older-than"
|
||||
# (see duplicity man page, chapter TIME_FORMATS)
|
||||
#EBU_MAX_AGE=3M
|
||||
|
||||
# Number of full backups to keep.
|
||||
# (see duplicity man page, action "remove-all-but-n-full")
|
||||
#EBU_MAX_FULL_BACKUPS=1
|
||||
|
||||
# Number of full backups for which incrementals will be kept for.
|
||||
# (see duplicity man page, action "remove-all-inc-of-but-n-full")
|
||||
#EBU_MAX_FULLS_WITH_INCRS=1
|
||||
|
||||
#
|
||||
## Exclusion options
|
||||
|
||||
# Standard excludes when backing up a full system
|
||||
EBU_EXCLUDES=(\
|
||||
"/backup*"\
|
||||
"/dev/*"\
|
||||
"/proc/*"\
|
||||
"/sys/*"\
|
||||
"/tmp/*"\
|
||||
"/run/*"\
|
||||
"/mnt/*"\
|
||||
"/media/*"\
|
||||
"/lost+found"\
|
||||
)
|
330
seqs/ebackup.sh
Executable file
330
seqs/ebackup.sh
Executable file
@@ -0,0 +1,330 @@
|
||||
#!/bin/bash
|
||||
|
||||
toolName=duplicity
|
||||
toolBin=
|
||||
toolPpa="ppa:duplicity-team/duplicity-release-git"
|
||||
toolCronDir="/etc/cron.d"
|
||||
toolPrefix="encBackup_"
|
||||
toolSyslogTag=
|
||||
|
||||
# Get script working directory
|
||||
# (when called from a different directory)
|
||||
WDIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" >>/dev/null 2>&1 && pwd )"
|
||||
CONFIG=0
|
||||
SCRIPT_NAME=$(basename -- $0)
|
||||
SCRIPT_NAME=${SCRIPT_NAME%%.*}
|
||||
CONFIG_FILE_TEMPLATE="$WDIR/${SCRIPT_NAME}.cfg.example"
|
||||
|
||||
step_config() {
|
||||
initSeqConfig -p "$SCRIPT_NAME" "$CONFIG_FILE_TEMPLATE"
|
||||
if [ $? -eq 0 ] ; then
|
||||
CONFIG=1
|
||||
else
|
||||
[ $DRY -eq 0 ] && return 1
|
||||
fi
|
||||
toolSyslogTag="${SCRIPT_NAME}-$SEQ_PROFILE_NAME"
|
||||
}
|
||||
|
||||
step_1_info() {
|
||||
echo -n "Backup "
|
||||
if [ $CONTEXT_HELP -ne 0 ] ; then
|
||||
echo -n "selected profile"
|
||||
else
|
||||
echo -n "profile: $SEQ_PROFILE_NAME"
|
||||
fi
|
||||
echo " [OPTIONS] [full|incremental]"
|
||||
echoinfo " [OPTIONS]"
|
||||
echoinfo " --no-purge, -n : Do not purge old backups after backup"
|
||||
}
|
||||
step_1_alias() { ALIAS="backup"; }
|
||||
step_1() {
|
||||
shift
|
||||
|
||||
local arg
|
||||
local retVal
|
||||
local dupArgs
|
||||
local purgeAfter=1
|
||||
|
||||
for arg in "$@" ; do
|
||||
case "$1" in
|
||||
--no-purge|-n)
|
||||
purgeAfter=0
|
||||
shift
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
if [ -z $EBU_TARGET ] || [ -z $EBU_SOURCE ] ; then
|
||||
echo " [I] Nothing to do. Check $SEQ_CONFIG_FILE"
|
||||
return 1
|
||||
fi
|
||||
|
||||
if [ ! -z "$1" ] && ( [ "$1" == "full" ] || [ "$1" == "incremental" ] ) ; then
|
||||
dupArgs+=("$1")
|
||||
elif [ ! -z "$1" ] ; then
|
||||
echo " [W] $toolName command \"$1\" not recognized"
|
||||
return 1
|
||||
fi
|
||||
|
||||
echo " [I] Running backup profile [$SEQ_PROFILE_NAME]"
|
||||
|
||||
if [ "${dupArgs[0]}" != "full" ] && [ ! -z "$EBU_MAX_FULLBKP_AGE" ] ; then
|
||||
dupArgs+=(--full-if-older-than "$EBU_MAX_FULLBKP_AGE")
|
||||
fi
|
||||
if [ ! -z "$EBU_VOLSIZE" ] ; then
|
||||
dupArgs+=(--volsize "$EBU_VOLSIZE")
|
||||
fi
|
||||
|
||||
checkInstalled
|
||||
setPassphrase
|
||||
exe $toolBin "${dupArgs[@]}" "$EBU_SOURCE" "$EBU_TARGET"
|
||||
retVal=$?
|
||||
unsetPassphrase
|
||||
|
||||
syslogEntry "Backup complete [$retVal]"
|
||||
|
||||
if [ $purgeAfter -ne 0 ] ; then
|
||||
step purge
|
||||
fi
|
||||
}
|
||||
|
||||
step_3_info() { echo "Verify selected backup"; }
|
||||
step_3_alias() { ALIAS="verify"; }
|
||||
step_3() {
|
||||
shift
|
||||
|
||||
if [ -z $EBU_TARGET ] || [ -z $EBU_SOURCE ] ; then
|
||||
echo " [I] Nothing to do. Check $SEQ_CONFIG_FILE"
|
||||
return 1
|
||||
fi
|
||||
|
||||
checkInstalled
|
||||
setPassphrase
|
||||
exe $toolBin verify "$EBU_TARGET" "$EBU_SOURCE"
|
||||
unsetPassphrase
|
||||
}
|
||||
|
||||
step_5_info() {
|
||||
echo "Restore [OPTIONS] <LOCAL TARGET> [TARGET]"
|
||||
echoinfo " [OPTIONS]"
|
||||
echoinfo " --file-to-restore, -f <RELPATH> : Relative path within backup"
|
||||
echoinfo " (file or folder)"
|
||||
echoinfo " --time, -t <TIME> : Age of file to be restored"
|
||||
}
|
||||
step_5_alias() { ALIAS="restore"; }
|
||||
step_5() {
|
||||
shift
|
||||
|
||||
local arg
|
||||
local restoreOpt
|
||||
|
||||
for arg in "$@" ; do
|
||||
case "$1" in
|
||||
--file-to-restore|-f)
|
||||
shift
|
||||
restoreOpt+=(--file-to-restore "$1")
|
||||
shift
|
||||
;;
|
||||
--time|-t)
|
||||
shift
|
||||
restoreOpt=(-t "$1")
|
||||
shift
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
if [ -z "$1" ] ; then
|
||||
echoerr " [E] No target provided"
|
||||
return 1
|
||||
fi
|
||||
local ebuLocalTarget="$1"
|
||||
local ebuTarget="$EBU_TARGET"
|
||||
if [ ! -z "$2" ] ; then
|
||||
ebuTarget="$2"
|
||||
fi
|
||||
|
||||
checkInstalled
|
||||
setPassphrase
|
||||
exe $toolBin restore "${restoreOpt[@]}" "$EBU_TARGET" "$ebuLocalTarget"
|
||||
unsetPassphrase
|
||||
}
|
||||
|
||||
step_7_info() { echo "Purge old backups [TARGET]"; }
|
||||
step_7_alias() { ALIAS="purge"; }
|
||||
step_7() {
|
||||
shift
|
||||
local ebuTarget="$EBU_TARGET"
|
||||
local dupCommand=
|
||||
if [ ! -z "$1" ] ; then
|
||||
ebuTarget="$1"
|
||||
fi
|
||||
|
||||
if [ ! -z "$EBU_MAX_AGE" ] ; then
|
||||
dupCommand+="remove-older-than $EBU_MAX_AGE "
|
||||
elif [ ! -z "$EBU_MAX_FULL_BACKUPS" ] ; then
|
||||
dupCommand+="remove-all-but-n-full $EBU_MAX_FULL_BACKUPS "
|
||||
elif [ ! -z "$EBU_MAX_FULLS_WITH_INCRS" ] ; then
|
||||
dupCommand+="remove-all-inc-of-but-n-full $EBU_MAX_FULLS_WITH_INCRS "
|
||||
else
|
||||
if [ $QUIET -eq 0 ] ; then echoerr " [W] No purge option configured" ; fi
|
||||
return 1
|
||||
fi
|
||||
|
||||
checkInstalled
|
||||
setPassphrase
|
||||
exe $toolBin $dupCommand --force "$ebuTarget"
|
||||
unsetPassphrase
|
||||
}
|
||||
|
||||
step_20_info() {
|
||||
shift
|
||||
local ebuTarget=$EBU_TARGET
|
||||
[ ! -z "$1" ] && ebuTarget="$1"
|
||||
if [ $CONTEXT_HELP -ne 0 ]; then
|
||||
echo "Status of (profile) [TARGET]"
|
||||
elif [ ! -z "$1" ]; then
|
||||
echo "Status of target: $ebuTarget"
|
||||
else
|
||||
echo "Status of profile \"$SEQ_PROFILE_NAME\" target: $ebuTarget"
|
||||
fi
|
||||
}
|
||||
step_20_alias() { ALIAS='status'; }
|
||||
step_20() {
|
||||
shift
|
||||
local ebuTarget="$EBU_TARGET"
|
||||
if [ ! -z "$1" ] ; then
|
||||
ebuTarget="$1"
|
||||
fi
|
||||
|
||||
checkInstalled
|
||||
exe $toolBin collection-status "$ebuTarget"
|
||||
}
|
||||
|
||||
step_22_info() { echo "List backup files [TARGET]"; }
|
||||
step_22_alias() { ALIAS='list'; }
|
||||
step_22() {
|
||||
shift
|
||||
local ebuTarget="$EBU_TARGET"
|
||||
if [ ! -z "$1" ] ; then
|
||||
ebuTarget="$1"
|
||||
fi
|
||||
|
||||
checkInstalled
|
||||
exe $toolBin list-current-files "$ebuTarget"
|
||||
}
|
||||
|
||||
|
||||
step_70_info() {
|
||||
echo -n "Manage cron file for "
|
||||
if [ $CONTEXT_HELP -ne 0 ] ; then
|
||||
echo -n "selected profile"
|
||||
else
|
||||
echo -n "profile: $SEQ_PROFILE_NAME"
|
||||
fi
|
||||
echo " [OPTIONS]"
|
||||
echoinfo " [OPTIONS]"
|
||||
echoinfo " --remove, -r : remove cron file"
|
||||
}
|
||||
step_70_alias() { ALIAS='cron'; }
|
||||
step_70() {
|
||||
shift
|
||||
local arg
|
||||
local cronRemove=0
|
||||
local cronScript="$toolCronDir/${toolPrefix}$SEQ_PROFILE_NAME"
|
||||
local cronLog='>/dev/null'
|
||||
local cronEntry="$EBU_CRONTIME $(whoami) $WDIR/$(basename -- $0) -qq -p $SEQ_PROFILE_NAME"
|
||||
|
||||
for arg in "$@" ; do
|
||||
case "$1" in
|
||||
--remove|-r)
|
||||
cronRemove=1
|
||||
shift
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
if [ ! -z "$EBU_LOG_DIR" ] ; then
|
||||
cronLog="$EBU_LOG_DIR/${toolPrefix}${SEQ_PROFILE_NAME}.log"
|
||||
exe touch "$cronLog"
|
||||
exe chmod 600 "$cronLog"
|
||||
fi
|
||||
|
||||
cronEntry+=" >$cronLog"
|
||||
|
||||
if [ -z "$EBU_CRONTIME" ] || [ $cronRemove -ne 0 ] ; then
|
||||
echo " [I] Removing cron for profile $SEQ_PROFILE_NAME"
|
||||
exe rm -r "$cronScript"
|
||||
else
|
||||
checkFileHead "$cronScript" "$cronEntry"
|
||||
if [ $? -ne 0 ] ; then
|
||||
echo " [I] Update cron for profile $SEQ_PROFILE_NAME"
|
||||
exep "sudo echo \"$cronEntry\" > \"$cronScript\""
|
||||
syslogEntry "Cron file update complete [$EBU_CRONTIME]"
|
||||
else
|
||||
echo " [I] Cron for profile $SEQ_PROFILE_NAME is up to date"
|
||||
fi
|
||||
fi
|
||||
}
|
||||
|
||||
step_72_info() { echo "Update all profile cron files"; }
|
||||
step_72_alias() { ALIAS="reload"; }
|
||||
step_72() {
|
||||
for seq in "$SEQ_CONFIG_HOME/"* ; do
|
||||
seq=$(basename ${seq})
|
||||
$WDIR/$(basename -- $0) $SEQUENCER_ARGS -qq -p ${seq%%.*} cron
|
||||
done
|
||||
}
|
||||
|
||||
step_100_info() { echo "Install $toolName $toolPpa"; }
|
||||
step_100_alias() { ALIAS="install"; }
|
||||
step_100() {
|
||||
local aptOpt=
|
||||
if [ $QUIET -ne 0 ] ; then
|
||||
aptOpt="-y"
|
||||
fi
|
||||
|
||||
exe add-apt-repository $toolPpa $aptOpt
|
||||
exe apt install $toolName $aptOpt
|
||||
}
|
||||
|
||||
setPassphrase() {
|
||||
if [ -z $PASSPHRASE ] && [ ! -z $EBU_PASSPHRASE ] ; then
|
||||
export PASSPHRASE="$EBU_PASSPHRASE"
|
||||
fi
|
||||
}
|
||||
|
||||
unsetPassphrase() {
|
||||
unset PASSPHRASE
|
||||
}
|
||||
|
||||
checkFileHead() {
|
||||
local readChar
|
||||
if [ ! -e "$1" ] ; then
|
||||
echoerr " [E] File $1 not found"
|
||||
return 1
|
||||
fi
|
||||
read -r -n ${#2} readChar < "$1"
|
||||
if [ "$readChar" == "$2" ] ; then
|
||||
return 0
|
||||
fi
|
||||
return 1
|
||||
}
|
||||
|
||||
syslogEntry() {
|
||||
if [ "$EBU_SYSLOG" == "true" ] ; then
|
||||
exe logger -t $toolSyslogTag "$@"
|
||||
fi
|
||||
}
|
||||
|
||||
checkInstalled() {
|
||||
if [ -z "$toolBin" ] ; then
|
||||
command -v $toolName >>/dev/null
|
||||
if [ $? -ne 0 ] ; then
|
||||
step install
|
||||
fi
|
||||
toolBin="$EBU_PRECMD $(command -v $toolName)"
|
||||
fi
|
||||
}
|
||||
|
||||
VERSION_SEQREV=12
|
||||
. /usr/local/bin/sequencer.sh
|
147
seqs/ejabberd.sh
Executable file
147
seqs/ejabberd.sh
Executable file
@@ -0,0 +1,147 @@
|
||||
#!/bin/bash
|
||||
|
||||
toolName=ejabberd
|
||||
toolConfLoc="/etc/ejabberd/ejabberd.yml"
|
||||
toolAdminConf="/etc/ejabberd/ejabberdctl.cfg"
|
||||
# for http upload
|
||||
toolStorageLoc="/var/ejabberd"
|
||||
certRoot="/etc/letsencrypt"
|
||||
|
||||
# needed for different steps
|
||||
myDomain=
|
||||
myUser=
|
||||
myPass=
|
||||
|
||||
step_1_info() { echo "Install $toolName via apt"; }
|
||||
step_1_alias() { ALIAS="install"; }
|
||||
step_1() {
|
||||
exe apt update
|
||||
exe apt install -y $toolName
|
||||
exe systemctl stop $toolName
|
||||
}
|
||||
|
||||
step_2_info() { echo "Use certificate from local letsencrypt"; }
|
||||
step_2() {
|
||||
readDomain
|
||||
|
||||
local certLoc="${certRoot}/live/${myDomain}/full.pem"
|
||||
if [ ! -f "$certLoc" ] ; then
|
||||
echo "[ERROR] $certLoc not found"
|
||||
return 1;
|
||||
fi
|
||||
|
||||
local toolCertLoc="/etc/ejabberd/ejabberd.pem"
|
||||
if [ -f "${toolCertLoc}.bck" ] ; then
|
||||
echo "[ERROR] Cannot backup original $toolName certificate"
|
||||
return 1;
|
||||
fi
|
||||
|
||||
exe mv "$toolCertLoc" "${toolCertLoc}.bck"
|
||||
exe ln -s "$certLoc" "$toolCertLoc"
|
||||
# read access for ejabberd to read certificate
|
||||
exe chown root:ejabberd "$certRoot"
|
||||
exe chmod 750 "$certRoot"
|
||||
}
|
||||
|
||||
step_3_info() { echo "Create basic configuration"; }
|
||||
step_3() {
|
||||
if [ ! -f $SEQDIR/ejabberd.yml ] ; then
|
||||
addConf -m "$MissingConfEntry" "$toolConfLoc"
|
||||
else
|
||||
readDomain
|
||||
echo -e "\nThis user will be the admin:"
|
||||
readUser
|
||||
addConf -c "$(cat $SEQDIR/ejabberd.yml)" "$toolConfLoc"
|
||||
# modify configuration
|
||||
exe sed -i "s/mydomain\.eu/${myDomain}/" "$toolConfLoc"
|
||||
exe sed -i "s/myuser/${myUser}/" "$toolConfLoc"
|
||||
# create storage for http upload
|
||||
exe mkdir -p "$toolStorageLoc"
|
||||
exe chown root:$toolName "$toolStorageLoc"
|
||||
exe chmod 770 "$toolStorageLoc"
|
||||
fi
|
||||
# Erlang-VM to listen only on local interface
|
||||
exe sed -i "s/#\(INET_DIST_INTERFACE=127\.0\.0\.1\)/\1/" "$toolAdminConf"
|
||||
}
|
||||
|
||||
MissingConfEntry="Seq's basic configuration file \"$SEQDIR/ejabberd.yml\" missing.
|
||||
Backup $toolConfLoc and create a configuration manually.
|
||||
|
||||
Some essential settings needed:
|
||||
- Domain
|
||||
- Admin User"
|
||||
|
||||
step_4_info() { echo "Restart $toolName"; }
|
||||
step_4_alias() { ALIAS="restart"; }
|
||||
step_4() {
|
||||
exe service ejabberd restart
|
||||
}
|
||||
|
||||
step_5_info() { echo "Create new user"; }
|
||||
step_5_alias() { ALIAS="adduser"; }
|
||||
step_5() {
|
||||
readDomain
|
||||
readUser
|
||||
readUserPass
|
||||
exe ejabberdctl register $myUser $myDomain $myPass
|
||||
}
|
||||
|
||||
step_10_info() { echo "List existing user"; }
|
||||
step_10_alias() { ALIAS="listuser"; }
|
||||
step_10() {
|
||||
readDomain
|
||||
exe ejabberdctl registered_users $myDomain
|
||||
}
|
||||
|
||||
step_12_info() { echo "Change password for existing user"; }
|
||||
step_12_alias() { ALIAS="passwd"; }
|
||||
step_12() {
|
||||
readDomain
|
||||
readUser
|
||||
readUserPass
|
||||
exe ejabberdctl change_password $myUser $myDomain $myPass
|
||||
}
|
||||
|
||||
step_14_info() { echo "Remove registered user"; }
|
||||
step_14_alias() { ALIAS="deluser"; }
|
||||
step_14() {
|
||||
readDomain
|
||||
readUser
|
||||
readUserPass
|
||||
exe ejabberdctl unregister $myUser $myDomain $myPass
|
||||
}
|
||||
|
||||
readDomain() {
|
||||
if [ "$myDomain" == "" ] ; then
|
||||
read -p "Enter your domain: " myDomain
|
||||
endCheckEmpty myDomain "$toolName domain"
|
||||
fi
|
||||
}
|
||||
|
||||
readUser() {
|
||||
echo -e "\nDon't use spaces in user name!"
|
||||
if [ "$myUser" == "" ] ; then
|
||||
read -p "Enter user name: " myUser
|
||||
echo
|
||||
endCheckEmpty myUser "$toolName user name"
|
||||
fi
|
||||
}
|
||||
|
||||
readUserPass() {
|
||||
echo -e "\nDon't use spaces in user password!"
|
||||
if [ "$myPass" == "" ] ; then
|
||||
read -s -p "Enter user password: " myPass
|
||||
echo
|
||||
read -s -p "Enter user password again: " myPass2
|
||||
echo
|
||||
if [ "$myPass" != "$myPass2" ] ; then
|
||||
echo "[ERROR] Passwords don't match"
|
||||
return 1;
|
||||
fi
|
||||
endCheckEmpty myPass "$toolName user password"
|
||||
fi
|
||||
}
|
||||
|
||||
SEQDIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >>/dev/null 2>&1 && pwd )"
|
||||
VERSION_SEQREV=4
|
||||
. sequencer.sh
|
321
seqs/ejabberd.yml
Normal file
321
seqs/ejabberd.yml
Normal file
@@ -0,0 +1,321 @@
|
||||
loglevel: 3
|
||||
hide_sensitive_log_data: true
|
||||
|
||||
log_rotate_size: 0
|
||||
log_rotate_date: ""
|
||||
log_rate_limit: 100
|
||||
|
||||
hosts:
|
||||
- "mydomain.eu"
|
||||
|
||||
listen:
|
||||
-
|
||||
port: 5222
|
||||
ip: "::"
|
||||
module: ejabberd_c2s
|
||||
##
|
||||
## If TLS is compiled in and you installed a SSL
|
||||
## certificate, specify the full path to the
|
||||
## file and uncomment these lines:
|
||||
##
|
||||
certfile: "/etc/ejabberd/ejabberd.pem"
|
||||
## starttls: true
|
||||
##
|
||||
## To enforce TLS encryption for client connections,
|
||||
## use this instead of the "starttls" option:
|
||||
##
|
||||
starttls_required: true
|
||||
##
|
||||
## Custom OpenSSL options
|
||||
##
|
||||
protocol_options:
|
||||
- "no_sslv3"
|
||||
- "no_tlsv1"
|
||||
- "no_tlsv1_1"
|
||||
max_stanza_size: 65536
|
||||
shaper: c2s_shaper
|
||||
access: c2s
|
||||
zlib: true
|
||||
resend_on_timeout: if_offline
|
||||
-
|
||||
port: 5269
|
||||
ip: "::"
|
||||
module: ejabberd_s2s_in
|
||||
-
|
||||
port: 5280
|
||||
ip: "::"
|
||||
module: ejabberd_http
|
||||
request_handlers:
|
||||
"/websocket": ejabberd_http_ws
|
||||
## "/pub/archive": mod_http_fileserver
|
||||
web_admin: true
|
||||
http_bind: true
|
||||
## register: true
|
||||
## captcha: true
|
||||
tls: true
|
||||
certfile: "/etc/ejabberd/ejabberd.pem"
|
||||
-
|
||||
port: 5443
|
||||
module: ejabberd_http
|
||||
tls: true
|
||||
certfile: "/etc/ejabberd/ejabberd.pem"
|
||||
request_handlers:
|
||||
"upload": mod_http_upload
|
||||
custom_headers:
|
||||
"Access-Control-Allow-Origin": "*"
|
||||
"Access-Control-Allow-Methods": "OPTIONS, HEAD, GET, PUT"
|
||||
"Access-Control-Allow-Headers": "Authorization"
|
||||
"Access-Control-Allow-Credentials": "true"
|
||||
|
||||
## Disabling digest-md5 SASL authentication. digest-md5 requires plain-text
|
||||
## password storage (see auth_password_format option).
|
||||
disable_sasl_mechanisms:
|
||||
- "digest-md5"
|
||||
- "x-oauth2"
|
||||
|
||||
s2s_use_starttls: required
|
||||
s2s_certfile: "/etc/ejabberd/ejabberd.pem"
|
||||
s2s_protocol_options:
|
||||
- "no_sslv3"
|
||||
- "no_tlsv1"
|
||||
- "no_tlsv1_1"
|
||||
|
||||
outgoing_s2s_families:
|
||||
- ipv4
|
||||
## - ipv6
|
||||
outgoing_s2s_timeout: 10000
|
||||
|
||||
auth_method: internal
|
||||
auth_password_format: scram
|
||||
|
||||
###. ===============
|
||||
###' DATABASE _SETUP
|
||||
|
||||
### MySQL server:
|
||||
###
|
||||
#sql_type: mysql
|
||||
#sql_server: "localhost"
|
||||
#sql_database: "db_name"
|
||||
#sql_username: "db_user"
|
||||
#sql_password: "db_pass"
|
||||
## Keepalive in seconds
|
||||
#sql_keepalive_interval: 28800
|
||||
#sql_pool_size: 5
|
||||
|
||||
###. ===============
|
||||
###' TRAFFIC SHAPERS
|
||||
shaper:
|
||||
##
|
||||
## The "normal" shaper limits traffic speed to 1000 B/s
|
||||
##
|
||||
normal: 1000
|
||||
|
||||
##
|
||||
## The "fast" shaper limits traffic speed to 50000 B/s
|
||||
##
|
||||
fast: 50000
|
||||
|
||||
max_fsm_queue: 1000
|
||||
|
||||
###. ====================
|
||||
###' ACCESS CONTROL LISTS
|
||||
acl:
|
||||
admin:
|
||||
user:
|
||||
- "myuser": "mydomain.eu"
|
||||
#- "@localhost"
|
||||
|
||||
local:
|
||||
user_regexp: ""
|
||||
|
||||
loopback:
|
||||
ip:
|
||||
- "127.0.0.0/8"
|
||||
|
||||
shaper_rules:
|
||||
## Maximum number of simultaneous sessions allowed for a single user:
|
||||
max_user_sessions: 10
|
||||
## Maximum number of offline messages that users can have:
|
||||
max_user_offline_messages:
|
||||
- 5000: admin
|
||||
- 100
|
||||
## For C2S connections, all users except admins use the "normal" shaper
|
||||
c2s_shaper:
|
||||
- none: admin
|
||||
- normal
|
||||
## All S2S connections use the "fast" shaper
|
||||
s2s_shaper: fast
|
||||
|
||||
###. ============
|
||||
###' ACCESS RULES
|
||||
access_rules:
|
||||
## This rule allows access only for local users:
|
||||
local:
|
||||
- allow: local
|
||||
## Only non-blocked users can use c2s connections:
|
||||
c2s:
|
||||
- deny: blocked
|
||||
- allow
|
||||
## Only admins can send announcement messages:
|
||||
announce:
|
||||
- allow: admin
|
||||
## Only admins can use the configuration interface:
|
||||
configure:
|
||||
- allow: admin
|
||||
## Only accounts of the local ejabberd server can create rooms:
|
||||
muc_create:
|
||||
- allow: local
|
||||
## Only accounts on the local ejabberd server can create Pubsub nodes:
|
||||
pubsub_createnode:
|
||||
- allow: local
|
||||
## In-band registration allows registration of any possible username.
|
||||
## To disable in-band registration, replace 'allow' with 'deny'.
|
||||
register:
|
||||
- deny
|
||||
## Only allow to register from localhost
|
||||
trusted_network:
|
||||
- allow: loopback
|
||||
## Do not establish S2S connections with bad servers
|
||||
s2s:
|
||||
## - deny:
|
||||
## - ip: "XXX.XXX.XXX.XXX/32"
|
||||
## - deny:
|
||||
## - ip: "XXX.XXX.XXX.XXX/32"
|
||||
- allow
|
||||
|
||||
language: "en"
|
||||
|
||||
modules:
|
||||
mod_adhoc: {}
|
||||
mod_admin_extra: {}
|
||||
mod_announce: # recommends mod_adhoc
|
||||
access: announce
|
||||
mod_blocking: {} # requires mod_privacy
|
||||
mod_caps: {}
|
||||
mod_carboncopy: {}
|
||||
mod_client_state: {}
|
||||
mod_configure: {} # requires mod_adhoc
|
||||
##mod_delegation: {} # for xep0356
|
||||
mod_disco:
|
||||
server_info:
|
||||
-
|
||||
modules: all
|
||||
name: "abuse-addresses"
|
||||
urls:
|
||||
- "mailto:jabberadmin@mydomain.eu"
|
||||
mod_echo: {}
|
||||
mod_irc: {}
|
||||
mod_http_bind: {}
|
||||
mod_http_upload:
|
||||
docroot: "/var/ejabberd"
|
||||
put_url: "https://@HOST@:5443/upload"
|
||||
thumbnail: true
|
||||
dir_mode: "2770"
|
||||
max_size: 104857600 # 100MB
|
||||
## mod_http_fileserver:
|
||||
## docroot: "/var/www"
|
||||
## accesslog: "/var/log/ejabberd/access.log"
|
||||
mod_last: {}
|
||||
mod_muc:
|
||||
## host: "conference.@HOST@"
|
||||
access:
|
||||
- allow
|
||||
access_admin:
|
||||
- allow: admin
|
||||
access_create: muc_create
|
||||
access_persistent: muc_create
|
||||
## mod_muc_log: {}
|
||||
mod_muc_admin: {}
|
||||
## mod_multicast: {}
|
||||
mod_offline:
|
||||
access_max_user_messages: max_user_offline_messages
|
||||
mod_ping: {}
|
||||
## mod_pres_counter:
|
||||
## count: 5
|
||||
## interval: 60
|
||||
mod_privacy: {}
|
||||
mod_private: {}
|
||||
## mod_proxy65: {}
|
||||
mod_pubsub:
|
||||
access_createnode: pubsub_createnode
|
||||
## reduces resource comsumption, but XEP incompliant
|
||||
#ignore_pep_from_offline: true
|
||||
## XEP compliant, but increases resource comsumption
|
||||
ignore_pep_from_offline: false
|
||||
last_item_cache: false
|
||||
max_items_node: 1000
|
||||
default_node_config:
|
||||
max_items: 1000
|
||||
plugins:
|
||||
- "flat"
|
||||
- "hometree"
|
||||
- "pep" # pep requires mod_caps
|
||||
mod_register:
|
||||
##
|
||||
## Protect In-Band account registrations with CAPTCHA.
|
||||
##
|
||||
## captcha_protected: true
|
||||
##
|
||||
## Set the minimum informational entropy for passwords.
|
||||
##
|
||||
## password_strength: 32
|
||||
##
|
||||
## After successful registration, the user receives
|
||||
## a message with this subject and body.
|
||||
##
|
||||
## welcome_message:
|
||||
## subject: "Welcome!"
|
||||
## body: |-
|
||||
## Hi.
|
||||
## Welcome to this XMPP server.
|
||||
##
|
||||
## When a user registers, send a notification to
|
||||
## these XMPP accounts.
|
||||
##
|
||||
## registration_watchers:
|
||||
## - "admin1@example.org"
|
||||
##
|
||||
## Only clients in the server machine can register accounts
|
||||
##
|
||||
## ip_access: trusted_network
|
||||
##
|
||||
## Local c2s or remote s2s users cannot register accounts
|
||||
##
|
||||
## access_from: deny
|
||||
## access: register
|
||||
|
||||
# No registration, but allow existing accounts to change password
|
||||
access: none
|
||||
mod_roster:
|
||||
versioning: true
|
||||
mod_shared_roster: {}
|
||||
mod_stats: {}
|
||||
mod_time: {}
|
||||
mod_vcard:
|
||||
search: false
|
||||
mod_version:
|
||||
show_os: false
|
||||
|
||||
##
|
||||
## Enable modules with custom options in a specific virtual host
|
||||
##
|
||||
## host_config:
|
||||
## "localhost":
|
||||
## modules:
|
||||
## mod_echo:
|
||||
## host: "mirror.localhost"
|
||||
|
||||
##
|
||||
## Enable modules management via ejabberdctl for installation and
|
||||
## uninstallation of public/private contributed modules
|
||||
## (enabled by default)
|
||||
##
|
||||
|
||||
allow_contrib_modules: true
|
||||
|
||||
###.
|
||||
###'
|
||||
### Local Variables:
|
||||
### mode: yaml
|
||||
### End:
|
||||
### vim: set filetype=yaml tabstop=8 foldmarker=###',###. foldmethod=marker:
|
6
seqs/element-web.cfg.example
Normal file
6
seqs/element-web.cfg.example
Normal file
@@ -0,0 +1,6 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Matrix element web sequence configuration
|
||||
|
||||
ELEMENT_WEB_LOC="/var/www/element"
|
||||
ELEMENT_WEB_BACKUP="/root/backup/element"
|
164
seqs/element-web.sh
Executable file
164
seqs/element-web.sh
Executable file
@@ -0,0 +1,164 @@
|
||||
#!/bin/bash
|
||||
|
||||
toolName=element-web
|
||||
latestUrl="https://api.github.com/repos/vector-im/element-web/releases/latest"
|
||||
|
||||
# Get script working directory
|
||||
# (when called from a different directory)
|
||||
WDIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >>/dev/null 2>&1 && pwd )"
|
||||
CONFIG=0
|
||||
CONFIG_FILE_NAME="${toolName}.cfg"
|
||||
CONFIG_FILE_TEMPLATE="$WDIR/${CONFIG_FILE_NAME}.example"
|
||||
|
||||
step_config() {
|
||||
initSeqConfig "$CONFIG_FILE_NAME" "$CONFIG_FILE_TEMPLATE"
|
||||
if [ $? -eq 0 ] ; then
|
||||
echo " ${toolName} path: ${ELEMENT_WEB_LOC}"
|
||||
echo " ${toolName} backup: ${ELEMENT_WEB_BACKUP}"
|
||||
CONFIG=1
|
||||
fi
|
||||
}
|
||||
|
||||
step_18_info() { echo "Check for updates"; }
|
||||
step_18_alias() { ALIAS="updatecheck"; }
|
||||
step_18() {
|
||||
shift
|
||||
local latestVersion=
|
||||
if [ ! -z $1 ] ; then
|
||||
latestVersion="$1"
|
||||
else
|
||||
latestVersion=$(curl --silent "$latestUrl" | grep -Po '"tag_name": "v\K.*?(?=")')
|
||||
fi
|
||||
|
||||
local isInstalled=$(grep -E "${latestVersion}" "${ELEMENT_WEB_LOC}/version" >>/dev/null && echo "1" || echo "0")
|
||||
if [ $isInstalled -eq 1 ] ; then
|
||||
echo " [I] Version $latestVersion is already installed"
|
||||
return 1
|
||||
else
|
||||
echo " [I] Update to $latestVersion available"
|
||||
fi
|
||||
return 0
|
||||
}
|
||||
|
||||
|
||||
step_20_info() {
|
||||
echo -n "Create a backup [ELEMENT WEB ROOT]"
|
||||
if [ $CONFIG -ne 0 ] ; then
|
||||
echo " at $ELEMENT_WEB_BACKUP"
|
||||
else
|
||||
echo
|
||||
fi
|
||||
}
|
||||
step_20_alias() { ALIAS="backup"; }
|
||||
step_20() {
|
||||
shift
|
||||
local tempRoot=
|
||||
if [ $CONFIG -eq 0 ] ; then
|
||||
echoerr " [E] No configuration file found"
|
||||
return 1
|
||||
fi
|
||||
if [ ! -z $ELEMENT_WEB_BACKUP ] ; then
|
||||
exe mkdir -p "$ELEMENT_WEB_BACKUP"
|
||||
fi
|
||||
if [ ! -z $1 ] ; then
|
||||
tempRoot="$1"
|
||||
else
|
||||
tempRoot="$ELEMENT_WEB_LOC"
|
||||
fi
|
||||
|
||||
local wwwBackup="$ELEMENT_WEB_BACKUP/${toolName}_www_`date +%Y%m%d-%H%M%S`.tar.gz"
|
||||
echo " [I] Backing up webserver directory to $wwwBackup"
|
||||
exe cd "$tempRoot/.."
|
||||
exe tar czf "$wwwBackup" $(basename "$tempRoot")
|
||||
}
|
||||
|
||||
step_22_info() {
|
||||
shift
|
||||
if [ -z $1 ] ; then
|
||||
echo -n "Get latest version from github"
|
||||
if [ $CONTEXT_HELP -eq 0 ] ; then
|
||||
echo ": $(curl --silent "$latestUrl" | grep -Po '"tag_name": "\K.*?(?=")')"
|
||||
else
|
||||
echo " [CUSTOM VERSION]"
|
||||
fi
|
||||
else
|
||||
echo "Get version $1 from github"
|
||||
fi
|
||||
}
|
||||
step_22_alias() { ALIAS="upgrade"; }
|
||||
step_22() {
|
||||
shift # don't need step number
|
||||
local latestVersion=
|
||||
if [ ! -z $1 ] ; then
|
||||
latestVersion="$1"
|
||||
else
|
||||
latestVersion=$(curl --silent "$latestUrl" | grep -Po '"tag_name": "v\K.*?(?=")')
|
||||
fi
|
||||
|
||||
if [ -z $latestVersion ] ; then
|
||||
echoerr " [E] Cannot determine latest version from github repository"
|
||||
return 1
|
||||
elif [ $QUIET -eq 0 ] ; then
|
||||
echo
|
||||
exe read -p "Install $latestVersion to $ELEMENT_WEB_LOC [n]o/(y)es? " answer
|
||||
case $answer in
|
||||
[yY])
|
||||
;;
|
||||
*)
|
||||
echoerr " [I] Upgrade aborted"
|
||||
return 1
|
||||
;;
|
||||
esac
|
||||
fi
|
||||
|
||||
local isInstalled=$(grep -E "${latestVersion}" "${ELEMENT_WEB_LOC}/version" >>/dev/null && echo "1" || echo "0")
|
||||
if [ $isInstalled -eq 1 ] ; then
|
||||
echo " [I] Version $latestVersion is already installed"
|
||||
return 0
|
||||
fi
|
||||
|
||||
# Download
|
||||
local downUrl="https://github.com/vector-im/element-web/releases/download/v${latestVersion}/element-v${latestVersion}.tar.gz"
|
||||
local tempExtract="$tempDown/element-v$latestVersion"
|
||||
|
||||
if [ ! -e "$tempExtract" ] ; then
|
||||
exe mkdir -p "$tempDown"
|
||||
exe wget -O "$tempLoc" $downUrl
|
||||
endReturn -o $? "Download failed: $downUrl"
|
||||
exe cd "$tempDown"
|
||||
exe tar -xf "$tempLoc"
|
||||
endReturn -o $? "Extract failed: $tempLoc"
|
||||
else
|
||||
echo " [I] Found existing download: $tempExtract"
|
||||
fi
|
||||
|
||||
# Installation
|
||||
local tempBu="${ELEMENT_WEB_LOC}_bu_`date +%Y%m%d-%H%M%S`"
|
||||
|
||||
exe mv "$ELEMENT_WEB_LOC" "$tempBu"
|
||||
step backup "$tempBu"
|
||||
endReturn -o $? "Backup failed; $ELEMENT_WEB_LOC renamed!"
|
||||
echo " [I] Installing version $latestVersion to $ELEMENT_WEB_LOC"
|
||||
exe mv "$tempExtract" "$ELEMENT_WEB_LOC"
|
||||
exe chown -R www-data: "$ELEMENT_WEB_LOC"
|
||||
|
||||
# Configuration
|
||||
echo " [I] Copying configuration"
|
||||
exe cp -ar "$tempBu/config.json" "$ELEMENT_WEB_LOC/"
|
||||
echo " [I] Copying login background"
|
||||
exe cp -ar "$tempBu/$tempBackImg/"* "$ELEMENT_WEB_LOC/$tempBackImg/"
|
||||
|
||||
exe rm -rf "$tempBu"
|
||||
}
|
||||
tempBackImg="themes/element/img/backgrounds"
|
||||
tempDown="/tmp/${toolName}"
|
||||
tempLoc="$tempDown/${toolName}.tar.gz"
|
||||
|
||||
step_24_info() { echo "Clean temporary files: $tempDown"; }
|
||||
step_24_alias() { ALIAS="clean"; }
|
||||
step_24() {
|
||||
exe rm -rf "$tempDown"
|
||||
}
|
||||
|
||||
VERSION_SEQREV=11
|
||||
. /usr/local/bin/sequencer.sh
|
89
seqs/fail2ban.sh
Executable file
89
seqs/fail2ban.sh
Executable file
@@ -0,0 +1,89 @@
|
||||
#!/bin/bash
|
||||
|
||||
toolName=fail2ban
|
||||
toolDeps="$toolName"
|
||||
toolConfDir="/etc/fail2ban"
|
||||
toolConfLoc="$toolConfDir/jail.local"
|
||||
toolFilter="$toolConfDir/filter.d"
|
||||
toolJails="$toolConfDir/jail.d"
|
||||
|
||||
# Get script working directory
|
||||
# (when called from a different directory)
|
||||
WDIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >>/dev/null 2>&1 && pwd )"
|
||||
CONFIG=0
|
||||
CONFIG_FILE_NAME="${toolName}.cfg"
|
||||
CONFIG_FILE_TEMPLATE="$WDIR/${CONFIG_FILE_NAME}.example"
|
||||
CONFIG_DIR="$WDIR/fail2ban"
|
||||
CONFIG_FILTER="$CONFIG_DIR/filter.d"
|
||||
CONFIG_JAILS="$CONFIG_DIR/jail.d"
|
||||
|
||||
#step_config() {
|
||||
# echo "Called once before executing steps."
|
||||
# ## e.g. to source a config file manually:
|
||||
# #. "$CONFIG_FILE"
|
||||
# ## or to use sequencer api:
|
||||
# #initSeqConfig "$CONFIG_FILE_NAME" "$CONFIG_FILE_TEMPLATE"
|
||||
# #if [ $? -eq 0 ] ; then
|
||||
# # CONFIG=1
|
||||
# #fi
|
||||
#}
|
||||
|
||||
step_1_info() { echo "Install $toolName"; }
|
||||
step_1_alias() { ALIAS="install"; }
|
||||
step_1() {
|
||||
local aptOpt=
|
||||
if [ $QUIET -ne 0 ];then
|
||||
aptOpt="-y"
|
||||
fi
|
||||
|
||||
exe apt update
|
||||
exe apt install $toolDeps $aptOpt
|
||||
}
|
||||
|
||||
step_2_info() { echo "Base jail configuration to use ufw"; }
|
||||
step_2_alias() { ALIAS="config"; }
|
||||
step_2() {
|
||||
echo " [I] Create local configuration";
|
||||
addConf -f "$failConfLocal" "$toolConfLoc"
|
||||
exe service $toolName restart
|
||||
}
|
||||
failConfLocal="[DEFAULT]
|
||||
|
||||
banaction = ufw
|
||||
banaction_multiport = ufw
|
||||
ignoreip = 127.0.0.1/8 ::1"
|
||||
|
||||
step_3_info() { echo "Add basic ip-blacklist"; }
|
||||
step_3_alias() { ALIAS="blacklist"; }
|
||||
step_3() {
|
||||
echo " [I] Adding filter"
|
||||
addConf -s -f "$ipBlackListFilter" "$toolFilter/$(basename $ipBlackListFilter)"
|
||||
addConf -s -f "$ipBlackListJail" "$toolJails/$(basename $ipBlackListJail)"
|
||||
addConf -s -f "$ipBlackList" "$toolConfDir/$(basename $ipBlackList)"
|
||||
exe service $toolName restart
|
||||
}
|
||||
ipBlackList="$CONFIG_DIR/ip.blacklist"
|
||||
ipBlackListJail="$CONFIG_JAILS/ip-blacklist.conf"
|
||||
ipBlackListFilter="$CONFIG_FILTER/ip-blacklist.conf"
|
||||
|
||||
step_4_info() { echo "$toolName notes"; }
|
||||
step_4_alias() { ALIAS="notes"; }
|
||||
step_4() {
|
||||
cat <<NOTES_EOF
|
||||
# Syslog not readable by librenms (https://github.com/fail2ban/fail2ban/issues/2734)
|
||||
[$toolConfDir/fail2ban.local]
|
||||
[Definition]
|
||||
logtarget = SYSLOG[format="%%(name)s[%%(process)d]: %%(levelname)s %%(message)s"]
|
||||
NOTES_EOF
|
||||
}
|
||||
|
||||
step_20_info() { echo "Install mailserver jail"; }
|
||||
step_20_alias() { ALIAS="mail"; }
|
||||
step_20() {
|
||||
addConf -s -f "$mailJail" "$toolJails/$(basename $mailJail)"
|
||||
exe service $toolName restart
|
||||
}
|
||||
mailJail="$CONFIG_JAILS/mail.conf"
|
||||
|
||||
VERSION_SEQREV=11
|
||||
. /usr/local/bin/sequencer.sh
|
8
seqs/fail2ban/filter.d/ip-blacklist.conf
Normal file
8
seqs/fail2ban/filter.d/ip-blacklist.conf
Normal file
@@ -0,0 +1,8 @@
|
||||
[Definition]
|
||||
|
||||
datepattern = %%Y/%%m/%%d %%H:%%M(?::%%S)?
|
||||
|
||||
failregex = ^<HOST> \[.*\]$
|
||||
|
||||
ignoreregex =
|
||||
|
4
seqs/fail2ban/filter.d/nextcloud.conf
Normal file
4
seqs/fail2ban/filter.d/nextcloud.conf
Normal file
@@ -0,0 +1,4 @@
|
||||
[Definition]
|
||||
|
||||
failregex = ^.*\"remoteAddr\":\"<HOST>\".*Trusted domain error.*$
|
||||
^.*\"remoteAddr\":\"<HOST>\".*Login failed:.*$
|
2
seqs/fail2ban/ip.blacklist
Normal file
2
seqs/fail2ban/ip.blacklist
Normal file
@@ -0,0 +1,2 @@
|
||||
#37.49.224.142 [2021/05/23 09:00]
|
||||
#37.49.224.142 [2021/05/23 16:00:00]
|
16
seqs/fail2ban/jail.d/ip-blacklist.conf
Normal file
16
seqs/fail2ban/jail.d/ip-blacklist.conf
Normal file
@@ -0,0 +1,16 @@
|
||||
[ip-blacklist]
|
||||
|
||||
enabled = true
|
||||
port = anyport
|
||||
filter = ip-blacklist
|
||||
logpath = /etc/fail2ban/ip.blacklist
|
||||
maxretry = 0
|
||||
findtime = 600
|
||||
# infinite ban
|
||||
#bantime = -1
|
||||
# 1 day ban
|
||||
#bantime = 24h
|
||||
# 2 day ban
|
||||
bantime = 48h
|
||||
# 10 minute ban
|
||||
#bantime = 10m
|
21
seqs/fail2ban/jail.d/mail.conf
Normal file
21
seqs/fail2ban/jail.d/mail.conf
Normal file
@@ -0,0 +1,21 @@
|
||||
[dovecot]
|
||||
enabled = true
|
||||
port = smtp,ssmtp,pop3,pop3s,imap,imap2,imaps
|
||||
filter = dovecot
|
||||
logpath = /var/log/mail.log
|
||||
maxretry = 3
|
||||
bantime = 24h
|
||||
|
||||
[postfix]
|
||||
enabled = true
|
||||
port = smtp,ssmtp
|
||||
filter = postfix
|
||||
logpath = /var/log/mail.log
|
||||
maxretry = 3
|
||||
|
||||
[postfix-sasl]
|
||||
enabled = true
|
||||
port = smtp,ssmtp,imap2,imaps,pop3,pop3s
|
||||
filter = postfix[mode=auth]
|
||||
logpath = /var/log/mail.log
|
||||
maxretry = 3
|
7
seqs/fail2ban/jail.d/nextcloud.conf
Normal file
7
seqs/fail2ban/jail.d/nextcloud.conf
Normal file
@@ -0,0 +1,7 @@
|
||||
[nextcloud]
|
||||
enabled = true
|
||||
logpath = /var/nc_data/nextcloud.log
|
||||
port = http,https
|
||||
filter = nextcloud
|
||||
maxretry = 3
|
||||
bantime = 24h
|
154
seqs/fhem.sh
Executable file
154
seqs/fhem.sh
Executable file
@@ -0,0 +1,154 @@
|
||||
#!/bin/bash
|
||||
|
||||
toolName="fhem"
|
||||
toolUser="$toolName"
|
||||
toolHome="/opt/fhem"
|
||||
toolVersion="6.0"
|
||||
toolDpkg="fhem-${toolVersion}.deb"
|
||||
toolUrl="http://fhem.de/$toolDpkg"
|
||||
# default deps listed at https://debian.fhem.de/
|
||||
toolDeps="perl-base libdevice-serialport-perl libwww-perl libio-socket-ssl-perl libcgi-pm-perl libjson-perl sqlite3 libdbd-sqlite3-perl libtext-diff-perl libtimedate-perl libmail-imapclient-perl libgd-graph-perl libtext-csv-perl libxml-simple-perl liblist-moreutils-perl fonts-liberation2 libimage-librsvg-perl libgd-text-perl libsocket6-perl libio-socket-inet6-perl libmime-base64-urlsafe-perl libimage-info-perl libusb-1.0-0-dev libnet-server-perl"
|
||||
toolDeps2="libdate-manip-perl libhtml-treebuilder-xpath-perl libmojolicious-perl libxml-bare-perl libauthen-oath-perl libconvert-base32-perl libmodule-pluggable-perl libnet-bonjour-perl libcrypt-urandom-perl"
|
||||
# for rounding operations e.g.:
|
||||
# { use Math::Round qw/nearest/;; nearest('0.01',ReadingsVal("1WT_28_5728E9070000", "temperature", 0)-1.1);; }
|
||||
toolDeps2+=" libmath-round-perl"
|
||||
# for fritzbox connection
|
||||
toolDeps2+=" libsoap-lite-perl libjson-xs-perl"
|
||||
# for xmpp support (no special solution needed for raspbian buster)
|
||||
toolDeps2+=" libnet-xmpp-perl libxml-stream-perl libnet-jabber-perl"
|
||||
|
||||
|
||||
# Get script working directory
|
||||
# (when called from a different directory)
|
||||
WDIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >>/dev/null 2>&1 && pwd )"
|
||||
WSUBDIR="${WDIR}/${toolName}"
|
||||
#CONFIG_FILE="$WDIR/${toolName}.cfg"
|
||||
#CONFIG_FILE_DEFAULT="${CONFIG_FILE}.example"
|
||||
|
||||
#step_config() {
|
||||
# echo "Called once before executing steps."
|
||||
# echo "e.g. to source a config file:"
|
||||
# #. "$CONFIG_FILE"
|
||||
#}
|
||||
|
||||
step_1_info() { echo "Install prerequisits for $toolName"; }
|
||||
step_1_alias() { ALIAS="install"; }
|
||||
step_1() {
|
||||
local aptOpt=
|
||||
if [ $QUIET != 0 ] ; then
|
||||
aptOpt="-y"
|
||||
fi
|
||||
#exe apt update
|
||||
exe apt install $toolDeps $toolDeps2 "$aptOpt"
|
||||
#exe apt install "$toolDeps2" "$aptOpt"
|
||||
endReturn -o $? "Installation of prerequisits failed"
|
||||
}
|
||||
|
||||
step_2_info() { echo "Download and install $toolName version $toolVersion"; }
|
||||
step_2() {
|
||||
exe wget "$toolUrl" -O "$downPath"
|
||||
endReturn -o $? "Download of $toolName failed"
|
||||
exe dpkg -i "$downPath"
|
||||
endReturn -o $? "Installation of $toolName failed"
|
||||
}
|
||||
downPath="/tmp/$toolDpkg"
|
||||
|
||||
step_3_info() { echo "Start $toolName service"; }
|
||||
step_3() {
|
||||
exe systemctl restart fhem.service
|
||||
}
|
||||
|
||||
step_20_info() { echo "List $toolName prerequisits"; }
|
||||
step_20_alias() { ALIAS="listdeps"; }
|
||||
step_20() {
|
||||
echo " [I] $toolName prerequisits:"
|
||||
echo "$toolDeps $toolDeps2"
|
||||
}
|
||||
|
||||
step_30_info() { echo "Create user $toolUser"; }
|
||||
step_30() {
|
||||
exe useradd --system --home "$toolHome" --gid dialout --shell /bin/false "$toolUser"
|
||||
endReturn -o $? "Creating user $toolUser failed"
|
||||
}
|
||||
|
||||
step_32_info() { echo "Create $toolName systemd service"; }
|
||||
step_32() {
|
||||
exe cp "${toolHome}/contrib/init-scripts/fhem.service" "$systemdConfigLoc"
|
||||
exe systemctl daemon-reload
|
||||
}
|
||||
systemdConfigLoc="/etc/systemd/system"
|
||||
|
||||
step_34_info() { echo "Downgrade $toolName jabber dependencies (callbackIQ -> FHEM crash)"; }
|
||||
step_34_alias() { ALIAS="downgrade_xmpp"; }
|
||||
step_34() {
|
||||
if [ ! -f $libnetDown ]; then
|
||||
exe wget "$libnetUrl" -O "$libnetDown"
|
||||
endReturn -o $? "Download of $libnetUrl failed"
|
||||
fi
|
||||
if [ ! -f $libxmlDown ]; then
|
||||
exe wget "$libxmlUrl" -O "$libxmlDown"
|
||||
endReturn -o $? "Download of $libxmlUrl failed"
|
||||
fi
|
||||
|
||||
local aptOption=
|
||||
if [ $QUIET -ne 0 ] ; then
|
||||
aptOption="-y"
|
||||
else
|
||||
aptOption=""
|
||||
fi
|
||||
|
||||
exe apt remove libnet-jabber-perl $aptOption
|
||||
saveReturn $?
|
||||
exe apt remove libnet-xmpp-perl $aptOption
|
||||
saveReturn $?
|
||||
exe apt remove libxml-stream-perl $aptOption
|
||||
saveReturn $?
|
||||
endReturn "Failed removing packages; Manual fix required"
|
||||
|
||||
exe dpkg -i "$libxmlDown"
|
||||
saveReturn $?
|
||||
exe dpkg -i "$libnetDown"
|
||||
saveReturn $?
|
||||
exe apt install libnet-jabber-perl $aptOption
|
||||
saveReturn $?
|
||||
endReturn "Failed removing packages; Manual fix required"
|
||||
|
||||
exe rm "$libxmlDown" "$libnetDown"
|
||||
}
|
||||
libnetName="libnet-xmpp-perl_1.02-3_all.deb"
|
||||
libnetDown="/tmp/$libnetName"
|
||||
libnetUrl="http://ftp.de.debian.org/debian-archive/debian/pool/main/libn/libnet-xmpp-perl/$libnetName"
|
||||
libxmlName="libxml-stream-perl_1.23-2_all.deb"
|
||||
libxmlDown="/tmp/$libxmlName"
|
||||
libxmlUrl="http://ftp.de.debian.org/debian/pool/main/libx/libxml-stream-perl/$libxmlName"
|
||||
|
||||
step_35_info() { echo "Pin downgraded $toolName jabber dependencies"; }
|
||||
step_35() {
|
||||
addConf -s "$aptPinXmpp" "$aptPinFile"
|
||||
}
|
||||
aptPinFile="/etc/apt/preferences.d/00_FhemJabber"
|
||||
aptPinXmpp="Package: libnet-xmpp-perl
|
||||
Pin: version 1.02-3*
|
||||
Pin-Priority: 1000
|
||||
|
||||
Package: libxml-stream-perl
|
||||
Pin: version 1.23-2
|
||||
Pin-Priority: 1000"
|
||||
|
||||
step_37_info() { echo "Download latest speedtest python script"; }
|
||||
step_37_alias() { ALIAS="speedtestdownload"; }
|
||||
step_37() {
|
||||
local lSpeedPath="/usr/local/bin/speedtest-cli"
|
||||
exe wget -O "$lSpeedPath" https://raw.githubusercontent.com/sivel/speedtest-cli/master/speedtest.py
|
||||
exe chmod +x "$lSpeedPath"
|
||||
}
|
||||
|
||||
step_40_info() { echo "Execute fhem [COMMAND]"; }
|
||||
step_40_alias() { ALIAS="exe"; }
|
||||
step_40() {
|
||||
shift
|
||||
exe perl "${toolHome}/fhem.pl" 7072 "$1"
|
||||
}
|
||||
|
||||
VERSION_SEQREV=11
|
||||
. /usr/local/bin/sequencer.sh
|
7
seqs/fhem/20-FhemIf.rules
Normal file
7
seqs/fhem/20-FhemIf.rules
Normal file
@@ -0,0 +1,7 @@
|
||||
# Datei: /etc/udev/rules.d/20-FehmIf.rules
|
||||
# Gerät CUL868 busware.de (homematic RF) an USB
|
||||
SUBSYSTEM=="tty", ATTRS{idVendor}=="03eb", ATTRS{idProduct}=="204b", SYMLINK+="tty_CUL868"
|
||||
SUBSYSTEM=="tty", ATTRS{idVendor}=="0658", ATTRS{idProduct}=="0200", SYMLINK+="tty_Zwave"
|
||||
SUBSYSTEM=="tty", ATTRS{idVendor}=="0403", ATTRS{idProduct}=="6001", ATTRS{serial}=="A40352S9", SYMLINK+="ttyUSB_RS485"
|
||||
SUBSYSTEM=="tty", ATTRS{idVendor}=="0403", ATTRS{idProduct}=="6001", ATTRS{serial}=="A103R0XO", SYMLINK+="ttyUSB_LinkUSBi"
|
||||
SUBSYSTEM=="tty", ATTRS{idVendor}=="0403", ATTRS{idProduct}=="6001", ATTRS{serial}=="FT8YS9UP", SYMLINK+="ttyUSB_Comfoair"
|
9
seqs/freeradius.cfg.example
Normal file
9
seqs/freeradius.cfg.example
Normal file
@@ -0,0 +1,9 @@
|
||||
#!/bin/bash
|
||||
|
||||
## Freeradius settings
|
||||
FRAD_DB_NAME="radius"
|
||||
FRAD_DB_USER="radius"
|
||||
# Default freeradius database password: radpass
|
||||
|
||||
## Daloradius settings
|
||||
DRAD_HOME="/var/www/daloradius"
|
73
seqs/freeradius.sh
Executable file
73
seqs/freeradius.sh
Executable file
@@ -0,0 +1,73 @@
|
||||
#!/bin/bash
|
||||
|
||||
toolName=freeradius
|
||||
toolConfLoc="/etc/freeradius/3.0"
|
||||
|
||||
# Get script working directory
|
||||
# (when called from a different directory)
|
||||
WDIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" >>/dev/null 2>&1 && pwd)"
|
||||
APTOPT=
|
||||
CONFIG=0
|
||||
SCRIPT_FILE=$(basename -- $0)
|
||||
SCRIPT_NAME=${SCRIPT_FILE%%.*}
|
||||
CONFIG_FILE_NAME="${SCRIPT_NAME}.cfg"
|
||||
CONFIG_FILE_TEMPLATE="$WDIR/${CONFIG_FILE_NAME}.example"
|
||||
|
||||
step_config() {
|
||||
## or to use sequencer api with profile config file support:
|
||||
initSeqConfig "$SCRIPT_NAME" "$CONFIG_FILE_TEMPLATE"
|
||||
if [ $? -eq 0 ] ; then
|
||||
CONFIG=1
|
||||
echoseq " [I] Freeradius DB: $FRAD_DB_NAME"
|
||||
echoseq " Daloradius home: $DRAD_HOME"
|
||||
else
|
||||
# End if no configuration file exists
|
||||
[ $DRY -eq 0 ] && return -1
|
||||
fi
|
||||
|
||||
## Apt cmdline option to suppress user interaction
|
||||
[ $QUIET -ne 0 ] && APTOPT="-y"
|
||||
|
||||
## Return of non zero value will abort the sequence
|
||||
return 0
|
||||
}
|
||||
|
||||
step_50_info() { echo "Init freeradius and daloradius database"; }
|
||||
step_50_alias() { ALIAS="initdb"; }
|
||||
step_50() {
|
||||
local drDbInit="$DRAD_HOME/contrib/db/mysql-daloradius.sql"
|
||||
local frDbSchema="$toolConfLoc/mods-config/sql/main/mysql/schema.sql"
|
||||
local frDbSetup="$toolConfLoc/mods-config/sql/main/mysql/setup.sql"
|
||||
exe "$WDIR"/mysql.sh createdb -c utf8 -d "$FRAD_DB_NAME" -u "$FRAD_DB_USER"
|
||||
endReturn -o $? "Creating database failed"
|
||||
|
||||
exep "mysql -uroot \"$FRAD_DB_NAME\" < $frDbSchema"
|
||||
#exep "mysql -uroot \"$FRAD_DB_NAME\" < $frDbSetup"
|
||||
exep "mysql -uroot \"$FRAD_DB_NAME\" < $drDbInit"
|
||||
}
|
||||
|
||||
|
||||
step_52_info() { echo "Reset freeradius and daloradius database"; }
|
||||
step_52_alias() { ALIAS="resetdb"; }
|
||||
step_52() {
|
||||
local lAnswer
|
||||
|
||||
if [ $QUIET -eq 0 ]; then
|
||||
read -p "Do you really want to reset the database $FRAD_DB_NAME y/[n]? " lAnswer
|
||||
else
|
||||
lAnswer=y
|
||||
fi
|
||||
case "$lAnswer" in
|
||||
[yY])
|
||||
echoseq -n " [I] Reseting DB...";;
|
||||
*)
|
||||
echoerr " [I] Abort reset"
|
||||
return 1;;
|
||||
esac
|
||||
|
||||
exe mysql -e "DROP DATABASE $FRAD_DB_NAME"
|
||||
step initdb
|
||||
}
|
||||
|
||||
VERSION_SEQREV=13
|
||||
. /usr/local/bin/sequencer.sh
|
9
seqs/friendica.cfg.example
Normal file
9
seqs/friendica.cfg.example
Normal file
@@ -0,0 +1,9 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Friendica sequence configuration
|
||||
# FR = Friendica
|
||||
|
||||
FR_LOC="/var/www/friendica"
|
||||
FR_LOC_DATA="/var/fd_data"
|
||||
FR_BACKUP="/root/backup/friendica"
|
||||
FR_DATABASE="friendica_db"
|
172
seqs/friendica.sh
Executable file
172
seqs/friendica.sh
Executable file
@@ -0,0 +1,172 @@
|
||||
#!/bin/bash
|
||||
|
||||
toolName=friendica
|
||||
latestUrl="https://api.github.com/repos/friendica/friendica/releases/latest"
|
||||
|
||||
# Get script working directory
|
||||
# (when called from a different directory)
|
||||
WDIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >>/dev/null 2>&1 && pwd )"
|
||||
CONFIG=0
|
||||
CONFIG_FILE_NAME="${toolName}.cfg"
|
||||
CONFIG_FILE_TEMPLATE="$WDIR/${CONFIG_FILE_NAME}.example"
|
||||
|
||||
step_config() {
|
||||
initSeqConfig "$CONFIG_FILE_NAME" "$CONFIG_FILE_TEMPLATE"
|
||||
if [ $? -eq 0 ] ; then
|
||||
CONFIG=1
|
||||
fi
|
||||
}
|
||||
|
||||
step_20_info() {
|
||||
shift
|
||||
echoinfoArgs "[FRIENDICA ROOT]"
|
||||
echo -n "Create a backup"
|
||||
if [ $CONFIG -ne 0 ] ; then
|
||||
echo " at $FR_BACKUP"
|
||||
else
|
||||
echo
|
||||
fi
|
||||
}
|
||||
step_20_alias() { ALIAS="backup"; }
|
||||
step_20() {
|
||||
shift
|
||||
local tempRoot=
|
||||
if [ $CONFIG -eq 0 ] ; then
|
||||
echoerr " [E] No configuration file found"
|
||||
return 1
|
||||
fi
|
||||
if [ ! -z $FR_BACKUP ] ; then
|
||||
exe mkdir -p "$FR_BACKUP"
|
||||
fi
|
||||
if [ ! -z "$1" ] ; then
|
||||
tempRoot="$1"
|
||||
else
|
||||
tempRoot="$FR_LOC"
|
||||
fi
|
||||
|
||||
exe $WDIR/mysql.sh -qq backup "$FR_DATABASE" "$FR_BACKUP"
|
||||
endReturn -o $? "Backup mysql database failed"
|
||||
|
||||
[ ! -e "$tempRoot" ] && endReturn -o 1 -f "Friendica root $tempRoot not found"
|
||||
|
||||
local wwwBackup="$FR_BACKUP/${toolName}_www_`date +%Y%m%d-%H%M%S`.tar.gz"
|
||||
local dataBackup="$FR_BACKUP/${toolName}_data_`date +%Y%m%d-%H%M%S`.tar.gz"
|
||||
echo " [I] Backing up webserver directory to $wwwBackup"
|
||||
exe cd "$tempRoot/.."
|
||||
exe tar czf "$wwwBackup" $(basename "$tempRoot")
|
||||
echo " [I] Backing up data directory to $dataBackup"
|
||||
exe cd "$FR_LOC_DATA/.."
|
||||
exe tar czf "$dataBackup" $(basename "$FR_LOC_DATA")
|
||||
}
|
||||
|
||||
step_22_info() {
|
||||
shift
|
||||
if [ -z $1 ] ; then
|
||||
echo -n "Get latest version from github"
|
||||
if [ $CONTEXT_HELP -eq 0 ] ; then
|
||||
echo ": $(curl --silent "$latestUrl" | grep -Po '"tag_name": "\K.*?(?=")')"
|
||||
else
|
||||
echo " [CUSTOM VERSION]"
|
||||
fi
|
||||
else
|
||||
echo "Get version $1 from github"
|
||||
fi
|
||||
}
|
||||
step_22_alias() { ALIAS="upgrade"; }
|
||||
step_22() {
|
||||
shift # don't need step number
|
||||
local latestVersion=
|
||||
if [ ! -z $1 ] ; then
|
||||
latestVersion="$1"
|
||||
else
|
||||
latestVersion=$(curl --silent "$latestUrl" | grep -Po '"tag_name": "\K.*?(?=")')
|
||||
fi
|
||||
|
||||
if [ -z $latestVersion ] ; then
|
||||
echoerr " [E] Cannot determine latest version from github repository"
|
||||
return 1
|
||||
elif [ $QUIET -eq 0 ] ; then
|
||||
echo
|
||||
exe read -p "Install $latestVersion to $FR_LOC [n]o/(y)es? " answer
|
||||
case $answer in
|
||||
[yY])
|
||||
;;
|
||||
*)
|
||||
echoerr " [I] Upgrade aborted"
|
||||
return 1
|
||||
;;
|
||||
esac
|
||||
fi
|
||||
|
||||
local isInstalled=$(grep -E "Version $latestVersion" "${FR_LOC}/CHANGELOG" >>/dev/null && echo "1" || echo "0")
|
||||
if [ $isInstalled -eq 1 ] ; then
|
||||
echoerr " [E] Version $latestVersion is already installed"
|
||||
return 2
|
||||
fi
|
||||
|
||||
# Download
|
||||
|
||||
local downUrl="https://files.friendi.ca/friendica-full-${latestVersion}.tar.gz"
|
||||
local downUrlAddons="https://files.friendi.ca/friendica-addons-${latestVersion}.tar.gz"
|
||||
local tempExtract="$tempDown/friendica-full-$latestVersion"
|
||||
local tempExtractAddons="$tempDown/friendica-addons-$latestVersion"
|
||||
|
||||
if [ ! -e "$tempExtract" ] ; then
|
||||
exe mkdir -p "$tempDown"
|
||||
exe wget -O "$tempLoc" $downUrl
|
||||
endReturn -o $? "Download failed: $downUrl"
|
||||
exe cd "$tempDown"
|
||||
exe tar -xf "$tempLoc"
|
||||
endReturn -o $? "Extract failed: $tempLoc"
|
||||
else
|
||||
echo " [I] Found existing download: $tempExtract"
|
||||
fi
|
||||
|
||||
if [ ! -e "$tempExtractAddons" ] ; then
|
||||
exe wget -O "$tempLocAddons" $downUrlAddons
|
||||
endReturn -o $? "Download failed: $downUrlAddons"
|
||||
exe cd "$tempDown"
|
||||
exe mkdir -p "$tempExtractAddons"
|
||||
exe tar -xC "${tempExtractAddons}" -f "$tempLocAddons"
|
||||
endReturn -o $? "Extract failed: $tempLocAddons"
|
||||
else
|
||||
echo " [I] Found existing download: $tempExtractAddons"
|
||||
fi
|
||||
|
||||
# Installation
|
||||
local tempBu="${FR_LOC}_bu_`date +%Y%m%d-%H%M%S`"
|
||||
local tempAddons="${FR_LOC}/addon"
|
||||
|
||||
exe mv "$FR_LOC" "$tempBu"
|
||||
step backup "$tempBu"
|
||||
endReturn -o $? "Backup failed; $FR_LOC renamed!"
|
||||
echo " [I] Installing version $latestVersion to $FR_LOC"
|
||||
exe mv "$tempExtract" "$FR_LOC"
|
||||
exe mv "$tempExtractAddons" "$tempAddons"
|
||||
exe chown -R www-data: "$FR_LOC"
|
||||
|
||||
# Configuration
|
||||
echo " [I] Copying configuration"
|
||||
exe cp -ar "$tempBu/config/local.config.php" "$FR_LOC/config/"
|
||||
if [ -f "$tempBu/config/addon.config.php" ]; then
|
||||
exe cp -ar "$tempBu/config/addon.config.php" "$FR_LOC/config/"
|
||||
fi
|
||||
# Custom landing page
|
||||
if [ -f "$tempBu/home.html" ]; then
|
||||
exe cp -ar "$tempBu/home".* "$FR_LOC/"
|
||||
fi
|
||||
|
||||
echo " [I] Don't forget to \"clean\" if everything is working as expected"
|
||||
}
|
||||
tempDown="/tmp/friendica"
|
||||
tempLoc="$tempDown/fr.tar.gz"
|
||||
tempLocAddons="$tempDown/fradd.tar.gz"
|
||||
|
||||
step_24_info() { echo "Clean temporary files: $tempDown"; }
|
||||
step_24_alias() { ALIAS="clean"; }
|
||||
step_24() {
|
||||
exe rm -rf "$tempDown"
|
||||
}
|
||||
|
||||
VERSION_SEQREV=14
|
||||
. /usr/local/bin/sequencer.sh
|
52
seqs/git.sh
Executable file
52
seqs/git.sh
Executable file
@@ -0,0 +1,52 @@
|
||||
#!/bin/bash
|
||||
|
||||
toolName=git
|
||||
|
||||
# Get script working directory
|
||||
# (when called from a different directory and even when called via symlink)
|
||||
WDIR="$(cd "$(dirname -- "$(realpath ${BASH_SOURCE[0]})")" >>/dev/null 2>&1 && pwd)"
|
||||
APTOPT=
|
||||
CONFIG=0
|
||||
SCRIPT_FILE=$(basename -- $0)
|
||||
SCRIPT_NAME=${SCRIPT_FILE%%.*}
|
||||
CONFIG_FILE_NAME="${SCRIPT_NAME}.cfg"
|
||||
CONFIG_FILE_TEMPLATE="$WDIR/${CONFIG_FILE_NAME}.example"
|
||||
|
||||
step_config() {
|
||||
## or to use sequencer api with global config file:
|
||||
#initSeqConfig "$CONFIG_FILE_NAME" "$CONFIG_FILE_TEMPLATE"
|
||||
#if [ $? -eq 0 ] ; then
|
||||
# CONFIG=1
|
||||
#else
|
||||
# # End if no configuration file exists
|
||||
# [ $DRY -eq 0 ] && return -1
|
||||
#fi
|
||||
|
||||
## Apt cmdline option to suppress user interaction
|
||||
[ $QUIET -ne 0 ] && APTOPT="-y"
|
||||
|
||||
## Return of non zero value will abort the sequence
|
||||
return 0
|
||||
}
|
||||
|
||||
step_1_info() { echo "Setup global git aliases"; }
|
||||
step_1_alias() { ALIAS="alias"; }
|
||||
step_1() {
|
||||
local brConf="branch \
|
||||
--format='%(HEAD) %(color:yellow)%(refname:short)%(color:reset) - \
|
||||
%(contents:subject) %(color:green)(%(committerdate:relative)) [%(authorname)]' \
|
||||
--sort=-committerdate"
|
||||
local logConf="!git log --pretty=format:\"%C(magenta)%h%Creset \
|
||||
-%C(red)%d%Creset %s %C(dim green)(%cr) [%an]\" --abbrev-commit -30"
|
||||
exe git config --global alias.s 'status -s'
|
||||
exe git config --global alias.st 'status'
|
||||
exe git config --global alias.co 'checkout'
|
||||
exe git config --global alias.ci 'commit'
|
||||
exe git config --global alias.b "${brConf}"
|
||||
exe git config --global alias.br 'branch'
|
||||
exe git config --global alias.l "${logConf}"
|
||||
exe git config --global alias.ll 'log'
|
||||
}
|
||||
|
||||
VERSION_SEQREV=15
|
||||
. /usr/local/bin/sequencer.sh
|
57
seqs/gitea.cfg.example
Normal file
57
seqs/gitea.cfg.example
Normal file
@@ -0,0 +1,57 @@
|
||||
#!/bin/bash
|
||||
|
||||
SEQ_GITEA_USER="git"
|
||||
SEQ_GITEA_BIN_LOC="/usr/local/bin/gitea"
|
||||
SEQ_GITEA_BASE_DIR="/var/lib/gitea"
|
||||
SEQ_GITEA_WORK_DIR="$SEQ_GITEA_BASE_DIR/work"
|
||||
SEQ_GITEA_HOME_DIR="$SEQ_GITEA_BASE_DIR/home"
|
||||
SEQ_GITEA_CONF_DIR="$SEQ_GITEA_BASE_DIR/config"
|
||||
SEQ_GITEA_BACKUP_DIR="$SEQ_GITEA_BASE_DIR/backup"
|
||||
|
||||
# Service Derived from
|
||||
# https://raw.githubusercontent.com/go-gitea/gitea/master/contrib/systemd/gitea.service
|
||||
SEQ_GITEA_SERVICE="[Unit]
|
||||
Description=Gitea (Git with a cup of tea)
|
||||
After=syslog.target
|
||||
After=network.target
|
||||
|
||||
Requires=mysql.service
|
||||
|
||||
[Service]
|
||||
# Modify these two values and uncomment them if you have
|
||||
# repos with lots of files and get an HTTP error 500 because
|
||||
# of that
|
||||
###
|
||||
#LimitMEMLOCK=infinity
|
||||
#LimitNOFILE=65535
|
||||
|
||||
RestartSec=2s
|
||||
Type=simple
|
||||
User=$SEQ_GITEA_USER
|
||||
Group=$SEQ_GITEA_USER
|
||||
WorkingDirectory=$SEQ_GITEA_WORK_DIR
|
||||
|
||||
# If using Unix socket: tells systemd to create the /run/gitea folder, which will contain the gitea.sock f
|
||||
# (manually creating /run/gitea doesn't work, because it would not persist across reboots)
|
||||
#RuntimeDirectory=gitea
|
||||
ExecStart=/usr/local/bin/gitea web --config \"$SEQ_GITEA_CONF_DIR/app.ini\"
|
||||
|
||||
Restart=always
|
||||
Environment=USER=\"$SEQ_GITEA_USER\" HOME=\"$SEQ_GITEA_HOME_DIR\" GITEA_WORK_DIR=\"$SEQ_GITEA_WORK_DIR\"
|
||||
|
||||
# If you install Git to directory prefix other than default PATH (which happens
|
||||
# for example if you install other versions of Git side-to-side with
|
||||
# distribution version), uncomment below line and add that prefix to PATH
|
||||
# Don't forget to place git-lfs binary on the PATH below if you want to enable
|
||||
# Git LFS support
|
||||
#Environment=PATH=/path/to/git/bin:/bin:/sbin:/usr/bin:/usr/sbin
|
||||
|
||||
# If you want to bind Gitea to a port below 1024, uncomment
|
||||
# the two values below, or use socket activation to pass Gitea its ports as above
|
||||
###
|
||||
#CapabilityBoundingSet=CAP_NET_BIND_SERVICE
|
||||
#AmbientCapabilities=CAP_NET_BIND_SERVICE
|
||||
###
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target"
|
248
seqs/gitea.sh
248
seqs/gitea.sh
@@ -4,119 +4,205 @@
|
||||
## Installation of self hosted git service Gitea
|
||||
|
||||
toolName="gitea"
|
||||
giteaDownload="https://dl.gitea.io/gitea/1.7.5/gitea-1.7.5-linux-arm-7"
|
||||
giteaService="https://raw.githubusercontent.com/go-gitea/gitea/master/contrib/systemd/gitea.service"
|
||||
giteaServiceLoc="/etc/systemd/system/gitea.service"
|
||||
# Get script working directory
|
||||
# (when called from a different directory)
|
||||
WDIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" >>/dev/null 2>&1 && pwd)"
|
||||
APTOPT=
|
||||
CONFIG=0
|
||||
SCRIPT_FILE=$(basename -- $0)
|
||||
SCRIPT_NAME=${SCRIPT_FILE%%.*}
|
||||
CONFIG_FILE_NAME="${SCRIPT_NAME}.cfg"
|
||||
CONFIG_FILE_TEMPLATE="$WDIR/${CONFIG_FILE_NAME}.example"
|
||||
|
||||
step_1_info() { echo "Updating apt"; }
|
||||
step_1() {
|
||||
apt update
|
||||
giteaLatestUrl="https://api.github.com/repos/go-gitea/gitea/releases/latest"
|
||||
giteaVersion=$(curl --silent "$giteaLatestUrl" | grep -Po '"tag_name": "v\K.*?(?=")')
|
||||
giteaArch=
|
||||
giteaDownloadEval='https://dl.gitea.io/gitea/${giteaVersion}/gitea-${giteaVersion}-linux-${giteaArch}'
|
||||
giteaDownload=$(eval echo $giteaDownloadEval)
|
||||
giteaDir="/usr/local/bin"
|
||||
giteaServiceLoc="/etc/systemd/system/gitea.service"
|
||||
giteaLogDir="/var/log/gitea"
|
||||
giteaIniLoc=
|
||||
giteaDownFile="/tmp/giteaDown"
|
||||
giteaUser="git"
|
||||
versionNow=
|
||||
|
||||
step_config() {
|
||||
initSeqConfig "$CONFIG_FILE_NAME" "$CONFIG_FILE_TEMPLATE"
|
||||
if [ $? -eq 0 ] ; then
|
||||
CONFIG=1
|
||||
else
|
||||
# End if no configuration file exists
|
||||
[ $DRY -eq 0 ] && return -1
|
||||
fi
|
||||
|
||||
## Apt cmdline option to suppress user interaction
|
||||
[ $QUIET -ne 0 ] && APTOPT="-y"
|
||||
|
||||
if [ -z $giteaVersion ] ; then
|
||||
echoerr " [E] Couldn't determine latest version of $toolName"
|
||||
fi
|
||||
[ ! -z "$(command -v gitea)" ] && versionNow=$(gitea --version | sed 's/.*version \([0-9.]\+\).*/\1/')
|
||||
|
||||
checkArchitecture
|
||||
giteaIniLoc="${SEQ_GITEA_CONF_DIR}/app.ini"
|
||||
|
||||
echoseq " [I] Gitea work: $SEQ_GITEA_WORK_DIR"
|
||||
echoseq " Gitea config: $SEQ_GITEA_CONF_DIR"
|
||||
echoseq " Git user home: $SEQ_GITEA_HOME_DIR"
|
||||
echoseq
|
||||
outColor yellow
|
||||
echoseq " [W] Don't forget to adapt $SEQ_GITEA_CONF_DIR/app.ini"
|
||||
outColor
|
||||
|
||||
## Return of non zero value will abort the sequence
|
||||
return 0
|
||||
}
|
||||
|
||||
step_2_info() { echo "Downloading $toolName to user home: $giteaDownload"; }
|
||||
checkArchitecture() {
|
||||
[ ! -z "$(command -v dpkg)" ] && giteaArch=$(dpkg --print-architecture)
|
||||
case $giteaArch in
|
||||
armhf)
|
||||
giteaArch="arm-6";;
|
||||
esac
|
||||
giteaDownload=$(eval echo $giteaDownloadEval)
|
||||
}
|
||||
|
||||
step_1_info() { echo "Updating apt"; }
|
||||
step_1_alias() { ALIAS="install"; }
|
||||
step_1() {
|
||||
exe apt update
|
||||
}
|
||||
|
||||
step_2_info() {
|
||||
[ -z "$giteaArch" ] && checkArchitecture
|
||||
echo "Downloading $toolName to user home from:"
|
||||
echoinfo "$giteaDownload"
|
||||
}
|
||||
step_2() {
|
||||
cd
|
||||
wget -O gitea $giteaDownload
|
||||
exe wget -O "$giteaDownFile" $giteaDownload
|
||||
saveReturn $?
|
||||
endReturn
|
||||
}
|
||||
|
||||
step_3_info() { echo "Adding user for $toolName (git:git)"; }
|
||||
step_3_info() { echo "Adding user for $toolName ($giteaUser)"; }
|
||||
step_3() {
|
||||
adduser \
|
||||
--system \
|
||||
--shell /bin/bash \
|
||||
--gecos 'Git Version Control' \
|
||||
--group \
|
||||
--disabled-password \
|
||||
--home /home/git \
|
||||
git
|
||||
exe adduser \
|
||||
--system \
|
||||
--shell /bin/bash \
|
||||
--gecos 'Git Version Control' \
|
||||
--group \
|
||||
--disabled-password \
|
||||
--home "$SEQ_GITEA_HOME_DIR" \
|
||||
"$SEQ_GITEA_USER"
|
||||
saveReturn $?
|
||||
endReturn
|
||||
}
|
||||
|
||||
step_4_info() { echo "Create required directory structure"; }
|
||||
step_4() {
|
||||
mkdir -p /var/lib/gitea/{custom,data,log}
|
||||
chown -R git: /var/lib/gitea/
|
||||
chmod -R 750 /var/lib/gitea/
|
||||
mkdir /etc/gitea
|
||||
chown root:git /etc/gitea
|
||||
chmod 770 /etc/gitea
|
||||
echo "Copying gitea to global location and making it executable"
|
||||
chmod +x ~/gitea
|
||||
cp ~/gitea /usr/local/bin/gitea
|
||||
saveReturn $?
|
||||
endReturn
|
||||
exe install -o $SEQ_GITEA_USER -g $SEQ_GITEA_USER -m 750 \
|
||||
-d "$SEQ_GITEA_BACKUP_DIR" "$SEQ_GITEA_CONF_DIR" \
|
||||
"$SEQ_GITEA_HOME_DIR" "$SEQ_GITEA_WORK_DIR"/{custom,data,log}
|
||||
exe chown root:$SEQ_GITEA_USER "$SEQ_GITEA_CONF_DIR"
|
||||
exe chmod 770 $SEQ_GITEA_CONF_DIR
|
||||
echoseq "Creating $giteaLogDir"
|
||||
exe install -g $SEQ_GITEA_USER -m 770 -d "$giteaLogDir"
|
||||
echoseq -n "Copying gitea to global location and making it executable..."
|
||||
exe install -b -m 755 -T "$giteaDownFile" "$SEQ_GITEA_BIN_LOC" && echo "ok"
|
||||
endReturn "Failed to install $SEQ_GITEA_BIN_LOC"
|
||||
}
|
||||
|
||||
step_5_info() { echo "Creating systemd service"; }
|
||||
step_5() {
|
||||
wget -O $giteaServiceLoc $giteaService
|
||||
echo -en "Uncomment needed services mysql (enter to continue): "
|
||||
read
|
||||
vi $giteaServiceLoc
|
||||
addConf -c "$SEQ_GITEA_SERVICE" "$giteaServiceLoc"
|
||||
}
|
||||
|
||||
step_6_info() { echo -e "Starting $toolName service\n"; }
|
||||
step_6_info() { echo "Starting $toolName service"; }
|
||||
step_6() {
|
||||
systemctl enable gitea
|
||||
systemctl start gitea
|
||||
echo "Before proceeding to installation you may need to create a database first with step 10"
|
||||
echo
|
||||
echo "Goto http://[yourip]:3000/install and complete installation"
|
||||
echo
|
||||
echo "Afterwards please execute step 20 to secure configuration"
|
||||
exe systemctl enable gitea --now
|
||||
echoseq "Before proceeding to installation you may need to create a database first with step 10"
|
||||
echoseq
|
||||
echoseq "Goto http://[yourip]:3000/install and complete installation"
|
||||
echoseq
|
||||
echoseq "Afterwards please execute step 20 to secure configuration"
|
||||
}
|
||||
|
||||
step_7_info() { echo "Show configuration notes"; }
|
||||
step_7_alias() { ALIAS="notes"; }
|
||||
step_7() {
|
||||
outColor green
|
||||
cat <<NOTES_END
|
||||
Final configuration notes for $giteaIniLoc:
|
||||
|
||||
step_10_info() { echo -e "Create mysql database for $toolName\n"; }
|
||||
[repository]
|
||||
DEFAULT_CLOSE_ISSUES_VIA_COMMITS_IN_ANY_BRANCH = true
|
||||
|
||||
[server]
|
||||
# Don't show home page
|
||||
LANDING_PAGE = explore
|
||||
|
||||
[mailer]
|
||||
# Allow local MTA without valid certificate
|
||||
SKIP_VERIFY = true
|
||||
|
||||
[service]
|
||||
# Use correct user identity when changing files in the web frontend
|
||||
NO_REPLY_ADDRESS = yourdomain.com
|
||||
|
||||
[attachment]
|
||||
# Allow more archives to be uploaded
|
||||
ALLOWED_TYPES=application/zip|application/gzip|application/x-zip|application/x-gzip|application/x-shellscript|text/markdown
|
||||
NOTES_END
|
||||
}
|
||||
|
||||
step_10_info() { echo "Create mysql database for $toolName"; }
|
||||
step_10() {
|
||||
local mysqlDatabase
|
||||
local mysqlUser
|
||||
local mysqlPass
|
||||
exe "$WDIR/mysql.sh" -qq createdb --charset utf8mb4
|
||||
}
|
||||
|
||||
echo "Existing mysql databases:"
|
||||
mysql -u root -e 'SHOW DATABASES;'
|
||||
step_12_info() {
|
||||
if [ ! -z "$versionNow" ] ; then
|
||||
if [ "$giteaVersion" == "$versionNow" ] ; then
|
||||
echo "No upgrade available. Already on latest: $versionNow"
|
||||
else
|
||||
echo "Download new version $giteaVersion to /usr/local/bin"
|
||||
echoinfo " - installed version: $versionNow -"
|
||||
fi
|
||||
else
|
||||
echo "Upgrade existing $toolName installation"
|
||||
fi
|
||||
}
|
||||
step_12_alias() { ALIAS="upgrade"; }
|
||||
step_12() {
|
||||
endCheckEmpty versionNow "Please install $toolName first"
|
||||
exe wget -O "$giteaDownFile" $giteaDownload
|
||||
endReturn -o $? "Download failed"
|
||||
|
||||
echo -en "Enter database name: "
|
||||
read mysqlDatabase
|
||||
endCheckEmpty mysqlDatabase "database name"
|
||||
mysql -u root -e 'CREATE DATABASE '$mysqlDatabase' CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;'
|
||||
saveReturn $?
|
||||
endReturn
|
||||
|
||||
echo "Existing mysql user:"
|
||||
mysql -u root -e 'SELECT User, Host FROM mysql.user;'
|
||||
echo -en "Enter mysql user name: "
|
||||
read mysqlUser
|
||||
endCheckEmpty mysqlDatabase "user name"
|
||||
|
||||
echo -en "Enter mysql user password: "
|
||||
read mysqlPass
|
||||
endCheckEmpty mysqlPass "password"
|
||||
mysql -u root -e 'CREATE USER '"'"$mysqlUser"'"'@'"'"'localhost'"'"' IDENTIFIED BY '"'"$mysqlPass"'"';'
|
||||
saveReturn $?
|
||||
endReturn
|
||||
|
||||
mysql -u root -e 'GRANT ALL PRIVILEGES ON '$mysqlDatabase'.* TO '"'"$mysqlUser"'"'@'"'"'localhost'"'"';'
|
||||
saveReturn $?
|
||||
endReturn
|
||||
|
||||
mysql -u root -e 'FLUSH PRIVILEGES;'
|
||||
if [ -f "$SEQ_GITEA_BIN_LOC" ] ; then
|
||||
local toolBackup="${SEQ_GITEA_BACKUP_DIR}/gitea_${versionNow}"
|
||||
exe service gitea stop
|
||||
saveReturn $?
|
||||
endReturn
|
||||
echoseq -n "Backing up existing executable to ${toolBackup}..."
|
||||
exe cp -ar "$SEQ_GITEA_BIN_LOC" "$toolBackup" && echoseq "ok" || echoseq "nok"
|
||||
fi
|
||||
exe install --backup=none -m 755 -T "$giteaDownFile" "$SEQ_GITEA_BIN_LOC"
|
||||
endReturn -o $? "Upgrade failed"
|
||||
exe service gitea start
|
||||
}
|
||||
|
||||
step_20_info() { echo "Secure settings after installation"; }
|
||||
step_20() {
|
||||
chmod 750 /etc/gitea
|
||||
chmod 644 /etc/gitea/app.ini
|
||||
exe chmod 750 "$SEQ_GITEA_CONF_DIR"
|
||||
exe chmod 644 "$giteaIniLoc"
|
||||
}
|
||||
|
||||
# Sequence Revision
|
||||
VERSION_SEQREV=1
|
||||
step_22_info() { echo "Open $toolName config file"; }
|
||||
step_22_alias() { ALIAS="config"; }
|
||||
step_22() {
|
||||
exe vi "$giteaIniLoc"
|
||||
}
|
||||
|
||||
# Workaround when called from different directory
|
||||
# Not needed when path to sequencer is absolut
|
||||
DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >>/dev/null 2>&1 && pwd )"
|
||||
# Path to sequencer
|
||||
. ${DIR}/../sequencer/sequencer.sh
|
||||
VERSION_SEQREV=14
|
||||
. /usr/local/bin/sequencer.sh
|
||||
|
3
seqs/grocy.cfg.example
Normal file
3
seqs/grocy.cfg.example
Normal file
@@ -0,0 +1,3 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
sc_grocyDir="/var/www/grocy"
|
166
seqs/grocy.sh
Executable file
166
seqs/grocy.sh
Executable file
@@ -0,0 +1,166 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
shopt -s extglob
|
||||
|
||||
readonly toolName=grocy
|
||||
readonly downUrl="https://releases.grocy.info/latest"
|
||||
readonly versionUrl="https://api.github.com/repos/grocy/grocy/releases/latest"
|
||||
|
||||
versionNew=
|
||||
versionNow=
|
||||
|
||||
sc_grocyConf=
|
||||
sc_grocyBackup="data/backup"
|
||||
sc_grocyViewcache="data/viewcache"
|
||||
|
||||
grocyDownLoc="/tmp/grocy_latest.zip"
|
||||
|
||||
# Get script working directory
|
||||
# (when called from a different directory and even when called via symlink)
|
||||
readonly sq_dir="$(cd "$(dirname -- "$(realpath ${BASH_SOURCE[0]})")" >>/dev/null 2>&1 && pwd)"
|
||||
readonly sq_scriptFile=$(basename -- $0)
|
||||
readonly sq_scriptName=${sq_scriptFile%%.*}
|
||||
readonly sq_configFileName="${sq_scriptName}.cfg"
|
||||
readonly sq_configFileTemplate="$sq_dir/${sq_configFileName}.example"
|
||||
sq_aptOpt=
|
||||
sq_config=0
|
||||
|
||||
step_config() {
|
||||
initSeqConfig -p "$sq_scriptName" "$sq_configFileTemplate"
|
||||
if [ $? -eq 0 ] ; then
|
||||
sq_config=1
|
||||
else
|
||||
# End if no configuration file exists
|
||||
[ $DRY -eq 0 ] && return -1
|
||||
fi
|
||||
|
||||
sc_grocyConf="${sc_grocyDir}/data/config.php"
|
||||
|
||||
## Apt cmdline option to suppress user interaction
|
||||
[ $QUIET -ne 0 ] && sq_aptOpt="-y"
|
||||
|
||||
## Return of non zero value will abort the sequence
|
||||
return 0
|
||||
}
|
||||
|
||||
getVersions() {
|
||||
versionNew=${versionNew:-$(curl --silent "$versionUrl" | grep -Po '"tag_name": "v\K.*?(?=")')}
|
||||
versionNow=${versionNow:-$(grep -Po '"Version": "\K.*?(?=")' 2>/dev/null < "${sc_grocyDir}/version.json")}
|
||||
}
|
||||
|
||||
step_1_info() {
|
||||
echo "Check $toolName status"
|
||||
echoinfo "Returns 1 if update is available"
|
||||
}
|
||||
step_1_alias() { ALIAS="status"; }
|
||||
step_1() {
|
||||
getVersions
|
||||
if [ -e "${sc_grocyDir}" ] ; then
|
||||
echo
|
||||
echo "$toolName installed"
|
||||
echo " at: ${sc_grocyDir}"
|
||||
echo " version: ${versionNow}"
|
||||
echo " config: ${sc_grocyConf}"
|
||||
echo -n " update: "
|
||||
if [[ ! ${versionNow} = ${versionNew} ]] ; then
|
||||
echo "available: ${versionNew}}"
|
||||
return 1
|
||||
else
|
||||
echo "already on latest"
|
||||
return 0
|
||||
fi
|
||||
else
|
||||
echo "$toolName not installed"
|
||||
echo "Version ${versionNew} available for installation"
|
||||
return 1
|
||||
fi
|
||||
}
|
||||
|
||||
step_20_info() { echo "Backup ${toolName}"; }
|
||||
step_20_alias() { ALIAS="backup"; }
|
||||
step_20() {
|
||||
local lBu="${sc_grocyDir}/${sc_grocyBackup}/${toolName}_$(date +%Y%m%d-%H%M%S).tgz"
|
||||
exe cd ${sc_grocyDir}/..
|
||||
exe tar \
|
||||
--exclude="${sc_grocyBackup}/*" \
|
||||
--exclude="${sc_grocyViewcache}/*" \
|
||||
-czf "${lBu}" \
|
||||
"$(basename "${sc_grocyDir}")"
|
||||
}
|
||||
|
||||
step_22_info() { echo "Install/upgrade ${toolName}"; }
|
||||
step_22_alias() { ALIAS="install"; }
|
||||
step_22() {
|
||||
getVersions
|
||||
if [[ ${versionNow} == ${versionNew} ]] ; then
|
||||
endReturn -o 1 "Latest version ${versionNow} already installed"
|
||||
else
|
||||
if [ -n "${versionNow}" ] ; then
|
||||
echoseq " [I] Upgrading $toolName from ${versionNow} to ${versionNew}"
|
||||
else
|
||||
echoseq " [I] Installing $toolName version ${versionNew}"
|
||||
fi
|
||||
fi
|
||||
exe wget ${downUrl} -q -O "${grocyDownLoc}"
|
||||
endReturn -o $? "Download failed"
|
||||
if [ -e "${sc_grocyDir}" ] ; then
|
||||
step backup
|
||||
exe rm -rf "${sc_grocyDir}/${sc_grocyViewcache}"
|
||||
fi
|
||||
exe rm -rf "${sc_grocyDir}/"!(data)
|
||||
exe unzip -o -qq "${grocyDownLoc}" -d "${sc_grocyDir}"
|
||||
exe chown -R www-data: "${sc_grocyDir}/public" "${sc_grocyDir}/data"
|
||||
# Populate first config
|
||||
if [ ! -e "${sc_grocyConf}" ] ; then
|
||||
exe cp "${sc_grocyDir}/config-dist.php" "${sc_grocyConf}"
|
||||
echoseq " [I] Please adjust the config: ${sc_grocyConf}"
|
||||
else
|
||||
echoseq " [I] Please check ${sc_grocyDir}/config-dist.php"
|
||||
echoseq " for new configuration options"
|
||||
fi
|
||||
}
|
||||
|
||||
step_30_alias() { ALIAS="notes"; }
|
||||
step_30() {
|
||||
outColor green
|
||||
cat <<NOTES_END
|
||||
# Behind reverse proxy as subfolder
|
||||
|
||||
* Install in the root of a nginx server (e.g. localhost:8080)
|
||||
* Proxy pass from a subdirectory (e.g. domain.me/grocy)
|
||||
* [data/config.php]
|
||||
Setting('BASE_PATH', '');
|
||||
Setting('BASE_URL', 'https://domain.me/grocy');
|
||||
|
||||
# Nginx config
|
||||
server {
|
||||
listen 8080;
|
||||
|
||||
root /var/www/grocy/public;
|
||||
|
||||
index index.php;
|
||||
|
||||
#access_log /var/log/nginx/grocy.access.log;
|
||||
error_log /var/log/nginx/grocy.error.log;
|
||||
|
||||
location ~ ^.+?\.php(/.*)?\$ {
|
||||
|
||||
fastcgi_pass unix:/var/run/php/php8.0-fpm.sock;
|
||||
fastcgi_split_path_info ^(.+\.php)(/.*)\$;
|
||||
|
||||
set \$path_info \$fastcgi_path_info;
|
||||
fastcgi_param PATH_INFO \$path_info;
|
||||
include fastcgi_params;
|
||||
fastcgi_param SCRIPT_FILENAME \$document_root\$fastcgi_script_name;
|
||||
}
|
||||
|
||||
location / {
|
||||
try_files \$uri /index.php\$is_args\$query_string;
|
||||
}
|
||||
}
|
||||
|
||||
NOTES_END
|
||||
}
|
||||
|
||||
VERSION_SEQREV=15
|
||||
. /usr/local/bin/sequencer.sh
|
145
seqs/jitsi.sh
Executable file
145
seqs/jitsi.sh
Executable file
@@ -0,0 +1,145 @@
|
||||
#!/bin/bash
|
||||
|
||||
toolName="jitsi-meet"
|
||||
|
||||
# Get script working directory
|
||||
# (when called from a different directory)
|
||||
WDIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >>/dev/null 2>&1 && pwd )"
|
||||
#CONFIG=0
|
||||
#CONFIG_FILE_NAME="${toolName}.cfg"
|
||||
#CONFIG_FILE_TEMPLATE="$WDIR/${CONFIG_FILE_NAME}.example"
|
||||
|
||||
#step_config() {
|
||||
#echo "Called once before executing steps."
|
||||
## e.g. to source a config file manually:
|
||||
#. "$CONFIG_FILE"
|
||||
## or to use sequencer api:
|
||||
#initSeqConfig "$CONFIG_FILE_NAME" "$CONFIG_FILE_TEMPLATE"
|
||||
#if [ $? -eq 0 ] ; then
|
||||
# CONFIG=1
|
||||
#fi
|
||||
#}
|
||||
|
||||
step_1_info() { echo "Installation of prerequisits"; }
|
||||
step_1_alias() { ALIAS="prepare"; }
|
||||
step_1() {
|
||||
exe apt install gnupg2 git lsb-release ssl-cert ca-certificates apt-transport-https \
|
||||
tree locate software-properties-common dirmngr screen htop nano net-tools zip unzip \
|
||||
curl ffmpeg ghostscript libfile-fcntllock-perl curl socat
|
||||
}
|
||||
|
||||
step_2_info() { echo "Add universe and official nginx apt repositories"; }
|
||||
step_2() {
|
||||
apt-add-repository universe
|
||||
exep "echo \"deb [arch=amd64] http://nginx.org/packages/mainline/ubuntu $(lsb_release -cs) nginx\" | tee /etc/apt/sources.list.d/nginx.list"
|
||||
exep "curl -fsSL https://nginx.org/keys/nginx_signing.key | sudo apt-key add -"
|
||||
}
|
||||
|
||||
step_3_info() { echo "Add official $toolName apt repository"; }
|
||||
step_3() {
|
||||
exep "echo \"deb https://download.jitsi.org stable/\" | tee /etc/apt/sources.list.d/jitsi.list"
|
||||
exep "wget -qO - https://download.jitsi.org/jitsi-key.gpg.key | sudo apt-key add -"
|
||||
}
|
||||
|
||||
step_4_info() { echo "Upgrade system packages"; }
|
||||
step_4() {
|
||||
exe apt update && apt upgrade
|
||||
}
|
||||
|
||||
step_5_info() { echo "Install nginx webserver"; }
|
||||
step_5_alias() { ALIAS="webserver"; }
|
||||
step_5() {
|
||||
exe apt install nginx
|
||||
endReturn -o $? "Installation of webserver nginx failed"
|
||||
exe mkdir -p /etc/nginx/sites-available
|
||||
exe mkdir -p /etc/nginx/sites-enabled
|
||||
exe mkdir -p /etc/nginx/modules-enabled
|
||||
exe systemctl enable nginx.service
|
||||
}
|
||||
|
||||
step_6_info() { echo "Install ufw firewall"; }
|
||||
step_6_alias() { ALIAS="firewall"; }
|
||||
step_6() {
|
||||
exe apt install ufw
|
||||
endReturn -o $? "Installation of firewall ufw failed"
|
||||
}
|
||||
|
||||
step_7_info() { echo "Setup ufw firewall to run $toolName"; }
|
||||
step_7() {
|
||||
echo " [I] Configure ufw firewall"
|
||||
exe ufw allow 22/tcp
|
||||
exe ufw allow 80/tcp
|
||||
exe ufw allow 443/tcp
|
||||
exe ufw allow 4443/tcp
|
||||
exe ufw allow 10000/udp
|
||||
exe ufw logging medium && ufw default deny incoming && ufw enable && service ufw restart
|
||||
}
|
||||
|
||||
step_8_info() { echo "Install $toolName"; }
|
||||
step_8_alias() { ALIAS="install"; }
|
||||
step_8() {
|
||||
exe read -p "Make sure SSL certificates are available. Enter to continue"
|
||||
exe apt install jitsi-meet -y
|
||||
}
|
||||
|
||||
step_9_info() { echo "Move automatically generated $toolName virutal host to new configuration directory"; }
|
||||
step_9() {
|
||||
exe mv /etc/nginx/sites-available/*.conf /etc/nginx/conf.d
|
||||
exe mv /etc/nginx/conf.d/default.conf /etc/nginx/sites-available
|
||||
exe service nginx restart
|
||||
echo " [I] Check /etc/nginx/conf.d for unwanted configurations"
|
||||
}
|
||||
|
||||
step_10_info() { echo "WIP post-install tasks"; }
|
||||
step_10() {
|
||||
echo " [I] Tasks to be automated"
|
||||
echo
|
||||
echo " * Make jitsi installation password protected"
|
||||
echo " (https://github.com/jitsi/jicofo#secure-domain)"
|
||||
echo " Creating new rooms will require username and password"
|
||||
echo
|
||||
echo " ** /etc/prosody/conf.avail/[your-hostname].cfg.lua"
|
||||
echo
|
||||
echo " a) Enable authentication on your main domain:"
|
||||
echo
|
||||
echo " VirtualHost \"jitsi-meet.example.com\""
|
||||
echo " authentication = \"internal_plain\""
|
||||
echo
|
||||
echo " b) Add new virtual host with anonymous login method for guests:"
|
||||
echo
|
||||
echo " VirtualHost \"guest.jitsi-meet.example.com\""
|
||||
echo " authentication = \"anonymous\""
|
||||
echo " c2s_require_encryption = false"
|
||||
echo
|
||||
echo " ** /etc/jitsi/meet/[your-hostname]-config.js"
|
||||
echo
|
||||
echo " var config = {"
|
||||
echo " hosts: {"
|
||||
echo " domain: 'jitsi-meet.example.com',"
|
||||
echo " anonymousdomain: 'guest.jitsi-meet.example.com',"
|
||||
echo " ..."
|
||||
echo " },"
|
||||
echo " ..."
|
||||
echo " }"
|
||||
echo
|
||||
echo " ** /etc/jitsi/jicofo/sip-communicator.properties"
|
||||
echo " add new line:"
|
||||
echo
|
||||
echo " org.jitsi.jicofo.auth.URL=XMPP:jitsi-meet.example.com"
|
||||
echo
|
||||
echo " ** Create prosody user(s):"
|
||||
echo
|
||||
echo " prosodyctl register <username> jitsi-meet.example.com <password>"
|
||||
echo
|
||||
echo " [I] Use step \"restart\" after these changes"
|
||||
}
|
||||
|
||||
step_20_info() { echo "Restart all $toolName components"; }
|
||||
step_20_alias() { ALIAS="restart"; }
|
||||
step_20() {
|
||||
echo " [I] Restart jitsi-meet components"
|
||||
exep "service prosody restart&& service jicofo restart && service jitsi-videobridge2 restart"
|
||||
}
|
||||
|
||||
VERSION_SEQREV=10
|
||||
. /usr/local/bin/sequencer.sh
|
196
seqs/kodi.sh
Executable file
196
seqs/kodi.sh
Executable file
@@ -0,0 +1,196 @@
|
||||
#!/bin/bash
|
||||
|
||||
## Installing kodi on a raspberry pi
|
||||
## Some measures are taken to prevent corrupting existing files
|
||||
## but it's intendet use is for a blank rasperry pi.
|
||||
|
||||
toolName="Kodi"
|
||||
toolUser="kodi"
|
||||
toolServiceFile="/etc/systemd/system/kodi.service"
|
||||
toolProfileDir="/home/kodi/.kodi"
|
||||
|
||||
step_1_info() { echo "Install $toolName via apt"; }
|
||||
step_1_alias() { ALIAS="install"; }
|
||||
step_1() {
|
||||
exe apt update && apt install kodi
|
||||
}
|
||||
|
||||
step_2_info() { echo "Set localisation and keyboard layout"; }
|
||||
step_2() {
|
||||
echo "Goto \"Localisation Options\" in the following menu."
|
||||
read -p "Press ENTER to continue..."
|
||||
exe raspi-config
|
||||
saveReturn $?
|
||||
endReturn
|
||||
}
|
||||
|
||||
step_3_info() { echo "Add $toolName user ($toolUser)"; }
|
||||
step_3() {
|
||||
exep "id -u $toolUser >>/dev/null 2>&1"
|
||||
if [ $? -eq 0 ] ; then
|
||||
echo
|
||||
echo "User $toolUser exists."
|
||||
echo "Skipping user creation."
|
||||
return 0
|
||||
fi
|
||||
exe adduser \
|
||||
--disabled-password \
|
||||
--gecos "User to run $toolName Media Center" \
|
||||
$toolUser
|
||||
exe usermod -a -G audio,video,plugdev,input,tty $toolUser
|
||||
saveReturn $?
|
||||
endReturn
|
||||
echo "User $toolUser details:"
|
||||
exe id $tooLuser
|
||||
}
|
||||
|
||||
|
||||
step_4_info() { echo "Create systemd service"; }
|
||||
step_4() {
|
||||
addConf -c "$toolServiceContent" "$toolServiceFile"
|
||||
|
||||
if [ $? -eq 0 ] ; then
|
||||
exe systemctl daemon-reload
|
||||
exe systemctl enable kodi.service
|
||||
saveReturn $?
|
||||
endReturn
|
||||
else
|
||||
echo "[ERROR] failed to setup systemd service"
|
||||
fi
|
||||
}
|
||||
|
||||
toolServiceContent="\
|
||||
[Unit]
|
||||
Description = Kodi Media Center
|
||||
|
||||
# if you don't need the MySQL DB backend, this should be sufficient
|
||||
After = systemd-user-sessions.service network.target sound.target
|
||||
|
||||
# if you need the MySQL DB backend, use this block instead of the previous
|
||||
# After = systemd-user-sessions.service network.target sound.target mysql.service
|
||||
# Wants = mysql.service
|
||||
|
||||
[Service]
|
||||
User = kodi
|
||||
Group = kodi
|
||||
Type = simple
|
||||
ExecStart = /usr/bin/kodi-standalone
|
||||
Restart = always
|
||||
RestartSec = 15
|
||||
|
||||
[Install]
|
||||
WantedBy = multi-user.target"
|
||||
|
||||
step_5_info() { echo "Enable text input for USB keyboards within $toolName"; }
|
||||
step_5() {
|
||||
local udevFile="/etc/udev/rules.d/99-kodi.rules"
|
||||
local inputRule="KERNEL==\"tty[0-9]*\", GROUP=\"tty\", MODE=\"0660\""
|
||||
|
||||
addConf -c "$inputRule" "$udevFile"
|
||||
}
|
||||
|
||||
step_6_info() { echo "Increase raspberry pi GPU memory to 320"; }
|
||||
step_6() {
|
||||
exep "grep -e '^[ ]*gpu_mem' \"$bootConfigLoc\" >>/dev/null 2>&1"
|
||||
if [ $? -ne 0 ] && [ -f "$bootConfigLoc" ] ; then
|
||||
# attach settings to raspberry boot configuration
|
||||
exe mount -o remount,rw /boot
|
||||
addConf -a "$bootConfig" "$bootConfigLoc"
|
||||
exe mount -o remount,ro /boot
|
||||
else
|
||||
# add to missing conf
|
||||
addConf -m "$bootConfig" "$bootConfigLoc"
|
||||
fi
|
||||
}
|
||||
|
||||
bootConfigLoc="/boot/config.txt"
|
||||
bootConfig="
|
||||
# Modifications for $toolName
|
||||
start_x=1
|
||||
gpu_mem=320"
|
||||
|
||||
step_7_info() { echo "Reboot is needed for all changes to take effect"; }
|
||||
step_7() {
|
||||
if [ $QUIET -eq "1" ] ; then
|
||||
answer=n
|
||||
else
|
||||
read -p "Reboot now? y/n(default)" answer
|
||||
fi
|
||||
case $answer in
|
||||
y|Y)
|
||||
exe reboot;;
|
||||
*)
|
||||
echo
|
||||
echo "Start $toolName manually:"
|
||||
echo "service kodi start"
|
||||
;;
|
||||
esac
|
||||
}
|
||||
|
||||
step_10_info() { echo "Send $toolName logs to syslog"; }
|
||||
step_10_alias() { ALIAS="syslog"; }
|
||||
step_10() {
|
||||
addConf -s "$kodiSyslog" "$kodiSyslogLoc"
|
||||
exe chmod -f +x "$kodiSyslogLoc"
|
||||
}
|
||||
kodiSyslogLoc="/usr/local/bin/kodisyslog"
|
||||
kodiSyslog="#!/bin/bash
|
||||
tail -f /home/kodi/.kodi/temp/kodi.log |
|
||||
while read -r line
|
||||
do
|
||||
logger -t KODI \"\${line:37}\"
|
||||
done"
|
||||
|
||||
step_11_info() { echo "Create systemd service for logging to syslog"; }
|
||||
step_11() {
|
||||
[ ! -f "$kodiSyslogLoc" ] && return 1
|
||||
|
||||
addConf -s "$kodiSyslogService" "$kodiSyslogServiceLoc"
|
||||
|
||||
echoseq " [I] Consider limiting systemd journal size"
|
||||
echoseq " [/etc/systemd/journald.conf]"
|
||||
echoseq " SystemMaxUse=50M"
|
||||
}
|
||||
kodiSyslogServiceLoc="/etc/systemd/system/kodisyslog.service"
|
||||
kodiSyslogService="[Unit]
|
||||
Description=Pipe kodi logs to syslog
|
||||
After=network.target syslog.service
|
||||
|
||||
[Service]
|
||||
User=root
|
||||
ExecStart=/usr/local/bin/kodisyslog
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target"
|
||||
|
||||
step_12_info() { echo "Enable and start kodisyslog service"; }
|
||||
step_12() {
|
||||
local kodiSyslogName="$(basename $kodiSyslogServiceLoc)"
|
||||
|
||||
exe systemctl daemon-reload
|
||||
exe systemctl enable $kodiSyslogName
|
||||
exe systemctl start $kodiSyslogName
|
||||
}
|
||||
|
||||
step_40_info() { echo "Reset music database"; }
|
||||
step_40_alias() { ALIAS="resetmusic"; }
|
||||
step_40() {
|
||||
local i
|
||||
local answer="y"
|
||||
local musicDb=( "$toolProfileDir/userdata/Database/MyMusic"*.db )
|
||||
echoseq " [W] Erasing:"
|
||||
for i in ${musicDb[@]}; do
|
||||
echoseq $i
|
||||
done
|
||||
[ $QUIET -eq 0 ] && read -p "Are you sure? (y)/[n] " answer
|
||||
case "$answer" in
|
||||
y|Y)
|
||||
exe rm ${musicDb[@]};;
|
||||
*)
|
||||
echoseq " [I] Abort reset"
|
||||
return 1;
|
||||
esac
|
||||
}
|
||||
|
||||
VERSION_SEQREV=12
|
||||
. /usr/local/bin/sequencer.sh
|
11
seqs/ldap.cfg.example
Normal file
11
seqs/ldap.cfg.example
Normal file
@@ -0,0 +1,11 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Configuration options for ldap installation and management
|
||||
|
||||
LDAP_DC="dc=winklerfamilie,dc=eu"
|
||||
LDAP_OU_GROUPS="ou=Groups"
|
||||
LDAP_OU_USERS="ou=Users"
|
||||
|
||||
LDAP_CERT="/etc/letsencrypt/live/winklerfamilie.eu/cert.pem"
|
||||
LDAP_CERT_KEY="/etc/letsencrypt/live/winklerfamilie.eu/privkey.pem"
|
||||
LDAP_CERT_CA="/etc/letsencrypt/live/winklerfamilie.eu/fullchain.pem"
|
368
seqs/ldap.sh
Executable file
368
seqs/ldap.sh
Executable file
@@ -0,0 +1,368 @@
|
||||
#!/bin/bash
|
||||
|
||||
toolName="ldap"
|
||||
toolDaemon="slapd"
|
||||
toolDeps="$toolDaemon ldap-utils"
|
||||
toolUser="openldap"
|
||||
|
||||
# Get script working directory
|
||||
# (when called from a different directory)
|
||||
WDIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >>/dev/null 2>&1 && pwd )"
|
||||
CONFIG=0
|
||||
CONFIG_FILE_NAME="${toolName}.cfg"
|
||||
CONFIG_FILE_TEMPLATE="$WDIR/${CONFIG_FILE_NAME}.example"
|
||||
|
||||
step_config() {
|
||||
initSeqConfig "$CONFIG_FILE_NAME" "$CONFIG_FILE_TEMPLATE"
|
||||
if [ $? -eq 0 ] ; then
|
||||
CONFIG=1
|
||||
fi
|
||||
}
|
||||
|
||||
step_1_info() { echo "$toolName installation"; }
|
||||
step_1_alias() { ALIAS="install"; }
|
||||
step_1() {
|
||||
exe apt update
|
||||
exe apt install $toolDeps
|
||||
}
|
||||
|
||||
step_2_info() { echo "Configuration of $toolName"; }
|
||||
step_2() {
|
||||
exe dpkg-reconfigure $toolDaemon
|
||||
}
|
||||
|
||||
step_3_info() { echo "Load memberof module"; }
|
||||
step_3() {
|
||||
local tempLdif=`eval "echo \"$loadMemberof\""`
|
||||
exep "echo \"$tempLdif\" | ldapmodify -Q -Y EXTERNAL -H ldapi:///"
|
||||
}
|
||||
loadMemberof="dn: cn=module{0},cn=config
|
||||
changetype: modify
|
||||
add: olcModuleLoad
|
||||
olcModuleLoad: memberof.la
|
||||
"
|
||||
|
||||
step_4_info() { echo "Configure memberof module"; }
|
||||
step_4() {
|
||||
local tempLdif=`eval "echo \"$configMemberof\""`
|
||||
exep "echo \"$tempLdif\" | ldapadd -Q -Y EXTERNAL -H ldapi:///"
|
||||
}
|
||||
configMemberof="dn: olcOverlay=memberof,olcDatabase={1}mdb,cn=config
|
||||
objectClass: olcOverlayConfig
|
||||
objectClass: olcMemberOf
|
||||
olcOverlay: memberof
|
||||
olcMemberOfRefint: TRUE
|
||||
-
|
||||
dn: olcDatabase={1}mdb,cn=config
|
||||
olcDbIndex: memberOf eq
|
||||
"
|
||||
|
||||
step_5_info() { echo "Load refint module"; }
|
||||
step_5() {
|
||||
local tempLdif=`eval "echo \"$loadRefint\""`
|
||||
exep "echo \"$tempLdif\" | ldapmodify -Q -Y EXTERNAL -H ldapi:///"
|
||||
}
|
||||
loadRefint="dn: cn=module{0},cn=config
|
||||
changetype: modify
|
||||
add: olcModuleLoad
|
||||
olcModuleLoad: refint.la
|
||||
"
|
||||
|
||||
step_6_info() { echo "Configure refint module"; }
|
||||
step_6() {
|
||||
local tempLdif=`eval "echo \"$configRefint\""`
|
||||
exep "echo \"$tempLdif\" | ldapadd -Q -Y EXTERNAL -H ldapi:///"
|
||||
}
|
||||
configRefint="dn: olcOverlay={1}refint,olcDatabase={1}mdb,cn=config
|
||||
objectClass: olcConfig
|
||||
objectClass: olcOverlayConfig
|
||||
objectClass: olcRefintConfig
|
||||
objectClass: top
|
||||
olcOverlay: {1}refint
|
||||
olcRefintAttribute: memberof member manager owner
|
||||
"
|
||||
|
||||
step_7_info() { echo "Create base DNs for users ($LDAP_OU_USERS) and groups ($LDAP_OU_GROUPS)"; }
|
||||
step_7() {
|
||||
variable2Ldif add "$ldapBase"
|
||||
}
|
||||
ldapBase="dn: \$LDAP_OU_USERS,\$LDAP_DC
|
||||
objectClass: organizationalUnit
|
||||
\${LDAP_OU_USERS/ou=/ou: }
|
||||
|
||||
dn: \$LDAP_OU_GROUPS,\$LDAP_DC
|
||||
objectClass: organizationalUnit
|
||||
\${LDAP_OU_GROUPS/ou=/ou: }
|
||||
"
|
||||
|
||||
step_8_info() { echo "Setup SSL secured ldaps:// access"; }
|
||||
step_8() {
|
||||
sudo -u $toolUser test -r "$LDAP_CERT_KEY" >>/dev/null 2>&1
|
||||
endReturn -o $? "$toolUser cannot access certificate key file: $LDAP_CERT_KEY"
|
||||
sudo -u $toolUser test -r "$LDAP_CERT" >>/dev/null 2>&1
|
||||
endReturn -o $? "$toolUser cannot access certificate file: $LDAP_CERT"
|
||||
sudo -u $toolUser test -r "$LDAP_CERT_CA" >>/dev/null 2>&1
|
||||
endReturn -o $? "$toolUser cannot access CA certificate file: $LDAP_CERT_CA"
|
||||
|
||||
local tempLdif=`eval "echo \"$sslSetup\""`
|
||||
exep "echo \"$tempLdif\" | ldapmodify -Y EXTERNAL -H ldapi:///"
|
||||
|
||||
exe service $toolDaemon restart
|
||||
}
|
||||
sslSetup="dn: cn=config
|
||||
changetype: modify
|
||||
replace: olcTLSCertificateKeyFile
|
||||
olcTLSCertificateKeyFile: \$LDAP_CERT_KEY
|
||||
-
|
||||
replace: olcTLSCertificateFile
|
||||
olcTLSCertificateFile: \$LDAP_CERT
|
||||
-
|
||||
replace: olcTLSCACertificateFile
|
||||
olcTLSCACertificateFile: \$LDAP_CERT_CA
|
||||
-
|
||||
replace: olcTLSVerifyClient
|
||||
olcTLSVerifyClient: never
|
||||
"
|
||||
step_9_info() { echo "Finalize SSL configuration (manually)"; }
|
||||
step_9() {
|
||||
echo "/etc/default/$toolDaemon"
|
||||
echo " Add \"ldaps:///\" to line:"
|
||||
echo " SLAPD_SERVICES=\"ldap:/// ldaps:/// ldapi:///\""
|
||||
echo
|
||||
}
|
||||
|
||||
step_20_info() { echo "Test plain ldap connection with anonymous access"; }
|
||||
step_20() {
|
||||
exe ldapwhoami -H ldapi:/// -x
|
||||
}
|
||||
|
||||
step_80_info() { echo -e "Some ldap command notes\n"; }
|
||||
step_80_alias() { ALIAS="notes"; }
|
||||
step_80() {
|
||||
outColor green
|
||||
cat <<NOTES_EOF
|
||||
# You can also check LDAP Base DN using the ldapsearch command as shown below
|
||||
ldapsearch -H ldapi:/// -x -LLL -s base -b "" namingContexts
|
||||
|
||||
# To view the RootDN, run the command below
|
||||
ldapsearch -H ldapi:/// -Y EXTERNAL -b "cn=config" "(olcRootDN=*)"
|
||||
|
||||
# Reset root password
|
||||
## Create a password hash {SSHA}....
|
||||
slappasswd
|
||||
|
||||
## Modify olcRootPW
|
||||
ldapmodify -Q -Y EXTERNAL -H ldapi:/// << E0F
|
||||
dn: olcDatabase={1}mdb,cn=config
|
||||
changetype: modify
|
||||
replace: olcRootPW
|
||||
olcRootPW: {SSHA}thehashyoucreatedabove
|
||||
E0F
|
||||
NOTES_EOF
|
||||
}
|
||||
|
||||
step_100_info() { echo "Add group <GROUP NAME> <USER ID>"; }
|
||||
step_100_alias() { ALIAS="addgroup"; }
|
||||
step_100() {
|
||||
shift
|
||||
local groupName=$1
|
||||
local memberDn="uid=$2,${LDAP_OU_USERS},${LDAP_DC}"
|
||||
|
||||
variable2Ldif add "$addGroup"
|
||||
}
|
||||
addGroup="dn: cn=\${groupName},\${LDAP_OU_GROUPS},\${LDAP_DC}
|
||||
objectClass: groupofnames
|
||||
cn: \${groupName}
|
||||
description: Created by $0
|
||||
member: \${memberDn}
|
||||
"
|
||||
|
||||
step_102_info() { echo "Add user <USER ID> <USER NAME> <USER LASTNAME> <UIDNUMBER> <USER EMAIL> [USER GID]"; }
|
||||
step_102_alias() { ALIAS="adduser"; }
|
||||
step_102() {
|
||||
shift
|
||||
userId="$1"
|
||||
local userCn="$2 $3"
|
||||
local givenName="$2"
|
||||
local userSn="$3"
|
||||
local uidNumber="$4"
|
||||
local userMail="$5"
|
||||
local userGid=10000
|
||||
if [ ! -z $6 ] ; then
|
||||
userGid="$6"
|
||||
fi
|
||||
|
||||
variable2Ldif add "$addUser"
|
||||
endReturn -o $? "Adding user failed"
|
||||
}
|
||||
userId=
|
||||
addUser="dn: uid=\$userId,\$LDAP_OU_USERS,\$LDAP_DC
|
||||
cn: \$userCn
|
||||
givenName: \$givenName
|
||||
sn: \$userSn
|
||||
uid: \$userId
|
||||
uidNumber: \$uidNumber
|
||||
gidNumber: \$userGid
|
||||
homeDirectory: /home/\$userId
|
||||
mail: \$userMail
|
||||
objectClass: top
|
||||
objectClass: posixAccount
|
||||
objectClass: shadowAccount
|
||||
objectClass: inetOrgPerson
|
||||
objectClass: organizationalPerson
|
||||
objectClass: person
|
||||
loginShell: /bin/bash
|
||||
"
|
||||
|
||||
step_103_info() { echo "(re)Set passwort for <USER>"; }
|
||||
step_103_alias() { ALIAS="passwd"; }
|
||||
step_103() {
|
||||
shift
|
||||
if [ ! -z $1 ] ; then
|
||||
echo " [I] Password operation for $1"
|
||||
userId="$1"
|
||||
elif [ ! -z $userId ] ; then
|
||||
echo " [I] Password operation for $userId"
|
||||
else
|
||||
echoerr " [E] No user id provided"
|
||||
return 1
|
||||
fi
|
||||
exe ldappasswd -H ldapi:/// -x -D "cn=admin,$LDAP_DC" -W -S "uid=$userId,$LDAP_OU_USERS,$LDAP_DC"
|
||||
}
|
||||
|
||||
step_105_info() { echo "Adding <USER ID> to existing group <GROUP NAME>"; }
|
||||
step_105_alias() { ALIAS="user2group"; }
|
||||
step_105() {
|
||||
shift
|
||||
if [ ! -z $1 ] ; then
|
||||
userId="$1"
|
||||
echo " [I] User operation for $userId"
|
||||
elif [ ! -z $userId ] ; then
|
||||
echo " [I] User operation for $userId"
|
||||
else
|
||||
echoerr " [E] No user id provided"
|
||||
return 1
|
||||
fi
|
||||
if [ -z $2 ] ; then
|
||||
echoerr " [E] No group name provided"
|
||||
return 2
|
||||
fi
|
||||
local groupName="$2"
|
||||
|
||||
variable2Ldif modify "$removeFromgroup"
|
||||
variable2Ldif modify "$add2group"
|
||||
endReturn -o $? "Adding user to group failed"
|
||||
}
|
||||
#remove empty member
|
||||
add2group="dn: cn=\$groupName,\$LDAP_OU_GROUPS,\$LDAP_DC
|
||||
changetype: modify
|
||||
add: member
|
||||
member: uid=\$userId,\$LDAP_OU_USERS,\$LDAP_DC
|
||||
|
||||
dn: cn=\$groupName,\$LDAP_OU_GROUPS,\$LDAP_DC
|
||||
changetype: modify
|
||||
delete: member
|
||||
member:
|
||||
"
|
||||
|
||||
step_107_info() { echo "Removing <USER ID> from existing group <GROUP NAME>"; }
|
||||
step_107_alias() { ALIAS="rmusergroup"; }
|
||||
step_107() {
|
||||
shift
|
||||
if [ ! -z $1 ] ; then
|
||||
userId="$1"
|
||||
echo " [I] User operation for $userId"
|
||||
elif [ ! -z $userId ] ; then
|
||||
echo " [I] User operation for $userId"
|
||||
else
|
||||
echoerr " [E] No user id provided"
|
||||
return 1
|
||||
fi
|
||||
if [ -z $2 ] ; then
|
||||
echoerr " [E] No group name provided"
|
||||
return 2
|
||||
fi
|
||||
local groupName="$2"
|
||||
|
||||
variable2Ldif modify "$removeFromgroup"
|
||||
}
|
||||
# try to delete user entry first to ensure correct memberof status
|
||||
# make sure an empty member entry exists
|
||||
removeFromgroup="dn: cn=\$groupName,\$LDAP_OU_GROUPS,\$LDAP_DC
|
||||
changetype: modify
|
||||
add: member
|
||||
member:
|
||||
|
||||
dn: cn=\$groupName,\$LDAP_OU_GROUPS,\$LDAP_DC
|
||||
changetype: modify
|
||||
delete: member
|
||||
member: uid=\$userId,\$LDAP_OU_USERS,\$LDAP_DC
|
||||
"
|
||||
|
||||
step_110_info() { echo "Remove group <GROUP NAME>"; }
|
||||
step_110_alias() { ALIAS="rmgroup"; }
|
||||
step_110() {
|
||||
shift
|
||||
if [ -z $1 ] ; then
|
||||
echoerr " [E] No group name provided"
|
||||
return 1
|
||||
fi
|
||||
local groupName=$1
|
||||
variable2Ldif modify "$rmGroup"
|
||||
}
|
||||
rmGroup="dn: cn=\${groupName},\${LDAP_OU_GROUPS},\${LDAP_DC}
|
||||
changetype: delete
|
||||
"
|
||||
|
||||
step_112_info() { echo "Remove user <USER ID>"; }
|
||||
step_112_alias() { ALIAS="rmuser"; }
|
||||
step_112() {
|
||||
shift
|
||||
if [ -z $1 ] ; then
|
||||
echoerr " [E] No user id provided"
|
||||
return 1
|
||||
fi
|
||||
local userName=$1
|
||||
variable2Ldif modify "$rmUser"
|
||||
}
|
||||
rmUser="dn: uid=\${userName},\${LDAP_OU_USERS},\${LDAP_DC}
|
||||
changetype: delete
|
||||
"
|
||||
|
||||
step_200_info() { echo "List available groups <ADDITONAL ATTRIBUTES...>"; }
|
||||
step_200_alias() { ALIAS="listgroups"; }
|
||||
step_200() {
|
||||
shift
|
||||
echo " [I] Available groups:"
|
||||
exe ldapsearch -x -LLL -H ldap:/// -b ${LDAP_OU_GROUPS},${LDAP_DC} dn gidNumber $*
|
||||
}
|
||||
|
||||
step_202_info() { echo "List available users <ADDITONAL ATTRIBUTES...>"; }
|
||||
step_202_alias() { ALIAS="listusers"; }
|
||||
step_202() {
|
||||
shift
|
||||
echo " [I] Available user:"
|
||||
exe ldapsearch -x -LLL -H ldap:/// -b ${LDAP_OU_USERS},${LDAP_DC} dn uidNumber gidNumber $*
|
||||
}
|
||||
|
||||
|
||||
variable2Ldif() {
|
||||
local cmd="ldapmodify"
|
||||
local tempLdif=`eval "echo \"$2\""`
|
||||
case $1 in
|
||||
add)
|
||||
cmd="ldapadd"
|
||||
;;
|
||||
delete)
|
||||
cmd="ldapdelete"
|
||||
;;
|
||||
esac
|
||||
exep "echo \"$tempLdif\" | $cmd -x -D cn=admin,${LDAP_DC} -W"
|
||||
}
|
||||
variable2LdifEcho() {
|
||||
local tempLdif=`eval "echo \"$2\""`
|
||||
echo "$tempLdif"
|
||||
}
|
||||
|
||||
VERSION_SEQREV=10
|
||||
. /usr/local/bin/sequencer.sh
|
5
seqs/librenms.cfg.example
Normal file
5
seqs/librenms.cfg.example
Normal file
@@ -0,0 +1,5 @@
|
||||
#!/bin/bash
|
||||
|
||||
LNMS_DIR="/opt/librenms"
|
||||
LNMS_BU_DIR="/root/backup/librenms"
|
||||
LNMS_DB_NAME="librenms_db"
|
333
seqs/librenms.sh
333
seqs/librenms.sh
@@ -2,141 +2,278 @@
|
||||
|
||||
#
|
||||
## Installation and maintenance for LibreNMS
|
||||
## Using buster repositories for php 7.3 installation
|
||||
|
||||
toolName="LibreNMS"
|
||||
librePhpDeps="composer php-cli-prompt php-composer-ca-bundle php-composer-semver php-composer-spdx-licenses php-json-schema php-psr-log php-symfony-console php-symfony-filesystem php-symfony-finder php-symfony-polyfill-mbstring php-symfony-process"
|
||||
librePackages="fping git graphviz imagemagick mtr-tiny nmap python-memcache python-mysqldb rrdtool snmp snmpd whoisi nagios-plugins"
|
||||
toolName="librenms"
|
||||
toolUser="librenms"
|
||||
phpVersion=
|
||||
|
||||
libreDeps='acl curl composer fping git graphviz imagemagick mtr-tiny nmap rrdtool snmp snmpd whois python3-dotenv python3-pymysql python3-redis python3-setuptools'
|
||||
|
||||
librePhpDeps='php${phpVersion}-cli php${phpVersion}-curl php${phpVersion}-fpm php${phpVersion}-gd php${phpVersion}-json php${phpVersion}-mbstring php${phpVersion}-mysql php${phpVersion}-snmp php${phpVersion}-xml php${phpVersion}-zip'
|
||||
|
||||
#librePhpDeps="composer php-cli-prompt php-composer-ca-bundle php-composer-semver php-composer-spdx-licenses php-json-schema php-psr-log php-symfony-console php-symfony-filesystem php-symfony-finder php-symfony-polyfill-mbstring php-symfony-process"
|
||||
#librePackages="fping git graphviz imagemagick mtr-tiny nmap python-memcache python-mysqldb rrdtool snmp snmpd whoisi nagios-plugins"
|
||||
|
||||
# Get script working directory
|
||||
# (when called from a different directory)
|
||||
WDIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" >>/dev/null 2>&1 && pwd )"
|
||||
CONFIG=0
|
||||
SCRIPT_NAME=$(basename -- "$0")
|
||||
SCRIPT_NAME=${SCRIPT_NAME%%.*}
|
||||
CONFIG_FILE_NAME="${SCRIPT_NAME}.cfg"
|
||||
CONFIG_FILE_TEMPLATE="$WDIR/${CONFIG_FILE_NAME}.example"
|
||||
|
||||
step_config() {
|
||||
initSeqConfig "$CONFIG_FILE_NAME" "$CONFIG_FILE_TEMPLATE"
|
||||
if [ $? -eq 0 ] ; then
|
||||
CONFIG=1
|
||||
echoseq " Install: $LNMS_DIR"
|
||||
echoseq " Backup: $LNMS_BU_DIR"
|
||||
else
|
||||
[ $DRY -eq 0 ] && return 1
|
||||
fi
|
||||
}
|
||||
|
||||
step_1_info() { echo "Updating apt"; }
|
||||
step_1_alias() { ALIAS="install"; }
|
||||
step_1() {
|
||||
apt update
|
||||
exe apt update
|
||||
}
|
||||
|
||||
step_2_info() { echo -e "Installing $toolname dependencies: $librePackages\n"; }
|
||||
step_2_info() {
|
||||
echo "Installing $toolname dependencies:"
|
||||
echoinfo "$libreDeps"
|
||||
}
|
||||
step_2() {
|
||||
apt install $librePackages
|
||||
saveReturn $?
|
||||
endReturn
|
||||
exe apt install $libreDeps
|
||||
endReturn -o $? "Failed to install $toolName dependencies"
|
||||
}
|
||||
|
||||
step_3_info() { echo -e "Installing -t buster PHP related packages\n$librePhpDeps\n"; }
|
||||
step_3_info() {
|
||||
echo "Installing PHP related packages:"
|
||||
fetchPhpVersion
|
||||
echoinfo `eval echo "$librePhpDeps"`
|
||||
}
|
||||
step_3() {
|
||||
apt -t buster install $librePhpDeps
|
||||
saveReturn $?
|
||||
endReturn
|
||||
fetchPhpVersion
|
||||
exe apt install `eval echo "$librePhpDeps"`
|
||||
endReturn -o $? "Failed to install $toolName php dependencies"
|
||||
}
|
||||
|
||||
step_4_info() { echo "Adding $toolName user (librenms:librenms)"; }
|
||||
step_4_info() { echo "Adding $toolName user ($toolUser)"; }
|
||||
step_4() {
|
||||
useradd librenms -d /opt/librenms -M -r
|
||||
exe useradd $toolUser -d "$LNMS_DIR" -M -r -s "$(which bash)"
|
||||
saveReturn $?
|
||||
usermod -a -G librenms www-data
|
||||
saveReturn $?
|
||||
endReturn
|
||||
#exe usermod -a -G librenms www-data
|
||||
#saveReturn $?
|
||||
endReturn "Failed to create user $toolUser"
|
||||
}
|
||||
|
||||
step_5_info() { echo "Installing $toolName using composer"; }
|
||||
step_5_info() { echo "Clone $toolName git repository"; }
|
||||
step_5() {
|
||||
cd /opt
|
||||
composer create-project --no-dev --keep-vcs librenms/librenms librenms dev-master
|
||||
saveReturn $?
|
||||
endReturn
|
||||
exe git clone https://github.com/librenms/librenms.git "$LNMS_DIR"
|
||||
# set permissions
|
||||
step fix
|
||||
}
|
||||
|
||||
step_6_info() { echo "Installing $toolName using composer"; }
|
||||
step_6() {
|
||||
exe sudo -u librenms "${LNMS_DIR}/scripts/composer_wrapper.php" install --no-dev
|
||||
endReturn -o $? "Failed to install php dependencies"
|
||||
}
|
||||
|
||||
step_10_info() { echo "Create mysql database for $toolName"; }
|
||||
step_10() {
|
||||
local mysqlDatabase
|
||||
local mysqlUser
|
||||
local mysqlPass
|
||||
|
||||
echo "Existing mysql databases:"
|
||||
mysql -u root -e 'SHOW DATABASES;'
|
||||
|
||||
echo -en "Enter database name: "
|
||||
read mysqlDatabase
|
||||
endCheckEmpty mysqlDatabase "database name"
|
||||
mysql -u root -e 'CREATE DATABASE '$mysqlDatabase' CHARACTER SET utf8 COLLATE utf8_unicode_ci;'
|
||||
saveReturn $?
|
||||
endReturn
|
||||
|
||||
echo "Existing mysql user:"
|
||||
mysql -u root -e 'SELECT User, Host FROM mysql.user;'
|
||||
echo -en "Enter mysql user name: "
|
||||
read mysqlUser
|
||||
endCheckEmpty mysqlDatabase "user name"
|
||||
|
||||
echo -en "Enter mysql user password: "
|
||||
read mysqlPass
|
||||
endCheckEmpty mysqlPass "password"
|
||||
mysql -u root -e 'CREATE USER '"'"$mysqlUser"'"'@'"'"'localhost'"'"' IDENTIFIED BY '"'"$mysqlPass"'"';'
|
||||
saveReturn $?
|
||||
endReturn
|
||||
|
||||
mysql -u root -e 'GRANT ALL PRIVILEGES ON '$mysqlDatabase'.* TO '"'"$mysqlUser"'"'@'"'"'localhost'"'"';'
|
||||
saveReturn $?
|
||||
endReturn
|
||||
|
||||
mysql -u root -e 'FLUSH PRIVILEGES;'
|
||||
local libreDbOpt=
|
||||
if [ ! -z "$LNMS_DB_NAME" ] ; then
|
||||
libreDbOpt="-d $LNMS_DB_NAME"
|
||||
fi
|
||||
exe ${WDIR}/mysql.sh -q createdb --charset utf8 $libreDbOpt
|
||||
endReturn -o $? "Failed to create mysql database $LNMS_DB_NAME"
|
||||
}
|
||||
|
||||
step_11_info() { echo "MariaDB configuration"; }
|
||||
step_11() {
|
||||
echo
|
||||
echo "Edit or create /etc/mysql/mariadb.conf.d/90-myconfig.cnf and add:"
|
||||
echo
|
||||
echo "------------------------"
|
||||
echo "[mysqld]"
|
||||
echo "innodb_file_per_table=1"
|
||||
echo "lower_case_table_names=0"
|
||||
echo "------------------------"
|
||||
echo
|
||||
echo "Restart mysql afterwards:"
|
||||
echo "service mysql restart"
|
||||
outColor green
|
||||
cat << SQLCONF_END
|
||||
|
||||
Edit or create /etc/mysql/mariadb.conf.d/90-myconfig.cnf and add:
|
||||
|
||||
------------------------
|
||||
[mysqld]
|
||||
innodb_file_per_table=1
|
||||
lower_case_table_names=0
|
||||
------------------------
|
||||
|
||||
Restart mysql afterwards:
|
||||
service mysql restart
|
||||
SQLCONF_END
|
||||
}
|
||||
|
||||
step_12_info() { echo "PHP fpm/cli configuration"; }
|
||||
step_12_info() { echo "PHP fpm/cli timezone configuration"; }
|
||||
step_12() {
|
||||
echo
|
||||
echo "Ensure date.timezone is set in php.ini to your preferred time zone. See http://php.net/manual/en/timezones.php for a list of supported timezones. Valid examples are: \"America/New_York\", \"Europe/Berlin\", \"Etc/UTC\"."
|
||||
echo
|
||||
echo "vi /etc/php/7.3/fpm/conf.d/90-custom_pi.ini"
|
||||
echo "vi /etc/php/7.3/cli/php.ini"
|
||||
echo
|
||||
echo "-------------------------------------------"
|
||||
echo "date.timezone = Europe/Berlin"
|
||||
echo "-------------------------------------------"
|
||||
echo
|
||||
echo "Restart php-fpm afterwards:"
|
||||
echo "service php7.3-fpm restart"
|
||||
outColor green
|
||||
cat << PHPCONF_END
|
||||
|
||||
Ensure date.timezone is set in php.ini to your preferred time zone. See http://php.net/manual/en/timezones.php for a list of supported timezones. Valid examples are: "America/New_York", "Europe/Berlin", "Etc/UTC".
|
||||
|
||||
vi /etc/php/7.3/fpm/conf.d/90-custom_pi.ini
|
||||
vi /etc/php/7.3/cli/conf.d/90-custom_pi.ini
|
||||
|
||||
-------------------------------------------
|
||||
date.timezone = Europe/Berlin
|
||||
-------------------------------------------
|
||||
|
||||
Restart php-fpm afterwards:
|
||||
service php7.3-fpm restart
|
||||
PHPCONF_END
|
||||
}
|
||||
|
||||
step_13_info() { echo "PHP fpm configuration"; }
|
||||
step_13() {
|
||||
outColor green
|
||||
cat << FPMCONF_END
|
||||
|
||||
cp /etc/php/7.3/fpm/pool.d/www.conf /etc/php/7.3/fpm/pool.d/librenms.conf
|
||||
vi /etc/php/7.3/fpm/pool.d/librenms.conf
|
||||
|
||||
# Change [www] to [librenms]:
|
||||
|
||||
[librenms]
|
||||
|
||||
# Change user and group to "librenms":
|
||||
|
||||
user = librenms
|
||||
group = librenms
|
||||
|
||||
# Change listen to a unique name:
|
||||
|
||||
listen = /run/php-fpm-librenms.sock
|
||||
FPMCONF_END
|
||||
}
|
||||
|
||||
step_14_info() { echo "Nginx configuration"; }
|
||||
step_14() {
|
||||
outColor green
|
||||
cat << NGINXCONF_END
|
||||
|
||||
server {
|
||||
listen 80;
|
||||
server_name librenms.example.com;
|
||||
root $LNMS_DIR/html;
|
||||
index index.php;
|
||||
|
||||
charset utf-8;
|
||||
gzip on;
|
||||
gzip_types text/css application/javascript text/javascript application/x-javascript image/svg+xml text/plain text/xsd text/xsl text/xml image/x-icon;
|
||||
location / {
|
||||
try_files \$uri \$uri/ /index.php?\$query_string;
|
||||
}
|
||||
location ~ [^/]\\.php(/|$) {
|
||||
fastcgi_pass unix:/run/php-fpm-librenms.sock;
|
||||
fastcgi_split_path_info ^(.+\\.php)(/.+)$;
|
||||
include fastcgi.conf;
|
||||
}
|
||||
location ~ /\\.(?!well-known).* {
|
||||
deny all;
|
||||
}
|
||||
}
|
||||
NGINXCONF_END
|
||||
}
|
||||
|
||||
step_20_info() { echo "Create $toolName cron job"; }
|
||||
step_20_alias() { ALIAS="cron"; }
|
||||
step_20() {
|
||||
echoseq -n " [I] Creating $lnmsCronLoc ... "
|
||||
exe cp "${LNMS_DIR}/librenms.nonroot.cron" "$lnmsCronLoc" && echoseq "Ok" || echoseq "Nok"
|
||||
}
|
||||
lnmsCronLoc="/etc/cron.d/librenms"
|
||||
|
||||
step_22_info() { echo "Enable lnms command completion"; }
|
||||
step_22_alias() { ALIAS="cmdcompletion"; }
|
||||
step_22() {
|
||||
exep 'echo -e "#!/bin/bash\nsudo -u '$toolUser' \"'$LNMS_DIR'/lnms\" \"\$@\"" > '"$lnmsLocalBin"
|
||||
exe chmod 744 "$lnmsLocalBin"
|
||||
exe cp "${LNMS_DIR}/misc/lnms-completion.bash" /etc/bash_completion.d/
|
||||
}
|
||||
lnmsLocalBin="/usr/local/bin/lnms"
|
||||
|
||||
step_24_info() { echo "Copy logrotate config"; }
|
||||
step_24_alias() { ALIAS="logrotate"; }
|
||||
step_24() {
|
||||
echoseq -n " [I] Creating $lnmsLogrotLoc ... "
|
||||
exe cp "${LNMS_DIR}/misc/librenms.logrotate" "$lnmsLogrotLoc" && echoseq "Ok" || echoseq "Nok"
|
||||
}
|
||||
lnmsLogrotLoc="/etc/logrotate.d/librenms"
|
||||
|
||||
step_26_info() { echo "Install nagios plugin to enable services"; }
|
||||
step_26_alias() { ALIAS="services"; }
|
||||
step_26() {
|
||||
exe apt install monitoring-plugins
|
||||
echoseq
|
||||
echoseq " [$LNMS_DIR/config.php]"
|
||||
echoseq "\$config['show_services'] = 1;"
|
||||
echoseq
|
||||
echoseq " [/etc/cron.d/librenms]"
|
||||
echoseq " */5 * * * * librenms /opt/librenms/services-wrapper.py 1"
|
||||
}
|
||||
|
||||
step_30_info() { echo "Backup ${toolName} web direcotry"; }
|
||||
step_30_alias() { ALIAS="backup"; }
|
||||
step_30() {
|
||||
echoseq " [I] Backup install directory to ${LNMS_BU_DIR}"
|
||||
exe mkdir -p "$LNMS_BU_DIR"
|
||||
exep "cd \"${LNMS_DIR}\"/.. && tar czf \"${LNMS_BU_DIR}/\`date +%Y%m%d\`_${toolName}_web.tar.gz\" \"$(basename "$LNMS_DIR")\""
|
||||
}
|
||||
|
||||
step_31_info() { echo "Backup ${toolName} database [daily|monthly(default)]"; }
|
||||
step_31_alias() { ALIAS="backupdb"; }
|
||||
step_31() {
|
||||
case "$2" in
|
||||
daily|Daily|DAILY)
|
||||
echoseq " [I] Daily backup..."
|
||||
exep "mysqldump --single-transaction -u root ${LNMS_DB_NAME} | bzip2 -c > \"${LNMS_BU_DIR}/${toolName}_daily.sql.bz2\""
|
||||
;;
|
||||
*)
|
||||
exe mkdir -p "$LNMS_BU_DIR/monthly"
|
||||
echoseq " [I] Monthly backup..."
|
||||
exep "mysqldump --single-transaction -u root ${LNMS_DB_NAME} | bzip2 -c > \"${LNMS_BU_DIR}/monthly/\`date +%Y%m%d\`_${toolName}.sql.bz2\""
|
||||
;;
|
||||
esac
|
||||
}
|
||||
|
||||
step_40_info() { echo "Switch $toolName installation to monthly stable"; }
|
||||
step_40() {
|
||||
echo
|
||||
echo "Add following to /opt/librenms/config.php"
|
||||
echo
|
||||
echo "--------------------------------------"
|
||||
echo "\$config['update_channel'] = 'release';"
|
||||
echo "--------------------------------------"
|
||||
echo
|
||||
echo "Execute following command afterwards:"
|
||||
echo "cd /opt/librenms && git fetch --tags && git checkout \$(git describe --tags \$(git rev-list --tags --max-count=1))"
|
||||
cat << STABLE_EOF
|
||||
|
||||
Add following to ${LNMS_DIR}/config.php
|
||||
|
||||
--------------------------------------
|
||||
\$config['update_channel'] = 'release';
|
||||
--------------------------------------
|
||||
|
||||
Execute following command afterwards:
|
||||
cd $LNMS_DIR && git fetch --tags && git checkout \$(git describe --tags \$(git rev-list --tags --max-count=1))
|
||||
STABLE_EOF
|
||||
}
|
||||
|
||||
step_42_info() { echo "Fix librenms permission"; }
|
||||
step_42_alias() { ALIAS="fix"; }
|
||||
step_42() {
|
||||
chown -R librenms:librenms /opt/librenms
|
||||
setfacl -d -m g::rwx /opt/librenms/bootstrap/cache /opt/librenms/storage /opt/librenms/logs /opt/librenms/rrd
|
||||
chmod -R ug=rwX /opt/librenms/bootstrap/cache /opt/librenms/storage /opt/librenms/logs /opt/librenms/rrd
|
||||
exe chown -R ${toolUser}: "$LNMS_DIR"
|
||||
exe chmod 771 "${LNMS_DIR}"
|
||||
exe setfacl -d -m g::rwx "${LNMS_DIR}/rrd" "${LNMS_DIR}/logs" "${LNMS_DIR}/bootstrap/cache/" "${LNMS_DIR}/storage/"
|
||||
exe setfacl -R -m g::rwx "${LNMS_DIR}/rrd" "${LNMS_DIR}/logs" "${LNMS_DIR}/bootstrap/cache/" "${LNMS_DIR}/storage/"
|
||||
}
|
||||
|
||||
fetchPhpVersion() {
|
||||
if [ ! -z $phpVersion ] ; then
|
||||
return 0
|
||||
fi
|
||||
|
||||
phpVersion="$(php -r 'echo PHP_MAJOR_VERSION.".".PHP_MINOR_VERSION;')"
|
||||
}
|
||||
|
||||
# Sequence Revision
|
||||
VERSION_SEQREV=1
|
||||
|
||||
# Workaround when called from different directory
|
||||
# Not needed when path to sequencer is absolut
|
||||
DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >>/dev/null 2>&1 && pwd )"
|
||||
# Path to sequencer
|
||||
. ${DIR}/../sequencer/sequencer.sh
|
||||
VERSION_SEQREV=12
|
||||
. /usr/local/bin/sequencer.sh
|
||||
|
21
seqs/mailserver.cfg.example
Normal file
21
seqs/mailserver.cfg.example
Normal file
@@ -0,0 +1,21 @@
|
||||
#!/bin/bash
|
||||
|
||||
# MAS = Mail Server
|
||||
|
||||
MAS_DOMAIN="mydomain.com"
|
||||
MAS_RELAYHOST=
|
||||
MAS_RELAYUSER=
|
||||
MAS_RELAYPASS=
|
||||
|
||||
MAS_DBUSER='pfa'
|
||||
MAS_DBPASS='pass'
|
||||
MAS_DBNAME='pfa_db'
|
||||
MAS_mysql_virtual_domains_maps="user = '\$MAS_DBUSER'
|
||||
password = '\$MAS_DBPASS'
|
||||
hosts = localhost
|
||||
dbname = '\$MAS_DBNAME'
|
||||
query = SELECT domain FROM domain WHERE domain='%s' AND active = '1'
|
||||
#query = SELECT domain FROM domain WHERE domain='%s'
|
||||
#optional query to use when relaying for backup MX
|
||||
#query = SELECT domain FROM domain WHERE domain='%s' AND backupmx = '0' AND active = '1'
|
||||
#expansion_limit = 100"
|
466
seqs/mailserver.sh
Executable file
466
seqs/mailserver.sh
Executable file
@@ -0,0 +1,466 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Installing a mailserver including postfix postfixadmin and dovecot
|
||||
#
|
||||
# MTA = Mail Transport Agent (postfix)
|
||||
# MDA = Mail Delivery Agent (dovecot)
|
||||
# MUA = Mail User Agent (Mail program used by the user)
|
||||
|
||||
toolName=mailserver
|
||||
mtaName=postfix
|
||||
mtaUser=postfix
|
||||
mtaDeps="$mtaName $mtaName-mysql"
|
||||
mtaConfLoc="/etc/$mtaName"
|
||||
mtaMysqlConfLoc="$mtaConfLoc/sql"
|
||||
mdaName=dovecot
|
||||
mdaConfLoc="/etc/$mdaName"
|
||||
mdaConfDir="$mdaConfLoc/conf.d"
|
||||
mdaDeps="dovecot-imapd dovecot-lmtpd dovecot-mysql dovecot-managesieved dovecot-sieve"
|
||||
|
||||
# Get script working directory
|
||||
# (when called from a different directory)
|
||||
WDIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >>/dev/null 2>&1 && pwd )"
|
||||
CONFIG=0
|
||||
CONFIG_FILE_NAME="${toolName}.cfg"
|
||||
CONFIG_FILE_TEMPLATE="$WDIR/${CONFIG_FILE_NAME}.example"
|
||||
|
||||
step_config() {
|
||||
if [ $(id -u) -ne 0 ] ; then
|
||||
endReturn -o 1 "No root"
|
||||
fi
|
||||
initSeqConfig "$CONFIG_FILE_NAME" "$CONFIG_FILE_TEMPLATE"
|
||||
if [ $? -eq 0 ] ; then
|
||||
CONFIG=1
|
||||
echoseq " Domain: $MAS_DOMAIN"
|
||||
elif [ $? -eq 1 ] ; then
|
||||
# Config $CONFIG_FILE_NAME created. Needs modification first
|
||||
[ $DRY -eq 0 ] && return -1
|
||||
fi
|
||||
return 0
|
||||
}
|
||||
|
||||
step_1_info() { echo "Update apt repositories"; }
|
||||
step_1_alias() { ALIAS="install"; }
|
||||
step_1() {
|
||||
exe apt update
|
||||
}
|
||||
|
||||
step_2_info() { echo "Install $mtaName"; }
|
||||
step_2() {
|
||||
local aptOpt=
|
||||
if [ $QUIET -ne 0 ];then
|
||||
aptOpt="-y"
|
||||
else
|
||||
read -p "In the following dialog chose \"Internet site\" and enter $MAS_DOMAIN as your domain. Enter to continue..."
|
||||
fi
|
||||
exe apt install $mtaDeps $aptOpt
|
||||
}
|
||||
|
||||
step_3_info() { echo "Enable $mtaName"; }
|
||||
step_3() {
|
||||
exe systemctl enable $mtaName
|
||||
echo -e " [I] Printing $mtaName status\n"
|
||||
exe service $mtaName status
|
||||
echo -e "\n [I] Installed postfix version: $(postconf mail_version)"
|
||||
}
|
||||
|
||||
step_4_info() { echo "$mtaName basic domain configuration"; }
|
||||
step_4() {
|
||||
exe postconf -e "myhostname = mail.$MAS_DOMAIN"
|
||||
exe postconf -e "mydomain = $MAS_DOMAIN"
|
||||
exe postconf -e "myorigin = $MAS_DOMAIN"
|
||||
exe postconf -e "mydestination = $MAS_DOMAIN, \$myhostname, mail.\$mydomain, localhost.\$mydomain, localhost"
|
||||
}
|
||||
|
||||
step_5_info() { echo "$mtaName enable submission service"; }
|
||||
step_5() {
|
||||
echoseq -e " [I] Copy following lines...\n"
|
||||
exe cat "$mtaConfSubmission"
|
||||
exe read -rep $'\nPress Enter to open the '$mtaConfLoc'/master.cf'
|
||||
exe vi $mtaConfLoc/master.cf
|
||||
exe echoseq
|
||||
exe cat "$mtaConfSmtps"
|
||||
exe read -rep $'\nPress Enter to open the '$mtaConfLoc'/master.cf'
|
||||
exe vi $mtaConfLoc/master.cf
|
||||
}
|
||||
mtaConfSubmission="$WDIR/$toolName/submissionService"
|
||||
mtaConfSmtps="$WDIR/$toolName/smtpsService"
|
||||
|
||||
step_6_info() { echo "Configure TLS"; }
|
||||
step_6() {
|
||||
exe postconf "smtpd_tls_cert_file = /etc/letsencrypt/live/$MAS_DOMAIN/fullchain.pem"
|
||||
exe postconf "smtpd_tls_key_file = /etc/letsencrypt/live/$MAS_DOMAIN/privkey.pem"
|
||||
|
||||
#Force TLSv1.3 or TLSv1.2
|
||||
exe postconf "smtpd_tls_mandatory_protocols = !SSLv2, !SSLv3, !TLSv1, !TLSv1.1"
|
||||
exe postconf "smtpd_tls_protocols = !SSLv2, !SSLv3, !TLSv1, !TLSv1.1"
|
||||
exe postconf "smtp_tls_mandatory_protocols = !SSLv2, !SSLv3, !TLSv1, !TLSv1.1"
|
||||
exe postconf "smtp_tls_protocols = !SSLv2, !SSLv3, !TLSv1, !TLSv1.1"
|
||||
|
||||
echoseq " [I] Restarting $mtaName"
|
||||
exe service $mtaName restart
|
||||
}
|
||||
|
||||
step_7_info() {
|
||||
echo "Restrict client access"
|
||||
echoinfo "Mainly PTR record check"
|
||||
}
|
||||
step_7() {
|
||||
exe postconf -e "smtpd_client_restrictions = permit_mynetworks, reject_unknown_client_hostname"
|
||||
}
|
||||
|
||||
step_8_info() { echo "Install $mdaName"; }
|
||||
step_8() {
|
||||
exe apt install $mdaDeps
|
||||
echoseq -e "\n [I] Installed version: $(dovecot --version)"
|
||||
}
|
||||
|
||||
step_9_info() {
|
||||
echo "Configure $mdaName"
|
||||
}
|
||||
step_9() {
|
||||
outColor green
|
||||
cat <<MDA_EOF
|
||||
# Configuring Mailbox Location
|
||||
[/etc/dovecot/conf.d/10-mail.conf]
|
||||
mail_location = maildir:~/Maildir
|
||||
mail_privileged_group = mail
|
||||
|
||||
usermod -aG mail dovecot
|
||||
|
||||
# Configuring Authentication Mechanism
|
||||
[/etc/dovecot/conf.d/10-auth.conf]
|
||||
disable_plaintext_auth = yes
|
||||
# Login with full mail address
|
||||
auth_username_format = %n
|
||||
# "login" to support older mail clients
|
||||
auth_mechanisms = plain login
|
||||
|
||||
# Configure SSL/TLS Encryption
|
||||
[/etc/dovecot/conf.d/10-ssl.conf]
|
||||
ssl = required
|
||||
ssl_cert = </etc/letsencrypt/live/$MAS_DOMAIN/fullchain.pem
|
||||
ssl_key = </etc/letsencrypt/live/$MAS_DOMAIN/privkey.pem
|
||||
ssl_min_protocol = TLSv1.2
|
||||
ssl_prefer_server_ciphers = yes
|
||||
ssl_dh = </etc/dovecot/dh.pem
|
||||
|
||||
openssl dhparam -out /etc/dovecot/dh.pem 4096
|
||||
|
||||
# SASL Authentication Between Postfix and Dovecot
|
||||
[/etc/dovecot/conf.d/10-master.conf]
|
||||
# Add to service auth {
|
||||
service auth {
|
||||
unix_listener /var/spool/postfix/private/auth {
|
||||
mode = 0600
|
||||
user = postfix
|
||||
group = postfix
|
||||
}
|
||||
}
|
||||
|
||||
# Auto-subscribe Drafts, Sent, Junk and Trash Folder
|
||||
and auto delete after 30 days
|
||||
[/etc/dovecot/conf.d/15-mailboxes.conf]
|
||||
# Add "auto = create" to folder e.g.:
|
||||
mailbox Trash {
|
||||
auto = subscribe
|
||||
autoexpunge = 30d
|
||||
special_use = \\Trash
|
||||
}
|
||||
|
||||
# Using Dovecot to Deliver Email to Message Store
|
||||
Make sure lmtp protocol is installed with dovecot-lmtp
|
||||
[/etc/dovecot/conf.d/10-master.conf]
|
||||
# Change lmtp service definition to:
|
||||
service lmtp {
|
||||
unix_listener /var/spool/postfix/private/dovecot-lmtp {
|
||||
mode = 0600
|
||||
user = postfix
|
||||
group = postfix
|
||||
}
|
||||
}
|
||||
|
||||
postconf -e "mailbox_transport = lmtp:unix:private/dovecot-lmtp"
|
||||
postconf -e "smtputf8_enable = no"
|
||||
|
||||
# Clean outgoing mail header from sensitiv information
|
||||
[/etc/postfix/master.cf]
|
||||
smtps inet n - y - - smtpd
|
||||
[...]
|
||||
-o cleanup_service_name=headclean
|
||||
#add below "cleanup"
|
||||
headclean unix n - - - 0 cleanup
|
||||
-o header_checks=regexp:/etc/postfix/sender_header_checks
|
||||
|
||||
[/etc/postfix/sender_header_checks]
|
||||
/^Received:/ IGNORE
|
||||
/^X-PHP-Originating-Script:/ IGNORE
|
||||
/^X-Originating-IP:/ IGNORE
|
||||
/^X-Mailer:/ IGNORE
|
||||
/^User-Agent:/ IGNORE
|
||||
MDA_EOF
|
||||
}
|
||||
|
||||
step_20_info() {
|
||||
echo "Install postfixadmin and create mysql database"
|
||||
echoinfo "Virtualize mailboxes, domains and aliases by using a mysql database"
|
||||
}
|
||||
step_20_alias() { ALIAS="virtual"; }
|
||||
step_20() {
|
||||
local qOpt=
|
||||
if [ $QUIET -ne 0 ] ; then
|
||||
qOpt="-q"
|
||||
fi
|
||||
exe $WDIR/postfixadmin.sh ${qOpt} install
|
||||
}
|
||||
|
||||
step_21_info() { echo "Create $mtaName mysql query files"; }
|
||||
step_21() {
|
||||
# eval needed to expand sourced configuration variables
|
||||
local localMysqlUser=`eval "echo \"$MAS_VIRTUAL_USER_PART\""`
|
||||
|
||||
exe mkdir -p "$mtaMysqlConfLoc"
|
||||
|
||||
local mtaFile
|
||||
local mtaVar
|
||||
local mtaMysqlFiles=(\
|
||||
"mysql_virtual_domains_maps"\
|
||||
"mysql_virtual_mailbox_maps"\
|
||||
"mysql_virtual_alias_domain_mailbox_maps"\
|
||||
"mysql_virtual_alias_maps"\
|
||||
"mysql_virtual_alias_domain_maps"\
|
||||
"mysql_virtual_alias_domain_catchall_maps"\
|
||||
)
|
||||
|
||||
for mtaFile in ${mtaMysqlFiles[@]}
|
||||
do
|
||||
eval 'mtaVar=$MAS_'${mtaFile}
|
||||
echoseq " [I] creating ${mtaFile}.cf"
|
||||
exe echo -e "$localMysqlUser\n$mtaVar" > "$mtaMysqlConfLoc/${mtaFile}.cf"
|
||||
done
|
||||
|
||||
exe chown -R root:${mtaUser} "$mtaMysqlConfLoc"
|
||||
exe chmod 640 "${mtaMysqlConfLoc}"/*
|
||||
}
|
||||
|
||||
step_22_info() { echo "Modify $mtaName configuration for virtual mailboxes"; }
|
||||
step_22() {
|
||||
exe postconf -e "virtual_mailbox_domains = proxy:mysql:/etc/postfix/sql/mysql_virtual_domains_maps.cf"
|
||||
exe postconf -e "virtual_mailbox_maps = proxy:mysql:/etc/postfix/sql/mysql_virtual_mailbox_maps.cf, proxy:mysql:/etc/postfix/sql/mysql_virtual_alias_domain_mailbox_maps.cf"
|
||||
exe postconf -e "virtual_alias_maps = proxy:mysql:/etc/postfix/sql/mysql_virtual_alias_maps.cf, proxy:mysql:/etc/postfix/sql/mysql_virtual_alias_domain_maps.cf, proxy:mysql:/etc/postfix/sql/mysql_virtual_alias_domain_catchall_maps.cf"
|
||||
exe postconf -e "virtual_transport = lmtp:unix:private/dovecot-lmtp"
|
||||
|
||||
# Apex domain removed, it is handled as virtual domain now
|
||||
exe postconf -e "mydestination = \$myhostname, localhost.\$mydomain, localhost"
|
||||
# Base location for the virtual maildirs
|
||||
exe postconf -e "virtual_mailbox_base = $MAS_VIRTUAL_FOLDER_BASE"
|
||||
exe postconf -e "virtual_minimum_uid = $MAS_VIRTUAL_USER_ID"
|
||||
exe postconf -e "virtual_uid_maps = static:$MAS_VIRTUAL_USER_ID"
|
||||
exe postconf -e "virtual_gid_maps = static:$MAS_VIRTUAL_USER_ID"
|
||||
}
|
||||
|
||||
step_23_info() { echo "Create virtual user $MAS_VIRTUAL_USER and folder $MAS_VIRTUAL_FOLDER_BASE"; }
|
||||
step_23() {
|
||||
exe mkdir -p "$MAS_VIRTUAL_FOLDER_BASE"
|
||||
exe groupadd --gid $MAS_VIRTUAL_USER_ID $MAS_VIRTUAL_USER
|
||||
exe adduser --disabled-login --disabled-password --home "$MAS_VIRTUAL_FOLDER_BASE" --uid $MAS_VIRTUAL_USER_ID --gid $MAS_VIRTUAL_USER_ID $MAS_VIRTUAL_USER
|
||||
exe chown -R ${MAS_VIRTUAL_USER}: "$MAS_VIRTUAL_FOLDER_BASE"
|
||||
exe chmod -R 770 "$MAS_VIRTUAL_FOLDER_BASE"
|
||||
|
||||
echoseq " [I] Restarting $mtaName"
|
||||
exe service $mtaName restart
|
||||
}
|
||||
|
||||
step_24_info() { echo "$mdaName virtualisation configuration instructions"; }
|
||||
step_24() {
|
||||
echo "# Configuring Mailbox Location"
|
||||
echo " [/etc/dovecot/conf.d/10-mail.conf]"
|
||||
echo " mail_location = maildir:~/Maildir"
|
||||
echo " mail_home = ${MAS_VIRTUAL_FOLDER_BASE}/%d/%n"
|
||||
echo
|
||||
echo "# Configure authentication"
|
||||
echo " [/etc/dovecot/conf.d/10-auth.conf]"
|
||||
echo " # Username with domain"
|
||||
echo " auth_username_format = %u"
|
||||
echo " # Find and uncomment following line"
|
||||
echo " !include auth-sql.conf.ext"
|
||||
echo " # Comment following line to prevent local users from sending mail"
|
||||
echo " # without having registered an email address"
|
||||
echo " #!include auth-system.conf.ext"
|
||||
echo " # Debug login issues in /var/log/maillog by adding:"
|
||||
echo " auth_debug = yes"
|
||||
echo " auth_debug_passwords = yes"
|
||||
echo
|
||||
echo "# Adding mysql login information"
|
||||
echo " [/etc/dovecot/dovecot-sql.conf.ext]"
|
||||
echo " driver = mysql"
|
||||
echo " connect = host=$MAS_DBHOST dbname=$MAS_DBNAME user=$MAS_DBUSER password='${MAS_DBPASS}'"
|
||||
echo " default_pass_scheme = MD5"
|
||||
echo " password_query = SELECT username AS user,password FROM mailbox WHERE username = '%u' AND active='1'"
|
||||
echo " user_query = SELECT maildir, $MAS_VIRTUAL_USER_ID AS uid, $MAS_VIRTUAL_USER_ID AS gid FROM mailbox WHERE username = '%u' AND active='1'"
|
||||
echo " iterate_query = SELECT username AS user FROM mailbox"
|
||||
}
|
||||
|
||||
step_25_info() {
|
||||
echo "Configure sieve for virtual users"
|
||||
}
|
||||
step_25() {
|
||||
echo "# Sieve script configuration"
|
||||
echo " [$mdaConfDir/90-sieve.conf]"
|
||||
echo " sieve = file:/var/vmail/%d/%n/sieve;active=/var/vmail/%d/%n/.dovecot.sieve"
|
||||
echo " sieve_extensions = +notify +imapflags +vnd.dovecot.execute"
|
||||
echo " sieve_plugins = sieve_extprograms"
|
||||
echo " sieve_user_log = file:/var/vmail/%d/%n/sieve/sieve.log"
|
||||
echo
|
||||
echo "# Enable sieve for lmtp"
|
||||
echo " [$mdaConfDir/20-lmtp.conf]"
|
||||
echo " postmaster_address = postmaster@$MAS_DOMAIN"
|
||||
echo " mail_plugins = $mail_plugins sieve"
|
||||
echo
|
||||
echo "# Enable excution of external programs (e.g. to send xmpp messages on certain keywords)"
|
||||
echo " [$mdaConfDir/90-sieve-extprograms.conf]"
|
||||
echo " sieve_execute_bin_dir = /usr/lib/dovecot/sieve-execute"
|
||||
echo
|
||||
echo "# Notes on execution of scripts"
|
||||
echo " * Scripts are executed with the $MAS_VIRTUAL_USER user"
|
||||
echo " * Scripts must no be writeable by others"
|
||||
echo " (chown root:$MAS_VIRTUAL_USER script; chmod 750 script)"
|
||||
echo " * \$HOME is set to the virtual users home"
|
||||
echo " (e.g. /var/vmail/$MAS_DOMAIN/max)"
|
||||
echo
|
||||
echo "# Notes about sendxmpp"
|
||||
echo " * .sendxmpprc resides in every virtual users home"
|
||||
echo " and must be owned by $MAS_VIRTUAL_USER"
|
||||
echo " (chown $MAS_VIRTUAL_USER: .sendxmpprc; chmod 700 .sendxmpprc)"
|
||||
}
|
||||
|
||||
step_50_info() { echo "Adding default relay host for sending mails"; }
|
||||
step_50_alias() { ALIAS="default_relay"; }
|
||||
step_50() {
|
||||
if [ ! -f "$saslPassFile" ] ; then
|
||||
exe postconf -e "relayhost = $MAS_RELAYHOST"
|
||||
exe postconf -e "smtp_sasl_auth_enable = yes"
|
||||
exe postconf -e "smtp_sasl_password_maps = hash:$saslPassFile"
|
||||
addConf -s "$MAS_RELAYHOST $MAS_RELAYUSER:$MAS_RELAYPASS" "$saslPassFile"
|
||||
fi
|
||||
echoseq " [I] Updating $saslPassFile"
|
||||
exe postmap "$saslPassFile"
|
||||
}
|
||||
saslPassFile="$mtaConfLoc/sasl_password"
|
||||
|
||||
step_52_info() {
|
||||
echo "Grant access for specific (local) hostnames"
|
||||
echoinfo "Workaround when local clients connect to 25 with different ips (v6)"
|
||||
}
|
||||
step_52_alias() { ALIAS="client_access"; }
|
||||
step_52() {
|
||||
if [ ! -f "$mtaClientAccessLoc" ] ; then
|
||||
echo " [I] Generating $mtaClientAccessLoc"
|
||||
exep "echo \"# myhost.lan OK\" > \"$mtaClientAccessLoc\""
|
||||
echo " [I] Don't forget to add the following"
|
||||
echo " [$mtaConfLoc/main.cf]"
|
||||
echo " smtpd_relay_restrictions ="
|
||||
echo " check_client_access hash:$mtaClientAccessLoc"
|
||||
fi
|
||||
echoseq " [I] Updating $mtaClientAccessLoc"
|
||||
exe postmap "$mtaClientAccessLoc"
|
||||
}
|
||||
mtaClientAccessLoc="$mtaConfLoc/client_access"
|
||||
|
||||
step_54_info() {
|
||||
echo "Deny recipient access for listed mail addresses"
|
||||
}
|
||||
step_54_alias() { ALIAS="recipient_access"; }
|
||||
step_54() {
|
||||
if [ ! -f "$mtaRecipientAccessLoc" ] ; then
|
||||
echoseq " [I] Generating $mtaRecipientAccessLoc"
|
||||
exep "echo \"# unwanted@${MAS_DOMAIN} 550 No mailbox. Nothing to see here.\" > \"$mtaRecipientAccessLoc\""
|
||||
echo " [I] Don't forget to add the following"
|
||||
echo " [$mtaConfLoc/main.cf]"
|
||||
echo " smtpd_recipient_restrictions ="
|
||||
echo " check_recipient_access hash:$mtaRecipientAccessLoc"
|
||||
fi
|
||||
echoseq " [I] Updating $mtaRecipientAccessLoc"
|
||||
exe postmap "$mtaRecipientAccessLoc"
|
||||
}
|
||||
mtaRecipientAccessLoc="$mtaConfLoc/recipient_access"
|
||||
|
||||
step_56_info() { echo "Add sender dependant relay with authentication"; }
|
||||
step_56_alias() { ALIAS="sender_relay"; }
|
||||
step_56() {
|
||||
if [ ! -f "$mtaSenderRelayLoc" ] ; then
|
||||
echoseq " [I] Generating $mtaSenderRelayLoc"
|
||||
exep "echo \"# user@extern.com smtp:[mail.extern.com]:587\" > \"$mtaSenderRelayLoc\""
|
||||
exe postconf -e "smtp_sender_dependent_authentication = yes"
|
||||
exe postconf -e "sender_dependent_relayhost_maps = hash:$mtaSenderRelayLoc"
|
||||
exe postconf -e "smtp_sasl_security_options = noanonymous"
|
||||
exe postconf -e "smtp_sasl_mechanism_filter = plain"
|
||||
exe postconf -e "smtp_tls_security_level = encrypt"
|
||||
exe postconf -e "smtp_tls_mandatory_ciphers = high"
|
||||
echo " [I] Don't forget to add credentials for the new relay"
|
||||
echo " [$saslPassFile]"
|
||||
echo " user@extern.com username:passwort"
|
||||
echo " postmap $saslPassFile"
|
||||
fi
|
||||
echoseq " [I] Updating $mtaSenderRelayLoc"
|
||||
exe postmap "$mtaSenderRelayLoc"
|
||||
exe postmap "$saslPassFile"
|
||||
}
|
||||
mtaSenderRelayLoc="$mtaConfLoc/sender_relay"
|
||||
|
||||
step_100_info() {
|
||||
echo "Send testmail [-u SYSTEMUSER | -f FROM] [TO]"
|
||||
echoinfo "Send as current user to postmaster@\$MAS_DOMAIN by default"
|
||||
}
|
||||
step_100_alias() { ALIAS="test"; }
|
||||
step_100() {
|
||||
shift
|
||||
local arg
|
||||
local fromAdr
|
||||
local toAdr="postmaster@$MAS_DOMAIN"
|
||||
local asUser=
|
||||
for arg in "$@" ; do
|
||||
case "$1" in
|
||||
-f)
|
||||
shift
|
||||
fromAdr="-f $1 "
|
||||
shift
|
||||
;;
|
||||
-u)
|
||||
shift
|
||||
asUser="sudo -u $1 "
|
||||
shift
|
||||
;;
|
||||
*)
|
||||
break
|
||||
;;
|
||||
esac
|
||||
done
|
||||
if [ ! -z $1 ] ; then
|
||||
toAdr="$1"
|
||||
fi
|
||||
exe ${asUser}sh -c "echo \"Subject: Test from Postfix\nIt is \$(date)\n\nGreetings \$(whoami)\" | sendmail ${fromAdr}$toAdr"
|
||||
}
|
||||
|
||||
step_102_info() { echo "Show mail queue"; }
|
||||
step_102_alias() { ALIAS="showqueue"; }
|
||||
step_102() {
|
||||
exe sendmail -bp
|
||||
}
|
||||
|
||||
step_104_info() {
|
||||
echo "Delete mail queue [ID]"
|
||||
echoinfo "Delete all queued mails if [ID] is empty"
|
||||
}
|
||||
step_104_alias() { ALIAS="delqueue"; }
|
||||
step_104() {
|
||||
shift
|
||||
local msgId="ALL"
|
||||
if [ ! -z $1 ] ; then
|
||||
msgId="$1"
|
||||
fi
|
||||
exe postsuper -d "$msgId"
|
||||
}
|
||||
|
||||
VERSION_SEQREV=12
|
||||
. /usr/local/bin/sequencer.sh
|
8
seqs/mailserver/smtpsService
Normal file
8
seqs/mailserver/smtpsService
Normal file
@@ -0,0 +1,8 @@
|
||||
smtps inet n - y - - smtpd
|
||||
-o syslog_name=postfix/smtps
|
||||
-o smtpd_tls_wrappermode=yes
|
||||
-o smtpd_sasl_auth_enable=yes
|
||||
-o smtpd_relay_restrictions=permit_sasl_authenticated,reject
|
||||
-o smtpd_recipient_restrictions=permit_mynetworks,permit_sasl_authenticated,reject
|
||||
-o smtpd_sasl_type=dovecot
|
||||
-o smtpd_sasl_path=private/auth
|
9
seqs/mailserver/submissionService
Normal file
9
seqs/mailserver/submissionService
Normal file
@@ -0,0 +1,9 @@
|
||||
submission inet n - y - - smtpd
|
||||
-o syslog_name=postfix/submission
|
||||
-o smtpd_tls_security_level=encrypt
|
||||
-o smtpd_tls_wrappermode=no
|
||||
-o smtpd_sasl_auth_enable=yes
|
||||
-o smtpd_relay_restrictions=permit_sasl_authenticated,reject
|
||||
-o smtpd_recipient_restrictions=permit_mynetworks,permit_sasl_authenticated,reject
|
||||
-o smtpd_sasl_type=dovecot
|
||||
-o smtpd_sasl_path=private/auth
|
25
seqs/matrix-commander.cfg.example
Normal file
25
seqs/matrix-commander.cfg.example
Normal file
@@ -0,0 +1,25 @@
|
||||
#!/bin/bash
|
||||
|
||||
MACO_USER="matrix-commander"
|
||||
MACO_BASE_DIR="/opt/matrix-commander"
|
||||
MACO_DIR="$MACO_BASE_DIR/matrix-commander"
|
||||
MACO_SERVICE="[Unit]
|
||||
Description=Matrix-Commander
|
||||
After=syslog.target network-online.target
|
||||
StartLimitIntervalSec=0
|
||||
|
||||
[Service]
|
||||
User=$MACO_USER
|
||||
Group=$MACO_USER
|
||||
|
||||
Type=simple
|
||||
|
||||
ExecStart=${MACO_BASE_DIR}/bin/python3 ${MACO_DIR}/matrix-commander.py --listen forever --listen-self
|
||||
TimeoutStopSec=20
|
||||
#KillMode=process
|
||||
Restart=always
|
||||
RestartSec=5
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
Alias=matrix-commander.service"
|
144
seqs/matrix-commander.sh
Executable file
144
seqs/matrix-commander.sh
Executable file
@@ -0,0 +1,144 @@
|
||||
#!/bin/bash
|
||||
|
||||
toolName=matrix-commander
|
||||
toolCloneUrl='https://github.com/8go/matrix-commander.git'
|
||||
toolDeps="python3-pip python3-venv libolm-dev"
|
||||
|
||||
toolCredentialDir=
|
||||
toolEncStoreDir=
|
||||
|
||||
# Get script working directory
|
||||
# (when called from a different directory)
|
||||
WDIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" >>/dev/null 2>&1 && pwd)"
|
||||
APTOPT=
|
||||
CONFIG=0
|
||||
SCRIPT_FILE=$(basename -- $0)
|
||||
SCRIPT_NAME=${SCRIPT_FILE%%.*}
|
||||
CONFIG_FILE_NAME="${SCRIPT_NAME}.cfg"
|
||||
CONFIG_FILE_TEMPLATE="$WDIR/${CONFIG_FILE_NAME}.example"
|
||||
|
||||
step_config() {
|
||||
## or to use sequencer api with global config file:
|
||||
initSeqConfig "$CONFIG_FILE_NAME" "$CONFIG_FILE_TEMPLATE"
|
||||
|
||||
if [ $? -eq 0 ] ; then
|
||||
CONFIG=1
|
||||
else
|
||||
# End if no configuration file exists
|
||||
[ $DRY -eq 0 ] && return -1
|
||||
fi
|
||||
|
||||
toolCredentialDir="$MACO_BASE_DIR/.config/matrix-commander"
|
||||
toolEncStoreDir="$MACO_BASE_DIR/.local/share/matrix-commander"
|
||||
|
||||
## Apt cmdline option to suppress user interaction
|
||||
[ $QUIET -ne 0 ] && APTOPT="-y"
|
||||
|
||||
## Return of non zero value will abort the sequence
|
||||
return 0
|
||||
}
|
||||
|
||||
step_1_info() { echo "Run $toolName"; }
|
||||
step_1_alias() { ALIAS="run"; }
|
||||
step_1() {
|
||||
shift
|
||||
exe "$MACO_BASE_DIR/bin/python3" "$MACO_DIR/matrix-commander.py" "$@"
|
||||
}
|
||||
|
||||
step_3_info() {
|
||||
echoinfoArgs "[MESSAGE] [MESSAGE] ..."
|
||||
echo "Send message"
|
||||
echoinfo "Each string ([MESSAGE]) is send as separate message"
|
||||
}
|
||||
step_3_alias() { ALIAS="message"; }
|
||||
step_3() {
|
||||
shift
|
||||
step run -m "$@"
|
||||
}
|
||||
|
||||
step_50_info() { echo "Install $toolName dependencies"; }
|
||||
step_50_alias() { ALIAS="install"; }
|
||||
step_50() {
|
||||
apt install $toolDeps $APTOPT
|
||||
}
|
||||
|
||||
step_51_info() { echo "Add system user $MACO_USER"; }
|
||||
step_51() {
|
||||
id $MACO_USER >/dev/null 2>&1
|
||||
[ $? -eq 0 ] && endReturn -o 1 "User $MACO_USER already exists"
|
||||
|
||||
exe adduser --system $MACO_USER --group --home "${MACO_BASE_DIR}" --no-create-home
|
||||
}
|
||||
|
||||
step_52_info() { echo "Create venv and install $toolName"; }
|
||||
step_52() {
|
||||
[ -e "$MACO_BASE_DIR" ] && endReturn -o 1 "$toolName already installed"
|
||||
|
||||
exe python3 -m venv "$MACO_BASE_DIR"
|
||||
endReturn -o $? "Creating virtual environment failed"
|
||||
|
||||
exe git clone $toolCloneUrl "$MACO_DIR"
|
||||
exe chown -R $MACO_USER: "$MACO_BASE_DIR"
|
||||
exe sudo -u $MACO_USER ${MACO_BASE_DIR}/bin/pip install --upgrade pip
|
||||
}
|
||||
|
||||
step_53_info() { echo "Install python requirements"; }
|
||||
step_53() {
|
||||
cat <<NOTES_END
|
||||
# Remove following packages for headless servers
|
||||
|
||||
dbus-python
|
||||
notify2
|
||||
NOTES_END
|
||||
exe read -p "Enter to continue..."
|
||||
exe "$DEFAULT_EDITOR_SYSTEM" "$MACO_DIR/requirements.txt"
|
||||
exe sudo -u $MACO_USER ${MACO_BASE_DIR}/bin/pip install -r ${MACO_DIR}/requirements.txt
|
||||
}
|
||||
|
||||
step_55_info() {
|
||||
echo "Create systemd service for $toolName"
|
||||
echoinfo "(Make sure to modify the service content in the step configuration)"
|
||||
}
|
||||
step_55_alias() { ALIAS="service"; }
|
||||
step_55() {
|
||||
local macommanderServiceLoc="/etc/systemd/system/matrix-commander.service"
|
||||
addConf -s "$MACO_SERVICE" "$macommanderServiceLoc"
|
||||
exe systemctl daemon-reload
|
||||
}
|
||||
|
||||
step_57_info() { echo "First run to create credential file and encryption store"; }
|
||||
step_57_alias() { ALIAS="firstrun"; }
|
||||
step_57() {
|
||||
exe sudo -u "$MACO_USER" mkdir -p "$toolCredentialDir" "$toolEncStoreDir"
|
||||
exe cd "$toolCredentialDir"
|
||||
step run
|
||||
[ -e ./store ] && exe mv store "$toolEncStoreDir"
|
||||
|
||||
echoseq " [I] use \"$SEQ_NAME run --verify\" to verify against an existing session (like Element)"
|
||||
}
|
||||
|
||||
step_60_alias() { ALIAS="notes"; }
|
||||
step_60() {
|
||||
outColor green
|
||||
cat <<NOTES_EOF
|
||||
# Verify matrix-commander "device"
|
||||
|
||||
For emoji verification to work, the matrix-commander user needs to be at least in one room.
|
||||
Enter the room on Element and goto
|
||||
|
||||
* Room Info -> People -> select matrix commander user -> Security -> sessions -> matrix-commander session
|
||||
* verify with emojis
|
||||
|
||||
## Credential information location
|
||||
|
||||
matrix-commander expects the following files to be in place for the user to be able to
|
||||
send/receive messages
|
||||
|
||||
credentials.json - $MACO_BASE_DIR/.config/matrix-commander/credentials.json
|
||||
store - $MACO_BASE_DIR/.local/share/matrix-commander/store
|
||||
|
||||
NOTES_EOF
|
||||
}
|
||||
|
||||
VERSION_SEQREV=15
|
||||
. /usr/local/bin/sequencer.sh
|
3
seqs/matrix-dimension.cfg.example
Normal file
3
seqs/matrix-dimension.cfg.example
Normal file
@@ -0,0 +1,3 @@
|
||||
#!/bin/bash
|
||||
|
||||
SEQ_DIMENSION_DIR="/opt/matrix-dimension"
|
79
seqs/matrix-dimension.sh
Executable file
79
seqs/matrix-dimension.sh
Executable file
@@ -0,0 +1,79 @@
|
||||
#!/bin/bash
|
||||
|
||||
toolName=matrix-dimension
|
||||
toolDownUrl="https://github.com/turt2live/matrix-dimension.git"
|
||||
toolAptDeps="nodejs"
|
||||
|
||||
# Get script working directory
|
||||
# (when called from a different directory)
|
||||
WDIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" >>/dev/null 2>&1 && pwd)"
|
||||
APTOPT=
|
||||
CONFIG=0
|
||||
SCRIPT_FILE=$(basename -- $0)
|
||||
SCRIPT_NAME=${SCRIPT_FILE%%.*}
|
||||
CONFIG_FILE_NAME="${SCRIPT_NAME}.cfg"
|
||||
CONFIG_FILE_TEMPLATE="$WDIR/${CONFIG_FILE_NAME}.example"
|
||||
|
||||
step_config() {
|
||||
## or to use sequencer api with global config file:
|
||||
initSeqConfig "$CONFIG_FILE_NAME" "$CONFIG_FILE_TEMPLATE"
|
||||
if [ $? -eq 0 ] ; then
|
||||
CONFIG=1
|
||||
else
|
||||
# End if no configuration file exists
|
||||
[ $DRY -eq 0 ] && return -1
|
||||
fi
|
||||
|
||||
## Apt cmdline option to suppress user interaction
|
||||
[ $QUIET -ne 0 ] && APTOPT="-y"
|
||||
|
||||
echoerr " [W] $SCRIPT_NAME is still in alpha stage"
|
||||
echoerr " TODO: - systemd script"
|
||||
echoerr " - initial config creation"
|
||||
|
||||
## Return of non zero value will abort the sequence
|
||||
return 0
|
||||
}
|
||||
|
||||
step_1_info() { echo "Install $toolName dependencies"; }
|
||||
step_1_alias() { ALIAS="install"; }
|
||||
step_1() {
|
||||
exep curl -sL https://deb.nodesource.com/setup_12.x \| bash -
|
||||
exe apt install $toolAptDeps $APTOPT
|
||||
}
|
||||
|
||||
step_2_info() { echo "Setup and build"; }
|
||||
step_2_alias() { ALIAS="setup"; }
|
||||
step_2() {
|
||||
if [ ! -e "$SEQ_DIMENSION_DIR" ]; then
|
||||
exe mkdir -p "$SEQ_DIMENSION_DIR"
|
||||
exe cd "$SEQ_DIMENSION_DIR/.."
|
||||
# Download dimension
|
||||
exe git clone $toolDownUrl
|
||||
fi
|
||||
|
||||
exe cd "$SEQ_DIMENSION_DIR"
|
||||
|
||||
# Install dependencies
|
||||
exe npm install
|
||||
|
||||
# Build it
|
||||
exe npm run build
|
||||
}
|
||||
|
||||
step_10_info() { echo "Start $toolName"; }
|
||||
step_10_alias() { ALIAS="start"; }
|
||||
step_10() {
|
||||
if [ ! -e "$SEQ_DIMENSION_DIR" ]; then
|
||||
echoerr " [E] $toolName not found ad $SEQ_DIMENSION_DIR"
|
||||
return 1;
|
||||
fi
|
||||
exe cd "$SEQ_DIMENSION_DIR"
|
||||
# TODO is "node build/app/index.js" enough after build
|
||||
# NODE_ENV=production npm run start:app runs actually:
|
||||
# start:app: `npm run-script build && node build/app/index.js`
|
||||
exep NODE_ENV=production node build/app/index.js
|
||||
}
|
||||
|
||||
VERSION_SEQREV=15
|
||||
. /usr/local/bin/sequencer.sh
|
8
seqs/matrix.cfg.example
Normal file
8
seqs/matrix.cfg.example
Normal file
@@ -0,0 +1,8 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Location of synapse virtual environment
|
||||
MATRIX_HOME="/opt/synapse"
|
||||
# Corresponds to "server_name" in synapse config
|
||||
MATRIX_DOMAIN="matrix.example.com"
|
||||
# Provide an admin access token for API calls
|
||||
MATRIX_ACCESS=""
|
563
seqs/matrix.sh
Executable file
563
seqs/matrix.sh
Executable file
@@ -0,0 +1,563 @@
|
||||
#!/bin/bash
|
||||
|
||||
toolName=synapse
|
||||
toolDeps="build-essential python3-dev libffi-dev python3-pip python3-setuptools postgresql libssl-dev virtualenv libjpeg-dev libxslt1-dev libpq5 libpq-dev"
|
||||
toolDeps+=" jq" # used as helper for api access
|
||||
toolDepsRaspi="libopenjp2-7 libtiff5"
|
||||
toolUser="synapse"
|
||||
toolGroup="synapse"
|
||||
toolServiceName="matrix-synapse"
|
||||
synapseHashTool="env/bin/hash_password"
|
||||
toolUrlLocal="http://localhost:8008"
|
||||
# Filled by configuration
|
||||
toolConfig=
|
||||
toolUrl=
|
||||
|
||||
# Needed for different steps
|
||||
postgresDb=""
|
||||
postgresUser=""
|
||||
postgresPass=""
|
||||
|
||||
# Get script working directory
|
||||
# (when called from a different directory)
|
||||
WDIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >>/dev/null 2>&1 && pwd )"
|
||||
CONFIG=0
|
||||
CONFIG_FILE_NAME="matrix.cfg"
|
||||
CONFIG_FILE_TEMPLATE="$WDIR/${CONFIG_FILE_NAME}.example"
|
||||
|
||||
step_config() {
|
||||
if [ "$(which lsb_release)" == "" ] ; then
|
||||
echoerr " [W] Cannot detect OS. Assuming Raspberry Pi OS"
|
||||
osName="Raspbian"
|
||||
else
|
||||
osName=$(lsb_release -is)
|
||||
distName=$(lsb_release -cs)
|
||||
fi
|
||||
|
||||
if [ "$osName" == "" ] ; then
|
||||
echoerr " [W] Error dedecting OS. Assuming Raspberry Pi OS"
|
||||
osName="Raspbian"
|
||||
fi
|
||||
|
||||
echo " [I] Detected OS: $osName $distName"
|
||||
|
||||
initSeqConfig "$CONFIG_FILE_NAME" "$CONFIG_FILE_TEMPLATE"
|
||||
if [ $? -eq 0 ] ; then
|
||||
CONFIG=1
|
||||
toolConfig="${MATRIX_HOME}/homeserver.yaml"
|
||||
toolUrl="https://$MATRIX_DOMAIN"
|
||||
localHome="$MATRIX_HOME"
|
||||
echo " $toolName home: $MATRIX_HOME"
|
||||
echo " $toolName domain: $MATRIX_DOMAIN"
|
||||
fi
|
||||
|
||||
return 0
|
||||
}
|
||||
|
||||
step_1_info() { echo "Installing $toolName dependencies"; }
|
||||
step_1_alias() { ALIAS="install"; }
|
||||
step_1() {
|
||||
local aptOption=
|
||||
|
||||
exe apt update
|
||||
endReturn -o $? "Updating apt repositories failed"
|
||||
|
||||
if [ $QUIET -ne 0 ] ; then
|
||||
aptOption="-y"
|
||||
else
|
||||
aptOption=""
|
||||
fi
|
||||
|
||||
if [ "$osName" != "Raspbian" ] ; then
|
||||
toolDepsRaspi=""
|
||||
fi
|
||||
exe apt install $toolDeps $toolDepsRaspi $aptOption
|
||||
}
|
||||
|
||||
step_2_info() { echo "Create postgres database for $toolName"; }
|
||||
step_2_alias() { ALIAS="createdb"; }
|
||||
step_2() {
|
||||
readDatabaseInfos
|
||||
|
||||
exe cd ~postgres
|
||||
exe su -c "psql -c \"CREATE USER ${postgresUser} WITH ENCRYPTED password '${postgresPass}';\"" - postgres
|
||||
exe su -c "psql -c \"CREATE DATABASE ${postgresDb} ENCODING \"UTF8\" LC_COLLATE='C' LC_CTYPE='C' template=template0 OWNER ${postgresUser};\"" - postgres
|
||||
exe su -c "psql -c \"GRANT ALL PRIVILEGES ON DATABASE \"${postgresDb}\" to ${postgresUser};\"" - postgres
|
||||
}
|
||||
|
||||
step_3_info() { echo "Create $toolName user and group"; }
|
||||
step_3() {
|
||||
exe addgroup "$toolGroup"
|
||||
exe adduser --system --home ${MATRIX_HOME}/ --no-create-home --disabled-password --shell /bin/nologin --ingroup "$toolGroup" "$toolUser"
|
||||
}
|
||||
|
||||
step_4_info() { echo "Install $toolName"; }
|
||||
step_4_alias() { ALIAS="virtualenv"; }
|
||||
step_4() {
|
||||
exe mkdir -p "$MATRIX_HOME"
|
||||
exe virtualenv -p python3 "${MATRIX_HOME}/env"
|
||||
exe cd "$MATRIX_HOME"
|
||||
exe source "${MATRIX_HOME}/env/bin/activate"
|
||||
exe pip install --upgrade pip
|
||||
exe pip install --upgrade setuptools
|
||||
exe pip install matrix-synapse[postgres] lxml
|
||||
}
|
||||
|
||||
step_5_info() { echo "Create default configuration and folder structure"; }
|
||||
step_5_alias() { ALIAS="defaultconfig"; }
|
||||
step_5() {
|
||||
# Create default configuration
|
||||
exe python3 -m synapse.app.homeserver --server-name "$MATRIX_DOMAIN" --config-path homeserver.yaml --generate-config --report-stats=no
|
||||
exe deactivate
|
||||
|
||||
# Create media directories
|
||||
exe mkdir -p ${MATRIX_HOME}/media_store ${MATRIX_HOME}/uploads
|
||||
exe chmod 770 "${MATRIX_HOME}/media_store" "${MATRIX_HOME}/uploads"
|
||||
# Allow matrix to write its logs in /opt/synapse
|
||||
exe chmod 755 "${MATRIX_HOME}"
|
||||
exe chown ${toolUser}:${toolGroup} "${MATRIX_HOME}" "${MATRIX_HOME}/media_store" "${MATRIX_HOME}/uploads"
|
||||
}
|
||||
|
||||
step_6_info() { echo "Open $toolName configuration file"; }
|
||||
step_6() {
|
||||
exe vi "$toolConfig"
|
||||
}
|
||||
|
||||
step_7_info() { echo "Create $toolName systemd service"; }
|
||||
step_7_alias() { ALIAS="systemd"; }
|
||||
step_7() {
|
||||
# eval needed to expand sourced configuration variables
|
||||
local localService=`eval "echo \"$toolService\""`
|
||||
addConf -c "$localService" "$toolServiceLoc"
|
||||
exe systemctl daemon-reload
|
||||
exe systemctl enable ${toolServiceName}.service
|
||||
exe service ${toolServiceName} start
|
||||
}
|
||||
toolServiceLoc="/etc/systemd/system/${toolServiceName}.service"
|
||||
toolService="[Unit]
|
||||
Description=Matrix Synapse service
|
||||
After=network.target postgresql.service
|
||||
|
||||
[Service]
|
||||
Type=forking
|
||||
WorkingDirectory=\${MATRIX_HOME}/
|
||||
ExecStart=\${MATRIX_HOME}/env/bin/synctl start
|
||||
ExecStop=\${MATRIX_HOME}/env/bin/synctl stop
|
||||
ExecReload=\${MATRIX_HOME}/env/bin/synctl restart
|
||||
User=\${toolUser}
|
||||
Group=\${toolGroup}
|
||||
Restart=always
|
||||
StandardOutput=syslog
|
||||
StandardError=syslog
|
||||
SyslogIdentifier=synapse
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target"
|
||||
|
||||
step_10_info() {
|
||||
echo -n "Upgrade $toolName installation"
|
||||
if [ $CONTEXT_HELP -eq 0 ] ; then
|
||||
echo " at $MATRIX_HOME"
|
||||
else
|
||||
echo
|
||||
fi
|
||||
}
|
||||
step_10_alias() { ALIAS="upgrade"; }
|
||||
step_10() {
|
||||
echo " [I] Upgrading $toolName"
|
||||
exe source "${MATRIX_HOME}/env/bin/activate"
|
||||
exe pip install --upgrade pip
|
||||
exe pip install --upgrade matrix-synapse
|
||||
saveReturn $?
|
||||
exe deactivate
|
||||
endReturn "Error upgrading $toolName"
|
||||
|
||||
echo " [I] Restarting $toolName"
|
||||
step restart
|
||||
echo " [I] New Version:"
|
||||
exe sleep 2
|
||||
step version
|
||||
}
|
||||
|
||||
step_12_info() { echo "Restart $toolName systemd service"; echo; }
|
||||
step_12_alias() { ALIAS="restart"; }
|
||||
step_12() {
|
||||
exe service ${toolServiceName} restart
|
||||
}
|
||||
|
||||
step_14_info() {
|
||||
echoinfoArgs "[IP]:8008"
|
||||
echo "Show $toolName version"
|
||||
}
|
||||
step_14_alias() { ALIAS="version"; }
|
||||
step_14() {
|
||||
local synapseIP=localhost
|
||||
shift
|
||||
if [ ! -z $1 ]; then
|
||||
synapseIP="$1"
|
||||
fi
|
||||
|
||||
local apiCall="http://${synapseIP}:8008/_synapse/admin/v1/server_version"
|
||||
# -sS to suppress download progress of curl
|
||||
exep "curl -sS \"$apiCall\" | python -m json.tool | grep _version"
|
||||
}
|
||||
|
||||
step_16_info() {
|
||||
echoinfoArgs "[OPTION] [IP]:8008"
|
||||
echo "List all registered users"
|
||||
echoinfo "[OPTION]"
|
||||
echoinfo " -r : Raw json output"
|
||||
}
|
||||
step_16_alias() { ALIAS="listuser"; }
|
||||
step_16() {
|
||||
adminTokenCheck
|
||||
endReturn -o $? "Admin token needed. Check $SEQ_CONFIG_FILE"
|
||||
|
||||
shift
|
||||
local synapseIP=localhost
|
||||
local grepOut=" | grep -E '(\"total\":|\"name\":)'"
|
||||
|
||||
for arg in "$@" ; do
|
||||
case "$1" in
|
||||
-r)
|
||||
grepOut=""
|
||||
shift
|
||||
;;
|
||||
*)
|
||||
break
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
if [ ! -z $1 ]; then
|
||||
synapseIP="$1"
|
||||
fi
|
||||
|
||||
local apiCall="http://${synapseIP}:8008/_synapse/admin/v2/users"
|
||||
exep "curl -sS --header \"Authorization: Bearer $MATRIX_ACCESS\" \"$apiCall\" | python -m json.tool $grepOut"
|
||||
}
|
||||
|
||||
step_18_info() { echo "Create new user"; }
|
||||
step_18_alias() { ALIAS="adduser"; }
|
||||
step_18() {
|
||||
exe /opt/synapse/env/bin/register_new_matrix_user -c "$MATRIX_HOME/homeserver.yaml" $toolUrlLocal
|
||||
}
|
||||
|
||||
step_20_info() {
|
||||
shift
|
||||
echoinfoArgs "[USER NAME]"
|
||||
echo -n "Reset user password"
|
||||
[ $CONTEXT_EXE -ne 0 ] && echoinfo " for $1" || echo
|
||||
}
|
||||
step_20_alias() { ALIAS="resetpw"; }
|
||||
step_20() {
|
||||
shift
|
||||
local user=
|
||||
|
||||
if [ ! -z $1 ]; then
|
||||
user="$1"
|
||||
else
|
||||
exe read -p "User name: " user
|
||||
fi
|
||||
|
||||
if [ -z $user ]; then
|
||||
echoerr "No user name provided"
|
||||
return 1
|
||||
fi
|
||||
local pw="$("${MATRIX_HOME}/${synapseHashTool}")"
|
||||
|
||||
# Escaping twice because password contains $ which would be treated as variables
|
||||
local string="\"UPDATE users SET password_hash=\''${pw}'\' WHERE name=\''@${user}:${MATRIX_DOMAIN}'\'\""
|
||||
exep "echo \"$string\" | su postgres -c 'psql -d synapse -f -'"
|
||||
}
|
||||
|
||||
step_22_info() {
|
||||
echoinfoArgs "[OPTION] [IP]:8008"
|
||||
echo "List all rooms"
|
||||
echoinfo "[OPTION]"
|
||||
echoinfo " -r : Raw json output"
|
||||
}
|
||||
step_22_alias() { ALIAS="listrooms"; }
|
||||
step_22() {
|
||||
adminTokenCheck
|
||||
endReturn -o $? "Admin token needed. Check $SEQ_CONFIG_FILE"
|
||||
|
||||
shift
|
||||
local arg
|
||||
local synapseIP=localhost
|
||||
local grepOut=" | grep -E '(\"total\":|\"name\":|\"room_id\":)'"
|
||||
|
||||
for arg in "$@" ; do
|
||||
case "$1" in
|
||||
-r)
|
||||
grepOut=""
|
||||
shift
|
||||
;;
|
||||
*)
|
||||
break
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
if [ ! -z $1 ]; then
|
||||
synapseIP="$1"
|
||||
fi
|
||||
|
||||
local apiCall="http://${synapseIP}:8008/_synapse/admin/v1/rooms"
|
||||
exep "curl -sS --header \"Authorization: Bearer $MATRIX_ACCESS\" \"$apiCall\" | python -m json.tool $grepOut"
|
||||
}
|
||||
|
||||
step_24_info() {
|
||||
echoinfoArgs "[OPTION] [ROOM ID] [IP]:8008"
|
||||
echo "List all room members"
|
||||
echoinfo "[OPTION]"
|
||||
echoinfo " -r : Raw json output"
|
||||
}
|
||||
step_24_alias() { ALIAS="listmember"; }
|
||||
step_24() {
|
||||
adminTokenCheck
|
||||
endReturn -o $? "Admin token needed. Check $SEQ_CONFIG_FILE"
|
||||
|
||||
shift
|
||||
local roomId=""
|
||||
local synapseIP=localhost
|
||||
local grepOut=" | grep -E '(\"total\":|\"members\":|\"@)'"
|
||||
|
||||
for arg in "$@" ; do
|
||||
case "$1" in
|
||||
-r)
|
||||
grepOut=""
|
||||
shift
|
||||
;;
|
||||
*)
|
||||
break
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
if [ ! -z $1 ]; then
|
||||
roomId="$1"
|
||||
shift
|
||||
fi
|
||||
|
||||
if [ ! -z $1 ]; then
|
||||
synapseIP="$1"
|
||||
fi
|
||||
|
||||
local apiCall="http://${synapseIP}:8008/_synapse/admin/v1/rooms/$roomId/members"
|
||||
exep "curl -sS --header \"Authorization: Bearer $MATRIX_ACCESS\" \"$apiCall\" | python -m json.tool $grepOut"
|
||||
}
|
||||
|
||||
step_26_info() {
|
||||
echoinfoArgs "[IP]:8008"
|
||||
echo "Delete rooms without local users"
|
||||
echoinfo " [IP] : default is localhost"
|
||||
}
|
||||
step_26_alias() { ALIAS="purge"; }
|
||||
step_26() {
|
||||
adminTokenCheck
|
||||
endReturn -o $? "Admin token needed. Check $SEQ_CONFIG_FILE"
|
||||
|
||||
shift
|
||||
local i
|
||||
local arg
|
||||
local synapseIP=localhost
|
||||
|
||||
if [ ! -z $1 ]; then
|
||||
synapseIP="$1"
|
||||
fi
|
||||
|
||||
local apiCall="http://${synapseIP}:8008/_synapse/admin/v1/rooms"
|
||||
local arrRoom=( $(curl -sS --header "Authorization: Bearer $MATRIX_ACCESS" "$apiCall" | jq '.rooms[] | select(.joined_local_members == 0) | .room_id') )
|
||||
|
||||
for i in "${!arrRoom[@]}" ; do
|
||||
arrRoom[$i]="${arrRoom[$i]:1:${#arrRoom[$i]}-2}"
|
||||
done
|
||||
|
||||
for i in "${arrRoom[@]}" ; do
|
||||
step deleteroom "$i"
|
||||
done
|
||||
}
|
||||
|
||||
|
||||
step_28_info() {
|
||||
echoinfoArgs "<ROOM ID> [IP]:8008"
|
||||
echo "Delete room"
|
||||
}
|
||||
step_28_alias() { ALIAS="deleteroom"; }
|
||||
step_28() {
|
||||
adminTokenCheck
|
||||
endReturn -o $? "Admin token needed. Check $SEQ_CONFIG_FILE"
|
||||
|
||||
shift
|
||||
local roomId=""
|
||||
local synapseIP=localhost
|
||||
|
||||
if [ ! -z $1 ]; then
|
||||
roomId="$1"
|
||||
shift
|
||||
else
|
||||
endReturn -o 1 "No room ID specified"
|
||||
fi
|
||||
|
||||
if [ ! -z $1 ]; then
|
||||
synapseIP="$1"
|
||||
fi
|
||||
|
||||
echo " [I] Deleting room with ID: $roomId"
|
||||
|
||||
local apiCall="http://${synapseIP}:8008/_synapse/admin/v2/rooms/$roomId"
|
||||
exep "curl -sS --header \"Authorization: Bearer $MATRIX_ACCESS\" \
|
||||
-X DELETE \
|
||||
-H \"Content-Type: application/json\" -d \"{}\" \
|
||||
\"$apiCall\" | python -m json.tool"
|
||||
|
||||
#end
|
||||
}
|
||||
# As note for further improvement
|
||||
# See https://github.com/matrix-org/synapse/blob/develop/docs/admin_api/rooms.md#delete-room-api
|
||||
postDataDeleteRoom()
|
||||
{
|
||||
cat <<EOF
|
||||
{
|
||||
"new_room_user_id": "@someuser:example.com",
|
||||
"room_name": "Content Violation Notification",
|
||||
"message": "Bad Room has been shutdown due to content violations on this server. Please review our Terms of Service.",
|
||||
"block": true,
|
||||
"purge": true
|
||||
}
|
||||
EOF
|
||||
}
|
||||
|
||||
step_30_info() { echoinfoArgs "[DATABASE]"; echo "Debloat postgres"; echo; }
|
||||
step_30_alias() { ALIAS="debloat"; }
|
||||
step_30() {
|
||||
shift
|
||||
local pgVerboseReId=" (VERBOSE) "
|
||||
local pgVerboseVac=" VERBOSE"
|
||||
|
||||
if [ $VERBOSE == 0 ]; then
|
||||
pgVerboseReId=" "
|
||||
pgVerboseVac=""
|
||||
fi
|
||||
|
||||
if [ -z $1 ]; then
|
||||
readDatabaseInfos
|
||||
else
|
||||
postgresDb="$1"
|
||||
fi
|
||||
|
||||
echo " [I] Stopping ${toolServiceName}"
|
||||
exe service ${toolServiceName} stop
|
||||
endReturn -o $? "Couldn't stop ${toolServiceName}. Stopping debloat."
|
||||
|
||||
exe cd ~postgres
|
||||
exe su -c "psql -d ${postgresDb} -c \"REINDEX${pgVerboseReId}DATABASE ${postgresDb};\"" - postgres
|
||||
exe su -c "psql -c \"VACUUM FULL${pgVerboseVac};\"" - postgres
|
||||
|
||||
echo -e "\n [I] Starting ${toolServiceName}"
|
||||
exe service ${toolServiceName} start
|
||||
}
|
||||
|
||||
step_50_info() { echo "Drop postgres database for $toolName"; }
|
||||
step_50_alias() { ALIAS="dropdb"; }
|
||||
step_50() {
|
||||
readDatabaseInfos
|
||||
|
||||
exe cd ~postgres
|
||||
exe su -c "psql -c \"DROP DATABASE ${postgresDb};\"" - postgres
|
||||
}
|
||||
|
||||
step_52_info() { echo "Backup postgres database"; }
|
||||
step_52_alias() { ALIAS="backupdb"; }
|
||||
step_52() {
|
||||
local DELYEAR=$(($(date +%Y)-2))
|
||||
if [ ! -s ~/.pgpass ] ; then
|
||||
echo " [I] For unattended backup please define ~/.pgpass containing credentials"
|
||||
echo " e.g. localhost:5432:database:user:pass"
|
||||
echo "Backup custom pg format with standard user / database: synapse / synapse"
|
||||
fi
|
||||
exep "pg_dump -h 127.0.0.1 -U synapse -Fc synapse | bzip2 -c > ${toolDbBackupFolder}/`date +%Y-%m-%d\"_\"%H-%M-%S`.backup.bz2"
|
||||
exe rm -f ${toolDbBackupFolder}/${DELYEAR}*
|
||||
}
|
||||
toolDbBackupFolder=/root/backupdb
|
||||
|
||||
|
||||
step_54_info() { echo "Postgres database restore"; }
|
||||
step_54_alias() { ALIAS="restoredb"; }
|
||||
step_54() {
|
||||
echo " [I] Postgres database restore procedure"
|
||||
echo "1. Create a empty postgres database first (step 4)"
|
||||
echo "2. psql -h <host> -U <database user> -d <database name> -W -f <sql dump file>"
|
||||
echo " e.g. psql -h 127.0.0.1 -U synapse -d synapse -W -f 2018-06-07_18-10-56.sql"
|
||||
echo "or"
|
||||
echo "3. Custom postgres format dump restore:"
|
||||
echo " pg_restore -h localhost -p 5432 -U synapse -d new_db -v \"10.70.0.61.backup\""
|
||||
echo
|
||||
echo "Available postgresql databases:"
|
||||
exe cd ~postgres
|
||||
exe su postgres -c "psql -c '\l'"
|
||||
echo "Available postgresql user:"
|
||||
exe su postgres -c "psql -c '\du'"
|
||||
}
|
||||
|
||||
step_56_info() { echo "$toolName migration notes"; }
|
||||
step_56_alias() { ALIAS="migrate"; }
|
||||
step_56() {
|
||||
echo " [I] Backup database"
|
||||
echo " ./postgres.sh backupdb synapse"
|
||||
echo
|
||||
echo " [I] Backup virtual env folders except \"env\""
|
||||
echo " cd ${MATRIX_HOME}"
|
||||
echo " tar czf ../\`date +%Y-%m-%d\"_\"%H-%M-%S\`.synapse_bu.tar.gz --exclude=\"./env\" ."
|
||||
echo
|
||||
echo " [I] Transfer both backup files to target server"
|
||||
echo
|
||||
echo " [I] Install $toolName on the target server up to step \"virtualenv\""
|
||||
echo " (Stop after first run and edit $SEQ_CONFIG_FILE)"
|
||||
echo " ./matrix.sh install"
|
||||
echo " cd ${MATRIX_HOME}"
|
||||
echo " tar xf ...synapse_bu.tar.gz"
|
||||
echo " Follow the instructions of:"
|
||||
echo " ./matrix.sh restoredb"
|
||||
echo " ./matrix.sh systemd"
|
||||
echo
|
||||
echo " [I] $toolName should be running. Now modify the reverse proxy configuration"
|
||||
}
|
||||
|
||||
# Read postgres database information dbname/user/pass if empty
|
||||
readDatabaseInfos() {
|
||||
if [ "$postgresDb" == "" ] ; then
|
||||
read -p "Enter postgres database name: " postgresDb
|
||||
endCheckEmpty postgresDb "database"
|
||||
fi
|
||||
if [ "$postgresUser" == "" ] ; then
|
||||
read -p "Enter postgres user name: " postgresUser
|
||||
endCheckEmpty postgresUser "user name"
|
||||
fi
|
||||
if [ "$postgresPass" == "" ] ; then
|
||||
read -s -p "Enter postgres password: " postgresPass
|
||||
endCheckEmpty postgresPass "password"
|
||||
fi
|
||||
echo
|
||||
}
|
||||
|
||||
# Needs readDatabaseInfos() to execute some commands
|
||||
toolScript() {
|
||||
if [ ! -z "$1" ] ; then
|
||||
readDatabaseInfos
|
||||
fi
|
||||
}
|
||||
|
||||
# End step if no admin access token is configured
|
||||
adminTokenCheck() {
|
||||
if [ -z "$MATRIX_ACCESS" ] ; then
|
||||
[ $QUIET -eq 0 ] && read -s -p "Please enter admin access tocken: " MATRIX_ACCESS
|
||||
# return 1 if it is still empty
|
||||
[ -z "$MATRIX_ACCESS" ] && return 1
|
||||
fi
|
||||
return 0
|
||||
}
|
||||
|
||||
VERSION_SEQREV=15
|
||||
. /usr/local/bin/sequencer.sh
|
199
seqs/matterbridge.sh
Executable file
199
seqs/matterbridge.sh
Executable file
@@ -0,0 +1,199 @@
|
||||
#!/bin/bash
|
||||
|
||||
#
|
||||
## Installation of chat bridge matterbridge
|
||||
|
||||
toolName="matterbridge"
|
||||
repoName="42wim"
|
||||
toolLatestUrl="https://api.github.com/repos/${repoName}/${toolName}/releases/latest"
|
||||
toolVersion=$(curl --silent "$toolLatestUrl" | grep -Po '"tag_name": "v\K.*?(?=")')
|
||||
toolDownload="https://github.com/${repoName}/${toolName}/releases/download/v${toolVersion}/${toolName}-${toolVersion}-linux-armv6"
|
||||
toolDir="/usr/local/bin"
|
||||
toolLoc="${toolDir}/${toolName}"
|
||||
toolWdir="/opt/${toolName}"
|
||||
toolConfig="${toolName}.toml"
|
||||
toolConfigLoc="${toolWdir}/${toolConfig}"
|
||||
toolService="[Unit]
|
||||
Description=${toolName}
|
||||
After=network.target matrix-synapse.service
|
||||
|
||||
[Service]
|
||||
Type=simple
|
||||
ExecStart=${toolLoc} -conf ${toolWdir}/matterbridge.toml
|
||||
Restart=always
|
||||
RestartSec=30
|
||||
WorkingDirectory=${toolWdir}
|
||||
User=root
|
||||
Group=root
|
||||
StandardOutput=syslog
|
||||
StandardError=syslog
|
||||
SyslogIdentifier=${toolName}
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target"
|
||||
toolServiceLoc="/etc/systemd/system/${toolName}.service"
|
||||
|
||||
readonly goDir="/usr/local/go"
|
||||
readonly goDownLoc="/tmp/go.tar.gz"
|
||||
|
||||
step_config() {
|
||||
if [ -z $toolVersion ] ; then
|
||||
echoerr " [E] Couldn't determine latest version of $toolName"
|
||||
fi
|
||||
}
|
||||
|
||||
step_1_info() {
|
||||
echo "Downloading $toolName version ${toolVersion} to ${toolLoc} from:"
|
||||
echoinfo "$toolDownload"
|
||||
}
|
||||
step_1_alias() { ALIAS="install"; }
|
||||
step_1() {
|
||||
step upgrade
|
||||
endReturn -o $? "Download failed"
|
||||
}
|
||||
|
||||
step_2_info() { echo "Create required directory structure"; }
|
||||
step_2() {
|
||||
exe mkdir -p ${toolWdir}
|
||||
exe touch ${toolConfigLoc}
|
||||
exe chmod -R 700 ${toolWdir}
|
||||
exe chmod +x ${toolLoc}
|
||||
}
|
||||
|
||||
step_3_info() { echo "Creating systemd service"; }
|
||||
step_3() {
|
||||
addConf -s "$toolService" "$toolServiceLoc"
|
||||
endReturn -o $? "Creating service failed"
|
||||
}
|
||||
|
||||
step_4_info() { echo "Enable $toolName service"; }
|
||||
step_4() {
|
||||
exe systemctl enable ${toolName}
|
||||
echo " [I] Before proceeding to run ${toolName} you need to modify ${toolConfigLoc} first"
|
||||
echo
|
||||
}
|
||||
|
||||
step_5_info() { echo "Show configuration notes"; }
|
||||
step_5_alias() { ALIAS="notes"; }
|
||||
step_5() {
|
||||
outColor green
|
||||
cat <<NOTES_END
|
||||
|
||||
# Sample configuration
|
||||
|
||||
https://raw.githubusercontent.com/${repoName}/${toolName}/v${toolVersion}/matterbridge.toml.simple"
|
||||
|
||||
NOTES_END
|
||||
}
|
||||
|
||||
step_10_info() { echo "Backup existing executable"; }
|
||||
step_10_alias() { ALIAS="backup"; }
|
||||
step_10() {
|
||||
if [ -f "$toolLoc" ] ; then
|
||||
local toolBackup=
|
||||
if [ ! -z ${versionNow} ] ; then
|
||||
toolBackup="${toolDir}/${toolName}_${versionNow}"
|
||||
else
|
||||
toolBackup="${toolDir}/${toolName}_bu"
|
||||
fi
|
||||
exe service ${toolName} stop >>/dev/null 2>&1
|
||||
echoseq -n " [I] Backing up existing executable to ${toolBackup}..."
|
||||
exe cp -ar "$toolLoc" "$toolBackup" && echoseq "ok"
|
||||
fi
|
||||
}
|
||||
versionNow=$([ ! -z $(which ${toolName}) ] && ${toolName} --version | sed 's/.*version: \([0-9.]\+\).*/\1/')
|
||||
|
||||
step_12_info() {
|
||||
if [ ! -z $versionNow ] ; then
|
||||
if [ "$toolVersion" == "$versionNow" ] ; then
|
||||
echo "No upgrade available. Already on latest: $versionNow"
|
||||
else
|
||||
echo "Download new version $toolVersion to $toolDir"
|
||||
echoinfo " - installed version: $versionNow -"
|
||||
fi
|
||||
else
|
||||
echo "Download new version $toolVersion to $toolDir"
|
||||
fi
|
||||
echo
|
||||
}
|
||||
step_12_alias() { ALIAS="upgrade"; }
|
||||
step_12() {
|
||||
step backup
|
||||
exe wget -O "$toolLoc" $toolDownload
|
||||
endReturn -o $? "Download failed"
|
||||
exe chmod +x "$toolLoc"
|
||||
exe service ${toolName} restart >>/dev/null 2>&1
|
||||
return 0
|
||||
}
|
||||
|
||||
|
||||
step_30_info() {
|
||||
echoinfoArgs "[OPTIONS]"
|
||||
echo "Download go"
|
||||
echoinfo " [OPTIONS]"
|
||||
echoinfo " --arch, -a : armhf(default), arm64"
|
||||
echoinfo " CPU architecture for downloading go sources"
|
||||
}
|
||||
step_30_alias() { ALIAS="build"; }
|
||||
step_30() {
|
||||
shift
|
||||
local goVer="$(curl --silent -L https://go.dev/dl | \
|
||||
grep --max-count 1 -E "go[[:digit:]\.]{3,}.*\.tar\.gz" |\
|
||||
sed 's/.*\/\(go.*\)\.linux.*/\1/g')"
|
||||
local goArch="armhf" #arm64"
|
||||
case "${1}" in
|
||||
--arch|-a)
|
||||
goArch="${2}"
|
||||
shift 2 ;;
|
||||
esac
|
||||
[[ "${goArch}" == "armhf" ]] && goArch="armv6l"
|
||||
local goDownUrl="https://go.dev/dl/${goVer}.linux-${goArch}.tar.gz"
|
||||
|
||||
# Download latest go
|
||||
if [ ! -e "${goDir}" ] ; then
|
||||
echoseq "Download go${goVer}: ${goDownUrl}"
|
||||
exe wget -O "${goDownLoc}" ${goDownUrl}
|
||||
endReturn -o $? "Download ${goVer} failed"
|
||||
exe tar -C "$(dirname -- "${goDir}")" -xzf "${goDownLoc}"
|
||||
endReturn -o $? "Extraction ${goVer} failed"
|
||||
fi
|
||||
}
|
||||
|
||||
step_31_info() { echo "Compile matterbridge"; }
|
||||
step_31() {
|
||||
local mabrTags="\
|
||||
noapi,\
|
||||
nodiscord,\
|
||||
nogitter,\
|
||||
noharmony,\
|
||||
noirc,\
|
||||
nokeybase,\
|
||||
nomattermost,\
|
||||
nomsteams,\
|
||||
norocketchat,\
|
||||
nonctalk,\
|
||||
nomumble,\
|
||||
noslack,\
|
||||
nosshchat,\
|
||||
notelegram,\
|
||||
notwitch,\
|
||||
novk,\
|
||||
nozulip,\
|
||||
whatsappmulti"
|
||||
|
||||
# Compile matterbridge
|
||||
exe "${goDir}/bin/go" install -tags ${mabrTags} github.com/42wim/matterbridge@master
|
||||
step backup
|
||||
exe cp -ar "${HOME}/go/bin/matterbridge" "${toolDir}"
|
||||
}
|
||||
|
||||
step_32_info() { echo "Clean temporary files"; }
|
||||
step_32() {
|
||||
exe rm -f "${goDownLoc}"
|
||||
}
|
||||
|
||||
# Sequence Revision
|
||||
VERSION_SEQREV=15
|
||||
|
||||
# Path to sequencer
|
||||
. /usr/local/bin/sequencer.sh
|
5
seqs/mayan-edms.cfg.example
Normal file
5
seqs/mayan-edms.cfg.example
Normal file
@@ -0,0 +1,5 @@
|
||||
#!/bin/bash
|
||||
|
||||
MAYAN_DB=
|
||||
MAYAN_DBUSER=
|
||||
MAYAN_DBPASS=
|
237
seqs/mayan-edms.sh
Executable file
237
seqs/mayan-edms.sh
Executable file
@@ -0,0 +1,237 @@
|
||||
#!/bin/bash
|
||||
|
||||
toolName="Mayan EDMS"
|
||||
toolVersion="4.2.1"
|
||||
toolRoot="/opt/mayan-edms"
|
||||
toolMediaFolder="/opt/mayan-edms/media"
|
||||
|
||||
# Needed for different steps
|
||||
postgresDb=""
|
||||
postgresUser=""
|
||||
postgresPass=""
|
||||
|
||||
# Get script working directory
|
||||
# (when called from a different directory)
|
||||
WDIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" >>/dev/null 2>&1 && pwd)"
|
||||
APTOPT=
|
||||
CONFIG=0
|
||||
SCRIPT_FILE=$(basename -- $0)
|
||||
SCRIPT_NAME=${SCRIPT_FILE%%.*}
|
||||
CONFIG_FILE_NAME="${SCRIPT_NAME}.cfg"
|
||||
CONFIG_FILE_TEMPLATE="$WDIR/${CONFIG_FILE_NAME}.example"
|
||||
|
||||
step_config() {
|
||||
## or to use sequencer api with global config file:
|
||||
initSeqConfig "$CONFIG_FILE_NAME" "$CONFIG_FILE_TEMPLATE"
|
||||
if [ $? -eq 0 ] ; then
|
||||
CONFIG=1
|
||||
postgresDb="$MAYAN_DB"
|
||||
postgresUser="$MAYAN_DBUSER"
|
||||
postgresPass="$MAYAN_DBPASS"
|
||||
else
|
||||
# End if no configuration file exists
|
||||
[ $DRY -eq 0 ] && return -1
|
||||
fi
|
||||
|
||||
## Apt cmdline option to suppress user interaction
|
||||
[ $QUIET -ne 0 ] && APTOPT="-y"
|
||||
|
||||
## Return of non zero value will abort the sequence
|
||||
return 0
|
||||
}
|
||||
|
||||
step_1_info() { echo "Install libreoffice without gui"; }
|
||||
step_1_alias() { ALIAS="install"; }
|
||||
step_1() {
|
||||
exe apt update
|
||||
exe apt --no-install-recommends install libreoffice -y
|
||||
}
|
||||
|
||||
step_2_info() { echo "Get $toolName binary dependencies"; }
|
||||
step_2() {
|
||||
exe apt-get install libimage-exiftool-perl g++ gcc coreutils ghostscript gnupg1 \
|
||||
graphviz libfuse2 libjpeg-dev libmagic1 libpq-dev libpng-dev libtiff-dev libldap2-dev libsasl2-dev \
|
||||
poppler-utils postgresql python3-dev python3-pip python3-venv python3-virtualenv \
|
||||
redis-server sane-utils supervisor tesseract-ocr tesseract-ocr-deu zlib1g-dev -y
|
||||
endReturn -o $? "Binary dependencies installation failed"
|
||||
|
||||
exe systemctl enable supervisor
|
||||
exe systemctl stop supervisor
|
||||
}
|
||||
|
||||
step_3_info() { echo "Create virtual environment"; }
|
||||
step_3() {
|
||||
exe adduser --disabled-password --disabled-login --no-create-home --gecos "" mayan
|
||||
exe usermod -a -G users mayan
|
||||
exe python3 -m venv ${toolRoot}
|
||||
endReturn -o $? "Creating virtual environment failed"
|
||||
exe chown -R mayan:mayan ${toolRoot}
|
||||
}
|
||||
|
||||
step_4_info() { echo "Create postgres database for $toolName"; }
|
||||
step_4_alias() { ALIAS="createdb"; }
|
||||
step_4() {
|
||||
readDatabaseInfos
|
||||
|
||||
exe cd ~postgres
|
||||
exe sudo -u postgres psql -c "CREATE USER ${postgresUser} WITH password '${postgresPass}';"
|
||||
# -O owner : Specifies the database user who will own the new database.
|
||||
exe sudo -u postgres createdb -O ${postgresUser} ${postgresDb}
|
||||
}
|
||||
|
||||
step_5_info() { echo "Install $toolName"; }
|
||||
step_5() {
|
||||
# upgrade pip first
|
||||
step upgradepip
|
||||
|
||||
exe sudo -u mayan ${toolRoot}/bin/pip install --no-cache-dir mayan-edms==$toolVersion
|
||||
endReturn -o $? "pip install for $toolName failed"
|
||||
exe sudo -u mayan ${toolRoot}/bin/pip install --no-cache-dir psycopg2==2.8.4 redis==3.4.1
|
||||
endReturn -o $?
|
||||
}
|
||||
|
||||
step_6_info() { echo "Supervisord configuration for $toolName"; }
|
||||
step_6_alias() { ALIAS="supervisorconf"; }
|
||||
step_6() {
|
||||
addConf -c "" "$supervisordConfLoc"
|
||||
toolScript "platformtemplate supervisord > ${supervisordConfLoc}"
|
||||
}
|
||||
supervisordConfLoc="/etc/supervisor/conf.d/mayan.conf"
|
||||
|
||||
step_7_info() { echo "Redis configuration file"; }
|
||||
step_7() {
|
||||
addConf -a "$redisConf" "$redisConfLoc"
|
||||
|
||||
exe systemctl restart redis
|
||||
}
|
||||
|
||||
step_8_info() { echo "Initial setup $toolName and start supervisor"; }
|
||||
step_8() {
|
||||
toolScript initialsetup
|
||||
|
||||
#exe sudo -u mayan MAYAN_MEDIA_ROOT=${toolMediaFolder} ${toolRoot}/bin/mayan-edms.py collectstatic --noinput # only < 3.4
|
||||
exe systemctl start supervisor
|
||||
}
|
||||
|
||||
redisConfLoc="/etc/redis/redis.conf"
|
||||
redisConf="\
|
||||
maxmemory-policy allkeys-lru
|
||||
save \"\"
|
||||
databases 2"
|
||||
|
||||
step_10_info() {
|
||||
echoinfoArgs "[OPTIONS]"
|
||||
echo "Upgrade $toolName to $toolVersion"
|
||||
echoinfo " [OPTIONS]"
|
||||
echoinfo " super : update also supervisor configuration"
|
||||
echoinfo " (manual redis password update may be needed)"
|
||||
}
|
||||
step_10_alias() { ALIAS="upgrade"; }
|
||||
step_10() {
|
||||
shift # don't need the step number
|
||||
step upgradepip
|
||||
exe curl -o "$uninstallRemovalsLoc" https://gitlab.com/mayan-edms/mayan-edms/raw/master/removals.txt
|
||||
exe sudo -u mayan ${toolRoot}/bin/pip uninstall -r "$uninstallRemovalsLoc"
|
||||
endReturn -o $?
|
||||
exe systemctl stop supervisor
|
||||
exe sudo -u mayan ${toolRoot}/bin/pip install --no-cache-dir mayan-edms==$toolVersion
|
||||
endReturn -o $?
|
||||
toolScript performupgrade
|
||||
#toolScript preparestatic --noinput # only < 3.4
|
||||
case $1 in
|
||||
"super")
|
||||
# Generating new supervisor file
|
||||
step supervisorconf ;;
|
||||
esac
|
||||
exe systemctl start supervisor
|
||||
}
|
||||
uninstallRemovalsLoc="/tmp/removals.txt"
|
||||
|
||||
|
||||
step_13_info() { echo "$toolName management script"; }
|
||||
step_13_alias() { ALIAS="manage"; }
|
||||
step_13() {
|
||||
shift
|
||||
if [ -z "$1" ] || [ "$1" == "" ] ; then
|
||||
echo -n "Command (empty for help): "
|
||||
if [ $DRY != 0 ]; then
|
||||
echo " dryrun"
|
||||
else
|
||||
read command
|
||||
fi
|
||||
else
|
||||
command="$@"
|
||||
fi
|
||||
toolScript "$command"
|
||||
}
|
||||
|
||||
step_15_info() { echo "Upgrade python pip"; }
|
||||
step_15_alias() { ALIAS="upgradepip"; }
|
||||
step_15()
|
||||
{
|
||||
exe ${toolRoot}/bin/pip install --upgrade pip
|
||||
}
|
||||
|
||||
step_20_info() { echo "Backup postgres database to media folder"; }
|
||||
step_20_alias() { ALIAS="backupdb"; }
|
||||
step_20() {
|
||||
local DELYEAR=$(($(date +%Y)-2))
|
||||
if [ ! -s ~/.pgpass ] ; then
|
||||
echo " [I] For unattended backup please define ~/.pgpass containing credentials for user mayan"
|
||||
echo " e.g. localhost:5432:mayan:mayan:pass4mayan"
|
||||
echo "Backup custom pg format with standard user / database: mayan / mayan"
|
||||
fi
|
||||
exep "pg_dump -h 127.0.0.1 -U mayan -Fc mayan | bzip2 -c > ${toolDbBackupFolder}/`date +%Y-%m-%d\"_\"%H-%M-%S`.backup.bz2"
|
||||
exe rm -f ${toolDbBackupFolder}/${DELYEAR}*
|
||||
}
|
||||
toolDbBackupFolder=${toolMediaFolder}/backupdb
|
||||
|
||||
|
||||
step_22_info() { echo "Postgres database restore"; }
|
||||
step_22_alias() { ALIAS="restoredb"; }
|
||||
step_22() {
|
||||
echo " [I] Postgres database restore procedure"
|
||||
echo "1. Create a empty postgres database first (step 4)"
|
||||
echo "2. psql -h <host> -U <database user> -d <database name> -W -f <sql dump file>"
|
||||
echo " e.g. psql -h 127.0.0.1 -U mayan -d mayan -W -f 2018-06-07_18-10-56.sql"
|
||||
echo "or"
|
||||
echo "3. Custom postgres format dump restore:"
|
||||
echo " pg_restore -h localhost -p 5432 -U mayan -d new_db -v \"10.70.0.61.backup\""
|
||||
echo
|
||||
echo "Available postgresql databases:"
|
||||
exe cd ~postgres && sudo -u postgres psql -c '\l'
|
||||
echo "Available postgresql user:"
|
||||
exe cd ~postgres && sudo -u postgres psql -c '\du'
|
||||
}
|
||||
|
||||
# Read postgres database information dbname/user/pass if empty
|
||||
readDatabaseInfos() {
|
||||
if [ -z "$postgresDb" ] ; then
|
||||
read -p "Enter postgres database name: " postgresDb
|
||||
endCheckEmpty postgresDb "database"
|
||||
fi
|
||||
if [ -z "$postgresUser" ] ; then
|
||||
read -p "Enter postgres user name: " postgresUser
|
||||
endCheckEmpty postgresUser "user name"
|
||||
fi
|
||||
if [ -z "$postgresPass" ] ; then
|
||||
read -s -p "Enter postgres password: " postgresPass
|
||||
endCheckEmpty postgresPass "password"
|
||||
fi
|
||||
echoseq
|
||||
}
|
||||
|
||||
# Needs readDatabaseInfos() to execute some commands
|
||||
toolScript() {
|
||||
if [ ! -z "$1" ] ; then
|
||||
readDatabaseInfos
|
||||
fi
|
||||
|
||||
exep "sudo -u mayan \
|
||||
MAYAN_DATABASES=\"{'default':{'ENGINE':'django.db.backends.postgresql','NAME':'${postgresDb}','PASSWORD':'${postgresPass}','USER':'${postgresUser}','HOST':'127.0.0.1'}}\" \
|
||||
MAYAN_MEDIA_ROOT=${toolMediaFolder} \
|
||||
${toolRoot}/bin/mayan-edms.py $*"
|
||||
}
|
||||
|
||||
VERSION_SEQREV=15
|
||||
. /usr/local/bin/sequencer.sh
|
150
seqs/motioneye.sh
Executable file
150
seqs/motioneye.sh
Executable file
@@ -0,0 +1,150 @@
|
||||
#!/bin/bash
|
||||
|
||||
toolName=motioneye
|
||||
|
||||
# Supporting tools dependencies (ffmpeg and motion)
|
||||
toolDeps="ffmpeg libmariadb3 libpq5 libmicrohttpd12"
|
||||
# Motioneye dependencies
|
||||
toolDeps+=" python-pip python-dev libssl-dev libcurl4-openssl-dev libjpeg-dev libz-dev"
|
||||
toolCfgDir="/etc/motioneye"
|
||||
|
||||
SEQ_OSNAME=
|
||||
SEQ_DISTNAME=
|
||||
|
||||
# Get script working directory
|
||||
# (when called from a different directory)
|
||||
WDIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >>/dev/null 2>&1 && pwd )"
|
||||
CONFIG=0
|
||||
#CONFIG_FILE_NAME="${toolName}.cfg"
|
||||
#CONFIG_FILE_TEMPLATE="$WDIR/${CONFIG_FILE_NAME}.example"
|
||||
|
||||
step_config() {
|
||||
## e.g. to source a config file manually:
|
||||
#. "$CONFIG_FILE"
|
||||
## or to use sequencer api:
|
||||
#initSeqConfig "$CONFIG_FILE_NAME" "$CONFIG_FILE_TEMPLATE"
|
||||
#if [ $? -eq 0 ] ; then
|
||||
# CONFIG=1
|
||||
#fi
|
||||
if [ "$(which lsb_release)" == "" ] ; then
|
||||
echoerr " [W] Cannot detect OS. Assuming Ubuntu"
|
||||
SEQ_OSNAME="Ubuntu"
|
||||
else
|
||||
SEQ_OSNAME=$(lsb_release -is)
|
||||
SEQ_DISTNAME=$(lsb_release -cs)
|
||||
fi
|
||||
|
||||
if [ "$SEQ_OSNAME" == "" ] ; then
|
||||
echoerr " [W] Error dedecting OS. Assuming Ubuntu"
|
||||
SEQ_OSNAME="Ubuntu"
|
||||
fi
|
||||
|
||||
echo " [I] Detected OS: $SEQ_OSNAME $SEQ_DISTNAME"
|
||||
}
|
||||
|
||||
step_1_info() { echo "Install $toolName dependencies"; }
|
||||
step_1_alias() { ALIAS="install"; }
|
||||
step_1() {
|
||||
local aptOption=
|
||||
|
||||
local pyVersion=$(python -V 2>&1)
|
||||
if [[ ! "$pyVersion" =~ \ 2\.[7-9]+ ]] ; then
|
||||
echoerr " [E] Motioneye requires python version 2.7 but $pyVersion was found."
|
||||
return 1
|
||||
fi
|
||||
|
||||
exe apt update
|
||||
endReturn -o $? "Updating apt repositories failed"
|
||||
|
||||
if [ $QUIET -ne 0 ] ; then
|
||||
aptOption="-y"
|
||||
else
|
||||
aptOption=""
|
||||
fi
|
||||
|
||||
exe apt install $toolDeps $aptOption
|
||||
}
|
||||
|
||||
step_2_info() { echo "Download recommended motion version"; }
|
||||
step_2() {
|
||||
local motionUrl=
|
||||
if [ "$SEQ_OSNAME" == "Raspbian" ]; then
|
||||
motionUrl="https://github.com/Motion-Project/motion/releases/download/release-4.2.2/pi_${SEQ_DISTNAME}_motion_4.2.2-1_armhf.deb"
|
||||
elif [ "$SEQ_OSNAME" == "Ubuntu" ]; then
|
||||
motionUrl="https://github.com/Motion-Project/motion/releases/download/release-4.2.2/${SEQ_DISTNAME}_motion_4.2.2-1_amd64.deb"
|
||||
fi
|
||||
|
||||
if [ "$motionUrl" == "" ]; then
|
||||
echo " [W] Unsupported OS"
|
||||
return 1
|
||||
fi
|
||||
|
||||
exe wget -O "$motionDownload" $motionUrl
|
||||
endReturn -o $? "Download motion failed"
|
||||
}
|
||||
motionDownload="/tmp/motion.deb"
|
||||
|
||||
step_3_info() { echo "Install downloaded motion version"; }
|
||||
step_3() {
|
||||
if [ ! -f "$motionDownload" ]; then
|
||||
echo " [I] No downloaded motion found attempting download"
|
||||
step 2
|
||||
fi
|
||||
|
||||
exe dpkg -i "$motionDownload"
|
||||
endReturn -o $? "Installing motion failed"
|
||||
}
|
||||
|
||||
step_4_info() { echo "Upgrade python pip"; }
|
||||
step_4_alias() { ALIAS="upgradepip"; }
|
||||
step_4()
|
||||
{
|
||||
exe pip install --upgrade pip
|
||||
endReturn -o $? "Upgrading pip failed"
|
||||
}
|
||||
|
||||
step_5_info() { echo "Install $toolName"; }
|
||||
step_5() {
|
||||
exe pip install motioneye
|
||||
endReturn -o $? "Installing $toolName failed"
|
||||
}
|
||||
|
||||
step_6_info() { echo "Prepare configuration directory $toolCfgDir"; }
|
||||
step_6() {
|
||||
exe mkdir -p /etc/motioneye
|
||||
saveReturn $?
|
||||
exe cp "$motioneyeConfigSource" "$motioneyeConfigTarget"
|
||||
saveReturn $?
|
||||
endReturn "Creating first configuration failed"
|
||||
}
|
||||
motioneyeConfigSource="/usr/local/share/motioneye/extra/motioneye.conf.sample"
|
||||
motioneyeConfigTarget="/etc/motioneye/motioneye.conf"
|
||||
|
||||
step_7_info() { echo "Create media directory $motioneyeMediaDir"; }
|
||||
step_7() {
|
||||
exe mkdir -p "$motioneyeMediaDir"
|
||||
}
|
||||
motioneyeMediaDir="/var/lib/motioneye"
|
||||
|
||||
step_8_info() { echo "Create $toolName service"; }
|
||||
step_8() {
|
||||
exe cp "$motioneyeServiceSource" "$motioneyeServiceTarget"
|
||||
endReturn -o $? "Creating service failed"
|
||||
exe systemctl daemon-reload
|
||||
exe systemctl enable motioneye
|
||||
exe systemctl start motioneye
|
||||
}
|
||||
motioneyeServiceSource="/usr/local/share/motioneye/extra/motioneye.systemd-unit-local"
|
||||
motioneyeServiceTarget="/etc/systemd/system/motioneye.service"
|
||||
|
||||
step_20_info() { echo "Upgrade $toolName"; }
|
||||
step_20_alias() { ALIAS="upgrade"; }
|
||||
step_20() {
|
||||
step "upgradepip"
|
||||
exe pip install motioneye --upgrade
|
||||
endReturn -o $? "Upgrading $toolName failed"
|
||||
exe systemctl restart motioneye
|
||||
}
|
||||
|
||||
VERSION_SEQREV=11
|
||||
. /usr/local/bin/sequencer.sh
|
344
seqs/mysql.sh
Executable file
344
seqs/mysql.sh
Executable file
@@ -0,0 +1,344 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Mysql management using mariadb
|
||||
|
||||
databaseName="mariadb"
|
||||
databasePackages="mariadb-server mariadb-client"
|
||||
dbName=
|
||||
dbUser=
|
||||
dbRemote=localhost
|
||||
dbPass=
|
||||
|
||||
step_1_info() {
|
||||
echo "Installation of ${databaseName} packages:"
|
||||
echoinfo "$databasePackages"
|
||||
echoinfo "(Consider step \"latest\" first to setup official repository with the latest version)"
|
||||
}
|
||||
step_1_alias() { ALIAS=install; }
|
||||
step_1() {
|
||||
exe apt update
|
||||
exe apt install $databasePackages
|
||||
endReturn -o $? "Error instaling $databaseName"
|
||||
}
|
||||
|
||||
step_2_info() { echo "Secure ${databaseName} installation"; }
|
||||
step_2() {
|
||||
exe mysql_secure_installation
|
||||
}
|
||||
|
||||
step_3_info() { echo "${databaseName} configuration"; }
|
||||
step_3() {
|
||||
addConf -c "$mariadbConfig" "$mariadbConfigLoc"
|
||||
|
||||
echo -n "Restarting mysql ... "
|
||||
exe service mysql restart && echo "ok"
|
||||
}
|
||||
mariadbConfigLoc="/etc/mysql/mariadb.conf.d/90-myconfig.cnf"
|
||||
mariadbConfig="[mysqld]
|
||||
innodb_large_prefix=on
|
||||
innodb_file_format=barracuda
|
||||
innodb_file_per_table=true
|
||||
|
||||
lower_case_table_names=0
|
||||
|
||||
# coming from friendica warning 2020.07
|
||||
table_definition_cache=1400
|
||||
|
||||
#innodb_force_recovery=6"
|
||||
|
||||
step_8_info() { echo "Setup ubuntu $databaseName repository"; }
|
||||
step_8_alias() { ALIAS="latest"; }
|
||||
step_8() {
|
||||
exe apt install curl
|
||||
exep "curl -sS https://downloads.mariadb.com/MariaDB/mariadb_repo_setup | sudo bash -s -- --skip-maxscale --skip-tools"
|
||||
}
|
||||
|
||||
step_10_info() {
|
||||
echoinfoArgs "[OPTIONS]"
|
||||
echo "Create mysql database without specific characterset"
|
||||
echoinfo " [OPTIONS]"
|
||||
echoinfo " --charset,-c <utf8|utf8mb4> : character set and collate"
|
||||
echoinfo " --database, -d : database name"
|
||||
echoinfo " [OPTIONS] used in following steps"
|
||||
echoinfo " --user, -u : user name"
|
||||
echoinfo " Manual password entry for non existing user"
|
||||
echoinfo " --remote, -r : ip of allowed remote host"
|
||||
}
|
||||
step_10_alias() { ALIAS="createdb"; }
|
||||
step_10() {
|
||||
local arg
|
||||
local dbOption=
|
||||
|
||||
shift
|
||||
for arg in "$@" ; do
|
||||
case "$1" in
|
||||
--charset|-c)
|
||||
dbOption="$2"
|
||||
shift 2;;
|
||||
--database|-d)
|
||||
dbName="$2"
|
||||
shift 2 ;;
|
||||
--user|-u)
|
||||
dbUser="$2"
|
||||
shift 2 ;;
|
||||
--remote|-r)
|
||||
dbRemote="$2"
|
||||
shift 2 ;;
|
||||
*)
|
||||
break ;;
|
||||
esac
|
||||
done
|
||||
|
||||
case "$dbOption" in
|
||||
utf8)
|
||||
dbOption="CHARACTER SET utf8 COLLATE utf8_unicode_ci";;
|
||||
utf8mb4)
|
||||
dbOption="CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci";;
|
||||
*)
|
||||
dbOption="";;
|
||||
esac
|
||||
|
||||
if [ -z "$dbName" ] ; then
|
||||
echo " [I] Existing mysql databases:"
|
||||
exe mysql -u root -e 'SHOW DATABASES;'
|
||||
|
||||
read -p "Enter database name: " dbName
|
||||
fi
|
||||
endCheckEmpty dbName "database name"
|
||||
exe mysql -u root -e 'CREATE DATABASE '$dbName' '"$dbOption"';'
|
||||
endReturn -o $? "Cannot create database $dbName"
|
||||
}
|
||||
|
||||
step_11_info() {
|
||||
echoinfoArgs "[OPTIONS]"
|
||||
echo "Create mysql user"
|
||||
echoinfo " [OPTIONS]"
|
||||
echoinfo " --user, -u : user name"
|
||||
echoinfo " with manual password entry for non existing user"
|
||||
echoinfo " --remote, -r : ip of allowed remote host"
|
||||
}
|
||||
step_11_alias() { ALIAS="createuser"; }
|
||||
step_11() {
|
||||
local arg
|
||||
|
||||
shift
|
||||
for arg in "$@" ; do
|
||||
case "$1" in
|
||||
--charset|-c)
|
||||
dbOption="$2"
|
||||
shift 2;;
|
||||
--database|-d)
|
||||
dbName="$2"
|
||||
shift 2 ;;
|
||||
--user|-u)
|
||||
dbUser="$2"
|
||||
shift 2 ;;
|
||||
--remote|-r)
|
||||
dbRemote="$2"
|
||||
shift 2 ;;
|
||||
*)
|
||||
break ;;
|
||||
esac
|
||||
done
|
||||
|
||||
if [ -z "$dbUser" ] ; then
|
||||
echo " [I] Existing mysql user:"
|
||||
exe mysql -u root -e 'SELECT User, Host FROM mysql.user;'
|
||||
read -p "Enter mysql user name: " dbUser
|
||||
fi
|
||||
endCheckEmpty dbUser "user name"
|
||||
|
||||
if ! echo "SELECT COUNT(*) FROM mysql.user WHERE user = '$dbUser' AND host = '$dbRemote';" | mysql | grep 1 &>/dev/null; then
|
||||
# User does not exist
|
||||
if [ $DRY -eq 0 ]; then
|
||||
read -s -p "Enter mysql user password: " dbPass
|
||||
endCheckEmpty dbPass "password"
|
||||
else
|
||||
echoseq "Enter mysql password: ...skipped..."
|
||||
fi
|
||||
exe mysql -u root -e 'CREATE USER '"'"$dbUser"'"'@'"'"$dbRemote"'"' IDENTIFIED BY '"'"$dbPass"'"';'
|
||||
endReturn -o $? "Error creating mysql user"
|
||||
fi
|
||||
}
|
||||
|
||||
step_12_info() {
|
||||
echoinfoArgs "[OPTIONS]"
|
||||
echo "Grant privileges"
|
||||
echoinfo " [OPTIONS]"
|
||||
echoinfo " --database, -d : 'database name'.*"
|
||||
echoinfo " --user, -u : user name"
|
||||
echoinfo " --remote, -r : ip of allowed remote host"
|
||||
}
|
||||
step_12_alias() { ALIAS="grant"; }
|
||||
step_12() {
|
||||
local arg
|
||||
|
||||
shift
|
||||
for arg in "$@" ; do
|
||||
case "$1" in
|
||||
--charset|-c)
|
||||
dbOption="$2"
|
||||
shift 2;;
|
||||
--database|-d)
|
||||
dbName="$2"
|
||||
shift 2 ;;
|
||||
--user|-u)
|
||||
dbUser="$2"
|
||||
shift 2 ;;
|
||||
--remote|-r)
|
||||
dbRemote="$2"
|
||||
shift 2 ;;
|
||||
*)
|
||||
break ;;
|
||||
esac
|
||||
done
|
||||
|
||||
exe mysql -u root -e 'GRANT ALL PRIVILEGES ON '$dbName'.* TO '"'"$dbUser"'"'@'"'"$dbRemote"'"';'
|
||||
endReturn -o $? "Error assigning privileges on database"
|
||||
|
||||
exe mysql -u root -e 'FLUSH PRIVILEGES;'
|
||||
}
|
||||
|
||||
step_14_info() {
|
||||
echoinfoArgs "[OPTIONS]"
|
||||
echo "Revoke all granted privilegs"
|
||||
echoinfo " [OPTIONS]"
|
||||
echoinfo " --user, -u : user name"
|
||||
echoinfo " --remote, -r : ip of allowed remote host"
|
||||
}
|
||||
step_14_alias() { ALIAS="revokeall"; }
|
||||
step_14() {
|
||||
local arg
|
||||
|
||||
shift
|
||||
for arg in "$@" ; do
|
||||
case "$1" in
|
||||
--user|-u)
|
||||
dbUser="$2"
|
||||
shift 2 ;;
|
||||
--remote|-r)
|
||||
dbRemote="$2"
|
||||
shift 2 ;;
|
||||
*)
|
||||
break ;;
|
||||
esac
|
||||
done
|
||||
|
||||
exe mysql -u root -e 'REVOKE ALL, GRANT OPTION FROM '"'"$dbUser"'"'@'"'"$dbRemote"'"';'
|
||||
endReturn -o $? "Error revoking privileges for user $dbUser"
|
||||
|
||||
exe mysql -u root -e 'FLUSH PRIVILEGES;'
|
||||
}
|
||||
|
||||
step_30_info() { echo "List mysql databases"; }
|
||||
step_30_alias() { ALIAS="listdb"; }
|
||||
step_30() {
|
||||
exe mysql -u root -e 'SHOW DATABASES;'
|
||||
echo -e "\nDrop userdb by: mysql -u root -e 'DROP DATABASE userdb;'"
|
||||
}
|
||||
|
||||
step_32_info() { echo "List mysql user"; }
|
||||
step_32_alias() { ALIAS="listuser"; }
|
||||
step_32() {
|
||||
exe mysql -u root -e 'SELECT User, Host FROM mysql.user;'
|
||||
echo -e "\nDrop dbuser by: mysql -u root -e 'DROP USER dbuser@localhost;'"
|
||||
}
|
||||
|
||||
step_34_info() {
|
||||
echoinfoArgs "[OPTIONS]"
|
||||
echo "Show privileges"
|
||||
echoinfo " [OPTIONS]"
|
||||
echoinfo " --user, -u : user name"
|
||||
echoinfo " --remote, -r : ip of allowed remote host"
|
||||
}
|
||||
step_34_alias() { ALIAS="listprivileges"; }
|
||||
step_34() {
|
||||
local arg
|
||||
|
||||
shift
|
||||
for arg in "$@" ; do
|
||||
case "$1" in
|
||||
--user|-u)
|
||||
dbUser="$2"
|
||||
shift 2 ;;
|
||||
--remote|-r)
|
||||
dbRemote="$2"
|
||||
shift 2 ;;
|
||||
*)
|
||||
break ;;
|
||||
esac
|
||||
done
|
||||
|
||||
exe mysql -u root -e 'SHOW GRANTS FOR '"'"$dbUser"'"'@'"'"$dbRemote"'"';'
|
||||
}
|
||||
|
||||
step_36_info() {
|
||||
echoinfoArgs "[DATABASE_NAME]"
|
||||
echo "Size of database"
|
||||
}
|
||||
step_36_alias() { ALIAS="sizedb"; }
|
||||
step_36() {
|
||||
if [ -z "$2" ]; then
|
||||
echo "Please provide a database name. e.g. $0 sizedb mydb_db"
|
||||
else
|
||||
exe mysql -u root -e 'SELECT table_schema "DB Name",
|
||||
ROUND(SUM(data_length + index_length) / 1024 / 1024, 1) "DB Size in MB"
|
||||
FROM information_schema.tables
|
||||
WHERE table_schema="'$2'"
|
||||
GROUP BY table_schema;'
|
||||
fi
|
||||
}
|
||||
|
||||
step_50_info() {
|
||||
echoinfoArgs "<DATABASE NAME> <TARGET DIR>"
|
||||
echo "Backup (dump) a mysql database"
|
||||
}
|
||||
step_50_alias() { ALIAS="backup"; }
|
||||
step_50() {
|
||||
shift # step number not used
|
||||
if [ -z $1 ] ; then
|
||||
echoerr " [E] No database name provided"
|
||||
return 1
|
||||
fi
|
||||
local dbName="$1"
|
||||
local buTarget="$2"
|
||||
if [ -z "$2" ] ; then
|
||||
echoerr " [W] No target directory provided. Using home of current user"
|
||||
buTarget="$HOME"
|
||||
elif [ ! -e "$2" ]; then
|
||||
endReturn -o 1 -f "$2 does not exist"
|
||||
fi
|
||||
|
||||
echo " [I] Dumping database $dbName to $buTarget"
|
||||
exep "mysqldump --single-transaction $dbName > \"$(realpath $buTarget)/${dbName}_backup_$(date +%Y%m%d-%H%M%S).sql\""
|
||||
endReturn -o $? "Error creating $dbName backup"
|
||||
}
|
||||
|
||||
step_52_info() { echo "Restore a mysql database"; }
|
||||
step_52_alias() { ALIAS="restore"; }
|
||||
step_52() {
|
||||
echo "Restore with:"
|
||||
echo " mysql -e \"DROP DATABASE nextcloud_db\""
|
||||
echo " mysql -e \"CREATE DATABASE nextcloud_db\""
|
||||
echo " mysql nextcloud_db < NextcloudBackup_DB_20170912.sql"
|
||||
}
|
||||
|
||||
# Read database information dbname/user/pass if empty
|
||||
readDatabaseInfos() {
|
||||
if [ "$dbName" == "" ] ; then
|
||||
read -p "Enter postgres database name: " dbName
|
||||
endCheckEmpty dbName "database"
|
||||
fi
|
||||
if [ "$dbUser" == "" ] ; then
|
||||
read -p "Enter postgres user name: " dbUser
|
||||
endCheckEmpty dbUser "user name"
|
||||
fi
|
||||
if [ "$dbPass" == "" ] ; then
|
||||
read -s -p "Enter postgres password: " dbPass
|
||||
endCheckEmpty postgresPass "password"
|
||||
fi
|
||||
echo
|
||||
}
|
||||
|
||||
VERSION_SEQREV=14
|
||||
. /usr/local/bin/sequencer.sh
|
5
seqs/nextcloud.cfg.example
Normal file
5
seqs/nextcloud.cfg.example
Normal file
@@ -0,0 +1,5 @@
|
||||
# Configuration file for nextcloud sequence
|
||||
|
||||
sc_ncServerUser="www-data"
|
||||
sc_ncInstallDir="/var/www/nextcloud"
|
||||
sc_ncDataDir="${sc_ncInstallDir}/data"
|
140
seqs/nextcloud.sh
Executable file
140
seqs/nextcloud.sh
Executable file
@@ -0,0 +1,140 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
# Dependency to other seqs
|
||||
# - mysql.sh (soft; Missing informational output)
|
||||
|
||||
toolName="nextcloud"
|
||||
localOcc=("echo" "occ not found!")
|
||||
|
||||
# Get script working directory
|
||||
# (when called from a different directory)
|
||||
sq_dir="$( cd "$( dirname -- "$(realpath "${BASH_SOURCE[0]}")")" >>/dev/null 2>&1 && pwd )"
|
||||
sq_config=0
|
||||
sq_configFileName="${toolName}.cfg"
|
||||
sq_configFileTemplate="$sq_dir/${sq_configFileName}.example"
|
||||
|
||||
step_config() {
|
||||
## or to use sequencer api:
|
||||
initSeqConfig "$sq_configFileName" "$sq_configFileTemplate"
|
||||
if [ $? -eq 0 ] ; then
|
||||
sq_config=1
|
||||
fi
|
||||
localOcc=( sudo -u $sc_ncServerUser php "$(escpath "$sc_ncInstallDir/occ")" )
|
||||
}
|
||||
|
||||
step_1_info() {
|
||||
echoinfoArgs "[OCC ARGS]"
|
||||
echo "Execute occ command"
|
||||
}
|
||||
step_1_alias() { ALIAS="occ"; }
|
||||
step_1() {
|
||||
shift
|
||||
|
||||
exe "${localOcc[@]}" "$@"
|
||||
}
|
||||
|
||||
step_20_info() { echo "Upgrade $toolName on command line to latest version of selected release channel"; }
|
||||
step_20_alias() { ALIAS="upgrade"; }
|
||||
step_20() {
|
||||
if [ $sq_config -eq 0 ] ; then
|
||||
echoerr " [E] No configuration found to determine installation directory"
|
||||
return 1
|
||||
fi
|
||||
exe cd "$sc_ncInstallDir"
|
||||
exe sudo -u www-data php "$ncInstaller"
|
||||
}
|
||||
ncInstaller="updater/updater.phar"
|
||||
|
||||
step_102_info() { echoinfoArgs "<NC DATABASE> <IPV4 ADDRESS>"; echo "Delete IP from bruteforce table"; }
|
||||
step_102_alias() { ALIAS="bruteforceRemoveIP"; }
|
||||
step_102() {
|
||||
shift
|
||||
local ncdb=
|
||||
local ip=
|
||||
local ipregex='^[0-2]*[0-9]{1,2}\.[0-2]*[0-9]{1,2}\.[0-2]*[0-9]{1,2}\.[0-2]*[0-9]{1,2}$'
|
||||
|
||||
if [ -z $1 ] ; then
|
||||
echoerr " [E] No database provided"
|
||||
if [ -f "${sq_dir}/mysql.sh" ] ; then
|
||||
echo " [I] Available mysql databases:"
|
||||
"${sq_dir}/mysql.sh" -qq listdb
|
||||
fi
|
||||
return 1
|
||||
else
|
||||
ncdb="$1"
|
||||
fi
|
||||
# Check if string looks like ipv4 address
|
||||
if [[ "$2" =~ $ipregex ]] ; then
|
||||
ip="$2"
|
||||
else
|
||||
echoerr " [E] No valid IP:PORT detected: $2"
|
||||
return 1
|
||||
fi
|
||||
|
||||
exe mysql -u root -D ${ncdb} -e 'delete FROM oc_bruteforce_attempts WHERE IP="'${ip}'";'
|
||||
endReturn -o $? "Error deleting ip $ip"
|
||||
}
|
||||
|
||||
step_104_info() { echoinfoArgs "<USER>"; echo "Reset and rescan the music library in the background for one user"; }
|
||||
step_104_alias() { ALIAS="audioreset"; }
|
||||
step_104() {
|
||||
shift
|
||||
local ncUser=$1
|
||||
|
||||
if [ -z "$ncUser" ] ; then
|
||||
echoerr " [E] Reset only for single user"
|
||||
return 1
|
||||
fi
|
||||
|
||||
exep "${localOcc[@]} audioplayer:reset $ncUser > /var/log/ncAudioRescan.log"
|
||||
echoseq " [I] Rescan audioplayer database for user $ncUser"
|
||||
exep "${localOcc[@]} audioplayer:scan -vvvv $ncUser >> /var/log/ncAudioRescan.log &"
|
||||
}
|
||||
|
||||
step_106_info() { echoinfoArgs "<USER>"; echo "Scan the music library"; }
|
||||
step_106_alias() { ALIAS="audioscan"; }
|
||||
step_106() {
|
||||
shift
|
||||
local ncUser=$1
|
||||
|
||||
if [ -z "$ncUser" ] ; then
|
||||
echoerr " [E] Reset only for single user"
|
||||
return 1
|
||||
fi
|
||||
|
||||
exe "${localOcc[@]}" audioplayer:scan -vvvv $ncUser
|
||||
}
|
||||
|
||||
step_110_info() { echo "Reset picture preview folder"; }
|
||||
step_110_alias() { ALIAS="resetpreview"; }
|
||||
step_110() {
|
||||
if [ -e "${sc_ncDataDir}" ]; then
|
||||
exe rm -rf "${sc_ncDataDir}/appdata_"*"/preview/"*
|
||||
|
||||
echoseq " [I] Rescan app data folder"
|
||||
exep "${localOcc[@]} files:scan-app-data &"
|
||||
else
|
||||
echoerr " [E] Nextcloud data direcotry $sc_ncDataDir not found"
|
||||
return 1
|
||||
fi
|
||||
}
|
||||
|
||||
step_200_alias() { ALIAS="notes"; }
|
||||
step_200() {
|
||||
outColor green
|
||||
cat<<NOTES_END
|
||||
# Recommended preview settings
|
||||
[$sc_ncInstallDir/config/config.php]
|
||||
occ config:app:set previewgenerator squareSizes --value="32 256"
|
||||
occ config:app:set previewgenerator widthSizes --value="256 384"
|
||||
occ config:app:set previewgenerator heightSizes --value="256"
|
||||
occ config:system:set preview_max_x --value 2048
|
||||
occ config:system:set preview_max_y --value 2048
|
||||
occ config:system:set jpeg_quality --value 60
|
||||
occ config:app:set preview jpeg_quality --value="60"
|
||||
|
||||
NOTES_END
|
||||
}
|
||||
|
||||
VERSION_SEQREV=15
|
||||
. /usr/local/bin/sequencer.sh
|
76
seqs/olivetin.sh
Executable file
76
seqs/olivetin.sh
Executable file
@@ -0,0 +1,76 @@
|
||||
#!/bin/bash
|
||||
|
||||
toolName=olivetin
|
||||
latestUrl="https://api.github.com/repos/OliveTin/OliveTin/releases/latest"
|
||||
latestVersion=
|
||||
tempExtract=
|
||||
tempInstall=
|
||||
|
||||
# Get script working directory
|
||||
# (when called from a different directory)
|
||||
WDIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" >>/dev/null 2>&1 && pwd)"
|
||||
APTOPT=
|
||||
CONFIG=0
|
||||
SCRIPT_FILE=$(basename -- $0)
|
||||
SCRIPT_NAME=${SCRIPT_FILE%%.*}
|
||||
CONFIG_FILE_NAME="${SCRIPT_NAME}.cfg"
|
||||
CONFIG_FILE_TEMPLATE="$WDIR/${CONFIG_FILE_NAME}.example"
|
||||
|
||||
step_config() {
|
||||
## or to use sequencer api with global config file:
|
||||
#initSeqConfig "$CONFIG_FILE_NAME" "$CONFIG_FILE_TEMPLATE"
|
||||
|
||||
## or to use sequencer api with profile config file support:
|
||||
#initSeqConfig -p "$SCRIPT_NAME" "$CONFIG_FILE_TEMPLATE"
|
||||
#if [ $? -eq 0 ] ; then
|
||||
# CONFIG=1
|
||||
#else
|
||||
# # End if no configuration file exists
|
||||
# [ $DRY -eq 0 ] && return -1
|
||||
#fi
|
||||
|
||||
## Apt cmdline option to suppress user interaction
|
||||
[ $QUIET -ne 0 ] && APTOPT="-y"
|
||||
|
||||
## Return of non zero value will abort the sequence
|
||||
return 0
|
||||
}
|
||||
|
||||
step_1_info() { echo "Install $toolName"; }
|
||||
step_1_alias() { ALIAS="install"; }
|
||||
step_1() {
|
||||
downloadLatest
|
||||
|
||||
if [ -e "$tempInstall" ]; then
|
||||
exe dpkg -i "$tempInstall"
|
||||
exe systemctl --now enable OliveTin
|
||||
fi
|
||||
}
|
||||
|
||||
fetchLatestVersion() {
|
||||
if [ ! -z $latestVersion ] ; then
|
||||
return 0
|
||||
fi
|
||||
|
||||
latestVersion=$(curl --silent "$latestUrl" | grep -Po '"tag_name": "\K.*(?=")')
|
||||
}
|
||||
|
||||
downloadLatest() {
|
||||
fetchLatestVersion
|
||||
|
||||
local downUrl="https://github.com/OliveTin/OliveTin/releases/download/${latestVersion}/OliveTin_${latestVersion}_linux_armv7.deb"
|
||||
|
||||
if [ ! -e "$tempInstall" ] ; then
|
||||
exe mkdir -p "$tempDown"
|
||||
exe wget -O "$tempInstall" $downUrl
|
||||
endReturn -o $? "Download failed: $downUrl"
|
||||
else
|
||||
echo " [I] Found existing download: $tempInstall"
|
||||
fi
|
||||
}
|
||||
tempDown="/tmp/olivetin"
|
||||
tempInstall="$tempDown/olivetin.deb"
|
||||
|
||||
|
||||
VERSION_SEQREV=13
|
||||
. /usr/local/bin/sequencer.sh
|
8
seqs/onlyoffice.cfg.example
Normal file
8
seqs/onlyoffice.cfg.example
Normal file
@@ -0,0 +1,8 @@
|
||||
#!/bin/bash
|
||||
|
||||
onlyOfficePort="80"
|
||||
dockerDns1="80.241.218.68" # https://dismail.de/info.html#dns
|
||||
dockerDns2="46.182.19.48" # https://digitalcourage.de/support/zensurfreier-dns-server
|
||||
dockerDefaultConf="/etc/default/docker"
|
||||
dockerImageName="onlyoffice/documentserver"
|
||||
dockerSecret=
|
194
seqs/onlyoffice.sh
Executable file
194
seqs/onlyoffice.sh
Executable file
@@ -0,0 +1,194 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Source
|
||||
# Docker - Install using the repository
|
||||
# https://docs.docker.com/install/linux/docker-ce/ubuntu/
|
||||
#
|
||||
# Onlyoffice - Docker
|
||||
# https://helpcenter.onlyoffice.com/server/docker/document/docker-installation.aspx
|
||||
|
||||
toolName="onlyoffice"
|
||||
dockerDeps="apt-transport-https ca-certificates curl gnupg-agent software-properties-common"
|
||||
dockerGpgKeyUrl="https://download.docker.com/linux/ubuntu/gpg"
|
||||
dockerRepoUrl="https://download.docker.com/linux/ubuntu"
|
||||
dockerPackages="docker-ce docker-ce-cli containerd.io"
|
||||
# Entry in config value $dockerDefaultConf
|
||||
dockerDnsEntry=
|
||||
|
||||
# Get script working directory
|
||||
# (when called from a different directory)
|
||||
WDIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" >>/dev/null 2>&1 && pwd)"
|
||||
APTOPT=
|
||||
CONFIG=0
|
||||
SCRIPT_FILE=$(basename -- $0)
|
||||
SCRIPT_NAME=${SCRIPT_FILE%%.*}
|
||||
CONFIG_FILE_NAME="${SCRIPT_NAME}.cfg"
|
||||
CONFIG_FILE_TEMPLATE="$WDIR/${CONFIG_FILE_NAME}.example"
|
||||
|
||||
step_config() {
|
||||
## Called once before executing steps.
|
||||
## e.g. to source a config file manually:
|
||||
#. "$CONFIG_FILE"
|
||||
|
||||
## or to use sequencer api with global config file:
|
||||
initSeqConfig "$CONFIG_FILE_NAME" "$CONFIG_FILE_TEMPLATE"
|
||||
|
||||
## or to use sequencer api with profile config file support:
|
||||
#initSeqConfig -p "$SCRIPT_NAME" "$CONFIG_FILE_TEMPLATE"
|
||||
if [ $? -eq 0 ] ; then
|
||||
CONFIG=1
|
||||
else
|
||||
# End if no configuration file exists
|
||||
[ $DRY -eq 0 ] && return -1
|
||||
fi
|
||||
|
||||
## Apt cmdline option to suppress user interaction
|
||||
[ $QUIET -ne 0 ] && APTOPT="-y"
|
||||
|
||||
dockerDnsEntry="DOCKER_OPTS=\"--dns $dockerDns1 --dns $dockerDns2\""
|
||||
|
||||
## Return of non zero value will abort the sequence
|
||||
return 0
|
||||
}
|
||||
|
||||
step_1_info() { echo "Install Docker dependencies"; }
|
||||
step_1_alias() { ALIAS="install"; }
|
||||
step_1() {
|
||||
exe apt update
|
||||
exe apt install $dockerDeps $APTOPT
|
||||
endReturn -o $? "Docker dependencies installation failed"
|
||||
}
|
||||
|
||||
step_2_info() { echo "Install Docker repository"; }
|
||||
step_2() {
|
||||
# Add official docker GPG key
|
||||
exep "curl -fsSL ${dockerGpgKeyUrl} | sudo apt-key add -"
|
||||
|
||||
# Add stable repository
|
||||
exe add-apt-repository "deb [arch=amd64] ${dockerRepoUrl} $(lsb_release -cs) stable"
|
||||
endReturn -o $? "Failed to add Docker repository"
|
||||
exe apt update
|
||||
endReturn -o $? "Docker repository not available"
|
||||
}
|
||||
|
||||
step_3_info() { echo "Install latest Docker version"; }
|
||||
step_3() {
|
||||
# Install the latest version
|
||||
if [ $QUIET -ne 0 ] ; then
|
||||
aptOption="-y"
|
||||
else
|
||||
aptOption=""
|
||||
fi
|
||||
exe apt install $dockerPackages $aptOption
|
||||
|
||||
echo " [I] You may test the installation by running:"
|
||||
echo " sudo docker run hello-world"
|
||||
}
|
||||
|
||||
step_4_info() { echo "Replace Docker DNS entry"; }
|
||||
step_4() {
|
||||
exe sed -i "s/\(^#DOCKER_OPTS=.*\)$/#\1\n${dockerDnsEntry}/" "$dockerDefaultConf"
|
||||
exep "grep \"${dockerDns1}\" \"$dockerDefaultConf\" >>/dev/null"
|
||||
if [ $? -ne 0 ] ; then
|
||||
echoerr " [W] Docker dns entry could not be changed"
|
||||
fi
|
||||
}
|
||||
|
||||
step_5_info() {
|
||||
echoinfoArgs "[SECRET]"
|
||||
echo "Install/start onlyoffice docker container"
|
||||
echoinfo "If [SECRET] is empty, user input will be available if not run --quiet."
|
||||
echoinfo "$toolName will be run unsecured if no secret was provied."
|
||||
}
|
||||
step_5_alias() { ALIAS="startoo"; }
|
||||
step_5() {
|
||||
local options=
|
||||
local secret=
|
||||
|
||||
if [ ! -z "$2" ] ; then
|
||||
secret="$2"
|
||||
elif [ ! -z "$dockerSecret" ]; then
|
||||
secret="$dockerSecret"
|
||||
elif [ $QUIET -eq 0 ] ; then
|
||||
exe read -s -p "JWT Secret: " secret
|
||||
fi
|
||||
|
||||
# The correct expansion for missing SECRET or SECRET with spaces is not possible.
|
||||
# Therefore docker without secret needs to be called separately
|
||||
if [ ! -z "$secret" ] ; then
|
||||
options="-e JWT_ENABLED=true -e JWT_SECRET="
|
||||
# This is the only way to provide SECRET($2) to docker command line which handles all types of characters.
|
||||
exe docker run -i -t -d -p ${onlyOfficePort}:80 ${options}"$secret" --restart=always \
|
||||
-v /app/onlyoffice/DocumentServer/logs:/var/log/onlyoffice \
|
||||
-v /app/onlyoffice/DocumentServer/data:/var/www/onlyoffice/Data \
|
||||
-v /app/onlyoffice/DocumentServer/lib:/var/lib/onlyoffice \
|
||||
-v /app/onlyoffice/DocumentServer/db:/var/lib/postgresql "${dockerImageName}"
|
||||
else
|
||||
echoerr " [W] Running $toolName without JWT (JSON Web Tokens)"
|
||||
exe docker run -i -t -d -p ${onlyOfficePort}:80 --restart=always "${dockerImageName}"
|
||||
fi
|
||||
|
||||
unset secret
|
||||
}
|
||||
|
||||
step_7_info() { echo "Upgrade $toolName to latest version"; }
|
||||
step_7_alias() { ALIAS="upgrade"; }
|
||||
step_7() {
|
||||
# get container ID
|
||||
local containerId=$(docker ps -aqf ancestor="$dockerImageName")
|
||||
if [ ! -z $containerId ] ; then
|
||||
exe docker stop $containerId
|
||||
exe docker rm $containerId
|
||||
else
|
||||
echoerr " [W] No $toolName Docker container found"
|
||||
fi
|
||||
exe docker pull $dockerImageName
|
||||
endReturn -o $? "Error getting $toolName Docker update"
|
||||
|
||||
step startoo
|
||||
}
|
||||
|
||||
step_10_info() { echo "List running Docker container"; }
|
||||
step_10_alias() { ALIAS="ls"; }
|
||||
step_10() {
|
||||
exe docker container ls
|
||||
echo
|
||||
echo " [I] To stop a container run:"
|
||||
echo " docker stop [CONTAINER ID]"
|
||||
echo " e.g.: docker stop 70f1c5c81be2"
|
||||
}
|
||||
|
||||
step_12_info() {
|
||||
echo "Clean unused Docker data"
|
||||
echoinfo "(unused containers, dangling images, networks, build cache and volumes)"
|
||||
}
|
||||
step_12_alias() { ALIAS="prune"; }
|
||||
step_12() {
|
||||
exe docker system df
|
||||
exe docker system prune
|
||||
exe docker volume prune
|
||||
}
|
||||
|
||||
step_100_info() { echo "Uninstall Docker"; }
|
||||
step_100_alias() { ALIAS="uninstall"; }
|
||||
step_100() {
|
||||
exe apt-get purge docker-ce
|
||||
}
|
||||
|
||||
step_102_info() { echo "Purge images, containers, volumes, or customized configuration files"; }
|
||||
step_102_alias() { ALIAS="purge"; }
|
||||
step_102() {
|
||||
exe read -p "Are you sure y/[n]? " answer
|
||||
case $answer in
|
||||
[yY])
|
||||
exe service docker stop
|
||||
exe rm -rf /var/lib/docker
|
||||
;;
|
||||
*)
|
||||
return 0
|
||||
;;
|
||||
esac
|
||||
}
|
||||
|
||||
VERSION_SEQREV=15
|
||||
. /usr/local/bin/sequencer.sh
|
59
seqs/openvpn.sh
Executable file
59
seqs/openvpn.sh
Executable file
@@ -0,0 +1,59 @@
|
||||
#!/bin/bash
|
||||
|
||||
toolName=openvpn
|
||||
toolDeps=openvpn
|
||||
toolDefaultConf="/etc/default/openvpn"
|
||||
toolUserScriptsLoc="/usr/lib/openvpn"
|
||||
|
||||
# Get script working directory
|
||||
# (when called from a different directory)
|
||||
WDIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" >>/dev/null 2>&1 && pwd)"
|
||||
APTOPT=
|
||||
CONFIG=0
|
||||
SCRIPT_FILE=$(basename -- $0)
|
||||
SCRIPT_NAME=${SCRIPT_FILE%%.*}
|
||||
CONFIG_FILE_NAME="${SCRIPT_NAME}.cfg"
|
||||
CONFIG_FILE_TEMPLATE="$WDIR/${CONFIG_FILE_NAME}.example"
|
||||
CONFIG_DIR="$WDIR/$SCRIPT_NAME"
|
||||
|
||||
step_config() {
|
||||
#echo "Called once before executing steps."
|
||||
## e.g. to source a config file manually:
|
||||
#. "$CONFIG_FILE"
|
||||
## or to use sequencer api with global config file:
|
||||
#initSeqConfig "$CONFIG_FILE_NAME" "$CONFIG_FILE_TEMPLATE"
|
||||
## or to use sequencer api with profile config file support:
|
||||
#initSeqConfig -p "$SCRIPT_NAME" "$CONFIG_FILE_TEMPLATE"
|
||||
#if [ $? -eq 0 ] ; then
|
||||
# CONFIG=1
|
||||
#else
|
||||
# # End if no configuration file exists
|
||||
# [ $DRY -eq 0 ] && return -1
|
||||
#fi
|
||||
[ $QUIET -ne 0 ] && APTOPT="-y"
|
||||
return 0
|
||||
}
|
||||
|
||||
step_1_info() { echo "Install $toolName"; }
|
||||
step_1_alias() { ALIAS="install"; }
|
||||
step_1() {
|
||||
exe apt update
|
||||
exe apt install $toolDeps $APTOPT
|
||||
}
|
||||
|
||||
step_2_info() { echo "Install customized helper scripts to $toolUserScriptsLoc"; }
|
||||
step_2() {
|
||||
exep "mkdir \"$toolUserScriptsLoc\" 2>>/dev/null"
|
||||
[ $? -ne 0 ] && \
|
||||
echoseq " [W] $toolUserScriptsLoc already exists. Not overwriting existing files."
|
||||
exe cp -n "$CONFIG_DIR"/* "$toolUserScriptsLoc"
|
||||
}
|
||||
|
||||
step_10_info() { echo "Open openvpn system start configuration"; }
|
||||
step_10_alias() { ALIAS="default"; }
|
||||
step_10() {
|
||||
exe vi "$toolDefaultConf"
|
||||
}
|
||||
|
||||
VERSION_SEQREV=12
|
||||
. /usr/local/bin/sequencer.sh
|
5
seqs/openvpn/down.sh
Executable file
5
seqs/openvpn/down.sh
Executable file
@@ -0,0 +1,5 @@
|
||||
#! /bin/bash
|
||||
echo "Restoring original nameservers"
|
||||
rm -f /etc/resolv.conf
|
||||
cp -f /etc/resolv.conf.default /etc/resolv.conf
|
||||
echo "Done restoring nameservers cheers"
|
22
seqs/openvpn/my.conf
Normal file
22
seqs/openvpn/my.conf
Normal file
@@ -0,0 +1,22 @@
|
||||
# Set output verbosity (3 recommended by openvpn)
|
||||
# 0 -- No output except fatal errors.
|
||||
# 1 to 4 -- Normal usage range.
|
||||
# 5 -- Output R and W characters to the console for each packet read
|
||||
# and write, uppercase is used for TCP/UDP packets and lowercase is
|
||||
# used for TUN/TAP packets.
|
||||
# 6 to 11 -- Debug info range (see errlevel.h for additional informtion
|
||||
verb 1
|
||||
|
||||
# Always add custom nameserver
|
||||
#dhcp-option DNS 208.67.222.222
|
||||
#dhcp-option DNS 84.200.69.80
|
||||
|
||||
# Mute common false alarm on WiFi networks
|
||||
mute-replay-warnings
|
||||
|
||||
# Allow openvpn to call user defined scripts
|
||||
script-security 2
|
||||
|
||||
# Execute our custom up and down scripts
|
||||
up /usr/lib/openvpn/vpn-up
|
||||
down /usr/lib/openvpn/vpn-down
|
38
seqs/openvpn/up.sh
Executable file
38
seqs/openvpn/up.sh
Executable file
@@ -0,0 +1,38 @@
|
||||
#! /bin/bash
|
||||
DEV=$1
|
||||
|
||||
if [ ! -d /tmp/openvpn ]; then
|
||||
mkdir /tmp/openvpn
|
||||
fi
|
||||
CACHE_NAMESERVER="/tmp/$DEV.nameserver"
|
||||
echo -n "" > $CACHE_NAMESERVER
|
||||
|
||||
TEMP_LOG="/tmp/openvpn_dns.log"
|
||||
echo "DNS openvpn" > "$TEMP_LOG"
|
||||
echo -e "${foreign_option_1}\n${foreign_option_2}\n$foreign_option_3" >> "$TEMP_LOG"
|
||||
|
||||
rm -rf /tmp/resolv.conf
|
||||
touch /tmp/resolv.conf
|
||||
dns=dns
|
||||
for opt in ${!foreign_option_*}
|
||||
do
|
||||
eval "echo \$$opt" >> "$TEMP_LOG"
|
||||
eval "dns=\${$opt#dhcp-option DNS }"
|
||||
if [[ $dns =~ [0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3} ]]; then
|
||||
if [ ! -f /etc/resolv.conf.default ]; then
|
||||
cp /etc/resolv.conf /etc/resolv.conf.default
|
||||
fi
|
||||
|
||||
# don't add "local" dns server
|
||||
#cat /etc/resolv.conf | grep -v ^# | grep -v ^nameserver > /tmp/resolv.conf
|
||||
|
||||
echo "nameserver $dns" >> /tmp/resolv.conf
|
||||
echo $dns >> $CACHE_NAMESERVER
|
||||
#cat /etc/resolv.conf | grep -v ^# | grep -v "nameserver $dns" | grep nameserver >> /tmp/resolv.conf
|
||||
|
||||
fi
|
||||
done
|
||||
|
||||
if [ -e "/tmp/resolv.conf" ]; then
|
||||
mv /tmp/resolv.conf /etc/resolv.conf
|
||||
fi
|
13
seqs/openvpn/vpn-down
Executable file
13
seqs/openvpn/vpn-down
Executable file
@@ -0,0 +1,13 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Manage nameserver with resolvconf
|
||||
#/etc/openvpn/update-resolv-conf
|
||||
|
||||
# Manage nameserver with /etc/resolv.conf only
|
||||
#/usr/lib/openvpn/down.sh $@
|
||||
|
||||
# Delete route to internal network
|
||||
#/usr/sbin/ip route del 10.5.0.0/24 via 192.168.0.20 dev eth0
|
||||
|
||||
# Stop services only active while vpn is connected
|
||||
/usr/lib/openvpn/vpn-services stop
|
15
seqs/openvpn/vpn-services
Executable file
15
seqs/openvpn/vpn-services
Executable file
@@ -0,0 +1,15 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Default or unrecognized stops the listed services
|
||||
serviceOp="stop"
|
||||
serviceCtl="$(command -v systemctl) -q"
|
||||
|
||||
case $1 in
|
||||
start|restart|stop)
|
||||
serviceOp="$1";;
|
||||
*)
|
||||
>&2 echo "Unrecognized argument. Stopping services"
|
||||
serviceOp="stop";;
|
||||
esac
|
||||
|
||||
#"$serviceCtl" $serviceOp danted
|
16
seqs/openvpn/vpn-up
Executable file
16
seqs/openvpn/vpn-up
Executable file
@@ -0,0 +1,16 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Make sure firewall is active
|
||||
#ufw --force enable
|
||||
|
||||
# Manage nameserver with resolvconf
|
||||
#/etc/openvpn/update-resolv-conf
|
||||
|
||||
# Manage nameserver with /etc/resolv.conf only
|
||||
#/usr/lib/openvpn/up.sh $@
|
||||
|
||||
# Add route to internal network
|
||||
#/usr/sbin/ip route add 10.5.0.0/24 via 192.168.0.20 dev eth0
|
||||
|
||||
# Start services only active while vpn is connected
|
||||
/usr/lib/openvpn/vpn-services start
|
32
seqs/paperless.sh
Executable file
32
seqs/paperless.sh
Executable file
@@ -0,0 +1,32 @@
|
||||
#!/bin/bash
|
||||
|
||||
step_1_info() { echo "Install python3"; }
|
||||
step_1() {
|
||||
exe apt update
|
||||
exe apt install python3 python3-pip
|
||||
}
|
||||
|
||||
step_2_info() { echo "Get paperless using git (checkout 2.7.0)"; }
|
||||
step_2() {
|
||||
exe git clone https://github.com/the-paperless-project/paperless.git /opt/paperless
|
||||
exe cd /opt/paperless && git checkout 2.7.0
|
||||
}
|
||||
|
||||
step_3_info() { echo "Install other dependcies"; }
|
||||
step_3() {
|
||||
exe apt install gnupg tesseract-ocr tesseract-ocr-deu imagemagick unpaper libpoppler-cpp-dev optipng
|
||||
exe pip3 install --user --requirement /opt/paperless/requirements.txt
|
||||
}
|
||||
|
||||
step_4_info() { echo "Paperless configuration file"; }
|
||||
step_4() {
|
||||
if [ ! -f /etc/paperless.conf ] ; then
|
||||
cp -ar paperless.conf.example /etc/paperless.conf
|
||||
else
|
||||
echo "[ WARN ] Configuration already exists. Doing nothing"
|
||||
fi
|
||||
}
|
||||
|
||||
VERSION_SEQREV=3
|
||||
|
||||
. sequencer.sh
|
5
seqs/piwigo.cfg.example
Normal file
5
seqs/piwigo.cfg.example
Normal file
@@ -0,0 +1,5 @@
|
||||
#!/bin/bash
|
||||
|
||||
PIWI_DIR="/var/www/piwigo"
|
||||
PIWI_BU_DIR="/root/backup/piwigodb"
|
||||
PIWI_DB_NAME="piwigo29_db"
|
52
seqs/piwigo.sh
Executable file
52
seqs/piwigo.sh
Executable file
@@ -0,0 +1,52 @@
|
||||
#!/bin/bash
|
||||
|
||||
#
|
||||
## Installation and management of piwigo gallery
|
||||
|
||||
toolName="piwigo"
|
||||
toolVersion="11.3.0"
|
||||
|
||||
# Get script working directory
|
||||
# (when called from a different directory)
|
||||
WDIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" >>/dev/null 2>&1 && pwd )"
|
||||
CONFIG=0
|
||||
SCRIPT_NAME=$(basename -- "$0")
|
||||
SCRIPT_NAME=${SCRIPT_NAME%%.*}
|
||||
CONFIG_FILE_NAME="${SCRIPT_NAME}.cfg"
|
||||
CONFIG_FILE_TEMPLATE="$WDIR/${CONFIG_FILE_NAME}.example"
|
||||
|
||||
step_config() {
|
||||
initSeqConfig "$CONFIG_FILE_NAME" "$CONFIG_FILE_TEMPLATE"
|
||||
if [ $? -eq 0 ] ; then
|
||||
CONFIG=1
|
||||
else
|
||||
[ $DRY -eq 0 ] && return 1
|
||||
fi
|
||||
}
|
||||
|
||||
step_30_info() { echo "Backup ${toolName} web direcotry"; }
|
||||
step_30_alias() { ALIAS="backup"; }
|
||||
step_30() {
|
||||
exep "cd \"${PIWI_DIR}\"/.. && tar czf \"${PIWI_BU_DIR}/\`date +%Y%m%d\`_${toolName}_web.tar.gz\" --exclude=\"${toolName}/network/*\" --exclude=\"${toolName}/_data/i/*\" \"$(basename "$PIWI_DIR")\""
|
||||
}
|
||||
|
||||
step_31_info() {
|
||||
echoinfoArgs "[daily|monthly(default]"
|
||||
echo "Backup ${toolName} database"
|
||||
}
|
||||
step_31_alias() { ALIAS="backupdb"; }
|
||||
step_31() {
|
||||
case "$2" in
|
||||
daily|Daily|DAILY)
|
||||
[ $QUIET -ne 2 ] && echo " [I] Daily backup..."
|
||||
exep "mysqldump --single-transaction -u root ${PIWI_DB_NAME} | bzip2 -c > \"${PIWI_BU_DIR}/${toolName}_daily.sql.bz2\""
|
||||
;;
|
||||
*)
|
||||
[ $QUIET -ne 2 ] && echo " [I] Monthly backup..."
|
||||
exep "mysqldump --single-transaction -u root ${PIWI_DB_NAME} | bzip2 -c > \"${PIWI_BU_DIR}/monthly/\`date +%Y%m%d\`_${toolName}.sql.bz2\""
|
||||
;;
|
||||
esac
|
||||
}
|
||||
|
||||
VERSION_SEQREV=14
|
||||
. /usr/local/bin/sequencer.sh
|
278
seqs/pixelfed.sh
Executable file
278
seqs/pixelfed.sh
Executable file
@@ -0,0 +1,278 @@
|
||||
#!/bin/bash
|
||||
|
||||
toolName="pixelfed"
|
||||
toolTag="dev"
|
||||
toolDeps="composer jpegoptim php7.3-bcmath php-imagick"
|
||||
toolPath="/var/www/pixelfed"
|
||||
|
||||
step_1_info() { echo "Updating apt"; }
|
||||
step_1_alias() { ALIAS="install"; }
|
||||
step_1() {
|
||||
exe apt update
|
||||
}
|
||||
|
||||
step_2_info() { echo -e "Installing $toolName dependencies: $toolDeps"; }
|
||||
step_2() {
|
||||
exe apt install $toolDeps -y
|
||||
endReturn -o $? "Installing deps for $toolName failed"
|
||||
exe service php7.3-fpm restart
|
||||
endReturn -o $? "Problems starting $toolName"
|
||||
}
|
||||
|
||||
step_3_info() { echo -e "Get $toolName using git"; }
|
||||
step_3() {
|
||||
exe git clone -b $toolTag https://github.com/pixelfed/pixelfed.git $toolPath
|
||||
exe cd $toolPath
|
||||
exe chown -R www-data:www-data . # change user/group to http user and http group
|
||||
exe find . -type d -exec chmod 755 {} \; # set all directories to rwx by user/group
|
||||
exe find . -type f -exec chmod 644 {} \; # set all files to rw by user/group
|
||||
exe composer install --no-ansi --no-interaction --optimize-autoloader
|
||||
endReturn -o $? "Composer install error"
|
||||
}
|
||||
|
||||
step_4_info() { echo "Create mysql database for $toolName"; }
|
||||
step_4() {
|
||||
local mysqlDatabase
|
||||
local mysqlUser
|
||||
local mysqlPass
|
||||
|
||||
echo "Existing mysql databases:"
|
||||
exe mysql -u root -e 'SHOW DATABASES;'
|
||||
|
||||
echo -en "Enter database name: "
|
||||
exe read mysqlDatabase
|
||||
endCheckEmpty mysqlDatabase "database name"
|
||||
exe mysql -u root -e 'CREATE DATABASE '$mysqlDatabase' CHARACTER SET utf8mb4;'
|
||||
endReturn -o $? "Creating database failed"
|
||||
|
||||
echo "Existing mysql user:"
|
||||
exe mysql -u root -e 'SELECT User, Host FROM mysql.user;'
|
||||
echo -en "Enter mysql user name: "
|
||||
read mysqlUser
|
||||
endCheckEmpty mysqlDatabase "user name"
|
||||
|
||||
echo -en "Enter mysql user password: "
|
||||
read -s mysqlPass
|
||||
endCheckEmpty mysqlPass "password"
|
||||
exe mysql -u root -e 'CREATE USER '"'"$mysqlUser"'"'@'"'"'localhost'"'"' IDENTIFIED BY '"'"$mysqlPass"'"';'
|
||||
endReturn -o $? "Creating database user \"${mysqlUser}\" failed";
|
||||
|
||||
exe mysql -u root -e 'GRANT ALL PRIVILEGES ON '$mysqlDatabase'.* TO '"'"$mysqlUser"'"'@'"'"'localhost'"'"';'
|
||||
endReturn -o $? "Granting privileges for user \"${mysqlUser}\" failed";
|
||||
|
||||
exe mysql -u root -e 'FLUSH PRIVILEGES;'
|
||||
}
|
||||
|
||||
step_5_info() { echo "$toolName configuration"; }
|
||||
step_5() {
|
||||
exe cd $toolPath
|
||||
exe cp .env.example .env
|
||||
exe read -p "Edit database settings, hostname, email settings, IMAGE_DRIVER=imagick, etc... (Enter to continue)"
|
||||
exe vi .env
|
||||
exe php artisan key:generate
|
||||
exe php artisan config:cache
|
||||
exe php artisan storage:link
|
||||
exe php artisan migrate --force
|
||||
exe php artisan route:cache
|
||||
# Needed for using oauth (app like pixeldroid)
|
||||
# https://github.com/pixelfed/pixelfed/issues/2654
|
||||
exe php artisan passport:install
|
||||
}
|
||||
|
||||
step_6_info() { echo "Create admin user"; }
|
||||
step_6() {
|
||||
exe cd $toolPath
|
||||
exe read -p "Create admin user. (Enter to continue)"
|
||||
exe php artisan user:create
|
||||
}
|
||||
|
||||
step_7_info() { echo "Create pixelfed (horzion) service"; }
|
||||
step_7() {
|
||||
addConf -c "${horizonService}" "${horizonServiceLoc}"
|
||||
endReturn -o $? "Failed to add horizon service"
|
||||
exe systemctl daemon-reload
|
||||
exe systemctl enable pixelfed.service
|
||||
exe service pixelfed start
|
||||
}
|
||||
horizonServiceLoc="/etc/systemd/system/pixelfed.service"
|
||||
horizonService="\
|
||||
[Unit]
|
||||
Description=${toolName}s' Horizon
|
||||
After=syslog.target
|
||||
After=network.target
|
||||
#Requires=mysql.service
|
||||
Requires=mariadb.service
|
||||
#Requires=postgresql.service
|
||||
#Requires=memcached.service
|
||||
#Requires=redis.service
|
||||
|
||||
[Service]
|
||||
# Modify these two values and uncomment them if you have
|
||||
# repos with lots of files and get an HTTP error 500 because
|
||||
# of that
|
||||
###
|
||||
#LimitMEMLOCK=infinity
|
||||
#LimitNOFILE=65535
|
||||
RestartSec=2s
|
||||
Type=simple
|
||||
User=www-data
|
||||
Group=www-data
|
||||
WorkingDirectory=${toolPath}/
|
||||
ExecStart=/usr/bin/php ${toolPath}/artisan horizon
|
||||
Restart=always
|
||||
Environment=
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target"
|
||||
|
||||
step_8_info() { echo "Create scheduler cron job"; }
|
||||
step_8_alias() { ALIAS="scheduler"; }
|
||||
step_8() {
|
||||
addConf -s "$schedulerCmd" "$schedulerCron"
|
||||
}
|
||||
schedulerCron="/etc/cron.d/pixelfedScheduler"
|
||||
schedulerCmd="* * * * * cd ${toolPath} && php artisan schedule:run >>/dev/null 2>&1"
|
||||
|
||||
step_9_info() { echo "Nginx configuration"; }
|
||||
step_9() {
|
||||
addConf -c "$nginxConfig" "$nginxConfigLoc"
|
||||
exe ln -s "$nginxConfigLoc" "$nginxConfigEnable"
|
||||
exe nginx -t
|
||||
endReturn -o $? "Nginx configuration check error"
|
||||
exe service nginx restart
|
||||
}
|
||||
|
||||
nginxConfigLoc="/etc/nginx/sites-available/pixelfed"
|
||||
nginxConfigEnable="/etc/nginx/sites-enabled/pixelfed"
|
||||
nginxConfig="\
|
||||
upstream php-handler-pixel {
|
||||
server unix:/var/run/php/php7.3-fpm.sock;
|
||||
}
|
||||
|
||||
map \$http_x_forwarded_proto \$proxy_https {
|
||||
default '';
|
||||
https 'on';
|
||||
}
|
||||
|
||||
server {
|
||||
listen 80;
|
||||
listen [::]:80;
|
||||
|
||||
add_header X-Frame-Options \"SAMEORIGIN\";
|
||||
add_header X-XSS-Protection \"1; mode=block\";
|
||||
add_header X-Content-Type-Options \"nosniff\";
|
||||
|
||||
# Path to the root of your installation
|
||||
root ${toolPath}/public;
|
||||
index index.html index.htm index.php;
|
||||
|
||||
charset utf-8;
|
||||
client_max_body_size 64M;
|
||||
|
||||
location / {
|
||||
try_files \$uri \$uri/ /index.php?\$query_string;
|
||||
}
|
||||
|
||||
location = /favicon.ico { access_log off; log_not_found off; }
|
||||
location = /robots.txt { access_log off; log_not_found off; }
|
||||
|
||||
error_page 404 /index.php;
|
||||
|
||||
location ~ \\.php$ {
|
||||
try_files \$uri =404;
|
||||
fastcgi_split_path_info ^(.+\\.php)(/.+)$;
|
||||
fastcgi_pass php-handler-pixel;
|
||||
fastcgi_index index.php;
|
||||
include fastcgi_params;
|
||||
fastcgi_param SCRIPT_FILENAME \$request_filename;
|
||||
fastcgi_param PATH_INFO \$fastcgi_path_info;
|
||||
# fix preview problem
|
||||
fastcgi_param REQUEST_SCHEME \$http_x_forwarded-proto;
|
||||
fastcgi_param HTTPS \$proxy_https if_not_empty;
|
||||
}
|
||||
|
||||
location ~ /\\.(?!well-known).* {
|
||||
deny all;
|
||||
}
|
||||
}"
|
||||
|
||||
step_20_info() { echo "Reload configuration (.env)"; }
|
||||
step_20_alias() { ALIAS="newenv"; }
|
||||
step_20() {
|
||||
exe cd $toolPath
|
||||
exe php artisan config:cache
|
||||
exe service pixelfed restart
|
||||
}
|
||||
|
||||
step_22_info() { echo "Create new user"; }
|
||||
step_22_alias() { ALIAS="createuser"; }
|
||||
step_22() {
|
||||
exe cd $toolPath
|
||||
exe php artisan user:create
|
||||
}
|
||||
|
||||
step_24_info() { echo "Checkout to dev branch. Losing local changes!"; }
|
||||
step_24_alias() { ALIAS="forcedev"; }
|
||||
step_24() {
|
||||
exe read -p "Are you sure: y/[n]? " answer
|
||||
if [ $DRY -eq 0 ] ; then
|
||||
case $answer in
|
||||
[yY])
|
||||
;;
|
||||
*)
|
||||
return 1
|
||||
;;
|
||||
esac
|
||||
fi
|
||||
exe cd $toolPath
|
||||
exe git fetch --all
|
||||
exe git reset --hard origin/dev
|
||||
exe git pull origin dev
|
||||
exe git checkout dev
|
||||
}
|
||||
|
||||
step_100_info() { echo "Upgrade \"${toolPath}\" to supported tag $toolTag"; }
|
||||
step_100_alias() { ALIAS="upgrade"; }
|
||||
step_100() {
|
||||
exe cd $toolPath
|
||||
exe git pull origin $toolTag
|
||||
endReturn -o $? "git pull failed"
|
||||
exe git checkout $toolTag
|
||||
endReturn -o $? "git checkout failed"
|
||||
}
|
||||
|
||||
step_101_info() { echo "Recommended post update procedure"; }
|
||||
step_101_alias() { ALIAS="postupdate"; }
|
||||
step_101() {
|
||||
exe cd $toolPath
|
||||
exe composer install
|
||||
exe php artisan config:cache
|
||||
exe php artisan route:cache
|
||||
exe php artisan view:cache
|
||||
exe php artisan cache:clear
|
||||
exe php artisan migrate --force
|
||||
exe php artisan horizon:purge
|
||||
exe php artisan horizon:publish
|
||||
exe php artisan storage:link
|
||||
exe php artisan instance:actor
|
||||
echo -n " [I] Restarting pixelfed horzion service..."
|
||||
exe service pixelfed restart && echo "ok"
|
||||
}
|
||||
|
||||
# Src: https://docs.pixelfed.org/running-pixelfed/troubleshooting.html
|
||||
step_102_info() { echo "Fix if horizon services is running but not showing the administration interface"; }
|
||||
step_102_alias() { ALIAS="fixhorizon"; }
|
||||
step_102() {
|
||||
exe cd $toolPath
|
||||
exe php artisan package:discover
|
||||
exe php artisan horizon:install
|
||||
exe php artisan route:cache
|
||||
echo -n " [I] Restarting pixelfed horzion service..."
|
||||
exe service pixelfed restart && echo "ok"
|
||||
}
|
||||
|
||||
# Sequence Revision
|
||||
VERSION_SEQREV=7
|
||||
|
||||
# Path to sequencer
|
||||
. sequencer.sh
|
9
seqs/postfixadmin.cfg.example
Normal file
9
seqs/postfixadmin.cfg.example
Normal file
@@ -0,0 +1,9 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Postfixamdin configuration
|
||||
|
||||
PFA_SRV_LOC="/srv/postfixadmin"
|
||||
PFA_WEB_LOC="/var/www/pfa"
|
||||
PFA_DATABASE="pfa_db"
|
||||
PFA_BACKUP="/root/backup/pfa"
|
||||
PFA_PHP_VERSION="7.3"
|
328
seqs/postfixadmin.sh
Executable file
328
seqs/postfixadmin.sh
Executable file
@@ -0,0 +1,328 @@
|
||||
#!/bin/bash
|
||||
|
||||
toolName=postfixadmin
|
||||
toolPhpDeps='php${PFA_PHP_VERSION}-fpm php${PFA_PHP_VERSION}-imap php${PFA_PHP_VERSION}-mbstring php${PFA_PHP_VERSION}-mysql php${PFA_PHP_VERSION}-json php${PFA_PHP_VERSION}-curl php${PFA_PHP_VERSION}-zip php${PFA_PHP_VERSION}-xml php${PFA_PHP_VERSION}-bz2 php${PFA_PHP_VERSION}-intl php${PFA_PHP_VERSION}-gmp'
|
||||
toolConfName="config.local.php"
|
||||
toolTemplates="templates_c"
|
||||
toolTemplatesLoc="$PFA_SRV_LOC/$toolTemplates"
|
||||
toolAdditionsLoc="$PFA_SRV_LOC/ADDITIONS"
|
||||
latestUrl="https://api.github.com/repos/$toolName/$toolName/releases/latest"
|
||||
fetchmailUser="fetchmail"
|
||||
fetchmailDeps="fetchmail liblockfile-simple-perl"
|
||||
|
||||
# Get script working directory
|
||||
# (when called from a different directory)
|
||||
WDIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >>/dev/null 2>&1 && pwd )"
|
||||
CONFIG=0
|
||||
CONFIG_FILE_NAME="${toolName}.cfg"
|
||||
CONFIG_FILE_TEMPLATE="$WDIR/${CONFIG_FILE_NAME}.example"
|
||||
|
||||
step_config() {
|
||||
initSeqConfig "$CONFIG_FILE_NAME" "$CONFIG_FILE_TEMPLATE"
|
||||
if [ $? -eq 0 ] ; then
|
||||
echo " ${toolName} path: ${PFA_WEB_LOC}"
|
||||
echo " ${toolName} backup: ${PFA_BACKUP}"
|
||||
echo " php Version: ${PFA_PHP_VERSION}"
|
||||
CONFIG=1
|
||||
fi
|
||||
}
|
||||
|
||||
step_1_info() {
|
||||
# eval needed to expand sourced configuration variables
|
||||
local localDeps=`eval "echo \"$toolPhpDeps\""`
|
||||
echo "Install $toolName dependencies:"
|
||||
echoinfo "$localDeps"
|
||||
}
|
||||
step_1_alias() { ALIAS="install"; }
|
||||
step_1() {
|
||||
# eval needed to expand sourced configuration variables
|
||||
local localDeps=`eval "echo \"$toolPhpDeps\""`
|
||||
local aptOpt=
|
||||
if [ $QUIET -ne 0 ];then
|
||||
aptOpt="-y"
|
||||
fi
|
||||
exe apt update
|
||||
exe apt install $localDeps $aptOpt
|
||||
}
|
||||
|
||||
step_2_info() { echo "Install $toolName to $PFA_SRV_LOC"; }
|
||||
step_2() {
|
||||
step upgrade
|
||||
}
|
||||
|
||||
step_3_info() { echo "Install fetchmail"; }
|
||||
step_3_alias() { ALIAS="install_fetchmail"; }
|
||||
step_3() {
|
||||
local aptOpt=
|
||||
if [ $QUIET -ne 0 ];then
|
||||
aptOpt="-y"
|
||||
fi
|
||||
exe apt install $fetchmailDeps $aptOpt
|
||||
endReturn -o $? "Failed to install fetchmail"
|
||||
exe systemctl stop fetchmail
|
||||
exe systemctl disable fetchmail
|
||||
}
|
||||
|
||||
step_4_info() { echo "Configure postfixadmin to use fetchmail"; }
|
||||
step_4() {
|
||||
echo "# Create mysql config"
|
||||
echo " [$PFA_SRV_LOC/fetchmail.conf]"
|
||||
echo " # Follow instructions in $toolAdditionsLoc/fetchmail.pl"
|
||||
echo " \$db_type = 'mysql';"
|
||||
echo " \$run_dir=\"/var/lock\";"
|
||||
echo
|
||||
echo " [$toolAdditionsLoc/fetchmail.pl]"
|
||||
echo " # Change path to fetchmail.conf (see above)"
|
||||
echo
|
||||
echo " [I] Run step \"timer\" when configuration is done"
|
||||
}
|
||||
|
||||
step_6_info() {
|
||||
echo "Create postfixadmin fetchmail systemd timer and reduce syslog entries"
|
||||
echoinfo "Needs to start after the mysql service"
|
||||
}
|
||||
step_6_alias() { ALIAS="timer"; }
|
||||
step_6() {
|
||||
# eval needed to expand sourced configuration variables
|
||||
local localService=`eval "echo \"$fetchPluginService\""`
|
||||
|
||||
addConf -s "$localService" "$fetchPluginServiceLoc"
|
||||
addConf -s "$fetchPluginTimer" "$fetchPluginTimerLoc"
|
||||
exe systemctl enable --now ${fetchPluginServiceName}.timer
|
||||
|
||||
addConf -s "$fetchPluginRsyslog" "$fetchPluginRsyslogLoc"
|
||||
exe service rsyslog restart
|
||||
}
|
||||
fetchPluginServiceName="pfafetchmail"
|
||||
fetchPluginServiceLoc="/etc/systemd/system/${fetchPluginServiceName}.service"
|
||||
fetchPluginService="[Unit]
|
||||
Description=Postfix fetchmail plugin
|
||||
After=mysql.service
|
||||
|
||||
[Service]
|
||||
# emerg (lowest log level, only highest priority messages),
|
||||
# alert, crit, err, warning, notice, info, debug
|
||||
LogLevelMax=notice
|
||||
User=$fetchmailUser
|
||||
ExecStart=\${PFA_SRV_LOC}/ADDITIONS/fetchmail.pl >>/dev/null
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target"
|
||||
fetchPluginTimerLoc="/etc/systemd/system/${fetchPluginServiceName}.timer"
|
||||
fetchPluginTimer="[Unit]
|
||||
Description=Postfix fetchmail plugin execute every minute
|
||||
|
||||
[Timer]
|
||||
OnCalendar=minutely
|
||||
Persistent=true
|
||||
|
||||
[Install]
|
||||
WantedBy=basic.target"
|
||||
fetchPluginRsyslogLoc="/etc/rsyslog.d/31-fetchmailreduce.conf"
|
||||
fetchPluginRsyslog="if \$programname == 'systemd' and re_match(\$msg, \"Started.*fetchmail\") then stop
|
||||
if \$programname == 'systemd' and re_match(\$msg, \"fetchmail.*Succeeded\") then stop"
|
||||
|
||||
step_7_info() { echo "Create separate log file for fetchmail using rsyslog"; }
|
||||
step_7_alias() { ALIAS="newlog"; }
|
||||
step_7() {
|
||||
addConf -f "$fetchmailRsyslog" "$fetchmailRsyslogLoc"
|
||||
addConf -f "$fetchmailRotate" "$fetchmailRotateLoc"
|
||||
exe service rsyslog restart
|
||||
}
|
||||
fetchmailLogLoc="/var/log/fetchmail.log"
|
||||
fetchmailRotateLoc="/etc/logrotate.d/fetchmail"
|
||||
fetchmailRotate="$fetchmailLogLoc {
|
||||
rotate 14
|
||||
weekly
|
||||
missingok
|
||||
daily
|
||||
compress
|
||||
delaycompress
|
||||
}"
|
||||
fetchmailRsyslogLoc="/etc/rsyslog.d/30-fetchmail.conf"
|
||||
fetchmailRsyslog="if \$programname == 'fetchmail' or \$programname == 'fetchmail-all' then $fetchmailLogLoc
|
||||
& stop"
|
||||
|
||||
step_18_info() { echoinfoArgs "[NEW VERSION]"; echo "Check for updates"; }
|
||||
step_18_alias() { ALIAS="updatecheck"; }
|
||||
step_18() {
|
||||
shift
|
||||
local isInstalled=
|
||||
local latestVersion=
|
||||
if [ ! -z $1 ] ; then
|
||||
latestVersion="$1"
|
||||
else
|
||||
latestVersion=$(curl --silent "$latestUrl" | grep -Po '"tag_name": "postfixadmin-\K.*?(?=")')
|
||||
fi
|
||||
|
||||
isInstalled=$(grep -E "${latestVersion}" "${PFA_WEB_LOC}/version" >>/dev/null 2>&1 && echo "1" || echo "0")
|
||||
if [ $isInstalled -eq 1 ] ; then
|
||||
echo " [I] Version $latestVersion is already installed"
|
||||
return 1
|
||||
else
|
||||
echo " [I] Update to $latestVersion available"
|
||||
fi
|
||||
return 0
|
||||
}
|
||||
|
||||
|
||||
step_20_info() {
|
||||
echoinfoArgs "[POSTFIXADMIN SRV ROOT]"
|
||||
echo -n "Create a backup"
|
||||
if [ $CONFIG -ne 0 ] ; then
|
||||
echo " at $PFA_BACKUP"
|
||||
else
|
||||
echo
|
||||
fi
|
||||
}
|
||||
step_20_alias() { ALIAS="backup"; }
|
||||
step_20() {
|
||||
shift
|
||||
local tempRoot=
|
||||
if [ $CONFIG -eq 0 ] ; then
|
||||
echoerr " [E] No configuration file found"
|
||||
return 1
|
||||
fi
|
||||
if [ ! -z $PFA_BACKUP ] ; then
|
||||
exe mkdir -p "$PFA_BACKUP"
|
||||
fi
|
||||
if [ ! -z $1 ] ; then
|
||||
tempRoot="$1"
|
||||
else
|
||||
tempRoot="$PFA_SRV_LOC"
|
||||
fi
|
||||
|
||||
local srvBackup="$PFA_BACKUP/${toolName}_`date +%Y%m%d-%H%M%S`.tar.gz"
|
||||
echo " [I] Backing up server directory to $srvBackup"
|
||||
exe cd "$tempRoot/.."
|
||||
exe tar czf "$srvBackup" $(basename "$tempRoot")
|
||||
|
||||
exe $WDIR/mysql.sh -qq backup "$PFA_DATABASE" "$PFA_BACKUP"
|
||||
}
|
||||
|
||||
step_22_info() {
|
||||
echoinfoArgs "[CUSTOM VERSION]"
|
||||
shift
|
||||
if [ $CONTEXT_EXE -ne 0 ]; then
|
||||
echoinfo -n "Upgrade to version "
|
||||
if [ -z "$1" ]; then
|
||||
echo -n "$(curl --silent "$latestUrl" | grep -Po '"tag_name": "postfixadmin-\K.*?(?=")')"
|
||||
else
|
||||
echo -n "$1"
|
||||
fi
|
||||
echo " from github"
|
||||
else
|
||||
echo "Upgrade to latest or a custom version from github"
|
||||
fi
|
||||
}
|
||||
step_22_alias() { ALIAS="upgrade"; }
|
||||
step_22() {
|
||||
shift # don't need step number
|
||||
local latestVersion=
|
||||
if [ ! -z $1 ] ; then
|
||||
latestVersion="$1"
|
||||
else
|
||||
latestVersion=$(curl --silent "$latestUrl" | grep -Po '"tag_name": "postfixadmin-\K.*?(?=")')
|
||||
fi
|
||||
|
||||
if [ -z $latestVersion ] ; then
|
||||
echoerr " [E] Cannot determine latest version from github repository"
|
||||
return 1
|
||||
elif [ $QUIET -eq 0 ] ; then
|
||||
echo
|
||||
exe read -p "Install $latestVersion to $PFA_SRV_LOC [n]o/(y)es? " answer
|
||||
case $answer in
|
||||
[yY])
|
||||
;;
|
||||
*)
|
||||
echoerr " [I] Upgrade aborted"
|
||||
return 1
|
||||
;;
|
||||
esac
|
||||
fi
|
||||
|
||||
# Major versions are stated in the CHANGELOG.TXT without the trailing minor version e.g. "3.3" for "3.3.0"
|
||||
# Trailing ".0" is removed if exists
|
||||
local isInstalled=$(grep -E "Version ${latestVersion%.0} " "${PFA_SRV_LOC}/CHANGELOG.TXT" >>/dev/null 2>&1 && echo "1" || echo "0")
|
||||
if [ $isInstalled -eq 1 ] ; then
|
||||
echoerr " [E] Version $latestVersion is already installed"
|
||||
return 2
|
||||
fi
|
||||
|
||||
# Download
|
||||
local downUrl="https://github.com/$toolName/$toolName/archive/postfixadmin-${latestVersion}.tar.gz"
|
||||
local tempExtract="$tempDown/postfixadmin-postfixadmin-$latestVersion"
|
||||
|
||||
if [ ! -e "$tempExtract" ] ; then
|
||||
exe mkdir -p "$tempDown"
|
||||
exe wget -O "$tempLoc" $downUrl
|
||||
endReturn -o $? "Download failed: $downUrl"
|
||||
exe cd "$tempDown"
|
||||
exe tar -xf "$tempLoc"
|
||||
endReturn -o $? "Extract failed: $tempLoc"
|
||||
else
|
||||
echo " [I] Found existing download: $tempExtract"
|
||||
fi
|
||||
|
||||
# Installation
|
||||
local tempBu="${PFA_SRV_LOC}_bu_`date +%Y%m%d-%H%M%S`"
|
||||
|
||||
if [ -e "$PFA_SRV_LOC" ] ; then
|
||||
exe mv "$PFA_SRV_LOC" "$tempBu"
|
||||
step backup "$tempBu"
|
||||
endReturn -o $? "Backup failed; $PFA_SRV_LOC renamed!"
|
||||
fi
|
||||
echo " [I] Installing version $latestVersion to $PFA_SRV_LOC"
|
||||
exe cp -ar "$tempExtract" "$PFA_SRV_LOC"
|
||||
exe mkdir -p $(dirname "$PFA_WEB_LOC")
|
||||
echo " [I] Create symlink to $PFA_WEB_LOC"
|
||||
exe ln -fs "$PFA_SRV_LOC/public" "$PFA_WEB_LOC"
|
||||
|
||||
# Setting file permissions
|
||||
exe chown -R www-data: "$PFA_SRV_LOC/public"
|
||||
|
||||
# Configuration
|
||||
local webConf="$tempBu/$toolConfName"
|
||||
if [ -e "$webConf" ] ; then
|
||||
echo " [I] Copying configuration"
|
||||
exe cp -ar "$webConf" "$PFA_SRV_LOC/"
|
||||
else
|
||||
echo " [I] Creating empty configuration file $PFA_SRV_LOC/$toolConfName"
|
||||
exep "echo -e \"# Created gy $WDIR/$(basename $0)\\n\\n# Changeme\" > \"$PFA_SRV_LOC/$toolConfName\""
|
||||
fi
|
||||
|
||||
# Templates
|
||||
local templatesLoc="$tempBu/$toolTemplates"
|
||||
if [ -e "$templatesLoc" ] ; then
|
||||
echo " [I] Copying $toolTemplates"
|
||||
exe cp -ar "$templatesLoc" "$toolTemplatesLoc"
|
||||
else
|
||||
echo " [I] Creating empty directory $toolTemplatesLoc"
|
||||
exe mkdir -p "$toolTemplatesLoc"
|
||||
exe chown -R www-data: "$toolTemplatesLoc"
|
||||
fi
|
||||
|
||||
exe rm -rf "$tempBu"
|
||||
}
|
||||
tempDown="/tmp/${toolName}"
|
||||
tempLoc="$tempDown/${toolName}.tar.gz"
|
||||
|
||||
step_23_info() { echo "Clean temporary files: $tempDown"; }
|
||||
step_23_alias() { ALIAS="clean"; }
|
||||
step_23() {
|
||||
exe rm -rf "$tempDown"
|
||||
}
|
||||
|
||||
step_100_info() {
|
||||
echoinfoArgs "[OPTIONS]"
|
||||
echo "Execute $toolName client script"
|
||||
echoinfo "[OPTIONS] are passed on to $toolName-cli unmodified"
|
||||
}
|
||||
step_100_alias() { ALIAS="cli"; }
|
||||
step_100() {
|
||||
shift
|
||||
exe ${PFA_SRV_LOC}/scripts/$toolName-cli $@
|
||||
}
|
||||
|
||||
VERSION_SEQREV=14
|
||||
. /usr/local/bin/sequencer.sh
|
3
seqs/postgres.cfg.example
Normal file
3
seqs/postgres.cfg.example
Normal file
@@ -0,0 +1,3 @@
|
||||
#!/bin/bash
|
||||
|
||||
POSTGRES_BACKUP_DIR="~/backup"
|
173
seqs/postgres.sh
Executable file
173
seqs/postgres.sh
Executable file
@@ -0,0 +1,173 @@
|
||||
#!/bin/bash
|
||||
|
||||
toolName=postgres
|
||||
toolDeps=postgresql
|
||||
toolUser=postgres
|
||||
|
||||
# Needed for different steps
|
||||
postgresDb=""
|
||||
postgresUser=""
|
||||
postgresPass=""
|
||||
|
||||
# Get script working directory
|
||||
# (when called from a different directory)
|
||||
WDIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >>/dev/null 2>&1 && pwd )"
|
||||
CONFIG=0
|
||||
CONFIG_FILE_NAME="postgres.cfg"
|
||||
CONFIG_FILE_TEMPLATE="$WDIR/${CONFIG_FILE_NAME}.example"
|
||||
|
||||
step_config() {
|
||||
initSeqConfig "$CONFIG_FILE_NAME" "$CONFIG_FILE_TEMPLATE"
|
||||
if [ $? -eq 0 ] ; then
|
||||
CONFIG=1
|
||||
fi
|
||||
}
|
||||
|
||||
step_1_info() { echo "Installing $toolName dependencies"; }
|
||||
step_1_alias() { ALIAS="install"; }
|
||||
step_1() {
|
||||
local aptOption=
|
||||
|
||||
exe apt update
|
||||
endReturn -o $? "Updating apt repositories failed"
|
||||
|
||||
if [ $QUIET -ne 0 ] ; then
|
||||
aptOption="-y"
|
||||
else
|
||||
aptOption=""
|
||||
fi
|
||||
|
||||
exe apt install $toolDeps $aptOption
|
||||
}
|
||||
|
||||
step_2_info() { echo "Create postgres database"; }
|
||||
step_2_alias() { ALIAS="createdb"; }
|
||||
step_2() {
|
||||
readDatabaseInfos
|
||||
|
||||
exe cd ~postgres
|
||||
exe su ${toolUser} -c "psql -c \"CREATE USER ${postgresUser} WITH ENCRYPTED password '${postgresPass}';\""
|
||||
exe su ${toolUser} -c "psql -c \"CREATE DATABASE ${postgresDb} ENCODING \"UTF8\" LC_COLLATE='C' LC_CTYPE='C' template=template0 OWNER ${postgresUser};\""
|
||||
exe su ${toolUser} -c "psql -c \"GRANT ALL PRIVILEGES ON DATABASE \"${postgresDb}\" to ${postgresUser};\""
|
||||
}
|
||||
|
||||
step_4_info() { echoinfoArgs "[DATABASE]"; echo "Drop a postgres database"; }
|
||||
step_4_alias() { ALIAS="dropdb"; }
|
||||
step_4() {
|
||||
shift
|
||||
local dbname=$1
|
||||
if [ -z $dbname ]; then
|
||||
readDatabaseInfos
|
||||
dbname=$postgresDb
|
||||
fi
|
||||
exe cd ~postgres
|
||||
exe su ${toolUser} -c "psql -c \"DROP DATABASE ${dbname};\""
|
||||
}
|
||||
|
||||
step_6_info() { echoinfoArgs "[DATABASE]"; echo "Size of a postgres database"; }
|
||||
step_6_alias() { ALIAS="sizedb"; }
|
||||
step_6() {
|
||||
shift
|
||||
local dbname=$1
|
||||
if [ -z $dbname ]; then
|
||||
readDatabaseInfos
|
||||
dbname=$postgresDb
|
||||
fi
|
||||
exe cd ~postgres
|
||||
exe su ${toolUser} -c "psql -c \"SELECT pg_size_pretty( pg_database_size('$dbname') );\""
|
||||
}
|
||||
|
||||
step_8_info() { echo "List available databases"; }
|
||||
step_8_alias() { ALIAS="listdb"; }
|
||||
step_8() {
|
||||
exe cd ~postgres
|
||||
exe su ${toolUser} -c "psql -c '\l'"
|
||||
}
|
||||
|
||||
step_10_info() { echoinfoArgs "[DATABASE]"; echo "List all tables of a postgres database"; }
|
||||
step_10_alias() { ALIAS="listtables"; }
|
||||
step_10() {
|
||||
shift
|
||||
local dbname=$1
|
||||
if [ -z $dbname ]; then
|
||||
readDatabaseInfos
|
||||
dbname=$postgresDb
|
||||
fi
|
||||
exe cd ~postgres
|
||||
exe su ${toolUser} -c "psql -d $dbname -c \"\\dt\""
|
||||
}
|
||||
|
||||
step_20_info() { echoinfoArgs "[DATABASE]"; echo "Backup ${toolName} database"; }
|
||||
step_20_alias() { ALIAS="backupdb"; }
|
||||
step_20() {
|
||||
shift
|
||||
local dbname=$1
|
||||
if [ -z $dbname ]; then
|
||||
readDatabaseInfos
|
||||
dbname=$postgresDb
|
||||
fi
|
||||
#if [ ! -s ~/.pgpass ] ; then
|
||||
# echo " [I] For unattended backup please define ~/.pgpass containing credentials"
|
||||
# echo " e.g. localhost:5432:database:user:pass"
|
||||
#fi
|
||||
# -Fc custom format
|
||||
#exep "pg_dump -h 127.0.0.1 -U ${postgresUser} -Fc synapse | bzip2 -c > ${toolDbBackupFolder}/`date +%Y-%m-%d\"_\"%H-%M-%S`.backup.bz2"
|
||||
exe mkdir -p "$POSTGRES_BACKUP_DIR"
|
||||
exe cd ~postgres
|
||||
exep "su ${toolUser} -c \"pg_dump -Fc $dbname\" | bzip2 -c > ${POSTGRES_BACKUP_DIR}/`date +%Y-%m-%d\"_\"%H-%M-%S`_${dbname}.backup.bz2"
|
||||
}
|
||||
|
||||
step_22_info() { echo "Postgres database restore"; }
|
||||
step_22_alias() { ALIAS="restoredb"; }
|
||||
step_22() {
|
||||
echo " [I] Postgres database restore procedure"
|
||||
echo "1. Create a empty postgres database first (step 4)"
|
||||
echo "2. psql -h <host> -U <database user> -d <database name> -W -f <sql dump file>"
|
||||
echo " e.g. psql -h 127.0.0.1 -U synapse -d synapse -W -f 2018-06-07_18-10-56.sql"
|
||||
echo "or"
|
||||
echo "3. Custom postgres format dump restore:"
|
||||
echo " pg_restore -h localhost -p 5432 -U synapse -d new_db -v \"10.70.0.61.backup\""
|
||||
echo
|
||||
echo "Available postgresql databases:"
|
||||
exe cd ~postgres
|
||||
exe su ${toolUser} -c "psql -c '\l'"
|
||||
echo "Available postgresql user:"
|
||||
exe su ${toolUser} -c "psql -c '\du'"
|
||||
}
|
||||
|
||||
step_24_info() {
|
||||
local DELYEAR=$(($(date +%Y)-2))
|
||||
echoinfoArgs "[DATABASE]"
|
||||
echo "Clean all ${DELYEAR} backups of a database";
|
||||
}
|
||||
step_24_alias() { ALIAS="backupclean"; }
|
||||
step_24() {
|
||||
shift
|
||||
local DELYEAR=$(($(date +%Y)-2))
|
||||
local dbname=$1
|
||||
if [ -z $dbname ]; then
|
||||
readDatabaseInfos
|
||||
dbname=$postgresDb
|
||||
fi
|
||||
exe rm -f ${POSTGRES_BACKUP_DIR}/${DELYEAR}*${dbname}*
|
||||
}
|
||||
|
||||
# Read postgres database information dbname/user/pass if empty
|
||||
readDatabaseInfos() {
|
||||
if [ "$postgresDb" == "" ] ; then
|
||||
read -p "Enter postgres database name: " postgresDb
|
||||
endCheckEmpty postgresDb "database"
|
||||
fi
|
||||
if [ "$postgresUser" == "" ] ; then
|
||||
read -p "Enter postgres user name: " postgresUser
|
||||
endCheckEmpty postgresUser "user name"
|
||||
fi
|
||||
if [ "$postgresPass" == "" ] ; then
|
||||
read -s -p "Enter postgres password: " postgresPass
|
||||
endCheckEmpty postgresPass "password"
|
||||
fi
|
||||
echo
|
||||
}
|
||||
|
||||
VERSION_SEQREV=14
|
||||
. /usr/local/bin/sequencer.sh
|
80
seqs/postgrey.sh
Executable file
80
seqs/postgrey.sh
Executable file
@@ -0,0 +1,80 @@
|
||||
#!/bin/bash
|
||||
|
||||
toolName=postgrey
|
||||
toolDeps="$toolName"
|
||||
toolWhitelistLoc="/etc/postgrey/whitelist_clients"
|
||||
updateUrl="https://postgrey.schweikert.ch/pub/postgrey_whitelist_clients"
|
||||
|
||||
# Get script working directory
|
||||
# (when called from a different directory)
|
||||
WDIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >>/dev/null 2>&1 && pwd )"
|
||||
CONFIG=0
|
||||
CONFIG_FILE_NAME="${toolName}.cfg"
|
||||
CONFIG_FILE_TEMPLATE="$WDIR/${CONFIG_FILE_NAME}.example"
|
||||
|
||||
#step_config() {
|
||||
# echo "Called once before executing steps."
|
||||
# ## e.g. to source a config file manually:
|
||||
# #. "$CONFIG_FILE"
|
||||
# ## or to use sequencer api:
|
||||
# #initSeqConfig "$CONFIG_FILE_NAME" "$CONFIG_FILE_TEMPLATE"
|
||||
# #if [ $? -eq 0 ] ; then
|
||||
# # CONFIG=1
|
||||
# #fi
|
||||
#}
|
||||
|
||||
step_1_info() { echo "Install $toolDeps"; }
|
||||
step_1_alias() { ALIAS="install"; }
|
||||
step_1() {
|
||||
local aptOpt=
|
||||
if [ $QUIET -ne 0 ];then
|
||||
aptOpt="-y"
|
||||
fi
|
||||
exe apt update
|
||||
exe apt install "$toolDeps" $aptOpt
|
||||
}
|
||||
|
||||
step_2_info() {
|
||||
echo "Add cron to update whitelist_clients from"
|
||||
echoinfo "$updateUrl"
|
||||
}
|
||||
step_2_alias() { ALIAS="cron"; }
|
||||
step_2() {
|
||||
addConf -s "$postCron" "$postCronLoc"
|
||||
}
|
||||
postCronLoc="/etc/cron.d/postgreyWhitelistUpdate"
|
||||
postCron="# -q quiet -N timestamping (overwrite existing file) -O target file
|
||||
01 23 5 * * root /usr/bin/wget -qNO \"$toolWhitelistLoc\" $updateUrl && /usr/sbin/service postgrey restart"
|
||||
|
||||
step_3_info() { echo "Configuration notes"; }
|
||||
step_3_alias() { ALIAS="notes"; }
|
||||
step_3() {
|
||||
echo "$toolNotes"
|
||||
}
|
||||
toolNotes="
|
||||
# Reduce default message delay to 1 minute
|
||||
[/etc/default/postgrey]
|
||||
POSTGREY_OPTS=\"--inet=10023 --delay=60\"
|
||||
|
||||
# Custom local whitelist rules
|
||||
[/etc/postgrey/whitelist_clients.local]
|
||||
# Rule examples
|
||||
# own domains
|
||||
mydomain.com
|
||||
# own network
|
||||
/^.*\.(lan|local)$/
|
||||
192.168.0.0/24
|
||||
fd21::/64
|
||||
# External domains in frequent use
|
||||
# Amazon mail system
|
||||
amazonses.com
|
||||
"
|
||||
|
||||
step_10_info() { echo "Restart $toolName"; }
|
||||
step_10_alias() { ALIAS="restart"; }
|
||||
step_10() {
|
||||
exe service $toolName restart
|
||||
}
|
||||
|
||||
VERSION_SEQREV=11
|
||||
. /usr/local/bin/sequencer.sh
|
5
seqs/pyload.cfg.example
Normal file
5
seqs/pyload.cfg.example
Normal file
@@ -0,0 +1,5 @@
|
||||
#!/bin/bash
|
||||
|
||||
PYL_USER="pyload"
|
||||
PYL_INSTALL_DIR="/opt/pyload"
|
||||
PYL_CONFIG_DIR="/home/pyload"
|
138
seqs/pyload.sh
Executable file
138
seqs/pyload.sh
Executable file
@@ -0,0 +1,138 @@
|
||||
#!/bin/bash
|
||||
toolName="pyload"
|
||||
toolBranch="stable"
|
||||
toolDownload="https://github.com/pyload/pyload.git"
|
||||
toolDeps="git liblept5 python python-crypto python-pycurl python-imaging python-sleekxmpp tesseract-ocr zip unzip python-openssl libmozjs-24-bin"
|
||||
# python-cryptography shall be implemented in future releases and replace pyhton-crypto
|
||||
toolDepsDebian="sudo git python-crypto python-pycurl python-pil python-sleekxmpp tesseract-ocr zip unzip pyhton-openssl libmozjs-60-dev"
|
||||
toolBuildDeps="rar unrar-nonfree"
|
||||
|
||||
# Get script working directory
|
||||
# (when called from a different directory)
|
||||
WDIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" >>/dev/null 2>&1 && pwd)"
|
||||
APTOPT=
|
||||
CONFIG=0
|
||||
SCRIPT_NAME=$(basename -- $0)
|
||||
SCRIPT_NAME=${SCRIPT_NAME%%.*}
|
||||
CONFIG_FILE_NAME="${SCRIPT_NAME}.cfg"
|
||||
CONFIG_FILE_TEMPLATE="$WDIR/${CONFIG_FILE_NAME}.example"
|
||||
|
||||
step_config() {
|
||||
initSeqConfig "$CONFIG_FILE_NAME" "$CONFIG_FILE_TEMPLATE"
|
||||
if [ $? -eq 0 ] ; then
|
||||
CONFIG=1
|
||||
else
|
||||
# End if no configuration file exists
|
||||
[ $DRY -eq 0 ] && return 1
|
||||
fi
|
||||
[ $QUIET -ne 0 ] && APTOPT="-y"
|
||||
return 0
|
||||
}
|
||||
|
||||
step_1_info() { echo "Apt sources.list check and update"; }
|
||||
step_1_alias() { ALIAS="install"; }
|
||||
step_1() {
|
||||
echo "Make sure you have the \"deb-src\" entry active in your /etc/apt/sources.list"
|
||||
echo "Especially check for \"non-free\""
|
||||
exe read -p "Press Enter to continue: "
|
||||
exe vi /etc/apt/sources.list
|
||||
exe apt update
|
||||
}
|
||||
|
||||
step_2_info() { echo "Install unrar-nonfree from source"; }
|
||||
step_2() {
|
||||
exe apt-get build-dep ${toolBuildDeps} $APTOPT
|
||||
exe cd /tmp
|
||||
exe apt-get source -b unrar-nonfree
|
||||
saveReturn $?
|
||||
endReturn
|
||||
exe dpkg -i unrar_*_armhf.deb
|
||||
exe rm -rf unrar-*
|
||||
}
|
||||
|
||||
step_3_info() {
|
||||
echoinfoArgs "[TARGET]"
|
||||
echo "Install dependencies"
|
||||
echoinfo " [TARGET] (default: raspi)"
|
||||
echoinfo " raspi: Raspberry Pi OS"
|
||||
echoinfo " debian: Debian"
|
||||
}
|
||||
step_3_alias() { ALIAS="deps"; }
|
||||
step_3() {
|
||||
shift
|
||||
local lDeps="$toolDeps"
|
||||
case "$1" in
|
||||
debian)
|
||||
lDeps="$toolDepsDebian";;
|
||||
raspi);;
|
||||
*)
|
||||
echoerr " [E] Unrecognized target"
|
||||
return 1;;
|
||||
esac
|
||||
exe apt-get install ${lDeps} $APTOPT
|
||||
saveReturn $?
|
||||
endReturn
|
||||
case "$1" in
|
||||
raspi)
|
||||
exe cd /usr/bin
|
||||
exe ln -s js24 js;;
|
||||
debian)
|
||||
exe cd /usr/bin
|
||||
exe ln -s js60 js;;
|
||||
esac
|
||||
}
|
||||
|
||||
step_4_info() { echo "Get $toolName from $toolDownload and create dedicated user"; }
|
||||
step_4() {
|
||||
exe git clone -b $toolBranch $toolDownload "$PYL_INSTALL_DIR"
|
||||
endReturn -o $? "Git clone failed"
|
||||
exe adduser --system --home "$PYL_CONFIG_DIR" "$PYL_USER"
|
||||
}
|
||||
|
||||
step_5_info() { echo "Make initial configuration"; }
|
||||
step_5() {
|
||||
echo "Webinterface server \"threaded\" is recommended on a raspberry pi."
|
||||
exe read -p "Press Enter to continue: "
|
||||
exe cd "$PYL_INSTALL_DIR"
|
||||
exe sudo -u $PYL_USER python pyLoadCore.py
|
||||
}
|
||||
|
||||
step_6_info() { echo "Create systemd service"; }
|
||||
step_6() {
|
||||
local lService=`eval "echo \"$toolService\""`
|
||||
addConf -c "$lService" "$toolServiceLoc"
|
||||
}
|
||||
toolServiceLoc="/etc/systemd/system/pyload.service"
|
||||
toolService="[Unit]
|
||||
Description=Python Downloader
|
||||
After=network.target
|
||||
|
||||
[Service]
|
||||
User=pyload
|
||||
ExecStart=/usr/bin/python \${PYL_INSTALL_DIR}/pyLoadCore.py
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target"
|
||||
|
||||
step_7_info() { echo "Add ufw rules"; }
|
||||
step_7_alias() { ALIAS="ufw"; }
|
||||
step_7() {
|
||||
echoseq " [I] Port 9666 needs to be forwarded to the target machine with ssh"
|
||||
echoseq " ssh -L 9666:localhost:9666 user@host -N"
|
||||
exe ufw allow in on eth0 to any port 8000 proto tcp comment "pyload webinterface"
|
||||
exe ufw allow in on eth0 to any port 7227 proto tcp comment "pyload remotes"
|
||||
exe ufw allow out on eth0 to 192.168.23.20 port 5222 proto tcp comment "XMPP Connection"
|
||||
}
|
||||
|
||||
step_10_info() { echo "Upgrade to latest version of branch $toolBranch"; }
|
||||
step_10_alias() { ALIAS="upgrade"; }
|
||||
step_10() {
|
||||
exe service $toolName stop
|
||||
exe cd "$PYL_INSTALL_DIR"
|
||||
exe git pull
|
||||
echo " [I] Service is not started automatically"
|
||||
echo " Do so manually with: service $toolName start"
|
||||
}
|
||||
|
||||
VERSION_SEQREV=14
|
||||
. /usr/local/bin/sequencer.sh
|
618
seqs/raspberry.sh
Executable file
618
seqs/raspberry.sh
Executable file
@@ -0,0 +1,618 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Collection of setup steps for a new raspberry pi
|
||||
# (e.g. boot from HD, disable swap file, ...)
|
||||
|
||||
# Get script working directory
|
||||
# (when called from a different directory)
|
||||
WDIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >>/dev/null 2>&1 && pwd )"
|
||||
#CONFIG_FILE="$WDIR/${toolName}.cfg"
|
||||
#CONFIG_FILE_DEFAULT="${CONFIG_FILE}.example"
|
||||
|
||||
osName=
|
||||
distName=
|
||||
RPI_BOOT_CONFIG="/boot/config.txt"
|
||||
|
||||
step_config() {
|
||||
# Shift away args
|
||||
local lArgs=( "$@" ); evalArgs "${lArgs[@]}"; shift $?
|
||||
# Set download url with specified CPU architecture
|
||||
PIDOWNURL="https://downloads.raspberrypi.org/raspios_lite_${PIARCH}_latest"
|
||||
|
||||
if [ "$(which lsb_release)" == "" ] ; then
|
||||
echoerr " [W] Cannot detect OS. Assuming Ubuntu"
|
||||
osName="Ubuntu"
|
||||
else
|
||||
osName=$(lsb_release -is)
|
||||
distName=$(lsb_release -cs)
|
||||
fi
|
||||
|
||||
if [ "$osName" == "" ] ; then
|
||||
echoerr " [W] Error dedecting OS. Assuming Ubuntu"
|
||||
osName="Ubuntu"
|
||||
fi
|
||||
|
||||
echoseq " Detected OS: $osName $distName"
|
||||
echoseq " Requested CPU Architecture: $PIARCH"
|
||||
|
||||
return 0
|
||||
}
|
||||
|
||||
PIARCH=armhf
|
||||
PIDOWNURL=
|
||||
SDDEV=
|
||||
SDBOOT=
|
||||
SDBOOTPUUID=
|
||||
SDROOT=
|
||||
SDROOTDEV=
|
||||
SDROOTPUUID=
|
||||
HDDEV=
|
||||
HDROOT=
|
||||
HDROOTPUUID=
|
||||
HDSWAP=
|
||||
HDSWAPPUUID=
|
||||
|
||||
evalArgs() {
|
||||
local argCount=0
|
||||
|
||||
for arg in "$@"; do
|
||||
case "$1" in
|
||||
-a|--arch)
|
||||
if [ ! -z "$2" ]; then
|
||||
PIARCH="$2"
|
||||
((argCount+=2))
|
||||
else
|
||||
((argCount+=1))
|
||||
fi
|
||||
shift $argCount
|
||||
;;
|
||||
*)
|
||||
break
|
||||
;;
|
||||
esac
|
||||
done
|
||||
return $argCount
|
||||
}
|
||||
|
||||
step_1_info() {
|
||||
# Shift away args
|
||||
shift; local lArgs=( "$@" ); evalArgs "${lArgs[@]}"; shift $?
|
||||
|
||||
echoinfoArgs "[OPTIONS] [SD CARD DEVICE] [HD DEVICE]"
|
||||
echo "Download latest Raspberry Pi OS lite image $PIARCH"
|
||||
if [ $CONTEXT_EXE -ne 0 ]; then
|
||||
echoinfo "Download URL: $PIDOWNURL"
|
||||
else
|
||||
echoinfo " [OPTIONS]"
|
||||
echoinfo " -a, --arch : armhf (default), arm64"
|
||||
fi
|
||||
}
|
||||
step_1_alias() { ALIAS="setup"; }
|
||||
step_1() {
|
||||
# Shift away args
|
||||
shift; local lArgs=( "$@" ); evalArgs "${lArgs[@]}"; shift $?
|
||||
|
||||
if [ ! -f "$downLoc" ] ; then
|
||||
exe wget "$PIDOWNURL" -O "$downLoc"
|
||||
echo -ne " [I] sha256 sum of download:\n "
|
||||
exe sha256sum "$downLoc"
|
||||
fi
|
||||
downImgName="${downDir}/$(zipinfo -1 "$downLoc")"
|
||||
if [ ! -f "$downImgName" ] ; then
|
||||
exe unzip "$downLoc" -d "$downDir"
|
||||
endReturn -o $? "Unzip raspios image $PIARCH failed"
|
||||
fi
|
||||
}
|
||||
downImgName=""
|
||||
downDay=$(date +%Y%m%d)
|
||||
downDir="/tmp"
|
||||
downLoc="${downDir}/raspios_$downDay.zip"
|
||||
|
||||
step_2_info() {
|
||||
# Shift away args
|
||||
shift; local lArgs=( "$@" ); evalArgs "${lArgs[@]}"; shift $?
|
||||
|
||||
echoinfoArgs "[OPTIONS] [SD CARD DEVICE]"
|
||||
echo "Write Raspberry Pi OS image to SD card"
|
||||
echoinfo "This operation will delete all data previously on the SD card!"
|
||||
[ $CONTEXT_EXE -ne 0 ] && [ ! -z $1 ] && echoinfo " [SD CARD DEVICE]: $1"
|
||||
}
|
||||
step_2_alias() { ALIAS="writesd"; }
|
||||
step_2() {
|
||||
# Shift away args
|
||||
shift; local lArgs=( "$@" ); evalArgs "${lArgs[@]}"; shift $?
|
||||
|
||||
if [ "$downImgName" == "" ] ; then
|
||||
# called again to make sure $downImgName is populated
|
||||
step setup
|
||||
fi
|
||||
if [ ! -f "$downImgName" ] ; then
|
||||
endReturn -o 1 "No raspios image found"
|
||||
fi
|
||||
|
||||
if [ $(id -u) -ne 0 ] ; then
|
||||
endReturn -o 1 "No root"
|
||||
fi
|
||||
|
||||
read_sd_dev "$1"
|
||||
# check if device was confirmed
|
||||
if [ $? -ne 0 ] ; then
|
||||
endReturn -o 1 "SD card device not found"
|
||||
fi
|
||||
|
||||
# write image
|
||||
exe dd bs=8M if="$downImgName" of="$SDDEV" conv=fsync
|
||||
endReturn -o "$?" "Writing image to $SDDEV failed"
|
||||
exe sync
|
||||
|
||||
# SD partitions will have new informations now
|
||||
# Leave SD card device intact for next step
|
||||
SDBOOT=""
|
||||
SDROOT=""
|
||||
|
||||
# TODO ? automatic remount
|
||||
echoerr " [W] Please remove SD now and plug it back in."
|
||||
exe read -p " Press enter to contiue."
|
||||
}
|
||||
|
||||
step_3_info() {
|
||||
# Shift away args
|
||||
shift; local lArgs=( "$@" ); evalArgs "${lArgs[@]}"; shift $?
|
||||
|
||||
echoinfoArgs "[SD CARD DEVICE]"
|
||||
echo "Prepare SD for first run"
|
||||
if [ $CONTEXT_EXE -ne 0 ]; then
|
||||
[ ! -z $1 ] && echoinfo " [SD CARD DEVICE]: $1"
|
||||
fi
|
||||
}
|
||||
step_3() {
|
||||
# Shift away args
|
||||
shift; local lArgs=( "$@" ); evalArgs "${lArgs[@]}"; shift $?
|
||||
|
||||
if [ -z $1 ] && [ ! -z $SDDEV ] ; then
|
||||
if [ $QUIET -ne 0 ] ; then
|
||||
answer="n"
|
||||
else
|
||||
exe lsblk -p "$SDDEV"
|
||||
echo
|
||||
exe read -p "Is $SDDEV still the SD card (y/[n])? " answer
|
||||
fi
|
||||
|
||||
case $answer in
|
||||
[yY])
|
||||
# Nothing todo
|
||||
;;
|
||||
*)
|
||||
SDDEV=""
|
||||
;;
|
||||
esac
|
||||
fi
|
||||
|
||||
read_sd_dev "$1"
|
||||
endReturn -o $? "SD card device not found"
|
||||
|
||||
if [ ! -w "$SDBOOT" ] ; then
|
||||
echoerr " [E] SD card boot partion not writeable"
|
||||
return 1
|
||||
fi
|
||||
|
||||
# enable systemd ssh service
|
||||
echo " [I] Enable SSH access"
|
||||
exe touch "$SDBOOT"/ssh
|
||||
|
||||
# save SD boot settings for easy emergency start from SD
|
||||
echo " [I] Save SD card boot information for later use"
|
||||
exe cp -ar "$SDBOOT"/cmdline.txt "$SDBOOT"/cmdline.txt.sd
|
||||
exe cp -ar "$SDROOT"/etc/fstab "$SDROOT"/etc/fstab.sd
|
||||
}
|
||||
|
||||
step_4_info() {
|
||||
# Shift away args
|
||||
shift; local lArgs=( "$@" ); evalArgs "${lArgs[@]}"; shift $?
|
||||
|
||||
echoinfoArgs "[SD CARD DEVICE] [HD DEVICE]"
|
||||
echo "Prepare SD card to boot from hard disk"
|
||||
if [ $CONTEXT_EXE -ne 0 ]; then
|
||||
[ ! -z $1 ] && echoinfo " [SD CARD DEVICE]: $1"
|
||||
[ ! -z $2 ] && echoinfo " [HD DEVICE]: $2"
|
||||
fi
|
||||
}
|
||||
step_4_alias() { ALIAS="hdboot"; }
|
||||
step_4() {
|
||||
# Shift away args
|
||||
shift; local lArgs=( "$@" ); evalArgs "${lArgs[@]}"; shift $?
|
||||
|
||||
read_sd_dev "$1"
|
||||
endReturn -o $? "SD detection error $?"
|
||||
read_hd_dev "$2"
|
||||
endReturn -o $? "HD detection error"
|
||||
echo " [I] SD: $SDDEV"
|
||||
echo " $SDBOOT [$SDBOOTPUUID]"
|
||||
echo " $SDROOT [$SDROOTPUUID]"
|
||||
echo " [I] HD: $HDDEV"
|
||||
echo " $HDROOT [$HDROOTPUUID]"
|
||||
echo " $HDSWAP [$HDSWAPPUUID]"
|
||||
echo
|
||||
|
||||
# Point boot command line to SSD
|
||||
echo -n " [I] modify PARTUUID of $SDBOOT/cmdline.txt"
|
||||
if [ ! -z $HDROOTPUUID ] ; then
|
||||
exe sed -i -E "s/root=PARTUUID=[a-f0-9-]+/root=PARTUUID=${HDROOTPUUID}/" "$SDBOOT/cmdline.txt"
|
||||
if [ $? -eq 0 ] ; then
|
||||
echo " ... Ok"
|
||||
else
|
||||
echo -e "\n Failed! Replace PARTUUID manually"
|
||||
fi
|
||||
else
|
||||
echo " Replace \"root=PARTUUID=******00-01\" manually"
|
||||
fi
|
||||
|
||||
# Disable initial resizing of the second partition
|
||||
echo -n " [I] remove \"init=/usr/lib/raspi-config/init_resize.sh\""
|
||||
exe sed -i -E "s/[ ]*init=.*\/init_resize\.sh//" "$SDBOOT/cmdline.txt"
|
||||
if [ $? -eq 0 ] ; then
|
||||
echo " ... Ok"
|
||||
else
|
||||
echo -e "\n Failed! Remove init=... manually"
|
||||
fi
|
||||
|
||||
# Save modifications for HD boot
|
||||
exe cp -ar "$SDBOOT"/cmdline.txt "$SDBOOT"/cmdline.txt.hd
|
||||
echo
|
||||
|
||||
# Resize second partition of SD to max. possible size
|
||||
echo " [I] Resize root partion of SD: ${SDROOT} "
|
||||
step resizesd "$SDDEV"
|
||||
if [ $? -ne 0 ] ; then
|
||||
echoerr " [W] Something seems to have failed during resize"
|
||||
else
|
||||
# Disable init script to resize SD
|
||||
echo -n " [I] remove \"init=\" part from $SDBOOT/cmdline.txt.sd"
|
||||
exe sed -i -E "s/[ ]*init=.*\/init_resize\.sh//" "$SDBOOT/cmdline.txt.sd"
|
||||
if [ $? -eq 0 ] ; then
|
||||
echo " ... Ok"
|
||||
else
|
||||
echo -e "\n Failed! Remove init=... manually"
|
||||
fi
|
||||
fi
|
||||
}
|
||||
|
||||
step_5_info() {
|
||||
# Shift away args
|
||||
shift; local lArgs=( "$@" ); evalArgs "${lArgs[@]}"; shift $?
|
||||
|
||||
echoinfoArgs "[SD CARD DEVICE] [HD DEVICE]"
|
||||
echo "Prepare HD for boot (TODO)"
|
||||
|
||||
if [ $CONTEXT_EXE -ne 0 ]; then
|
||||
[ ! -z $1 ] && echoinfo " [SD CARD DEVICE]: $1"
|
||||
[ ! -z $2 ] && echoinfo " [HD DEVICE]: $2"
|
||||
fi
|
||||
}
|
||||
step_5() {
|
||||
# Shift away args
|
||||
shift; local lArgs=( "$@" ); evalArgs "${lArgs[@]}"; shift $?
|
||||
|
||||
#TODO
|
||||
echoerr " [E] Not ready yet...TODO"
|
||||
#return 1
|
||||
read_sd_dev "$1"
|
||||
endReturn -o $? "SD detection error $?"
|
||||
|
||||
read_hd_dev "$2"
|
||||
endReturn -o $? "HD detection error"
|
||||
echo " [I] SD: $SDDEV"
|
||||
echo " $SDBOOT [$SDBOOTPUUID]"
|
||||
echo " $SDROOT [$SDROOTPUUID]"
|
||||
echo " [I] HD: $HDDEV"
|
||||
echo " $HDROOT [$HDROOTPUUID]"
|
||||
echo " $HDSWAP [$HDSWAPPUUID]"
|
||||
echo
|
||||
|
||||
# TODO how to partition HD
|
||||
echo " [I] $HDDEV is expected to be partitioned with root and swap"
|
||||
echo " TODO create a step for partitioning script support?!"
|
||||
echo
|
||||
|
||||
# Initial rsync of system to HD
|
||||
echo " [I] Clone SD root to HD root:"
|
||||
echo " rsync -avxHAX --numeric-ids --info=stats2 $SDROOT/ $HDROOT/"
|
||||
echo
|
||||
|
||||
# Modify fstab on HD for root and swap on HD
|
||||
echo " [I] modify $HDROOT/etc/fstab"
|
||||
echo " PARTUUID=$SDBOOTPUUID /boot vfat ro,defaults 0 2"
|
||||
echo " PARTUUID=$SDROOTPUUID /backup ext4 ro,defaults,noatime 0 2"
|
||||
echo " PARTUUID=$HDROOTPUUID / ext4 defaults,noatime 0 1"
|
||||
echo " PARTUUID=$HDSWAPPUUID none swap sw 0 0"
|
||||
echo
|
||||
|
||||
# etc
|
||||
echo " [I] modify $HDROOT/etc/dhcpcd.conf for static IPs"
|
||||
}
|
||||
|
||||
read_sd_dev() {
|
||||
local partExt=""
|
||||
if [ ! -z "$1" ] ; then
|
||||
SDBOOT=
|
||||
SDROOT=
|
||||
SDROOTDEV=
|
||||
SDROOTPUUID=
|
||||
SDBOOTPUUID=
|
||||
SDDEV="$1"
|
||||
elif [ -z $SDDEV ] || [ ! -b "$SDDEV" ] ; then
|
||||
SDDEV=
|
||||
SDBOOT=
|
||||
SDROOT=
|
||||
SDROOTDEV=
|
||||
SDBOOTPUUID=
|
||||
SDROOTPUUID=
|
||||
echo " [I] Available devices:"
|
||||
echo
|
||||
exe lsblk -p
|
||||
echo
|
||||
exe read -p "Provide SD card device (e.g. /dev/sdb): " SDDEV
|
||||
fi
|
||||
|
||||
if [ ! -b "$SDDEV" ] ; then
|
||||
echoerr " [I] $SDDEV not a block device"
|
||||
SDDEV=
|
||||
return 1
|
||||
fi
|
||||
|
||||
if [[ "$SDDEV" =~ .*blk.* ]] ; then
|
||||
partExt="p"
|
||||
fi
|
||||
|
||||
if [ -z $SDBOOT ] ; then
|
||||
SDBOOT=$(findmnt -no TARGET "${SDDEV}${partExt}${SDBOOTPARTNO}")
|
||||
fi
|
||||
if [ -z $SDBOOTPUUID ] ; then
|
||||
IFS=\" read -r _ vPARTUUID _ < <(blkid "${SDDEV}${partExt}${SDBOOTPARTNO}" -s PARTUUID)
|
||||
SDBOOTPUUID=$vPARTUUID
|
||||
fi
|
||||
SDROOTDEV=${SDDEV}${partExt}${SDROOTPARTNO}
|
||||
if [ -z $SDROOT ] ; then
|
||||
SDROOT=$(findmnt -no TARGET "${SDROOTDEV}")
|
||||
fi
|
||||
if [ -z $SDROOTPUUID ] ; then
|
||||
SDROOTPUUID=$(findmnt -no PARTUUID "${SDROOTDEV}")
|
||||
fi
|
||||
|
||||
return 0
|
||||
}
|
||||
SDBOOTPARTNO=1
|
||||
SDROOTPARTNO=2
|
||||
|
||||
read_hd_dev() {
|
||||
if [ ! -z "$1" ] ; then
|
||||
HDROOT=
|
||||
HDROOTPUUID=
|
||||
HDSWAPPUUID=
|
||||
HDDEV="$1"
|
||||
elif [ -z $HDDEV ] || [ ! -b "$HDDEV" ] ; then
|
||||
HDROOT=
|
||||
HDROOTPUUID=
|
||||
HDSWAPPUUID=
|
||||
echo " [I] Available devices:"
|
||||
echo
|
||||
exe lsblk -p
|
||||
echo
|
||||
exe read -p "Provide HD device (e.g. /dev/sdf): " HDDEV
|
||||
fi
|
||||
|
||||
if [ ! -b "$HDDEV" ] ; then
|
||||
HDDEV=
|
||||
return 1
|
||||
fi
|
||||
|
||||
if [ -z $HDROOT ] ; then
|
||||
HDROOT=$(findmnt -no TARGET "${HDDEV}1")
|
||||
fi
|
||||
if [ -z $HDROOTPUUID ] ; then
|
||||
IFS=\" read -r _ vPARTUUID _ < <(blkid "${HDDEV}1" -s PARTUUID)
|
||||
HDROOTPUUID=$vPARTUUID
|
||||
fi
|
||||
if [ -z $HDSWAPPUUID ] ; then
|
||||
IFS=\" read -r _ vPARTUUID _ < <(blkid "${HDDEV}2" -s PARTUUID)
|
||||
HDSWAPPUUID=$vPARTUUID
|
||||
HDSWAP="${HDDEV}2"
|
||||
fi
|
||||
|
||||
return 0
|
||||
}
|
||||
|
||||
step_20_info() { echo "Disable swap file and remove it"; }
|
||||
step_20_alias() { ALIAS="disable_swap"; }
|
||||
step_20() {
|
||||
exe swapoff -a
|
||||
exe systemctl disable dphys-swapfile
|
||||
exe rm -rf "$rpiSwapFile"
|
||||
echoerr " [W] Reboot to apply changes"
|
||||
if [ $QUIET -eq 0 ] ; then
|
||||
exe read -p " Reboot now ([n]/y)? " answer
|
||||
case $answer in
|
||||
[yY])
|
||||
echoerr " [I] Rebooting now ..."
|
||||
exe reboot
|
||||
;;
|
||||
*)
|
||||
;;
|
||||
esac
|
||||
fi
|
||||
}
|
||||
rpiSwapFile="/var/swap"
|
||||
|
||||
step_22_info() { echoinfoArgs "[SD CARD DEVICE]"; echo "Resize second SD card partition"; }
|
||||
step_22_alias() { ALIAS="resizesd"; }
|
||||
step_22() {
|
||||
shift
|
||||
read_sd_dev "$1"
|
||||
if [ -z $SDDEV ] || [ "$SDDEV" = "" ] || [ "$SDROOT" == "/" ] ; then
|
||||
echoerr " [E] No SD found"
|
||||
return 1
|
||||
fi
|
||||
echo " [I] Device to be resized: $SDROOTDEV"
|
||||
|
||||
exe umount -q "$SDROOT"
|
||||
exe parted -s "$SDDEV" "resizepart $SDROOTPARTNO -1" quit
|
||||
saveReturn $?
|
||||
exe e2fsck -f "$SDROOTDEV"
|
||||
saveReturn $?
|
||||
exe resize2fs "$SDROOTDEV"
|
||||
saveReturn $?
|
||||
if [ -z $SDROOT ] ; then
|
||||
read -p "Please provide a mountpoint: " SDROOT
|
||||
exe mkdir -p "$SDROOT"
|
||||
fi
|
||||
exe mount "$SDROOTDEV" "$SDROOT"
|
||||
saveReturn $?
|
||||
getReturn
|
||||
return $?
|
||||
}
|
||||
|
||||
step_24_info() {
|
||||
echoinfoArgs "[OPTION]"
|
||||
echo "Turn off power LED"
|
||||
echoinfo " [OPTION]"
|
||||
echoinfo " -p : Turn off permanentely (/etc/rc.local)"
|
||||
}
|
||||
step_24_alias() { ALIAS="disable_powerled"; }
|
||||
step_24() {
|
||||
exep "${ledOffCmd}"
|
||||
if [ ! -z "$2" ] && [ "$2" == "-p" ] ; then
|
||||
exep "grep \"$ledPowerBright\" $startScript >>/dev/null"
|
||||
if [ $? -eq 0 ] ; then
|
||||
echo " [I] Power LED brightness already used. Please check $startScript manually for:"
|
||||
echo " $ledOffCmd"
|
||||
return 1
|
||||
fi
|
||||
exe sed -i "s/^exit 0/# Turn off power LED/" "$startScript"
|
||||
exep "echo \"${ledOffCmd}\" >> $startScript"
|
||||
exep "echo -e \"\nexit 0\" >> $startScript"
|
||||
fi
|
||||
}
|
||||
startScript="/etc/rc.local"
|
||||
ledPowerBright="/sys/class/leds/led1/brightness"
|
||||
ledOffCmd="sudo sh -c 'echo 0 > ${ledPowerBright}'"
|
||||
|
||||
step_26_info() { echo "Restart network without reboot"; }
|
||||
step_26_alias() { ALIAS="netrestart"; }
|
||||
step_26() {
|
||||
exep "sudo ip link set eth0 down && sudo ip link set eth0 up"
|
||||
}
|
||||
|
||||
step_28_info() { echo "Disable bluetooth"; }
|
||||
step_28_alias() { ALIAS="disable_bluetooth"; }
|
||||
step_28() {
|
||||
checkBootConfig "$RPI_CONFIG_DTOVERLAY" "$RPI_CONF_DI_BLUETOOTH"
|
||||
[ $? -eq 0 ] && endReturn -o 1 "Bluetooth already disabled"
|
||||
|
||||
addConf -a "${RPI_CONFIG_DTOVERLAY}=$RPI_CONF_DI_BLUETOOTH" "$RPI_BOOT_CONFIG"
|
||||
}
|
||||
RPI_CONFIG_DTOVERLAY="dtoverlay"
|
||||
RPI_CONF_DI_BLUETOOTH="disable-bt"
|
||||
RPI_CONF_DI_WIFI="disable-wifi"
|
||||
|
||||
step_29_info() { echo "Disable bluetooth services"; }
|
||||
step_29() {
|
||||
exe systemctl disable hciuart.service
|
||||
exe systemctl disable bluealsa.service
|
||||
exe systemctl disable bluetooth.service
|
||||
|
||||
echoseq " [I] Consider uninstalling bluetooth software:"
|
||||
echoseq "apt purge --autoremove -y bluez"
|
||||
echoseq
|
||||
echoseq " [W] Reboot to make changes active"
|
||||
}
|
||||
|
||||
|
||||
step_31_info() { echo "Disable Wifi"; }
|
||||
step_31_alias() { ALIAS="disable_wifi"; }
|
||||
step_31() {
|
||||
checkBootConfig "$RPI_CONFIG_DTOVERLAY" "$RPI_CONF_DI_WIFI"
|
||||
[ $? -eq 0 ] && endReturn -o 1 "Wifi already disabled"
|
||||
|
||||
addConf -a "${RPI_CONFIG_DTOVERLAY}=$RPI_CONF_DI_WIFI" "$RPI_BOOT_CONFIG"
|
||||
|
||||
echoseq " [W] Reboot to make changes active"
|
||||
}
|
||||
|
||||
step_33_info() { echo "Disable HDMI"; }
|
||||
step_33_alias() { ALIAS="disable_hdmi"; }
|
||||
step_33() {
|
||||
checkBootConfig "$RPI_CONFIG_HDMI_BLANK" "$RPI_CONF_DI_HDMI"
|
||||
[ $? -eq 0 ] && endReturn -o 1 "HDMI already disabled"
|
||||
|
||||
addConf -a "${RPI_CONFIG_HDMI_BLANK}=$RPI_CONF_DI_HDMI" "$RPI_BOOT_CONFIG"
|
||||
}
|
||||
RPI_CONFIG_HDMI_BLANK="hdmi_blanking"
|
||||
RPI_CONF_DI_HDMI="1"
|
||||
|
||||
step_34_info() { echo "Disable TV service"; }
|
||||
step_34() {
|
||||
exe $tvserviceOffCmd
|
||||
exep "grep \"$tvserviceBin\" $startScript >>/dev/null"
|
||||
if [ $? -eq 0 ] ; then
|
||||
echo " [I] Tvservice already used. Please check $startScript manually for:"
|
||||
echo " $tvserviceOffCmd"
|
||||
return 1
|
||||
fi
|
||||
|
||||
exe sed -i "s/^exit 0/# Turn off tvservice/" "$startScript"
|
||||
exep "echo \"${tvserviceOffCmd}\" >> $startScript"
|
||||
exep "echo -e \"\nexit 0\" >> $startScript"
|
||||
|
||||
echoseq " [W] Reboot to make changes active"
|
||||
}
|
||||
tvserviceBin="/usr/bin/tvservice"
|
||||
tvserviceOffCmd="${tvserviceBin} -o'"
|
||||
|
||||
# checkBootConfig <CONFIGNAME> [VALUE]
|
||||
checkBootConfig() {
|
||||
[ -z "$1" ] && return 1
|
||||
|
||||
local re_check="^[[:blank:]]*[^#]*${1}[[:blank:]]*=[[:blank:]]*$2"
|
||||
grep -rqE "$re_check" "$RPI_BOOT_CONFIG"
|
||||
return $?
|
||||
}
|
||||
|
||||
step_100_alias() { ALIAS="notes"; }
|
||||
step_100() {
|
||||
outColor green
|
||||
cat <<NOTES_EOF
|
||||
# Initial configuration steps
|
||||
|
||||
* Set password for pi (\`passwd\`)
|
||||
* Add [\$HOME/.ssh/authorized_keys]
|
||||
* Set hostname (\`raspi-config\` -> System Options))
|
||||
* Configure Timezone (\`raspi-confg\` -> Localisation Options)
|
||||
* Set GPU memory (\`raspi-config\` -> Performance Options)
|
||||
* Configure swap partition
|
||||
|
||||
[/etc/fstab]
|
||||
> \`PARTUUID=******-03 none swap sw 0 0\`
|
||||
|
||||
\`$SEQ_NAME disable_swap\`
|
||||
|
||||
* Update system
|
||||
|
||||
\`apt update && apt dist-upgrade\`
|
||||
|
||||
* Configure own NTP server
|
||||
|
||||
[/etc/systemd/timesyncd.conf]
|
||||
> NTP=<NTP server IP>
|
||||
|
||||
\`system systemd-timesyncd restart\`
|
||||
|
||||
* Configure vim to remember last position in a file
|
||||
|
||||
Uncomment the following in [/etc/vim/vimrc]
|
||||
> \`au BufReadPost ...\`
|
||||
|
||||
NOTES_EOF
|
||||
}
|
||||
|
||||
VERSION_SEQREV=15
|
||||
. /usr/local/bin/sequencer.sh
|
3
seqs/raspberry/fstab.hd.template
Normal file
3
seqs/raspberry/fstab.hd.template
Normal file
@@ -0,0 +1,3 @@
|
||||
proc /proc proc defaults 0 0
|
||||
PARTUUID=mysdid-boot /boot vfat ro,defaults 0 2
|
||||
PARTUUID=mysdid-backup /backup ext4 ro,defaults,noatime 0 2
|
4
seqs/redis.cfg.example
Normal file
4
seqs/redis.cfg.example
Normal file
@@ -0,0 +1,4 @@
|
||||
#!/bin/bash
|
||||
|
||||
# If you use a password you may set it here for cli commands
|
||||
REDIS_AUTH=
|
86
seqs/redis.sh
Executable file
86
seqs/redis.sh
Executable file
@@ -0,0 +1,86 @@
|
||||
#!/bin/bash
|
||||
|
||||
toolName=redis
|
||||
toolDeps=redis-server
|
||||
|
||||
# Get script working directory
|
||||
# (when called from a different directory)
|
||||
WDIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" >>/dev/null 2>&1 && pwd)"
|
||||
CONFIG=0
|
||||
SCRIPT_NAME=$(basename -- $0)
|
||||
SCRIPT_NAME=${SCRIPT_NAME%%.*}
|
||||
CONFIG_FILE_NAME="${SCRIPT_NAME}.cfg"
|
||||
CONFIG_FILE_TEMPLATE="$WDIR/${CONFIG_FILE_NAME}.example"
|
||||
|
||||
step_config() {
|
||||
initSeqConfig "$CONFIG_FILE_NAME" "$CONFIG_FILE_TEMPLATE"
|
||||
if [ $? -eq 0 ] ; then
|
||||
CONFIG=1
|
||||
fi
|
||||
}
|
||||
|
||||
step_1_info() { echo "Install $toolName"; }
|
||||
step_1_alias() { ALIAS="install"; }
|
||||
step_1() {
|
||||
local aptOpt=
|
||||
if [ $QUIET -ne 0 ];then
|
||||
aptOpt="-y"
|
||||
fi
|
||||
|
||||
exe apt update
|
||||
exe apt install $toolDeps $aptOpt
|
||||
}
|
||||
|
||||
step_2_info() { echo "Installation notes"; }
|
||||
step_2_alias() { ALIAS="notes"; }
|
||||
step_2() {
|
||||
cat <<NOTES_EOF
|
||||
# For php applications make sure php-redis is installed
|
||||
apt install php-redis
|
||||
|
||||
# Bind to localhsot
|
||||
[/etc/redis/redis.conf]
|
||||
bind 127.0.0.1 ::1
|
||||
|
||||
# or use socket
|
||||
unixsocket /var/run/redis/redis-server.sock
|
||||
unixsocketperm 770
|
||||
|
||||
## Password protect
|
||||
requirepass verystrongpassword
|
||||
|
||||
# Nextcloud configuration
|
||||
[/var/www/nextcloud/config/config.php]
|
||||
'memcache.locking' => '\\OC\\Memcache\\Redis',
|
||||
'memcache.distributed' => '\\OC\\Memcache\\Redis',
|
||||
'redis' =>
|
||||
array (
|
||||
'host' => '/var/run/redis/redis-server.sock',
|
||||
'port' => 0,
|
||||
'password' => 'verystrongpassword',
|
||||
'timeout' => 0.0,
|
||||
),
|
||||
|
||||
NOTES_EOF
|
||||
}
|
||||
|
||||
step_10_info() {
|
||||
echoinfoArgs "[CLI COMMAND]"
|
||||
echo "Execute redis-cli commands"
|
||||
echoinfo " [CLI COMMAND]"
|
||||
echoinfo " e.g. info"
|
||||
}
|
||||
step_10_alias() { ALIAS="cli"; }
|
||||
step_10() {
|
||||
shift
|
||||
local cliCmd="$@"
|
||||
if [ ! -z "$REDIS_AUTH" ] ; then
|
||||
#exe "echo -e \"AUTH=$REDIS_AUTH$cliCmd\" | redis-cli"
|
||||
exe redis-cli -a "$REDIS_AUTH" $cliCmd
|
||||
else
|
||||
exe redis-cli $cliCmd
|
||||
fi
|
||||
}
|
||||
|
||||
VERSION_SEQREV=14
|
||||
. /usr/local/bin/sequencer.sh
|
8
seqs/roundcube.cfg.example
Normal file
8
seqs/roundcube.cfg.example
Normal file
@@ -0,0 +1,8 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Roundcube sequence configuration
|
||||
# RC = RoundCube
|
||||
|
||||
RC_LOC="/var/www/webmail"
|
||||
RC_BACKUP="/root/backup/roundcube"
|
||||
RC_DATABASE="roundcube_db"
|
258
seqs/roundcube.sh
Executable file
258
seqs/roundcube.sh
Executable file
@@ -0,0 +1,258 @@
|
||||
#!/bin/bash
|
||||
|
||||
toolName=roundcube
|
||||
toolPhpDeps="php\${phpVersion}-gd php-imagick"
|
||||
#https://github.com/roundcube/roundcubemail/releases/latest
|
||||
latestUrl="https://api.github.com/repos/roundcube/roundcubemail/releases/latest"
|
||||
latestVersion=
|
||||
tempExtract=
|
||||
tempInstall=
|
||||
phpVersion=
|
||||
|
||||
# Get script working directory
|
||||
# (when called from a different directory)
|
||||
WDIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >>/dev/null 2>&1 && pwd )"
|
||||
CONFIG=0
|
||||
CONFIG_FILE_NAME="${toolName}.cfg"
|
||||
CONFIG_FILE_TEMPLATE="$WDIR/${CONFIG_FILE_NAME}.example"
|
||||
|
||||
step_config() {
|
||||
## use sequencer api:
|
||||
initSeqConfig -t "$CONFIG_FILE_NAME" "$CONFIG_FILE_TEMPLATE"
|
||||
if [ $CONFIG -eq 0 ] ; then
|
||||
CONFIG=1
|
||||
fi
|
||||
}
|
||||
|
||||
step_1_info() { echo "Install $toolName"; }
|
||||
step_1_alias() { ALIAS="install"; }
|
||||
step_1() {
|
||||
local aptOpt=
|
||||
if [ $QUIET -ne 0 ];then
|
||||
aptOpt="-y"
|
||||
fi
|
||||
|
||||
downloadLatest
|
||||
fetchPhpVersion
|
||||
|
||||
if [ ! -z $phpVersion ] ; then
|
||||
exe apt update
|
||||
exe apt install `eval echo "$toolPhpDeps"` $aptOpt
|
||||
fi
|
||||
|
||||
exe chown -R www-data: "$tempExtract"
|
||||
exe cp -nar "$tempExtract" "$RC_LOC"
|
||||
}
|
||||
|
||||
step_2_info() { echo "Install composer"; }
|
||||
step_2() {
|
||||
exe cd "$RC_LOC"
|
||||
local EXPECTED_CHECKSUM="$(wget -q -O - https://composer.github.io/installer.sig)"
|
||||
exe php -r "copy('https://getcomposer.org/installer', 'composer-setup.php');"
|
||||
local ACTUAL_CHECKSUM="$(php -r "echo hash_file('sha384', 'composer-setup.php');")"
|
||||
|
||||
if [ "$EXPECTED_CHECKSUM" != "$ACTUAL_CHECKSUM" ]
|
||||
then
|
||||
echoerr ' [E] Invalid installer checksum'
|
||||
exe rm composer-setup.php
|
||||
return 1
|
||||
fi
|
||||
|
||||
exe php composer-setup.php --quiet
|
||||
saveReturn $?
|
||||
exe rm composer-setup.php
|
||||
endReturn "Composer setup failed"
|
||||
}
|
||||
|
||||
step_3_info() { echo "Configure $toolName"; }
|
||||
step_3_alias() { ALIAS="config"; }
|
||||
step_3() {
|
||||
echo " [I] Recommended composer packages to be added to \"require\" section:"
|
||||
echo ' "melanie2/mobile": "*",'
|
||||
echo ' "roundcube/carddav": "*",'
|
||||
echo ' "alexandregz/twofactor_gauthenticator": "dev-master"'
|
||||
exe read -p "Copy the lines above and press Enter to continue."
|
||||
exe vi "$RC_LOC/composer.json"
|
||||
step postupgrade
|
||||
|
||||
echo " [I] Generating mysql database $RC_DATABASE"
|
||||
echo
|
||||
exe $WDIR/mysql.sh createdb -c utf8mb4
|
||||
|
||||
echo
|
||||
echo " [I] Now visit: http://url-to-roundcube/installer/"
|
||||
echo
|
||||
echo " ! Check the database password in $RC_LOC/config/config.inc.php"
|
||||
echo " afterwards, the installer may have corrupted some special character"
|
||||
echo
|
||||
echo " ! After installation please delete $RC_LOC/installer"
|
||||
}
|
||||
|
||||
step_10_info() { echo "Configuration notes"; }
|
||||
step_10_alias() { ALIAS="notes"; }
|
||||
step_10() {
|
||||
outColor green
|
||||
cat <<NOTES_END
|
||||
# smtp port if missing after installation
|
||||
[$RC_LOC/config/config.inc.php]
|
||||
// SMTP port (default is 25; use 587 for STARTTLS or 465 for the
|
||||
// deprecated SSL over SMTP (aka SMTPS))
|
||||
\$config['smtp_port'] = 465;
|
||||
|
||||
# Enable two factor auth (installed with step config) for all user
|
||||
[$RC_LOC/plugins/twofactor_gauthenticator/config.inc.php]
|
||||
$rcmail_config['users_allowed_2FA'] = array('.*');
|
||||
|
||||
# Add mobile skin to roundcube and run step 'postupgrade'.
|
||||
Don't forget to activate plugins if asked for.
|
||||
|
||||
[$RC_LOC/composer.json]
|
||||
"require": {
|
||||
...
|
||||
"mobiledetect/mobiledetectlib": "^2.8",
|
||||
"roundcube/elastic4mobile": "dev-master"
|
||||
}
|
||||
|
||||
# Install pspell and aspell spell check engine
|
||||
apt install php7.x-pspell aspell-en aspell-de
|
||||
|
||||
[$RC_LOC/config/config.inc.php]
|
||||
\$config['spellcheck_engine'] = 'pspell';
|
||||
\$config['spellcheck_languages'] = array(
|
||||
'en' => 'English',
|
||||
'de' => 'Deutsch',
|
||||
);
|
||||
NOTES_END
|
||||
}
|
||||
|
||||
step_12_info() { echo "Troubleshooting"; }
|
||||
step_12_alias() { ALIAS="trouble"; }
|
||||
step_12() {
|
||||
outColor green
|
||||
cat <<TROUBLE_END
|
||||
# On composer update errors.
|
||||
|
||||
* Backup '/var/www/webmail/plugin' config. Especially twofactor_gauthenticator
|
||||
* Delete '/var/www/webmail/vendor' folder. Or at least 'vendor/autoload.php' and 'vendor/composer'
|
||||
* 'sqn_roundcube -q postupgrade'
|
||||
|
||||
I also installed 'php-pear' since one error indicated connection to it.
|
||||
TROUBLE_END
|
||||
}
|
||||
|
||||
step_20_info() {
|
||||
echo -n "Create a backup"
|
||||
if [ $CONFIG -ne 0 ] ; then
|
||||
echo " at $RC_BACKUP"
|
||||
else
|
||||
echo
|
||||
fi
|
||||
}
|
||||
step_20_alias() { ALIAS="backup"; }
|
||||
step_20() {
|
||||
if [ $CONFIG -eq 0 ] ; then
|
||||
echoerr " [E] No configuration file found"
|
||||
return 1
|
||||
fi
|
||||
if [ ! -z $RC_BACKUP ] ; then
|
||||
exe mkdir -p "$RC_BACKUP"
|
||||
fi
|
||||
exe $WDIR/mysql.sh -qq backup "$RC_DATABASE" "$RC_BACKUP"
|
||||
local wwwBackup="$RC_BACKUP/${toolName}_www_`date +%Y%m%d-%H%M%S`.tar.gz"
|
||||
echo " [I] Backing up webserver directory to $wwwBackup"
|
||||
exe cd "$RC_LOC/.."
|
||||
exe tar czf "$wwwBackup" $(basename "$RC_LOC")
|
||||
}
|
||||
|
||||
step_22_info() {
|
||||
echoinfoArgs "[CUSTOM VERSION]"
|
||||
echo "Upgrade installation to \"latest\" from github if [CUSTOM_VERSION] is empty"
|
||||
}
|
||||
step_22_alias() { ALIAS="upgrade"; }
|
||||
step_22() {
|
||||
shift # don't need step number
|
||||
local currentVersion=
|
||||
|
||||
if [ ! -z $1 ] ; then
|
||||
latestVersion="$1"
|
||||
else
|
||||
fetchLatestVersion
|
||||
fi
|
||||
|
||||
if [ -z $latestVersion ] ; then
|
||||
echoerr " [E] Cannot determine latest version from github repository"
|
||||
return 1
|
||||
elif [ $QUIET -eq 0 ] ; then
|
||||
echo
|
||||
currentVersion="$(grep -Po ' \| Version \K.*?(?= )' $RC_LOC/index.php)"
|
||||
exe read -p "Install $latestVersion over $currentVersion to $RC_LOC [n]o/(y)es? " answer
|
||||
case $answer in
|
||||
[yY])
|
||||
;;
|
||||
*)
|
||||
echoerr " [I] Upgrade aborted"
|
||||
return 1
|
||||
;;
|
||||
esac
|
||||
fi
|
||||
|
||||
local isInstalled=$(grep -E "RELEASE $latestVersion" "${RC_LOC}/CHANGELOG" >>/dev/null && echo "1" || echo "0")
|
||||
if [ $isInstalled -eq 1 ] ; then
|
||||
echoerr " [E] Version $latestVersion is already installed"
|
||||
return 2
|
||||
fi
|
||||
|
||||
downloadLatest
|
||||
|
||||
step backup
|
||||
echo " [I] Installing version $latestVersion to $RC_LOC"
|
||||
exe "$tempInstall" "$RC_LOC"
|
||||
echo " [I] Make sure to check composer.json-dist file for upstream changes"
|
||||
}
|
||||
|
||||
step_23_info() { echo "Post upgrade procedure"; }
|
||||
step_23_alias() { ALIAS="postupgrade"; }
|
||||
step_23() {
|
||||
exe cd "$RC_LOC"
|
||||
echo " [I] Starting post update procedure"
|
||||
exe php composer.phar update --no-dev
|
||||
}
|
||||
|
||||
fetchPhpVersion() {
|
||||
if [ ! -z $phpVersion ] ; then
|
||||
return 0
|
||||
fi
|
||||
|
||||
phpVersion="$(php -r 'echo PHP_MAJOR_VERSION.".".PHP_MINOR_VERSION;')"
|
||||
}
|
||||
|
||||
fetchLatestVersion() {
|
||||
if [ ! -z $latestVersion ] ; then
|
||||
return 0
|
||||
fi
|
||||
latestVersion=$(curl --silent "$latestUrl" | grep -Po '"tag_name": "\K.*?(?=")')
|
||||
}
|
||||
|
||||
downloadLatest() {
|
||||
fetchLatestVersion
|
||||
|
||||
local downUrl="https://github.com/roundcube/roundcubemail/releases/download/${latestVersion}/roundcubemail-${latestVersion}-complete.tar.gz"
|
||||
tempExtract="$tempDown/roundcubemail-$latestVersion"
|
||||
tempInstall="$tempExtract/bin/installto.sh"
|
||||
|
||||
if [ ! -e "$tempExtract" ] ; then
|
||||
exe mkdir -p "$tempDown"
|
||||
exe wget -O "$tempLoc" $downUrl
|
||||
endReturn -o $? "Download failed: $downUrl"
|
||||
exe cd "$tempDown"
|
||||
exe tar -xf "$tempLoc"
|
||||
endReturn -o $? "Extract failed: $tempLoc"
|
||||
else
|
||||
echo " [I] Found existing download: $tempExtract"
|
||||
fi
|
||||
}
|
||||
tempDown="/tmp/roundcube"
|
||||
tempLoc="$tempDown/rc.tar.gz"
|
||||
|
||||
VERSION_SEQREV=14
|
||||
. /usr/local/bin/sequencer.sh
|
110
seqs/rsyslog.sh
Executable file
110
seqs/rsyslog.sh
Executable file
@@ -0,0 +1,110 @@
|
||||
#!/bin/bash
|
||||
|
||||
# rsyslog management
|
||||
#
|
||||
# source:
|
||||
# - https://selivan.github.io/2017/02/07/rsyslog-log-forward-save-filename-handle-multi-line-failover.html
|
||||
|
||||
toolName="rsyslog"
|
||||
toolConfig="/etc/rsyslog.conf"
|
||||
|
||||
# Get script working directory
|
||||
# (when called from a different directory)
|
||||
WDIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >>/dev/null 2>&1 && pwd )"
|
||||
CONFIG_SNMP="$WDIR/${toolName}/10-snmp.conf"
|
||||
CONFIG_CRON="$WDIR/${toolName}/10-cron.conf"
|
||||
CONFIG_RNGD="$WDIR/${toolName}/10-rngd.conf"
|
||||
CONFIG_REMOTE="$WDIR/${toolName}/90-remote.conf"
|
||||
|
||||
step_1_info() { echo "Install $toolName"; }
|
||||
step_1_alias() { ALIAS="install"; }
|
||||
step_1() {
|
||||
exe apt update
|
||||
exe apt install "$toolName"
|
||||
}
|
||||
|
||||
step_2_info() { echo "Check configuration"; }
|
||||
step_2_alias() { ALIAS="checkconf"; }
|
||||
step_2() {
|
||||
exe rsyslogd -N 1 -f "$toolConfig"
|
||||
endReturn -o $? "Invalid $toolName configuration"
|
||||
}
|
||||
|
||||
step_10_info() { echo "Reduce snmpd syslog messages"; }
|
||||
step_10_alias() { ALIAS="snmpd"; }
|
||||
step_10() {
|
||||
addConf -s -f "$CONFIG_SNMP" "$CONFIG_SNMP_DEST"
|
||||
endReturn -o $?
|
||||
|
||||
step checkconf
|
||||
exe service rsyslog restart
|
||||
}
|
||||
CONFIG_SNMP_DEST="/etc/rsyslog.d/$(basename $CONFIG_SNMP)"
|
||||
|
||||
step_12_info() { echo "Reduce cron syslog messages"; }
|
||||
step_12_alias() { ALIAS="cron"; }
|
||||
step_12() {
|
||||
addConf -s -f "$CONFIG_CRON" "$CONFIG_CRON_DEST"
|
||||
endReturn -o $?
|
||||
|
||||
step checkconf
|
||||
exe service rsyslog restart
|
||||
}
|
||||
CONFIG_CRON_DEST="/etc/rsyslog.d/$(basename $CONFIG_CRON)"
|
||||
|
||||
step_14_info() { echo "Reduce rngd syslog messages"; }
|
||||
step_14_alias() { ALIAS="rngd"; }
|
||||
step_14() {
|
||||
addConf -s -f "$CONFIG_RNGD" "$CONFIG_RNGD_DEST"
|
||||
endReturn -o $?
|
||||
|
||||
step checkconf
|
||||
exe service rsyslog restart
|
||||
}
|
||||
CONFIG_RNGD_DEST="/etc/rsyslog.d/$(basename $CONFIG_RNGD)"
|
||||
|
||||
step_16_info() {
|
||||
echoinfoArgs "<REMOTE_IP:PORT>"
|
||||
echo "Send syslog messages to remote syslog server"
|
||||
}
|
||||
step_16_alias() { ALIAS="remote"; }
|
||||
step_16() {
|
||||
local rex='^[0-9\.]+\:[0-9]+$'
|
||||
local remoteHost=""
|
||||
# Check if string is a ipv4 address and port
|
||||
if [[ "$2" =~ $rex ]] ; then
|
||||
remoteHost=$2
|
||||
else
|
||||
echoerr " [E] No valid IP:PORT detected: $2"
|
||||
return 1
|
||||
fi
|
||||
addConf -s -f "$CONFIG_REMOTE" "$CONFIG_REMOTE_DEST"
|
||||
endReturn -o $? "Custom remote host $remoteHost not applied to destination or $MISSING_CONF"
|
||||
exe sed -i "s/12\.34\.56\.78\:514/${remoteHost}/" "$CONFIG_REMOTE_DEST"
|
||||
endReturn -o $? "Couldn't apply $remoteHost to $CONFIG_REMOTE_DEST"
|
||||
|
||||
step checkconf
|
||||
exe service rsyslog restart
|
||||
}
|
||||
CONFIG_REMOTE_DEST="/etc/rsyslog.d/$(basename $CONFIG_REMOTE)"
|
||||
|
||||
step_17_info() { echo "Add ufw rules for sending to remote syslog. Port 514/tcp"; }
|
||||
step_17_alias() { ALIAS="ufw"; }
|
||||
step_17() {
|
||||
exe ufw allow out on eth0 to any port 514 proto tcp comment "syslog remote"
|
||||
}
|
||||
|
||||
step_30_info() { echo "Activating syslog server"; }
|
||||
step_30_alias() { ALIAS="server"; }
|
||||
step_30() {
|
||||
outColor green
|
||||
cat << SERVER_EOF
|
||||
|
||||
# Uncomment the chapter
|
||||
provide UDP syslog reception
|
||||
provide TCP syslog reception
|
||||
SERVER_EOF
|
||||
}
|
||||
|
||||
VERSION_SEQREV=14
|
||||
. /usr/local/bin/sequencer.sh
|
1
seqs/rsyslog/10-cron.conf
Normal file
1
seqs/rsyslog/10-cron.conf
Normal file
@@ -0,0 +1 @@
|
||||
if $programname == 'CRON' and re_match($msg, "\\(root\\).*CMD.*") then stop
|
1
seqs/rsyslog/10-rngd.conf
Normal file
1
seqs/rsyslog/10-rngd.conf
Normal file
@@ -0,0 +1 @@
|
||||
if $programname == 'rngd' and re_match($msg, "stats:.*") then stop
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user