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.
- ybox/__init__.py +2 -0
- ybox/cmd.py +307 -0
- ybox/conf/completions/ybox.fish +93 -0
- ybox/conf/distros/arch/add-gpg-key.sh +29 -0
- ybox/conf/distros/arch/distro.ini +192 -0
- ybox/conf/distros/arch/init-base.sh +10 -0
- ybox/conf/distros/arch/init-user.sh +35 -0
- ybox/conf/distros/arch/init.sh +82 -0
- ybox/conf/distros/arch/list_fmt_long.py +76 -0
- ybox/conf/distros/arch/pkgdeps.py +276 -0
- ybox/conf/distros/deb-generic/check-package.sh +77 -0
- ybox/conf/distros/deb-generic/distro.ini +190 -0
- ybox/conf/distros/deb-generic/fetch-gpg-key-id.sh +30 -0
- ybox/conf/distros/deb-generic/init-base.sh +11 -0
- ybox/conf/distros/deb-generic/init-user.sh +3 -0
- ybox/conf/distros/deb-generic/init.sh +136 -0
- ybox/conf/distros/deb-generic/list_fmt_long.py +114 -0
- ybox/conf/distros/deb-generic/pkgdeps.py +208 -0
- ybox/conf/distros/deb-oldstable/distro.ini +21 -0
- ybox/conf/distros/deb-stable/distro.ini +21 -0
- ybox/conf/distros/supported.list +5 -0
- ybox/conf/distros/ubuntu2204/distro.ini +21 -0
- ybox/conf/distros/ubuntu2404/distro.ini +21 -0
- ybox/conf/profiles/apps.ini +26 -0
- ybox/conf/profiles/basic.ini +310 -0
- ybox/conf/profiles/dev.ini +25 -0
- ybox/conf/profiles/games.ini +39 -0
- ybox/conf/resources/entrypoint-base.sh +170 -0
- ybox/conf/resources/entrypoint-common.sh +23 -0
- ybox/conf/resources/entrypoint-cp.sh +32 -0
- ybox/conf/resources/entrypoint-root.sh +20 -0
- ybox/conf/resources/entrypoint-user.sh +21 -0
- ybox/conf/resources/entrypoint.sh +249 -0
- ybox/conf/resources/prime-run +13 -0
- ybox/conf/resources/run-in-dir +60 -0
- ybox/conf/resources/run-user-bash-cmd +14 -0
- ybox/config.py +255 -0
- ybox/env.py +205 -0
- ybox/filelock.py +77 -0
- ybox/migrate/0.9.0-0.9.7:0.9.8.py +33 -0
- ybox/pkg/__init__.py +0 -0
- ybox/pkg/clean.py +33 -0
- ybox/pkg/info.py +40 -0
- ybox/pkg/inst.py +638 -0
- ybox/pkg/list.py +191 -0
- ybox/pkg/mark.py +68 -0
- ybox/pkg/repair.py +150 -0
- ybox/pkg/repo.py +251 -0
- ybox/pkg/search.py +52 -0
- ybox/pkg/uninst.py +92 -0
- ybox/pkg/update.py +56 -0
- ybox/print.py +121 -0
- ybox/run/__init__.py +0 -0
- ybox/run/cmd.py +54 -0
- ybox/run/control.py +102 -0
- ybox/run/create.py +1116 -0
- ybox/run/destroy.py +64 -0
- ybox/run/graphics.py +367 -0
- ybox/run/logs.py +57 -0
- ybox/run/ls.py +64 -0
- ybox/run/pkg.py +445 -0
- ybox/schema/0.9.1-added.sql +27 -0
- ybox/schema/0.9.6-added.sql +18 -0
- ybox/schema/init.sql +39 -0
- ybox/schema/migrate/0.9.0:0.9.1.sql +42 -0
- ybox/schema/migrate/0.9.1:0.9.2.sql +8 -0
- ybox/schema/migrate/0.9.2:0.9.3.sql +2 -0
- ybox/schema/migrate/0.9.5:0.9.6.sql +2 -0
- ybox/state.py +914 -0
- ybox/util.py +351 -0
- ybox-0.9.8.dist-info/LICENSE +19 -0
- ybox-0.9.8.dist-info/METADATA +533 -0
- ybox-0.9.8.dist-info/RECORD +76 -0
- ybox-0.9.8.dist-info/WHEEL +5 -0
- ybox-0.9.8.dist-info/entry_points.txt +8 -0
- 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
|