ybox 0.9.8__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.
Files changed (76) hide show
  1. ybox/__init__.py +2 -0
  2. ybox/cmd.py +307 -0
  3. ybox/conf/completions/ybox.fish +93 -0
  4. ybox/conf/distros/arch/add-gpg-key.sh +29 -0
  5. ybox/conf/distros/arch/distro.ini +192 -0
  6. ybox/conf/distros/arch/init-base.sh +10 -0
  7. ybox/conf/distros/arch/init-user.sh +35 -0
  8. ybox/conf/distros/arch/init.sh +82 -0
  9. ybox/conf/distros/arch/list_fmt_long.py +76 -0
  10. ybox/conf/distros/arch/pkgdeps.py +276 -0
  11. ybox/conf/distros/deb-generic/check-package.sh +77 -0
  12. ybox/conf/distros/deb-generic/distro.ini +190 -0
  13. ybox/conf/distros/deb-generic/fetch-gpg-key-id.sh +30 -0
  14. ybox/conf/distros/deb-generic/init-base.sh +11 -0
  15. ybox/conf/distros/deb-generic/init-user.sh +3 -0
  16. ybox/conf/distros/deb-generic/init.sh +136 -0
  17. ybox/conf/distros/deb-generic/list_fmt_long.py +114 -0
  18. ybox/conf/distros/deb-generic/pkgdeps.py +208 -0
  19. ybox/conf/distros/deb-oldstable/distro.ini +21 -0
  20. ybox/conf/distros/deb-stable/distro.ini +21 -0
  21. ybox/conf/distros/supported.list +5 -0
  22. ybox/conf/distros/ubuntu2204/distro.ini +21 -0
  23. ybox/conf/distros/ubuntu2404/distro.ini +21 -0
  24. ybox/conf/profiles/apps.ini +26 -0
  25. ybox/conf/profiles/basic.ini +310 -0
  26. ybox/conf/profiles/dev.ini +25 -0
  27. ybox/conf/profiles/games.ini +39 -0
  28. ybox/conf/resources/entrypoint-base.sh +170 -0
  29. ybox/conf/resources/entrypoint-common.sh +23 -0
  30. ybox/conf/resources/entrypoint-cp.sh +32 -0
  31. ybox/conf/resources/entrypoint-root.sh +20 -0
  32. ybox/conf/resources/entrypoint-user.sh +21 -0
  33. ybox/conf/resources/entrypoint.sh +249 -0
  34. ybox/conf/resources/prime-run +13 -0
  35. ybox/conf/resources/run-in-dir +60 -0
  36. ybox/conf/resources/run-user-bash-cmd +14 -0
  37. ybox/config.py +255 -0
  38. ybox/env.py +205 -0
  39. ybox/filelock.py +77 -0
  40. ybox/migrate/0.9.0-0.9.7:0.9.8.py +33 -0
  41. ybox/pkg/__init__.py +0 -0
  42. ybox/pkg/clean.py +33 -0
  43. ybox/pkg/info.py +40 -0
  44. ybox/pkg/inst.py +638 -0
  45. ybox/pkg/list.py +191 -0
  46. ybox/pkg/mark.py +68 -0
  47. ybox/pkg/repair.py +150 -0
  48. ybox/pkg/repo.py +251 -0
  49. ybox/pkg/search.py +52 -0
  50. ybox/pkg/uninst.py +92 -0
  51. ybox/pkg/update.py +56 -0
  52. ybox/print.py +121 -0
  53. ybox/run/__init__.py +0 -0
  54. ybox/run/cmd.py +54 -0
  55. ybox/run/control.py +102 -0
  56. ybox/run/create.py +1116 -0
  57. ybox/run/destroy.py +64 -0
  58. ybox/run/graphics.py +367 -0
  59. ybox/run/logs.py +57 -0
  60. ybox/run/ls.py +64 -0
  61. ybox/run/pkg.py +445 -0
  62. ybox/schema/0.9.1-added.sql +27 -0
  63. ybox/schema/0.9.6-added.sql +18 -0
  64. ybox/schema/init.sql +39 -0
  65. ybox/schema/migrate/0.9.0:0.9.1.sql +42 -0
  66. ybox/schema/migrate/0.9.1:0.9.2.sql +8 -0
  67. ybox/schema/migrate/0.9.2:0.9.3.sql +2 -0
  68. ybox/schema/migrate/0.9.5:0.9.6.sql +2 -0
  69. ybox/state.py +914 -0
  70. ybox/util.py +351 -0
  71. ybox-0.9.8.dist-info/LICENSE +19 -0
  72. ybox-0.9.8.dist-info/METADATA +533 -0
  73. ybox-0.9.8.dist-info/RECORD +76 -0
  74. ybox-0.9.8.dist-info/WHEEL +5 -0
  75. ybox-0.9.8.dist-info/entry_points.txt +8 -0
  76. ybox-0.9.8.dist-info/top_level.txt +1 -0
@@ -0,0 +1,25 @@
1
+ [base]
2
+ name = Profile for creating development environment
3
+ includes = basic.ini
4
+
5
+ [security]
6
+ # SYS_PTRACE is required by mesa and without this, the following warning can be seen:
7
+ # WARNING: Kernel has no file descriptor comparison support: Operation not permitted
8
+ caps_add = SYS_PTRACE
9
+
10
+ [mounts]
11
+ # add your projects and other directories having source code
12
+ #projects = $HOME/projects:$TARGET_HOME/projects
13
+ #pyenv = $HOME/.pyenv:$TARGET_HOME/.pyenv:ro
14
+
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
+ [apps]
22
+ # some packages for Arch Linux - uncomment and update for your distribution as required
23
+ #ides = intellij-idea-community-edition-jre,visual-studio-code-bin,zed
24
+ #others = aws-cli-bin,aws-session-manager-plugin,helm,kubectl,yq,github-cli,jdk17-openjdk
25
+ #other_deps = gnome-keyring:dep(github-cli)
@@ -0,0 +1,39 @@
1
+ [base]
2
+ name = Profile for games and other apps requiring NVIDIA acceleration
3
+ includes = basic.ini
4
+ nvidia = on
5
+
6
+ [security]
7
+ # Steam uses bwrap which needs capability to create new namespaces etc that apparently
8
+ # gives greater security. More details here:
9
+ # https://github.com/ValveSoftware/steam-runtime/issues/297#issuecomment-723004767
10
+ # This is apparently no longer required after adding "--user=1000:1000"
11
+ # or with setpriv/capsh dropping ambient capabilities
12
+ #caps_add = SYS_ADMIN,SYS_CHROOT,NET_ADMIN,SETUID,SETGID,SYS_PTRACE
13
+
14
+ # SYS_PTRACE is required by mesa and without this, the following warning can be seen:
15
+ # WARNING: Kernel has no file descriptor comparison support: Operation not permitted
16
+ caps_add = SYS_PTRACE
17
+
18
+ [mounts]
19
+ video_dev = /dev/video0:/dev/video0
20
+
21
+ [env]
22
+ NVIDIA_DRIVER_CAPABILITIES = all
23
+
24
+ [apps]
25
+ # steam and deps for Arch Linux - uncomment and update for your distribution as required
26
+ #steam_deps = lib32-vulkan-intel:dep(steam),lib32-libpulse:dep(steam)
27
+ # these are apparently required but not in the upstream deps
28
+ # https://bugs.archlinux.org/task/74827, https://bugs.archlinux.org/task/75155
29
+ # https://bugs.archlinux.org/task/75443, https://bugs.archlinux.org/task/75590,
30
+ # https://bugs.archlinux.org/task/75156, https://bugs.archlinux.org/task/75157
31
+ # some packages among above are skipped because they are already direct/indirect dependencies
32
+ #steam_opt_deps = lib32-fontconfig:dep(steam),lib32-pipewire:dep(steam),lib32-libxcursor:dep(steam),
33
+ # lib32-libva:dep(steam),lib32-libnm:dep(steam),lib32-libxinerama:dep(steam)
34
+ #steam = steam
35
+
36
+ [app_flags]
37
+ # steam needs setpriv or equivalent to allow user namespace to be used by bubblewrap
38
+ steam = /usr/bin/setpriv --ambient-caps -all !p !a
39
+ steam-runtime = /usr/bin/setpriv --ambient-caps -all !p !a
@@ -0,0 +1,170 @@
1
+ #!/bin/bash
2
+
3
+ set -e
4
+
5
+ SCRIPT="$(basename "${BASH_SOURCE[0]}")"
6
+ SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
7
+
8
+ source "$SCRIPT_DIR/entrypoint-common.sh"
9
+
10
+ user=ybox
11
+ uid=1000
12
+ name=ybox
13
+ group=ybox
14
+ gid=1000
15
+ secondary_groups=video,input,lp,mail
16
+ localtime=
17
+ timezone=
18
+
19
+ function show_usage() {
20
+ echo
21
+ echo "Usage: $SCRIPT [-u USER] [-U UID] [-n FULLNAME] [-g GROUP] [-G GID]"
22
+ echo " [-l LOCALTIME] [-z TIMEZONE] [-h]"
23
+ echo
24
+ echo "Options:"
25
+ echo " -u USER login of the user being added"
26
+ echo " -U UID UID of the user"
27
+ echo " -n FULLNAME full name of the user"
28
+ echo " -g GROUP primary group of the user being added"
29
+ echo " -G GID GID of the primary group of the user"
30
+ echo " -s GROUPS secondary groups of the user being added"
31
+ echo " -l LOCALTIME the destination link for /etc/localtime"
32
+ echo " -z TIMEZONE the timezone to be written in /etc/timezone"
33
+ echo " -h show this help message and exit"
34
+ }
35
+
36
+ function check_space() {
37
+ check_val="$1"
38
+ if [[ "$check_val" = *[[:space:]]* ]]; then
39
+ echo "$0: cannot have white space character in $2 -- $check_val"
40
+ show_usage
41
+ exit 1
42
+ fi
43
+ }
44
+
45
+ function check_int() {
46
+ check_val="$1"
47
+ if ! [ "$check_val" -eq "$check_val" ] 2>/dev/null; then
48
+ echo "$0: expected integer for $2 -- $check_val"
49
+ show_usage
50
+ exit 1
51
+ fi
52
+ }
53
+
54
+ while getopts "u:U:n:g:G:s:l:z:h" opt; do
55
+ case "$opt" in
56
+ u)
57
+ check_space "$OPTARG" USER
58
+ user=$OPTARG
59
+ ;;
60
+ U)
61
+ check_int "$OPTARG" UID
62
+ uid=$OPTARG
63
+ ;;
64
+ n)
65
+ name="$OPTARG"
66
+ ;;
67
+ g)
68
+ check_space "$OPTARG" GROUP
69
+ group=$OPTARG
70
+ ;;
71
+ G)
72
+ check_int "$OPTARG" GID
73
+ gid=$OPTARG
74
+ ;;
75
+ s)
76
+ check_space "$OPTARG" GROUPS
77
+ secondary_groups=$OPTARG
78
+ ;;
79
+ l)
80
+ localtime="$OPTARG"
81
+ ;;
82
+ z)
83
+ timezone="$OPTARG"
84
+ ;;
85
+ h)
86
+ show_usage
87
+ exit 0
88
+ ;;
89
+ ?)
90
+ show_usage
91
+ exit 1
92
+ ;;
93
+ esac
94
+ done
95
+
96
+ # run the distribution specific initialization scripts
97
+ if [ -r "$SCRIPT_DIR/init-base.sh" ]; then
98
+ /bin/bash "$SCRIPT_DIR/init-base.sh" >/dev/null
99
+ fi
100
+
101
+ # setup timezone
102
+ if [ -n "$localtime" ]; then
103
+ echo_color "$fg_blue" "Setting up timezone to $localtime"
104
+ if [ -e "$localtime" ]; then
105
+ rm -f /etc/localtime
106
+ ln -s "$localtime" /etc/localtime
107
+ fi
108
+ fi
109
+ if [ -n "$timezone" ]; then
110
+ echo "$timezone" > /etc/timezone
111
+ chmod 0644 /etc/timezone
112
+ fi
113
+
114
+ # add the user with the same UID/GID as provided which should normally be the same as the
115
+ # user running this ybox (which avoids --userns=keep-id from increasing the image size
116
+ # else the image size may get nearly doubled)
117
+ existing_user="$(getent passwd $uid | cut -d: -f1)"
118
+ if [ -n "$existing_user" ]; then
119
+ deluser --remove-home $existing_user
120
+ fi
121
+ existing_group="$(getent group $gid | cut -d: -f1)"
122
+ if [ -n "$existing_group" ]; then
123
+ delgroup $existing_group
124
+ fi
125
+ groupadd -g $gid $group
126
+ echo_color "$fg_blue" "Added group '$group'"
127
+ useradd -m -g $group -G $secondary_groups \
128
+ -u $uid -d /home/$user -s /bin/bash -c "$name" $user
129
+ usermod --lock $user
130
+
131
+ # add the given user for sudoers with NOPASSWD
132
+ sudoers_file=/etc/sudoers.d/$user
133
+ echo "$user ALL=(ALL:ALL) NOPASSWD: ALL" > $sudoers_file
134
+ chmod 0440 $sudoers_file
135
+ echo_color "$fg_purple" "Added admin user '$user' to sudoers with NOPASSWD"
136
+
137
+ # generate /etc/machine-id which is required by some apps
138
+ rm -f /etc/machine-id /var/lib/dbus/machine-id
139
+ dbus-uuidgen --ensure=/etc/machine-id
140
+ dbus-uuidgen --ensure
141
+
142
+ # change ownership of user's /run/user/<uid> tree which may have root ownership due to the
143
+ # docker bind mounts
144
+ run_dir=${XDG_RUNTIME_DIR:-/run/user/$uid}
145
+ mkdir -p $run_dir
146
+ chmod 0700 $run_dir
147
+ chown -Rf $uid:$gid $run_dir
148
+ echo_color "$fg_blue" "Created run directory for '$user' with proper permissions"
149
+
150
+ # add root user to all user groups for rootless docker that needs to run as the root user
151
+ # (which is mapped to the host's current user allowing for proper file and other permissions)
152
+ usermod -aG $group,$secondary_groups root
153
+ # the home directory of root user should be /root which is assumed to be the target directory
154
+ # by the ybox commands when using docker
155
+ root_home="$(getent passwd root | cut -d: -f6)"
156
+ if [ "$root_home" != "/root" ]; then
157
+ echo_color "$fg_purple" "Changing home directory of root user from '$root_home' to '/root'"
158
+ # this should be done at the very end of the entrypoint script to avoid any complications
159
+ # due to change of root user's home directory in the middle of running commands
160
+ mkdir -p /root
161
+ chmod 700 /root
162
+ sed -i "s|:$root_home:|:/root:|" /etc/passwd
163
+ if [ "$root_home" != "/" ]; then
164
+ cd "$root_home"
165
+ # copy dotfiles skipping `.` and `..` which is done by setting GLOBIGNORE
166
+ export GLOBIGNORE=.
167
+ cp -a .* /root/.
168
+ # not removing $root_home since it can potentially be some system directory (e.g. /usr)
169
+ fi
170
+ fi
@@ -0,0 +1,23 @@
1
+ # ensure that system path is always searched first for all the system utilities
2
+ export PATH="/usr/sbin:/usr/bin:/sbin:/bin:$PATH"
3
+
4
+ status_file=/usr/local/ybox-status
5
+
6
+ fg_red='\033[31m'
7
+ fg_green='\033[32m'
8
+ fg_orange='\033[33m'
9
+ fg_blue='\033[34m'
10
+ fg_purple='\033[35m'
11
+ fg_cyan='\033[36m'
12
+ fg_reset='\033[00m'
13
+
14
+ function echo_color() {
15
+ args=
16
+ while [[ $1 = -* ]]; do
17
+ args="$args $1"
18
+ shift
19
+ done
20
+ color="$1"
21
+ shift
22
+ echo -e $args "$color$@" $fg_reset
23
+ }
@@ -0,0 +1,32 @@
1
+ #!/bin/bash
2
+
3
+ set -e
4
+
5
+ SCRIPT="$(basename "${BASH_SOURCE[0]}")"
6
+ SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
7
+
8
+ source "$SCRIPT_DIR/entrypoint-common.sh"
9
+
10
+ function show_usage() {
11
+ echo
12
+ echo "Usage: $SCRIPT SHARED_DIRS SHARED_BIND"
13
+ echo
14
+ echo "Arguments:"
15
+ echo " SHARED_DIRS comma separated list of directories to share among containers"
16
+ echo " SHARED_BIND shared bind mount where the DIRS above will be copied"
17
+ }
18
+
19
+ if [ $# -ne 2 ]; then
20
+ show_usage
21
+ exit 1
22
+ fi
23
+
24
+ shared_dirs="$1"
25
+ shared_bind="$2"
26
+
27
+ echo_color "$fg_purple" "Copying data from container to shared root mounted on '$shared_bind'"
28
+ IFS="," read -ra shared_dirs_arr <<< "$shared_dirs"
29
+ for dir in "${shared_dirs_arr[@]}"; do
30
+ echo_color "$fg_orange" "Copying $dir to $shared_bind$dir"
31
+ cp -a "$dir" "$shared_bind$dir"
32
+ done
@@ -0,0 +1,20 @@
1
+ #!/bin/bash
2
+
3
+ set -e
4
+
5
+ # this script has actions that need to be run as root
6
+
7
+ SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
8
+
9
+ source "$SCRIPT_DIR/entrypoint-common.sh"
10
+
11
+ echo_color "$fg_cyan" "Copying prime-run, run-in-dir and run-user-bash-cmd" >> $status_file
12
+ cp -a "$SCRIPT_DIR/prime-run" /usr/local/bin/prime-run
13
+ cp -a "$SCRIPT_DIR/run-in-dir" /usr/local/bin/run-in-dir
14
+ cp -a "$SCRIPT_DIR/run-user-bash-cmd" /usr/local/bin/run-user-bash-cmd
15
+ chmod 0755 /usr/local/bin/prime-run /usr/local/bin/run-in-dir /usr/local/bin/run-user-bash-cmd
16
+
17
+ # invoke the NVIDIA setup script if present
18
+ if [ -r "$SCRIPT_DIR/nvidia-setup.sh" ]; then
19
+ /bin/bash "$SCRIPT_DIR/nvidia-setup.sh"
20
+ fi
@@ -0,0 +1,21 @@
1
+ #!/bin/bash
2
+
3
+ set -e
4
+
5
+ SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
6
+
7
+ source "$SCRIPT_DIR/entrypoint-common.sh"
8
+
9
+ current_user="$(id -un)"
10
+ user_home="$(getent passwd "$current_user" | cut -d: -f6)"
11
+ # set gpg keyserver to an available one
12
+ mkdir -p "$user_home/.gnupg" && chmod 0700 "$user_home/.gnupg"
13
+ echo "keyserver $DEFAULT_GPG_KEY_SERVER" > "$user_home/.gnupg/dirmngr.conf"
14
+ rm -f "$user_home"/.gnupg/*/*.lock
15
+
16
+ echo_color "$fg_cyan" "Enabling python pip installation for $current_user" >> $status_file
17
+ mkdir -p "$user_home/.config/pip"
18
+ cat > "$user_home/.config/pip/pip.conf" << EOF
19
+ [global]
20
+ break-system-packages = true
21
+ EOF
@@ -0,0 +1,249 @@
1
+ #!/bin/bash
2
+
3
+ set -e
4
+
5
+ SCRIPT="$(basename "${BASH_SOURCE[0]}")"
6
+ SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
7
+
8
+ source "$SCRIPT_DIR/entrypoint-common.sh"
9
+
10
+ config_list=
11
+ config_dir=
12
+ app_list=
13
+ pkgmgr_conf="$SCRIPT_DIR/pkgmgr.conf"
14
+ startup_list=
15
+ run_user_bash_cmd=/usr/local/bin/run-user-bash-cmd
16
+
17
+ # first clear the status_file
18
+ echo -n > $status_file
19
+
20
+ # for docker the container runs as root user but some actions need to be performed as normal
21
+ # user (like installing AUR packages in Arch), so the status file is made writable by both
22
+ # the current user as well as the group of the normal user
23
+ uid="$(id -u)"
24
+ gid="$(id -g)"
25
+ chown $uid:$YBOX_HOST_GID $status_file
26
+ chmod 0660 $status_file
27
+ if [ "$uid" -eq 0 ]; then
28
+ SUDO=""
29
+ else
30
+ SUDO="sudo -E"
31
+ fi
32
+
33
+ function show_usage() {
34
+ echo
35
+ echo "Usage: $SCRIPT [-c CONFIG_LIST] [-d CONFIG_DIR] [-a APP_LIST]"
36
+ echo " [-s STARTUP_LIST] [-h] BOX_NAME"
37
+ echo
38
+ echo "Arguments:"
39
+ echo " BOX_NAME name of the ybox container being created"
40
+ echo
41
+ echo "Options:"
42
+ echo " -c CONFIG_LIST file having list of configuration files to be setup in user's HOME"
43
+ echo " -d CONFIG_DIR target directory having the configuration files"
44
+ echo " -a APP_LIST file having list of applications to be installed"
45
+ echo " (each line should start with any additional package manager flags)"
46
+ echo " -s STARTUP_LIST file containing list of startup applications for the container"
47
+ echo " -h show this help message and exit"
48
+ }
49
+
50
+ # link the configuration files in HOME to the target directory having the required files
51
+ function link_config_files() {
52
+ # line is of the form <src> -> <dest>; pattern below matches this while trimming spaces
53
+ echo_color "$fg_orange" "Linking configuration files from $config_dir to user's home" >> $status_file
54
+ pattern='(.*[^[:space:]]+)[[:space:]]*->[[:space:]]*(.*)'
55
+ while read -r config; do
56
+ if [[ "$config" =~ $pattern ]]; then
57
+ home_file="${BASH_REMATCH[1]}"
58
+ # expand env variables
59
+ eval home_file="$home_file"
60
+ dest_file="$config_dir/${BASH_REMATCH[2]}"
61
+ # 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
63
+ if [ -e "$dest_file" ]; then
64
+ if [ -L "$home_file" ]; then
65
+ rm -f "$home_file"
66
+ elif [ -d "$home_file" ]; then
67
+ do_rmdir=true
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
75
+ rm -rf "$home_file"
76
+ fi
77
+ fi
78
+ home_filedir="$(dirname "$home_file")"
79
+ if [ ! -e "$home_filedir" ]; then
80
+ mkdir -p "$home_filedir"
81
+ fi
82
+ if [ ! -e "$home_file" ]; then
83
+ ln -s "$dest_file" "$home_file"
84
+ fi
85
+ fi
86
+ else
87
+ echo_color "$fg_red" "Skipping config line having unknown format: $config" >> $status_file
88
+ fi
89
+ done < "$config_list"
90
+ }
91
+
92
+ # install applications listed in the given file with the configured package manager commands
93
+ function install_apps() {
94
+ # source PKGMGR_* variables from the configuration file created by 'ybox-create'
95
+ source "$pkgmgr_conf"
96
+ if [ -z "$PKGMGR_INSTALL" -o -z "$PKGMGR_CLEAN" ]; then
97
+ echo_color "$fg_red" "$pkgmgr_conf should define PKGMGR_INSTALL and PKGMGR_CLEAN" >> $status_file
98
+ exit 1
99
+ fi
100
+ # install packages line by line
101
+ while read -r pkg_line; do
102
+ echo_color "$fg_orange" "Installing: ${pkg_line:0:40} ..." >> $status_file
103
+ $run_user_bash_cmd "$PKGMGR_INSTALL $pkg_line"
104
+ echo_color "$fg_green" "Done." >> $status_file
105
+ done < "$app_list"
106
+ echo_color "$fg_green" "Cleaning up." >> $status_file
107
+ $run_user_bash_cmd "$PKGMGR_CLEAN"
108
+ }
109
+
110
+ # invoke the startup apps as listed in the container configuration file
111
+ function invoke_startup_apps() {
112
+ log_dir="$HOME/.local/share/ybox/logs"
113
+ log_no=1
114
+ # start apps in the order listed in the file
115
+ while read -r app_line; do
116
+ mkdir -p "$log_dir"
117
+ echo_color "$fg_orange" "Starting: ${app_line:0:40} ..." >> $status_file
118
+ nohup $app_line >> "$log_dir/app-${log_no}_out.log" 2>> "$log_dir/app-${log_no}_err.log" &
119
+ sleep 1
120
+ done < "$startup_list"
121
+ }
122
+
123
+
124
+ while getopts "c:d:a:s:h" opt; do
125
+ case "$opt" in
126
+ c)
127
+ config_list="$OPTARG"
128
+ ;;
129
+ d)
130
+ config_dir="$OPTARG"
131
+ ;;
132
+ a)
133
+ app_list="$OPTARG"
134
+ # assume package manager configuration to be in pkgmgr.conf in same dir as this script
135
+ if [ ! -r "$pkgmgr_conf" ]; then
136
+ echo "Cannot find $pkgmgr_conf to apply the given APP_LIST"
137
+ exit 1
138
+ fi
139
+ ;;
140
+ s)
141
+ startup_list="$OPTARG"
142
+ ;;
143
+ h)
144
+ show_usage
145
+ exit 0
146
+ ;;
147
+ ?)
148
+ show_usage
149
+ exit 1
150
+ ;;
151
+ esac
152
+ done
153
+
154
+ if [ -n "$config_list" -a -z "$config_dir" ]; then
155
+ echo "$0: missing '-d CONFIG_DIR' option for given CONFIG_LIST -- $config_list"
156
+ show_usage
157
+ exit 1
158
+ fi
159
+
160
+ # handle positional arguments
161
+ if [ $(("$#" - "$OPTIND")) -ne 0 ]; then
162
+ echo "$0: incorrect number of required arguments"
163
+ show_usage
164
+ exit 1
165
+ fi
166
+ box_name="${@:$OPTIND:1}"
167
+
168
+ # create/update some common directories that are mounted and may have root permissions
169
+ dir_init=". .cache .cache/fontconfig .config .config/pulse .local .local/share"
170
+ dir_init+=" .local/share/ybox .local/share/ybox/$box_name Downloads"
171
+ echo_color "$fg_orange" "Ensuring proper permissions for user directories" >> $status_file
172
+ for d in $dir_init; do
173
+ dir=$HOME/$d
174
+ $SUDO mkdir -p $dir || true
175
+ $SUDO chown $uid:$gid $dir || true
176
+ done
177
+ # change ownership of user's /run/user/<uid> tree which may have root ownership due to the
178
+ # docker bind mounts
179
+ run_dir=${XDG_RUNTIME_DIR:-/run/user/$uid}
180
+ if [ -d $run_dir ]; then
181
+ $SUDO chown $uid:$gid $run_dir 2>/dev/null || true
182
+ fi
183
+ if [ -n "$(ls $run_dir 2>/dev/null)" ]; then
184
+ $SUDO chown $uid:$gid $run_dir/* 2>/dev/null || true
185
+ fi
186
+
187
+ # run actions requiring root access
188
+ $SUDO /bin/bash "$SCRIPT_DIR/entrypoint-root.sh"
189
+
190
+ # run the distribution specific initialization scripts
191
+ if [ ! -e "$SCRIPT_DIR/ybox-init.done" ]; then
192
+ if [ -r "$SCRIPT_DIR/init.sh" ]; then
193
+ echo_color "$fg_orange" "Running distribution's system initialization script" >> $status_file
194
+ $SUDO /bin/bash "$SCRIPT_DIR/init.sh"
195
+ fi
196
+ if [ -r "$SCRIPT_DIR/init-user.sh" ]; then
197
+ echo_color "$fg_orange" "Running user initialization scripts" >> $status_file
198
+ # run the common user initialization script for both the root and non-root user
199
+ $SUDO /bin/bash "$SCRIPT_DIR/entrypoint-user.sh"
200
+ $run_user_bash_cmd "/bin/bash \"$SCRIPT_DIR/entrypoint-user.sh\""
201
+ # run the distribution's user initialization script for the non-root user
202
+ $run_user_bash_cmd "/bin/bash \"$SCRIPT_DIR/init-user.sh\""
203
+ fi
204
+ $SUDO rm -rf /root/.cache/*
205
+ # Update the status file to indicate the stoppage and exit because system libraries
206
+ # may have been installed/updated by the above scripts.
207
+ # Caller will restart the container after removing the init scripts.
208
+ echo stopped >> $status_file
209
+ sync $status_file
210
+ exit 0
211
+ fi
212
+
213
+ # process config files, application installs and invoke startup apps
214
+ if [ -n "$config_list" ]; then
215
+ link_config_files
216
+ fi
217
+ if [ -n "$app_list" ]; then
218
+ install_apps
219
+ fi
220
+ if [ -n "$startup_list" ]; then
221
+ invoke_startup_apps
222
+ fi
223
+ # update the status file to indicate successful startup
224
+ echo started >> $status_file
225
+
226
+ # finally go into infinite wait using tail on /dev/null but handle TERM signal for clean exit
227
+ tail -s10 -f /dev/null &
228
+ childPID=$!
229
+
230
+ function cleanup() {
231
+ # clear status file first just in case other operations do not finish before SIGKILL comes
232
+ echo -n > $status_file
233
+ # first send SIGTERM to all "docker exec" processes that will have parent PID as 0 or 1
234
+ exec_pids="$(ps -e -o ppid=,pid= | \
235
+ awk '{ if (($1 == 0 || $1 == 1) && $2 != 1 && $2 != '$childPID') print $2 }')"
236
+ for pid in $exec_pids; do
237
+ echo "Sending SIGTERM to $pid"
238
+ kill -TERM $pid
239
+ done
240
+ # sleep a bit for $exec_pids to finish
241
+ [ -n "$exec_pids" ] && sleep 3
242
+ # lastly kill the infinite tail process
243
+ kill -TERM $childPID
244
+ }
245
+
246
+ # truncate status file and cleanly kill the processes on SIGHUP and SIGTERM
247
+ trap "cleanup" 1 15
248
+
249
+ wait $childPID
@@ -0,0 +1,13 @@
1
+ #!/bin/sh
2
+
3
+ set -e
4
+
5
+ __NV_PRIME_RENDER_OFFLOAD=1
6
+ __GLX_VENDOR_LIBRARY_NAME=nvidia
7
+ __VK_LAYER_NV_optimus=NVIDIA_only
8
+ VK_ICD_FILES=/usr/share/vulkan/icd.d/nvidia_icd.json
9
+ VK_ICD_FILENAMES=/usr/share/vulkan/icd.d/nvidia_icd.json
10
+
11
+ export __NV_PRIME_RENDER_OFFLOAD __GLX_VENDOR_LIBRARY_NAME __VK_LAYER_NV_optimus VK_ICD_FILES VK_ICD_FILENAMES
12
+
13
+ exec "$@"
@@ -0,0 +1,60 @@
1
+ #!/bin/bash
2
+
3
+ set -e
4
+
5
+ dir="$1"
6
+ shift
7
+
8
+ if [ -n "$dir" -a -d "$dir" ]; then
9
+ cd "$dir"
10
+ fi
11
+
12
+ # XAUTHORITY file can change after a re-login or a restart, so search for the passed one
13
+ # by podman/docker exec in the mount point of its parent directory
14
+ if [ -n "$XAUTHORITY" -a -n "$XAUTHORITY_ORIG" -a ! -r "$XAUTHORITY" ]; then
15
+ # XAUTHORITY is assumed to be either in /run/user or in /tmp
16
+ run_dir="${XDG_RUNTIME_DIR:-/run/user/$(id -u)}"
17
+ if [[ "$XAUTHORITY" == $run_dir/* ]]; then
18
+ host_dir="$run_dir"
19
+ elif [[ "$XAUTHORITY" == /tmp/* ]]; then
20
+ host_dir=/tmp
21
+ else
22
+ host_dir="$(dirname "$XAUTHORITY")"
23
+ fi
24
+ XAUTHORITY="${XAUTHORITY/#$host_dir/${host_dir}-host}" # replace $host_dir by ${host_dir}-host
25
+ if [ ! -r "$XAUTHORITY" ]; then
26
+ XAUTHORITY="$XAUTHORITY_ORIG"
27
+ fi
28
+ export XAUTHORITY
29
+ fi
30
+
31
+ # In case NVIDIA driver has been updated, the updated libraries and other files may need to be
32
+ # linked again, so check for a missing library file and invoke the setup script if present
33
+ nvidia_setup="$YBOX_TARGET_SCRIPTS_DIR/nvidia-setup.sh"
34
+ if [ -e "$nvidia_setup" ]; then
35
+ function is_nvidia_valid() {
36
+ nvidia_glx_libs="$(echo /usr/local/nvidia/lib*/libGLX_nvidia.so.*)"
37
+ for lib in $nvidia_glx_libs; do
38
+ if [ ! -r "$lib" ]; then
39
+ return 1
40
+ fi
41
+ done
42
+ return 0
43
+ }
44
+ if ! is_nvidia_valid; then
45
+ lock_file="/tmp/nvidia-setup.lock"
46
+ (
47
+ # ensure no other instance is trying the same (wait for reasonable time before continuing)
48
+ lock_fd=100
49
+ flock -x -w 60 $lock_fd || /bin/true
50
+ trap "flock -u $lock_fd || /bin/true" 0 1 2 3 4 5 6 7 8 10 11 12 13 14 15
51
+ if ! is_nvidia_valid; then
52
+ umask 022
53
+ sudo /bin/bash "$nvidia_setup" || /bin/true
54
+ fi
55
+ ) 100>"$lock_file"
56
+ break
57
+ fi
58
+ fi
59
+
60
+ exec "$@"
@@ -0,0 +1,14 @@
1
+ #!/bin/bash
2
+
3
+ set -e
4
+
5
+ if [ "$#" -ne 1 ]; then
6
+ echo "Usage: $0 <full command to run as single argument like passed to '/bin/bash -c'>"
7
+ exit 1
8
+ fi
9
+
10
+ if [ "$(id -u)" -eq 0 -a -n "$YBOX_HOST_UID" ] && getent passwd $YBOX_HOST_UID > /dev/null; then
11
+ exec sudo -u "#$YBOX_HOST_UID" -g "#$YBOX_HOST_GID" /bin/bash -c "$1"
12
+ else
13
+ eval "$1"
14
+ fi