-
-
Notifications
You must be signed in to change notification settings - Fork 27
/
zwift.sh
executable file
·271 lines (235 loc) · 8.08 KB
/
zwift.sh
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
#!/usr/bin/env bash
if [ ! -z $DEBUG ]; then set -x; fi
# Message Box to simplify errors/ and questions.
msgbox() {
TYPE=$1 # Type, info, warning or error
MSG="$2" # Message to Display
TIMEOUT=${3:-0} # Timeout for message, default no timeout.
RED='\033[0;31m'
NC='\033[0m'
BOLD='\033[1m'
UNDERLINE='\033[4m'
case $1 in
error) echo -e "${RED}${BOLD}${UNDERLINE}Error - $MSG${NC}";;
warning) echo -e "${BOLD}${UNDERLINE}Warning - $MSG${NC}";;
question)
if [ $TIMEOUT -ne 0 ]; then TIMEOUT="-t $TIMEOUT"; else TIMEOUT=""; fi
echo -n -e "${RED}${BOLD}${UNDERLINE}Question - $MSG (y/n)${NC}"
read $TIMEOUT -n 1 -p " " yn
echo
case $yn in
y) return 0;;
n) return 1;;
*) return 5;;
esac
;;
*) echo "$MSG";;
esac
if [ $TIMEOUT -eq 0 ]; then
read -p "Press key to continue.. " -n1 -s
else
sleep $TIMEOUT
fi
}
#########################################################
# Config early to allow setting of startup env files.
# More ease of use starting from desktop icon.
# Check for other zwift configuration, sourced here and passed on to container aswell
if [[ -f "$HOME/.config/zwift/config" ]]; then
ZWIFT_CONFIG_FLAG="--env-file $HOME/.config/zwift/config"
source $HOME/.config/zwift/config
fi
# Check for $USER specific zwift configuration, sourced here and passed on to container aswell
if [[ -f "$HOME/.config/zwift/$USER-config" ]]
then
ZWIFT_USER_CONFIG_FLAG="--env-file $HOME/.config/zwift/$USER-config"
source $HOME/.config/zwift/$USER-config
fi
# If a workout directory is specified then map to that directory.
if [[ ! -z $ZWIFT_WORKOUT_DIR ]]; then
ZWIFT_WORKOUT_VOL="-v $ZWIFT_WORKOUT_DIR:/home/user/.wine/drive_c/users/user/Documents/Zwift/Workouts"
fi
########################################
###### Default Setup and Settings ######
WINDOW_MANAGER="Other" # XOrg, XWayland, Wayland, Other
IMAGE=${IMAGE:-docker.io/netbrain/zwift} # Set the container image to use
VERSION=${VERSION:-latest} # The container version
NETWORKING=${NETWORKING:-bridge} # Default Docker Network is Bridge
ZWIFT_UID=${ZWIFT_UID:-$(id -u)}
ZWIFT_GID=${ZWIFT_GID:-$(id -g)}
# CONTAINER_TOOL, Use podman if available
if [ ! $CONTAINER_TOOL ]; then
if [ -x "$(command -v podman)" ]; then
CONTAINER_TOOL=podman
else
CONTAINER_TOOL=docker
fi
fi
if [ $CONTAINER_TOOL == "podman" ]; then
# Podman has to use container id 1000
# Local user is mapped to the container id
LOCAL_UID=$ZWIFT_UID
LOCAL_GID=$ZWIFT_GID
CONTAINER_UID=1000
CONTAINER_GID=1000
else
# Docker will run as the id's provided.
LOCAL_UID=$UID
CONTAINER_UID=$ZWIFT_UID
CONTAINER_GID=$ZWIFT_GID
fi
########################################
###### OS and WM Manager Settings ######
case "$XDG_SESSION_TYPE" in
"wayland")
WINDOW_MANAGER="Wayland"
;;
"x11")
WINDOW_MANAGER="XOrg"
;;
*)
if [ ! -z $WAYLAND_DISPLAY ]; then
WINDOW_MANAGER="Wayland"
elif [ ! -z $DISPLAY ]; then
WINDOW_MANAGER="XOrg"
fi
;;
esac
# Verify which system we are using for wayland and some checks.
if [ "$WINDOW_MANAGER" = "Wayland" ]; then
# System is using wayland or xwayland.
if [ -z $WINE_EXPERIMENTAL_WAYLAND ]; then
WINDOW_MANAGER="XWayland"
else
WINDOW_MANAGER="Wayland"
fi
# ZWIFT_UID does not work on XWayland, show warning
if [ $ZWIFT_UID -ne $(id -u) ]; then
msgbox warning "Wayland does not support ZWIFT_UID different to your id of $(id -u), may not start." 5
fi
fi
#######################################
###### UPD SCRIPTS and CONTAINER ######
# Check for updated zwift.sh
if [[ ! $DONT_CHECK ]]
then
REMOTE_SUM=$(curl -s https://raw.githubusercontent.com/netbrain/zwift/master/zwift.sh | sha256sum | awk '{print $1}')
THIS_SUM=$(sha256sum $0 | awk '{print $1}')
# Compare the checksums
if [ "$REMOTE_SUM" = "$THIS_SUM" ]; then
echo "You are running latest zwift.sh 👏"
else
# Ask with Timeout, default is do not update.
msgbox question "You are not running the latest zwift.sh 😭, (Default no in 5 seconds)" 5
if [ $? -eq 0 ]; then
pkexec env PATH=$PATH bash -c "$(curl -fsSL https://raw.githubusercontent.com/netbrain/zwift/master/bin/install.sh)"
exec "$0" "${@}"
fi
fi
fi
# Check for updated container image
if [[ ! $DONT_PULL ]]
then
$CONTAINER_TOOL pull $IMAGE:$VERSION
fi
#############################
##### PREPARE ALL FLAGS #####
# Define Base Container Parameters
GENERAL_FLAGS=(
-d
--rm
--privileged
--network $NETWORKING
--name zwift-$USER
--security-opt label=disable
--hostname $HOSTNAME
-e DISPLAY=$DISPLAY
-e ZWIFT_UID=$CONTAINER_UID
-e ZWIFT_GID=$CONTAINER_GID
-e PULSE_SERVER=/run/user/$CONTAINER_UID/pulse/native
-v zwift-$USER:/home/user/.wine/drive_c/users/user/Documents/Zwift
-v /run/user/$LOCAL_UID/pulse:/run/user/$CONTAINER_UID/pulse
)
###################################
##### SPECIFIC CONFIGURATIONS #####
# Check for proprietary nvidia driver and set correct device to use
if [[ -f "/proc/driver/nvidia/version" ]]
then
if [[ $CONTAINER_TOOL == "podman" ]]
then
VGA_DEVICE_FLAG="--device=nvidia.com/gpu=all"
else
VGA_DEVICE_FLAG="--gpus=all"
fi
else
VGA_DEVICE_FLAG="--device=/dev/dri:/dev/dri"
fi
if [[ -n "$DBUS_SESSION_BUS_ADDRESS" ]]
then
[[ $DBUS_SESSION_BUS_ADDRESS =~ ^unix:path=([^,]+) ]]
DBUS_UNIX_SOCKET=${BASH_REMATCH[1]}
if [[ -n "$DBUS_UNIX_SOCKET" ]]
then
DBUS_CONFIG_FLAGS=(
-e DBUS_SESSION_BUS_ADDRESS=$(echo $DBUS_SESSION_BUS_ADDRESS | sed 's/'$LOCAL_UID'/'$CONTAINER_UID'/')
-v $DBUS_UNIX_SOCKET:$(echo $DBUS_UNIX_SOCKET | sed 's/'$LOCAL_UID'/'$CONTAINER_UID'/')
)
fi
fi
# Setup Flags for Window Managers
if [ $WINDOW_MANAGER == "Wayland" ]; then
WM_FLAGS=(
-e WINE_EXPERIMENTAL_WAYLAND=1
-e XDG_RUNTIME_DIR=/run/user/$CONTAINER_UID
-e $WAYLAND_DISPLAY=$WAYLAND_DISPLAY
-v $XDG_RUNTIME_DIR/$WAYLAND_DISPLAY:$(echo $XDG_RUNTIME_DIR | sed 's/'$LOCAL_UID'/'$CONTAINER_UID'/')/$WAYLAND_DISPLAY
)
fi
if [ $WINDOW_MANAGER == "XWayland" ] || [ $WINDOW_MANAGER == "XOrg" ]; then
# If not XAuthority set then don't pass, hyprland is one that does not use it.
if [ -z $XAUTHORITY ]; then
WM_FLAGS=(
-v /tmp/.X11-unix:/tmp/.X11-unix
)
else
WM_FLAGS=(
-e XAUTHORITY=$(echo $XAUTHORITY | sed 's/'$LOCAL_UID'/'$CONTAINER_UID'/')
-v /tmp/.X11-unix:/tmp/.X11-unix
-v $XAUTHORITY:$(echo $XAUTHORITY | sed 's/'$LOCAL_UID'/'$CONTAINER_UID'/')
)
fi
fi
if [ $WINDOW_MANAGER == "XOrg" ]; then
unset WINE_EXPERIMENTAL_WAYLAND
fi
# Initiate podman Volume with correct permissions
if [ $CONTAINER_TOOL == "podman" ]; then
# Create a volume if not already exists, this is done now as
# if left to the run command the directory can get the wrong permissions
if [[ -z $(podman volume ls | grep zwift-$USER) ]]; then
$CONTAINER_TOOL volume create zwift-$USER
fi
PODMAN_FLAGS=(
--userns keep-id:uid=$CONTAINER_UID,gid=$CONTAINER_GID
)
fi
#########################
##### RUN CONTAINER #####
CONTAINER=$($CONTAINER_TOOL run ${GENERAL_FLAGS[@]} \
$ZWIFT_CONFIG_FLAG \
$ZWIFT_USER_CONFIG_FLAG \
$ZWIFT_WORKOUT_VOL \
$VGA_DEVICE_FLAG \
${DBUS_CONFIG_FLAGS[@]} \
${WM_FLAGS[@]} \
${PODMAN_FLAGS[@]} \
$IMAGE:$VERSION $@
)
if [ $? -ne 0 ]; then
msgbox error "Error can't run zwift, check variables!" 10
exit 0
fi
# Allow container to connect to X, has to be set for different UID
if [ -x "$(command -v xhost)" ] && [ $ZWIFT_UID -ne $(id -u) ] && [ -z $WINE_EXPERIMENTAL_WAYLAND ]; then
xhost +local:$($CONTAINER_TOOL inspect --format='{{ .Config.Hostname }}' $CONTAINER)
fi