cross
cross copied to clipboard
Don't require the docker client to be present
I'm trying to use cross in my CI jobs to cross-compile a library so I can provide precompiled binaries to my users. It looks like cross currently shells out to the docker program, meaning you need to have the client installed on your machine in order to use cross.
I know there's at least one docker client available on crates.io. What are your thoughts on trying to use something like that instead of requiring the docker client to be installed?
Hey @Michael-F-Bryan, I'm open to the idea, but would not know how to implement that. I would be happy to review a PR for it though!
rust-docker currently hasn't been maintained in over 7 years, and we support much more than just Docker now (including podman, and I've gotten Lima to work as well), and this still requires a docker daemon running. It uses the try! macro as well, so it's well before Rust 1.0.
Not all container engines with a CLI API compatible with Docker will necessarily use a client/server architecture, and we'd have to listen on different endpoints. For example, podman by default doesn't use expose a socket for an HTTP API in rootless mode, although it can if enabled. For example, we'd need to probe the following locations, and support an entirely different API:
/var/run/docker.sock/run/user/$UID/podman/podman.sock
$ curl --unix-socket /run/user/1000/podman/podman.sock http://localhost/v1.41/images/json
We'd also need to support the following tools:
docker inspectdocker rundocker cpdocker execdocker imagesdocker stopdocker volumedocker rmdocker ps
A lot of this is due to remote Docker support. I'm not entirely sure if that's worth it. We may be able to support this if CROSS_CONTAINER_ENGINE_SOCKET was provided, but it would be a lot of code.
Probably the best solution now would be to use bollard, but because this has numerous dependencies with major compile-time overhead, it would require feature-gating it. We'd also need to make sure this other code-path does not go out-of-sync with our default code.
If anyone wants to contribute, that would be great, but it would need:
- Wrappers for commands to ensure our CLI and bollard-based APIs would be identical
- Be feature-gated
- Provide an API for the socket/gateway path
- Tests to ensure it works
Other downsides include that it would not work with lima (except when emulating docker/podman) and likely other container engines.
This might still be possible, we just need to add on the following requirements:
docker build(optionally, with buildkit): Docker::build_imagedocker inspect: Docker::inspect_containerdocker runDocker::start_container, Docker::create_exec, and Docker::start_execdocker cp(unsure)docker exec: same asdocker rundocker images: Docker::list_imagesdocker stop: Docker::stop_containerdocker volume: Docker::list_volumes, Docker::remove_volume, and Docker::prune_volumesdocker rm: Docker::remove_containerdocker ps: Docker::list_containers
Would require CROSS_CONTAINER_ENGINE_SOCKET or assuming the defaults. In short, everything could be done via bollard, I believe.
The steps required would be as follows:
- Convert into
api,shell, andclientsubmodules in the dockerdockermodule. - Structify the data that needs to be passed.
- Create API functions that automatically call the
shellvariant.
Then, when implementing client:
- Feature gate
client. - Implement
intofor the structified data to thebollardstructs. - Implement
clientAPI functions. - Change
apito useshellorclientdepending on some environment variable or config option if theclientfeature is enabled.
This is doable, and maybe less work than initially imagined.