Commit 60f2ba12 authored by Jens Henrik  Goebbert's avatar Jens Henrik Goebbert

made profiles ready for JURECA

parent 3112f869
......@@ -9,7 +9,7 @@ A graphical desktop can increase productivity of each HPC-user as the workflows
It also helps new users to shorten the time to debug, run and post-process their codes (e.g. debugging, performance and visualization tools are more easy to start use).
But different user groups and various research topics make sense for multiple desktop configurations.
The solution are XDG Desktop Profiles (https://specifications.freedesktop.org/basedir-spec/basedir-spec-latest.html).
The solution are XDG Desktop Profiles (https://specifications.freedesktop.org).
They are located in *${XDG_PROFILES_DIR}* with each profile located in one subdirectory.
The current profile name is *${XDG_PROFILE}*.
......@@ -39,10 +39,10 @@ These configurations overwrite all settings located in *${XDG_CONFIG_DIRS}*.
All XDG data, which is independent of a certain configuration, is stored in *${XDG_DATA_HOME}* for each user or in *${XDG_DATA_DIRS}* system-wide.
This can be
- background images
- .desktop-files for desktop icons, menus or autostart files
- icons
- submenus for the application menu
- mime type settings
- .desktop-files for desktop icons, menus or autostart files ([4])
- icons (*${XDG_DATA_HOME}*/icons [5])
- submenus for the application menu ([6])
- mime type settings ([7])
- infoterm directories
*${XDG_DATA_HOME}* is set to *${HOME}/.local/xdg_profiles/${XDG_PROFILE}*.
*${XDG_DATA_DIRS}* includes multiple directories starting with *${XDG_PROFILES_DIR}/${XDG_PROFILE}/data/*
......@@ -84,8 +84,22 @@ srun -n 1 --cpu_bind=none --gres=gpu:1 bash -c 'vncserver -profile vis'
## XFCE4 XDG configurations
XDG Base Directory Specification are supported by most of the popular desktop systems found on Linux (GNOME, KDE, XFCE etc.). On JURECA we use XFCE4 as a light weighted desktop system.
XDG Base Directory Specification are supported by most of the popular desktop systems found on Linux (GNOME, KDE, XFCE etc.).
They are specified in documents located at (https://specifications.freedesktop.org). Examples are:
- standard search paths
- icons
- *${XDG_DATA_DIRS}/icons*
- will be overwritten by other files listed in [5]
- menus
- *{$XDG_CONFIG_DIRS}/menus/applications-merged*
- *{$XDG_DATA_DIRS}/applications*
- will be overwritten by other paths/files listed in [6]
- mime types
- *${XDG_DATA_DIRS}/applications/mimeapps.list*
- will be overwritten by other files listed in [7]
On JURECA we use XFCE4 as a light weighted desktop system, which supports the specifications of the X Desktop Group.
XFCE4 specific configurations are stored in *${XDF_CONFIG_\*}/xfce4/* and
XFCE4 specific data is stored in *${XDF_DATA_\*}/xfce4/*. Examples are:
......@@ -103,6 +117,18 @@ XFCE4 specific data is stored in *${XDF_DATA_\*}/xfce4/*. Examples are:
- panel widget description files:
- ${XDG_CONFIG_\*}/xfce4/panel/
- standard search paths
- icons
- *${XDG_DATA_DIRS}/icons*
- will be overwritten by other files listed in [5]
- menus
- *{$XDG_CONFIG_DIRS}/menus/applications-merged*
- *{$XDG_DATA_DIRS}/applications*
- will be overwritten by other paths/files listed in [6]
- mime types
- *${XDG_DATA_DIRS}/applications/mimeapps.list*
- will be overwritten by other files listed in [7]
#### Background Image
The background image is set in *${XDF_CONFIG_\*}/xfce4/xfconf/xfce-perchannel-xml/xfce4-desktop.xml*.
......@@ -159,7 +185,7 @@ Adding "Category=Visualization" to a .desktop-file will place it in the sub-menu
The application menu icon is set in *${XDF_CONFIG_\*}/xfce4/xfconf/xfce-perchannel-xml/xfce4-panel.xml*.
By default it is set in the default profile in *etc/xdg/xdg_profiles/default/config/xfce4/xfconf/xfce-perchannel-xml/xfce4-panel.xml*
to the FZJ logo located in *etc/xdg/xdg_profiles/default/data/pixmaps/fzj-logo_64x64.png*.
to the FZJ logo located in *etc/xdg/xdg_profiles/default/data/icons/fzj-logo_64x64.png*.
##### MIME Types
MIME types are defined in ${XDG_DATA_DIRS}/mime/packages.
......@@ -222,3 +248,12 @@ Devil's Pie runs in the background and is called from *etc/xdg/xdg_profiles/defa
But the messages can also be caught and processed from anyone else (e.g. http://bazaar.launchpad.net/~jconti/recent-notifications/trunk/view/head:/recent_notifications/Notification.py)
Nice-to-know: Desktop notifications support HTML (http://www.galago-project.org/specs/notification/0.9/x161.html)
## References
[1] freedesktop specs - https://specifications.freedesktop.org
[2] basedir - https://specifications.freedesktop.org/basedir-spec/basedir-spec-latest.html
[3] autostart - https://specifications.freedesktop.org/autostart-spec/autostart-spec-latest.html
[4] desktop-entry - https://specifications.freedesktop.org/desktop-entry-spec/desktop-entry-spec-latest.html
[5] icons - https://specifications.freedesktop.org/icon-theme-spec/icon-theme-spec-latest.html
[6] menus - https://specifications.freedesktop.org/menu-spec/menu-spec-latest.html
[7] mime - https://specifications.freedesktop.org/mime-apps-spec/mime-apps-spec-latest.html
# set XDG profiles directory
export XDG_PROFILES_DIR=${XDG_PROFILES_DIR:-/homeb/zam/goebbert/workspace/xdg_profiles/etc/xdg/xdg_profiles}
export XDG_PROFILES_DIR=${XDG_PROFILES_DIR:-/homeb/zam/goebbert/workspace/xdg_profiles/etc/xdg/profiles}
# initialize XDG profiles
source ${XDG_PROFILES_DIR}/../xdg_profile_set.sh
source ${XDG_PROFILES_DIR}/../scripts/xdg_profile_set.sh
# run XFCE4
# (replaces the current shell with startxfce4, without forking a new process)
......
# set XDG profiles directory
export XDG_PROFILES_DIR=${XDG_PROFILES_DIR:-/homeb/zam/goebbert/workspace/xdg_profiles/etc/xdg/xdg_profiles}
export XDG_PROFILES_DIR=${XDG_PROFILES_DIR:-/homeb/zam/goebbert/workspace/xdg_profiles/etc/xdg/profiles}
# initialize XDG profiles
source ${XDG_PROFILES_DIR}/../xdg_profile_set.sh
source ${XDG_PROFILES_DIR}/../scripts/xdg_profile_set.sh
# run XFCE4
# (replaces the current shell with startxfce4, without forking a new process)
......
......@@ -32,7 +32,7 @@ if (get_window_name()=="infoterm-motd-default") then
center()
-- focuses the current window
focus_window()
-- focus_window() - this gives the error: "Wnck-WARNING **: Received a timestamp of 0; window activation may not function properly."
-- sets the window type, according to _NET_WM_WINDOW_TYPE
-- set_window_type("WINDOW_TYPE_SPLASH")
......
......@@ -4,9 +4,9 @@
<property name="backdrop" type="empty">
<property name="screen0" type="empty">
<property name="monitor0" type="empty">
<property name="image-path" type="string" value="/homeb/zam/goebbert/workspace/xdg_profiles/etc/xdg/xdg_profiles/default/data/xfce4/backdrops/default-background_default.jpg"/>
<property name="image-path" type="string" value="/homeb/zam/goebbert/workspace/xdg_profiles/etc/xdg/profiles/default/data/xfce4/backdrops/default-background_default.jpg"/>
<property name="last-image" type="empty"/>
<property name="last-single-image" type="string" value="/homeb/zam/goebbert/workspace/xdg_profiles/etc/xdg/xdg_profiles/default/data/xfce4/backdrops/default-background_default.jpg"/>
<property name="last-single-image" type="string" value="/homeb/zam/goebbert/workspace/xdg_profiles/etc/xdg/profiles/default/data/xfce4/backdrops/default-background_default.jpg"/>
<property name="last-image-list" type="empty"/>
<property name="backdrop-cycle-enable" type="empty"/>
<property name="backdrop-cycle-timer" type="empty"/>
......
......@@ -22,7 +22,7 @@
</property>
<property name="plugins" type="empty">
<property name="plugin-1" type="string" value="applicationsmenu">
<property name="button-icon" type="string" value="/homeb/zam/goebbert/workspace/xdg_profiles/etc/xdg/xdg_profiles/default/data/pixmaps/fzj-logo_64x64.png"/>
<property name="button-icon" type="string" value="/homeb/zam/goebbert/workspace/xdg_profiles/etc/xdg/profiles/default/data/icons/fzj-logo_64x64.png"/>
<property name="show-tooltips" type="bool" value="true"/>
</property>
<property name="plugin-2" type="string" value="actions">
......
......@@ -4,7 +4,7 @@ Type=Application
Name=LLview
Comment=
Exec=llview
Icon=/homeb/zam/goebbert/workspace/xdg_profiles/etc/xdg/xdg_profiles/default/data/pixmaps/llview_32x32.png
Icon=llview_32x32.png
Path=
Terminal=false
StartupNotify=false
......
[Desktop Entry]
Version=1.0
Type=Directory
Icon=/homeb/zam/goebbert/workspace/xdg_profiles/etc/xdg/xdg_profiles/default/data/pixmaps/fzj-utils-logo_32x32.png
Icon=fzj-utils-logo_32x32.png
Name=FZJ Utilities
Comment=Forschungszentrum Juelich - Utilities
[Desktop Entry]
Version=1.0
Type=Directory
Icon=/homeb/zam/goebbert/workspace/xdg_profiles/etc/xdg/xdg_profiles/vis/data/pixmaps/fzj-vis-logo_32x32.png
Icon=fzj-vis-logo_32x32.png
Name=FZJ Visualization
Comment=Forschungszentrum Juelich - Visualization
[Desktop Entry]
Version=1.0
Type=Directory
Icon=/homeb/zam/goebbert/workspace/xdg_profiles/etc/xdg/xdg_profiles/default/data/pixmaps/fzj-logo_32x32.png
Icon=fzj-logo_32x32.png
Name=FZ Juelich
Comment=Forschungszentrum Juelich
......@@ -4,7 +4,7 @@ Type=Application
Name=ParaView
Comment=
Exec=bash -c 'module load intel-para/2015.07 && module load ParaView/4.3.1 && vglrun paraview'
Icon=/homeb/zam/goebbert/workspace/xdg_profiles/etc/xdg/xdg_profiles/vis/data/pixmaps/paraview.png
Icon=paraview.png
Path=
Terminal=true
StartupNotify=false
......
......@@ -4,7 +4,7 @@ Type=Application
Name=VisIt
Comment=
Exec=bash -c 'export TERM=xterm && module purge --force && module load Stages/Devel && module load intel-para/2015.07 && module load VisIt && vglrun visit'
Icon=/homeb/zam/goebbert/workspace/xdg_profiles/etc/xdg/xdg_profiles/vis/data/pixmaps/paraview.png
Icon=paraview.png
Path=
Terminal=true
StartupNotify=false
......
[Desktop Entry]
Version=1.0
Type=Directory
Icon=/homeb/zam/goebbert/workspace/xdg_profiles/etc/xdg/xdg_profiles/vis/data/pixmaps/vis-logo_32x32.png
Icon=vis-logo_32x32.png
Name=Visualization
Comment=Juelich Supercomputing Centre - Visualization
../scripts/xdg_profile_set.sh
\ No newline at end of file
#!/bin/bash
# ---------------------------------
# Do not run as root
if [ "$LOGNAME" == "root" ] ; then
if [ "${LOGNAME}" == "root" ] ; then
return
fi
# Do not run as a local user
if grep -q "^$LOGNAME" /etc/passwd ; then
if grep -q "^${LOGNAME}" /etc/passwd ; then
return
fi
# set XDG_BIN if not set
# ---------------------------------
# set XDG profile environment
# ---------------------------------
# check if profile is given
if [ -z "${XDG_PROFILE}" ]; then
echo "XDG PROFILE ERROR: \$XDG_PROFILE not set"
unset ${!XDG_*}
return
fi
# set XDG_PROFILES_BIN if not set (take folder of this script as default)
export XDG_PROFILES_BIN="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
if [ ! -d ${XDG_PROFILES_BIN} ]; then
echo "XDG PROFILE ERROR: directory \$XDG_PROFILES_BIN=${XDG_PROFILES_BIN} does not exist"
unset ${!XDG_*}
return
fi
# set XDG_PROFILES_DIR if not set
export XDG_PROFILES_DIR=${XDG_PROFILES_DIR:-${XDG_PROFILES_BIN}/xdg_profiles/}
export XDG_PROFILES_DIR=${XDG_PROFILES_DIR:-${XDG_PROFILES_BIN}/../profiles/}
if [ ! -d ${XDG_PROFILES_DIR} ]; then
echo "XDG PROFILE ERROR: directory \$XDG_PROFILES_DIR=${XDG_PROFILES_DIR} does not exist"
unset ${!XDG_*}
return
fi
# set XDG_PROFILES_HOME, if not set
export XDG_PROFILES_HOME=${XDG_PROFILES_HOME:-${HOME}/.local/xdg/xdg_profiles/}
# set XDG_PROFILES_HOME, if not set (no need for this path to exist)
export XDG_PROFILES_HOME=${XDG_PROFILES_HOME:-${HOME}/.local/xdg/profiles/}
# ---------------------------------
# set XDG directories
# ---------------------------------
# set default XDG variables
export XDG_CONFIG_HOME=${HOME}/.config/xdg_profiles/default
export XDG_CONFIG_DIR=${XDG_PROFILES_DIR}/default/config
export XDG_CONFIG_DIRS=${XDG_CONFIG_DIR}:/etc/xdg:/etc
export XDG_DATA_HOME=${HOME}/.local/xdg_profiles/default
export XDG_DATA_DIR=${XDG_PROFILES_DIR}/default/data
export XDG_DATA_DIRS=${XDG_DATA_DIR}:/usr/local/share:/usr/share
export XDG_CACHE_HOME=${XDG_DATA_HOME}/cache
if [ -d ${XDG_PROFILES_DIR}/default ]; then
export XDG_CONFIG_DIRS=${XDG_PROFILES_DIR}/default/config:/etc/xdg:/etc
export XDG_DATA_DIRS=${XDG_PROFILES_DIR}/default/data:/usr/local/share:/usr/share
else
echo "XDG PROFILE ERROR: directory \$XDG_PROFILES_DIR/default=${XDG_PROFILES_DIR}/default does not exist"
unset ${!XDG_*}
return
fi
# set profile XDG variables
# XDG_DATA_HOME must be ${HOME}/.local/xdg_profiles/${XDG_PROFILE}, as this is fixed in ${XDG_CONFIG_HOME}/user-dirs.dirs
echo -n "select XDG profile ${XDG_PROFILE} ... "
# search first in global profiles dir XDG_PROFILES_DIR and than in user profiles dir XDG_PROFILES_HOME
# if profile not found - use default
if [ -d ${XDG_PROFILES_DIR}/${XDG_PROFILE} ]; then
export XDG_CONFIG_HOME=${HOME}/.config/xdg_profiles/${XDG_PROFILE}
export XDG_CONFIG_DIR=${XDG_PROFILES_DIR}/${XDG_PROFILE}/config
export XDG_CONFIG_DIRS=${XDG_CONFIG_DIR}:${XDG_CONFIG_DIRS}
export XDG_DATA_HOME=${HOME}/.local/xdg_profiles/${XDG_PROFILE}
export XDG_DATA_DIR=${XDG_PROFILES_DIR}/${XDG_PROFILE}/data
export XDG_DATA_DIRS=${XDG_DATA_DIR}:${XDG_DATA_DIRS}
export XDG_CACHE_HOME=${XDG_DATA_HOME}/cache
echo "found"
export XDG_PROFILE_DIR=${XDG_PROFILES_DIR}/${XDG_PROFILE}
echo "XDG PROFILE INFO: profile ${XDG_PROFILE} found in directory ${XDG_PROFILE_DIR}."
elif [ -d ${XDG_PROFILES_HOME}/${XDG_PROFILE} ]; then
export XDG_PROFILE_DIR=${XDG_PROFILES_HOME}/${XDG_PROFILE}
echo "XDG PROFILE INFO: profile ${XDG_PROFILE} found in directory ${XDG_PROFILE_DIR}."
else
echo "is unkown - chosing default"
echo -n "XDG PROFILE WARNING: profile ${XDG_PROFILE} is NOT found"
export XDG_PROFILE=default
export XDG_PROFILE_DIR=${XDG_PROFILES_DIR}/${XDG_PROFILE}
echo -n " - using profile ${XDG_PROFILE} found in directory ${XDG_PROFILE_DIR}."
fi
# create XDG directories if not existant
export XDG_CONFIG_HOME=${HOME}/.config/xdg_profiles/${XDG_PROFILE}
export XDG_CONFIG_DIR=${XDG_PROFILE_DIR}/config
export XDG_CONFIG_DIRS=${XDG_CONFIG_DIR}:${XDG_CONFIG_DIRS}
# XDG_DATA_HOME must be ${HOME}/.local/xdg_profiles/${XDG_PROFILE}, as this is fixed in ${XDG_CONFIG_HOME}/user-dirs.dirs
export XDG_DATA_HOME=${HOME}/.local/xdg_profiles/${XDG_PROFILE}
export XDG_DATA_DIR=${XDG_PROFILE_DIR}/data
export XDG_DATA_DIRS=${XDG_DATA_DIR}:${XDG_DATA_DIRS}
export XDG_CACHE_HOME=${XDG_DATA_HOME}/cache
# ---------------------------------
# create XDG directories (if not existant)
# ---------------------------------
# create ${XDG_CONFIG_HOME}
if [ ! -d ${XDG_CONFIG_HOME} ]; then
echo "XDG profile ${XDG_PROFILE} choosen the first time ... creating ${XDG_CONFIG_HOME}"
echo "XDG PROFILE INFO: profile ${XDG_PROFILE} choosen the first time ... creating ${XDG_CONFIG_HOME}"
mkdir -p ${XDG_CONFIG_HOME}
# change default desktop directory from ${HOME}/Desktop to ${XDG_DATA_HOME}/Desktop
# to enable profile-specific desktop icons
cp ${XDG_PROFILES_DIR}/${XDG_PROFILE}/config/user-dirs.dirs ${XDG_CONFIG_HOME}/
# add bookmarks file
cp ${XDG_PROFILE_DIR}/config/user-dirs.dirs ${XDG_CONFIG_HOME}/
# create directory for bookmarks file
mkdir -p ${XDG_CONFIG_HOME}/gtk-3.0/
fi
# create ${XDG_DATA_HOME}
if [ ! -d ${XDG_DATA_HOME} ]; then
echo "XDG profile ${XDG_PROFILE} choosen the first time ... creating ${XDG_DATA_HOME}"
echo "XDG PROFILE INFO: profile ${XDG_PROFILE} choosen the first time ... creating ${XDG_DATA_HOME}"
mkdir -p ${XDG_DATA_HOME}
fi
if [ ! -z "${XDG_RUNTIME_DIR}" ]; then
# create ${XDG_RUNTIME_DIR} if not set
if [ -z "${XDG_RUNTIME_DIR}" ]; then
export XDG_RUNTIME_DIR=/tmp/${UID}-${DISPLAY}-${XDG_PROFILE}-runtime-dir
if [ ! -d ${XDG_RUNTIME_DIR} ]; then
mkdir "${XDG_RUNTIME_DIR}"
......@@ -70,11 +113,16 @@ if [ ! -z "${XDG_RUNTIME_DIR}" ]; then
fi
fi
# ---------------------------------
# workarounds - modify file/directory in $HOME on every login
# ---------------------------------
# --- desktop icons
# always renew desktop icons, which linke to $XDG_PROFILES_DIR/...
# this might annoy users, who have removed the icons,
# but it ensures that icon updates are pushed to the users on every new login
if [ ! -d ${XDG_DATA_HOME}/Desktop ]; then
echo "XDG profile ${XDG_PROFILE} choosen the first time ... creating ${XDG_DATA_HOME}/Desktop"
echo "XDG PROFILE INFO: profile ${XDG_PROFILE} choosen the first time ... creating ${XDG_DATA_HOME}/Desktop"
mkdir -p ${XDG_DATA_HOME}/Desktop
fi
for file in ${XDG_DATA_HOME}/Desktop/*; do
......@@ -93,10 +141,11 @@ for p in ${XDG_DATA_DIRS}; do
fi
done
# --- devilspie2
# always renew devilspie2 scripts on login
# (remove any links to XDG_PROFILES_DIR first)
if [ ! -d ${XDG_CONFIG_HOME}/devilspie2 ]; then
echo "XDG profile ${XDG_PROFILE} choosen the first time ... creating ${XDG_CONFIG_HOME}/devilspie2"
echo "XDG PROFILE INFO: profile ${XDG_PROFILE} choosen the first time ... creating ${XDG_CONFIG_HOME}/devilspie2"
mkdir -p ${XDG_CONFIG_HOME}/devilspie2/
fi
for file in ${XDG_CONFIG_HOME}/devilspie2/*; do
......@@ -115,9 +164,10 @@ for p in ${XDG_CONFIG_DIRS}; do
fi
done
# --- bookmarks
# always renew gtk-bookmarks
if [ ! -d ${XDG_CONFIG_HOME}/gtk-3.0 ]; then
echo "XDG profile ${XDG_PROFILE} choosen the first time ... creating ${XDG_CONFIG_HOME}/gtk-3.0"
echo "XDG PROFILE INFO: profile ${XDG_PROFILE} choosen the first time ... creating ${XDG_CONFIG_HOME}/gtk-3.0"
mkdir -p ${XDG_CONFIG_HOME}/gtk-3.0/
fi
if [ ! -f ${XDG_CONFIG_HOME}/gtk-3.0/bookmarks ]; then
......@@ -128,7 +178,7 @@ fi
IFS=:
for p in ${XDG_CONFIG_DIRS}; do
if [ -f ${p}/gtk-3.0/bookmarks ]; then
echo "debug: merge"
echo -n ""
#merge with ${XDG_CONFIG_DIR}/gtk-3.0/bookmarks
fi
done
......@@ -144,6 +194,10 @@ if [ ! -f ${HOME}/.gtk-bookmarks ]; then
ln -s ${XDG_CONFIG_HOME}/gtk-3.0/bookmarks ${HOME}/.gtk-bookmarks
fi
# ---------------------------------
# workarounds - clean up
# ---------------------------------
# remove saved sessions, as we do not want infoterm windows to appear multiple times
# (todo: only remove the call of infoterm scripts instead)
if [ ! -z "${XDG_DATA_HOME}" ]; then
......@@ -151,7 +205,7 @@ if [ ! -z "${XDG_DATA_HOME}" ]; then
fi
# echo settings
echo "XDG Settings:"
echo "XDG PROFILE SETTINGS:"
for x in ${!XDG_*}; do echo ${x} = ${!x}; done
echo
[Desktop Entry]
Version=1.0
Type=Application
Name=LLview
Comment=
Exec=llview
Icon=/homeb/zam/goebbert/workspace/xdg_profiles/etc/xdg/xdg_profiles/default/data/pixmaps/llview_32x32.png
Path=
Terminal=true
StartupNotify=false
Categories=FZJ-Visualization
../xdg_profile_set.sh
\ No newline at end of file
#!/bin/bash
OLD_PATH=/homeb/zam/goebbert/workspace/xdg_profiles
NEW_PATH="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
#OLD_PATH=/homeb/zam/goebbert/workspace/xdg_profiles
#NEW_PATH="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
OLD_PATH=
NEW_PATH=
echo
echo "${OLD_PATH} -> ${NEW_PATH}"
......@@ -11,5 +14,6 @@ echo
SED_OLD_PATH=$(echo $OLD_PATH | sed 's_/_\\/_g')
SED_NEW_PATH=$(echo $NEW_PATH | sed 's_/_\\/_g')
find ${NEW_PATH} -type f -print0 | xargs -0 sed -i "s/${SED_OLD_PATH}/${SED_NEW_PATH}/g"
#find ${NEW_PATH} -type f -print0 | xargs -0 sed -i "s/${SED_OLD_PATH}/${SED_NEW_PATH}/g"
find . -type f -print0 | xargs -0 sed -i "s/${SED_OLD_PATH}/${SED_NEW_PATH}/g"
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment