Files
podman/internal/domain/infra/abi/testing.go
2025-10-01 10:42:08 -04:00

223 lines
7.3 KiB
Go

//go:build !remote
package abi
import (
"bytes"
"context"
"fmt"
"os"
"path/filepath"
"github.com/containers/podman/v5/internal/domain/entities"
"github.com/containers/podman/v5/libpod"
"go.podman.io/image/v5/manifest"
"go.podman.io/storage"
graphdriver "go.podman.io/storage/drivers"
"go.podman.io/storage/pkg/chrootarchive"
"go.podman.io/storage/pkg/stringid"
)
type TestingEngine struct {
Libpod *libpod.Runtime
Store storage.Store
}
func (te *TestingEngine) CreateStorageLayer(_ context.Context, opts entities.CreateStorageLayerOptions) (*entities.CreateStorageLayerReport, error) {
driver, err := te.Store.GraphDriver()
if err != nil {
return nil, err
}
id := opts.ID
if id == "" {
id = stringid.GenerateNonCryptoID()
}
if err := driver.CreateReadWrite(id, opts.Parent, &graphdriver.CreateOpts{}); err != nil {
return nil, err
}
return &entities.CreateStorageLayerReport{ID: id}, nil
}
func (te *TestingEngine) CreateLayer(_ context.Context, opts entities.CreateLayerOptions) (*entities.CreateLayerReport, error) {
layer, err := te.Store.CreateLayer(opts.ID, opts.Parent, nil, "", true, nil)
if err != nil {
return nil, err
}
return &entities.CreateLayerReport{ID: layer.ID}, nil
}
func (te *TestingEngine) CreateLayerData(_ context.Context, opts entities.CreateLayerDataOptions) (*entities.CreateLayerDataReport, error) {
for key, data := range opts.Data {
if err := te.Store.SetLayerBigData(opts.ID, key, bytes.NewReader(data)); err != nil {
return nil, err
}
}
return &entities.CreateLayerDataReport{}, nil
}
func (te *TestingEngine) ModifyLayer(_ context.Context, opts entities.ModifyLayerOptions) (*entities.ModifyLayerReport, error) {
mnt, err := te.Store.Mount(opts.ID, "")
if err != nil {
return nil, err
}
modifyError := chrootarchive.UntarWithRoot(bytes.NewReader(opts.ContentsArchive), mnt, nil, mnt)
if _, err := te.Store.Unmount(opts.ID, false); err != nil {
return nil, err
}
if modifyError != nil {
return nil, modifyError
}
return &entities.ModifyLayerReport{}, nil
}
func (te *TestingEngine) PopulateLayer(_ context.Context, opts entities.PopulateLayerOptions) (*entities.PopulateLayerReport, error) {
if _, err := te.Store.ApplyDiff(opts.ID, bytes.NewReader(opts.ContentsArchive)); err != nil {
return nil, err
}
return &entities.PopulateLayerReport{}, nil
}
func (te *TestingEngine) CreateImage(_ context.Context, opts entities.CreateImageOptions) (*entities.CreateImageReport, error) {
image, err := te.Store.CreateImage(opts.ID, opts.Names, opts.Layer, "", nil)
if err != nil {
return nil, err
}
return &entities.CreateImageReport{ID: image.ID}, nil
}
func (te *TestingEngine) CreateImageData(_ context.Context, opts entities.CreateImageDataOptions) (*entities.CreateImageDataReport, error) {
for key, data := range opts.Data {
if err := te.Store.SetImageBigData(opts.ID, key, data, manifest.Digest); err != nil {
return nil, err
}
}
return &entities.CreateImageDataReport{}, nil
}
func (te *TestingEngine) CreateContainer(_ context.Context, opts entities.CreateContainerOptions) (*entities.CreateContainerReport, error) {
image, err := te.Store.CreateContainer(opts.ID, opts.Names, opts.Image, opts.Layer, "", nil)
if err != nil {
return nil, err
}
return &entities.CreateContainerReport{ID: image.ID}, nil
}
func (te *TestingEngine) CreateContainerData(_ context.Context, opts entities.CreateContainerDataOptions) (*entities.CreateContainerDataReport, error) {
for key, data := range opts.Data {
if err := te.Store.SetContainerBigData(opts.ID, key, data); err != nil {
return nil, err
}
}
return &entities.CreateContainerDataReport{}, nil
}
func (te *TestingEngine) RemoveStorageLayer(_ context.Context, opts entities.RemoveStorageLayerOptions) (*entities.RemoveStorageLayerReport, error) {
driver, err := te.Store.GraphDriver()
if err != nil {
return nil, err
}
if err := driver.Remove(opts.ID); err != nil {
return nil, err
}
return &entities.RemoveStorageLayerReport{ID: opts.ID}, nil
}
func (te *TestingEngine) RemoveLayer(_ context.Context, opts entities.RemoveLayerOptions) (*entities.RemoveLayerReport, error) {
if err := te.Store.Delete(opts.ID); err != nil {
return nil, err
}
return &entities.RemoveLayerReport{ID: opts.ID}, nil
}
func (te *TestingEngine) RemoveImage(_ context.Context, opts entities.RemoveImageOptions) (*entities.RemoveImageReport, error) {
if err := te.Store.Delete(opts.ID); err != nil {
return nil, err
}
return &entities.RemoveImageReport{ID: opts.ID}, nil
}
func (te *TestingEngine) RemoveContainer(_ context.Context, opts entities.RemoveContainerOptions) (*entities.RemoveContainerReport, error) {
if err := te.Store.Delete(opts.ID); err != nil {
return nil, err
}
return &entities.RemoveContainerReport{ID: opts.ID}, nil
}
func (te *TestingEngine) datapath(itemType, id, key string) (string, error) {
switch itemType {
default:
return "", fmt.Errorf("unknown item type %q", itemType)
case "layer", "image", "container":
}
driverName := te.Store.GraphDriverName()
graphRoot := te.Store.GraphRoot()
datapath := filepath.Join(graphRoot, driverName+"-"+itemType+"s", id, key) // more or less accurate for keys whose names are [.a-z0-9]+
return datapath, nil
}
func (te *TestingEngine) RemoveLayerData(_ context.Context, opts entities.RemoveLayerDataOptions) (*entities.RemoveLayerDataReport, error) {
datapath, err := te.datapath("layer", opts.ID, opts.Key)
if err != nil {
return nil, err
}
if err = os.Remove(datapath); err != nil {
return nil, err
}
return &entities.RemoveLayerDataReport{}, nil
}
func (te *TestingEngine) RemoveImageData(_ context.Context, opts entities.RemoveImageDataOptions) (*entities.RemoveImageDataReport, error) {
datapath, err := te.datapath("image", opts.ID, opts.Key)
if err != nil {
return nil, err
}
if err = os.Remove(datapath); err != nil {
return nil, err
}
return &entities.RemoveImageDataReport{}, nil
}
func (te *TestingEngine) RemoveContainerData(_ context.Context, opts entities.RemoveContainerDataOptions) (*entities.RemoveContainerDataReport, error) {
datapath, err := te.datapath("container", opts.ID, opts.Key)
if err != nil {
return nil, err
}
if err = os.Remove(datapath); err != nil {
return nil, err
}
return &entities.RemoveContainerDataReport{}, nil
}
func (te *TestingEngine) ModifyLayerData(_ context.Context, opts entities.ModifyLayerDataOptions) (*entities.ModifyLayerDataReport, error) {
datapath, err := te.datapath("layer", opts.ID, opts.Key)
if err != nil {
return nil, err
}
if err = os.WriteFile(datapath, opts.Data, 0o0600); err != nil {
return nil, err
}
return &entities.ModifyLayerDataReport{}, nil
}
func (te *TestingEngine) ModifyImageData(_ context.Context, opts entities.ModifyImageDataOptions) (*entities.ModifyImageDataReport, error) {
datapath, err := te.datapath("image", opts.ID, opts.Key)
if err != nil {
return nil, err
}
if err = os.WriteFile(datapath, opts.Data, 0o0600); err != nil {
return nil, err
}
return &entities.ModifyImageDataReport{}, nil
}
func (te *TestingEngine) ModifyContainerData(_ context.Context, opts entities.ModifyContainerDataOptions) (*entities.ModifyContainerDataReport, error) {
datapath, err := te.datapath("container", opts.ID, opts.Key)
if err != nil {
return nil, err
}
if err = os.WriteFile(datapath, opts.Data, 0o0600); err != nil {
return nil, err
}
return &entities.ModifyContainerDataReport{}, nil
}