-
-
Notifications
You must be signed in to change notification settings - Fork 34
/
Copy pathzwift.sh
executable file
·298 lines (258 loc) · 9.26 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
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
#!/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 [ -z "$CONTAINER_TOOL" ]; then
if [ -x "$(command -v podman)" ]; then
CONTAINER_TOOL=podman
else
CONTAINER_TOOL=docker
fi
fi
# get password from SecretService (if username is set but not password)
if [ -n "${ZWIFT_USERNAME}" -a -z "${ZWIFT_PASSWORD}" -a -x "$(command -v secret-tool)" ]; then
echo "Looking up Zwift password for ${ZWIFT_USERNAME}..."
PASSWORD_SECRET_NAME="zwift-password-${ZWIFT_USERNAME}"
secret-tool lookup application zwift username ${ZWIFT_USERNAME} | ${CONTAINER_TOOL} secret create $([ "${CONTAINER_TOOL}" == "podman" ] && echo "--replace=true") "${PASSWORD_SECRET_NAME}" - > /dev/null
# secret will not be created if the password does not exist
if ${CONTAINER_TOOL} secret exists "${PASSWORD_SECRET_NAME}"; then
echo "Passing password to zwift container."
ZWIFT_PASSWORD_SECRET="--secret ${PASSWORD_SECRET_NAME},type=env,target=ZWIFT_PASSWORD"
else
echo "Password not found in the SecretService keyring, you can store it with" \
"\`secret-tool store --label \"Zwift password for ${ZWIFT_USERNAME}\" application zwift username ${ZWIFT_USERNAME}\`"
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=(
--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 foreground/background flag
if [[ $ZWIFT_FG -eq "1" ]]
then
ZWIFT_FG_FLAG=(-it) # run in fg
else
ZWIFT_FG_FLAG=(-d) # run in bg
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_FG_FLAG[@]} \
$ZWIFT_CONFIG_FLAG \
$ZWIFT_PASSWORD_SECRET \
$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)" ] && [ -z $WINE_EXPERIMENTAL_WAYLAND ]; then
xhost +local:$($CONTAINER_TOOL inspect --format='{{ .Config.Hostname }}' $CONTAINER)
fi