forked from 89luca89/distrobox
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathdistrobox-export
executable file
·177 lines (162 loc) · 4.69 KB
/
distrobox-export
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
#!/bin/sh
# POSIX
# Expected env variables:
# HOME
# USER
# DISTROBOX_ENTER_PATH
trap '[ "$?" -ne 0 ] && echo An error occurred' EXIT
# Defaults
container_app=""
container_app_delete=0
verbose=0
# We depend on some commands, let's be sure we have them
base_dependencies="basename grep sed find"
for dep in ${base_dependencies}; do
if ! command -v "${dep}" >/dev/null; then
echo "Missing dependency: ${dep}"
exit 127
fi
done
# Print usage to stdout.
# Arguments:
# None
# Outputs:
# print usage with examples.
show_help() {
echo "USAGE:
distrobox-export --app mpv
distrobox-export --service syncthing
Note you can use --app OR --service but not together.
Arguments:
--app/-a: name of the application to export
--service/-s: name of the service to export
--delete/-d: delete exported application or service
--help/-h: show this message
-v: show more verbosity
"
}
# Parse arguments
while :; do
case $1 in
-h | --help)
# Call a "show_help" function to display a synopsis, then exit.
show_help
exit
;;
-v)
shift
verbose=1
;;
-a | --app)
if [ -n "$2" ]; then
container_app="$2"
shift
shift
fi
;;
-s | --service)
if [ -n "$2" ]; then
container_service="$2"
shift
shift
fi
;;
-d | --delete)
container_app_delete=1
shift
;;
*) # Default case: If no more options then break out of the loop.
break ;;
esac
done
# Ensure the foundamental variables are set and not empty, we will not proceed if
# they are not all set.
if [ -z "${container_app}" ] && [ -z "${container_service}" ]; then
echo "Invalid arguments, missing app or service to export"
exit 1
fi
if [ -n "${container_app}" ] && [ -n "${container_service}" ]; then
echo "Invalid arguments, choose an app OR a service to export"
exit 1
fi
# Also check we're running inside a container and not on the host
if [ ! -f /run/.containerenv ]; then
echo "You must run $(basename "$0") inside a container..."
exit 1
fi
set -o errexit
set -o nounset
# set verbosity
if [ "${verbose}" -ne 0 ]; then
set -o xtrace
fi
container_name=$(grep "name=" /run/.containerenv | cut -d'"' -f2)
# Prefix to add to an existing command to work throught the container
container_command_prefix="${DISTROBOX_ENTER_PATH} --name ${container_name} -e "
# Work on a desktop app export
if [ -n "${container_app}" ]; then
# Ensure the app we're exporting is installed
if ! command -v "${container_app}" >/dev/null; then
echo "Error: trying to export a non-installed application"
exit 127
fi
# Find desktop file for the application to export
desktop_files=$(grep -ril "${container_app}" /usr/share/applications/*)
icon_files=$(find /usr/share/icons -iname "*${container_app}*")
# copy icons in home directory
for icon in $icon_files; do
icon_home_folder="$(dirname "${icon}" | sed "s|/usr/share/|${HOME}/.local/share/|g")"
# check if we're exporting or deleting
if [ "${container_app_delete}" -ne 0 ]; then
# we need to remove, not export
rm -f "${icon_home_folder}"/"$(basename "${icon}")"
else
# we wanto to export the application's icons
mkdir -p "${icon_home_folder}"
cp "${icon}" "${icon_home_folder}"
fi
done
# create desktop files for the distrobox
for desktop_file in $desktop_files; do
desktop_home_file="$(basename "${desktop_file}")"
# check if we're exporting or deleting
if [ "${container_app_delete}" -ne 0 ]; then
rm -f "${HOME}/.local/share/applications/${desktop_home_file}"
else
# If a TryExec is present, we have to fake it as it will not work throught the
# container separation
sed "s|^Exec=|Exec=${container_command_prefix} |g" "${desktop_file}" |
sed "s|^TryExec=.*|TryExec=true|g" \
>"${HOME}/.local/share/applications/${desktop_home_file}"
fi
done
elif [ -n "${container_service}" ]; then
# If we're managing services, let's be sure we have systemctl
if ! command -v systemctl >/dev/null; then
echo "Missing dependency: systemd"
exit 127
fi
# Ensure we're working with fresh data
systemctl --user daemon-reload
# Fetch original service file
service_file="${HOME}/.config/systemd/user/${container_service}.service"
# Create temp file with random name
temp_file="/tmp/$(
tr -dc A-Za-z0-9 </dev/urandom | head -c 13
echo ''
)"
# Replace all Exec occurrencies
for cmd in ExecStart ExecStartPre ExecStartPost ExecReload ExecStop ExecStopPost; do
# Save to temp file
systemctl --user cat "${container_service}.service" >"${temp_file}" 2>/dev/null
# Add prefix only if not present
if ! grep "${cmd}" "${temp_file}" | grep -q "${container_command_prefix}"; then
tail -n+2 "${temp_file}" |
sed "s|^${cmd}=|${cmd}=${container_command_prefix} |g" >"${service_file}"
fi
done
# Cleanup
rm -f "${temp_file}"
# Reload
systemctl --user daemon-reload
fi