-
Notifications
You must be signed in to change notification settings - Fork 24
/
reflect-apps
executable file
·141 lines (126 loc) · 4.9 KB
/
reflect-apps
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
#!/bin/bash
#
# Map desktop files from guest to host, prefixing the Exec stanzas
# with ds-runner or ds-shell -c (as appropriate), to allow direct
# invocation of 64-bit applications in the container from the 32-bit
# host.
#
# Takes a single parameter, the name of the machine to reflect from
# ("debian-buster-64", for example).
#
# Intended to be triggered via a path unit watching the
# ${DS64_DIR}/usr/share/applications directory for changes.
#
# Desktop files without "Type=Application" are ignored, and any
# prior desktop files at the target location in the host, which have
# NoDisplay=true set, will not be overwritten.
#
# Also copies contents of /usr/share/icons into /usr/share/gdm/icons,
# so that (most, at least) referenced icons will refer.
#
# AUTHOR
# ------
#
# Copyright (c) 2019-20 sakaki <[email protected]>
#
# License (GPL v3.0)
# ------------------
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
# General Public License for more details.
#
set -e
set -u
shopt -s nullglob
DS64_NAME="${1:-debian-buster-64}"
DS64_DIR="/var/lib/machines/${DS64_NAME}"
CONTAINER="${DS64_DIR}"
CONTAINER_APP_DIR="${CONTAINER}/usr/share/applications"
HOST_APP_DIR="/usr/share/applications"
SCRIPT_NAME="$(basename -- "${0}")"
if pidof -o %PPID -x "${SCRIPT_NAME}" &>/dev/null; then
# already running
exit 0
fi
# let things settle
sleep 2
while pidof -x apt-get &>/dev/null || pidof -x apt &>/dev/null || pidof -x dpkg &>/dev/null; do
sleep 1
done
# bail out if ds64 not running, but, not an error since
# e.g. user may have guest container down for maintenance
if ! ds64-running; then
# try one more time
sleep 2
if ! ds64-running; then
exit 0
fi
fi
check-aarch64 || exit 1
# bail out if no container present at all
if ! [[ -d "${CONTAINER}" ]]; then
exit 1
fi
do_reflect_apps() {
mkdir -p "${CONTAINER_APP_DIR}"
mkdir -p "${HOST_APP_DIR}"
# begin by removing any shadowed .desktop files that don't explicitly
# have NoDisplay=true set (the latter are left as a way to block
# certain apps from being auto-reflected
for F in "${HOST_APP_DIR}"/ds64-app-*.desktop; do
if ! grep -q "^NoDisplay=true" "${F}"; then
rm -f "${F}"
fi
done
for F in "${CONTAINER_APP_DIR}"/*.desktop; do
NEXTFNAME="ds64-app-${F##*/}"
T="${HOST_APP_DIR}/${NEXTFNAME}"
if grep -q "^Type=Application" "${F}" 2>/dev/null && ! grep -q "^NoDisplay=true" "${F}"; then
# unless the .desktop file already exists, copy it over, modifying it en route
# so that both desktop and script-based files can be invoked from the
# 32-bit Raspbian host
# if you mark a copied variant as NoDisplay=true then it will not show up
# in the menu, and the copy so marked will not be overwritten
if ! [[ -s "${T}" ]]; then
# deal with shell and GUI apps separately
if grep -q "Terminal=true" "${F}" 2>/dev/null; then
sed -e 's/^\(Name.*\)$/\1 (64-bit)/; s/^\(Comment.*\)$/\1 (64-bit)/; s/^Exec=\(.*\)$/Exec=ds64-shell -c \1/; /^TryExec/d; /^StartupNotify/d' "${F}" > "${T}"
else
sed -e 's/^\(Name.*\)$/\1 (64-bit)/; s/^\(Comment.*\)$/\1 (64-bit)/; s/^Exec=\(.*\)$/Exec=ds64-runner \1/; /^TryExec/d; /^StartupNotify/d' "${F}" > "${T}"
fi
echo "StartupNotify=false" >> "${T}"
# .desktop files do not need to be executable
chmod 0644 "${T}"
fi
fi
done
# ensure at least most icons available
mkdir -p "/usr/share/gdm"
rm -rf "/usr/share/gdm/icons"
rm -rf "/usr/share/gdm/pixmaps"
# make a copy inside the container first, to resolve any dangling symlinks
machinectl shell "${DS64_NAME}" /bin/bash -c "rm -rf /tmp/icons /tmp/pixmaps; cp -rL /usr/share/icons /tmp/icons; cp -rL /usr/share/pixmaps /tmp/pixmaps" &>/dev/null
machinectl copy-from "${DS64_NAME}" "/tmp/pixmaps" "/usr/share/gdm/pixmaps" &>/dev/null
machinectl copy-from "${DS64_NAME}" "/tmp/icons" "/usr/share/gdm/icons" &>/dev/null
# remove menu caches to ensure visible on host
for D in /home/*; do
find "${D}/.cache/menus" -type f -delete
done
lxpanelctl reload || true
machinectl shell "${DS64_NAME}" /bin/bash -c "rm -rf /tmp/icons /tmp/pixmaps" &>/dev/null
touch /etc/xdg/menus/lxde-*.menu
}
if ! do_reflect_apps; then
# try one more time before giving up, there can be timing
# issues on startup
sleep 2
do_reflect_apps
fi
exit 0