195 lines
4.9 KiB
Markdown
195 lines
4.9 KiB
Markdown
# go-bds exec
|
|
|
|
Go library for running commands in different environments: `host`, `Docker`, `SSH`, and `proot`.
|
|
|
|
The package exposes a common process interface and a few `rootfs` helpers for copying, importing, and exporting filesystems across those environments.
|
|
|
|
## What this package provides
|
|
|
|
- Unified process interface: `process.Proc`
|
|
- Standard command struct: `process.Exec`
|
|
- Execution backends:
|
|
- `host` / `os`
|
|
- `docker`
|
|
- `proot`
|
|
- `ssh`
|
|
- `rootfs` implementations:
|
|
- `host.Rootfs`
|
|
- `docker.Rootfs`
|
|
- `ssh.Rootfs`
|
|
- `proot` extensions:
|
|
- `bind`
|
|
- `fs`
|
|
- `overlayfs`
|
|
- `qemu`
|
|
- Utility for downloading OCI/Docker images directly from a registry without depending on the local daemon:
|
|
- `tools/local_extract_registry`
|
|
|
|
## Requirements
|
|
|
|
- Go `1.25` or newer
|
|
- A reachable Docker daemon for the `docker` backend and `docker.Rootfs`
|
|
- Valid SSH access for `ssh.Rootfs` and `ssh.Session`
|
|
- Linux or Android for the pure-Go `proot` backend
|
|
|
|
## Installation
|
|
|
|
```bash
|
|
go get sirherobrine23.com.br/go-bds/exec/v2
|
|
```
|
|
|
|
## Basic usage
|
|
|
|
```go
|
|
package main
|
|
|
|
import (
|
|
"log"
|
|
"os"
|
|
|
|
"sirherobrine23.com.br/go-bds/exec/v2/host"
|
|
"sirherobrine23.com.br/go-bds/exec/v2/process"
|
|
)
|
|
|
|
func main() {
|
|
proc, err := host.NewProc()
|
|
if err != nil {
|
|
log.Fatal(err)
|
|
}
|
|
|
|
defer proc.Close()
|
|
_ = proc.AttachStdout(os.Stdout)
|
|
_ = proc.AttachStderr(os.Stderr)
|
|
|
|
err = proc.Start(&process.Exec{
|
|
Arguments: []string{"sh", "-lc", "echo hello"},
|
|
})
|
|
if err != nil {
|
|
log.Fatal(err)
|
|
}
|
|
|
|
if err := proc.Wait(); err != nil {
|
|
log.Fatal(err)
|
|
}
|
|
}
|
|
```
|
|
|
|
## Using the process registry
|
|
|
|
Backends are registered by name when their packages are imported.
|
|
|
|
```go
|
|
import (
|
|
_ "sirherobrine23.com.br/go-bds/exec/v2/docker"
|
|
_ "sirherobrine23.com.br/go-bds/exec/v2/host"
|
|
_ "sirherobrine23.com.br/go-bds/exec/v2/proot"
|
|
|
|
"sirherobrine23.com.br/go-bds/exec/v2/process"
|
|
)
|
|
|
|
proc, err := process.ReturnNewProcess("host", &process.Exec{
|
|
Arguments: []string{"sh", "-lc", "id"},
|
|
})
|
|
```
|
|
|
|
Registered process names:
|
|
|
|
- `host`
|
|
- `os`
|
|
- `docker`
|
|
- `proot`
|
|
|
|
## Backends
|
|
|
|
### `host`
|
|
|
|
Runs the command on the local operating system. `host.Os` accepts `SysProcAttr` and an optional `Rootfs` used to prefix the working directory.
|
|
|
|
### `docker`
|
|
|
|
Runs the command inside a Docker container. `docker.DockerContainer` lets you configure image, platform, ports, and volumes.
|
|
|
|
### `ssh`
|
|
|
|
Runs commands in an SSH session. `ssh.Session` can be created from an existing `ssh.Client` or through helpers such as `ssh.NewClientPassword`.
|
|
|
|
### `proot`
|
|
|
|
Pure-Go backend for Linux/Android, without depending on the external `proot` binary. It uses `ptrace` to remap path-based system calls and supports:
|
|
|
|
- `rootfs` remapping
|
|
- host-to-guest bind mappings
|
|
- `cwd` and `PATH` resolution
|
|
- `execve`, `openat`, `stat`, `access`, `readlink`, `chdir`, and common path mutations
|
|
|
|
Example:
|
|
|
|
```go
|
|
import (
|
|
"sirherobrine23.com.br/go-bds/exec/v2/process"
|
|
"sirherobrine23.com.br/go-bds/exec/v2/proot"
|
|
)
|
|
|
|
proc := &proot.Proot{
|
|
Rootfs: "/tmp/rootfs",
|
|
Binds: map[string][]string{
|
|
"/dev": {"/dev"},
|
|
},
|
|
DefaultBinds: []string{"/dev"},
|
|
}
|
|
|
|
err := proc.Start(&process.Exec{
|
|
Arguments: []string{"/bin/sh", "-lc", "echo inside proot"},
|
|
})
|
|
```
|
|
|
|
`proot` also exposes `AddNameservers`, which writes entries into `etc/resolv.conf` inside the `rootfs`.
|
|
|
|
## `proot` extensions
|
|
|
|
Extensions live under `proot/extensions` and are applied before the process starts.
|
|
|
|
- `bind`: exposes host paths inside the guest
|
|
- `fs`: adds an `io/fs.FS` as a read-only tree
|
|
- `overlayfs`: adds overlay semantics with upper/lower layers and whiteouts
|
|
- `qemu`: redirects execution to a `qemu-*` emulator when needed
|
|
|
|
Extensions are applied in order and can adjust `Rootfs`, `Binds`, `DefaultBinds`, path resolvers, and exec resolvers.
|
|
|
|
## Rootfs
|
|
|
|
`rootfs` types implement `process.Rootfs` and let you create processes from a filesystem source.
|
|
|
|
- `host.Rootfs`:
|
|
- works on a local directory
|
|
- supports tar import and export
|
|
- can use `chroot` when requested
|
|
- `docker.Rootfs`:
|
|
- exports and imports images through Docker
|
|
- creates a `docker.DockerContainer` for execution
|
|
- `ssh.Rootfs`:
|
|
- synchronizes files over SFTP
|
|
- creates an `ssh.Session` for remote execution
|
|
|
|
## Registry utility
|
|
|
|
`tools/local_extract_registry.PullImage` downloads an OCI/Docker image and extracts its layers directly into a local directory.
|
|
|
|
This is useful when you want to build a `rootfs` without depending on the local Docker daemon.
|
|
|
|
## Module layout
|
|
|
|
- `process`: process and rootfs types plus registries
|
|
- `host`: local execution and local rootfs
|
|
- `docker`: container execution and Docker-backed rootfs
|
|
- `ssh`: remote execution and SSH/SFTP-backed rootfs
|
|
- `proot`: pure-Go backend and extensions
|
|
- `tools/local_extract_registry`: registry image extraction
|
|
|
|
## Notes
|
|
|
|
- The `proot` backend is specific to Linux/Android.
|
|
- The `docker` backend depends on the Docker daemon and the current user's permissions.
|
|
- The `ssh` backend assumes the remote server accepts interactive and `exec` sessions.
|
|
|