mirror of
https://github.com/TrezOne/docker-mods-uptime-kuma-timeout-fix.git
synced 2026-06-26 02:03:14 -04:00
Merge pull request #451 from junkman690/jellyfin-rffmpeg
jellyfin:rffmpeg initial release
This commit is contained in:
@@ -4,8 +4,8 @@ on: [push, pull_request, workflow_dispatch]
|
||||
|
||||
env:
|
||||
ENDPOINT: "linuxserver/mods" #don't modify
|
||||
BASEIMAGE: "replace_baseimage" #replace
|
||||
MODNAME: "replace_modname" #replace
|
||||
BASEIMAGE: "jellyfin" #replace
|
||||
MODNAME: "rffmpeg" #replace
|
||||
|
||||
jobs:
|
||||
build:
|
||||
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
FROM scratch
|
||||
|
||||
LABEL maintainer="username"
|
||||
LABEL maintainer="junkman690"
|
||||
|
||||
# copy local files
|
||||
COPY root/ /
|
||||
|
||||
@@ -1,23 +0,0 @@
|
||||
## Buildstage ##
|
||||
FROM ghcr.io/linuxserver/baseimage-alpine:3.12 as buildstage
|
||||
|
||||
RUN \
|
||||
echo "**** install packages ****" && \
|
||||
apk add --no-cache \
|
||||
curl && \
|
||||
echo "**** grab rclone ****" && \
|
||||
mkdir -p /root-layer && \
|
||||
curl -o \
|
||||
/root-layer/rclone.deb -L \
|
||||
"https://downloads.rclone.org/v1.47.0/rclone-v1.47.0-linux-amd64.deb"
|
||||
|
||||
# copy local files
|
||||
COPY root/ /root-layer/
|
||||
|
||||
## Single layer deployed image ##
|
||||
FROM scratch
|
||||
|
||||
LABEL maintainer="username"
|
||||
|
||||
# Add files from buildstage
|
||||
COPY --from=buildstage /root-layer/ /
|
||||
@@ -1,25 +1,88 @@
|
||||
# Rsync - Docker mod for openssh-server
|
||||
# rffmpeg - Docker mod for Jellyfin
|
||||
|
||||
This mod adds rsync to openssh-server, to be installed/updated during container start.
|
||||
This mod adds rffmpeg to Linuxserver.io's Jellyfin https://github.com/linuxserver/docker-jellyfin.
|
||||
|
||||
In openssh-server docker arguments, set an environment variable `DOCKER_MODS=linuxserver/mods:openssh-server-rsync`
|
||||
rffmpeg is a remote FFmpeg wrapper used to execute FFmpeg commands on a remote server via SSH. It is most useful in situations involving media servers such as Jellyfin (our reference user), where one might want to perform transcoding actions with FFmpeg on a remote machine or set of machines which can better handle transcoding, take advantage of hardware acceleration, or distribute transcodes across multiple servers for load balancing.
|
||||
|
||||
If adding multiple mods, enter them in an array separated by `|`, such as `DOCKER_MODS=linuxserver/mods:openssh-server-rsync|linuxserver/mods:openssh-server-mod2`
|
||||
See https://github.com/joshuaboniface/rffmpeg for more details about rffmpeg
|
||||
|
||||
# Mod creation instructions
|
||||
In Jellyfin docker arguments, set an environment variable `DOCKER_MODS=linuxserver/mods:jellyfin-rffmpeg`
|
||||
|
||||
* Fork the repo, create a new branch based on the branch `template`.
|
||||
* Edit the `Dockerfile` for the mod. `Dockerfile.complex` is only an example and included for reference; it should be deleted when done.
|
||||
* Inspect the `root` folder contents. Edit, add and remove as necessary.
|
||||
* Edit this readme with pertinent info, delete these instructions.
|
||||
* Finally edit the `.github/workflows/BuildImage.yml`. Customize the build branch, and the vars for `BASEIMAGE` and `MODNAME`.
|
||||
* Ask the team to create a new branch named `<baseimagename>-<modname>`. Baseimage should be the name of the image the mod will be applied to. The new branch will be based on the `template` branch.
|
||||
* Submit PR against the branch created by the team.
|
||||
If adding multiple mods, enter them in an array separated by `|`, such as `DOCKER_MODS=linuxserver/mods:jellyfin-rffmpeg|linuxserver/mods:jellyfin-mod2`
|
||||
|
||||
This mod requires you to update the rffmpeg.yml located in "Your jellyfin config dir"/rffmpeg/rffmpeg.yml with your remote SSH username. You also need to add your authorized SSH file to "Your jellyfin config dir"/rffmpeg/.ssh/id_rsa"
|
||||
|
||||
## Tips and tricks
|
||||
You can specify the remote SSH username and host using ENV, note currently only supports 1 host and doesn't overwrite values other than defaults:
|
||||
* RFFMPEG_USER= remote SSH username
|
||||
* RFFMPEG_HOST= remote server name or IP
|
||||
|
||||
* To decrease startup times when multiple mods are used, we have consolidated `apt-get update` down to one file. As seen in the [nodejs mod](https://github.com/linuxserver/docker-mods/tree/code-server-nodejs/root/etc/cont-init.d)
|
||||
* Some images has helpers built in, these images are currently:
|
||||
* [Openvscode-server](https://github.com/linuxserver/docker-openvscode-server/pull/10/files)
|
||||
* [Code-server](https://github.com/linuxserver/docker-code-server/pull/95)
|
||||
You also need to ensure that /cache inside the container is exported on the host so it can be mapped on the remote host. Eg for docker compose.
|
||||
```yaml
|
||||
volumes:
|
||||
- "Your jellyfin config dir":/config
|
||||
- "Your jellyfin config dir"/cache:/cache
|
||||
```
|
||||
See https://github.com/joshuaboniface/rffmpeg/blob/master/SETUP.md NFS setup for more details
|
||||
|
||||
EXAMPLE Docker-Compose file with WOL support via API:
|
||||
|
||||
```yaml
|
||||
---
|
||||
version: "2.1"
|
||||
services:
|
||||
jellyfin:
|
||||
image: lscr.io/linuxserver/jellyfin:latest
|
||||
container_name: jellyfin
|
||||
environment:
|
||||
- PUID=1000
|
||||
- PGID=1000
|
||||
- TZ=Europe/London
|
||||
- RFFMPEG_USER=jellyfin
|
||||
- RFFMPEG_WOL=api
|
||||
- RFFMPEG_HOST=transcode
|
||||
- RFFMPEG_HOST_MAC="12:ab:34:cd:ef:56"
|
||||
- WOL_API=192.168.1.5 #docker host IP
|
||||
- WOL_API_PORT=8431
|
||||
- WOL_WAIT=10 #time transcode host takes to start
|
||||
volumes:
|
||||
- /path/to/jellyfin/config:/config
|
||||
- /path/to/jellyfin/config/cache:/cache
|
||||
- /path/to/data:/data/
|
||||
ports:
|
||||
- 8096:8096
|
||||
- 8920:8920 #optional
|
||||
- 7359:7359/udp #optional
|
||||
- 1900:1900/udp #optional
|
||||
restart: unless-stopped
|
||||
depends_on:
|
||||
- wol_api
|
||||
wol_api:
|
||||
image: rix1337/docker-wol_api
|
||||
container_name: wol_api
|
||||
environment:
|
||||
- PORT=8431
|
||||
network_mode: host
|
||||
restart: unless-stopped
|
||||
```
|
||||
|
||||
If you want to run rffmpeg commands they must be run as ABC inside the container eg:
|
||||
* To add new host ``` docker exec -it jellyfin s6-setuidgid abc /usr/local/bin/rffmpeg add --weight 1 remotehost ```
|
||||
* To view status ``` docker exec -it jellyfin s6-setuidgid abc /usr/local/bin/rffmpeg status ```
|
||||
* To test connection ``` docker exec -it jellyfin s6-setuidgid abc /usr/local/bin/ffmpeg -version ```
|
||||
* To test connection ``` docker exec -it jellyfin s6-setuidgid abc /usr/local/bin/ffprobe -version ```
|
||||
* To view all commands ``` docker exec -it jellyfin s6-setuidgid abc /usr/local/bin/rffmpeg -h ```
|
||||
|
||||
You then need to set your FFMPEG binary in Jellyfin to:
|
||||
* /usr/local/bin/ffmpeg - Normal rffmpeg without WOL support
|
||||
* /usr/local/bin/wol_rffmpeg/ffmpeg - rffmpeg with WOL support
|
||||
|
||||
WOL Support
|
||||
Native WOL support is available if you are running in host network mode. If not you can use the WOL_API container https://hub.docker.com/r/rix1337/docker-wol_api. Note the image name is rix1337/docker-wol_api
|
||||
|
||||
WOL ENV:
|
||||
* RFFMPEG_WOL= native or api
|
||||
* RFFMPEG_HOST= remote host to wake
|
||||
* RFFMPEG_HOST_MAC= remote host to wake mac enclosed in " " eg "aa:12:34:bb:cc:56"
|
||||
* WOL_API = IP of docker host
|
||||
* WOL_API_PORT= port wol_api is running on
|
||||
* WOL_WAIT= time in seconds to wait for host to wake
|
||||
|
||||
@@ -0,0 +1,70 @@
|
||||
---
|
||||
# Configuration file for rffmpeg
|
||||
#
|
||||
# Copy this sample to /etc/rffmpeg/rffmpeg.yml and replace the various attributes
|
||||
# with the values for your environment. For more details please see the README.
|
||||
#
|
||||
# Any commented value represents the default. Uncomment and alter as required.
|
||||
|
||||
rffmpeg:
|
||||
# Logging configuration
|
||||
logging:
|
||||
# Enable or disable file logging.
|
||||
#log_to_file: true
|
||||
|
||||
# Log messages to this file.
|
||||
# Ensure the user running rffmpeg can write to this directory.
|
||||
#logfile: "/var/log/jellyfin/rffmpeg.log"
|
||||
|
||||
# Show debugging messages
|
||||
#debug: false
|
||||
|
||||
# Directory configuration
|
||||
directories:
|
||||
# Persistent directory to store state database.
|
||||
#state: "/var/lib/rffmpeg"
|
||||
|
||||
# Temporary directory to store SSH persistence sockets.
|
||||
#persist: "/run/shm"
|
||||
|
||||
# The user who should own the state directory and database.
|
||||
# This should normally be the user who normally runs rffmpeg commands (i.e. the media
|
||||
# server service user).
|
||||
#owner: jellyfin
|
||||
|
||||
# The group who should own the state directory and database (an administrative group).
|
||||
# Use this group to control who is able to run "rffmpeg" management commands; users in
|
||||
# this group will have unlimited access to the tool to add/remove hosts, view status, etc.
|
||||
#group: sudo
|
||||
|
||||
# Remote (SSH) configuration
|
||||
remote:
|
||||
# The remote SSH user to connect as.
|
||||
#user: jellyfin
|
||||
|
||||
# How long to persist SSH sessions; 0 to disable SSH persistence.
|
||||
#persist: 300
|
||||
|
||||
# A YAML list of additional SSH arguments (e.g. private keys).
|
||||
# One entry line per space-separated argument element.
|
||||
#args:
|
||||
# - "-i"
|
||||
# - "/var/lib/jellyfin/id_rsa"
|
||||
|
||||
# Remote command configuration
|
||||
commands:
|
||||
# The path (either full or in $PATH) to the default SSH binary.
|
||||
#ssh: "/usr/bin/ssh"
|
||||
|
||||
# A YAML list of prefixes to the ffmpeg command (e.g. sudo, nice, etc.).
|
||||
# One entry line per space-separated command element.
|
||||
#pre:
|
||||
# - ""
|
||||
|
||||
# The (remote) ffmpeg and ffprobe command binary paths.
|
||||
#ffmpeg: "/usr/lib/jellyfin-ffmpeg/ffmpeg"
|
||||
#ffprobe: "/usr/lib/jellyfin-ffmpeg/ffprobe"
|
||||
|
||||
# Optional local fallback ffmpeg and ffprobe binary paths, if different from the above.
|
||||
#fallback_ffmpeg: "/usr/lib/jellyfin-ffmpeg/ffmpeg"
|
||||
#fallback_ffprobe: "/usr/lib/jellyfin-ffmpeg/ffprobe"
|
||||
@@ -0,0 +1,3 @@
|
||||
#!/usr/bin/with-contenv bash
|
||||
|
||||
apt-get update
|
||||
@@ -0,0 +1,58 @@
|
||||
#!/usr/bin/with-contenv bash
|
||||
|
||||
#Install dependancies
|
||||
apt-get install -y --no-install-recommends \
|
||||
iputils-ping \
|
||||
openssh-client \
|
||||
python3-click \
|
||||
python3-yaml \
|
||||
wakeonlan
|
||||
|
||||
#Grab Config
|
||||
mkdir -p \
|
||||
/etc/rffmpeg \
|
||||
/config/rffmpeg/.ssh
|
||||
touch /config/rffmpeg/.ssh/id_rsa
|
||||
chmod 600 /config/rffmpeg/.ssh/id_rsa
|
||||
if [ -f /config/rffmpeg/rffmpeg.yml ]; then
|
||||
echo "**** rffmpeg.yml already present ****"
|
||||
else
|
||||
echo "**** Creating rffmpeg.yml from sample ****"
|
||||
cp /defaults/rffmpeg.yml.sample /config/rffmpeg/rffmpeg.yml
|
||||
fi
|
||||
|
||||
#Grab rffmpeg
|
||||
mkdir -p /usr/local/bin/
|
||||
echo "**** Grabbing rffmpeg from upstream ****"
|
||||
rm -rf /usr/local/bin/rffmpeg
|
||||
curl -L -o /usr/local/bin/rffmpeg https://raw.githubusercontent.com/joshuaboniface/rffmpeg/master/rffmpeg
|
||||
chmod +x /usr/local/bin/rffmpeg
|
||||
|
||||
##Update rffmpeg.yml
|
||||
sed -i 's~#persist: "/run/shm"~persist: "/dev/shm"~' /config/rffmpeg/rffmpeg.yml
|
||||
sed -i 's~#state: "/var/lib/rffmpeg"~state: "/config/rffmpeg"~' /config/rffmpeg/rffmpeg.yml
|
||||
sed -i 's~#logfile: "/var/log/jellyfin/rffmpeg.log"~logfile: "/config/rffmpeg/rffmpeg.log"~' /config/rffmpeg/rffmpeg.yml
|
||||
sed -i 's~#log_to_file: true~log_to_file: true~' /config/rffmpeg/rffmpeg.yml
|
||||
sed -i 's~#owner: jellyfin~owner: abc~' /config/rffmpeg/rffmpeg.yml
|
||||
sed -i 's~#group: sudo~group: abc~' /config/rffmpeg/rffmpeg.yml
|
||||
sed -i 's~#args:~args:~' /config/rffmpeg/rffmpeg.yml
|
||||
sed -i 's~# - "-i"~ - "-i"~' /config/rffmpeg/rffmpeg.yml
|
||||
sed -i 's~# - "/var/lib/jellyfin/id_rsa"~ - "/config/rffmpeg/.ssh/id_rsa"~' /config/rffmpeg/rffmpeg.yml
|
||||
if [ ! -z "$RFFMPEG_USER" ]; then
|
||||
sed -i "s~#user: jellyfin~user: $RFFMPEG_USER~" /config/rffmpeg/rffmpeg.yml
|
||||
fi
|
||||
|
||||
#Fix permissions
|
||||
chown abc:abc -R /config/rffmpeg
|
||||
|
||||
#Initialize database
|
||||
if [ -f /config/rffmpeg/rffmpeg.db ]; then
|
||||
echo "**** DB already inialized ****"
|
||||
else
|
||||
echo "**** Initialize database ****"
|
||||
/usr/local/bin/rffmpeg init --yes
|
||||
#Add host
|
||||
if [ ! -z "$RFFMPEG_HOST" ]; then
|
||||
s6-setuidgid abc /usr/local/bin/rffmpeg add --weight 1 $RFFMPEG_HOST
|
||||
fi
|
||||
fi
|
||||
@@ -1,27 +0,0 @@
|
||||
#!/usr/bin/with-contenv bash
|
||||
|
||||
# Determine if setup is needed
|
||||
if [ ! -f /usr/local/lib/python***/dist-packages/sshuttle ] && \
|
||||
[ -f /usr/bin/apt ]; then
|
||||
## Ubuntu
|
||||
apt-get update
|
||||
apt-get install --no-install-recommends -y \
|
||||
iptables \
|
||||
openssh-client \
|
||||
python3 \
|
||||
python3-pip
|
||||
pip3 install sshuttle
|
||||
fi
|
||||
if [ ! -f /usr/lib/python***/site-packages/sshuttle ] && \
|
||||
[ -f /sbin/apk ]; then
|
||||
# Alpine
|
||||
apk add --no-cache \
|
||||
iptables \
|
||||
openssh \
|
||||
py3-pip \
|
||||
python3
|
||||
pip3 install sshuttle
|
||||
fi
|
||||
|
||||
chown -R root:root /root
|
||||
chmod -R 600 /root/.ssh
|
||||
Symlink
+1
@@ -0,0 +1 @@
|
||||
/config/rffmpeg/rffmpeg.yml
|
||||
@@ -0,0 +1,14 @@
|
||||
#!/usr/bin/with-contenv bash
|
||||
|
||||
for package in iputils-ping openssh-client python3-click python3-yaml wakeonlan; do
|
||||
if ! dpkg -s "${package}" >/dev/null 2>&1; then
|
||||
PACKAGES="${package} ${PACKAGES}"
|
||||
fi
|
||||
done
|
||||
|
||||
if [ -n "${PACKAGES}" ]; then
|
||||
echo "${PACKAGES}" >> /mod-repo-packages-to-install.list
|
||||
echo "**** Adding rffmpeg dependencies to package install list ****"
|
||||
else
|
||||
echo "**** rffmpeg dependencies already installed, skipping ****"
|
||||
fi
|
||||
@@ -0,0 +1 @@
|
||||
oneshot
|
||||
@@ -0,0 +1 @@
|
||||
/etc/s6-overlay/s6-rc.d/init-mod-jellyfin-rffmpeg-add-package/run
|
||||
@@ -0,0 +1,50 @@
|
||||
#!/usr/bin/with-contenv bash
|
||||
|
||||
#Grab Config
|
||||
mkdir -p \
|
||||
/etc/rffmpeg \
|
||||
/config/rffmpeg/.ssh
|
||||
touch /config/rffmpeg/.ssh/id_rsa
|
||||
chmod 600 /config/rffmpeg/.ssh/id_rsa
|
||||
if [ -f /config/rffmpeg/rffmpeg.yml ]; then
|
||||
echo "**** rffmpeg.yml already present ****"
|
||||
else
|
||||
echo "**** Creating rffmpeg.yml from sample ****"
|
||||
cp /defaults/rffmpeg.yml.sample /config/rffmpeg/rffmpeg.yml
|
||||
fi
|
||||
|
||||
#Grab rffmpeg
|
||||
mkdir -p /usr/local/bin/
|
||||
echo "**** Grabbing rffmpeg from upstream ****"
|
||||
rm -rf /usr/local/bin/rffmpeg
|
||||
curl -L -o /usr/local/bin/rffmpeg https://raw.githubusercontent.com/joshuaboniface/rffmpeg/master/rffmpeg
|
||||
chmod +x /usr/local/bin/rffmpeg
|
||||
|
||||
##Update rffmpeg.yml
|
||||
sed -i 's~#persist: "/run/shm"~persist: "/dev/shm"~' /config/rffmpeg/rffmpeg.yml
|
||||
sed -i 's~#state: "/var/lib/rffmpeg"~state: "/config/rffmpeg"~' /config/rffmpeg/rffmpeg.yml
|
||||
sed -i 's~#logfile: "/var/log/jellyfin/rffmpeg.log"~logfile: "/config/rffmpeg/rffmpeg.log"~' /config/rffmpeg/rffmpeg.yml
|
||||
sed -i 's~#log_to_file: true~log_to_file: true~' /config/rffmpeg/rffmpeg.yml
|
||||
sed -i 's~#owner: jellyfin~owner: abc~' /config/rffmpeg/rffmpeg.yml
|
||||
sed -i 's~#group: sudo~group: abc~' /config/rffmpeg/rffmpeg.yml
|
||||
sed -i 's~#args:~args:~' /config/rffmpeg/rffmpeg.yml
|
||||
sed -i 's~# - "-i"~ - "-i"~' /config/rffmpeg/rffmpeg.yml
|
||||
sed -i 's~# - "/var/lib/jellyfin/id_rsa"~ - "/config/rffmpeg/.ssh/id_rsa"~' /config/rffmpeg/rffmpeg.yml
|
||||
if [ ! -z "$RFFMPEG_USER" ]; then
|
||||
sed -i "s~#user: jellyfin~user: $RFFMPEG_USER~" /config/rffmpeg/rffmpeg.yml
|
||||
fi
|
||||
|
||||
#Fix permissions
|
||||
chown abc:abc -R /config/rffmpeg
|
||||
|
||||
#Initialize database
|
||||
if [ -f /config/rffmpeg/rffmpeg.db ]; then
|
||||
echo "**** rffmpeg DB already inialized ****"
|
||||
else
|
||||
echo "**** Initialize rffmpeg database ****"
|
||||
/usr/local/bin/rffmpeg init --yes
|
||||
#Add host
|
||||
if [ ! -z "$RFFMPEG_HOST" ]; then
|
||||
s6-setuidgid abc /usr/local/bin/rffmpeg add --weight 1 $RFFMPEG_HOST
|
||||
fi
|
||||
fi
|
||||
@@ -0,0 +1 @@
|
||||
oneshot
|
||||
@@ -0,0 +1 @@
|
||||
/etc/s6-overlay/s6-rc.d/init-mod-jellyfin-rffmpeg-setup/run
|
||||
@@ -1,3 +0,0 @@
|
||||
#!/usr/bin/with-contenv bash
|
||||
|
||||
sshuttle --dns --remote root@${HOST}:${PORT} 0/0 -x 172.17.0.0/16
|
||||
Symlink
+1
@@ -0,0 +1 @@
|
||||
rffmpeg
|
||||
Symlink
+1
@@ -0,0 +1 @@
|
||||
rffmpeg
|
||||
+1
@@ -0,0 +1 @@
|
||||
wol
|
||||
+1
@@ -0,0 +1 @@
|
||||
wol
|
||||
Executable
+44
@@ -0,0 +1,44 @@
|
||||
#!/usr/bin/bash
|
||||
|
||||
mac="${RFFMPEG_HOST_MAC%\"}"
|
||||
mac="${mac#\"}"
|
||||
|
||||
if [ -z $WOL_WAIT ]
|
||||
then
|
||||
WOL_WAIT=30
|
||||
fi
|
||||
|
||||
ping -c1 -W1 $RFFMPEG_HOST >/dev/null 2>&1 && host=up || host=down
|
||||
|
||||
if [ $RFFMPEG_WOL == "native" ] && [ ! -z $RFFMPEG_HOST ] && [ ! -z $RFFMPEG_HOST_MAC ] && [ ! -z $WOL_WAIT ] && [ $host == "down" ];
|
||||
then
|
||||
echo WOL enabled
|
||||
echo "$RFFMPEG_HOST" is down, sending wakeup to "$mac"
|
||||
wakeonlan $mac
|
||||
#wakeonlan -i $RFFMPEG_HOST $mac
|
||||
echo "waiting $WOL_WAIT seconds for $RFFMPEG_HOST to wake"
|
||||
sleep $WOL_WAIT
|
||||
fi
|
||||
|
||||
if [ $RFFMPEG_WOL == "api" ] && [ ! -z $RFFMPEG_HOST ] && [ ! -z $RFFMPEG_HOST_MAC ] && [ $host == "down" ] && [ ! -z $WOL_WAIT ] && [ ! -z $WOL_API ] && [ ! -z $WOL_API_PORT ];
|
||||
then
|
||||
echo WOL enabled
|
||||
echo "$RFFMPEG_HOST" is down, sending wakeup via WOL_API: curl -X POST $WOL_API:$WOL_API_PORT/wol/"$mac"
|
||||
curl -X POST $WOL_API:$WOL_API_PORT/wol/$mac
|
||||
echo "waiting $WOL_WAIT seconds for $RFFMPEG_HOST to wake"
|
||||
sleep $WOL_WAIT
|
||||
fi
|
||||
|
||||
if [ ${0##*/} == "ffmpeg" ]
|
||||
then
|
||||
#echo ${0##*/}
|
||||
/usr/local/bin/ffmpeg "$@"
|
||||
fi
|
||||
|
||||
if [ ${0##*/} == "ffprobe" ];
|
||||
then
|
||||
#echo ${0##*/}
|
||||
/usr/local/bin/ffprobe "$@"
|
||||
fi
|
||||
|
||||
exit
|
||||
Reference in New Issue
Block a user