ybox 0.9.11.1__tar.gz → 0.9.12__tar.gz
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-0.9.11.1/src/ybox.egg-info → ybox-0.9.12}/PKG-INFO +1 -1
- {ybox-0.9.11.1 → ybox-0.9.12}/src/ybox/__init__.py +1 -1
- {ybox-0.9.11.1 → ybox-0.9.12}/src/ybox/conf/distros/arch/distro.ini +2 -2
- {ybox-0.9.11.1 → ybox-0.9.12}/src/ybox/conf/distros/deb-generic/distro.ini +1 -1
- {ybox-0.9.11.1 → ybox-0.9.12}/src/ybox/conf/profiles/basic.ini +35 -7
- {ybox-0.9.11.1 → ybox-0.9.12}/src/ybox/conf/resources/entrypoint-user.sh +1 -1
- {ybox-0.9.11.1 → ybox-0.9.12}/src/ybox/conf/resources/entrypoint.sh +11 -4
- {ybox-0.9.11.1 → ybox-0.9.12}/src/ybox/conf/resources/run-in-dir +0 -1
- {ybox-0.9.11.1 → ybox-0.9.12}/src/ybox/config.py +6 -2
- ybox-0.9.12/src/ybox/pkg/clean.py +43 -0
- {ybox-0.9.11.1 → ybox-0.9.12}/src/ybox/pkg/inst.py +25 -12
- {ybox-0.9.11.1 → ybox-0.9.12}/src/ybox/run/create.py +80 -8
- {ybox-0.9.11.1 → ybox-0.9.12}/src/ybox/run/destroy.py +5 -0
- {ybox-0.9.11.1 → ybox-0.9.12}/src/ybox/run/graphics.py +5 -6
- {ybox-0.9.11.1 → ybox-0.9.12}/src/ybox/run/pkg.py +2 -1
- {ybox-0.9.11.1 → ybox-0.9.12/src/ybox.egg-info}/PKG-INFO +1 -1
- {ybox-0.9.11.1 → ybox-0.9.12}/src/ybox.egg-info/SOURCES.txt +1 -0
- ybox-0.9.12/tests/create-all-migration-dbs.sh +44 -0
- ybox-0.9.12/tests/resources/migration/0.9.0.db.gz +0 -0
- ybox-0.9.12/tests/resources/migration/0.9.1.db.gz +0 -0
- ybox-0.9.12/tests/resources/migration/0.9.10.db.gz +0 -0
- ybox-0.9.12/tests/resources/migration/0.9.2.db.gz +0 -0
- ybox-0.9.12/tests/resources/migration/0.9.5.db.gz +0 -0
- ybox-0.9.12/tests/resources/migration/0.9.6.db.gz +0 -0
- ybox-0.9.12/tests/resources/migration/0.9.7.db.gz +0 -0
- {ybox-0.9.11.1 → ybox-0.9.12}/tests/unit/test_config.py +1 -0
- ybox-0.9.11.1/src/ybox/pkg/clean.py +0 -27
- ybox-0.9.11.1/tests/resources/migration/0.9.0.db.gz +0 -0
- ybox-0.9.11.1/tests/resources/migration/0.9.1.db.gz +0 -0
- ybox-0.9.11.1/tests/resources/migration/0.9.10.db.gz +0 -0
- ybox-0.9.11.1/tests/resources/migration/0.9.2.db.gz +0 -0
- ybox-0.9.11.1/tests/resources/migration/0.9.5.db.gz +0 -0
- ybox-0.9.11.1/tests/resources/migration/0.9.6.db.gz +0 -0
- ybox-0.9.11.1/tests/resources/migration/0.9.7.db.gz +0 -0
- {ybox-0.9.11.1 → ybox-0.9.12}/LICENSE +0 -0
- {ybox-0.9.11.1 → ybox-0.9.12}/MANIFEST.in +0 -0
- {ybox-0.9.11.1 → ybox-0.9.12}/README.md +0 -0
- {ybox-0.9.11.1 → ybox-0.9.12}/pyproject.toml +0 -0
- {ybox-0.9.11.1 → ybox-0.9.12}/setup.cfg +0 -0
- {ybox-0.9.11.1 → ybox-0.9.12}/src/ybox/cmd.py +0 -0
- {ybox-0.9.11.1 → ybox-0.9.12}/src/ybox/conf/completions/ybox.fish +0 -0
- {ybox-0.9.11.1 → ybox-0.9.12}/src/ybox/conf/distros/arch/add-gpg-key.sh +0 -0
- {ybox-0.9.11.1 → ybox-0.9.12}/src/ybox/conf/distros/arch/init-base.sh +0 -0
- {ybox-0.9.11.1 → ybox-0.9.12}/src/ybox/conf/distros/arch/init-user.sh +0 -0
- {ybox-0.9.11.1 → ybox-0.9.12}/src/ybox/conf/distros/arch/init.sh +0 -0
- {ybox-0.9.11.1 → ybox-0.9.12}/src/ybox/conf/distros/arch/list_fmt_long.py +0 -0
- {ybox-0.9.11.1 → ybox-0.9.12}/src/ybox/conf/distros/arch/pkgdeps.py +0 -0
- {ybox-0.9.11.1 → ybox-0.9.12}/src/ybox/conf/distros/deb-generic/check-package.sh +0 -0
- {ybox-0.9.11.1 → ybox-0.9.12}/src/ybox/conf/distros/deb-generic/fetch-gpg-key-id.sh +0 -0
- {ybox-0.9.11.1 → ybox-0.9.12}/src/ybox/conf/distros/deb-generic/init-base.sh +0 -0
- {ybox-0.9.11.1 → ybox-0.9.12}/src/ybox/conf/distros/deb-generic/init-user.sh +0 -0
- {ybox-0.9.11.1 → ybox-0.9.12}/src/ybox/conf/distros/deb-generic/init.sh +0 -0
- {ybox-0.9.11.1 → ybox-0.9.12}/src/ybox/conf/distros/deb-generic/list_fmt_long.py +0 -0
- {ybox-0.9.11.1 → ybox-0.9.12}/src/ybox/conf/distros/deb-generic/pkgdeps.py +0 -0
- {ybox-0.9.11.1 → ybox-0.9.12}/src/ybox/conf/distros/deb-oldstable/distro.ini +0 -0
- {ybox-0.9.11.1 → ybox-0.9.12}/src/ybox/conf/distros/deb-stable/distro.ini +0 -0
- {ybox-0.9.11.1 → ybox-0.9.12}/src/ybox/conf/distros/supported.list +0 -0
- {ybox-0.9.11.1 → ybox-0.9.12}/src/ybox/conf/distros/ubuntu2204/distro.ini +0 -0
- {ybox-0.9.11.1 → ybox-0.9.12}/src/ybox/conf/distros/ubuntu2404/distro.ini +0 -0
- {ybox-0.9.11.1 → ybox-0.9.12}/src/ybox/conf/profiles/apps.ini +0 -0
- {ybox-0.9.11.1 → ybox-0.9.12}/src/ybox/conf/profiles/dev.ini +0 -0
- {ybox-0.9.11.1 → ybox-0.9.12}/src/ybox/conf/profiles/games.ini +0 -0
- {ybox-0.9.11.1 → ybox-0.9.12}/src/ybox/conf/resources/entrypoint-base.sh +0 -0
- {ybox-0.9.11.1 → ybox-0.9.12}/src/ybox/conf/resources/entrypoint-common.sh +0 -0
- {ybox-0.9.11.1 → ybox-0.9.12}/src/ybox/conf/resources/entrypoint-cp.sh +0 -0
- {ybox-0.9.11.1 → ybox-0.9.12}/src/ybox/conf/resources/entrypoint-root.sh +0 -0
- {ybox-0.9.11.1 → ybox-0.9.12}/src/ybox/conf/resources/prime-run +0 -0
- {ybox-0.9.11.1 → ybox-0.9.12}/src/ybox/conf/resources/run-user-bash-cmd +0 -0
- {ybox-0.9.11.1 → ybox-0.9.12}/src/ybox/conf/resources/ybox-systemd.template +0 -0
- {ybox-0.9.11.1 → ybox-0.9.12}/src/ybox/env.py +0 -0
- {ybox-0.9.11.1 → ybox-0.9.12}/src/ybox/filelock.py +0 -0
- {ybox-0.9.11.1 → ybox-0.9.12}/src/ybox/migrate/0.9.0-0.9.10:0.9.11.py +0 -0
- {ybox-0.9.11.1 → ybox-0.9.12}/src/ybox/pkg/__init__.py +0 -0
- {ybox-0.9.11.1 → ybox-0.9.12}/src/ybox/pkg/info.py +0 -0
- {ybox-0.9.11.1 → ybox-0.9.12}/src/ybox/pkg/list.py +0 -0
- {ybox-0.9.11.1 → ybox-0.9.12}/src/ybox/pkg/mark.py +0 -0
- {ybox-0.9.11.1 → ybox-0.9.12}/src/ybox/pkg/repair.py +0 -0
- {ybox-0.9.11.1 → ybox-0.9.12}/src/ybox/pkg/repo.py +0 -0
- {ybox-0.9.11.1 → ybox-0.9.12}/src/ybox/pkg/search.py +0 -0
- {ybox-0.9.11.1 → ybox-0.9.12}/src/ybox/pkg/uninst.py +0 -0
- {ybox-0.9.11.1 → ybox-0.9.12}/src/ybox/pkg/update.py +0 -0
- {ybox-0.9.11.1 → ybox-0.9.12}/src/ybox/print.py +0 -0
- {ybox-0.9.11.1 → ybox-0.9.12}/src/ybox/run/__init__.py +0 -0
- {ybox-0.9.11.1 → ybox-0.9.12}/src/ybox/run/cmd.py +0 -0
- {ybox-0.9.11.1 → ybox-0.9.12}/src/ybox/run/control.py +0 -0
- {ybox-0.9.11.1 → ybox-0.9.12}/src/ybox/run/logs.py +0 -0
- {ybox-0.9.11.1 → ybox-0.9.12}/src/ybox/run/ls.py +0 -0
- {ybox-0.9.11.1 → ybox-0.9.12}/src/ybox/schema/0.9.1-added.sql +0 -0
- {ybox-0.9.11.1 → ybox-0.9.12}/src/ybox/schema/0.9.6-added.sql +0 -0
- {ybox-0.9.11.1 → ybox-0.9.12}/src/ybox/schema/init.sql +0 -0
- {ybox-0.9.11.1 → ybox-0.9.12}/src/ybox/schema/migrate/0.9.0:0.9.1.sql +0 -0
- {ybox-0.9.11.1 → ybox-0.9.12}/src/ybox/schema/migrate/0.9.1:0.9.2.sql +0 -0
- {ybox-0.9.11.1 → ybox-0.9.12}/src/ybox/schema/migrate/0.9.2:0.9.3.sql +0 -0
- {ybox-0.9.11.1 → ybox-0.9.12}/src/ybox/schema/migrate/0.9.5:0.9.6.sql +0 -0
- {ybox-0.9.11.1 → ybox-0.9.12}/src/ybox/state.py +0 -0
- {ybox-0.9.11.1 → ybox-0.9.12}/src/ybox/util.py +0 -0
- {ybox-0.9.11.1 → ybox-0.9.12}/src/ybox.egg-info/dependency_links.txt +0 -0
- {ybox-0.9.11.1 → ybox-0.9.12}/src/ybox.egg-info/entry_points.txt +0 -0
- {ybox-0.9.11.1 → ybox-0.9.12}/src/ybox.egg-info/requires.txt +0 -0
- {ybox-0.9.11.1 → ybox-0.9.12}/src/ybox.egg-info/top_level.txt +0 -0
- {ybox-0.9.11.1 → ybox-0.9.12}/tests/create_migration_db.py +0 -0
- {ybox-0.9.11.1 → ybox-0.9.12}/tests/functional/__init__.py +0 -0
- {ybox-0.9.11.1 → ybox-0.9.12}/tests/functional/distro_base.py +0 -0
- {ybox-0.9.11.1 → ybox-0.9.12}/tests/functional/test_create_destroy.py +0 -0
- {ybox-0.9.11.1 → ybox-0.9.12}/tests/resources/basic_no_shared.ini +0 -0
- {ybox-0.9.11.1 → ybox-0.9.12}/tests/resources/containers.json +0 -0
- {ybox-0.9.11.1 → ybox-0.9.12}/tests/resources/distro_minimal.ini +0 -0
- {ybox-0.9.11.1 → ybox-0.9.12}/tests/resources/packages.json +0 -0
- {ybox-0.9.11.1 → ybox-0.9.12}/tests/resources/repos.json +0 -0
- {ybox-0.9.11.1 → ybox-0.9.12}/tests/unit/__init__.py +0 -0
- {ybox-0.9.11.1 → ybox-0.9.12}/tests/unit/test_cmd.py +0 -0
- {ybox-0.9.11.1 → ybox-0.9.12}/tests/unit/test_env.py +0 -0
- {ybox-0.9.11.1 → ybox-0.9.12}/tests/unit/test_filelock.py +0 -0
- {ybox-0.9.11.1 → ybox-0.9.12}/tests/unit/test_state.py +0 -0
- {ybox-0.9.11.1 → ybox-0.9.12}/tests/unit/util.py +0 -0
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.4
|
2
2
|
Name: ybox
|
3
|
-
Version: 0.9.
|
3
|
+
Version: 0.9.12
|
4
4
|
Summary: Securely run Linux distribution inside a container
|
5
5
|
Author-email: Sumedh Wale <sumwale@yahoo.com>, Vishal Rao <vishalrao@gmail.com>
|
6
6
|
License: Copyright (c) 2024-2025 Sumedh Wale and contributors
|
@@ -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.12"
|
@@ -50,12 +50,12 @@ recommended_deps = intel-media-driver libva-mesa-driver vulkan-intel vulkan-mesa
|
|
50
50
|
# optional packages for enhanced experience in shell and GUI apps
|
51
51
|
# (for some reason TERMINFO_DIRS does not work for root user, so explicitly installing terminfo
|
52
52
|
# packages for other terminal emulators available in arch which occupy only a tiny space)
|
53
|
-
suggested = cantarell-fonts ttf-fira-code noto-fonts neovim eza ncdu fd bat
|
53
|
+
suggested = cantarell-fonts ttf-fira-code noto-fonts neovim eza ncdu fd bat gnome-settings-daemon
|
54
54
|
kitty-terminfo rxvt-unicode-terminfo realtime-privileges tree starship
|
55
55
|
# dependencies of the `suggested` packages
|
56
56
|
suggested_deps = xsel
|
57
57
|
# additional packages that are in AUR and installed by paru in init-user.sh
|
58
|
-
extra = neovim-symlinks tinyxxd
|
58
|
+
extra = neovim-symlinks tinyxxd
|
59
59
|
|
60
60
|
|
61
61
|
# The commands here will be run as normal userns mapped user, so use sudo if the command
|
@@ -53,7 +53,7 @@ recommended_deps = xauth netbase xdg-user-dirs intel-media-va-driver-non-free me
|
|
53
53
|
mesa-vulkan-drivers libfribidi0 fonts-dejavu-core sensible-utils libpam-cap
|
54
54
|
# optional packages for enhanced experience in shell and GUI apps
|
55
55
|
suggested = fonts-cantarell fonts-firacode fonts-noto-core neovim ncdu fd-find bat
|
56
|
-
kitty-terminfo tree
|
56
|
+
gnome-settings-daemon-common kitty-terminfo tree
|
57
57
|
# dependencies of the `suggested` packages
|
58
58
|
suggested_deps = xsel xxd
|
59
59
|
|
@@ -151,6 +151,12 @@ log_opts = max-size=10m,max-file=3
|
|
151
151
|
# the --device option to podman/docker run. Example: devices = /dev/video0,/dev/ttyUSB0
|
152
152
|
devices =
|
153
153
|
|
154
|
+
# Additional options passed as such to the podman/docker run command.
|
155
|
+
# These are parsed using `shlex.split()`, so use POSIX shell quotes and escape characters for
|
156
|
+
# spaces and other special characters in an option.
|
157
|
+
custom_options =
|
158
|
+
|
159
|
+
|
154
160
|
# The security-opt and other security options passed to podman/docker.
|
155
161
|
# You should restrict these as required.
|
156
162
|
# If these have to be relaxed for some apps, then it is highly recommended to put
|
@@ -189,10 +195,29 @@ label = type:container_runtime_t
|
|
189
195
|
# --ulimit=host is only available for podman which copies host ulimits by default
|
190
196
|
# ulimits = host
|
191
197
|
# default is private IPC
|
192
|
-
# WARNING: setting this to 'host' can open a
|
198
|
+
# WARNING: setting this to 'host' can open a significant security attack vector
|
193
199
|
ipc = private
|
194
200
|
|
195
201
|
|
202
|
+
# Networking related options passed to podman/docker. Available keys are:
|
203
|
+
# mode: set the networking mode, passed as --network=...
|
204
|
+
# expose: comma-separated container ports to expose, passed as --expose=...
|
205
|
+
# publish: comma-separated container ports to publish to the host, passed as --publish=...
|
206
|
+
# publish_all: publish all exposed ports to the host, value can be empty which means enable
|
207
|
+
# or explicit boolean (true/false, on/off, 1/0) and is passed as -P when enabled
|
208
|
+
# host: host name for the container, passed as --hostname=...
|
209
|
+
# ip: ipv4 address of the container, passed as --ip=...
|
210
|
+
# ip6: ipv6 address of the container, passed as --ip6=...
|
211
|
+
# dns: custom DNS servers, passed as --dns=...
|
212
|
+
# dns_option: custom DNS options, passed as --dns-option=...
|
213
|
+
# dns_search: custom DNS search domain, passed as --dns-search=...
|
214
|
+
# mac: custom MAC address for the network interface of the container, passed as --mac-address=...
|
215
|
+
# alias: network scoped alias for the container, passed as --network-alias=...
|
216
|
+
[network]
|
217
|
+
# WARNING: setting this to 'host' can open significant security attack vectors
|
218
|
+
mode =
|
219
|
+
|
220
|
+
|
196
221
|
# These are podman/docker volumes that can use either the format of --mount or -v options
|
197
222
|
# (the scripts make a quick guess by searching for = or ,).
|
198
223
|
# These will typically include some directories from your home like Downloads.
|
@@ -256,6 +281,7 @@ zsh_p10 = $HOME/.p10k.zsh -> .p10k.zsh
|
|
256
281
|
dir_colors = $HOME/.dir_colors -> .dir_colors
|
257
282
|
vimrc = $HOME/.vimrc -> .vimrc
|
258
283
|
nvimrc = $HOME/.config/nvim -> .config/nvim
|
284
|
+
dconf = $HOME/.config/dconf -> .config/dconf
|
259
285
|
themes = $HOME/.themes -> .themes
|
260
286
|
cursors = $HOME/.icons -> .icons
|
261
287
|
icons = $HOME/.local/share/icons -> .local/share/icons
|
@@ -264,8 +290,7 @@ gitconf = $HOME/.gitconfig -> .gitconfig
|
|
264
290
|
gtk2rc = $HOME/.gtkrc-2.0 -> .gtkrc-2.0
|
265
291
|
gtk3rc = $HOME/.config/gtk-3.0 -> .config/gtk-3.0
|
266
292
|
gtk4rc = $HOME/.config/gtk-4.0 -> .config/gtk-4.0
|
267
|
-
|
268
|
-
qt5ctconf = $HOME/.config/qt5ct/qt5ct.conf -> .config/qt5ct/qt5ct.conf
|
293
|
+
qtconf = $HOME/.config/Trolltech.conf -> .config/Trolltech.conf
|
269
294
|
ariaconf = $HOME/.config/aria2/aria2.conf -> .config/aria2/aria2.conf
|
270
295
|
speechconf = $HOME/.config/speech-dispatcher -> .config/speech-dispatcher
|
271
296
|
|
@@ -325,11 +350,14 @@ XMODIFIERS
|
|
325
350
|
chromium = !p --enable-chrome-browser-cloud-management !a
|
326
351
|
|
327
352
|
|
328
|
-
# Startup programs
|
329
|
-
#
|
353
|
+
# Startup programs to run in background when starting the container. Each command is run using
|
354
|
+
# `nohup` and in background with logs in `$HOME/.local/share/ybox/logs/app-<number>_{out|err}.log`
|
355
|
+
# (`_out.log` suffix for standard output and `_err.log` for standard error). The number is the
|
356
|
+
# 1-based index of the command in the list in the section below.
|
357
|
+
#
|
330
358
|
# These programs are run as normal container user, so if you need to run using root
|
331
|
-
# account then add 'sudo' before the command.
|
359
|
+
# account then add 'sudo' before the command. The commands (i.e. the values of the keys)
|
360
|
+
# should be in a single line and cannot contain newlines.
|
332
361
|
[startup]
|
333
362
|
# for example you can avoid sharing dbus of the original session rather start a separate one
|
334
363
|
#dbus = /usr/bin/dbus-daemon --session
|
335
|
-
#dbus_sys = sudo /usr/bin/dbus-daemon --system
|
@@ -10,7 +10,7 @@ current_user="$(id -un)"
|
|
10
10
|
user_home="$(getent passwd "$current_user" | cut -d: -f6)"
|
11
11
|
# set gpg keyserver to an available one
|
12
12
|
mkdir -p "$user_home/.gnupg" && chmod 0700 "$user_home/.gnupg"
|
13
|
-
echo "keyserver $DEFAULT_GPG_KEY_SERVER" > "$user_home/.gnupg/dirmngr.conf"
|
13
|
+
echo "keyserver $DEFAULT_GPG_KEY_SERVER" > "$user_home/.gnupg/dirmngr.conf" || /bin/true
|
14
14
|
rm -f "$user_home"/.gnupg/*/*.lock
|
15
15
|
|
16
16
|
if [ ! -e "$user_home/.config/pip/pip.conf" ]; then
|
@@ -110,11 +110,12 @@ function install_apps() {
|
|
110
110
|
function invoke_startup_apps() {
|
111
111
|
log_dir="$HOME/.local/share/ybox/logs"
|
112
112
|
log_no=1
|
113
|
+
mkdir -p "$log_dir"
|
113
114
|
# start apps in the order listed in the file
|
114
115
|
while read -r app_line; do
|
115
|
-
mkdir -p "$log_dir"
|
116
116
|
echo_color "$fg_orange" "Starting: ${app_line:0:40} ..." >> $status_file
|
117
117
|
nohup $app_line >> "$log_dir/app-${log_no}_out.log" 2>> "$log_dir/app-${log_no}_err.log" &
|
118
|
+
((log_no++))
|
118
119
|
sleep 1
|
119
120
|
done < "$startup_list"
|
120
121
|
}
|
@@ -176,6 +177,7 @@ done
|
|
176
177
|
# change ownership of user's /run/user/<uid> tree which may have root ownership due to the
|
177
178
|
# docker bind mounts
|
178
179
|
run_dir=${XDG_RUNTIME_DIR:-/run/user/$uid}
|
180
|
+
host_run_dir=${run_dir}-host
|
179
181
|
if [ -d $run_dir ]; then
|
180
182
|
$SUDO chown $uid:$gid $run_dir 2>/dev/null || true
|
181
183
|
fi
|
@@ -183,6 +185,11 @@ if compgen -G "$run_dir/*" >/dev/null; then
|
|
183
185
|
$SUDO chown $uid:$gid $run_dir/* 2>/dev/null || true
|
184
186
|
fi
|
185
187
|
|
188
|
+
# link wayland sockets/locks if enabled
|
189
|
+
if [ "$ENABLE_WAYLAND" = true ] && compgen -G "$host_run_dir/wayland-*" >/dev/null; then
|
190
|
+
ln -sf $host_run_dir/wayland-* $run_dir/.
|
191
|
+
fi
|
192
|
+
|
186
193
|
# run actions requiring root access
|
187
194
|
$SUDO /bin/bash "$SCRIPT_DIR/entrypoint-root.sh"
|
188
195
|
|
@@ -210,13 +217,13 @@ if [ ! -e "$SCRIPT_DIR/ybox-init.done" ]; then
|
|
210
217
|
fi
|
211
218
|
|
212
219
|
# process config files, application installs and invoke startup apps
|
213
|
-
if [ -n "$config_list" ]; then
|
220
|
+
if [ -n "$config_list" -a -s "$config_list" ]; then
|
214
221
|
replicate_config_files
|
215
222
|
fi
|
216
|
-
if [ -n "$app_list" ]; then
|
223
|
+
if [ -n "$app_list" -a -s "$app_list" ]; then
|
217
224
|
install_apps
|
218
225
|
fi
|
219
|
-
if [ -n "$startup_list" ]; then
|
226
|
+
if [ -n "$startup_list" -a -s "$startup_list" ]; then
|
220
227
|
invoke_startup_apps
|
221
228
|
fi
|
222
229
|
# update the status file to indicate successful startup
|
@@ -44,6 +44,7 @@ class StaticConfiguration:
|
|
44
44
|
self._status_file = f"{container_dir}/status"
|
45
45
|
self._config_list = f"{self._scripts_dir}/config.list"
|
46
46
|
self._app_list = f"{self._scripts_dir}/app.list"
|
47
|
+
self._startup_list = f"{self._scripts_dir}/startup.list"
|
47
48
|
|
48
49
|
@property
|
49
50
|
def env(self) -> Environ:
|
@@ -123,8 +124,6 @@ class StaticConfiguration:
|
|
123
124
|
"""local status file to communicate when the container is ready for use"""
|
124
125
|
return self._status_file
|
125
126
|
|
126
|
-
# file containing list of configuration files to be linked on that container to host
|
127
|
-
# as mentioned in the [configs] section
|
128
127
|
@property
|
129
128
|
def config_list(self) -> str:
|
130
129
|
"""file containing list of configuration files to be linked on that container to host
|
@@ -136,6 +135,11 @@ class StaticConfiguration:
|
|
136
135
|
"""file containing list of applications to be installed in the container"""
|
137
136
|
return self._app_list
|
138
137
|
|
138
|
+
@property
|
139
|
+
def startup_list(self) -> str:
|
140
|
+
"""file containing list of commands to be executed in the container on startup"""
|
141
|
+
return self._startup_list
|
142
|
+
|
139
143
|
|
140
144
|
class Consts:
|
141
145
|
"""
|
@@ -0,0 +1,43 @@
|
|
1
|
+
"""
|
2
|
+
Clean package cache and related intermediate files of an active ybox container.
|
3
|
+
"""
|
4
|
+
|
5
|
+
import argparse
|
6
|
+
from configparser import SectionProxy
|
7
|
+
|
8
|
+
from ybox.cmd import (PkgMgr, build_shell_command, check_active_ybox,
|
9
|
+
run_command)
|
10
|
+
from ybox.config import StaticConfiguration
|
11
|
+
from ybox.print import print_info
|
12
|
+
from ybox.state import RuntimeConfiguration, YboxStateManagement
|
13
|
+
|
14
|
+
|
15
|
+
# noinspection PyUnusedLocal
|
16
|
+
def clean_cache(args: argparse.Namespace, pkgmgr: SectionProxy, docker_cmd: str,
|
17
|
+
conf: StaticConfiguration, runtime_conf: RuntimeConfiguration,
|
18
|
+
state: YboxStateManagement) -> int:
|
19
|
+
# pylint: disable=unused-argument
|
20
|
+
"""
|
21
|
+
Clean package cache and related intermediate files.
|
22
|
+
|
23
|
+
:param args: arguments having `package` and all other attributes passed by the user
|
24
|
+
:param pkgmgr: the `[pkgmgr]` section from `distro.ini` configuration file of the distribution
|
25
|
+
:param docker_cmd: the podman/docker executable to use
|
26
|
+
:param conf: the :class:`StaticConfiguration` for the container
|
27
|
+
:param runtime_conf: the `RuntimeConfiguration` of the container
|
28
|
+
:param state: instance of `YboxStateManagement` having the state of all ybox containers
|
29
|
+
:return: integer exit status of clean command where 0 represents success
|
30
|
+
"""
|
31
|
+
clean_cmd = pkgmgr[PkgMgr.CLEAN.value] if args.ask else pkgmgr[PkgMgr.CLEAN_QUIET.value]
|
32
|
+
# run clean for each container since it can involve actions that are container specific
|
33
|
+
# apart from the generic ones for the shared root (e.g. AUR cache cleaning for Arch Linux)
|
34
|
+
code = 0
|
35
|
+
for container in state.get_containers(shared_root=runtime_conf.shared_root):
|
36
|
+
if not check_active_ybox(docker_cmd, container):
|
37
|
+
continue
|
38
|
+
print_info(f"Cleaning package cache in container '{container}'")
|
39
|
+
if (c := int(run_command(build_shell_command(docker_cmd, container, clean_cmd),
|
40
|
+
exit_on_error=False, error_msg="cleaning package cache"))) != 0:
|
41
|
+
code = c
|
42
|
+
print()
|
43
|
+
return code
|
@@ -32,10 +32,16 @@ _EXEC_ICON_RE = re.compile(f"{_EXEC_PATTERN}|{_ICON_PATH_PATTERN}")
|
|
32
32
|
# match !p and !a to replace executable program (third group above) and arguments respectively
|
33
33
|
_FLAGS_RE = re.compile("![ap]")
|
34
34
|
# environment variables passed through from host environment to podman/docker executable
|
35
|
-
_PASSTHROUGH_ENVVARS = ("XAUTHORITY", "DISPLAY", "
|
35
|
+
_PASSTHROUGH_ENVVARS = ("XAUTHORITY", "DISPLAY", "XDG_SESSION_TYPE", "FREETYPE_PROPERTIES",
|
36
36
|
"SSH_AUTH_SOCK", "GPG_AGENT_INFO",
|
37
37
|
"__NV_PRIME_RENDER_OFFLOAD", "__GLX_VENDOR_LIBRARY_NAME",
|
38
38
|
"__VK_LAYER_NV_optimus", "VK_ICD_FILES", "VK_ICD_FILENAMES")
|
39
|
+
# environment variables passed from host to podman/docker executable with empty if not set;
|
40
|
+
# note that these variables are assumed to have values that don't need quoting by /bin/sh
|
41
|
+
# else code will need to be updated to quote $<var> value when passing to the shell
|
42
|
+
_PASSTHRU_EMPTY_ENVVARS = ("WAYLAND_DISPLAY", "QT_QPA_PLATFORM")
|
43
|
+
# characters that need to be escaped in quoted string of Exec/TryExec line
|
44
|
+
_DESKTOP_ESCAPE_RE = re.compile(r'["`$\\]')
|
39
45
|
|
40
46
|
|
41
47
|
def install_package(args: argparse.Namespace, pkgmgr: SectionProxy, docker_cmd: str,
|
@@ -356,9 +362,9 @@ def wrap_container_files(package: str, copy_type: CopyType, app_flags: dict[str,
|
|
356
362
|
# clear EXECUTABLE mask so that no wrapper executable is created
|
357
363
|
copy_type &= ~CopyType.EXECUTABLE
|
358
364
|
|
359
|
-
# the "-
|
360
|
-
#
|
361
|
-
#
|
365
|
+
# the "-i" flag is used in the wrapper executable for podman/docker exec which is safe;
|
366
|
+
# if the app needs stdin then Terminal must be true in its desktop file in which case
|
367
|
+
# a terminal will be opened during execution
|
362
368
|
for file_dir, filename, file in file_paths:
|
363
369
|
# check if this is a .desktop directory and copy it over adding appropriate
|
364
370
|
# "docker exec" prefix to the command
|
@@ -454,8 +460,6 @@ def _wrap_desktop_file(filename: str, file: str, docker_cmd: str, conf: StaticCo
|
|
454
460
|
container configuration
|
455
461
|
:param wrapper_files: the accumulated list of all wrapper files so far
|
456
462
|
"""
|
457
|
-
# container name is added to desktop file to make it unique
|
458
|
-
wrapper_name = f"ybox.{conf.box_name}.{filename}"
|
459
463
|
|
460
464
|
def replace_exec_icon(match: re.Match[str]) -> str:
|
461
465
|
"""replace Exec, TryExec and Icon lines appropriately for the host system"""
|
@@ -475,14 +479,20 @@ def _wrap_desktop_file(filename: str, file: str, docker_cmd: str, conf: StaticCo
|
|
475
479
|
else:
|
476
480
|
full_cmd = program
|
477
481
|
# pseudo-tty cannot be allocated with rootless docker outside of a terminal app
|
478
|
-
|
479
|
-
|
480
|
-
|
482
|
+
ev1 = " -e=".join(_PASSTHROUGH_ENVVARS)
|
483
|
+
ev2 = " -e=".join((f"{k}=\\\\${k}" for k in _PASSTHRU_EMPTY_ENVVARS))
|
484
|
+
full_cmd = _DESKTOP_ESCAPE_RE.sub(r'\\\g<0>', full_cmd)
|
485
|
+
# TODO: SW: add "-i" flag if Terminal is true
|
486
|
+
return (f'{exec_word}/bin/sh -c "{docker_cmd} exec -e={ev1} -e={ev2} {conf.box_name} '
|
487
|
+
f'/usr/local/bin/run-in-dir \\\\"\\\\" {full_cmd}"\n')
|
481
488
|
|
482
489
|
# the destination will be $HOME/.local/share/applications
|
483
490
|
os.makedirs(conf.env.user_applications_dir, mode=Consts.default_directory_mode(),
|
484
491
|
exist_ok=True)
|
485
|
-
wrapper_file = f"{conf.env.user_applications_dir}/{
|
492
|
+
wrapper_file = f"{conf.env.user_applications_dir}/{filename}"
|
493
|
+
if os.path.exists(wrapper_file):
|
494
|
+
# container name is added to desktop file to make it unique
|
495
|
+
wrapper_file = f"{conf.env.user_applications_dir}/ybox.{conf.box_name}.{filename}"
|
486
496
|
print_notice(f"Linking container desktop file {file} to {wrapper_file}")
|
487
497
|
|
488
498
|
def write_desktop_file(src: str) -> None:
|
@@ -622,9 +632,12 @@ def _wrap_executable(filename: str, file: str, docker_cmd: str, conf: StaticConf
|
|
622
632
|
lambda f_match: _replace_flags(f_match, flags, f'"{file}"', '"$@"'), flags)
|
623
633
|
else:
|
624
634
|
full_cmd = f'/usr/local/bin/run-in-dir "`pwd`" "{file}" "$@"'
|
625
|
-
|
635
|
+
ev1 = " -e=".join(_PASSTHROUGH_ENVVARS)
|
636
|
+
ev2 = " -e=".join((f"{k}=${k}" for k in _PASSTHRU_EMPTY_ENVVARS))
|
637
|
+
# TODO: some apps like those asking for password from terminal (e.g. ssh/ykman) also
|
638
|
+
# need pseudo-terminal i.e. "-t", so allow for an cmdline option to add "-t" here
|
626
639
|
exec_content = ("#!/bin/sh\n",
|
627
|
-
f"exec {docker_cmd} exec -
|
640
|
+
f"exec {docker_cmd} exec -i -e={ev1} -e={ev2} {conf.box_name} ", full_cmd)
|
628
641
|
with open(wrapper_exec, "w", encoding="utf-8") as wrapper_fd:
|
629
642
|
wrapper_fd.writelines(exec_content)
|
630
643
|
os.chmod(wrapper_exec, mode=0o755, follow_symlinks=True)
|
@@ -8,6 +8,7 @@ import grp
|
|
8
8
|
import os
|
9
9
|
import pwd
|
10
10
|
import re
|
11
|
+
import shlex
|
11
12
|
import shutil
|
12
13
|
import stat
|
13
14
|
import subprocess
|
@@ -491,16 +492,20 @@ def process_sections(profile: PathName, conf: StaticConfiguration, pkgmgr: Secti
|
|
491
492
|
for section in config.sections():
|
492
493
|
if section == "security":
|
493
494
|
process_security_section(config["security"], profile, docker_args)
|
495
|
+
elif section == "network":
|
496
|
+
process_network_section(config["network"], profile, docker_args)
|
494
497
|
elif section == "mounts":
|
495
498
|
process_mounts_section(config["mounts"], docker_args)
|
496
499
|
elif section == "env":
|
497
|
-
process_env_section(config["env"], docker_args)
|
500
|
+
process_env_section(config["env"], conf, docker_args)
|
498
501
|
elif section == "configs":
|
499
502
|
if config_hardlinks is not None:
|
500
503
|
process_configs_section(config["configs"], config_hardlinks, conf, docker_args)
|
501
504
|
elif section == "apps":
|
502
505
|
apps_with_deps = process_apps_section(config["apps"], conf, pkgmgr)
|
503
|
-
elif section
|
506
|
+
elif section == "startup":
|
507
|
+
process_startup_section(config["startup"], conf)
|
508
|
+
elif section not in ("base", "app_flags"):
|
504
509
|
raise NotSupportedError(f"Unknown section [{section}] in '{profile}' "
|
505
510
|
"or one of its includes")
|
506
511
|
return shared_root, config, apps_with_deps
|
@@ -649,8 +654,11 @@ def process_base_section(base_section: SectionProxy, profile: PathName, conf: St
|
|
649
654
|
elif key == "devices":
|
650
655
|
if val:
|
651
656
|
add_multi_opt(docker_args, "device", val)
|
657
|
+
elif key == "custom_options":
|
658
|
+
if val:
|
659
|
+
docker_args.extend(shlex.split(val))
|
652
660
|
elif key not in ("name", "dbus_sys", "includes"):
|
653
|
-
raise NotSupportedError(f"Unknown key '{key}' in the [base] of {profile} "
|
661
|
+
raise NotSupportedError(f"Unknown key '{key}' in the [base] section of {profile} "
|
654
662
|
"or its includes")
|
655
663
|
if config_locale:
|
656
664
|
for lang_var in ("LANG", "LANGUAGE"):
|
@@ -796,7 +804,38 @@ def process_security_section(sec_section: SectionProxy, profile: PathName,
|
|
796
804
|
if _get_boolean(val):
|
797
805
|
docker_args.append("--security-opt=no-new-privileges")
|
798
806
|
else:
|
799
|
-
raise NotSupportedError(f"Unknown key '{key}' in the [security] of {profile} "
|
807
|
+
raise NotSupportedError(f"Unknown key '{key}' in the [security] section of {profile} "
|
808
|
+
"or its includes")
|
809
|
+
|
810
|
+
|
811
|
+
def process_network_section(net_section: SectionProxy, profile: PathName,
|
812
|
+
docker_args: list[str]) -> None:
|
813
|
+
"""
|
814
|
+
Process the `[network]` section in the container profile to append required podman/docker
|
815
|
+
options in the list that has been passed.
|
816
|
+
|
817
|
+
:param net_section: an object of :class:`SectionProxy` from parsing the `[network]` section
|
818
|
+
:param profile: the profile file returned by :func:`select_profile` to use for ybox container
|
819
|
+
configuration as a `Path` or resource file from importlib (`Traversable`)
|
820
|
+
:param docker_args: list of podman/docker arguments to which required options as per the
|
821
|
+
configuration in the `[network]` section are appended
|
822
|
+
:raises NotSupportedError: if there is an unknown key in the `[network]` section
|
823
|
+
"""
|
824
|
+
net_options = {"mode": "network", "host": "hostname", "dns": "dns", "dns_option": "dns-option",
|
825
|
+
"dns_search": "dns-search", "ip": "ip", "ip6": "ip6", "mac": "mac-address",
|
826
|
+
"alias": "network-alias"}
|
827
|
+
multi_options = {"expose": "expose", "publish": "publish"}
|
828
|
+
for key, val in net_section.items():
|
829
|
+
if opt := net_options.get(key):
|
830
|
+
if val:
|
831
|
+
docker_args.append(f"--{opt}={val}")
|
832
|
+
elif opt := multi_options.get(key):
|
833
|
+
add_multi_opt(docker_args, opt, val)
|
834
|
+
elif key == "publish_all":
|
835
|
+
if not val or _get_boolean(val): # empty value means enable
|
836
|
+
docker_args.append("-P")
|
837
|
+
else:
|
838
|
+
raise NotSupportedError(f"Unknown key '{key}' in the [network] section of {profile} "
|
800
839
|
"or its includes")
|
801
840
|
|
802
841
|
|
@@ -811,7 +850,7 @@ def process_mounts_section(mounts_section: SectionProxy, docker_args: list[str])
|
|
811
850
|
"""
|
812
851
|
# keys here are only symbolic names and serve no purpose other than allowing
|
813
852
|
# later profile files to override previous ones
|
814
|
-
for
|
853
|
+
for val in mounts_section.values():
|
815
854
|
if val:
|
816
855
|
if "=" in val or "," in val:
|
817
856
|
docker_args.append(f"--mount={val}")
|
@@ -861,7 +900,10 @@ def process_configs_section(configs_section: SectionProxy, config_hardlinks: boo
|
|
861
900
|
dest_path = f"{conf.configs_dir}/{dest_rel_path}"
|
862
901
|
if os.access(src_path, os.R_OK):
|
863
902
|
if os.path.exists(dest_path):
|
864
|
-
|
903
|
+
if os.path.isdir(dest_path):
|
904
|
+
shutil.rmtree(dest_path)
|
905
|
+
else:
|
906
|
+
os.unlink(dest_path)
|
865
907
|
else:
|
866
908
|
os.makedirs(os.path.dirname(dest_path),
|
867
909
|
mode=Consts.default_directory_mode(), exist_ok=True)
|
@@ -891,15 +933,27 @@ def process_configs_section(configs_section: SectionProxy, config_hardlinks: boo
|
|
891
933
|
add_mount_option(docker_args, conf.configs_dir, conf.target_configs_dir)
|
892
934
|
|
893
935
|
|
894
|
-
def process_env_section(env_section: SectionProxy,
|
936
|
+
def process_env_section(env_section: SectionProxy, conf: StaticConfiguration,
|
937
|
+
docker_args: list[str]) -> None:
|
895
938
|
"""
|
896
939
|
Process the `[env]` section in the container profile to append required podman/docker
|
897
940
|
options in the list that has been passed.
|
898
941
|
|
899
942
|
:param env_section: an object of :class:`SectionProxy` from parsing the `[env]` section
|
943
|
+
:param conf: the :class:`StaticConfiguration` for the container
|
900
944
|
:param docker_args: list of podman/docker arguments to which required options as per the
|
901
945
|
configuration in the `[env]` section are appended
|
902
946
|
"""
|
947
|
+
# add a TMPDIR to share between host and container since some apps require TMPDIR to be
|
948
|
+
# visible on the host (e.g. electron uses it to expose the app/tray icon available via dbus)
|
949
|
+
if "TMPDIR" not in env_section:
|
950
|
+
# use /var/tmp rather than /tmp since latter is a tmpfs system in many setups that will not
|
951
|
+
# retain the created tmpdir after a reboot
|
952
|
+
tmpdir = f"/var/tmp/ybox.{conf.box_name}"
|
953
|
+
os.makedirs(tmpdir, exist_ok=True)
|
954
|
+
os.chmod(tmpdir, 0o1777)
|
955
|
+
add_mount_option(docker_args, tmpdir, tmpdir)
|
956
|
+
add_env_option(docker_args, "TMPDIR", tmpdir)
|
903
957
|
for key, val in env_section.items():
|
904
958
|
add_env_option(docker_args, key, val)
|
905
959
|
|
@@ -939,7 +993,7 @@ def process_apps_section(apps_section: SectionProxy, conf: StaticConfiguration,
|
|
939
993
|
return dep
|
940
994
|
|
941
995
|
with open(conf.app_list, "w", encoding="utf-8") as apps_fd:
|
942
|
-
for
|
996
|
+
for val in apps_section.values():
|
943
997
|
apps = [app.strip() for app in val.split(",")]
|
944
998
|
deps = [capture_dep(match) for dep in apps if (match := _DEP_SUFFIX.match(dep))]
|
945
999
|
if deps:
|
@@ -952,6 +1006,21 @@ def process_apps_section(apps_section: SectionProxy, conf: StaticConfiguration,
|
|
952
1006
|
return apps_with_deps
|
953
1007
|
|
954
1008
|
|
1009
|
+
def process_startup_section(startup_section: SectionProxy, conf: StaticConfiguration) -> None:
|
1010
|
+
"""
|
1011
|
+
Process the `[startup]` section in the container profile to write the list of commands to be
|
1012
|
+
executed (in background) in the container on startup.
|
1013
|
+
|
1014
|
+
:param startup_section: an object of :class:`SectionProxy` from parsing the `[startup]` section
|
1015
|
+
:param conf: the :class:`StaticConfiguration` for the container
|
1016
|
+
"""
|
1017
|
+
if not startup_section:
|
1018
|
+
return
|
1019
|
+
with open(conf.startup_list, "w", encoding="utf-8") as startup_fd:
|
1020
|
+
for val in startup_section.values():
|
1021
|
+
startup_fd.write(val + "\n")
|
1022
|
+
|
1023
|
+
|
955
1024
|
# The shutil.copytree(...) method does not work correctly for "symlinks=False" (or at least
|
956
1025
|
# not like 'cp -aL' or 'cp -alL') where it does not create the source symlinked file rather
|
957
1026
|
# only the target one in the destination directory, and neither does it provide the option to
|
@@ -1236,6 +1305,9 @@ def run_container(docker_full_cmd: list[str], current_user: str, shared_root: st
|
|
1236
1305
|
if os.access(conf.app_list, os.R_OK):
|
1237
1306
|
docker_full_cmd.append("-a")
|
1238
1307
|
docker_full_cmd.append(f"{conf.target_scripts_dir}/app.list")
|
1308
|
+
if os.access(conf.startup_list, os.R_OK):
|
1309
|
+
docker_full_cmd.append("-s")
|
1310
|
+
docker_full_cmd.append(f"{conf.target_scripts_dir}/startup.list")
|
1239
1311
|
docker_full_cmd.append(conf.box_name)
|
1240
1312
|
|
1241
1313
|
if (code := int(run_command(docker_full_cmd, exit_on_error=False,
|
@@ -56,6 +56,11 @@ def main_argv(argv: list[str]) -> None:
|
|
56
56
|
rm_args.append(container_name)
|
57
57
|
run_command(rm_args, error_msg=f"removing '{container_name}'")
|
58
58
|
|
59
|
+
# remove shared TMPDIR if present
|
60
|
+
tmpdir = f"/var/tmp/ybox.{container_name}"
|
61
|
+
if os.path.isdir(tmpdir) and os.access(tmpdir, os.W_OK):
|
62
|
+
shutil.rmtree(tmpdir)
|
63
|
+
|
59
64
|
# remove systemd service file and reload daemon
|
60
65
|
if systemctl:
|
61
66
|
print_color(f"Removing systemd service '{ybox_svc}' and reloading daemon", fg=fgcolor.cyan)
|
@@ -126,12 +126,11 @@ def enable_wayland(docker_args: list[str], env: Environ) -> None:
|
|
126
126
|
:param docker_args: list of podman/docker arguments to which the options have to be appended
|
127
127
|
:param env: an instance of the current :class:`Environ`
|
128
128
|
"""
|
129
|
-
if env.xdg_rt_dir
|
130
|
-
add_env_option(docker_args, "WAYLAND_DISPLAY"
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
f"{env.target_xdg_rt_dir}/{wayland_display}")
|
129
|
+
if env.xdg_rt_dir:
|
130
|
+
add_env_option(docker_args, "WAYLAND_DISPLAY")
|
131
|
+
# don't bind wayland sockets rather link in entrypoint so that it works even
|
132
|
+
# when run in X11 setup after being created in Wayland setup
|
133
|
+
add_env_option(docker_args, "ENABLE_WAYLAND", "true")
|
135
134
|
|
136
135
|
|
137
136
|
def enable_dri(docker_args: list[str]) -> None:
|
@@ -376,7 +376,8 @@ def add_clean(subparser: argparse.ArgumentParser) -> None:
|
|
376
376
|
|
377
377
|
:param subparser: the :class:`argparse.ArgumentParser` object for the sub-command
|
378
378
|
"""
|
379
|
-
subparser.
|
379
|
+
subparser.add_argument("-A", "--ask", action="store_true",
|
380
|
+
help="ask before each action else silently clean everything")
|
380
381
|
subparser.set_defaults(group_by_shared_root=True)
|
381
382
|
subparser.set_defaults(func=clean_cache)
|
382
383
|
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.4
|
2
2
|
Name: ybox
|
3
|
-
Version: 0.9.
|
3
|
+
Version: 0.9.12
|
4
4
|
Summary: Securely run Linux distribution inside a container
|
5
5
|
Author-email: Sumedh Wale <sumwale@yahoo.com>, Vishal Rao <vishalrao@gmail.com>
|
6
6
|
License: Copyright (c) 2024-2025 Sumedh Wale and contributors
|
@@ -79,6 +79,7 @@ src/ybox/schema/migrate/0.9.0:0.9.1.sql
|
|
79
79
|
src/ybox/schema/migrate/0.9.1:0.9.2.sql
|
80
80
|
src/ybox/schema/migrate/0.9.2:0.9.3.sql
|
81
81
|
src/ybox/schema/migrate/0.9.5:0.9.6.sql
|
82
|
+
tests/create-all-migration-dbs.sh
|
82
83
|
tests/create_migration_db.py
|
83
84
|
tests/functional/__init__.py
|
84
85
|
tests/functional/distro_base.py
|
@@ -0,0 +1,44 @@
|
|
1
|
+
#!/bin/bash
|
2
|
+
|
3
|
+
# create test migration databases for all versions listed in test_state.py#test_migration
|
4
|
+
|
5
|
+
set -e
|
6
|
+
|
7
|
+
# use only standard system paths for all utilities
|
8
|
+
export PATH="/usr/sbin:/usr/bin:/sbin:/bin"
|
9
|
+
|
10
|
+
SCRIPT="$(basename "${BASH_SOURCE[0]}")"
|
11
|
+
PROJ_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && cd .. && pwd)"
|
12
|
+
|
13
|
+
# keep this in sync with the list in test_state.py#test_migration
|
14
|
+
all_versions="0.9.0 0.9.1 0.9.2 0.9.5 0.9.6 0.9.7 0.9.10"
|
15
|
+
|
16
|
+
# checkout the repository in a temporary path
|
17
|
+
tmp_co_dir="$PROJ_DIR/tmp-ybox"
|
18
|
+
rm -rf "$tmp_co_dir" && mkdir -p "$tmp_co_dir"
|
19
|
+
git clone https://github.com/sumwale/ybox.git "$tmp_co_dir/"
|
20
|
+
|
21
|
+
pushd "$tmp_co_dir"
|
22
|
+
rm -f "$PROJ_DIR/tests/resources/migration"/*
|
23
|
+
|
24
|
+
# for all versions, checkout the tag, copy latest test artifacts and profiles used by
|
25
|
+
# test_migration, and run the create_migration_db.py script to create the db for the tag
|
26
|
+
for ver in $all_versions; do
|
27
|
+
git reset --hard
|
28
|
+
rm -rf tests src/ybox/conf/profiles
|
29
|
+
git checkout v$ver
|
30
|
+
rm -rf tests src/ybox/conf/profiles
|
31
|
+
cp -r "$PROJ_DIR/tests" tests
|
32
|
+
cp -r "$PROJ_DIR/src/ybox/conf/profiles" src/ybox/conf/profiles
|
33
|
+
find . -name __pycache__ -type d -print0 | xargs -0 -r rm -rf
|
34
|
+
echo
|
35
|
+
echo "Creating test migration database for ybox version:"
|
36
|
+
tail -n1 src/ybox/__init__.py
|
37
|
+
echo
|
38
|
+
PYTHONPATH=./src python3 ./tests/create_migration_db.py "$PROJ_DIR/tests/resources/migration/"
|
39
|
+
done
|
40
|
+
|
41
|
+
popd
|
42
|
+
rm -rf "$tmp_co_dir"
|
43
|
+
|
44
|
+
exit 0
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
@@ -78,6 +78,7 @@ def test_properties(env: Environ, config: static_conf):
|
|
78
78
|
assert config.status_file == f"{env.data_dir}/{_TEST_CONTAINER}/status"
|
79
79
|
assert config.config_list == f"{env.data_dir}/{_TEST_CONTAINER}/ybox-scripts/config.list"
|
80
80
|
assert config.app_list == f"{env.data_dir}/{_TEST_CONTAINER}/ybox-scripts/app.list"
|
81
|
+
assert config.startup_list == f"{env.data_dir}/{_TEST_CONTAINER}/ybox-scripts/startup.list"
|
81
82
|
|
82
83
|
|
83
84
|
def test_consts():
|
@@ -1,27 +0,0 @@
|
|
1
|
-
"""
|
2
|
-
Clean package cache and related intermediate files of an active ybox container.
|
3
|
-
"""
|
4
|
-
|
5
|
-
import argparse
|
6
|
-
from configparser import SectionProxy
|
7
|
-
|
8
|
-
from ybox.cmd import PkgMgr, build_shell_command, run_command
|
9
|
-
from ybox.config import StaticConfiguration
|
10
|
-
from ybox.print import print_info
|
11
|
-
|
12
|
-
|
13
|
-
def clean_cache(args: argparse.Namespace, pkgmgr: SectionProxy, docker_cmd: str,
|
14
|
-
conf: StaticConfiguration) -> int:
|
15
|
-
"""
|
16
|
-
Clean package cache and related intermediate files.
|
17
|
-
|
18
|
-
:param args: arguments having `quiet` and all other attributes passed by the user
|
19
|
-
:param pkgmgr: the `[pkgmgr]` section from `distro.ini` configuration file of the distribution
|
20
|
-
:param docker_cmd: the podman/docker executable to use
|
21
|
-
:param conf: the :class:`StaticConfiguration` for the container
|
22
|
-
:return: integer exit status of clean command where 0 represents success
|
23
|
-
"""
|
24
|
-
print_info(f"Cleaning package cache in container '{conf.box_name}'")
|
25
|
-
clean_cmd = pkgmgr[PkgMgr.CLEAN_QUIET.value] if args.quiet else pkgmgr[PkgMgr.CLEAN.value]
|
26
|
-
return int(run_command(build_shell_command(docker_cmd, conf.box_name, clean_cmd),
|
27
|
-
exit_on_error=False, error_msg="cleaning package cache"))
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|