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

go get sirherobrine23.com.br/go-bds/exec/v2

Basic usage

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.

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:

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.
S
Description
Tools to execute software in Local or Remote host, or virtualize
Readme
1.3 MiB
Languages
Go 100%