97 lines
2.5 KiB
Go
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
|
|
}
|