ybox 0.9.10__tar.gz → 0.9.11.1__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.
Files changed (113) hide show
  1. {ybox-0.9.10/src/ybox.egg-info → ybox-0.9.11.1}/PKG-INFO +30 -19
  2. {ybox-0.9.10 → ybox-0.9.11.1}/README.md +26 -16
  3. {ybox-0.9.10 → ybox-0.9.11.1}/pyproject.toml +1 -1
  4. {ybox-0.9.10 → ybox-0.9.11.1}/src/ybox/__init__.py +1 -1
  5. {ybox-0.9.10 → ybox-0.9.11.1}/src/ybox/conf/profiles/apps.ini +10 -5
  6. {ybox-0.9.10 → ybox-0.9.11.1}/src/ybox/conf/profiles/basic.ini +23 -11
  7. {ybox-0.9.10 → ybox-0.9.11.1}/src/ybox/conf/profiles/dev.ini +4 -0
  8. {ybox-0.9.10 → ybox-0.9.11.1}/src/ybox/conf/resources/entrypoint-cp.sh +1 -1
  9. {ybox-0.9.10 → ybox-0.9.11.1}/src/ybox/conf/resources/entrypoint-root.sh +3 -3
  10. {ybox-0.9.10 → ybox-0.9.11.1}/src/ybox/conf/resources/entrypoint.sh +2 -9
  11. {ybox-0.9.10 → ybox-0.9.11.1}/src/ybox/conf/resources/run-in-dir +26 -16
  12. {ybox-0.9.10 → ybox-0.9.11.1}/src/ybox/conf/resources/ybox-systemd.template +7 -5
  13. {ybox-0.9.10 → ybox-0.9.11.1}/src/ybox/env.py +18 -7
  14. ybox-0.9.10/src/ybox/migrate/0.9.0-0.9.7:0.9.8.py → ybox-0.9.11.1/src/ybox/migrate/0.9.0-0.9.10:0.9.11.py +6 -5
  15. {ybox-0.9.10 → ybox-0.9.11.1}/src/ybox/pkg/inst.py +22 -10
  16. {ybox-0.9.10 → ybox-0.9.11.1}/src/ybox/pkg/mark.py +1 -1
  17. {ybox-0.9.10 → ybox-0.9.11.1}/src/ybox/run/control.py +17 -2
  18. {ybox-0.9.10 → ybox-0.9.11.1}/src/ybox/run/create.py +98 -45
  19. {ybox-0.9.10 → ybox-0.9.11.1}/src/ybox/run/destroy.py +32 -10
  20. {ybox-0.9.10 → ybox-0.9.11.1}/src/ybox/run/graphics.py +37 -17
  21. {ybox-0.9.10 → ybox-0.9.11.1}/src/ybox/run/pkg.py +3 -3
  22. {ybox-0.9.10 → ybox-0.9.11.1/src/ybox.egg-info}/PKG-INFO +30 -19
  23. {ybox-0.9.10 → ybox-0.9.11.1}/src/ybox.egg-info/SOURCES.txt +2 -2
  24. ybox-0.9.11.1/tests/resources/migration/0.9.0.db.gz +0 -0
  25. ybox-0.9.11.1/tests/resources/migration/0.9.1.db.gz +0 -0
  26. ybox-0.9.11.1/tests/resources/migration/0.9.10.db.gz +0 -0
  27. ybox-0.9.11.1/tests/resources/migration/0.9.2.db.gz +0 -0
  28. ybox-0.9.11.1/tests/resources/migration/0.9.5.db.gz +0 -0
  29. ybox-0.9.11.1/tests/resources/migration/0.9.6.db.gz +0 -0
  30. ybox-0.9.11.1/tests/resources/migration/0.9.7.db.gz +0 -0
  31. {ybox-0.9.10 → ybox-0.9.11.1}/tests/unit/test_env.py +2 -0
  32. {ybox-0.9.10 → ybox-0.9.11.1}/tests/unit/test_filelock.py +0 -1
  33. {ybox-0.9.10 → ybox-0.9.11.1}/tests/unit/test_state.py +1 -1
  34. ybox-0.9.10/tests/resources/migration/0.9.0.db.gz +0 -0
  35. ybox-0.9.10/tests/resources/migration/0.9.1.db.gz +0 -0
  36. ybox-0.9.10/tests/resources/migration/0.9.2.db.gz +0 -0
  37. ybox-0.9.10/tests/resources/migration/0.9.5.db.gz +0 -0
  38. ybox-0.9.10/tests/resources/migration/0.9.6.db.gz +0 -0
  39. ybox-0.9.10/tests/resources/migration/0.9.7.db.gz +0 -0
  40. ybox-0.9.10/tests/resources/migration/0.9.8.db.gz +0 -0
  41. {ybox-0.9.10 → ybox-0.9.11.1}/LICENSE +0 -0
  42. {ybox-0.9.10 → ybox-0.9.11.1}/MANIFEST.in +0 -0
  43. {ybox-0.9.10 → ybox-0.9.11.1}/setup.cfg +0 -0
  44. {ybox-0.9.10 → ybox-0.9.11.1}/src/ybox/cmd.py +0 -0
  45. {ybox-0.9.10 → ybox-0.9.11.1}/src/ybox/conf/completions/ybox.fish +0 -0
  46. {ybox-0.9.10 → ybox-0.9.11.1}/src/ybox/conf/distros/arch/add-gpg-key.sh +0 -0
  47. {ybox-0.9.10 → ybox-0.9.11.1}/src/ybox/conf/distros/arch/distro.ini +0 -0
  48. {ybox-0.9.10 → ybox-0.9.11.1}/src/ybox/conf/distros/arch/init-base.sh +0 -0
  49. {ybox-0.9.10 → ybox-0.9.11.1}/src/ybox/conf/distros/arch/init-user.sh +0 -0
  50. {ybox-0.9.10 → ybox-0.9.11.1}/src/ybox/conf/distros/arch/init.sh +0 -0
  51. {ybox-0.9.10 → ybox-0.9.11.1}/src/ybox/conf/distros/arch/list_fmt_long.py +0 -0
  52. {ybox-0.9.10 → ybox-0.9.11.1}/src/ybox/conf/distros/arch/pkgdeps.py +0 -0
  53. {ybox-0.9.10 → ybox-0.9.11.1}/src/ybox/conf/distros/deb-generic/check-package.sh +0 -0
  54. {ybox-0.9.10 → ybox-0.9.11.1}/src/ybox/conf/distros/deb-generic/distro.ini +0 -0
  55. {ybox-0.9.10 → ybox-0.9.11.1}/src/ybox/conf/distros/deb-generic/fetch-gpg-key-id.sh +0 -0
  56. {ybox-0.9.10 → ybox-0.9.11.1}/src/ybox/conf/distros/deb-generic/init-base.sh +0 -0
  57. {ybox-0.9.10 → ybox-0.9.11.1}/src/ybox/conf/distros/deb-generic/init-user.sh +0 -0
  58. {ybox-0.9.10 → ybox-0.9.11.1}/src/ybox/conf/distros/deb-generic/init.sh +0 -0
  59. {ybox-0.9.10 → ybox-0.9.11.1}/src/ybox/conf/distros/deb-generic/list_fmt_long.py +0 -0
  60. {ybox-0.9.10 → ybox-0.9.11.1}/src/ybox/conf/distros/deb-generic/pkgdeps.py +0 -0
  61. {ybox-0.9.10 → ybox-0.9.11.1}/src/ybox/conf/distros/deb-oldstable/distro.ini +0 -0
  62. {ybox-0.9.10 → ybox-0.9.11.1}/src/ybox/conf/distros/deb-stable/distro.ini +0 -0
  63. {ybox-0.9.10 → ybox-0.9.11.1}/src/ybox/conf/distros/supported.list +0 -0
  64. {ybox-0.9.10 → ybox-0.9.11.1}/src/ybox/conf/distros/ubuntu2204/distro.ini +0 -0
  65. {ybox-0.9.10 → ybox-0.9.11.1}/src/ybox/conf/distros/ubuntu2404/distro.ini +0 -0
  66. {ybox-0.9.10 → ybox-0.9.11.1}/src/ybox/conf/profiles/games.ini +0 -0
  67. {ybox-0.9.10 → ybox-0.9.11.1}/src/ybox/conf/resources/entrypoint-base.sh +0 -0
  68. {ybox-0.9.10 → ybox-0.9.11.1}/src/ybox/conf/resources/entrypoint-common.sh +0 -0
  69. {ybox-0.9.10 → ybox-0.9.11.1}/src/ybox/conf/resources/entrypoint-user.sh +0 -0
  70. {ybox-0.9.10 → ybox-0.9.11.1}/src/ybox/conf/resources/prime-run +0 -0
  71. {ybox-0.9.10 → ybox-0.9.11.1}/src/ybox/conf/resources/run-user-bash-cmd +0 -0
  72. {ybox-0.9.10 → ybox-0.9.11.1}/src/ybox/config.py +0 -0
  73. {ybox-0.9.10 → ybox-0.9.11.1}/src/ybox/filelock.py +0 -0
  74. {ybox-0.9.10 → ybox-0.9.11.1}/src/ybox/pkg/__init__.py +0 -0
  75. {ybox-0.9.10 → ybox-0.9.11.1}/src/ybox/pkg/clean.py +0 -0
  76. {ybox-0.9.10 → ybox-0.9.11.1}/src/ybox/pkg/info.py +0 -0
  77. {ybox-0.9.10 → ybox-0.9.11.1}/src/ybox/pkg/list.py +0 -0
  78. {ybox-0.9.10 → ybox-0.9.11.1}/src/ybox/pkg/repair.py +0 -0
  79. {ybox-0.9.10 → ybox-0.9.11.1}/src/ybox/pkg/repo.py +0 -0
  80. {ybox-0.9.10 → ybox-0.9.11.1}/src/ybox/pkg/search.py +0 -0
  81. {ybox-0.9.10 → ybox-0.9.11.1}/src/ybox/pkg/uninst.py +0 -0
  82. {ybox-0.9.10 → ybox-0.9.11.1}/src/ybox/pkg/update.py +0 -0
  83. {ybox-0.9.10 → ybox-0.9.11.1}/src/ybox/print.py +0 -0
  84. {ybox-0.9.10 → ybox-0.9.11.1}/src/ybox/run/__init__.py +0 -0
  85. {ybox-0.9.10 → ybox-0.9.11.1}/src/ybox/run/cmd.py +0 -0
  86. {ybox-0.9.10 → ybox-0.9.11.1}/src/ybox/run/logs.py +0 -0
  87. {ybox-0.9.10 → ybox-0.9.11.1}/src/ybox/run/ls.py +0 -0
  88. {ybox-0.9.10 → ybox-0.9.11.1}/src/ybox/schema/0.9.1-added.sql +0 -0
  89. {ybox-0.9.10 → ybox-0.9.11.1}/src/ybox/schema/0.9.6-added.sql +0 -0
  90. {ybox-0.9.10 → ybox-0.9.11.1}/src/ybox/schema/init.sql +0 -0
  91. {ybox-0.9.10 → ybox-0.9.11.1}/src/ybox/schema/migrate/0.9.0:0.9.1.sql +0 -0
  92. {ybox-0.9.10 → ybox-0.9.11.1}/src/ybox/schema/migrate/0.9.1:0.9.2.sql +0 -0
  93. {ybox-0.9.10 → ybox-0.9.11.1}/src/ybox/schema/migrate/0.9.2:0.9.3.sql +0 -0
  94. {ybox-0.9.10 → ybox-0.9.11.1}/src/ybox/schema/migrate/0.9.5:0.9.6.sql +0 -0
  95. {ybox-0.9.10 → ybox-0.9.11.1}/src/ybox/state.py +0 -0
  96. {ybox-0.9.10 → ybox-0.9.11.1}/src/ybox/util.py +0 -0
  97. {ybox-0.9.10 → ybox-0.9.11.1}/src/ybox.egg-info/dependency_links.txt +0 -0
  98. {ybox-0.9.10 → ybox-0.9.11.1}/src/ybox.egg-info/entry_points.txt +0 -0
  99. {ybox-0.9.10 → ybox-0.9.11.1}/src/ybox.egg-info/requires.txt +0 -0
  100. {ybox-0.9.10 → ybox-0.9.11.1}/src/ybox.egg-info/top_level.txt +0 -0
  101. {ybox-0.9.10 → ybox-0.9.11.1}/tests/create_migration_db.py +0 -0
  102. {ybox-0.9.10 → ybox-0.9.11.1}/tests/functional/__init__.py +0 -0
  103. {ybox-0.9.10 → ybox-0.9.11.1}/tests/functional/distro_base.py +0 -0
  104. {ybox-0.9.10 → ybox-0.9.11.1}/tests/functional/test_create_destroy.py +0 -0
  105. {ybox-0.9.10 → ybox-0.9.11.1}/tests/resources/basic_no_shared.ini +0 -0
  106. {ybox-0.9.10 → ybox-0.9.11.1}/tests/resources/containers.json +0 -0
  107. {ybox-0.9.10 → ybox-0.9.11.1}/tests/resources/distro_minimal.ini +0 -0
  108. {ybox-0.9.10 → ybox-0.9.11.1}/tests/resources/packages.json +0 -0
  109. {ybox-0.9.10 → ybox-0.9.11.1}/tests/resources/repos.json +0 -0
  110. {ybox-0.9.10 → ybox-0.9.11.1}/tests/unit/__init__.py +0 -0
  111. {ybox-0.9.10 → ybox-0.9.11.1}/tests/unit/test_cmd.py +0 -0
  112. {ybox-0.9.10 → ybox-0.9.11.1}/tests/unit/test_config.py +0 -0
  113. {ybox-0.9.10 → ybox-0.9.11.1}/tests/unit/util.py +0 -0
@@ -1,6 +1,6 @@
1
- Metadata-Version: 2.2
1
+ Metadata-Version: 2.4
2
2
  Name: ybox
3
- Version: 0.9.10
3
+ Version: 0.9.11.1
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
@@ -25,7 +25,7 @@ License: Copyright (c) 2024-2025 Sumedh Wale and contributors
25
25
 
26
26
  Project-URL: Homepage, https://github.com/sumwale/ybox
27
27
  Project-URL: Issues, https://github.com/sumwale/ybox/issues
28
- Keywords: Linux in container,toolbox
28
+ Keywords: Linux in container,toolbox,distrobox
29
29
  Classifier: Development Status :: 4 - Beta
30
30
  Classifier: Intended Audience :: End Users/Desktop
31
31
  Classifier: License :: OSI Approved :: MIT License
@@ -42,6 +42,7 @@ License-File: LICENSE
42
42
  Requires-Dist: packaging
43
43
  Requires-Dist: simple-term-menu
44
44
  Requires-Dist: tabulate>=0.9.0
45
+ Dynamic: license-file
45
46
 
46
47
  ## Introduction
47
48
 
@@ -99,7 +100,7 @@ So, for example, if you want to run the latest and greatest Intellij IDEA commun
99
100
  to do is:
100
101
 
101
102
  ```sh
102
- # create an Arch Linux based container
103
+ # create an Arch Linux based container and generate systemd service file (if possible)
103
104
  ybox-create arch
104
105
  # then select an appropriate built-in profile e.g. "dev.ini" from the menu
105
106
 
@@ -197,6 +198,8 @@ to point to the full path of the podman or docker executable.
197
198
  ybox-create
198
199
  ```
199
200
 
201
+ By default this will also generate a user systemd service if possible (add `-S` or
202
+ `--skip-systemd-service` option to skip creation of a user systemd service).
200
203
  This will allow choosing from supported distributions, then from the available profiles.
201
204
  You can start with the Arch Linux distribution and `apps.ini` profile to try it out. The container
202
205
  will have a name like `ybox-<distribution>_<profile>` by default like `ybox-arch_apps` for the
@@ -269,7 +272,7 @@ ybox-pkg list -o
269
272
  ```
270
273
  To show more details of the packages (combine with -a/-o as required):
271
274
  ```sh
272
- ybox-pkg list -o
275
+ ybox-pkg list -v
273
276
  ```
274
277
 
275
278
  List all the files installed by the package:
@@ -309,6 +312,8 @@ Clean package cache, temporary downloads etc:
309
312
  ```sh
310
313
  ybox-pkg clean
311
314
  ```
315
+ Add `-q` option to answer yes for any questions automatically if all your containers use
316
+ the same shared root.
312
317
 
313
318
  Mark a package as explicitly installed (also registers with `ybox-pkg` if not present):
314
319
  ```sh
@@ -317,7 +322,7 @@ ybox-pkg mark firefox -e
317
322
 
318
323
  Mark a package as a dependency of another (also registers with `ybox-pkg` if not present):
319
324
  ```sh
320
- ybox-pkg mark qt5ct -D zoom # mark qt5ct as an optional dependency of zoom
325
+ ybox-pkg mark qt5ct -d zoom # mark qt5ct as an optional dependency of zoom
321
326
  ```
322
327
 
323
328
  Repair package installation after a failure or interrupt:
@@ -437,26 +442,32 @@ for a ybox container. See the full set of options with `ybox-control -h/--help`.
437
442
  ### Auto-starting containers
438
443
 
439
444
  Containers can be auto-started as per the usual way for rootless podman/docker services.
440
- This is triggered by systemd on user login which is exactly what we want for ybox
445
+ This is triggered by systemd on user login which is exactly what is required for ybox
441
446
  containers so that the container applications are available on login and are stopped on
442
- session logout. For docker the following should suffice:
447
+ session logout. All the tested Linux distributions support this and provide for user
448
+ systemd daemon on user login.
443
449
 
444
- ```sh
445
- systemctl --user enable docker
446
- ```
450
+ The `ybox-create` command autogenerates the systemd service file (in absence of `-S` or
451
+ `--skip-systemd-service` option) which is also removed by `ybox-destroy` automatically.
452
+ The name of the generated service is `ybox-<NAME>` where `<NAME>` is the name of the
453
+ container if `<NAME>` does not start with `ybox-` prefix, else it is just `<NAME>`.
447
454
 
448
- See [docker docs](https://docs.docker.com/engine/security/rootless/#daemon) for details.
449
-
450
- For podman you will need to explicitly generate systemd service file for each container and
451
- copy to your systemd configuration directory since podman does not use a background daemon.
452
- For the `ybox-arch_apps` container in the examples before:
455
+ With a user service installed, the `systemctl` commands can be used to control the
456
+ ybox container (`<SERVICE_NAME>` is `ybox-<NAME>/<NAME>` mentioned above):
453
457
 
454
458
  ```sh
455
- mkdir -p ~/.config/systemd/user/
456
- podman generate systemd --name ybox-arch_apps > ~/.config/systemd/user/container-ybox-arch_apps.service
457
- systemctl --user enable container-ybox-arch_apps.service
459
+ systemctl --user status <SERVICE_NAME> # show status of the service
460
+ systemctl --user stop <SERVICE_NAME> # stop the service
461
+ systemctl --user start <SERVICE_NAME> # start the service
458
462
  ```
459
463
 
464
+ If your Linux distribution does not use systemd, then the autostart has to be handled
465
+ manually as per the distribution's preferred way. For instance an appropriate desktop
466
+ file can be added to `~/.config/autostart` directory to start a ybox container on
467
+ graphical login, though performing a clean stop can be hard with this approach.
468
+ Note that the preferred way to start/stop a ybox container is using the `ybox-control`
469
+ command rather than directly using podman/docker.
470
+
460
471
 
461
472
  ## Development
462
473
 
@@ -54,7 +54,7 @@ So, for example, if you want to run the latest and greatest Intellij IDEA commun
54
54
  to do is:
55
55
 
56
56
  ```sh
57
- # create an Arch Linux based container
57
+ # create an Arch Linux based container and generate systemd service file (if possible)
58
58
  ybox-create arch
59
59
  # then select an appropriate built-in profile e.g. "dev.ini" from the menu
60
60
 
@@ -152,6 +152,8 @@ to point to the full path of the podman or docker executable.
152
152
  ybox-create
153
153
  ```
154
154
 
155
+ By default this will also generate a user systemd service if possible (add `-S` or
156
+ `--skip-systemd-service` option to skip creation of a user systemd service).
155
157
  This will allow choosing from supported distributions, then from the available profiles.
156
158
  You can start with the Arch Linux distribution and `apps.ini` profile to try it out. The container
157
159
  will have a name like `ybox-<distribution>_<profile>` by default like `ybox-arch_apps` for the
@@ -224,7 +226,7 @@ ybox-pkg list -o
224
226
  ```
225
227
  To show more details of the packages (combine with -a/-o as required):
226
228
  ```sh
227
- ybox-pkg list -o
229
+ ybox-pkg list -v
228
230
  ```
229
231
 
230
232
  List all the files installed by the package:
@@ -264,6 +266,8 @@ Clean package cache, temporary downloads etc:
264
266
  ```sh
265
267
  ybox-pkg clean
266
268
  ```
269
+ Add `-q` option to answer yes for any questions automatically if all your containers use
270
+ the same shared root.
267
271
 
268
272
  Mark a package as explicitly installed (also registers with `ybox-pkg` if not present):
269
273
  ```sh
@@ -272,7 +276,7 @@ ybox-pkg mark firefox -e
272
276
 
273
277
  Mark a package as a dependency of another (also registers with `ybox-pkg` if not present):
274
278
  ```sh
275
- ybox-pkg mark qt5ct -D zoom # mark qt5ct as an optional dependency of zoom
279
+ ybox-pkg mark qt5ct -d zoom # mark qt5ct as an optional dependency of zoom
276
280
  ```
277
281
 
278
282
  Repair package installation after a failure or interrupt:
@@ -392,26 +396,32 @@ for a ybox container. See the full set of options with `ybox-control -h/--help`.
392
396
  ### Auto-starting containers
393
397
 
394
398
  Containers can be auto-started as per the usual way for rootless podman/docker services.
395
- This is triggered by systemd on user login which is exactly what we want for ybox
399
+ This is triggered by systemd on user login which is exactly what is required for ybox
396
400
  containers so that the container applications are available on login and are stopped on
397
- session logout. For docker the following should suffice:
401
+ session logout. All the tested Linux distributions support this and provide for user
402
+ systemd daemon on user login.
398
403
 
399
- ```sh
400
- systemctl --user enable docker
401
- ```
404
+ The `ybox-create` command autogenerates the systemd service file (in absence of `-S` or
405
+ `--skip-systemd-service` option) which is also removed by `ybox-destroy` automatically.
406
+ The name of the generated service is `ybox-<NAME>` where `<NAME>` is the name of the
407
+ container if `<NAME>` does not start with `ybox-` prefix, else it is just `<NAME>`.
402
408
 
403
- See [docker docs](https://docs.docker.com/engine/security/rootless/#daemon) for details.
404
-
405
- For podman you will need to explicitly generate systemd service file for each container and
406
- copy to your systemd configuration directory since podman does not use a background daemon.
407
- For the `ybox-arch_apps` container in the examples before:
409
+ With a user service installed, the `systemctl` commands can be used to control the
410
+ ybox container (`<SERVICE_NAME>` is `ybox-<NAME>/<NAME>` mentioned above):
408
411
 
409
412
  ```sh
410
- mkdir -p ~/.config/systemd/user/
411
- podman generate systemd --name ybox-arch_apps > ~/.config/systemd/user/container-ybox-arch_apps.service
412
- systemctl --user enable container-ybox-arch_apps.service
413
+ systemctl --user status <SERVICE_NAME> # show status of the service
414
+ systemctl --user stop <SERVICE_NAME> # stop the service
415
+ systemctl --user start <SERVICE_NAME> # start the service
413
416
  ```
414
417
 
418
+ If your Linux distribution does not use systemd, then the autostart has to be handled
419
+ manually as per the distribution's preferred way. For instance an appropriate desktop
420
+ file can be added to `~/.config/autostart` directory to start a ybox container on
421
+ graphical login, though performing a clean stop can be hard with this approach.
422
+ Note that the preferred way to start/stop a ybox container is using the `ybox-control`
423
+ command rather than directly using podman/docker.
424
+
415
425
 
416
426
  ## Development
417
427
 
@@ -30,7 +30,7 @@ classifiers = [
30
30
  "Programming Language :: Python :: 3.12",
31
31
  "Programming Language :: Python :: 3.13",
32
32
  ]
33
- keywords = ["Linux in container", "toolbox"]
33
+ keywords = ["Linux in container", "toolbox", "distrobox"]
34
34
 
35
35
  [project.urls]
36
36
  Homepage = "https://github.com/sumwale/ybox"
@@ -1,2 +1,2 @@
1
1
  """`ybox` is a tool to easily manage linux distributions in containers"""
2
- __version__ = "0.9.10"
2
+ __version__ = "0.9.11.1"
@@ -1,6 +1,7 @@
1
1
  [base]
2
2
  name = Profile for CLI and GUI apps
3
3
  includes = basic.ini
4
+ ssh_agent = on
4
5
 
5
6
  [security]
6
7
  # SYS_PTRACE may be required by mesa which is invoked indirectly by both firefox and chromium.
@@ -9,6 +10,9 @@ includes = basic.ini
9
10
  caps_add = SYS_PTRACE
10
11
 
11
12
  [mounts]
13
+ # export the host's ssh keys for use by ssh-agent in the container as required ("ro" mode
14
+ # implies that known_hosts and other files within ~/.ssh cannot be changed)
15
+ ssh = $HOME/.ssh:$TARGET_HOME/.ssh:ro
12
16
  music = $HOME/Music:$TARGET_HOME/Music:ro
13
17
  pictures = $HOME/Pictures:$TARGET_HOME/Pictures:ro
14
18
  videos = $HOME/Videos:$TARGET_HOME/Videos:ro
@@ -19,8 +23,9 @@ videos = $HOME/Videos:$TARGET_HOME/Videos:ro
19
23
 
20
24
  [app_flags]
21
25
  # These flags will be added to Exec line of google-chrome.desktop when it is copied to host.
22
- # /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
26
+
27
+ # the --disable-dev-shm-usage flag in chrome/chromium based browsers disables use of /dev/shm
28
+ # which can reduce memory footprint at the cost of performance and increased disk activity
29
+ #google-chrome = !p --disable-dev-shm-usage !a
30
+ #google-chrome-beta = !p --disable-dev-shm-usage !a
31
+ #google-chrome-unstable = !p --disable-dev-shm-usage !a
@@ -20,8 +20,8 @@
20
20
  # - YBOX_SYS_CONF_DIR: path to system configuration directory where configuration directory
21
21
  # shipped with ybox is installed (or the string form of
22
22
  # the directory if it is not on filesystem like an egg or similar)
23
- # - TARGET_HOME: set to the home directory of the container user as it exists on the host
24
- # (i.e. the expanded value of the "home" key in the [base] section)
23
+ # - TARGET_HOME: set to the home directory of the container user in the container
24
+ # (which is same as the host user's $HOME for podman and /root for docker)
25
25
  # Additionally a special notation can be used for current date+time with this notation:
26
26
  # ${NOW:<fmt>}. The <fmt> uses the format supported by python strftime
27
27
  # (https://docs.python.org/3/library/datetime.html#datetime.datetime.strftime)
@@ -67,7 +67,7 @@ includes =
67
67
  # to freely create as many containers as desired to achieve best isolation without worrying
68
68
  # about dramatic increase in disk and/or memory usage.
69
69
  shared_root = $HOME/.local/share/ybox/SHARED_ROOTS/$YBOX_DISTRIBUTION_NAME
70
- # Bind mount the container $HOME to this local path (aka $TARGET_HOME). This makes it
70
+ # Bind mount the container $HOME to this local path. This makes it
71
71
  # easier for backup software and otherwise to read useful container data.
72
72
  # If not provided then you should explicitly mount required directories in the [mounts]
73
73
  # section otherwise home will remain completely ephemeral which is not recommended.
@@ -100,6 +100,16 @@ pulseaudio = on
100
100
  dbus = on
101
101
  # If enabled then the system dbus from the host is available to the container.
102
102
  dbus_sys = off
103
+ # If enabled then the socket for SSH agent, if present, is made available to the container.
104
+ # The $SSH_AUTH_SOCK environment variables must be set in the host environment for this to work.
105
+ # You can also mount $HOME/.ssh with appropriate flags ("ro" if possible) in the [mounts]
106
+ # section to enable the container use the host's ssh keys.
107
+ ssh_agent = off
108
+ # If enabled then the socket for GPG agent, if present, is made available to the container.
109
+ # The $GPG_AGENT_INFO environment variable must be set in the host environment for this to work.
110
+ # You can also mount $HOME/.gnupg with appropriate flags ("ro" if possible) in the [mounts]
111
+ # section to enable the container use the host's gpg keys.
112
+ gpg_agent = off
103
113
  # If enabled then Direct Rendering Infrastructure for accelerated graphics is available to
104
114
  # the container.
105
115
  dri = on
@@ -123,8 +133,8 @@ nvidia = off
123
133
  #
124
134
  # This will take precedence if both "nvidia" and "nvidia_ctk" are enabled.
125
135
  nvidia_ctk = off
126
- # default podman/docker shm-size is 64m which can be insufficient for many apps
127
- shm_size = 1g
136
+ # default podman/docker shm-size is only 64m which can be insufficient for many apps
137
+ shm_size = 2g
128
138
  # Limit the maximum number of processes in the container (to avoid stuff like fork bombs).
129
139
  pids_limit = 2048
130
140
  # Logging driver to use. Default for podman/docker is to use journald in modern Linux
@@ -137,6 +147,9 @@ log_driver = json-file
137
147
  # Example for docker that does not support `path`
138
148
  log_opts = max-size=10m,max-file=3
139
149
 
150
+ # Comma separated list of additional devices that should be made available to the container using
151
+ # the --device option to podman/docker run. Example: devices = /dev/video0,/dev/ttyUSB0
152
+ devices =
140
153
 
141
154
  # The security-opt and other security options passed to podman/docker.
142
155
  # You should restrict these as required.
@@ -227,9 +240,10 @@ documents = $HOME/Documents:$TARGET_HOME/Documents:ro
227
240
  # in the [base] section.
228
241
  #
229
242
  # Note: The LHS should typically have a path having $HOME while RHS will be relative to the
230
- # target's home inside the container. Do not use $TARGET_HOME on RHS (or LHS for that matter)
231
- # which is the target's home as on the host and not the one inside the container.
243
+ # target's home inside the container. Do not use $TARGET_HOME on RHS since path the assumed
244
+ # to be a relative one and $TARGET_HOME already inserted as required.
232
245
  [configs]
246
+ env_conf = $HOME/.config/environment.d -> .config/environment.d
233
247
  bashrc = $HOME/.bashrc -> .bashrc
234
248
  starship = $HOME/.config/starship.toml -> .config/starship.toml
235
249
  # replicate fish configuration directory with copy of fish_variables but symlinks for the rest
@@ -303,14 +317,12 @@ XMODIFIERS
303
317
  [app_flags]
304
318
  # These flags/arguments will be added to Exec line of chromium.desktop when it is copied to
305
319
  # host as well as in the wrapper chromium executable created on the host.
306
- # You can use "!p" here for the first argument in the 'Exec='/'TryExec=' line in the desktop
320
+ # You can use "!p" here for the first argument in the 'Exec=' line in the desktop
307
321
  # file and '!a' for rest of the arguments. When linking to an executable program, '!p' will
308
322
  # refer to the full path of the executable while '!a' will be replaced by "$@" in the shell
309
323
  # script. Use '!!p' for a literal '!p' and '!!a' for a literal '!a'.
310
324
 
311
- # /dev/shm usage is disabled for chromium because that requires ipc=host or mounting host
312
- # /dev/shm in read-write mode which is quite insecure.
313
- chromium = !p --disable-dev-shm-usage --enable-chrome-browser-cloud-management !a
325
+ chromium = !p --enable-chrome-browser-cloud-management !a
314
326
 
315
327
 
316
328
  # Startup programs you want to run when starting the container. These are run using
@@ -1,6 +1,7 @@
1
1
  [base]
2
2
  name = Profile for creating development environment
3
3
  includes = basic.ini
4
+ ssh_agent = on
4
5
 
5
6
  [security]
6
7
  # SYS_PTRACE is required by mesa and without this, the following warning can be seen:
@@ -8,6 +9,9 @@ includes = basic.ini
8
9
  caps_add = SYS_PTRACE
9
10
 
10
11
  [mounts]
12
+ # export the host's ssh keys for use by ssh-agent in the container as required ("ro" mode
13
+ # implies that known_hosts and other files within ~/.ssh cannot be changed)
14
+ ssh = $HOME/.ssh:$TARGET_HOME/.ssh:ro
11
15
  # add your projects and other directories having source code
12
16
  #projects = $HOME/projects:$TARGET_HOME/projects
13
17
  #pyenv = $HOME/.pyenv:$TARGET_HOME/.pyenv:ro
@@ -28,5 +28,5 @@ echo_color "$fg_purple" "Copying data from container to shared root mounted on '
28
28
  IFS="," read -ra shared_dirs_arr <<< "$shared_dirs"
29
29
  for dir in "${shared_dirs_arr[@]}"; do
30
30
  echo_color "$fg_orange" "Copying $dir to $shared_bind$dir"
31
- cp -a "$dir" "$shared_bind$dir"
31
+ cp -an "$dir" "$shared_bind$dir"
32
32
  done
@@ -10,9 +10,9 @@ source "$SCRIPT_DIR/entrypoint-common.sh"
10
10
 
11
11
  export HOME=/root
12
12
  echo_color "$fg_cyan" "Copying prime-run, run-in-dir and run-user-bash-cmd" >> $status_file
13
- cp -a "$SCRIPT_DIR/prime-run" /usr/local/bin/prime-run
14
- cp -a "$SCRIPT_DIR/run-in-dir" /usr/local/bin/run-in-dir
15
- cp -a "$SCRIPT_DIR/run-user-bash-cmd" /usr/local/bin/run-user-bash-cmd
13
+ cp -af "$SCRIPT_DIR/prime-run" /usr/local/bin/prime-run
14
+ cp -af "$SCRIPT_DIR/run-in-dir" /usr/local/bin/run-in-dir
15
+ cp -af "$SCRIPT_DIR/run-user-bash-cmd" /usr/local/bin/run-user-bash-cmd
16
16
  chmod 0755 /usr/local/bin/prime-run /usr/local/bin/run-in-dir /usr/local/bin/run-user-bash-cmd
17
17
 
18
18
  # invoke the NVIDIA setup script if present
@@ -57,19 +57,12 @@ function replicate_config_files() {
57
57
  home_file="$HOME/${BASH_REMATCH[2]}"
58
58
  dest_file="$config_dir/${BASH_REMATCH[2]}"
59
59
  # only replace the file if it is already a link (assuming the link target may
60
- # have changed in the config_list file), or a directory containing links
60
+ # have changed in the config_list file), or a directory containing only links
61
61
  if [ -e "$dest_file" ]; then
62
62
  if [ -L "$home_file" ]; then
63
63
  rm -f "$home_file"
64
64
  elif [ -d "$home_file" ]; then
65
- do_rmdir=true
66
- for f in "$home_file"/*; do
67
- if [ -e "$f" -a ! -L "$f" ]; then
68
- do_rmdir=false
69
- break
70
- fi
71
- done
72
- if [ "$do_rmdir" = true ]; then
65
+ if [ -z $(find "$home_file" -type f -print -quit) ]; then
73
66
  rm -rf "$home_file"
74
67
  fi
75
68
  fi
@@ -9,24 +9,34 @@ if [ -n "$dir" -a -d "$dir" ]; then
9
9
  cd "$dir"
10
10
  fi
11
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
12
+ # XAUTHORITY, SSH_AUTH_SOCK and GPG_AGENT_INFO files can change after a re-login or a restart,
13
+ # so search for the passed one by podman/docker exec in the mount point of its parent directory
14
+ for env_var in XAUTHORITY SSH_AUTH_SOCK GPG_AGENT_INFO; do
15
+ env_var_orig=${env_var}_ORIG
16
+ var_val=${!env_var}
17
+ var_val_orig=${!env_var_orig}
18
+ if [ -n "$var_val" -a -n "$var_val_orig" ]; then
19
+ if [ ! -r "$var_val" ]; then
20
+ # the value should be in /run/user/<uid> or in /tmp, or else the parent directory is used
21
+ run_dir="${XDG_RUNTIME_DIR:-/run/user/$(id -u)}"
22
+ if [[ "$var_val" == $run_dir/* ]]; then
23
+ host_dir="$run_dir"
24
+ elif [[ "$var_val" == /tmp/* ]]; then
25
+ host_dir=/tmp
26
+ else
27
+ host_dir="$(dirname "$var_val")"
28
+ fi
29
+ new_val="${var_val/#$host_dir/${host_dir}-host}" # replace $host_dir by ${host_dir}-host
30
+ if [ ! -r "$new_val" ]; then
31
+ new_val="$var_val_orig"
32
+ fi
33
+ export $env_var="$new_val"
34
+ fi
21
35
  else
22
- host_dir="$(dirname "$XAUTHORITY")"
36
+ # remove unset variable in the container else apps can misbehave
37
+ unset $env_var
23
38
  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
39
+ done
30
40
 
31
41
  # In case NVIDIA driver has been updated, the updated libraries and other files may need to be
32
42
  # linked again, so check for a missing library file and invoke the setup script if present
@@ -8,15 +8,17 @@ Wants=network-online.target
8
8
  After=network-online.target
9
9
  {docker_requires}
10
10
  [Service]
11
- EnvironmentFile={env_file}
12
- Type=forking
11
+ Environment=PATH={sys_path}:{ybox_bin_dir}
12
+ EnvironmentFile=%h/.config/systemd/user/{env_file}
13
+ Type=notify
14
+ NotifyAccess=all
13
15
  Restart=on-failure
14
- TimeoutStopSec=70
15
16
  # sleep to allow for initialization of the user's login/graphical environment
16
17
  ExecStartPre=/usr/bin/sleep $SLEEP_SECS
17
- ExecStart=/bin/sh -c 'ybox-control start {name}'
18
+ ExecStart=/bin/sh -c 'ybox-control start {name} && systemd-notify --ready && exec ybox-control wait {name}'
18
19
  ExecStop=/bin/sh -c 'ybox-control stop -t 20 --ignore-stopped {name}'
19
20
  ExecStopPost=/bin/sh -c 'ybox-control stop -t 20 --ignore-stopped {name}'
20
- {pid_file}
21
+ TimeoutStopSec=60
22
+
21
23
  [Install]
22
24
  WantedBy=default.target
@@ -60,34 +60,41 @@ class Environ:
60
60
  :param home_dir: if a non-default user home directory has to be set
61
61
  """
62
62
  self._home_dir = home_dir or os.path.expanduser("~")
63
+ self._home_dir = self._home_dir.rstrip("/")
63
64
  self._docker_cmd = docker_cmd or get_docker_command()
64
65
  cmd_version = subprocess.check_output([self._docker_cmd, "--version"])
65
66
  self._uses_podman = "podman" in cmd_version.decode("utf-8").lower()
66
67
  # local user home might be in a different location than /home but target user in the
67
68
  # container will always be in /home with podman else /root for the root user with docker
68
69
  # as ensured by entrypoint-base.sh script
69
- target_uid = 0
70
+ current_user = getpass.getuser()
71
+ current_uid = pwd.getpwnam(current_user).pw_uid
70
72
  if self._uses_podman:
71
- self._target_user = getpass.getuser()
72
- target_uid = pwd.getpwnam(self._target_user).pw_uid
73
+ self._target_user = current_user
74
+ target_uid = current_uid
73
75
  self._target_home = f"/home/{self._target_user}"
74
76
  else:
75
77
  self._target_user = "root"
78
+ target_uid = 0
76
79
  self._target_home = "/root"
77
80
  # confirm that docker is being used in rootless mode (not required for podman because
78
81
  # it runs as rootless when run by a non-root user in any case without explicit sudo
79
82
  # which the ybox tools don't use)
80
83
  if (docker_ctx := subprocess.check_output(
81
84
  [self._docker_cmd, "context", "show"]).decode("utf-8")).strip() != "rootless":
82
- raise NotSupportedError("docker should use the rootless mode (see "
83
- "https://docs.docker.com/engine/security/rootless/) "
84
- f"but the current context is '{docker_ctx}'")
85
+ # check for DOCKER_HOST environment variable
86
+ expected_docker_host = f"unix:///run/user/{current_uid}/docker.sock"
87
+ if not docker_ctx or os.environ.get("DOCKER_HOST", "") != expected_docker_host:
88
+ raise NotSupportedError("docker should use the rootless mode (see "
89
+ "https://docs.docker.com/engine/security/rootless/) "
90
+ f"but the current context is '{docker_ctx}' and "
91
+ f"$DOCKER_HOST is not set to '{expected_docker_host}'")
85
92
  os.environ["TARGET_HOME"] = self._target_home
86
93
  self._user_base = user_base = site.getuserbase()
87
94
  target_user_base = f"{self._target_home}/.local"
88
95
  self._data_dir = f"{user_base}/share/ybox"
89
96
  self._target_data_dir = f"{target_user_base}/share/ybox"
90
- self._xdg_rt_dir = os.environ.get("XDG_RUNTIME_DIR", "")
97
+ self._xdg_rt_dir = os.environ.get("XDG_RUNTIME_DIR", "").rstrip("/")
91
98
  # the container user's one can be different because it is the root user for docker
92
99
  self._target_xdg_rt_dir = f"/run/user/{target_uid}"
93
100
  self._now = datetime.now()
@@ -148,6 +155,10 @@ class Environ:
148
155
  """if podman is the container manager being used"""
149
156
  return self._uses_podman
150
157
 
158
+ def systemd_user_conf_dir(self) -> str:
159
+ """standard configuration directory location of user specific systemd services"""
160
+ return f"{self._home_dir}/.config/systemd/user"
161
+
151
162
  @property
152
163
  def target_user(self) -> str:
153
164
  """username of the container user (which is the same as the current user for podman
@@ -20,11 +20,12 @@ copy_ybox_scripts_to_container(static_conf, distro_conf)
20
20
 
21
21
  # rename PKGMGR_CLEANUP to PKGMGR_CLEAN in pkgmgr.conf
22
22
  scripts_dir = static_conf.scripts_dir
23
- pkgmgr_conf = f"{scripts_dir}/pkgmgr.conf"
24
- with open(pkgmgr_conf, "r", encoding="utf-8") as pkgmgr_file:
25
- pkgmgr_data = pkgmgr_file.read()
26
- with open(pkgmgr_conf, "w", encoding="utf-8") as pkgmgr_file:
27
- pkgmgr_file.write(pkgmgr_data.replace("PKGMGR_CLEANUP", "PKGMGR_CLEAN"))
23
+ pkgmgr_conf = Path(f"{scripts_dir}/pkgmgr.conf")
24
+ if pkgmgr_conf.exists():
25
+ with pkgmgr_conf.open("r", encoding="utf-8") as pkgmgr_file:
26
+ pkgmgr_data = pkgmgr_file.read()
27
+ with pkgmgr_conf.open("w", encoding="utf-8") as pkgmgr_file:
28
+ pkgmgr_file.write(pkgmgr_data.replace("PKGMGR_CLEANUP", "PKGMGR_CLEAN"))
28
29
  # run entrypoint-root.sh again to refresh scripts and configuration
29
30
  subprocess.run([static_conf.env.docker_cmd, "exec", "-it", static_conf.box_name, "/usr/bin/sudo",
30
31
  "/bin/bash", f"{static_conf.target_scripts_dir}/entrypoint-root.sh"])