mirror of
https://github.com/termux/proot-distro.git
synced 2026-06-19 07:35:29 +00:00
changes to support regular host os
Prepare proot-distro for supporting Linux distribution as host system. 1. Option --termux-home renamed to --shared-home, alias --termux-home kept. 2. If host environment is not Termux, hide all Termux-specific stuff. 3. Change location of data files on non-Termux environment. 4. Don't prompt to install proot when it doesn't exist on non-Termux environment, just show an error.
This commit is contained in:
+1
-1
@@ -1,6 +1,6 @@
|
||||
#!/usr/bin/env python3
|
||||
#
|
||||
# Proot-Distro - manage proot containers on Termux.
|
||||
# Proot-Distro - manage proot containers.
|
||||
#
|
||||
# Created by Sylirre <sylirre@termux.dev> for Termux project.
|
||||
# Development assisted by Claude Code (https://claude.ai/code).
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#
|
||||
# Proot-Distro - manage proot containers on Termux.
|
||||
# Proot-Distro - manage proot containers.
|
||||
#
|
||||
# Created by Sylirre <sylirre@termux.dev> for Termux project.
|
||||
# Development assisted by Claude Code (https://claude.ai/code).
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#
|
||||
# Proot-Distro - manage proot containers on Termux.
|
||||
# Proot-Distro - manage proot containers.
|
||||
#
|
||||
# Created by Sylirre <sylirre@termux.dev> for Termux project.
|
||||
# Development assisted by Claude Code (https://claude.ai/code).
|
||||
|
||||
+55
-42
@@ -1,5 +1,5 @@
|
||||
#
|
||||
# Proot-Distro - manage proot containers on Termux.
|
||||
# Proot-Distro - manage proot containers.
|
||||
#
|
||||
# Created by Sylirre <sylirre@termux.dev> for Termux project.
|
||||
# Development assisted by Claude Code (https://claude.ai/code).
|
||||
@@ -31,7 +31,7 @@ import shutil
|
||||
import subprocess
|
||||
import sys
|
||||
|
||||
from proot_distro.constants import PROGRAM_NAME
|
||||
from proot_distro.constants import IS_TERMUX, PROGRAM_NAME
|
||||
from proot_distro.colors import C, msg
|
||||
from proot_distro.commands.install import command_install
|
||||
from proot_distro.commands.remove import command_remove
|
||||
@@ -51,7 +51,7 @@ from proot_distro.commands.help import command_help, _HELP_COMMANDS
|
||||
def build_parser() -> argparse.ArgumentParser:
|
||||
parser = argparse.ArgumentParser(
|
||||
prog=PROGRAM_NAME,
|
||||
description="Manage Linux proot containers on Termux.",
|
||||
description="Manage Linux proot containers.",
|
||||
add_help=False,
|
||||
)
|
||||
parser.add_argument("-h", "--help", action="store_true")
|
||||
@@ -103,10 +103,15 @@ def build_parser() -> argparse.ArgumentParser:
|
||||
_p_login_ports.add_argument(
|
||||
"--fix-low-ports", dest="redirect_ports", action="store_true"
|
||||
)
|
||||
p_login.add_argument("--isolated", action="store_true")
|
||||
p_login.add_argument("--minimal", action="store_true")
|
||||
p_login.add_argument(
|
||||
"--termux-home", dest="termux_home", action="store_true"
|
||||
if IS_TERMUX:
|
||||
p_login.add_argument("--isolated", action="store_true")
|
||||
p_login.add_argument("--minimal", action="store_true")
|
||||
_p_login_shared_home = p_login.add_mutually_exclusive_group()
|
||||
_p_login_shared_home.add_argument(
|
||||
"--shared-home", dest="shared_home", action="store_true"
|
||||
)
|
||||
_p_login_shared_home.add_argument(
|
||||
"--termux-home", dest="shared_home", action="store_true"
|
||||
)
|
||||
p_login.add_argument(
|
||||
"--shared-tmp", dest="shared_tmp", action="store_true"
|
||||
@@ -120,9 +125,10 @@ def build_parser() -> argparse.ArgumentParser:
|
||||
p_login.add_argument(
|
||||
"--no-link2symlink", dest="no_link2symlink", action="store_true"
|
||||
)
|
||||
p_login.add_argument(
|
||||
"--no-sysvipc", dest="no_sysvipc", action="store_true"
|
||||
)
|
||||
if IS_TERMUX:
|
||||
p_login.add_argument(
|
||||
"--no-sysvipc", dest="no_sysvipc", action="store_true"
|
||||
)
|
||||
p_login.add_argument(
|
||||
"--no-kill-on-exit", dest="no_kill_on_exit", action="store_true"
|
||||
)
|
||||
@@ -190,10 +196,15 @@ def build_parser() -> argparse.ArgumentParser:
|
||||
p_run.add_argument(
|
||||
"--redirect-ports", dest="redirect_ports", action="store_true"
|
||||
)
|
||||
p_run.add_argument("--isolated", action="store_true")
|
||||
p_run.add_argument("--minimal", action="store_true")
|
||||
p_run.add_argument(
|
||||
"--termux-home", dest="termux_home", action="store_true"
|
||||
if IS_TERMUX:
|
||||
p_run.add_argument("--isolated", action="store_true")
|
||||
p_run.add_argument("--minimal", action="store_true")
|
||||
_p_run_shared_home = p_run.add_mutually_exclusive_group()
|
||||
_p_run_shared_home.add_argument(
|
||||
"--shared-home", dest="shared_home", action="store_true"
|
||||
)
|
||||
_p_run_shared_home.add_argument(
|
||||
"--termux-home", dest="shared_home", action="store_true"
|
||||
)
|
||||
p_run.add_argument(
|
||||
"--shared-tmp", dest="shared_tmp", action="store_true"
|
||||
@@ -207,9 +218,10 @@ def build_parser() -> argparse.ArgumentParser:
|
||||
p_run.add_argument(
|
||||
"--no-link2symlink", dest="no_link2symlink", action="store_true"
|
||||
)
|
||||
p_run.add_argument(
|
||||
"--no-sysvipc", dest="no_sysvipc", action="store_true"
|
||||
)
|
||||
if IS_TERMUX:
|
||||
p_run.add_argument(
|
||||
"--no-sysvipc", dest="no_sysvipc", action="store_true"
|
||||
)
|
||||
p_run.add_argument(
|
||||
"--no-kill-on-exit", dest="no_kill_on_exit", action="store_true"
|
||||
)
|
||||
@@ -303,38 +315,39 @@ def main() -> None:
|
||||
msg()
|
||||
msg(f"{C['BRED']}Error: unable to find proot utility.{C['RST']}")
|
||||
msg()
|
||||
if sys.stdin.isatty():
|
||||
sys.stderr.write(
|
||||
f"{C['CYAN']}Would you like to install it now? [y/N] {C['RST']}"
|
||||
)
|
||||
sys.stderr.flush()
|
||||
try:
|
||||
answer = input().strip().lower()
|
||||
except (EOFError, KeyboardInterrupt):
|
||||
answer = ""
|
||||
if answer in ("y", "yes"):
|
||||
msg()
|
||||
if IS_TERMUX:
|
||||
if sys.stdin.isatty():
|
||||
sys.stderr.write(
|
||||
f"{C['CYAN']}Would you like to install it now? [y/N] {C['RST']}"
|
||||
)
|
||||
sys.stderr.flush()
|
||||
try:
|
||||
subprocess.run(
|
||||
["pkg", "install", "-y", "-q", "proot"], check=True
|
||||
)
|
||||
except (subprocess.CalledProcessError, FileNotFoundError) as exc:
|
||||
answer = input().strip().lower()
|
||||
except (EOFError, KeyboardInterrupt):
|
||||
answer = ""
|
||||
if answer in ("y", "yes"):
|
||||
msg()
|
||||
msg(f"{C['BRED']}Error: failed to install proot: "
|
||||
f"{exc}{C['RST']}")
|
||||
try:
|
||||
subprocess.run(
|
||||
["pkg", "install", "-y", "-q", "proot"], check=True
|
||||
)
|
||||
except (subprocess.CalledProcessError, FileNotFoundError) as exc:
|
||||
msg()
|
||||
msg(f"{C['BRED']}Error: failed to install proot: "
|
||||
f"{exc}{C['RST']}")
|
||||
msg()
|
||||
sys.exit(1)
|
||||
else:
|
||||
msg()
|
||||
msg(f"{C['CYAN']}Install it manually with: "
|
||||
f"{C['GREEN']}pkg install proot{C['RST']}")
|
||||
msg()
|
||||
sys.exit(1)
|
||||
else:
|
||||
msg()
|
||||
msg(f"{C['CYAN']}Install it manually with: "
|
||||
msg(f"{C['CYAN']}Install it with: "
|
||||
f"{C['GREEN']}pkg install proot{C['RST']}")
|
||||
msg()
|
||||
sys.exit(1)
|
||||
else:
|
||||
msg(f"{C['CYAN']}Install it with: "
|
||||
f"{C['GREEN']}pkg install proot{C['RST']}")
|
||||
msg()
|
||||
sys.exit(1)
|
||||
sys.exit(1)
|
||||
|
||||
if len(sys.argv) < 2 or sys.argv[1] in (
|
||||
"-h", "--help", "help", "hel", "he", "h"
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#
|
||||
# Proot-Distro - manage proot containers on Termux.
|
||||
# Proot-Distro - manage proot containers.
|
||||
#
|
||||
# Created by Sylirre <sylirre@termux.dev> for Termux project.
|
||||
# Development assisted by Claude Code (https://claude.ai/code).
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#
|
||||
# Proot-Distro - manage proot containers on Termux.
|
||||
# Proot-Distro - manage proot containers.
|
||||
#
|
||||
# Created by Sylirre <sylirre@termux.dev> for Termux project.
|
||||
# Development assisted by Claude Code (https://claude.ai/code).
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#
|
||||
# Proot-Distro - manage proot containers on Termux.
|
||||
# Proot-Distro - manage proot containers.
|
||||
#
|
||||
# Created by Sylirre <sylirre@termux.dev> for Termux project.
|
||||
# Development assisted by Claude Code (https://claude.ai/code).
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#
|
||||
# Proot-Distro - manage proot containers on Termux.
|
||||
# Proot-Distro - manage proot containers.
|
||||
#
|
||||
# Created by Sylirre <sylirre@termux.dev> for Termux project.
|
||||
# Development assisted by Claude Code (https://claude.ai/code).
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#
|
||||
# Proot-Distro - manage proot containers on Termux.
|
||||
# Proot-Distro - manage proot containers.
|
||||
#
|
||||
# Created by Sylirre <sylirre@termux.dev> for Termux project.
|
||||
# Development assisted by Claude Code (https://claude.ai/code).
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#
|
||||
# Proot-Distro - manage proot containers on Termux.
|
||||
# Proot-Distro - manage proot containers.
|
||||
#
|
||||
# Created by Sylirre <sylirre@termux.dev> for Termux project.
|
||||
# Development assisted by Claude Code (https://claude.ai/code).
|
||||
@@ -31,6 +31,7 @@ import shutil
|
||||
import textwrap
|
||||
|
||||
from proot_distro.constants import (
|
||||
IS_TERMUX,
|
||||
PROGRAM_NAME,
|
||||
PROGRAM_VERSION,
|
||||
RUNTIME_DIR,
|
||||
@@ -494,10 +495,13 @@ _HELP_PAGES = {
|
||||
"configured in /etc/passwd. Alternatively user can specify "
|
||||
"a custom command to use instead of default shell after "
|
||||
"command line separator ('--')."
|
||||
"\n\n"
|
||||
"By default container is not isolated from the host file"
|
||||
"system. It is highly discouraged to run destructive commands "
|
||||
"unless isolated mode enabled."
|
||||
+ (
|
||||
"\n\n"
|
||||
"By default container is not isolated from the host file"
|
||||
"system. It is highly discouraged to run destructive commands "
|
||||
"unless isolated mode enabled."
|
||||
if IS_TERMUX else ""
|
||||
)
|
||||
),
|
||||
"options": [
|
||||
("--help", "Show this help."),
|
||||
@@ -507,37 +511,40 @@ _HELP_PAGES = {
|
||||
"(22 -> 2022, 80 -> 2080, etc). Port shift offset is "
|
||||
"hardcoded into proot executable itself and can't be "
|
||||
f"configured through {PROGRAM_NAME}."),
|
||||
("--isolated",
|
||||
"Enable Isolated Mode. No host file system bindings created "
|
||||
"unless using QEMU user mode emulation or user manually "
|
||||
"requested specific directories to be bound."),
|
||||
("--minimal",
|
||||
"Enable Isolated Mode with bare mimimum proot configuration. "
|
||||
"Only /dev, /proc and /sys are bound. All proot extensions "
|
||||
"except link2symlink are disabled. No /proc system data "
|
||||
"workarounds, no kernel release override. Specific features "
|
||||
"may only be enabled through command line options. Could show "
|
||||
"higher performance than in other modes."),
|
||||
("--termux-home",
|
||||
"Bind Termux home directory into the container. Takes "
|
||||
"priority over Isolated Mode. Already included in default mode."),
|
||||
*([("--isolated",
|
||||
"Enable Isolated Mode. No host file system bindings created "
|
||||
"unless using QEMU user mode emulation or user manually "
|
||||
"requested specific directories to be bound.")] if IS_TERMUX else []),
|
||||
*([("--minimal",
|
||||
"Enable Isolated Mode with bare mimimum proot configuration. "
|
||||
"Only /dev, /proc and /sys are bound. All proot extensions "
|
||||
"except link2symlink are disabled. No /proc system data "
|
||||
"workarounds, no kernel release override. Specific features "
|
||||
"may only be enabled through command line options. Could show "
|
||||
"higher performance than in other modes.")] if IS_TERMUX else []),
|
||||
("--shared-home",
|
||||
"Bind host home directory into the container."
|
||||
+ (" Takes priority over Isolated Mode."
|
||||
" Already included in default mode." if IS_TERMUX else "")),
|
||||
("--shared-tmp",
|
||||
"Bind Termux tmp directory to /tmp. Takes priority over "
|
||||
"Isolated Mode. Already included in default mode."),
|
||||
"Bind host tmp directory to /tmp."
|
||||
+ (" Takes priority over Isolated Mode."
|
||||
" Already included in default mode." if IS_TERMUX else "")),
|
||||
("--shared-x11",
|
||||
"Bind Termux X11 socket directory to /tmp/.X11-unix. "
|
||||
"Takes priority over Isolated Mode. Inherited by --shared-tmp. "
|
||||
"Already included in default mode."),
|
||||
"Bind host X11 socket directory to /tmp/.X11-unix."
|
||||
+ (" Takes priority over Isolated Mode."
|
||||
" Inherited by --shared-tmp."
|
||||
" Already included in default mode." if IS_TERMUX else "")),
|
||||
("--bind [SRC:DEST]",
|
||||
"Custom filesystem binding. Can be specified multiple "
|
||||
"times. Takes priority over Isolated Mode."),
|
||||
"Custom filesystem binding. Can be specified multiple times."
|
||||
+ (" Takes priority over Isolated Mode." if IS_TERMUX else "")),
|
||||
("--no-link2symlink",
|
||||
"Disable hardlink emulation by proot. Recommended only for "
|
||||
"devices with SELinux in permissive mode."),
|
||||
("--no-sysvipc",
|
||||
"Disable System V IPC emulation by proot. Recommended only "
|
||||
"for devices where kernel has this feature enabled and "
|
||||
"SELinux set to permissive mode."),
|
||||
*([("--no-sysvipc",
|
||||
"Disable System V IPC emulation by proot. Recommended only "
|
||||
"for devices where kernel has this feature enabled and "
|
||||
"SELinux set to permissive mode.")] if IS_TERMUX else []),
|
||||
("--no-kill-on-exit",
|
||||
"Hang indefinitely until all session processes exit."),
|
||||
("--emulator [FILE]",
|
||||
@@ -557,7 +564,7 @@ _HELP_PAGES = {
|
||||
"paste into a terminal."),
|
||||
],
|
||||
"footer": [
|
||||
{
|
||||
*([{
|
||||
"title": "HOST BINDINGS",
|
||||
"intro": (
|
||||
"Without --isolated, the following host paths "
|
||||
@@ -578,18 +585,21 @@ _HELP_PAGES = {
|
||||
("/system_ext", None),
|
||||
("/vendor", None),
|
||||
],
|
||||
},
|
||||
}] if IS_TERMUX else []),
|
||||
{
|
||||
"title": "NOTES",
|
||||
"intro": (
|
||||
"If host utilities like termux-api do not work, "
|
||||
"ensure that PATH includes Termux bin directory as "
|
||||
"well as special environment variables such as "
|
||||
"ANDROID_ART_ROOT, ANDROID_DATA, ANDROID_I18N_ROOT, "
|
||||
"ANDROID_ROOT, ANDROID_TZDATA_ROOT, BOOTCLASSPATH, "
|
||||
"EXTERNAL_STORAGE. Valid values can be retrieved "
|
||||
"through Termux shell."
|
||||
"\n\n"
|
||||
(
|
||||
"If host utilities like termux-api do not work, "
|
||||
"ensure that PATH includes Termux bin directory as "
|
||||
"well as special environment variables such as "
|
||||
"ANDROID_ART_ROOT, ANDROID_DATA, ANDROID_I18N_ROOT, "
|
||||
"ANDROID_ROOT, ANDROID_TZDATA_ROOT, BOOTCLASSPATH, "
|
||||
"EXTERNAL_STORAGE. Valid values can be retrieved "
|
||||
"through Termux shell."
|
||||
"\n\n"
|
||||
if IS_TERMUX else ""
|
||||
) +
|
||||
"PRoot-Distro does not guarantee that everything "
|
||||
"inside given distribution will work flawlessly "
|
||||
"and is not responsible for that. Thus it is not "
|
||||
@@ -695,37 +705,40 @@ _HELP_PAGES = {
|
||||
"(22 -> 2022, 80 -> 2080, etc). Port shift offset is "
|
||||
"hardcoded into proot executable itself and can't be "
|
||||
f"configured through {PROGRAM_NAME}."),
|
||||
("--isolated",
|
||||
"Enable Isolated Mode. No host file system bindings created "
|
||||
"unless using QEMU user mode emulation or user manually "
|
||||
"requested specific directories to be bound."),
|
||||
("--minimal",
|
||||
"Enable Isolated Mode with bare mimimum proot configuration. "
|
||||
"Only /dev, /proc and /sys are bound. All proot extensions "
|
||||
"except link2symlink are disabled. No /proc system data "
|
||||
"workarounds, no kernel release override. Specific features "
|
||||
"may only be enabled through command line options. Could show "
|
||||
"higher performance than in other modes."),
|
||||
("--termux-home",
|
||||
"Bind Termux home directory into the container. Takes "
|
||||
"priority over Isolated Mode. Already included in default mode."),
|
||||
*([("--isolated",
|
||||
"Enable Isolated Mode. No host file system bindings created "
|
||||
"unless using QEMU user mode emulation or user manually "
|
||||
"requested specific directories to be bound.")] if IS_TERMUX else []),
|
||||
*([("--minimal",
|
||||
"Enable Isolated Mode with bare mimimum proot configuration. "
|
||||
"Only /dev, /proc and /sys are bound. All proot extensions "
|
||||
"except link2symlink are disabled. No /proc system data "
|
||||
"workarounds, no kernel release override. Specific features "
|
||||
"may only be enabled through command line options. Could show "
|
||||
"higher performance than in other modes.")] if IS_TERMUX else []),
|
||||
("--shared-home",
|
||||
"Bind host home directory into the container."
|
||||
+ (" Takes priority over Isolated Mode."
|
||||
" Already included in default mode." if IS_TERMUX else "")),
|
||||
("--shared-tmp",
|
||||
"Bind Termux tmp directory to /tmp. Takes priority over "
|
||||
"Isolated Mode. Already included in default mode."),
|
||||
"Bind host tmp directory to /tmp."
|
||||
+ (" Takes priority over Isolated Mode."
|
||||
" Already included in default mode." if IS_TERMUX else "")),
|
||||
("--shared-x11",
|
||||
"Bind Termux X11 socket directory to /tmp/.X11-unix. "
|
||||
"Takes priority over Isolated Mode. Inherited by --shared-tmp. "
|
||||
"Already included in default mode."),
|
||||
"Bind host X11 socket directory to /tmp/.X11-unix."
|
||||
+ (" Takes priority over Isolated Mode."
|
||||
" Inherited by --shared-tmp."
|
||||
" Already included in default mode." if IS_TERMUX else "")),
|
||||
("--bind [SRC:DEST]",
|
||||
"Custom filesystem binding. Can be specified multiple "
|
||||
"times. Takes priority over Isolated Mode."),
|
||||
"Custom filesystem binding. Can be specified multiple times."
|
||||
+ (" Takes priority over Isolated Mode." if IS_TERMUX else "")),
|
||||
("--no-link2symlink",
|
||||
"Disable hardlink emulation by proot. Recommended only for "
|
||||
"devices with SELinux in permissive mode."),
|
||||
("--no-sysvipc",
|
||||
"Disable System V IPC emulation by proot. Recommended only "
|
||||
"for devices where kernel has this feature enabled and "
|
||||
"SELinux set to permissive mode."),
|
||||
*([("--no-sysvipc",
|
||||
"Disable System V IPC emulation by proot. Recommended only "
|
||||
"for devices where kernel has this feature enabled and "
|
||||
"SELinux set to permissive mode.")] if IS_TERMUX else []),
|
||||
("--no-kill-on-exit",
|
||||
"Hang indefinitely until all session processes exit."),
|
||||
("--emulator [FILE]",
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#
|
||||
# Proot-Distro - manage proot containers on Termux.
|
||||
# Proot-Distro - manage proot containers.
|
||||
#
|
||||
# Created by Sylirre <sylirre@termux.dev> for Termux project.
|
||||
# Development assisted by Claude Code (https://claude.ai/code).
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#
|
||||
# Proot-Distro - manage proot containers on Termux.
|
||||
# Proot-Distro - manage proot containers.
|
||||
#
|
||||
# Created by Sylirre <sylirre@termux.dev> for Termux project.
|
||||
# Development assisted by Claude Code (https://claude.ai/code).
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#
|
||||
# Proot-Distro - manage proot containers on Termux.
|
||||
# Proot-Distro - manage proot containers.
|
||||
#
|
||||
# Created by Sylirre <sylirre@termux.dev> for Termux project.
|
||||
# Development assisted by Claude Code (https://claude.ai/code).
|
||||
@@ -35,6 +35,7 @@ import sys
|
||||
|
||||
from proot_distro.constants import (
|
||||
CONTAINERS_DIR,
|
||||
IS_TERMUX,
|
||||
LEGACY_ROOTFS_DIR,
|
||||
PREFIX,
|
||||
TERMUX_HOME,
|
||||
@@ -309,7 +310,7 @@ def command_login(args, configs: dict) -> None: # noqa: ARG001
|
||||
redirect_ports = getattr(args, "redirect_ports", False)
|
||||
isolated = getattr(args, "isolated", False)
|
||||
minimal = getattr(args, "minimal", False)
|
||||
use_termux_home = getattr(args, "termux_home", False)
|
||||
use_shared_home = getattr(args, "shared_home", False)
|
||||
shared_tmp = getattr(args, "shared_tmp", False)
|
||||
shared_x11 = getattr(args, "shared_x11", False)
|
||||
no_link2symlink = getattr(args, "no_link2symlink", False)
|
||||
@@ -434,8 +435,9 @@ def command_login(args, configs: dict) -> None: # noqa: ARG001
|
||||
else:
|
||||
# Baseline guest env. Always exported on every login.
|
||||
child_env["PATH"] = DEFAULT_PATH_ENV
|
||||
child_env["MOZ_FAKE_NO_SANDBOX"] = "1"
|
||||
child_env["PULSE_SERVER"] = "127.0.0.1"
|
||||
if IS_TERMUX:
|
||||
child_env["MOZ_FAKE_NO_SANDBOX"] = "1"
|
||||
child_env["PULSE_SERVER"] = "127.0.0.1"
|
||||
|
||||
# Image-defined Env entries. Blocked vars cannot be overridden.
|
||||
for entry in _read_manifest_env(container_dir):
|
||||
@@ -443,8 +445,8 @@ def command_login(args, configs: dict) -> None: # noqa: ARG001
|
||||
if key and key not in _IMAGE_ENV_BLOCKED:
|
||||
child_env[key] = val
|
||||
|
||||
# Android system vars exported only when not running --isolated.
|
||||
if not isolated:
|
||||
# Android system vars exported only on Termux and when not --isolated.
|
||||
if IS_TERMUX and not isolated:
|
||||
for var in (
|
||||
"ANDROID_ART_ROOT", "ANDROID_DATA", "ANDROID_I18N_ROOT",
|
||||
"ANDROID_ROOT", "ANDROID_RUNTIME_ROOT",
|
||||
@@ -519,14 +521,14 @@ def command_login(args, configs: dict) -> None: # noqa: ARG001
|
||||
else:
|
||||
inner = [login_shell, "-l"]
|
||||
|
||||
if not minimal:
|
||||
if IS_TERMUX and not minimal:
|
||||
setup_fake_sysdata(rootfs)
|
||||
|
||||
# Ensure Termux bin is always last in PATH so guest tools can invoke
|
||||
# host Termux utilities. Skipped in --isolated and --minimal modes where
|
||||
# PREFIX is not bound into the guest. De-duplicates any existing
|
||||
# occurrence first.
|
||||
if not isolated and not minimal:
|
||||
if IS_TERMUX and not isolated and not minimal:
|
||||
termux_bin = f"{PREFIX}/bin"
|
||||
components = [
|
||||
c for c in child_env.get("PATH", "").split(":")
|
||||
@@ -535,7 +537,7 @@ def command_login(args, configs: dict) -> None: # noqa: ARG001
|
||||
components.append(termux_bin)
|
||||
child_env["PATH"] = ":".join(components)
|
||||
|
||||
if dist_type == "normal" and not isolated and not minimal:
|
||||
if dist_type == "normal" and IS_TERMUX and not isolated and not minimal:
|
||||
_inject_termux_profile(rootfs)
|
||||
|
||||
# Architecture detection.
|
||||
@@ -577,7 +579,7 @@ def command_login(args, configs: dict) -> None: # noqa: ARG001
|
||||
if dist_type != "termux" and not no_link2symlink:
|
||||
proot_args.append("--link2symlink")
|
||||
|
||||
if not no_sysvipc and not minimal:
|
||||
if IS_TERMUX and not no_sysvipc and not minimal:
|
||||
proot_args.append("--sysvipc")
|
||||
|
||||
_ARCH_UNAME_M = {
|
||||
@@ -587,7 +589,7 @@ def command_login(args, configs: dict) -> None: # noqa: ARG001
|
||||
"x86_64": "x86_64",
|
||||
"riscv64": "riscv64",
|
||||
}
|
||||
if not minimal:
|
||||
if IS_TERMUX and not minimal:
|
||||
uname_m = _ARCH_UNAME_M.get(target_arch, os.uname().machine)
|
||||
proot_args.append(
|
||||
f"--kernel-release=\\Linux\\{hostname}\\{kernel_release}"
|
||||
@@ -606,26 +608,27 @@ def command_login(args, configs: dict) -> None: # noqa: ARG001
|
||||
|
||||
if not minimal:
|
||||
if dist_type != "termux":
|
||||
proot_args += [
|
||||
"--bind=/dev/urandom:/dev/random",
|
||||
"--bind=/proc/self/fd:/dev/fd",
|
||||
]
|
||||
for i, name in ((0, "stdin"), (1, "stdout"), (2, "stderr")):
|
||||
if os.path.exists(f"/proc/self/fd/{i}"):
|
||||
proot_args.append(f"--bind=/proc/self/fd/{i}:/dev/{name}")
|
||||
if IS_TERMUX:
|
||||
proot_args += [
|
||||
"--bind=/dev/urandom:/dev/random",
|
||||
"--bind=/proc/self/fd:/dev/fd",
|
||||
]
|
||||
for i, name in ((0, "stdin"), (1, "stdout"), (2, "stderr")):
|
||||
if os.path.exists(f"/proc/self/fd/{i}"):
|
||||
proot_args.append(f"--bind=/proc/self/fd/{i}:/dev/{name}")
|
||||
|
||||
proot_args.append(f"--bind={rootfs}/sys/.empty:/sys/fs/selinux")
|
||||
proot_args += fake_proc_bindings(rootfs)
|
||||
proot_args.append(f"--bind={rootfs}/sys/.empty:/sys/fs/selinux")
|
||||
proot_args += fake_proc_bindings(rootfs)
|
||||
|
||||
tmp_dir = os.path.join(rootfs, "tmp")
|
||||
os.makedirs(tmp_dir, exist_ok=True)
|
||||
try:
|
||||
os.chmod(tmp_dir, 0o1777)
|
||||
except OSError:
|
||||
pass
|
||||
proot_args.append(f"--bind={tmp_dir}:/dev/shm")
|
||||
tmp_dir = os.path.join(rootfs, "tmp")
|
||||
os.makedirs(tmp_dir, exist_ok=True)
|
||||
try:
|
||||
os.chmod(tmp_dir, 0o1777)
|
||||
except OSError:
|
||||
pass
|
||||
proot_args.append(f"--bind={tmp_dir}:/dev/shm")
|
||||
|
||||
if not isolated:
|
||||
if IS_TERMUX and not isolated:
|
||||
for data_dir in (
|
||||
"/data/app", "/data/dalvik-cache",
|
||||
"/data/misc/apexdata/com.android.art/dalvik-cache",
|
||||
@@ -655,12 +658,12 @@ def command_login(args, configs: dict) -> None: # noqa: ARG001
|
||||
|
||||
proot_args += _storage_bindings()
|
||||
|
||||
if dist_type == "termux" or not isolated or need_emu:
|
||||
if IS_TERMUX and (dist_type == "termux" or not isolated or need_emu):
|
||||
proot_args += _system_bindings()
|
||||
if dist_type != "termux":
|
||||
proot_args.append(f"--bind={PREFIX}")
|
||||
|
||||
if use_termux_home:
|
||||
if use_shared_home:
|
||||
if dist_type == "termux":
|
||||
proot_args.append(f"--bind={TERMUX_HOME}:{_TERMUX_HOME_INNER}")
|
||||
elif login_user == "root":
|
||||
@@ -668,10 +671,10 @@ def command_login(args, configs: dict) -> None: # noqa: ARG001
|
||||
else:
|
||||
proot_args.append(f"--bind={TERMUX_HOME}:{login_home}")
|
||||
|
||||
if shared_tmp and dist_type != "termux":
|
||||
if IS_TERMUX and shared_tmp and dist_type != "termux":
|
||||
proot_args.append(f"--bind={PREFIX}/tmp:/tmp")
|
||||
|
||||
if shared_x11 and dist_type != "termux":
|
||||
if IS_TERMUX and shared_x11 and dist_type != "termux":
|
||||
proot_args.append(f"--bind={PREFIX}/tmp/.X11-unix:/tmp/.X11-unix")
|
||||
|
||||
for bnd in custom_binds:
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#
|
||||
# Proot-Distro - manage proot containers on Termux.
|
||||
# Proot-Distro - manage proot containers.
|
||||
#
|
||||
# Created by Sylirre <sylirre@termux.dev> for Termux project.
|
||||
# Development assisted by Claude Code (https://claude.ai/code).
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#
|
||||
# Proot-Distro - manage proot containers on Termux.
|
||||
# Proot-Distro - manage proot containers.
|
||||
#
|
||||
# Created by Sylirre <sylirre@termux.dev> for Termux project.
|
||||
# Development assisted by Claude Code (https://claude.ai/code).
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#
|
||||
# Proot-Distro - manage proot containers on Termux.
|
||||
# Proot-Distro - manage proot containers.
|
||||
#
|
||||
# Created by Sylirre <sylirre@termux.dev> for Termux project.
|
||||
# Development assisted by Claude Code (https://claude.ai/code).
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#
|
||||
# Proot-Distro - manage proot containers on Termux.
|
||||
# Proot-Distro - manage proot containers.
|
||||
#
|
||||
# Created by Sylirre <sylirre@termux.dev> for Termux project.
|
||||
# Development assisted by Claude Code (https://claude.ai/code).
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#
|
||||
# Proot-Distro - manage proot containers on Termux.
|
||||
# Proot-Distro - manage proot containers.
|
||||
#
|
||||
# Created by Sylirre <sylirre@termux.dev> for Termux project.
|
||||
# Development assisted by Claude Code (https://claude.ai/code).
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#
|
||||
# Proot-Distro - manage proot containers on Termux.
|
||||
# Proot-Distro - manage proot containers.
|
||||
#
|
||||
# Created by Sylirre <sylirre@termux.dev> for Termux project.
|
||||
# Development assisted by Claude Code (https://claude.ai/code).
|
||||
|
||||
+59
-11
@@ -1,5 +1,5 @@
|
||||
#
|
||||
# Proot-Distro - manage proot containers on Termux.
|
||||
# Proot-Distro - manage proot containers.
|
||||
#
|
||||
# Created by Sylirre <sylirre@termux.dev> for Termux project.
|
||||
# Development assisted by Claude Code (https://claude.ai/code).
|
||||
@@ -19,11 +19,13 @@
|
||||
#
|
||||
|
||||
# Architecture: All global constants and path variables for proot-distro.
|
||||
# Paths are rooted under TERMUX_PREFIX (env var), which defaults to the
|
||||
# standard Termux installation prefix. Changing this env var allows running
|
||||
# proot-distro against a custom Termux installation.
|
||||
# On Termux/Android, paths are rooted under TERMUX_PREFIX (env var). On a
|
||||
# regular Linux host, XDG base directories (~/.local/share, ~/.cache) are
|
||||
# used instead. IS_TERMUX is computed once at import time and drives both
|
||||
# path selection and runtime behaviour (e.g. isolated-mode default).
|
||||
|
||||
import os
|
||||
import platform
|
||||
from importlib.metadata import version, PackageNotFoundError
|
||||
|
||||
PROGRAM_NAME = "proot-distro"
|
||||
@@ -38,6 +40,34 @@ os.umask(0o022)
|
||||
# Keep LD_PRELOAD for restoring after proot invocations.
|
||||
_SAVED_LD_PRELOAD = os.environ.get("LD_PRELOAD", "")
|
||||
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# Termux / Android detection
|
||||
# ---------------------------------------------------------------------------
|
||||
|
||||
def _detect_termux() -> bool:
|
||||
"""Return True when running inside Termux on Android."""
|
||||
# Termux-specific env var — always set by the Termux shell.
|
||||
if os.environ.get("TERMUX_PREFIX"):
|
||||
return True
|
||||
# Standard Android system env var present in every Android process.
|
||||
if os.environ.get("ANDROID_ROOT"):
|
||||
return True
|
||||
# platform.platform() reports "android" on Python builds for Android.
|
||||
try:
|
||||
if "android" in platform.platform().lower():
|
||||
return True
|
||||
except Exception:
|
||||
pass
|
||||
# /system/build.prop exists on every Android device.
|
||||
if os.path.isfile("/system/build.prop"):
|
||||
return True
|
||||
return False
|
||||
|
||||
|
||||
IS_TERMUX: bool = _detect_termux()
|
||||
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# Paths
|
||||
# ---------------------------------------------------------------------------
|
||||
@@ -48,8 +78,18 @@ PREFIX = os.environ.get(
|
||||
TERMUX_HOME = os.environ.get("HOME", "/data/data/com.termux/files/home")
|
||||
TERMUX_APP_PACKAGE = os.environ.get("TERMUX_APP_PACKAGE", "com.termux")
|
||||
|
||||
RUNTIME_DIR = os.path.join(PREFIX, "var", "lib", "proot-distro")
|
||||
DOWNLOAD_CACHE_DIR = os.path.join(RUNTIME_DIR, "dlcache")
|
||||
if IS_TERMUX:
|
||||
RUNTIME_DIR = os.path.join(PREFIX, "var", "lib", "proot-distro")
|
||||
DOWNLOAD_CACHE_DIR = os.path.join(RUNTIME_DIR, "dlcache")
|
||||
else:
|
||||
_xdg_data = os.environ.get("XDG_DATA_HOME") or os.path.join(
|
||||
os.path.expanduser("~"), ".local", "share"
|
||||
)
|
||||
_xdg_cache = os.environ.get("XDG_CACHE_HOME") or os.path.join(
|
||||
os.path.expanduser("~"), ".cache"
|
||||
)
|
||||
RUNTIME_DIR = os.path.join(_xdg_data, "proot-distro")
|
||||
DOWNLOAD_CACHE_DIR = os.path.join(_xdg_cache, "proot-distro")
|
||||
|
||||
# New container storage layout: containers/<name>/manifest.json + rootfs/
|
||||
CONTAINERS_DIR = os.path.join(RUNTIME_DIR, "containers")
|
||||
@@ -67,11 +107,19 @@ MANIFEST_CACHE_DIR = os.path.join(DOWNLOAD_CACHE_DIR, "manifests")
|
||||
|
||||
DEFAULT_PRIMARY_NS = "8.8.8.8"
|
||||
DEFAULT_SECONDARY_NS = "8.8.4.4"
|
||||
DEFAULT_PATH_ENV = (
|
||||
"/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
|
||||
":/usr/local/games:/usr/games"
|
||||
f":{PREFIX}/bin:/system/bin:/system/xbin"
|
||||
)
|
||||
|
||||
if IS_TERMUX:
|
||||
DEFAULT_PATH_ENV = (
|
||||
"/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
|
||||
":/usr/local/games:/usr/games"
|
||||
f":{PREFIX}/bin:/system/bin:/system/xbin"
|
||||
)
|
||||
else:
|
||||
DEFAULT_PATH_ENV = (
|
||||
"/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
|
||||
":/usr/local/games:/usr/games"
|
||||
)
|
||||
|
||||
DEFAULT_FAKE_KERNEL_RELEASE = "6.17.0-PRoot-Distro"
|
||||
DEFAULT_FAKE_KERNEL_VERSION = (
|
||||
"#1 SMP PREEMPT_DYNAMIC Fri, 10 Oct 2025 00:00:00 +0000"
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#
|
||||
# Proot-Distro - manage proot containers on Termux.
|
||||
# Proot-Distro - manage proot containers.
|
||||
#
|
||||
# Created by Sylirre <sylirre@termux.dev> for Termux project.
|
||||
# Development assisted by Claude Code (https://claude.ai/code).
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#
|
||||
# Proot-Distro - manage proot containers on Termux.
|
||||
# Proot-Distro - manage proot containers.
|
||||
#
|
||||
# Created by Sylirre <sylirre@termux.dev> for Termux project.
|
||||
# Development assisted by Claude Code (https://claude.ai/code).
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#
|
||||
# Proot-Distro - manage proot containers on Termux.
|
||||
# Proot-Distro - manage proot containers.
|
||||
#
|
||||
# Created by Sylirre <sylirre@termux.dev> for Termux project.
|
||||
# Development assisted by Claude Code (https://claude.ai/code).
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#
|
||||
# Proot-Distro - manage proot containers on Termux.
|
||||
# Proot-Distro - manage proot containers.
|
||||
#
|
||||
# Created by Sylirre <sylirre@termux.dev> for Termux project.
|
||||
# Development assisted by Claude Code (https://claude.ai/code).
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#
|
||||
# Proot-Distro - manage proot containers on Termux.
|
||||
# Proot-Distro - manage proot containers.
|
||||
#
|
||||
# Created by Sylirre <sylirre@termux.dev> for Termux project.
|
||||
# Development assisted by Claude Code (https://claude.ai/code).
|
||||
|
||||
Reference in New Issue
Block a user