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,208 @@
|
|
1
|
+
"""
|
2
|
+
Show the optional dependencies for a package that may be in deb package repositories.
|
3
|
+
The output is in the format:
|
4
|
+
|
5
|
+
{header}
|
6
|
+
{prefix}<name>{separator}<level>{separator}<order>{separator}<installed>{separator}<description>
|
7
|
+
|
8
|
+
where:
|
9
|
+
* <name>: name of the optional dependency
|
10
|
+
* <level>: level of the dependency i.e. 1 for direct dependency, 2 for dependency of dependency
|
11
|
+
and so on; resolution of level > 2 is not required since caller currently ignores those
|
12
|
+
* <order>: this is a simple counter assigned to the dependencies where the value itself is of no
|
13
|
+
significance but if multiple dependencies have the same value then it means that they
|
14
|
+
are ORed dependencies and only one of them should normlly be selected for installation
|
15
|
+
* <installed>: true if the dependency already installed and false otherwise
|
16
|
+
* <description>: detailed description of the dependency; it can contain literal \n to indicate
|
17
|
+
newlines in the description
|
18
|
+
"""
|
19
|
+
|
20
|
+
import os
|
21
|
+
import re
|
22
|
+
import sys
|
23
|
+
from enum import Enum
|
24
|
+
from typing import Callable, Iterable, Optional, Union
|
25
|
+
|
26
|
+
from ybox.cmd import parse_opt_deps_args, run_command
|
27
|
+
from ybox.print import print_error, print_notice
|
28
|
+
|
29
|
+
# regex pattern for package name in Recommends or Suggests fields
|
30
|
+
PKG_DEP_RE = re.compile(r"([,|]?)\s*([^\s,|(]+)\s*(\([^)]*\))?\s*")
|
31
|
+
|
32
|
+
PackageAlternate = tuple[str, str, Optional[list[str]]]
|
33
|
+
|
34
|
+
|
35
|
+
def main() -> None:
|
36
|
+
"""main entrypoint for `pkgdeps.py` script"""
|
37
|
+
main_argv(sys.argv[1:])
|
38
|
+
|
39
|
+
|
40
|
+
def main_argv(argv: list[str]) -> None:
|
41
|
+
"""
|
42
|
+
Main entrypoint of `pkgdeps.py` that takes a list of arguments which are usually the
|
43
|
+
command-line arguments of the `main()` function.
|
44
|
+
|
45
|
+
:param argv: arguments to the function (main function passes `sys.argv[1:]`)
|
46
|
+
"""
|
47
|
+
args = parse_opt_deps_args(argv)
|
48
|
+
if args.level > 2:
|
49
|
+
print_error(f"pkgdeps.py does not support level > 2 (given = {args.level})")
|
50
|
+
sys.exit(1)
|
51
|
+
|
52
|
+
print_notice(f"Searching dependencies of '{args.package}' in deb repositories")
|
53
|
+
sep: str = args.separator
|
54
|
+
if opt_deps := find_opt_deps(args.package, args.level):
|
55
|
+
if args.header:
|
56
|
+
print(args.header)
|
57
|
+
prefix = args.prefix
|
58
|
+
for pkg, (desc, level, order, installed) in opt_deps.items():
|
59
|
+
# columns below are expected by ybox-pkg
|
60
|
+
print(f"{prefix}{pkg}{sep}{level}{sep}{order}{sep}{installed}{sep}{desc}")
|
61
|
+
|
62
|
+
|
63
|
+
class PkgDetail(Enum):
|
64
|
+
"""Enumerates the package fields used by `pkgdeps`"""
|
65
|
+
PACKAGE = 1
|
66
|
+
DESCRIPTION = 2
|
67
|
+
PROVIDE = 3
|
68
|
+
REQUIRED_DEP = 4
|
69
|
+
OPTIONAL_DEP = 5
|
70
|
+
|
71
|
+
|
72
|
+
def process_next_item(line: str, parse_line: Callable[[str], tuple[PkgDetail, str]],
|
73
|
+
parse_dep: Callable[[str], Iterable[tuple[str, str, Optional[str]]]],
|
74
|
+
installed: Callable[[str], bool], max_level: int,
|
75
|
+
pkg_details: dict[str, list[PackageAlternate]], level: int = 1) -> None:
|
76
|
+
"""
|
77
|
+
Process the next item in the package details.
|
78
|
+
"""
|
79
|
+
# pylint: disable=unused-argument
|
80
|
+
print("TODO: SW: refactor so that it can be used by pkgdeps of deb-generic as well as arch")
|
81
|
+
sys.exit(1)
|
82
|
+
|
83
|
+
|
84
|
+
def find_opt_deps(package: str, max_level: int) -> dict[str, tuple[str, int, int, bool]]:
|
85
|
+
"""
|
86
|
+
Find the optional dependencies of a package till the given `level`. Here `Recommends` packages
|
87
|
+
are treated as level 1 while `Suggests` are treated as level 2. Higher levels than 2 will fail.
|
88
|
+
|
89
|
+
The result is returned as a dictionary having package name as the key with a tuple having its
|
90
|
+
description, the level it was found, its `order` and a boolean indicating whether the package
|
91
|
+
is already installed or not.
|
92
|
+
|
93
|
+
:param package: name of the package whose optional dependencies have to be searched
|
94
|
+
:param max_level: the maximum level to which the search will extend
|
95
|
+
:return: a dictionary which will be populated with the result having dependency name
|
96
|
+
as the key with a tuple of description, level, order and whether package is installed
|
97
|
+
"""
|
98
|
+
# Fetching optional dependencies consists of two steps:
|
99
|
+
# 1. find the recomends and suggests fields of the package
|
100
|
+
# 2. determine whether those packages are installed or not and obtain their descriptions
|
101
|
+
# It also needs to take care of "|" dependencies where either of the two can be present,
|
102
|
+
# so the `order` needs to be set appropriately.
|
103
|
+
|
104
|
+
# The map below stores all the available package names to their description.
|
105
|
+
# This deliberately uses only the first line of the description for a multi-line description
|
106
|
+
# since it is used for display of the optional dependencies menu where single line is enough.
|
107
|
+
all_packages: dict[str, str] = {}
|
108
|
+
# the map below stores all the virtual packages to the list of the packages that provide them,
|
109
|
+
# including the actual package itself which always provides itself
|
110
|
+
provides_map: dict[str, Union[str, list[str]]] = {}
|
111
|
+
|
112
|
+
def insert_or_update_provides(provide: str, pkg: str) -> None:
|
113
|
+
"""insert a single value in provides map if not present, else change to list and append"""
|
114
|
+
if provides := provides_map.get(provide):
|
115
|
+
if isinstance(provides, list):
|
116
|
+
provides.append(pkg)
|
117
|
+
else:
|
118
|
+
provides_map[provide] = [provides, pkg]
|
119
|
+
else:
|
120
|
+
provides_map[provide] = pkg
|
121
|
+
|
122
|
+
# map of `Recommends` and `Suggests` dependencies to their level and order
|
123
|
+
opt_dep_map: dict[str, tuple[int, int]] = {}
|
124
|
+
# dump all available packages, build a map of package name and its description, then pick the
|
125
|
+
# package and its dependencies; the total map size with just those fields will be a few MB
|
126
|
+
# while using `grep-aptavail` multiple times will be inefficient
|
127
|
+
check_optional = False
|
128
|
+
current_pkg = ""
|
129
|
+
# this counter is for assigning a counter to the dependencies which has a significance only
|
130
|
+
# for ORed dependencies which will have the same order (and thus indicate to the higher level
|
131
|
+
# that only one of them should be installed)
|
132
|
+
order = 0
|
133
|
+
for line in str(run_command(["/usr/bin/apt-cache", "dumpavail"],
|
134
|
+
capture_output=True)).splitlines():
|
135
|
+
if line.startswith("Package:"):
|
136
|
+
if (current_pkg := line[len("Package:"):].strip()) == package:
|
137
|
+
check_optional = True
|
138
|
+
else:
|
139
|
+
check_optional = False
|
140
|
+
insert_or_update_provides(current_pkg, current_pkg)
|
141
|
+
elif check_optional:
|
142
|
+
# Note: version comparisons are not required here since all we need is the description
|
143
|
+
# of the package. This assumes that the best package available for installation in the
|
144
|
+
# repositories satisfies the version mentioned in the Recommends/Suggests dependencies,
|
145
|
+
# but that may not be true in some rare cases in which case the installation of the
|
146
|
+
# optional dependency will fail after user selects it.
|
147
|
+
if line.startswith("Recommends:"):
|
148
|
+
for match in PKG_DEP_RE.finditer(line, len("Recommends:")):
|
149
|
+
if match.group(1) != "|": # ORed dependencies have the same `order`
|
150
|
+
order += 1
|
151
|
+
opt_dep_map[match.group(2)] = (1, order)
|
152
|
+
elif max_level > 1 and line.startswith("Suggests:"):
|
153
|
+
for match in PKG_DEP_RE.finditer(line, len("Suggests:")):
|
154
|
+
if match.group(1) != "|": # ORed dependencies have the same `order`
|
155
|
+
order += 1
|
156
|
+
opt_dep_map[match.group(2)] = (2, order)
|
157
|
+
else:
|
158
|
+
if line.startswith("Provides:"):
|
159
|
+
for match in PKG_DEP_RE.finditer(line, len("Provides:")):
|
160
|
+
insert_or_update_provides(match.group(2), current_pkg)
|
161
|
+
elif line.startswith("Description:"):
|
162
|
+
all_packages[current_pkg] = line[len("Description:"):].strip()
|
163
|
+
|
164
|
+
if not opt_dep_map:
|
165
|
+
return {}
|
166
|
+
# get the system architecture to quickly check for existence of an installed package
|
167
|
+
sys_arch = str(run_command(["/usr/bin/dpkg", "--print-architecture"],
|
168
|
+
capture_output=True)).strip()
|
169
|
+
# list of required optional dependencies as a tuple (name, (description, level, order,
|
170
|
+
# installed)); note that `Recommends` are level 1 while `Suggests` are level 2 and recursion
|
171
|
+
# for levels is skipped
|
172
|
+
opt_deps: list[tuple[str, tuple[str, int, int, bool]]] = []
|
173
|
+
# loop through the `opt_deps_map` and look them up in the `provides` map to get the actual
|
174
|
+
# packages which will be inserted in `opt_deps` with their level and order while description
|
175
|
+
# will be looked up from `all_packages` map
|
176
|
+
last_installed_order = 0
|
177
|
+
for dep, (level, order) in opt_dep_map.items():
|
178
|
+
if provides := provides_map.get(dep):
|
179
|
+
if isinstance(provides, str):
|
180
|
+
provides = (provides,)
|
181
|
+
for provide in provides:
|
182
|
+
if provide == package: # for the possible case of self-recommend/suggest
|
183
|
+
continue
|
184
|
+
# for each `provide` check if its installed
|
185
|
+
installed = os.path.exists(f"/var/lib/dpkg/info/{provide}.list") or os.path.exists(
|
186
|
+
f"/var/lib/dpkg/info/{provide}:{sys_arch}.list")
|
187
|
+
# if there is an installed package, then remove the uninstalled packages in the
|
188
|
+
# same order since one of them is already installed (installed ones are required
|
189
|
+
# for registeration as existing dependency by ybox-pkg, so they are still kept)
|
190
|
+
if installed:
|
191
|
+
last_installed_order = order
|
192
|
+
# pop uninstalled ones in the same `order` which will be at the end since
|
193
|
+
# opt_dep_map iterator will be insertion order which is sorted by `order`;
|
194
|
+
# previous installed one in same `order` would have removed all uninstalled
|
195
|
+
# ones in that order that were before it, so don't need to check before it
|
196
|
+
while opt_deps and opt_deps[-1][1][2] == order and not opt_deps[-1][1][3]:
|
197
|
+
opt_deps.pop()
|
198
|
+
elif order == last_installed_order:
|
199
|
+
continue
|
200
|
+
opt_deps.append((provide, (all_packages[provide], level, order, installed)))
|
201
|
+
|
202
|
+
# sort opt_deps by level and order and return
|
203
|
+
opt_deps.sort(key=lambda x: (x[1][1], x[1][2]))
|
204
|
+
return dict(opt_deps)
|
205
|
+
|
206
|
+
|
207
|
+
if __name__ == "__main__":
|
208
|
+
main()
|
@@ -0,0 +1,21 @@
|
|
1
|
+
# Configuration specific to each distribution (INI style file)
|
2
|
+
|
3
|
+
# Base configuration for the distribution
|
4
|
+
[base]
|
5
|
+
# name is required
|
6
|
+
name = Debian oldstable - Bullseye
|
7
|
+
# Comma separated files to include before applying these settings.
|
8
|
+
# Paths can be absolute or relative to the location of this file.
|
9
|
+
includes = ../deb-generic/distro.ini
|
10
|
+
# docker image of the distribution
|
11
|
+
image = docker.io/library/debian:bullseye
|
12
|
+
# whether to search for and configure fastest available mirrors for packages
|
13
|
+
# (debian uses the builtin mirror by default since those determined dynamically can be
|
14
|
+
# flaky and instead uses apt-fast to configure parallel downloads)
|
15
|
+
configure_fastest_mirrors = false
|
16
|
+
# distribution scripts that need to be copied to the container in $YBOX_TARGET_SCRIPTS_DIR
|
17
|
+
# (should include init.sh, init-base.sh and init-user.sh scripts that are are normally required
|
18
|
+
# for all distributions)
|
19
|
+
scripts = ../deb-generic/init-base.sh,../deb-generic/init.sh,../deb-generic/init-user.sh,
|
20
|
+
../deb-generic/check-package.sh,
|
21
|
+
../deb-generic/list_fmt_long.py,../deb-generic/fetch-gpg-key-id.sh
|
@@ -0,0 +1,21 @@
|
|
1
|
+
# Configuration specific to each distribution (INI style file)
|
2
|
+
|
3
|
+
# Base configuration for the distribution
|
4
|
+
[base]
|
5
|
+
# name is required
|
6
|
+
name = Debian stable - Bookworm
|
7
|
+
# Comma separated files to include before applying these settings.
|
8
|
+
# Paths can be absolute or relative to the location of this file.
|
9
|
+
includes = ../deb-generic/distro.ini
|
10
|
+
# docker image of the distribution
|
11
|
+
image = docker.io/library/debian:bookworm
|
12
|
+
# whether to search for and configure fastest available mirrors for packages
|
13
|
+
# (debian uses the builtin mirror by default since those determined dynamically can be
|
14
|
+
# flaky and instead uses apt-fast to configure parallel downloads)
|
15
|
+
configure_fastest_mirrors = false
|
16
|
+
# distribution scripts that need to be copied to the container in $YBOX_TARGET_SCRIPTS_DIR
|
17
|
+
# (should include init.sh, init-base.sh and init-user.sh scripts that are are normally required
|
18
|
+
# for all distributions)
|
19
|
+
scripts = ../deb-generic/init-base.sh,../deb-generic/init.sh,../deb-generic/init-user.sh,
|
20
|
+
../deb-generic/check-package.sh,
|
21
|
+
../deb-generic/list_fmt_long.py,../deb-generic/fetch-gpg-key-id.sh
|
@@ -0,0 +1,21 @@
|
|
1
|
+
# Configuration specific to each distribution (INI style file)
|
2
|
+
|
3
|
+
# Base configuration for the distribution
|
4
|
+
[base]
|
5
|
+
# name is required
|
6
|
+
name = Ubuntu 22.04 LTS Jammy Jellyfish
|
7
|
+
# Comma separated files to include before applying these settings.
|
8
|
+
# Paths can be absolute or relative to the location of this file.
|
9
|
+
includes = ../deb-generic/distro.ini
|
10
|
+
# docker image of the distribution
|
11
|
+
image = docker.io/library/ubuntu:jammy
|
12
|
+
# whether to search for and configure fastest available mirrors for packages
|
13
|
+
# (ubuntu uses the builtin mirror by default since those determined dynamically can be
|
14
|
+
# flaky and instead uses apt-fast to configure parallel downloads)
|
15
|
+
configure_fastest_mirrors = false
|
16
|
+
# distribution scripts that need to be copied to the container in $YBOX_TARGET_SCRIPTS_DIR
|
17
|
+
# (should include init.sh, init-base.sh and init-user.sh scripts that are are normally required
|
18
|
+
# for all distributions)
|
19
|
+
scripts = ../deb-generic/init-base.sh,../deb-generic/init.sh,../deb-generic/init-user.sh,
|
20
|
+
../deb-generic/check-package.sh,
|
21
|
+
../deb-generic/list_fmt_long.py,../deb-generic/fetch-gpg-key-id.sh
|
@@ -0,0 +1,21 @@
|
|
1
|
+
# Configuration specific to each distribution (INI style file)
|
2
|
+
|
3
|
+
# Base configuration for the distribution
|
4
|
+
[base]
|
5
|
+
# name is required
|
6
|
+
name = Ubuntu 24.04 LTS Noble Numbat
|
7
|
+
# Comma separated files to include before applying these settings.
|
8
|
+
# Paths can be absolute or relative to the location of this file.
|
9
|
+
includes = ../deb-generic/distro.ini
|
10
|
+
# docker image of the distribution
|
11
|
+
image = docker.io/library/ubuntu:noble
|
12
|
+
# whether to search for and configure fastest available mirrors for packages
|
13
|
+
# (ubuntu uses the builtin mirror by default since those determined dynamically can be
|
14
|
+
# flaky and instead uses apt-fast to configure parallel downloads)
|
15
|
+
configure_fastest_mirrors = false
|
16
|
+
# distribution scripts that need to be copied to the container in $YBOX_TARGET_SCRIPTS_DIR
|
17
|
+
# (should include init.sh, init-base.sh and init-user.sh scripts that are are normally required
|
18
|
+
# for all distributions)
|
19
|
+
scripts = ../deb-generic/init-base.sh,../deb-generic/init.sh,../deb-generic/init-user.sh,
|
20
|
+
../deb-generic/check-package.sh,
|
21
|
+
../deb-generic/list_fmt_long.py,../deb-generic/fetch-gpg-key-id.sh
|
@@ -0,0 +1,26 @@
|
|
1
|
+
[base]
|
2
|
+
name = Profile for CLI and GUI apps
|
3
|
+
includes = basic.ini
|
4
|
+
|
5
|
+
[security]
|
6
|
+
# SYS_PTRACE may be required by mesa which is invoked indirectly by both firefox and chromium.
|
7
|
+
# Without this, the following warning is seen:
|
8
|
+
# WARNING: Kernel has no file descriptor comparison support: Operation not permitted
|
9
|
+
caps_add = SYS_PTRACE
|
10
|
+
|
11
|
+
[mounts]
|
12
|
+
music = $HOME/Music:$TARGET_HOME/Music:ro
|
13
|
+
pictures = $HOME/Pictures:$TARGET_HOME/Pictures:ro
|
14
|
+
videos = $HOME/Videos:$TARGET_HOME/Videos:ro
|
15
|
+
|
16
|
+
[apps]
|
17
|
+
# some packages for Arch Linux - uncomment and update for your distribution as required
|
18
|
+
#browsers = firefox,chromium
|
19
|
+
|
20
|
+
[app_flags]
|
21
|
+
# These flags will be added to Exec line of google-chrome.desktop when it is copied to host.
|
22
|
+
# /dev/shm usage is disabled for chrome because that requires ipc=host or mounting host
|
23
|
+
# /dev/shm in read-write mode which can be insecure.
|
24
|
+
google-chrome = !p --disable-dev-shm-usage !a
|
25
|
+
google-chrome-beta = !p --disable-dev-shm-usage !a
|
26
|
+
google-chrome-unstable = !p --disable-dev-shm-usage !a
|
@@ -0,0 +1,310 @@
|
|
1
|
+
# Configuration file for podman/docker containers used by ybox scripts.
|
2
|
+
# This is the common file included by all other configurations.
|
3
|
+
#
|
4
|
+
# Value format is as supported by python ConfigParser
|
5
|
+
# (e.g. https://docs.python.org/3/library/configparser.html for Python3 docs).
|
6
|
+
# Specifically boolean values are extracted using getboolean() method which supports
|
7
|
+
# many different values like on/off, true/false etc.
|
8
|
+
# Key-value separator can only be '=' while ':' is not supported. Default basic value
|
9
|
+
# interpolation implemented by the python module has been extended to also support environment
|
10
|
+
# variables as described next.
|
11
|
+
#
|
12
|
+
# The values can contain environment variables using the notation supported by
|
13
|
+
# python expandvars (https://docs.python.org/3/library/os.path.html#os.path.expandvars).
|
14
|
+
# A few special environment variables are also available:
|
15
|
+
# - YBOX_DISTRIBUTION_NAME: name of the Linux distribution (as provided to 'ybox-create')
|
16
|
+
# - YBOX_CONTAINER_NAME: name of the current container (as provided/set by 'ybox-create')
|
17
|
+
# - YBOX_CONTAINER_DIR: set to $HOME/.local/share/ybox/$YBOX_CONTAINER_NAME for convenience
|
18
|
+
# - YBOX_TARGET_SCRIPTS_DIR: local directory in the container where various ybox scripts
|
19
|
+
# are mounted (e.g. entrypoint scripts)
|
20
|
+
# - YBOX_SYS_CONF_DIR: path to system configuration directory where configuration directory
|
21
|
+
# shipped with ybox is installed (or the string form of
|
22
|
+
# the directory if it is not on filesystem like an egg or similar)
|
23
|
+
# - TARGET_HOME: set to the home directory of the container user
|
24
|
+
# Additionally a special notation can be used for current date+time with this notation:
|
25
|
+
# ${NOW:<fmt>}. The <fmt> uses the format supported by python strftime
|
26
|
+
# (https://docs.python.org/3/library/datetime.html#datetime.datetime.strftime)
|
27
|
+
# while the NOW is the result of datetime.now() call.
|
28
|
+
#
|
29
|
+
# Expansion of other keys in the same section or the special 'DEFAULT' section is also provided
|
30
|
+
# using the notation supported by python's configparser BasicInterpolation, see:
|
31
|
+
# https://docs.python.org/3/library/configparser.html#configparser.BasicInterpolation
|
32
|
+
# In a nutshell you need '%(<var>)s' notation to expand <var> key and bare '%' should be '%%'.
|
33
|
+
# However, the '%' inside the ${NOW:<fmt>} format should not be escaped because all environment
|
34
|
+
# variables as well as ${NOW:...} are expanded before the variable references.
|
35
|
+
#
|
36
|
+
# NOTE: Take care to have different path settings point to distinct directory/path
|
37
|
+
# locations e.g. base.shared_root, base.home and base.log_opts.path (podman) should point to
|
38
|
+
# different directories else you can lose one or the other since the code currently does not
|
39
|
+
# check for such overlaps and will happily mount the directory as the container home while
|
40
|
+
# logs are also being written there which can result in an unpredictable behavior.
|
41
|
+
# Likewise the configuration files in [configs] section are temporarily copied/linked in
|
42
|
+
# $YBOX_CONTAINER_DIR/configs which is not configurable and should not be used and there
|
43
|
+
# is a temporary mount directory having utility scripts in $YBOX_CONTAINER_DIR/ybox-scripts
|
44
|
+
|
45
|
+
|
46
|
+
# Basic container settings that are documented individually below.
|
47
|
+
[base]
|
48
|
+
# A short description of this profile.
|
49
|
+
name = Basic profile for CLI and most GUI apps
|
50
|
+
# Comma separated files to include before applying these settings.
|
51
|
+
# Paths can be absolute or relative to the location of this file.
|
52
|
+
includes =
|
53
|
+
# Whether the system directories are shared between all containers of the same distribution
|
54
|
+
# is determined by this variable. The common system directories are bind mounted to a common
|
55
|
+
# host directory specified by this `shared_root` variable.
|
56
|
+
#
|
57
|
+
# It includes all directories (defined in distro.ini) that hold system package data which
|
58
|
+
# also means that the packages installed on one container are visible on all the containers
|
59
|
+
# of the same distribution. So those packages can be launched from any of the containers
|
60
|
+
# but they will be subject to that container configuration. The wrapper launcher scripts
|
61
|
+
# created by `ybox-pkg install` will ensure that packages are launched only from the containers
|
62
|
+
# where they were installed so that should be the preferred way to launch apps (except for
|
63
|
+
# packages common to multiple containers which can be launched from any of those).
|
64
|
+
#
|
65
|
+
# Default is enabled so as to save space, page cache space etc, and allow users
|
66
|
+
# to freely create as many containers as desired to achieve best isolation without worrying
|
67
|
+
# about dramatic increase in disk and/or memory usage.
|
68
|
+
shared_root = $HOME/.local/share/ybox/SHARED_ROOTS/$YBOX_DISTRIBUTION_NAME
|
69
|
+
# Bind mount the container $HOME to this local path (aka $TARGET_HOME). This makes it
|
70
|
+
# easier for backup software and otherwise to read useful container data.
|
71
|
+
# If not provided then you should explicitly mount required directories in the [mounts]
|
72
|
+
# section otherwise home will remain completely ephemeral which is not recommended.
|
73
|
+
home = $YBOX_CONTAINER_DIR/home
|
74
|
+
# Whether the configuration files (specified in [configs] section) should be hard linked
|
75
|
+
# to a temporary directory that is made available to the container, or copied over.
|
76
|
+
# Hardlinks will not work if you have mounted the temporary directory inside
|
77
|
+
# ~/.local/share/ybox on a separate volume other than home itself.
|
78
|
+
# Directories are hard linked recursively and symlinks in the source are followed to their
|
79
|
+
# destination which must again exist on the same filesystem.
|
80
|
+
#
|
81
|
+
# In case of hardlinks, any changes made on host will be immediately visible otherwise
|
82
|
+
# with this as false, you need to re-create the container to let it see any changes.
|
83
|
+
# You can also use this for only first time reference and then make a separate copy
|
84
|
+
# inside the container which will break any direct sharing between the host and container.
|
85
|
+
#
|
86
|
+
# An empty value will cause [configs] section to be completely skipped.
|
87
|
+
config_hardlinks = true
|
88
|
+
# If enabled, then locale in the container will be configured as per the LANG and LANGUAGE
|
89
|
+
# environment variables from the host environment.
|
90
|
+
config_locale = true
|
91
|
+
# If enabled then X server from the user session is available to the container.
|
92
|
+
x11 = on
|
93
|
+
# If enabled then Wayland server from the user session is available to the container.
|
94
|
+
wayland = on
|
95
|
+
# If enabled then pulseaudio/pipewire from the user session is available to the container.
|
96
|
+
# This will enable either of pulse/pipewire (or both) whichever is available on the host.
|
97
|
+
pulseaudio = on
|
98
|
+
# If enabled then dbus from the user session is available to the container.
|
99
|
+
dbus = on
|
100
|
+
# If enabled then the system dbus from the host is available to the container.
|
101
|
+
dbus_sys = off
|
102
|
+
# If enabled then Direct Rendering Infrastructure for accelerated graphics is available to
|
103
|
+
# the container.
|
104
|
+
dri = on
|
105
|
+
# If enabled then NVIDIA GPUs will be accessible in the container by making available NVIDIA
|
106
|
+
# devices, libraries and binaries from the host system to the container. The search for
|
107
|
+
# NVIDIA on the host should work on most modern Linux distributions, but if does not then
|
108
|
+
# install NVIDIA container toolkit and use the "nvidia_ctk" option below.
|
109
|
+
#
|
110
|
+
# This option should be preferred over "nvidia_ctk" option because it can handle NVIDIA
|
111
|
+
# driver updates transparently without reconfiguration and does not need additional installation.
|
112
|
+
nvidia = off
|
113
|
+
# If enabled then NVIDIA GPUs will be available to the container. You need to install
|
114
|
+
# NVIDIA container toolkit for this to work. Refer to Arch wiki for details which usually
|
115
|
+
# works well on most Linux distros (https://wiki.archlinux.org/title/docker or
|
116
|
+
# https://wiki.archlinux.org/title/podman), and the official NVIDIA docs:
|
117
|
+
# https://docs.nvidia.com/datacenter/cloud-native/container-toolkit/latest/install-guide.html
|
118
|
+
# For example on ubuntu with podman, configure the apt repository from the previous link
|
119
|
+
# and install the package as noted there, then run
|
120
|
+
# `sudo nvidia-ctk cdi generate --output=/etc/cdi/nvidia.yaml`.
|
121
|
+
# This will need to be repeated if nvidia driver version is upgraded.
|
122
|
+
#
|
123
|
+
# This will take precedence if both "nvidia" and "nvidia_ctk" are enabled.
|
124
|
+
nvidia_ctk = off
|
125
|
+
# default podman/docker shm-size is 64m which can be insufficient for many apps
|
126
|
+
shm_size = 1g
|
127
|
+
# Limit the maximum number of processes in the container (to avoid stuff like fork bombs).
|
128
|
+
pids_limit = 2048
|
129
|
+
# Logging driver to use. Default for podman/docker is to use journald in modern Linux
|
130
|
+
# distributions which pollutes the journald logs.
|
131
|
+
# Note that on podman, json-file is an alias for k8s-file which produces plaintext format.
|
132
|
+
log_driver = json-file
|
133
|
+
# Comma separated options for the logger.
|
134
|
+
# Example of path with timestamped file for podman
|
135
|
+
#log_opts = path=$YBOX_CONTAINER_DIR/logs/${NOW:%Y-%m-%d_%H.%M.%S}.log,max-size=10m,max-file=3
|
136
|
+
# Example for docker that does not support `path`
|
137
|
+
log_opts = max-size=10m,max-file=3
|
138
|
+
|
139
|
+
|
140
|
+
# The security-opt and other security options passed to podman/docker.
|
141
|
+
# You should restrict these as required.
|
142
|
+
# If these have to be relaxed for some apps, then it is highly recommended to put
|
143
|
+
# those in their own separate containers having minimal or no access to original home
|
144
|
+
# directories to isolate them as much as possible. Do read up on security implications
|
145
|
+
# before relaxing these.
|
146
|
+
# See docs like https://docs.docker.com/engine/security/seccomp,
|
147
|
+
# https://docs.docker.com/engine/security/apparmor,
|
148
|
+
# https://docs.podman.io/en/latest/markdown/podman-run.1.html etc
|
149
|
+
# The following keys are available -- not all of these may be supported by the available
|
150
|
+
# podman/docker installation but are passed as is, so they can throw an error:
|
151
|
+
# label: corresponding to --security-opt=label=...
|
152
|
+
# apparmor: --security-opt=apparmor=...
|
153
|
+
# seccomp: --security-opt=seccomp=...
|
154
|
+
# mask: --security-opt=mask=...
|
155
|
+
# unmask: --security-opt=unmask=...
|
156
|
+
# no_new_privileges: boolean to enable --security-opt=no-new-privileges
|
157
|
+
# proc_opts: --security-opt=proc-opts=...
|
158
|
+
# seccomp_policy: --seccomp-policy=...
|
159
|
+
# caps_add: comma separated multiple --cap-add=... options
|
160
|
+
# caps_drop: comma separated multiple --cap-drop=... options
|
161
|
+
# ulimits: comma separated multiple --ulimit=... options
|
162
|
+
# ipc: --ipc=...
|
163
|
+
# cgroup_parent: --cgroup-parent=...
|
164
|
+
# cgroup_confs: comma separated multiple --cgroup-conf=... options
|
165
|
+
# cgroupns: --cgroupns=...
|
166
|
+
# cgroups: --cgroups=...
|
167
|
+
# device_cgroup_rules: comma separated multiple --device-cgroup-rule=... options
|
168
|
+
# secrets: comma separated multiple --secret=... options
|
169
|
+
[security]
|
170
|
+
# The options are sent as is to podman/docker e.g. "label=type:container_runtime_t"
|
171
|
+
# (the default "container_runtime_t" label bypasses some selinux restrictions)
|
172
|
+
label = type:container_runtime_t
|
173
|
+
# arch pacman may need this but seems to be working fine without it even with the warnings
|
174
|
+
#caps_add = SYS_CHROOT
|
175
|
+
# --ulimit=host is only available for podman which copies host ulimits by default
|
176
|
+
# ulimits = host
|
177
|
+
# default is private IPC
|
178
|
+
# WARNING: setting this to 'host' can open a major security attack vector
|
179
|
+
ipc = private
|
180
|
+
|
181
|
+
|
182
|
+
# These are podman/docker volumes that can use either the format of --mount or -v options
|
183
|
+
# (the scripts make a quick guess by searching for = or ,).
|
184
|
+
# These will typically include some directories from your home like Downloads.
|
185
|
+
[mounts]
|
186
|
+
# Share terminfo definitions which may be missing for some terminals in the container.
|
187
|
+
terminfo = /usr/share/terminfo:/var/lib/terminfo:ro
|
188
|
+
# Downloads is configured to share data with original session easily so it should not
|
189
|
+
# contain "unsharable" stuff.
|
190
|
+
downloads = $HOME/Downloads:$TARGET_HOME/Downloads
|
191
|
+
# Documents is shared in read-only mode
|
192
|
+
documents = $HOME/Documents:$TARGET_HOME/Documents:ro
|
193
|
+
# might be required for some apps if NVIDIA is enabled
|
194
|
+
# video_dev = /dev/video0:/dev/video0
|
195
|
+
|
196
|
+
|
197
|
+
# These can be used to specify the configuration files from the host session
|
198
|
+
# that you want to share with the container. The files from the host session
|
199
|
+
# will either be copied or hard linked (depending on the "config_hardlinks" option in [base]
|
200
|
+
# section) to a directory that is mounted read-only.
|
201
|
+
#
|
202
|
+
# The value has two parts separated by "->" with the LHS of this being the source that
|
203
|
+
# is to be copied while the RHS is the required relative path in the target directory.
|
204
|
+
# On the target container the same is used to symlink from the target on RHS to source on LHS.
|
205
|
+
# Source is skipped if it does not exist or not readable with a message on standard output.
|
206
|
+
#
|
207
|
+
# Typically this will contain shell, vim and other common configuration files.
|
208
|
+
# These can be either files or directories and are skipped if they do not exist.
|
209
|
+
# The keys here have no special significance other than the fact that they should be
|
210
|
+
# unique and can be used to override in later files that include this one.
|
211
|
+
#
|
212
|
+
# Note: The files are symlinks in the container user area and are mounted on a read-only
|
213
|
+
# mount by default, so if you need to change a file within a container then you will
|
214
|
+
# need to first remove the symlink and make a copy of the file. This will remove the
|
215
|
+
# direct sharing between the two which has to be done manually thereon if required.
|
216
|
+
# The sharing behavior also depends on "config_hardlinks" as described in its comment above
|
217
|
+
# in the [base] section.
|
218
|
+
#
|
219
|
+
# Note: The HOME environment variable here will be evaluated both in the host
|
220
|
+
# session (for the source to be transferred) and inside the container session
|
221
|
+
# (for the target). Do not use TARGET_HOME here which can be incorrect for the host session.
|
222
|
+
[configs]
|
223
|
+
bashrc = $HOME/.bashrc -> .bashrc
|
224
|
+
starship = $HOME/.config/starship.toml -> .config/starship.toml
|
225
|
+
fishrc = $HOME/.config/fish -> .config/fish
|
226
|
+
omf = $HOME/.config/omf -> .config/omf
|
227
|
+
omf_data = $HOME/.local/share/omf -> .local/share/omf
|
228
|
+
zshrc = $HOME/.zshrc -> .zshrc
|
229
|
+
zsh_p10 = $HOME/.p10k.zsh -> .p10k.zsh
|
230
|
+
dir_colors = $HOME/.dir_colors -> .dir_colors
|
231
|
+
vimrc = $HOME/.vimrc -> .vimrc
|
232
|
+
nvimrc = $HOME/.config/nvim -> .config/nvim
|
233
|
+
themes = $HOME/.themes -> .themes
|
234
|
+
cursors = $HOME/.icons -> .icons
|
235
|
+
icons = $HOME/.local/share/icons -> .local/share/icons
|
236
|
+
pipconf = $HOME/.config/pip/pip.conf -> .config/pip/pip.conf
|
237
|
+
gitconf = $HOME/.gitconfig -> .gitconfig
|
238
|
+
gtk2rc = $HOME/.gtkrc-2.0 -> .gtkrc-2.0
|
239
|
+
gtk3rc = $HOME/.config/gtk-3.0 -> .config/gtk-3.0
|
240
|
+
gtk4rc = $HOME/.config/gtk-4.0 -> .config/gtk-4.0
|
241
|
+
qt5conf = $HOME/.config/Trolltech.conf -> .config/Trolltech.conf
|
242
|
+
qt5ctconf = $HOME/.config/qt5ct/qt5ct.conf -> .config/qt5ct/qt5ct.conf
|
243
|
+
ariaconf = $HOME/.config/aria2/aria2.conf -> .config/aria2/aria2.conf
|
244
|
+
speechconf = $HOME/.config/speech-dispatcher -> .config/speech-dispatcher
|
245
|
+
|
246
|
+
|
247
|
+
# Environment variables set for the container using invoking podman/docker environment.
|
248
|
+
# Environment variables in values can be specified like usual which are expanded by
|
249
|
+
# python expandvars as usual.
|
250
|
+
#
|
251
|
+
# X, pulse and other such environment variables are set automatically by the settings
|
252
|
+
# in the [base] section but one can override/add to them explicitly here if required.
|
253
|
+
#
|
254
|
+
# Keys without values can be specified which are sent as such to the "-e" option
|
255
|
+
# which means they will be set and passed if set in the invoking podman/docker environment.
|
256
|
+
#
|
257
|
+
# Special note on LD_LIBRARY_PATH: the "nvidia=on" directive in the [base] section sets up
|
258
|
+
# LD_LIBRARY_PATH to point to internally created NVIDIA library directories shared from
|
259
|
+
# the host environment. So explicitly setting LD_LIBRARY_PATH below will break NVIDIA
|
260
|
+
# unless one also figures out and adds the internally added paths to LD_LIBRARY_PATH.
|
261
|
+
[env]
|
262
|
+
TERM
|
263
|
+
TERMINFO_DIRS = /usr/share/terminfo:/var/lib/terminfo
|
264
|
+
XDG_CURRENT_DESKTOP
|
265
|
+
XDG_SESSION_DESKTOP
|
266
|
+
XDG_SESSION_TYPE
|
267
|
+
DESKTOP_SESSION
|
268
|
+
GTK_IM_MODULE
|
269
|
+
QT_IM_MODULE
|
270
|
+
SDL_IM_MODULE
|
271
|
+
XMODIFIERS
|
272
|
+
|
273
|
+
|
274
|
+
# Additional apps to be installed in the container. Note that these are installed
|
275
|
+
# on first container startup and will go away if the container is removed, so you
|
276
|
+
# should keep persistent data related to apps on separate persistent storage
|
277
|
+
# specified in the [mounts] section above.
|
278
|
+
[apps]
|
279
|
+
# The format is a unique name followed by comma separated package names of the distro
|
280
|
+
# specific packages. The package name may have a ':dep(<pkg>)' suffix that indicates it is being
|
281
|
+
# installed as an optional dependency of another package which is mentioned in the parentheses.
|
282
|
+
# For example (package names are from pacman) -- also notice multiline value for 'firefox_deps':
|
283
|
+
#firefox = firefox
|
284
|
+
#firefox_deps = hunspell-en_us:dep(firefox),libnotify:dep(firefox),
|
285
|
+
# speech-dispatcher:dep(firefox)
|
286
|
+
|
287
|
+
|
288
|
+
# Default flags can be added to specified programs when launching them via their wrapper
|
289
|
+
# desktop files or wrapper executables
|
290
|
+
[app_flags]
|
291
|
+
# These flags/arguments will be added to Exec line of chromium.desktop when it is copied to
|
292
|
+
# host as well as in the wrapper chromium executable created on the host.
|
293
|
+
# You can use "!p" here for the first argument in the 'Exec='/'TryExec=' line in the desktop
|
294
|
+
# file and '!a' for rest of the arguments. When linking to an executable program, '!p' will
|
295
|
+
# refer to the full path of the executable while '!a' will be replaced by "$@" in the shell
|
296
|
+
# script. Use '!!p' for a literal '!p' and '!!a' for a literal '!a'.
|
297
|
+
|
298
|
+
# /dev/shm usage is disabled for chromium because that requires ipc=host or mounting host
|
299
|
+
# /dev/shm in read-write mode which is quite insecure.
|
300
|
+
chromium = !p --disable-dev-shm-usage --enable-chrome-browser-cloud-management !a
|
301
|
+
|
302
|
+
|
303
|
+
# Startup programs you want to run when starting the container. These are run using
|
304
|
+
# /bin/bash shell of the container, so you can use shell variables if required.
|
305
|
+
# These programs are run as normal container user, so if you need to run using root
|
306
|
+
# account then add 'sudo' before the command.
|
307
|
+
[startup]
|
308
|
+
# for example you can avoid sharing dbus of the original session rather start a separate one
|
309
|
+
#dbus = /usr/bin/dbus-daemon --session
|
310
|
+
#dbus_sys = sudo /usr/bin/dbus-daemon --system
|