Add ability to load bundles from an arbitrary filesystem

Support OPA Client SDK programs loading bundles from an arbitraty filesystem, such as an in-memory filesystem, which unlocks additional uses that include compiling a bundle to an intermediate representation from a client program rather than the OPA command line.

Fixes #5833

bundle: Add filesystem support
Soften constraint in `Equal` method to support bundle comparison for rootless filesystems, eg treat "/file" and "file" as equal for both URLs and Paths
Add `WithPathFormat` for `DirectoryLoader` builders to centralise logic for how paths are returned during file traversal, ie in `NextFile`
Add support for specifiying the root directory for `dirLoaderFS`

compile: Add filesystem support
Add `WithFS` builder helper to pass into `initload.LoadPaths` to load bundles from a filesystem

internal/runtime/init: Add filesystem support
Pass newly supplied `fsys fs.FS` parameter in `LoadPaths` into file loader builder

loader: Add filesystem support
Add new `GetBundleDirectLoaderFS` which can load bundles from the supplied filesystem

runtime: Add filesystem support
Pass-through nil parameter as `fsys fs.FS` parameter into `initLoad.LoadPaths` (OPA servers/repls are not in scope for loading from filesystem)

util/test: Add in-memory filesystem support
Add new `WithTestFS` helper to allow tests that currently use `WithTempFS` to choose between a disk-based or memory-based filesystem - now used throughout `compile_test`

Signed-off-by: Kieran Othen <kieran.othen@mac.com>
This commit is contained in:
Kieran Othen
2023-04-25 15:57:54 +01:00
committed by Ashutosh Narkar
parent 1ec047c063
commit b65c68e340
11 changed files with 877 additions and 633 deletions
+22
View File
@@ -5,8 +5,10 @@
package test
import (
"io/fs"
"os"
"path/filepath"
"testing/fstest"
)
// WithTempFS creates a temporary directory structure and invokes f with the
@@ -66,3 +68,23 @@ func MakeTempFS(root, prefix string, files map[string]string) (rootDir string, c
return rootDir, cleanup, nil
}
// WithTestFS creates a temporary file system of `files` in memory
// if `inMemoryFS` is true and invokes `f“ with that filesystem
func WithTestFS(files map[string]string, inMemoryFS bool, f func(string, fs.FS)) {
if inMemoryFS {
fsys := make(fstest.MapFS)
rootDir := "."
for k, v := range files {
fsys[filepath.Join(rootDir, k)] = &fstest.MapFile{Data: []byte(v)}
}
f(rootDir, fsys)
} else {
rootDir, cleanup, err := MakeTempFS("", "opa_test", files)
if err != nil {
panic(err)
}
defer cleanup()
f(rootDir, nil)
}
}