Files
exec/proot/extensions.go
T

97 lines
2.5 KiB
Go

package proot
import (
"context"
"errors"
"fmt"
bindext "sirherobrine23.com.br/go-bds/exec/v2/proot/extensions/bind"
prootext "sirherobrine23.com.br/go-bds/exec/v2/proot/extensions/extensions"
qemuext "sirherobrine23.com.br/go-bds/exec/v2/proot/extensions/qemu"
)
type preparedExtensions struct {
config prootext.Config
cleanups []func() error
}
func (pr *Proot) prepareExtensions() (*preparedExtensions, error) {
runtimeConfig := &preparedExtensions{
config: prootext.Config{
Rootfs: pr.Rootfs,
Binds: pr.Binds,
DefaultBinds: pr.DefaultBinds,
}.Clone(),
}
ctx := context.Background()
for _, ext := range pr.Extensions {
if ext == nil {
continue
}
switch ext.Type() {
case prootext.ExtensionTypePath, prootext.ExtensionTypeExec:
default:
return nil, errors.Join(runtimeConfig.cleanup(), fmt.Errorf("proot extension %q: unsupported type %q", ext.Name(), ext.Type()))
}
cleanup, err := ext.Apply(ctx, &runtimeConfig.config)
if err != nil {
return nil, errors.Join(runtimeConfig.cleanup(), fmt.Errorf("proot extension %q: %w", ext.Name(), err))
}
if cleanup != nil {
runtimeConfig.cleanups = append(runtimeConfig.cleanups, cleanup)
}
}
if err := pr.applyLegacyBinds(ctx, &runtimeConfig.config); err != nil {
return nil, errors.Join(runtimeConfig.cleanup(), err)
}
if err := pr.applyLegacyQemu(ctx, &runtimeConfig.config); err != nil {
return nil, errors.Join(runtimeConfig.cleanup(), err)
}
return runtimeConfig, nil
}
func (pr *Proot) applyLegacyQemu(ctx context.Context, config *prootext.Config) error {
if pr.Qemu == "" {
return nil
}
_, err := qemuext.New(pr.Qemu).Apply(ctx, config)
if err != nil {
return fmt.Errorf("proot extension %q: %w", "qemu", err)
}
return nil
}
func (pr *Proot) applyLegacyBinds(ctx context.Context, config *prootext.Config) error {
bindings, err := bindext.DefaultBindings(config.DefaultBinds)
if err != nil {
return err
}
for host, guests := range config.Binds {
for _, guest := range guests {
bindings = append(bindings, bindext.Binding{Host: host, Guest: guest})
}
}
if len(bindings) == 0 {
return nil
}
_, err = bindext.New(bindings...).Apply(ctx, config)
if err != nil {
return fmt.Errorf("proot extension %q: %w", "bind", err)
}
return nil
}
func (p *preparedExtensions) cleanup() error {
if p == nil {
return nil
}
var err error
for i := len(p.cleanups) - 1; i >= 0; i-- {
err = errors.Join(err, p.cleanups[i]())
}
p.cleanups = nil
return err
}