* feat(enter): rewrite in go
* chore: make InspectContainer public
* chore: use userenv package for user's environment
* chore: export InspectResult type for convenience
* fix: rename containerInspect to inpectOutput
* fix: use userenv inside generateEnterCommand
* fix(enter): more userenv
* chore: add some unit tests for buildContainerPath and buildCommandArgs
* embed shell scripts to execute inside the distrobox
The command init, export and host-exec must be accessible from inside
the distrobox container.
When needed, the embedded scripts will be written to a host directory
and then mounted as volume on the created container.
The host directory is determined by configuration and environment
variables.
The script will be not converted to GO to keep then
architecture-agnostic.
* add Create to the Docker container manager
The function will compose argument string to append to the `docker`
command.
If `DryRun=true`, the command is just printed on screen and not
executed.
* add Create command package
* mount cli command
* add GenerateEntryCommand package
The package mimics the actual distrobox-generate-entry shell command
that installs a desktop entry file so that the host's desktop
environment can render the appropriate application icon.
This first implementantion scaffolds the command package and implements
the simplest scenario for a single container.
* delete entry
If the `delete` flag is provided, the command remove the desktop entry
if present.
Deleting a non-existing item does not raise an error.
* generate entries for all containers
With `opts.All` we implement an abstraction over the
`GenerateEntryCommand` that iterates across all the containers to
generate or delete the relative desktop entries.
`ListCommand` is used to fetch the list of containers.
* mount the generate-entry cli command
Mount the command so that is reachable from the CLI. Define parameters
with type and basic validation.
Depending on the flag `--all`, the appropriate set of options is provided
to the `GenerateEntryCommand.Execute()` method.
If `--all` is set, `container-name` and `icon` arguments will be ignored.
* feat(cli): validate sudo (sudo -v) in beforeCommand if --root is set
Signed-off-by: Fabrizio Sestito <fabrizio.sestito@suse.com>
* feat(docker): add root and sudoCommand and execute commands with sudo if root is set
Signed-off-by: Fabrizio Sestito <fabrizio.sestito@suse.com>
* feat(cli): add --root description and -r alias
Signed-off-by: Fabrizio Sestito <fabrizio.sestito@suse.com>
---------
Signed-off-by: Fabrizio Sestito <fabrizio.sestito@suse.com>
* chore: disable mdlint (#6)
* resolve lint issues
Some issues where detected by the CI once run:
* use of `fmt.Printf` forbidden by pattern `^(fmt\.Print(|f|ln)|print|println)$` (forbidigo)
* File is not properly formatted (goimports)
* Magic number: 12, in <condition> detected (mnd)
* error-format: fmt.Errorf can be replaced with errors.New (perfsprint)
---------
Co-authored-by: Alessio Biancalana <alessio@dottorblaster.it>
The unshare_groups variable was previously read from a container label
only after the positional-parameter manipulation that decides whether
to wrap the command in `su`. As a result, containers labeled with
distrobox.unshare_groups=1 (e.g. ubi-init images) were entered as root
instead of the host user.
Read the label early via a dedicated lightweight inspect, so the
wrapping logic sees the correct value. The full container inspect
remains in its original position to preserve the existing behavior
when the container does not exist yet.
Also fix the `su` argument order in the unshare_groups branch: POSIX
`su` requires options before the username, and the previous code passed
a stray `--` literal that broke the wrapping shell snippet.
The `su` invocation also needed a literal `--` between options and the
username: util-linux `su` uses GNU getopt with argument reordering, so
without `--` any flag-looking argument in the user's command (e.g.
`uname -n`) is parsed as a `su` option and rejected.
Fixes#2011
Co-authored-by: Daniel Lindenfelser <daniel@lindenfelser.de>
The existing cleanup pattern `*.so.*` only matches versioned libraries
(e.g. libcuda.so.1) but misses unversioned stubs (e.g. libcuda.so,
libnvcuvid.so). After a driver upgrade, these remain as empty 0-byte
files and are not overwritten by the subsequent bind-mounts, which only
mount the versioned files. Applications that dlopen the unversioned name
(like DaVinci Resolve for CUDA) load the empty file and silently fall
back to OpenCL.
Widen the glob to `*.so*` so that both versioned and unversioned empty
stubs are removed before the host driver libraries are mounted.
Fixes#1764
On container storage drivers where CAP_DAC_OVERRIDE is not effective
(e.g. fuse-overlayfs in rootless mode, or VMs like Docker Desktop /
Colima on macOS), root cannot read files with mode 000 despite having
the capability in its effective set. This causes pam_unix.so account
management to fail with "Authentication service cannot retrieve
authentication info" when calling getspnam(), because glibc's NSS
files backend cannot open /etc/shadow.
Fedora and Arch ship /etc/shadow and /etc/gshadow as mode 000, relying
on CAP_DAC_OVERRIDE to grant root access. Set them to 0400 (owner-read)
after password setup so that standard POSIX owner checks suffice.
Signed-off-by: Luca Di Maio <luca.dimaio1@gmail.com>
On macOS, Docker Desktop mounts all paths as private (rprivate) in its
Linux VM via VirtioFS, so rslave/rshared bind propagation is rejected.
Strip these propagation options from the generated docker create command
when running on Darwin.
Also fix a bug in distrobox-init where the socket path prefix stripping
used `sed 's|/run/host||g'` with the global flag, causing paths like
`/run/host/run/host-services/ssh-auth.sock` (a Docker Desktop socket)
to be mangled into `-services/ssh-auth.sock`. The leading `-` was then
parsed as a flag by `rm`, crashing the init script. Replace with shell
parameter expansion `${host_socket#/run/host}` which strips the prefix
exactly once.
distrobox-init detects "rootful" mode by checking if /run/host/etc/shadow
is accessible and owned by root. On macOS with Docker Desktop, all containers
run as root inside the Linux VM, so this check always succeeds even for
containers created without --root, causing a spurious first-shell password
prompt.
Fix this by having distrobox-create mount /dev/null:/run/.distrobox.rootless:ro
for every rootless container. distrobox-init now checks for this marker first
and skips the shadow heuristic when it is present.
This is backward-compatible: existing containers without the marker continue
to use the shadow-file heuristic as before.
Signed-off-by: Eric Curtin <eric.curtin@docker.com>
I had mounted my Docker at `/run/home/docker`. Docker then mounted my
home folder somewhere under an overlayfs folder there. Distrobox had
appeared frozen at "Setting up host's sockets integration..." as it
tried to traverse my entire home directory on a slow hard disk.
No relevant socket was found on any submount, so excluding the submounts
should be OK.
* fix: use mkdir -p to prevent error on existing user tcb directory
Use mkdir -p in setup_aptrpm() to prevent command failure if
/etc/tcb/$user already exists.
Signed-off-by: Andrey Limachko <liannnix@altlinux.org>
* fix: disable pam_mktemp for PAM stack compatibility
Private tmp directory is not needed as /tmp is mounted from host system.
Using pam_mktemp would break the PAM stack.
Signed-off-by: Andrey Limachko <liannnix@altlinux.org>
* fix: ALT Linux --init compatibility via runuser wrapper
ALT Linux ships its own su(1) implementation incompatible with util-linux
su flags. distrobox-enter passes -m, --pty, -s, -c when unshare_groups is
enabled (--init containers). These flags are rejected by ALT's su, causing
instant failure.
Add /usr/local/bin/su wrapper that delegates to /usr/sbin/runuser (from
util-linux, always present in ALT). The wrapper is placed in /usr/local/bin
to survive package updates, and the existing generic --pty-stripping wrapper
is guarded to not overwrite it.
Fix PATH ordering in distrobox-enter to ensure /usr/local/bin precedes
/usr/bin when host PATH is passed through. This follows FHS conventions
and guarantees the wrapper is found first.
Signed-off-by: Andrey Limachko <liannnix@altlinux.org>
---------
Signed-off-by: Andrey Limachko <liannnix@altlinux.org>
This fix ensures that the printed command in dry-run mode is the same
as the one that would be executed without the --dry-run flag.
The container command, either default or custom, is always appended to
the command in both normal and dry-run execution.
The inspect command to fetch the container status is now executed only
when not in dry-run mode.