################################################################################
# Copyright (C) 2019-2024 NI SP GmbH
# All Rights Reserved
#
# info@ni-sp.com / www.ni-sp.com
#
# We provide the information on an as is basis. 
# We provide no warranties, express or implied, related to the
# accuracy, completeness, timeliness, useability, and/or merchantability
# of the data and are not liable for any loss, damage, claim, liability,
# expense, or penalty, or for any direct, indirect, special, secondary,
# incidental, consequential, or exemplary damages or lost profit
# deriving from the use or misuse of this information.
################################################################################
# Version v1.1
#

###################################################
# Install DCV on RH/CentOS 9.x
#
# We recommend to execute the script step by step to see what is happening.

###################################################
# Update the OS with latest patches  

sudo yum upgrade -y
sudo reboot 

###################################################
# configuration
# check if on AWS 
aws_cfg="NO"

###################################################
# create dcvtest user? 
# echo -n "Do you want to setup the dcvtest user for testing the session creation Y/N ? " 
# read -s resp
# if [ $resp == "Y" ] ; then
#   echo 
#   echo -n "Password for user dcvtest : " 
#   read -s password
#   echo 
#   user="dcvtest"
#   # encr=`echo thePassword | sudo passwd $user --stdin`
#   sudo adduser $user 
#   echo "$user:$password" | sudo chpasswd
#   echo User $user has been setup 
# fi 

echo

##############################################################
# Installation of DCV 2023.x 

sudo yum groupinstall 'Server with GUI' -y

sudo systemctl get-default
sudo systemctl set-default graphical.target
sudo systemctl isolate graphical.target
# Verify that the X Server is running
ps aux | grep X | grep -v grep

sudo yum install glx-utils -y  # for checking the installation

# Verify
sudo DISPLAY=:0 XAUTHORITY=$(ps aux | grep "X.*\-auth" | grep -v grep \
      | sed -n 's/.*-auth \([^ ]\+\).*/\1/p') glxinfo | grep -i "opengl.*version"
# OpenGL core profile version string: 3.3 (Core Profile) Mesa 19.3.4
# OpenGL core profile shading language version string: 3.30
# OpenGL version string: 3.1 Mesa 19.3.4
# OpenGL shading language version string: 1.40
# OpenGL ES profile version string: OpenGL ES 3.1 Mesa 19.3.4
# OpenGL ES profile shading language version string: OpenGL ES GLSL ES 3.10

sudo yum erase nvidia cuda

# get ready to install the nVidia driver 
sudo yum install -y make gcc kernel-devel-$(uname -r) wget
# if the kernel-devel-(version) is not found install as follows
# sudo yum install -y make gcc kernel-devel wget
cat << EOF | sudo tee --append /etc/modprobe.d/blacklist.conf
blacklist vga16fb
blacklist nouveau
blacklist rivafb
blacklist nvidiafb
blacklist rivatv
EOF

echo 'GRUB_CMDLINE_LINUX="rdblacklist=nouveau"' | sudo tee -a /etc/default/grub > /dev/null
sudo grub2-mkconfig -o /boot/grub2/grub.cfg
sudo reboot # to remove nouveau driver in case 

# when on AWS 
# sudo yum install python3-pip -y
# pip3 install awscli --upgrade --user
# aws s3 cp --no-sign-request --recursive s3://ec2-linux-nvidia-drivers/latest/ .
# redhat 8
sudo yum install elfutils-libelf-devel elfutils-devel -y 

# get nVidia driver - adapt if necessary
# Drivers are here:  https://www.nvidia.com/Download/index.aspx?lang=en-us
# wget http://us.download.nvidia.com/XFree86/Linux-x86_64/430.26/NVIDIA-Linux-x86_64-430.26.run
wget https://us.download.nvidia.com/tesla/515.48.07/NVIDIA-Linux-x86_64-515.48.07.run

sudo systemctl isolate multi-user.target   # which will log you out probably
sudo /bin/sh ./NVIDIA-Linux-x86_64*.run -s
# ignore the warning about libglvnd EGL vendor library config files.
# sudo reboot

# check driver 
nvidia-smi -q | head

sudo nvidia-xconfig --preserve-busid --enable-all-gpus

# Tips
# In case necessary add line ‘Option "UseDisplayDevice" "None" ’ into the Device section
# in xorg.conf - otherwise your X server might not start properly; this is e.g. needed for older cards
#
# In case you experience a frame rate of 1 FPS after a couple of minutes you need to
# turn off nVidia DPMS (Display Power Management System) by adding the line
#  ' Option         "HardDPMS" "false" ' into the Device section in xorg.conf
#
# If you are using a G3 or G4 Amazon EC2 instance and you want to use a multi-monitor
# console session, include the --connected-monitor=DFP-0,DFP-1,DFP-2,DFP-3 parameter as follows.
# nvidia-xconfig --preserve-busid --enable-all-gpus --connected-monitor=DFP-0,DFP-1,DFP-2,DFP-3

# sudo vim /etc/X11/xorg.conf

###################################################
# identify the right DCV server to download
dcv_version="2024"
echo Checking for latest DCV $dcv_version version 
dcv_server=`curl --silent --output - https://www.amazondcv.com/ | \
    grep href | egrep "$dcv_version" | grep "el9" | grep Server | sed -e 's/.*http/http/' -e 's/tgz.*/tgz/' | head -1`
echo "We will be downloading DCV server from $dcv_server"
echo 

# install DCV 
# use $dcv_server
# wget https://d1uj6qtbmh3dt5.cloudfront.net/2019.0/Servers/nice-dcv-2019.0-7318-el8.tgz
sudo rpm --import https://d1uj6qtbmh3dt5.cloudfront.net/NICE-GPG-KEY # allow the package manager to verify the signature
echo Downloading DCV Server from $dcv_server
wget $dcv_server 

tar zxvf nice-dcv-*el9*.tgz
cd nice-dcv-*x86_64
sudo yum install nice-dcv-server-*.el9.x86_64.rpm \
     nice-xdcv-*.el9.x86_64.rpm nice-dcv-gl-*.el9.x86_64.rpm \
     nice-dcv-web-viewer*.el9.x86_64.rpm  \
     nice-dcv-gltest-*.el9.x86_64.rpm nice-dcv-simple-external-authenticator-*.el9.x86_64.rpm -y

# in case of USB remotization
# sudo yum install https://dl.fedoraproject.org/pub/epel/epel-release-latest-8.noarch.rpm
# sudo yum install dkms
# sudo dcvusbdriverinstaller

# ensure that X server is running; you might get logged out by these commands
# use these commands to stop the X-server and start it again for testing the X-org configuration 
sudo systemctl isolate multi-user.target
sudo systemctl isolate graphical.target

# check for nvidia profile
sudo DISPLAY=:0 XAUTHORITY=$(ps aux | grep "X.*\-auth" | \
   grep -v grep | sed -n 's/.*-auth \([^ ]\+\).*/\1/p') glxinfo | grep -i "opengl.*version"
# OpenGL core profile version string: 4.6.0 NVIDIA 450.51.05
# OpenGL core profile shading language version string: 4.60 NVIDIA
# OpenGL version string: 4.6.0 NVIDIA 450.51.05
# OpenGL shading language version string: 4.60 NVIDIA
# OpenGL ES profile version string: OpenGL ES 3.2 NVIDIA 450.51.05
# OpenGL ES profile shading language version string: OpenGL ES GLSL ES 3.20

# in case of issues check the gdm startup file 
# cat /etc/gdm/Init/Default
# it should show 
# dcvxgrantaccess +dcv  
# and 
# dcvxgrantaccess  # in case of DCV-GL

# enable GPU sharing
# sudo dcvgladmin disable
sudo dcvgladmin enable

# add GPU sharing in configuration if needed - you can also use the defaults in dcv.conf which should work well. 
# [display/linux]
# gl-displays = [':0.0']
# sudo vim /etc/dcv/dcv.conf

# Add QUIC/UDP support: In the [connectivity] section of /etc/dcv/dcv.conf add
# enable-quic-frontend=true

# verify installation
ps -ef | grep X | grep -v grep
echo You should see the X server running - e.g.  /usr/bin/X :0 -background none -noreset -audit 4 -verbose -auth /run/gdm/auth-for-gdm-kgN6Mc/database -seat seat0 -nolisten tcp vt1

echo Verify DCV installation 
# sudo DISPLAY=:0 XAUTHORITY=$(ps aux | grep "X.*\-auth" | grep -v grep | gawk -F" -auth "'{print $2}' | awk '{print $1}') xhost | grep "SI:localuser:dcv$"
sudo DISPLAY=:0 XAUTHORITY=$(ps aux | grep "X.*\-auth" | \
    grep -v grep | sed -n 's/.*-auth \([^ ]\+\) .*/\1/p') xhost | grep "SI:localuser:dcv$"
echo If the command has returned SI:localuser:dcv, the dcv user can access the X server.
# If not you can try the following command
#  sudo DISPLAY=:0 dcvxgrantaccess +dcv

# verify that local users can access the X server - should show LOCAL:
sudo DISPLAY=:0 XAUTHORITY=$(ps aux | grep "X.*\-auth" | grep -v grep | sed -n 's/.*-auth \([^ ]\+\).*/\1/p') xhost | grep "LOCAL:$"

# Verify that OpenGL hardware rendering is available
sudo DISPLAY=:0 glxinfo | grep -i "opengl.*version"

# Now run the DCV installation verification program (in case you installed the GL package as well for GPU sharing on Linux)
sudo dcvgldiag

# uncomment auth-token-verifier="http://127.0.0.1:8444" in case you want to use DCV with EnginFrame Views session management - please note this will disable standard authentication
# sudo vim /etc/dcv/dcv.conf
# configure dcvsimpleextauth
# sudo systemctl start dcvsimpleextauth    # in EF Views deployments

# enable autostart of the DCV server 
sudo systemctl enable dcvserver
# sudo systemctl enable dcvsimpleextauth    # in EF Views deployments

# start server
sudo systemctl start dcvserver
# stop command
# sudo systemctl stop dcvserver

# in case you want to check the DCV logfile to see output from the DCV server have a look at
less /var/log/dcv/server.log

# DCV Conf file
# cat /etc/dcv/dcv.conf

#adapt colord 
cat << EOF | sudo tee --append /etc/polkit-1/localauthority/50-local.d/45-allow-colord.pkla
    [Allow Colord all Users]
    Identity=unix-user:*
    Action=org.freedesktop.color-manager.create-device;org.freedesktop.color-manager.create-profile;org.freedesktop.color-manager.delete-device;org.freedesktop.color-manager.delete-profile;org.freedesktop.color-manager.modify-device;org.freedesktop.color-manager.modify-profile
    ResultAny=no
    ResultInactive=no
    ResultActive=yes
EOF

# create a session
# sudo dcv create-session --owner $user session1    # issue: --type=console 
echo You should be non-root to test DCV session creation and be able to login as that user 
dcv create-session --type=virtual test1
# list sessions
dcv list-sessions
# for details
# dcv list-sessions -j
# get details of session
dcv describe-session test1 
# close session
# dcv close-session {session_id}
# in case the session is not created you might want to unset the variable XDG_RUNTIME_DIR
# or create the directory $XDG_RUNTIME_DIR (e.g. /run/user/1000)

# show DCV Server log in case to see the newly created session 
# tail /var/log/dcv/server.log

# open port in security group in case on AWS
[ "$aws_cfg" != "NO" ] && echo "Don\'t forget to open the port on the security group in case running in the cloud"

# open port on firewall
## >>>>> add inbound port rule in security group to allow 8443 inbound in case on AWS 
# show firewall settings
sudo iptables-save
sudo firewall-cmd --zone=public --add-port=8443/tcp --permanent
# sudo firewall-cmd --zone=public --add-port=8443/udp --permanent # in case of QUIC
# sudo firewall-cmd --zone=public --add-port=443/tcp --permanent
sudo firewall-cmd --reload
sudo firewall-cmd --list-all
sudo iptables-save | grep 8443

# installed CA for the https connection
# generate certificate
cd /etc/dcv/
sudo openssl req -x509 -newkey rsa:4096 -keyout key.pem -out cert.pem -days 365

# Add CA in the [security] section in dcv.conf near # auth-token-verifier="http://127.0.0.1:8444" at the end of the file
sudo echo 'ca-file="/etc/dcv/cert.pem"  ' >> /etc/dcv/dcv.conf

# get Public IP on AWS
# curl http://169.254.169.254/latest/meta-data/public-ipv4

# in case you get a package manager update popup: 
# sudo echo X-GNOME-Autostart-enabled=false >> /etc/xdg/autostart/gnome-software-service.desktop

# connect to your DCV session
echo Point your browser to https://YOUR_IP_ADDRESS:8443 and login with the user and password you have been using to create the test1 session earlier
echo 
echo With EnginFrame Views session management you just click on a link in the portal and get the DCV session automatically including single-sign on.
echo 
echo After login you can start a terminal via Applications, Terminal and run nvidia-smi to check the status of the nVidia driver 
