Skip to content

Commit e31dcff

Browse files
committed
added init scripts and services and fixed small issues
1 parent 91ee29e commit e31dcff

7 files changed

Lines changed: 214 additions & 13 deletions

File tree

README.md

Lines changed: 50 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ by [Harrier Central](https://www.harriercentral.com)
1515
* pytz
1616
* phpserialize
1717
* mysql-connector
18+
* psutil
1819

1920
### WP Event Manager Plugin
2021
* WP Event Manager >= 3.1.21
@@ -24,19 +25,19 @@ by [Harrier Central](https://www.harriercentral.com)
2425

2526
## RedHat based OS
2627
* on RedHat/CentOS 7 you need to install python3.6 and pip from EPEL first
27-
* on RedHat/CentOS 8 systems the package name changed to `python3-pip`
28-
```
28+
* on RHEL/Rocky Linux 8 systems the package name changed to `python3-pip`
29+
```shell
2930
yum install python36-pip
3031
```
3132

3233
## Ubuntu 18.04 & 20.04
33-
```
34+
```shell
3435
apt-get update && apt-get install python3-venv
3536
```
3637

3738
## Clone repo and install dependencies
3839
* download and setup of virtual environment
39-
```
40+
```shell
4041
cd /opt
4142
git clone https://github.com/bb-Ricardo/wordpress-hash-event-api.git
4243
cd wordpress-hash-event-api
@@ -45,6 +46,50 @@ python3 -m venv .venv
4546
pip3 install -r requirements.txt || pip install -r requirements.txt
4647
```
4748

49+
## Install as systemd service
50+
If files have been installed in a different directory then the systemd service file
51+
needs to be edited.
52+
53+
Ubuntu
54+
```shell
55+
cp /opt/wordpress-hash-event-api/contrib/wordpress-hash-event-api.service /etc/systemd/system
56+
```
57+
RHEL/Rocky Linux
58+
```shell
59+
sed -e 's/nogroup/nobody/g' /opt/wordpress-hash-event-api/contrib/wordpress-hash-event-api.service > /etc/systemd/system/wordpress-hash-event-api.service
60+
```
61+
62+
Enable and start service
63+
```shell
64+
systemctl daemon-reload
65+
systemctl start wordpress-hash-event-api
66+
systemctl enable wordpress-hash-event-api
67+
```
68+
69+
## Install as OpenRC service
70+
The [uvicorn.confd](contrib/uvicorn.confd) config file needs to be copied to `/etc/conf.d/`.
71+
Let's assume the API is called `nerd-h3`.
72+
```shell
73+
cp contrib/uvicorn.confd /etc/conf.d/uvicorn.nerd-h3
74+
chmod 644 /etc/conf.d/uvicorn.nerd-h3
75+
```
76+
77+
The init script [uvicorn.openrc](contrib/uvicorn.openrc) needs to be copied to `etc/init.d/`
78+
and symlinked.
79+
```shell
80+
cp contrib/uvicorn.openrc /etc/init.d/uvicorn
81+
chmod 755 /etc/init.d/uvicorn
82+
cd /etc/init.d
83+
ln -s uvicorn uvicorn.nerd-h3
84+
```
85+
86+
Then the correct values need to be set in `/etc/conf.d/uvicorn.nerd-h3`. After the configuration
87+
is finished the service can be started.
88+
```shell
89+
/etc/init.d/uvicorn.nerd-h3 start
90+
rc-update add uvicorn.nerd-h3 default
91+
```
92+
4893
## Docker
4994

5095
Run the application in docker container
@@ -74,7 +119,7 @@ All options are described in the example file.
74119
- [x] add docker file
75120
- [x] try to add "auto-install", this should set up the WordPress Event Manager to add all available fields to all events
76121
- [x] requirements.ini
77-
- [ ] add OpenRC init script and config to server API via uvicorn
122+
- [x] add OpenRC init script and config to server API via uvicorn
78123
- [ ] add nginx config example
79124
- [ ] add CORS Headers to nginx config
80125

common/log.py

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@
88
# repository or visit: <https://opensource.org/licenses/MIT>.
99

1010
import logging
11+
import psutil
12+
import os
1113

1214
# define valid log levels
1315
valid_log_levels = ["DEBUG", "INFO", "WARNING", "ERROR"]
@@ -41,6 +43,13 @@ def setup_logging(log_level=None):
4143

4244
log_format = '%(asctime)s - %(levelname)s: %(message)s'
4345

46+
# if app is started via systemd then strip time stamp from log format
47+
try:
48+
if psutil.Process(psutil.Process(os.getpid()).ppid()).name() == "systemd":
49+
log_format = '%(levelname)s: %(message)s'
50+
except Exception as e:
51+
print(f"unable to determine parent process name: {e}")
52+
4453
if log_level is None or log_level == "":
4554
print("ERROR: log level undefined or empty. Check config please.")
4655
exit(1)

contrib/uvicorn.confd

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
# /etc/conf.d/uvicorn
2+
# vim: set ft=sh:
3+
4+
###############################################################################
5+
# This configuration file defines default options for all uvicorn apis #
6+
# managed by uvicorn.* runscripts. #
7+
# #
8+
# Specific configuration for each API should be defined in a file #
9+
# /etc/conf.d/uvicorn.<API_NAME>. #
10+
###############################################################################
11+
12+
#
13+
# This is an example configuration for uvicorn runscript. It contain all
14+
# user-definable variables with their default values. If the default value is
15+
# suitable for you, then you can omit that variable in your API config.
16+
#
17+
18+
19+
# User to run the uvicorn process.
20+
#user="nobody"
21+
22+
# Group to run the uvicorn process.
23+
#group="nobody"
24+
25+
# Where to store the uvicorn process PID.
26+
#pidfile="/run/uvicorn/${API_NAME}/uvicorn.pid"
27+
28+
# Where to redirect stdout/stderr of the uvicorn process.
29+
#logfile="/var/log/uvicorn/${API_NAME}.log"
30+
31+
# Is this instance a "development" or a "production" environment
32+
# will add "--reload" to uvicorn command line if set to "development"
33+
#environment=production
34+
35+
# The path where this uvicorn api is installed
36+
#app_path="/var/www/my-api-app"
37+
38+
# The desired app which should be served by uvicorn
39+
#app_call="main:app"
40+
41+
# The port this uvicorn instance will listen on
42+
#port="8000"
43+
44+
# Any additional arguments to be passed to uvicorn command.
45+
# More options here: https://www.uvicorn.org/settings/
46+
#extra_args=""
47+
48+
# Specify service dependencies. You can use the same directives as in the
49+
# depend() function, but as variables prefixed by "rc_" (e.g. rc_need, rc_use).
50+
#rc_need=""

contrib/uvicorn.openrc

Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
#!/sbin/openrc-run
2+
# vim: set ft=sh: ts=4:
3+
4+
API_NAME="${RC_SVCNAME#uvicorn.}"
5+
6+
: ${user:=nobody}
7+
: ${group:=nobody}
8+
: ${pidfile:=/run/uvicorn/${API_NAME}/uvicorn.pid}
9+
: ${logfile:=/var/log/uvicorn/${API_NAME}.log}
10+
11+
: ${environment:=production}
12+
: ${app_path:=/var/www/my-api-app}
13+
: ${app_call:=main:app}
14+
: ${port:=8000}
15+
: ${extra_args:=}
16+
17+
name="API $API_NAME"
18+
description="uvicorn FastAPI \"$API_NAME\""
19+
20+
# using find in app_path to find uvicorn bin
21+
command=""
22+
23+
command_args="${app_call} --app-dir '${app_path}' --port ${port}"
24+
command_background='yes'
25+
command_user="$user"
26+
command_group="$group"
27+
28+
start_stop_daemon_args="--wait=1000 --stdout=$logfile --stderr=$logfile"
29+
30+
depend() {
31+
need net
32+
}
33+
34+
start_pre() {
35+
if [ "$RC_SVCNAME" = 'uvicorn' ]; then
36+
eerror ''
37+
eerror 'You are not supposed to run this runscript directly. Instead, you should'
38+
eerror 'create a symlink for the API you want to run as well as a copy of the'
39+
eerror 'configuration file and modify it appropriately, like so:'
40+
eerror ''
41+
eerror ' ln -s uvicorn /etc/init.d/uvicorn.example'
42+
eerror ' cp /etc/conf.d/uvicorn /etc/conf.d/uvicorn.example'
43+
return 1
44+
fi
45+
46+
command=$(find "${app_path}" -type f -name "uvicorn" 2>/dev/null)
47+
48+
if [ -z "$command" ]; then
49+
eerror ''
50+
eerror 'command "uvicorn" not found in app_path "'${app_path}'"'
51+
return 1
52+
fi
53+
54+
if [ ! "$environment" = "production" ]; then
55+
command_args="$command_args --reload --reload-dir '${app_path}'"
56+
fi
57+
58+
command_args="$command_args $extra_args"
59+
60+
local path; for path in "$pidfile" "$logfile"; do
61+
# checkpath doesn't create intermediate directories
62+
file_dir_path="$(dirname "$path")"
63+
mkdir -p "$file_dir_path"
64+
[ ! "$file_dir_path" = "/var/log" ] && checkpath -d -m 0755 -o root:root "$file_dir_path"
65+
touch "$path"
66+
[ ! "$path" = "$pidfile" ] && checkpath -f -m 0640 -o $user:$group "$path"
67+
done
68+
69+
return 0
70+
}
71+
72+
stop_post() {
73+
[ -f "$pidfile" ] && rm -f "$pidfile"
74+
return 0
75+
}
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
[Unit]
2+
Description=WordpPress Hash Event API
3+
Wants=network-online.target
4+
After=network-online.target
5+
6+
[Service]
7+
Type=simple
8+
User=nobody
9+
Group=nogroup
10+
WorkingDirectory=/opt/wordpress-hash-event-api
11+
ExecStart=/opt/wordpress-hash-event-api/.venv/bin/uvicorn main:app --port 8001 --proxy-headers
12+
StandardOutput=syslog
13+
StandardError=syslog
14+
SyslogIdentifier=wordpress-hash-event-api
15+
RemainAfterExit=no
16+
Restart=always
17+
RestartSec=5s
18+
19+
[Install]
20+
WantedBy=multi-user.target

main.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
#!/usr/bin/env python3.9
1+
#!/usr/bin/env python3
22
# Copyright (c) 2021 Ricardo Bartels. All rights reserved.
33
#
44
# wordpress-hash-event-api

requirements.txt

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
1-
starlette
2-
fastapi
3-
pydantic
4-
uvicorn
5-
pytz
6-
phpserialize
7-
mysql-connector
1+
wheel
2+
starlette==0.17.1
3+
fastapi==0.71.0
4+
pydantic==1.9.0
5+
uvicorn==0.17.0
6+
pytz==2021.3
7+
phpserialize==1.3
8+
mysql-connector==2.2.9
9+
psutil==5.9.0

0 commit comments

Comments
 (0)