ybox 0.9.8.1__py3-none-any.whl → 0.9.11__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- ybox/__init__.py +1 -1
- ybox/cmd.py +17 -1
- ybox/conf/completions/ybox.fish +2 -0
- ybox/conf/distros/arch/init-user.sh +2 -2
- ybox/conf/distros/arch/init.sh +1 -0
- ybox/conf/distros/arch/pkgdeps.py +2 -0
- ybox/conf/distros/deb-generic/pkgdeps.py +2 -1
- ybox/conf/profiles/apps.ini +10 -5
- ybox/conf/profiles/basic.ini +48 -23
- ybox/conf/profiles/dev.ini +4 -6
- ybox/conf/resources/entrypoint-cp.sh +1 -1
- ybox/conf/resources/entrypoint-root.sh +4 -3
- ybox/conf/resources/entrypoint-user.sh +5 -3
- ybox/conf/resources/entrypoint.sh +24 -22
- ybox/conf/resources/prime-run +0 -2
- ybox/conf/resources/run-in-dir +30 -16
- ybox/conf/resources/run-user-bash-cmd +17 -1
- ybox/conf/resources/ybox-systemd.template +24 -0
- ybox/config.py +9 -1
- ybox/env.py +18 -7
- ybox/migrate/{0.9.0-0.9.7:0.9.8.py → 0.9.0-0.9.10:0.9.11.py} +6 -5
- ybox/pkg/clean.py +1 -7
- ybox/pkg/info.py +1 -7
- ybox/pkg/inst.py +40 -22
- ybox/pkg/list.py +1 -6
- ybox/pkg/mark.py +1 -1
- ybox/pkg/repair.py +4 -0
- ybox/pkg/search.py +1 -7
- ybox/run/cmd.py +2 -1
- ybox/run/control.py +107 -25
- ybox/run/create.py +254 -63
- ybox/run/destroy.py +89 -4
- ybox/run/graphics.py +37 -17
- ybox/run/logs.py +2 -1
- ybox/run/ls.py +2 -1
- ybox/run/pkg.py +49 -7
- ybox/state.py +22 -3
- ybox/util.py +5 -5
- {ybox-0.9.8.1.dist-info → ybox-0.9.11.dist-info}/METADATA +68 -34
- ybox-0.9.11.dist-info/RECORD +77 -0
- {ybox-0.9.8.1.dist-info → ybox-0.9.11.dist-info}/WHEEL +1 -1
- ybox-0.9.8.1.dist-info/RECORD +0 -76
- {ybox-0.9.8.1.dist-info → ybox-0.9.11.dist-info}/entry_points.txt +0 -0
- {ybox-0.9.8.1.dist-info → ybox-0.9.11.dist-info/licenses}/LICENSE +0 -0
- {ybox-0.9.8.1.dist-info → ybox-0.9.11.dist-info}/top_level.txt +0 -0
ybox/__init__.py
CHANGED
@@ -1,2 +1,2 @@
|
|
1
1
|
"""`ybox` is a tool to easily manage linux distributions in containers"""
|
2
|
-
__version__ = "0.9.
|
2
|
+
__version__ = "0.9.11"
|
ybox/cmd.py
CHANGED
@@ -10,6 +10,7 @@ import sys
|
|
10
10
|
from enum import Enum
|
11
11
|
from typing import Callable, Iterable, Optional, Union
|
12
12
|
|
13
|
+
from ybox import __version__ as product_version
|
13
14
|
from ybox.config import Consts
|
14
15
|
|
15
16
|
from .print import print_error, print_info, print_notice, print_warn
|
@@ -207,7 +208,7 @@ def run_command(cmd: Union[str, list[str]], capture_output: bool = False,
|
|
207
208
|
sys.exit(result.returncode)
|
208
209
|
else:
|
209
210
|
return result.returncode
|
210
|
-
if capture_output and result.stderr:
|
211
|
+
if capture_output and result.stderr and error_msg != "SKIP":
|
211
212
|
print_warn(result.stderr.decode("utf-8"), file=sys.stderr)
|
212
213
|
return result.stdout.decode("utf-8") if capture_output else result.returncode
|
213
214
|
|
@@ -221,6 +222,21 @@ def _print_subprocess_output(result: subprocess.CompletedProcess[bytes]) -> None
|
|
221
222
|
print_warn(result.stderr.decode("utf-8"), file=sys.stderr)
|
222
223
|
|
223
224
|
|
225
|
+
def parser_version_check(parser: argparse.ArgumentParser, argv: list[str]) -> None:
|
226
|
+
"""
|
227
|
+
Update command-line parser to add `--version` option to existing ones that will output the
|
228
|
+
ybox product version and exit if specified in the given list of arguments.
|
229
|
+
|
230
|
+
:param parser: instance of :class:`argparse.ArgumentParser` having the command-line parser
|
231
|
+
:param argv: the list of arguments to be parsed
|
232
|
+
"""
|
233
|
+
parser.add_argument("--version", action="store_true", help="output ybox version")
|
234
|
+
# argv may have required positional arguments, hence check for --version separately
|
235
|
+
if "--version" in argv:
|
236
|
+
print(product_version)
|
237
|
+
sys.exit(0)
|
238
|
+
|
239
|
+
|
224
240
|
def parse_opt_deps_args(argv: list[str]) -> argparse.Namespace:
|
225
241
|
"""
|
226
242
|
Common command-line parser for `opt_deps` utilities (see [pkgmgr] section of distro.ini)
|
ybox/conf/completions/ybox.fish
CHANGED
@@ -29,6 +29,8 @@ end
|
|
29
29
|
complete -f -c ybox-create -s h -l help -d "show help"
|
30
30
|
complete -c ybox-create -s n -l name -d "name of the ybox container" -r
|
31
31
|
complete -f -c ybox-create -s F -l force-own-orphans -d "force ownership of orphans on shared root"
|
32
|
+
complete -f -c ybox-create -s C -l distribution-config -d "path to custom distribution configuration file"
|
33
|
+
complete -f -c ybox-create -l distribution-image -d "custom container image"
|
32
34
|
complete -f -c ybox-create -s q -l quiet -d "skip interactive questions"
|
33
35
|
complete -f -c ybox-create -n "not __fish_seen_subcommand_from (__fish_ybox_complete_distributions)" -a "(__fish_ybox_complete_distributions)"
|
34
36
|
|
@@ -10,8 +10,8 @@ current_user="$(id -un)"
|
|
10
10
|
# install binaries for paru from paru-bin (paru takes too long to compile)
|
11
11
|
PARU="paru --noconfirm"
|
12
12
|
echo_color "$fg_cyan" "Installing AUR helper 'paru'" >> $status_file
|
13
|
-
export HOME
|
14
|
-
cd
|
13
|
+
export HOME=$(getent passwd "$current_user" | cut -d: -f6)
|
14
|
+
cd "$HOME"
|
15
15
|
rm -rf paru-bin
|
16
16
|
git clone https://aur.archlinux.org/paru-bin.git
|
17
17
|
cd paru-bin
|
ybox/conf/distros/arch/init.sh
CHANGED
@@ -11,7 +11,7 @@ where:
|
|
11
11
|
and so on; resolution of level > 2 is not required since caller currently ignores those
|
12
12
|
* <order>: this is a simple counter assigned to the dependencies where the value itself is of no
|
13
13
|
significance but if multiple dependencies have the same value then it means that they
|
14
|
-
are ORed dependencies and only one of them
|
14
|
+
are ORed dependencies and only one of them need to be selected for installation
|
15
15
|
* <installed>: true if the dependency already installed and false otherwise
|
16
16
|
* <description>: detailed description of the dependency; it can contain literal \n to indicate
|
17
17
|
newlines in the description
|
@@ -69,6 +69,7 @@ class PkgDetail(Enum):
|
|
69
69
|
OPTIONAL_DEP = 5
|
70
70
|
|
71
71
|
|
72
|
+
# noinspection PyUnusedLocal
|
72
73
|
def process_next_item(line: str, parse_line: Callable[[str], tuple[PkgDetail, str]],
|
73
74
|
parse_dep: Callable[[str], Iterable[tuple[str, str, Optional[str]]]],
|
74
75
|
installed: Callable[[str], bool], max_level: int,
|
ybox/conf/profiles/apps.ini
CHANGED
@@ -1,6 +1,7 @@
|
|
1
1
|
[base]
|
2
2
|
name = Profile for CLI and GUI apps
|
3
3
|
includes = basic.ini
|
4
|
+
ssh_agent = on
|
4
5
|
|
5
6
|
[security]
|
6
7
|
# SYS_PTRACE may be required by mesa which is invoked indirectly by both firefox and chromium.
|
@@ -9,6 +10,9 @@ includes = basic.ini
|
|
9
10
|
caps_add = SYS_PTRACE
|
10
11
|
|
11
12
|
[mounts]
|
13
|
+
# export the host's ssh keys for use by ssh-agent in the container as required ("ro" mode
|
14
|
+
# implies that known_hosts and other files within ~/.ssh cannot be changed)
|
15
|
+
ssh = $HOME/.ssh:$TARGET_HOME/.ssh:ro
|
12
16
|
music = $HOME/Music:$TARGET_HOME/Music:ro
|
13
17
|
pictures = $HOME/Pictures:$TARGET_HOME/Pictures:ro
|
14
18
|
videos = $HOME/Videos:$TARGET_HOME/Videos:ro
|
@@ -19,8 +23,9 @@ videos = $HOME/Videos:$TARGET_HOME/Videos:ro
|
|
19
23
|
|
20
24
|
[app_flags]
|
21
25
|
# These flags will be added to Exec line of google-chrome.desktop when it is copied to host.
|
22
|
-
|
23
|
-
#
|
24
|
-
|
25
|
-
google-chrome
|
26
|
-
google-chrome-
|
26
|
+
|
27
|
+
# the --disable-dev-shm-usage flag in chrome/chromium based browsers disables use of /dev/shm
|
28
|
+
# which can reduce memory footprint at the cost of performance and increased disk activity
|
29
|
+
#google-chrome = !p --disable-dev-shm-usage !a
|
30
|
+
#google-chrome-beta = !p --disable-dev-shm-usage !a
|
31
|
+
#google-chrome-unstable = !p --disable-dev-shm-usage !a
|
ybox/conf/profiles/basic.ini
CHANGED
@@ -20,7 +20,8 @@
|
|
20
20
|
# - YBOX_SYS_CONF_DIR: path to system configuration directory where configuration directory
|
21
21
|
# shipped with ybox is installed (or the string form of
|
22
22
|
# the directory if it is not on filesystem like an egg or similar)
|
23
|
-
# - TARGET_HOME: set to the home directory of the container user
|
23
|
+
# - TARGET_HOME: set to the home directory of the container user in the container
|
24
|
+
# (which is same as the host user's $HOME for podman and /root for docker)
|
24
25
|
# Additionally a special notation can be used for current date+time with this notation:
|
25
26
|
# ${NOW:<fmt>}. The <fmt> uses the format supported by python strftime
|
26
27
|
# (https://docs.python.org/3/library/datetime.html#datetime.datetime.strftime)
|
@@ -66,7 +67,7 @@ includes =
|
|
66
67
|
# to freely create as many containers as desired to achieve best isolation without worrying
|
67
68
|
# about dramatic increase in disk and/or memory usage.
|
68
69
|
shared_root = $HOME/.local/share/ybox/SHARED_ROOTS/$YBOX_DISTRIBUTION_NAME
|
69
|
-
# Bind mount the container $HOME to this local path
|
70
|
+
# Bind mount the container $HOME to this local path. This makes it
|
70
71
|
# easier for backup software and otherwise to read useful container data.
|
71
72
|
# If not provided then you should explicitly mount required directories in the [mounts]
|
72
73
|
# section otherwise home will remain completely ephemeral which is not recommended.
|
@@ -99,6 +100,16 @@ pulseaudio = on
|
|
99
100
|
dbus = on
|
100
101
|
# If enabled then the system dbus from the host is available to the container.
|
101
102
|
dbus_sys = off
|
103
|
+
# If enabled then the socket for SSH agent, if present, is made available to the container.
|
104
|
+
# The $SSH_AUTH_SOCK environment variables must be set in the host environment for this to work.
|
105
|
+
# You can also mount $HOME/.ssh with appropriate flags ("ro" if possible) in the [mounts]
|
106
|
+
# section to enable the container use the host's ssh keys.
|
107
|
+
ssh_agent = off
|
108
|
+
# If enabled then the socket for GPG agent, if present, is made available to the container.
|
109
|
+
# The $GPG_AGENT_INFO environment variable must be set in the host environment for this to work.
|
110
|
+
# You can also mount $HOME/.gnupg with appropriate flags ("ro" if possible) in the [mounts]
|
111
|
+
# section to enable the container use the host's gpg keys.
|
112
|
+
gpg_agent = off
|
102
113
|
# If enabled then Direct Rendering Infrastructure for accelerated graphics is available to
|
103
114
|
# the container.
|
104
115
|
dri = on
|
@@ -115,15 +126,15 @@ nvidia = off
|
|
115
126
|
# works well on most Linux distros (https://wiki.archlinux.org/title/docker or
|
116
127
|
# https://wiki.archlinux.org/title/podman), and the official NVIDIA docs:
|
117
128
|
# https://docs.nvidia.com/datacenter/cloud-native/container-toolkit/latest/install-guide.html
|
118
|
-
# For example on ubuntu with podman, configure the apt repository from the previous link
|
129
|
+
# For example, on ubuntu with podman, configure the apt repository from the previous link
|
119
130
|
# and install the package as noted there, then run
|
120
131
|
# `sudo nvidia-ctk cdi generate --output=/etc/cdi/nvidia.yaml`.
|
121
132
|
# This will need to be repeated if nvidia driver version is upgraded.
|
122
133
|
#
|
123
134
|
# This will take precedence if both "nvidia" and "nvidia_ctk" are enabled.
|
124
135
|
nvidia_ctk = off
|
125
|
-
# default podman/docker shm-size is 64m which can be insufficient for many apps
|
126
|
-
shm_size =
|
136
|
+
# default podman/docker shm-size is only 64m which can be insufficient for many apps
|
137
|
+
shm_size = 2g
|
127
138
|
# Limit the maximum number of processes in the container (to avoid stuff like fork bombs).
|
128
139
|
pids_limit = 2048
|
129
140
|
# Logging driver to use. Default for podman/docker is to use journald in modern Linux
|
@@ -136,6 +147,9 @@ log_driver = json-file
|
|
136
147
|
# Example for docker that does not support `path`
|
137
148
|
log_opts = max-size=10m,max-file=3
|
138
149
|
|
150
|
+
# Comma separated list of additional devices that should be made available to the container using
|
151
|
+
# the --device option to podman/docker run. Example: devices = /dev/video0,/dev/ttyUSB0
|
152
|
+
devices =
|
139
153
|
|
140
154
|
# The security-opt and other security options passed to podman/docker.
|
141
155
|
# You should restrict these as required.
|
@@ -200,29 +214,41 @@ documents = $HOME/Documents:$TARGET_HOME/Documents:ro
|
|
200
214
|
# section) to a directory that is mounted read-only.
|
201
215
|
#
|
202
216
|
# The value has two parts separated by "->" with the LHS of this being the source that
|
203
|
-
# is to be copied while the RHS is the required relative path in the
|
204
|
-
#
|
217
|
+
# is to be copied while the RHS is the required relative path in the container's home directory.
|
218
|
+
# Any spaces around "->" are excluded from the LHS and RHS names.
|
205
219
|
# Source is skipped if it does not exist or not readable with a message on standard output.
|
206
220
|
#
|
207
221
|
# Typically this will contain shell, vim and other common configuration files.
|
208
222
|
# These can be either files or directories and are skipped if they do not exist.
|
209
|
-
# The keys here
|
210
|
-
# unique and can be used to override in later files that include this one.
|
223
|
+
# The keys here should be unique and can be used to override in later files that include this one.
|
211
224
|
#
|
212
|
-
#
|
213
|
-
#
|
214
|
-
#
|
225
|
+
# Two special suffixes can be used in the key names:
|
226
|
+
# 1) ":dir" : this suffix indicates that the source is a directory and entire directory structure
|
227
|
+
# should be replicated in the target with symlinks only for the individual files;
|
228
|
+
# this helps in cases where user needs to make a separate copy of a file inside
|
229
|
+
# the directory (using either ":copy" suffix or manually)
|
230
|
+
# 2) ":copy": this suffix indicates that the source should be copied to the target; if a
|
231
|
+
# file/directory to be copied lies inside another directory that is being linked,
|
232
|
+
# then it should be mentioned before this and marked with ":dir" so that directory
|
233
|
+
# structure is replicated in the target (see example of fish shell config below)
|
234
|
+
#
|
235
|
+
# Note: The files from the host are mounted read-only by default in the target container, so if
|
236
|
+
# you need to change a file within a container then you can use the ":copy" suffix in the key name
|
237
|
+
# or manually remove the symlink and make a copy of the file. This will remove the
|
215
238
|
# direct sharing between the two which has to be done manually thereon if required.
|
216
239
|
# The sharing behavior also depends on "config_hardlinks" as described in its comment above
|
217
240
|
# in the [base] section.
|
218
241
|
#
|
219
|
-
# Note: The HOME
|
220
|
-
#
|
221
|
-
#
|
242
|
+
# Note: The LHS should typically have a path having $HOME while RHS will be relative to the
|
243
|
+
# target's home inside the container. Do not use $TARGET_HOME on RHS since path the assumed
|
244
|
+
# to be a relative one and $TARGET_HOME already inserted as required.
|
222
245
|
[configs]
|
246
|
+
env_conf = $HOME/.config/environment.d -> .config/environment.d
|
223
247
|
bashrc = $HOME/.bashrc -> .bashrc
|
224
248
|
starship = $HOME/.config/starship.toml -> .config/starship.toml
|
225
|
-
|
249
|
+
# replicate fish configuration directory with copy of fish_variables but symlinks for the rest
|
250
|
+
fish_conf:dir = $HOME/.config/fish -> .config/fish
|
251
|
+
fish_vars:copy = $HOME/.config/fish/fish_variables -> .config/fish/fish_variables
|
226
252
|
omf = $HOME/.config/omf -> .config/omf
|
227
253
|
omf_data = $HOME/.local/share/omf -> .local/share/omf
|
228
254
|
zshrc = $HOME/.zshrc -> .zshrc
|
@@ -261,10 +287,11 @@ speechconf = $HOME/.config/speech-dispatcher -> .config/speech-dispatcher
|
|
261
287
|
[env]
|
262
288
|
TERM
|
263
289
|
TERMINFO_DIRS = /usr/share/terminfo:/var/lib/terminfo
|
264
|
-
|
265
|
-
|
290
|
+
# always pretend desktop to be GNOME since KDE/*DE apps required by xdg-* are not installed
|
291
|
+
XDG_CURRENT_DESKTOP = GNOME
|
292
|
+
XDG_SESSION_DESKTOP = GNOME
|
293
|
+
DESKTOP_SESSION = gnome
|
266
294
|
XDG_SESSION_TYPE
|
267
|
-
DESKTOP_SESSION
|
268
295
|
GTK_IM_MODULE
|
269
296
|
QT_IM_MODULE
|
270
297
|
SDL_IM_MODULE
|
@@ -290,14 +317,12 @@ XMODIFIERS
|
|
290
317
|
[app_flags]
|
291
318
|
# These flags/arguments will be added to Exec line of chromium.desktop when it is copied to
|
292
319
|
# host as well as in the wrapper chromium executable created on the host.
|
293
|
-
# You can use "!p" here for the first argument in the 'Exec='
|
320
|
+
# You can use "!p" here for the first argument in the 'Exec=' line in the desktop
|
294
321
|
# file and '!a' for rest of the arguments. When linking to an executable program, '!p' will
|
295
322
|
# refer to the full path of the executable while '!a' will be replaced by "$@" in the shell
|
296
323
|
# script. Use '!!p' for a literal '!p' and '!!a' for a literal '!a'.
|
297
324
|
|
298
|
-
|
299
|
-
# /dev/shm in read-write mode which is quite insecure.
|
300
|
-
chromium = !p --disable-dev-shm-usage --enable-chrome-browser-cloud-management !a
|
325
|
+
chromium = !p --enable-chrome-browser-cloud-management !a
|
301
326
|
|
302
327
|
|
303
328
|
# Startup programs you want to run when starting the container. These are run using
|
ybox/conf/profiles/dev.ini
CHANGED
@@ -1,6 +1,7 @@
|
|
1
1
|
[base]
|
2
2
|
name = Profile for creating development environment
|
3
3
|
includes = basic.ini
|
4
|
+
ssh_agent = on
|
4
5
|
|
5
6
|
[security]
|
6
7
|
# SYS_PTRACE is required by mesa and without this, the following warning can be seen:
|
@@ -8,16 +9,13 @@ includes = basic.ini
|
|
8
9
|
caps_add = SYS_PTRACE
|
9
10
|
|
10
11
|
[mounts]
|
12
|
+
# export the host's ssh keys for use by ssh-agent in the container as required ("ro" mode
|
13
|
+
# implies that known_hosts and other files within ~/.ssh cannot be changed)
|
14
|
+
ssh = $HOME/.ssh:$TARGET_HOME/.ssh:ro
|
11
15
|
# add your projects and other directories having source code
|
12
16
|
#projects = $HOME/projects:$TARGET_HOME/projects
|
13
17
|
#pyenv = $HOME/.pyenv:$TARGET_HOME/.pyenv:ro
|
14
18
|
|
15
|
-
[env]
|
16
|
-
# always pretend desktop to be GNOME since KDE apps required by xdg-* are not installed
|
17
|
-
XDG_CURRENT_DESKTOP = GNOME
|
18
|
-
XDG_SESSION_DESKTOP = GNOME
|
19
|
-
DESKTOP_SESSION = gnome
|
20
|
-
|
21
19
|
[apps]
|
22
20
|
# some packages for Arch Linux - uncomment and update for your distribution as required
|
23
21
|
#ides = intellij-idea-community-edition-jre,visual-studio-code-bin,zed
|
@@ -28,5 +28,5 @@ echo_color "$fg_purple" "Copying data from container to shared root mounted on '
|
|
28
28
|
IFS="," read -ra shared_dirs_arr <<< "$shared_dirs"
|
29
29
|
for dir in "${shared_dirs_arr[@]}"; do
|
30
30
|
echo_color "$fg_orange" "Copying $dir to $shared_bind$dir"
|
31
|
-
cp -
|
31
|
+
cp -an "$dir" "$shared_bind$dir"
|
32
32
|
done
|
@@ -8,10 +8,11 @@ SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
8
8
|
|
9
9
|
source "$SCRIPT_DIR/entrypoint-common.sh"
|
10
10
|
|
11
|
+
export HOME=/root
|
11
12
|
echo_color "$fg_cyan" "Copying prime-run, run-in-dir and run-user-bash-cmd" >> $status_file
|
12
|
-
cp -
|
13
|
-
cp -
|
14
|
-
cp -
|
13
|
+
cp -af "$SCRIPT_DIR/prime-run" /usr/local/bin/prime-run
|
14
|
+
cp -af "$SCRIPT_DIR/run-in-dir" /usr/local/bin/run-in-dir
|
15
|
+
cp -af "$SCRIPT_DIR/run-user-bash-cmd" /usr/local/bin/run-user-bash-cmd
|
15
16
|
chmod 0755 /usr/local/bin/prime-run /usr/local/bin/run-in-dir /usr/local/bin/run-user-bash-cmd
|
16
17
|
|
17
18
|
# invoke the NVIDIA setup script if present
|
@@ -13,9 +13,11 @@ mkdir -p "$user_home/.gnupg" && chmod 0700 "$user_home/.gnupg"
|
|
13
13
|
echo "keyserver $DEFAULT_GPG_KEY_SERVER" > "$user_home/.gnupg/dirmngr.conf"
|
14
14
|
rm -f "$user_home"/.gnupg/*/*.lock
|
15
15
|
|
16
|
-
|
17
|
-
|
18
|
-
|
16
|
+
if [ ! -e "$user_home/.config/pip/pip.conf" ]; then
|
17
|
+
echo_color "$fg_cyan" "Enabling python pip installation for $current_user" >> $status_file
|
18
|
+
mkdir -p "$user_home/.config/pip"
|
19
|
+
cat > "$user_home/.config/pip/pip.conf" << EOF
|
19
20
|
[global]
|
20
21
|
break-system-packages = true
|
21
22
|
EOF
|
23
|
+
fi
|
@@ -22,7 +22,7 @@ echo -n > $status_file
|
|
22
22
|
# the current user as well as the group of the normal user
|
23
23
|
uid="$(id -u)"
|
24
24
|
gid="$(id -g)"
|
25
|
-
chown $uid:$YBOX_HOST_GID $status_file
|
25
|
+
chown $uid:${YBOX_HOST_GID:-$gid} $status_file
|
26
26
|
chmod 0660 $status_file
|
27
27
|
if [ "$uid" -eq 0 ]; then
|
28
28
|
SUDO=""
|
@@ -47,31 +47,22 @@ function show_usage() {
|
|
47
47
|
echo " -h show this help message and exit"
|
48
48
|
}
|
49
49
|
|
50
|
-
# link the configuration files in HOME to the target directory having the required files
|
51
|
-
function
|
50
|
+
# copy/link the configuration files in HOME to the target directory having the required files
|
51
|
+
function replicate_config_files() {
|
52
52
|
# line is of the form <src> -> <dest>; pattern below matches this while trimming spaces
|
53
53
|
echo_color "$fg_orange" "Linking configuration files from $config_dir to user's home" >> $status_file
|
54
|
-
pattern='(
|
54
|
+
pattern='(COPY|LINK_DIR|LINK):(.*)'
|
55
55
|
while read -r config; do
|
56
56
|
if [[ "$config" =~ $pattern ]]; then
|
57
|
-
home_file="${BASH_REMATCH[
|
58
|
-
# expand env variables
|
59
|
-
eval home_file="$home_file"
|
57
|
+
home_file="$HOME/${BASH_REMATCH[2]}"
|
60
58
|
dest_file="$config_dir/${BASH_REMATCH[2]}"
|
61
59
|
# only replace the file if it is already a link (assuming the link target may
|
62
|
-
# have changed in the config_list file), or a directory containing links
|
60
|
+
# have changed in the config_list file), or a directory containing only links
|
63
61
|
if [ -e "$dest_file" ]; then
|
64
62
|
if [ -L "$home_file" ]; then
|
65
63
|
rm -f "$home_file"
|
66
64
|
elif [ -d "$home_file" ]; then
|
67
|
-
|
68
|
-
for f in "$home_file"/*; do
|
69
|
-
if [ -e "$f" -a ! -L "$f" ]; then
|
70
|
-
do_rmdir=false
|
71
|
-
break
|
72
|
-
fi
|
73
|
-
done
|
74
|
-
if [ "$do_rmdir" = true ]; then
|
65
|
+
if [ -z $(find "$home_file" -type f -print -quit) ]; then
|
75
66
|
rm -rf "$home_file"
|
76
67
|
fi
|
77
68
|
fi
|
@@ -80,7 +71,15 @@ function link_config_files() {
|
|
80
71
|
mkdir -p "$home_filedir"
|
81
72
|
fi
|
82
73
|
if [ ! -e "$home_file" ]; then
|
83
|
-
|
74
|
+
if [ "${BASH_REMATCH[1]}" = "COPY" ]; then
|
75
|
+
cp -r "$dest_file" "$home_file"
|
76
|
+
elif [ "${BASH_REMATCH[1]}" = "LINK_DIR" ]; then
|
77
|
+
# if dest_file is a directory, then replicate the directory structure in home and
|
78
|
+
# symlink individual files which is accomplished with "cp -sr"
|
79
|
+
cp -sr "$dest_file" "$home_file"
|
80
|
+
else # "${BASH_REMATCH[1]}" = "LINK"
|
81
|
+
ln -s "$dest_file" "$home_file"
|
82
|
+
fi
|
84
83
|
fi
|
85
84
|
fi
|
86
85
|
else
|
@@ -180,7 +179,7 @@ run_dir=${XDG_RUNTIME_DIR:-/run/user/$uid}
|
|
180
179
|
if [ -d $run_dir ]; then
|
181
180
|
$SUDO chown $uid:$gid $run_dir 2>/dev/null || true
|
182
181
|
fi
|
183
|
-
if
|
182
|
+
if compgen -G "$run_dir/*" >/dev/null; then
|
184
183
|
$SUDO chown $uid:$gid $run_dir/* 2>/dev/null || true
|
185
184
|
fi
|
186
185
|
|
@@ -212,7 +211,7 @@ fi
|
|
212
211
|
|
213
212
|
# process config files, application installs and invoke startup apps
|
214
213
|
if [ -n "$config_list" ]; then
|
215
|
-
|
214
|
+
replicate_config_files
|
216
215
|
fi
|
217
216
|
if [ -n "$app_list" ]; then
|
218
217
|
install_apps
|
@@ -231,14 +230,17 @@ function cleanup() {
|
|
231
230
|
# clear status file first just in case other operations do not finish before SIGKILL comes
|
232
231
|
echo -n > $status_file
|
233
232
|
# first send SIGTERM to all "docker exec" processes that will have parent PID as 0 or 1
|
233
|
+
kill_sent=0
|
234
234
|
exec_pids="$(ps -e -o ppid=,pid= | \
|
235
235
|
awk '{ if (($1 == 0 || $1 == 1) && $2 != 1 && $2 != '$childPID') print $2 }')"
|
236
236
|
for pid in $exec_pids; do
|
237
|
-
|
238
|
-
|
237
|
+
if kill -TERM $pid 2>/dev/null; then
|
238
|
+
kill_sent=1
|
239
|
+
echo "Sent SIGTERM to $pid"
|
240
|
+
fi
|
239
241
|
done
|
240
242
|
# sleep a bit for $exec_pids to finish
|
241
|
-
[ -
|
243
|
+
[ $kill_sent -eq 1 ] && sleep 3
|
242
244
|
# lastly kill the infinite tail process
|
243
245
|
kill -TERM $childPID
|
244
246
|
}
|
ybox/conf/resources/prime-run
CHANGED
ybox/conf/resources/run-in-dir
CHANGED
@@ -9,24 +9,34 @@ if [ -n "$dir" -a -d "$dir" ]; then
|
|
9
9
|
cd "$dir"
|
10
10
|
fi
|
11
11
|
|
12
|
-
# XAUTHORITY
|
13
|
-
# by podman/docker exec in the mount point of its parent directory
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
12
|
+
# XAUTHORITY, SSH_AUTH_SOCK and GPG_AGENT_INFO files can change after a re-login or a restart,
|
13
|
+
# so search for the passed one by podman/docker exec in the mount point of its parent directory
|
14
|
+
for env_var in XAUTHORITY SSH_AUTH_SOCK GPG_AGENT_INFO; do
|
15
|
+
env_var_orig=${env_var}_ORIG
|
16
|
+
var_val=${!env_var}
|
17
|
+
var_val_orig=${!env_var_orig}
|
18
|
+
if [ -n "$var_val" -a -n "$var_val_orig" ]; then
|
19
|
+
if [ ! -r "$var_val" ]; then
|
20
|
+
# the value should be in /run/user/<uid> or in /tmp, or else the parent directory is used
|
21
|
+
run_dir="${XDG_RUNTIME_DIR:-/run/user/$(id -u)}"
|
22
|
+
if [[ "$var_val" == $run_dir/* ]]; then
|
23
|
+
host_dir="$run_dir"
|
24
|
+
elif [[ "$var_val" == /tmp/* ]]; then
|
25
|
+
host_dir=/tmp
|
26
|
+
else
|
27
|
+
host_dir="$(dirname "$var_val")"
|
28
|
+
fi
|
29
|
+
new_val="${var_val/#$host_dir/${host_dir}-host}" # replace $host_dir by ${host_dir}-host
|
30
|
+
if [ ! -r "$new_val" ]; then
|
31
|
+
new_val="$var_val_orig"
|
32
|
+
fi
|
33
|
+
export $env_var="$new_val"
|
34
|
+
fi
|
21
35
|
else
|
22
|
-
|
23
|
-
|
24
|
-
XAUTHORITY="${XAUTHORITY/#$host_dir/${host_dir}-host}" # replace $host_dir by ${host_dir}-host
|
25
|
-
if [ ! -r "$XAUTHORITY" ]; then
|
26
|
-
XAUTHORITY="$XAUTHORITY_ORIG"
|
36
|
+
# remove unset variable in the container else apps can misbehave
|
37
|
+
unset $env_var
|
27
38
|
fi
|
28
|
-
|
29
|
-
fi
|
39
|
+
done
|
30
40
|
|
31
41
|
# In case NVIDIA driver has been updated, the updated libraries and other files may need to be
|
32
42
|
# linked again, so check for a missing library file and invoke the setup script if present
|
@@ -49,6 +59,7 @@ if [ -e "$nvidia_setup" ]; then
|
|
49
59
|
flock -x -w 60 $lock_fd || /bin/true
|
50
60
|
trap "flock -u $lock_fd || /bin/true" 0 1 2 3 4 5 6 7 8 10 11 12 13 14 15
|
51
61
|
if ! is_nvidia_valid; then
|
62
|
+
# set umask for root execution to ensure that other users have read/execute permissions
|
52
63
|
umask 022
|
53
64
|
sudo /bin/bash "$nvidia_setup" || /bin/true
|
54
65
|
fi
|
@@ -57,4 +68,7 @@ if [ -e "$nvidia_setup" ]; then
|
|
57
68
|
fi
|
58
69
|
fi
|
59
70
|
|
71
|
+
# reset to more conservative umask setting
|
72
|
+
umask 027
|
73
|
+
|
60
74
|
exec "$@"
|
@@ -1,5 +1,11 @@
|
|
1
1
|
#!/bin/bash
|
2
2
|
|
3
|
+
# This script either runs a given command using bash directly, or if YBOX_HOST_UID environment
|
4
|
+
# variable is set to something other than the UID of the current user, then uses sudo to run
|
5
|
+
# the command as that UID (plus YBOX_HOST_GID as the GID). This latter case happens for rootless
|
6
|
+
# docker where the ybox container runs as the root user (due to absence of --userns=keep-id like
|
7
|
+
# in podman) but some commands need to be run as a normal user like Arch's paru/yay AUR helpers.
|
8
|
+
|
3
9
|
set -e
|
4
10
|
|
5
11
|
if [ "$#" -ne 1 ]; then
|
@@ -8,7 +14,17 @@ if [ "$#" -ne 1 ]; then
|
|
8
14
|
fi
|
9
15
|
|
10
16
|
if [ "$(id -u)" -eq 0 -a -n "$YBOX_HOST_UID" ] && getent passwd $YBOX_HOST_UID > /dev/null; then
|
11
|
-
|
17
|
+
sudo -u "#$YBOX_HOST_UID" -g "#$YBOX_HOST_GID" /bin/bash -c "$1"
|
18
|
+
status=$?
|
19
|
+
if [ $status -ne 0 ]; then
|
20
|
+
echo "FAILED (exit code = $status) in sudo execution of: $1"
|
21
|
+
exit $status
|
22
|
+
fi
|
12
23
|
else
|
13
24
|
eval "$1"
|
25
|
+
status=$?
|
26
|
+
if [ $status -ne 0 ]; then
|
27
|
+
echo "FAILED (exit code = $status) in execution of: $1"
|
28
|
+
exit $status
|
29
|
+
fi
|
14
30
|
fi
|
@@ -0,0 +1,24 @@
|
|
1
|
+
# ybox-{name}.service
|
2
|
+
#
|
3
|
+
# Autogenerated by ybox-create {version} on {date}
|
4
|
+
|
5
|
+
[Unit]
|
6
|
+
Description={manager_name} ybox-{name}.service
|
7
|
+
Wants=network-online.target
|
8
|
+
After=network-online.target
|
9
|
+
{docker_requires}
|
10
|
+
[Service]
|
11
|
+
Environment=PATH={sys_path}:{ybox_bin_dir}
|
12
|
+
EnvironmentFile=%h/.config/systemd/user/{env_file}
|
13
|
+
Type=notify
|
14
|
+
NotifyAccess=all
|
15
|
+
Restart=on-failure
|
16
|
+
# sleep to allow for initialization of the user's login/graphical environment
|
17
|
+
ExecStartPre=/usr/bin/sleep $SLEEP_SECS
|
18
|
+
ExecStart=/bin/sh -c 'ybox-control start {name} && systemd-notify --ready && exec ybox-control wait {name}'
|
19
|
+
ExecStop=/bin/sh -c 'ybox-control stop -t 20 --ignore-stopped {name}'
|
20
|
+
ExecStopPost=/bin/sh -c 'ybox-control stop -t 20 --ignore-stopped {name}'
|
21
|
+
TimeoutStopSec=60
|
22
|
+
|
23
|
+
[Install]
|
24
|
+
WantedBy=default.target
|
ybox/config.py
CHANGED
@@ -142,6 +142,9 @@ class Consts:
|
|
142
142
|
Defines fixed file/path and other names used by ybox that are not configurable.
|
143
143
|
"""
|
144
144
|
|
145
|
+
# standard system executable paths
|
146
|
+
_SYS_BIN_DIRS = ("/usr/bin", "/bin", "/usr/sbin", "/sbin", "/usr/local/bin", "/usr/local/sbin")
|
147
|
+
# regex pattern to match all manual page directories
|
145
148
|
_MAN_DIRS_PATTERN = re.compile(r"/usr(/local)?(/share)?/man(/[^/]*)?/man[0-9][a-zA-Z_]*")
|
146
149
|
|
147
150
|
@staticmethod
|
@@ -216,13 +219,18 @@ class Consts:
|
|
216
219
|
@staticmethod
|
217
220
|
def container_bin_dirs() -> Iterable[str]:
|
218
221
|
"""directories on the container that has executables that may need to be wrapped"""
|
219
|
-
return
|
222
|
+
return Consts._SYS_BIN_DIRS
|
220
223
|
|
221
224
|
@staticmethod
|
222
225
|
def container_man_dir_pattern() -> re.Pattern[str]:
|
223
226
|
"""directory regex pattern on the container having man-pages that may need to be linked"""
|
224
227
|
return Consts._MAN_DIRS_PATTERN
|
225
228
|
|
229
|
+
@staticmethod
|
230
|
+
def sys_bin_dirs() -> Iterable[str]:
|
231
|
+
"""standard directories to search for system installed executables"""
|
232
|
+
return Consts._SYS_BIN_DIRS
|
233
|
+
|
226
234
|
@staticmethod
|
227
235
|
def nvidia_target_base_dir() -> str:
|
228
236
|
"""base directory path where NVIDIA libs/data are linked in the container"""
|