├── README.md ├── ct └── kodi-v1.sh └── setup └── kodi-install.sh /README.md: -------------------------------------------------------------------------------- 1 | # Proxmox Helper 2 | 3 | Set of scripts to help in deployment of containers into Proxmox. 4 | 5 | based on great work of https://github.com/tteck/Proxmox 6 | 7 | # Kodi Media Manager LXC 8 | 9 | ## To create a new Proxmox Kodi Media Manager, run the following in the Proxmox Shell. 10 | 11 | ```yaml 12 | bash -c "$(wget -qLO - https://raw.githubusercontent.com/mrrudy/proxmoxHelper/main/ct/kodi-v1.sh)" 13 | ``` 14 | Kodi should be attached to TTY7 console 15 | 16 | ## To Update Kodi Media Manager: 17 | 18 | Run in the LXC console 19 | ```yaml 20 | apt update && apt upgrade -y 21 | ``` 22 | ## Issue with X on Ubuntu 20.04 and Unprivileged 23 | 24 | If you really need to use Ubuntu below 22.04 there is an issue with access rights that prevents Xorg from starting on TTY7 on an Unprivileged container. Workaround exists but a change on the host machine is required so please accept the risk beforehand. In the Proxmox Shell: 25 | ```yaml 26 | chmod 660 /dev/tty7 27 | ``` 28 | -------------------------------------------------------------------------------- /ct/kodi-v1.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | echo -e "Loading..." 4 | APP="kodi" 5 | var_disk="8" 6 | var_cpu="2" 7 | var_ram="2048" 8 | var_os="ubuntu" 9 | var_version="22.04" 10 | NSAPP=$(echo ${APP,,} | tr -d ' ') 11 | var_install="${NSAPP}-install" 12 | NEXTID=$(pvesh get /cluster/nextid) 13 | INTEGER='^[0-9]+$' 14 | YW=`echo "\033[33m"` 15 | BL=`echo "\033[36m"` 16 | RD=`echo "\033[01;31m"` 17 | BGN=`echo "\033[4;92m"` 18 | GN=`echo "\033[1;92m"` 19 | DGN=`echo "\033[32m"` 20 | CL=`echo "\033[m"` 21 | BFR="\\r\\033[K" 22 | HOLD="-" 23 | CM="${GN}✓${CL}" 24 | set -o errexit 25 | set -o errtrace 26 | set -o nounset 27 | set -o pipefail 28 | shopt -s expand_aliases 29 | alias die='EXIT=$? LINE=$LINENO error_exit' 30 | trap die ERR 31 | function error_exit() { 32 | trap - ERR 33 | local reason="Unknown failure occurred." 34 | local msg="${1:-$reason}" 35 | local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" 36 | echo -e "$flag $msg" 1>&2 37 | exit $EXIT 38 | } 39 | if (whiptail --title "${APP} LXC" --yesno "This will create a New ${APP} LXC. Proceed?" 10 58); then 40 | echo "User selected Yes" 41 | else 42 | clear 43 | echo -e "⚠ User exited script \n" 44 | exit 45 | fi 46 | function header_info { 47 | echo -e "kodi---------\n\n" 48 | } 49 | function msg_info() { 50 | local msg="$1" 51 | echo -ne " ${HOLD} ${YW}${msg}..." 52 | } 53 | function msg_ok() { 54 | local msg="$1" 55 | echo -e "${BFR} ${CM} ${GN}${msg}${CL}" 56 | } 57 | function PVE_CHECK() { 58 | PVE=$(pveversion | grep "pve-manager/7" | wc -l) 59 | if [[ $PVE != 1 ]]; then 60 | echo -e "${RD}This script requires Proxmox Virtual Environment 7.0 or greater${CL}" 61 | echo -e "Exiting..." 62 | sleep 2 63 | exit 64 | fi 65 | } 66 | function default_settings() { 67 | echo -e "${DGN}Using ${var_os} Version: ${BGN}${var_version}${CL}" 68 | 69 | echo -e "${DGN}Using Container Type: ${BGN}Unprivileged${CL}" 70 | CT_TYPE="1" 71 | echo -e "${DGN}Using Root Password: ${BGN}Automatic Login${CL}" 72 | PW="" 73 | echo -e "${DGN}Using Container ID: ${BGN}$NEXTID${CL}" 74 | CT_ID=$NEXTID 75 | echo -e "${DGN}Using Hostname: ${BGN}$NSAPP${CL}" 76 | HN=$NSAPP 77 | echo -e "${DGN}Using Disk Size: ${BGN}$var_disk${CL}${DGN}GB${CL}" 78 | DISK_SIZE="$var_disk" 79 | echo -e "${DGN}Allocated Cores ${BGN}$var_cpu${CL}" 80 | CORE_COUNT="$var_cpu" 81 | echo -e "${DGN}Allocated Ram ${BGN}$var_ram${CL}" 82 | RAM_SIZE="$var_ram" 83 | echo -e "${DGN}Using Bridge: ${BGN}vmbr0${CL}" 84 | BRG="vmbr0" 85 | echo -e "${DGN}Using Static IP Address: ${BGN}dhcp${CL}" 86 | NET=dhcp 87 | echo -e "${DGN}Using Gateway Address: ${BGN}Default${CL}" 88 | GATE="" 89 | echo -e "${DGN}Using MAC Address: ${BGN}Default${CL}" 90 | MAC="" 91 | echo -e "${DGN}Using VLAN Tag: ${BGN}Default${CL}" 92 | VLAN="" 93 | echo -e "${BL}Creating a ${APP} LXC using the above default settings${CL}" 94 | } 95 | function advanced_settings() { 96 | var_version=$(whiptail --title "UBUNTU VERSION" --radiolist "Choose Version" 10 58 3 \ 97 | "20.04" "Focal" OFF \ 98 | "22.04" "Jammy" ON \ 99 | 3>&1 1>&2 2>&3) 100 | exitstatus=$? 101 | if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Ubuntu Version: ${BGN}$var_version${CL}"; fi 102 | CT_TYPE=$(whiptail --title "CONTAINER TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 8 58 2 \ 103 | "1" "Unprivileged" ON \ 104 | "0" "Privileged" OFF \ 105 | 3>&1 1>&2 2>&3) 106 | exitstatus=$? 107 | if [ $exitstatus = 0 ]; then 108 | echo -e "${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}" 109 | fi 110 | PW1=$(whiptail --inputbox "Set Root Password" 8 58 --title "PASSWORD(leave blank for automatic login)" --cancel-button Exit-Script 3>&1 1>&2 2>&3) 111 | exitstatus=$? 112 | if [ $exitstatus = 0 ]; then 113 | if [ -z $PW1 ]; then PW1="Automatic Login" PW=" "; 114 | echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" 115 | else 116 | PW="-password $PW1" 117 | echo -e "${DGN}Using Root Password: ${BGN}$PW1${CL}" 118 | fi 119 | fi 120 | CT_ID=$(whiptail --inputbox "Set Container ID" 8 58 $NEXTID --title "CONTAINER ID" --cancel-button Exit-Script 3>&1 1>&2 2>&3) 121 | exitstatus=$? 122 | if [ -z $CT_ID ]; then CT_ID="$NEXTID"; echo -e "${DGN}Container ID: ${BGN}$CT_ID${CL}"; 123 | else 124 | if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Container ID: ${BGN}$CT_ID${CL}"; fi; 125 | fi 126 | CT_NAME=$(whiptail --inputbox "Set Hostname" 8 58 $NSAPP --title "HOSTNAME" --cancel-button Exit-Script 3>&1 1>&2 2>&3) 127 | exitstatus=$? 128 | if [ -z $CT_NAME ]; then HN="$NSAPP"; echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}"; 129 | else 130 | if [ $exitstatus = 0 ]; then HN=$(echo ${CT_NAME,,} | tr -d ' '); echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}"; fi; 131 | fi 132 | DISK_SIZE=$(whiptail --inputbox "Set Disk Size in GB" 8 58 $var_disk --title "DISK SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) 133 | exitstatus=$? 134 | if [ -z $DISK_SIZE ]; then DISK_SIZE="$var_disk"; echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}"; 135 | else 136 | if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}"; fi; 137 | if ! [[ $DISK_SIZE =~ $INTEGER ]] ; then echo -e "${RD}⚠ DISK SIZE MUST BE A INTEGER NUMBER!${CL}"; advanced_settings; fi; 138 | fi 139 | CORE_COUNT=$(whiptail --inputbox "Allocate CPU Cores" 8 58 $var_cpu --title "CORE COUNT" --cancel-button Exit-Script 3>&1 1>&2 2>&3) 140 | exitstatus=$? 141 | if [ -z $CORE_COUNT ]; then CORE_COUNT="$var_cpu"; echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}"; 142 | else 143 | if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}"; fi; 144 | fi 145 | RAM_SIZE=$(whiptail --inputbox "Allocate RAM in MiB" 8 58 $var_ram --title "RAM" --cancel-button Exit-Script 3>&1 1>&2 2>&3) 146 | exitstatus=$? 147 | if [ -z $RAM_SIZE ]; then RAM_SIZE="$var_ram"; echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; 148 | else 149 | if [ $exitstatus = 0 ]; then echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"; fi; 150 | fi 151 | BRG=$(whiptail --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" --cancel-button Exit-Script 3>&1 1>&2 2>&3) 152 | exitstatus=$? 153 | if [ -z $BRG ]; then BRG="vmbr0"; echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; 154 | else 155 | if [ $exitstatus = 0 ]; then echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"; fi; 156 | fi 157 | NET=$(whiptail --inputbox "Set a Static IPv4 CIDR Address(/24)" 8 58 dhcp --title "IP ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) 158 | exitstatus=$? 159 | if [ -z $NET ]; then NET="dhcp"; echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}"; 160 | else 161 | if [ $exitstatus = 0 ]; then echo -e "${DGN}Using IP Address: ${BGN}$NET${CL}"; fi; 162 | fi 163 | GATE1=$(whiptail --inputbox "Set a Gateway IP (mandatory if Static IP was used)" 8 58 --title "GATEWAY IP" --cancel-button Exit-Script 3>&1 1>&2 2>&3) 164 | exitstatus=$? 165 | if [ $exitstatus = 0 ]; then 166 | if [ -z $GATE1 ]; then GATE1="Default" GATE=""; 167 | echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" 168 | else 169 | GATE=",gw=$GATE1" 170 | echo -e "${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}" 171 | fi 172 | fi 173 | MAC1=$(whiptail --inputbox "Set a MAC Address(leave blank for default)" 8 58 --title "MAC ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3) 174 | exitstatus=$? 175 | if [ $exitstatus = 0 ]; then 176 | if [ -z $MAC1 ]; then MAC1="Default" MAC=""; 177 | echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" 178 | else 179 | MAC=",hwaddr=$MAC1" 180 | echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}" 181 | fi 182 | fi 183 | VLAN1=$(whiptail --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" --cancel-button Exit-Script 3>&1 1>&2 2>&3) 184 | exitstatus=$? 185 | if [ $exitstatus = 0 ]; then 186 | if [ -z $VLAN1 ]; then VLAN1="Default" VLAN=""; 187 | echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" 188 | else 189 | VLAN=",tag=$VLAN1" 190 | echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}" 191 | fi 192 | fi 193 | if (whiptail --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create ${APP} LXC?" --no-button Do-Over 10 58); then 194 | echo -e "${RD}Creating a ${APP} LXC using the above advanced settings${CL}" 195 | else 196 | clear 197 | header_info 198 | echo -e "${RD}Using Advanced Settings${CL}" 199 | advanced_settings 200 | fi 201 | } 202 | function start_script() { 203 | if (whiptail --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then 204 | header_info 205 | echo -e "${BL}Using Default Settings${CL}" 206 | default_settings 207 | else 208 | header_info 209 | echo -e "${RD}Using Advanced Settings${CL}" 210 | advanced_settings 211 | fi 212 | } 213 | clear 214 | start_script 215 | if [ "$CT_TYPE" == "1" ]; then 216 | FEATURES="nesting=1,keyctl=1" 217 | else 218 | FEATURES="nesting=1" 219 | fi 220 | TEMP_DIR=$(mktemp -d) 221 | pushd $TEMP_DIR >/dev/null 222 | export CTID=$CT_ID 223 | export PCT_OSTYPE=$var_os 224 | export PCT_OSVERSION=$var_version 225 | export PCT_DISK_SIZE=$DISK_SIZE 226 | export PCT_OPTIONS=" 227 | -features $FEATURES 228 | -hostname $HN 229 | -net0 name=eth0,bridge=$BRG$MAC,ip=$NET$GATE$VLAN 230 | -onboot 1 231 | -cores $CORE_COUNT 232 | -memory $RAM_SIZE 233 | -unprivileged $CT_TYPE 234 | $PW 235 | " 236 | bash -c "$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/create_lxc.sh)" || exit 237 | 238 | msg_info "Pre-starting LXC Container" 239 | pct start $CTID 240 | msg_ok "Pre-started LXC Container" 241 | 242 | VIDEO_GID=$(pct exec ${CTID} getent group video | cut -d: -f3) 243 | RENDER_GID=$(pct exec ${CTID} getent group render | cut -d: -f3) 244 | TTY_GID=$(pct exec ${CTID} getent group tty | cut -d: -f3) 245 | INPUT_GID=$(pct exec ${CTID} getent group input | cut -d: -f3) 246 | AUDIO_GID=$(pct exec ${CTID} getent group audio | cut -d: -f3) 247 | 248 | msg_info "Stopping LXC Container" 249 | pct stop $CTID 250 | msg_ok "Stopped LXC Container" 251 | 252 | LXC_CONFIG=/etc/pve/lxc/${CTID}.conf 253 | cat <> $LXC_CONFIG 254 | lxc.cgroup2.devices.allow: c 226:0 rwm 255 | lxc.cgroup2.devices.allow: c 226:128 rwm 256 | lxc.cgroup2.devices.allow: c 29:0 rwm 257 | lxc.mount.entry: /dev/fb0 dev/fb0 none bind,optional,create=file 258 | lxc.mount.entry: /dev/dri dev/dri none bind,optional,create=dir 259 | lxc.mount.entry: /dev/dri/renderD128 dev/renderD128 none bind,optional,create=file 260 | # tty 7 - default for x 261 | lxc.cgroup2.devices.allow: c 4:7 rwm 262 | lxc.mount.entry: /dev/tty7 dev/tty7 none bind,optional,create=file 263 | # all input devices 264 | lxc.cgroup2.devices.allow: c 13:* rwm 265 | lxc.mount.entry: /dev/input dev/input none bind,optional,create=dir 266 | # sound 267 | lxc.cgroup2.devices.allow: c 116:* rwm 268 | lxc.mount.entry: /dev/snd dev/snd none bind,optional,create=dir 269 | EOF 270 | if [ "$CT_TYPE" == "1" ]; then 271 | cat <> $LXC_CONFIG 272 | lxc.idmap: u 0 100000 65536 273 | EOF 274 | #TODO internalize code to generate mapping instad of using external python script 275 | LXC_SUB_CONF=$(python3 -c "$(wget -qLO - https://raw.githubusercontent.com/ddimick/proxmox-lxc-idmapper/master/run.py)" \ 276 | ${VIDEO_GID}=$(getent group video | cut -d: -f3) ${RENDER_GID}=$(getent group render | cut -d: -f3) ${TTY_GID}=$(getent group tty | cut -d: -f3) ${INPUT_GID}=$(getent group input | cut -d: -f3) ${AUDIO_GID}=$(getent group audio | cut -d: -f3)) 277 | echo "$LXC_SUB_CONF" | grep 'lxc.idmap: g ' >> $LXC_CONFIG 278 | # on host add rights to map gids but only if they are not already in the file 279 | echo "$LXC_SUB_CONF" | sed -n '/subgid/,// { /subgid/! p }' | while read line; do cat /etc/subgid | sed 's/[[:blank:]]*//g' | grep -qxF "$line" || echo $line >> /etc/subgid; done 280 | /usr/bin/systemctl restart lxc 281 | else 282 | cat <> $LXC_CONFIG 283 | lxc.hook.mount: sh -c "/var/lib/lxc/${CTID}/mount_hook.sh" 284 | EOF 285 | cat </var/lib/lxc/${CTID}/mount_hook.sh 286 | #!/usr/bin/env bash 287 | 288 | /bin/chown :${VIDEO_GID} /dev/fb0 289 | /bin/chmod 660 /dev/fb0 290 | /bin/chown :${VIDEO_GID} /dev/dri 291 | /bin/chmod 755 /dev/dri 292 | /bin/chown :${VIDEO_GID} /dev/dri/* 293 | /bin/chmod 660 /dev/dri/* 294 | /bin/chown :${RENDER_GID} /dev/renderD128 295 | /bin/chmod 660 /dev/renderD128 296 | /bin/chown :${TTY_GID} /dev/tty7 297 | /bin/chown :${INPUT_GID} /dev/input/* 298 | /bin/chown :${AUDIO_GID} /dev/snd/* 299 | EOF 300 | /bin/chmod +x /var/lib/lxc/${CTID}/mount_hook.sh 301 | fi 302 | 303 | msg_info "Starting LXC Container" 304 | pct start $CTID 305 | msg_ok "Started LXC Container" 306 | 307 | lxc-attach -n $CTID -- bash -c "$(wget -qLO - https://raw.githubusercontent.com/mrrudy/proxmoxHelper/main/setup/$var_install.sh)" || exit 308 | IP=$(pct exec $CTID ip a s dev eth0 | sed -n '/inet / s/\// /p' | awk '{print $2}') 309 | pct set $CTID -description "# ${APP} LXC" 310 | msg_ok "Completed Successfully!\n" 311 | echo -e "${APP} should be started on TTY7 312 | \n" 313 | -------------------------------------------------------------------------------- /setup/kodi-install.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | YW=`echo "\033[33m"` 4 | RD=`echo "\033[01;31m"` 5 | BL=`echo "\033[36m"` 6 | GN=`echo "\033[1;92m"` 7 | CL=`echo "\033[m"` 8 | RETRY_NUM=10 9 | RETRY_EVERY=3 10 | NUM=$RETRY_NUM 11 | CM="${GN}✓${CL}" 12 | CROSS="${RD}✗${CL}" 13 | BFR="\\r\\033[K" 14 | HOLD="-" 15 | set -o errexit 16 | set -o errtrace 17 | set -o nounset 18 | set -o pipefail 19 | shopt -s expand_aliases 20 | alias die='EXIT=$? LINE=$LINENO error_exit' 21 | trap die ERR 22 | 23 | function error_exit() { 24 | trap - ERR 25 | local reason="Unknown failure occurred." 26 | local msg="${1:-$reason}" 27 | local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE" 28 | echo -e "$flag $msg" 1>&2 29 | exit $EXIT 30 | } 31 | 32 | function msg_info() { 33 | local msg="$1" 34 | echo -ne " ${HOLD} ${YW}${msg}..." 35 | } 36 | 37 | function msg_ok() { 38 | local msg="$1" 39 | echo -e "${BFR} ${CM} ${GN}${msg}${CL}" 40 | } 41 | 42 | function msg_error() { 43 | local msg="$1" 44 | echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}" 45 | } 46 | 47 | msg_info "Setting up Container OS " 48 | sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen 49 | locale-gen >/dev/null 50 | while [ "$(hostname -I)" = "" ]; do 51 | 1>&2 echo -en "${CROSS}${RD} No Network! " 52 | sleep $RETRY_EVERY 53 | ((NUM--)) 54 | if [ $NUM -eq 0 ] 55 | then 56 | 1>&2 echo -e "${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}" 57 | exit 1 58 | fi 59 | done 60 | msg_ok "Set up Container OS" 61 | msg_ok "Network Connected: ${BL}$(hostname -I)" 62 | 63 | if nc -zw1 8.8.8.8 443; then msg_ok "Internet Connected"; else msg_error "Internet NOT Connected"; exit 1; fi; 64 | RESOLVEDIP=$(nslookup "github.com" | awk -F':' '/^Address: / { matched = 1 } matched { print $2}' | xargs) 65 | if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to $RESOLVEDIP"; fi; 66 | 67 | msg_info "Updating Container OS" 68 | apt-get update &>/dev/null 69 | apt-get -y upgrade &>/dev/null 70 | msg_ok "Updated Container OS" 71 | 72 | msg_info "Installing Dependencies" 73 | apt-get install -y curl &>/dev/null 74 | apt-get install -y sudo &>/dev/null 75 | apt-get install -y gnupg &>/dev/null 76 | msg_ok "Installed Dependencies" 77 | 78 | msg_info "Setting Up Hardware Acceleration" 79 | apt-get -y install \ 80 | va-driver-all \ 81 | ocl-icd-libopencl1 &>/dev/null 82 | set +e 83 | alias die='' 84 | apt-get install --ignore-missing -y beignet-opencl-icd &>/dev/null 85 | alias die='EXIT=$? LINE=$LINENO error_exit' 86 | set -e 87 | 88 | msg_ok "Set Up Hardware Acceleration" 89 | 90 | msg_info "Setting Up kodi user" 91 | useradd -d /home/kodi -m kodi &>/dev/null 92 | gpasswd -a kodi audio &>/dev/null 93 | gpasswd -a kodi video &>/dev/null 94 | gpasswd -a kodi render &>/dev/null 95 | groupadd -r autologin &>/dev/null 96 | gpasswd -a kodi autologin &>/dev/null 97 | gpasswd -a kodi input &>/dev/null #to enable direct access to devices 98 | msg_ok "Set Up kodi user" 99 | 100 | msg_info "Installing lightdm" 101 | DEBIAN_FRONTEND=noninteractive apt-get install -y lightdm &>/dev/null 102 | echo "/usr/sbin/lightdm" > /etc/X11/default-display-manager 103 | msg_ok "Installed lightdm" 104 | 105 | msg_info "Installing kodi" 106 | apt-get update &>/dev/null 107 | apt-get install -y kodi &>/dev/null 108 | set +e 109 | alias die='' 110 | apt-get install --ignore-missing -y kodi-peripheral-joystick &>/dev/null 111 | alias die='EXIT=$? LINE=$LINENO error_exit' 112 | set -e 113 | msg_ok "Installed kodi" 114 | 115 | msg_info "Updating xsession" 116 | cat </usr/share/xsessions/kodi-alsa.desktop 117 | [Desktop Entry] 118 | Name=Kodi-alsa 119 | Comment=This session will start Kodi media center with alsa support 120 | Exec=env AE_SINK=ALSA kodi-standalone 121 | TryExec=env AE_SINK=ALSA kodi-standalone 122 | Type=Application 123 | EOF 124 | msg_ok "Updated xsession" 125 | 126 | msg_info "Setting up autologin" 127 | cat </etc/lightdm/lightdm.conf.d/autologin-kodi.conf 128 | [Seat:*] 129 | autologin-user=kodi 130 | autologin-session=kodi-alsa 131 | EOF 132 | msg_ok "Set up autologin" 133 | 134 | msg_info "Setting up device detection for xorg" 135 | apt-get install -y xserver-xorg-input-evdev &>/dev/null 136 | #following script needs to be executed before Xorg starts to enumerate all input devices 137 | /bin/mkdir -p /etc/X11/xorg.conf.d 138 | cat >/usr/local/bin/preX-populate-input.sh << __EOF__ 139 | #!/usr/bin/env bash 140 | 141 | ### Creates config file for X with all currently present input devices 142 | # after connecting new device restart X (systemctl restart lightdm) 143 | ###################################################################### 144 | 145 | cat >/etc/X11/xorg.conf.d/10-lxc-input.conf << _EOF_ 146 | Section "ServerFlags" 147 | Option "AutoAddDevices" "False" 148 | EndSection 149 | _EOF_ 150 | 151 | cd /dev/input 152 | for input in event* 153 | do 154 | cat >> /etc/X11/xorg.conf.d/10-lxc-input.conf <<_EOF_ 155 | Section "InputDevice" 156 | Identifier "\$input" 157 | Option "Device" "/dev/input/\$input" 158 | Option "AutoServerLayout" "true" 159 | Driver "evdev" 160 | EndSection 161 | _EOF_ 162 | done 163 | __EOF__ 164 | /bin/chmod +x /usr/local/bin/preX-populate-input.sh 165 | /bin/mkdir -p /etc/systemd/system/lightdm.service.d 166 | cat > /etc/systemd/system/lightdm.service.d/override.conf << __EOF__ 167 | [Service] 168 | ExecStartPre=/bin/sh -c '/usr/local/bin/preX-populate-input.sh' 169 | SupplementaryGroups=video render input audio tty 170 | __EOF__ 171 | systemctl daemon-reload 172 | msg_ok "Set up device detection for xorg" 173 | 174 | PASS=$(grep -w "root" /etc/shadow | cut -b6); 175 | if [[ $PASS != $ ]]; then 176 | msg_info "Customizing Container" 177 | chmod -x /etc/update-motd.d/* 178 | touch ~/.hushlogin 179 | GETTY_OVERRIDE="/etc/systemd/system/container-getty@1.service.d/override.conf" 180 | mkdir -p $(dirname $GETTY_OVERRIDE) 181 | cat << EOF > $GETTY_OVERRIDE 182 | [Service] 183 | ExecStart= 184 | ExecStart=-/sbin/agetty --autologin root --noclear --keep-baud tty%I 115200,38400,9600 \$TERM 185 | EOF 186 | systemctl daemon-reload 187 | systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') 188 | msg_ok "Customized Container" 189 | fi 190 | 191 | msg_info "Cleaning up" 192 | apt-get autoremove >/dev/null 193 | apt-get autoclean >/dev/null 194 | msg_ok "Cleaned" 195 | 196 | msg_info "Starting X up" 197 | systemctl start lightdm 198 | ln -fs /lib/systemd/system/lightdm.service /etc/systemd/system/display-manager.service 199 | msg_info "Started X" 200 | 201 | 202 | 203 | --------------------------------------------------------------------------------