The migrate command introduced a parallel insidedistrobox.ScriptsDir()
that resolved to the old v2 prerelease location
(~/.local/share/distrobox/v2), which was abandoned in 94ae7fa with a
BREAKING CHANGE note. The two resolutions only agree when
DBX_SCRIPTS_DIR is set, which is exactly what the tests do - hiding the
divergence: migrate provisioned and filtered on a different host
directory than the create command mounts into new containers.
- drop insidedistrobox.ScriptsDir(); migrate now provisions and filters
on c.cfg.ScriptsDir, the same resolution the create command uses
- set ScriptsDir on the recreated container's CreateOptions: it was
left empty, which made ProvisionScripts("") fail on real runtimes
- make the scripts-mount filter path-boundary aware
- add an end-to-end migration test driving a fake podman runtime:
v1 inspect JSON in, then compare the recreated container's create
spec to the known-good v2 layout (scripts mounted from the config
scripts dir, distrobox.version label set, v1 helper mounts gone)
Unit tests can't prove the rewritten binary actually works on each supported
distro and on both podman and docker; this exercises the real thing.
Move the tests in a set of simple scripts to run them.
Make a smaller e2e test for CLI and Images that runs on every PR
Keep the full compatibility suite in a separate job for main merge and
manual runs.
Signed-off-by: Luca Di Maio <luca.dimaio1@gmail.com>
Lock down the container-name slug, enter env allow/deny, and podman/docker
ps parsers so provider JSON drift and symlink/env edge cases fail in CI
instead of in the field. Fixtures also capture the known doc/code and
comma-in-label quirks so they're tracked rather than silently accepted.
Signed-off-by: Luca Di Maio <luca.dimaio1@gmail.com>
The harness boots real VMs, so gate it to PRs touching distrobox-init or the
test itself instead of every push.
Base images use a split cache restore/save and on failure the per-distro log
dir is uploaded so it's debuggable without a re-run.
Signed-off-by: Luca Di Maio <luca.dimaio1@gmail.com>
The --nvidia path had no automated coverage and regresses easily (silent
32/64-bit collisions, dropped files), and GPU CI runners to exercise it
don't exist. This harness needs no GPU: it installs the nvidia driver in a
throwaway VM, runs `distrobox create --nvidia` against ubuntu/fedora/arch
guests, and checks every file the host package manager ships is mirrored in
with a matching checksum and resolvable deps. The package manifest is the
source of truth, so any gap fails loudly instead of silently.
Signed-off-by: Luca Di Maio <luca.dimaio1@gmail.com>
ROCm and other GPU workloads reach the device through /dev/kfd and
/dev/dri/renderD*, which are typically owned by group render (mode 0660).
Podman keeps the invoking user's supplementary groups via the
run.oci.keep_original_groups annotation, but the docker path forwarded only
the primary gid, so the container user was not in render/video and hit EACCES.
This generally puts docker on par with podman+crun
run.oci.keep_original_groups annotation.
Signed-off-by: Luca Di Maio <luca.dimaio1@gmail.com>
The --nvidia path mapped each driver library to a guest destination by
rewriting its host path (x86_64-linux-gnu / lib64 / lib32 via sed), which is
fragile across distros and can shadow the guest's own libGL/glvnd/Mesa.
Mount libs into /usr/lib/distrobox-nvidia/{lib64,lib32} bucketed by ELF class +
one ld.so.conf, instead of guessing the guest path; 4 mount loops fold into one.
Signed-off-by: Luca Di Maio <luca.dimaio1@gmail.com>
In rootless containers systemd-tmpfiles chowns the bind-mounted /tmp,
/dev and /sys and fails with EPERM, aborting package setup (systemd
>= 261, tpm-udev). Masks those configs.
Signed-off-by: Luca Di Maio <luca.dimaio1@gmail.com>
zypper returns >= 100 when the transaction committed but a caveat
applies - e.g. 107 when a package %post fails, common in containers.
Only 106 was accepted; warn on the whole band except 105 (a real abort).
Signed-off-by: Luca Di Maio <luca.dimaio1@gmail.com>
alpine:edge's base image musl can lag the repo, so new package binaries
fail to relocate newer symbols (e.g. renameat2) and their post-install
scripts abort.
Signed-off-by: Luca Di Maio <luca.dimaio1@gmail.com>
The legacy shell tree carried a per-file license header; the Go rewrite
shipped without one. Add it to all files and enforce it going forward
via golangci-lint's goheader linter, so the notice can't be dropped.
Signed-off-by: Luca Di Maio <luca.dimaio1@gmail.com>
The exported struct was produced and consumed by nothing — no
InspectImage method exists and no caller references it — so it was
dead public surface, not a usable affordance.
Signed-off-by: Luca Di Maio <luca.dimaio1@gmail.com>
The (:|^)…(:|$) regexes only tested whether a path was an exact
colon-delimited segment — what slices.Contains over strings.Split does
directly, without recompiling a regex on every loop iteration.
Signed-off-by: Luca Di Maio <luca.dimaio1@gmail.com>
* refactor(userenv): drop unreachable UID/GID id-command fallbacks
os.Getuid/os.Getgid only return -1 on Windows, and distrobox is
Linux/macOS only, so the `id -ru`/`id -rg` fallbacks never executed.
Call them directly and drop the now-unused //nolint:gocognit.
Signed-off-by: Luca Di Maio <luca.dimaio1@gmail.com>
* refactor(config): use maps.Copy in mergeConfigMaps
Replace the hand-rolled nested-loop map merge with the stdlib
maps.Copy. Rename the variadic parameter to configMaps so it no
longer shadows the maps package.
Signed-off-by: Luca Di Maio <luca.dimaio1@gmail.com>
* refactor(ephemeral): drop DryRun field shadowing CreateOptions
EphemeralOptions embedded CreateOptions yet redeclared DryRun,
shadowing it. Remove the field and rely on promotion; set DryRun
in the embedded CreateOptions at the call sites instead.
Signed-off-by: Luca Di Maio <luca.dimaio1@gmail.com>
* refactor(create): drop duplicate local --verbose flag
The root command already declares --verbose/-v as a persistent
flag, so create's local copy was redundant. Remove it; -v and
--verbose on `distrobox create` still resolve to the global.
Signed-off-by: Luca Di Maio <luca.dimaio1@gmail.com>
* refactor(containermanager): use time.RFC3339Nano in TimestampNow
Replace the hand-written "…000000000+00:00" layout with the stdlib
RFC3339Nano constant. Output is equivalent RFC3339 (UTC "Z", trailing
zeros trimmed), still valid input for `podman/docker logs --since`.
Signed-off-by: Luca Di Maio <luca.dimaio1@gmail.com>
---------
Signed-off-by: Luca Di Maio <luca.dimaio1@gmail.com>
`distrobox enter my-box --help` and any distrobox flag placed after the
container name, was passed to the container manager as the command instead
of being parsed, so it failed with a crun error. This diverged from the
original bash distrobox-enter, which keeps parsing flags after the name and
only starts the command at -e/--exec/--.
The port stopped flag parsing at the first positional (StopOnNthArg), which
cannot tell the name from the command: when --name or DBX_CONTAINER_NAME
already supplies the name, the first positional *is* the command. So the
command boundary is resolved before parsing and everything past it is handed
to urfave verbatim, letting flags be recognized wherever they appear while
the custom command is still passed through untouched. ephemeral gets the
same treatment.
Unknown flags after the name are rejected, as in bash, so a mistyped flag
surfaces instead of being silently executed inside the container.
Fixes https://github.com/89luca89/distrobox/issues/2160
Signed-off-by: Luca Di Maio <luca.dimaio1@gmail.com>
The presence of distrobox-init (or -export or -host-exec) in the host PATH must not be considered when checking the
presence of the scripts, the container manager is only considering the
configured host directory as a source for copying the files into a
newly-created container.
An alternative solution could it be to use the location of the file when
the script is detected in PATH. That has been discarded for two reasons:
1. the need to propagate the value of the file location though all the
usage chain; also, potentially each file can be in different
locations thus requiring the code to handle them;
2. the scripts in PATH may not be the ones used by the current version
of Distrobox (think about try out the latest version while having the
stable one installed on the machine).