mirror of
https://github.com/fluxcd/flux2.git
synced 2026-05-05 09:38:50 +00:00
feat: add WithInMemoryBuild to use filesys.MakeFsInMemory for kustomize
Signed-off-by: rycli <cyril@ryc.li>
This commit is contained in:
parent
c432d380dd
commit
8b7adab83c
5 changed files with 244 additions and 15 deletions
|
|
@ -72,6 +72,7 @@ type buildKsFlags struct {
|
||||||
strictSubst bool
|
strictSubst bool
|
||||||
recursive bool
|
recursive bool
|
||||||
localSources map[string]string
|
localSources map[string]string
|
||||||
|
inMemoryBuild bool
|
||||||
}
|
}
|
||||||
|
|
||||||
var buildKsArgs buildKsFlags
|
var buildKsArgs buildKsFlags
|
||||||
|
|
@ -85,6 +86,8 @@ func init() {
|
||||||
"When enabled, the post build substitutions will fail if a var without a default value is declared in files but is missing from the input vars.")
|
"When enabled, the post build substitutions will fail if a var without a default value is declared in files but is missing from the input vars.")
|
||||||
buildKsCmd.Flags().BoolVarP(&buildKsArgs.recursive, "recursive", "r", false, "Recursively build Kustomizations")
|
buildKsCmd.Flags().BoolVarP(&buildKsArgs.recursive, "recursive", "r", false, "Recursively build Kustomizations")
|
||||||
buildKsCmd.Flags().StringToStringVar(&buildKsArgs.localSources, "local-sources", nil, "Comma-separated list of repositories in format: Kind/namespace/name=path")
|
buildKsCmd.Flags().StringToStringVar(&buildKsArgs.localSources, "local-sources", nil, "Comma-separated list of repositories in format: Kind/namespace/name=path")
|
||||||
|
buildKsCmd.Flags().BoolVar(&buildKsArgs.inMemoryBuild, "in-memory-build", false,
|
||||||
|
"Use in-memory filesystem during build.")
|
||||||
buildCmd.AddCommand(buildKsCmd)
|
buildCmd.AddCommand(buildKsCmd)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -130,6 +133,7 @@ func buildKsCmdRun(cmd *cobra.Command, args []string) (err error) {
|
||||||
build.WithStrictSubstitute(buildKsArgs.strictSubst),
|
build.WithStrictSubstitute(buildKsArgs.strictSubst),
|
||||||
build.WithRecursive(buildKsArgs.recursive),
|
build.WithRecursive(buildKsArgs.recursive),
|
||||||
build.WithLocalSources(buildKsArgs.localSources),
|
build.WithLocalSources(buildKsArgs.localSources),
|
||||||
|
build.WithInMemoryBuild(buildKsArgs.inMemoryBuild),
|
||||||
)
|
)
|
||||||
} else {
|
} else {
|
||||||
builder, err = build.NewBuilder(name, buildKsArgs.path,
|
builder, err = build.NewBuilder(name, buildKsArgs.path,
|
||||||
|
|
@ -140,6 +144,7 @@ func buildKsCmdRun(cmd *cobra.Command, args []string) (err error) {
|
||||||
build.WithStrictSubstitute(buildKsArgs.strictSubst),
|
build.WithStrictSubstitute(buildKsArgs.strictSubst),
|
||||||
build.WithRecursive(buildKsArgs.recursive),
|
build.WithRecursive(buildKsArgs.recursive),
|
||||||
build.WithLocalSources(buildKsArgs.localSources),
|
build.WithLocalSources(buildKsArgs.localSources),
|
||||||
|
build.WithInMemoryBuild(buildKsArgs.inMemoryBuild),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -62,6 +62,7 @@ type diffKsFlags struct {
|
||||||
strictSubst bool
|
strictSubst bool
|
||||||
recursive bool
|
recursive bool
|
||||||
localSources map[string]string
|
localSources map[string]string
|
||||||
|
inMemoryBuild bool
|
||||||
}
|
}
|
||||||
|
|
||||||
var diffKsArgs diffKsFlags
|
var diffKsArgs diffKsFlags
|
||||||
|
|
@ -75,6 +76,8 @@ func init() {
|
||||||
"When enabled, the post build substitutions will fail if a var without a default value is declared in files but is missing from the input vars.")
|
"When enabled, the post build substitutions will fail if a var without a default value is declared in files but is missing from the input vars.")
|
||||||
diffKsCmd.Flags().BoolVarP(&diffKsArgs.recursive, "recursive", "r", false, "Recursively diff Kustomizations")
|
diffKsCmd.Flags().BoolVarP(&diffKsArgs.recursive, "recursive", "r", false, "Recursively diff Kustomizations")
|
||||||
diffKsCmd.Flags().StringToStringVar(&diffKsArgs.localSources, "local-sources", nil, "Comma-separated list of repositories in format: Kind/namespace/name=path")
|
diffKsCmd.Flags().StringToStringVar(&diffKsArgs.localSources, "local-sources", nil, "Comma-separated list of repositories in format: Kind/namespace/name=path")
|
||||||
|
diffKsCmd.Flags().BoolVar(&diffKsArgs.inMemoryBuild, "in-memory-build", false,
|
||||||
|
"Use in-memory filesystem during build.")
|
||||||
diffCmd.AddCommand(diffKsCmd)
|
diffCmd.AddCommand(diffKsCmd)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -113,6 +116,7 @@ func diffKsCmdRun(cmd *cobra.Command, args []string) error {
|
||||||
build.WithRecursive(diffKsArgs.recursive),
|
build.WithRecursive(diffKsArgs.recursive),
|
||||||
build.WithLocalSources(diffKsArgs.localSources),
|
build.WithLocalSources(diffKsArgs.localSources),
|
||||||
build.WithSingleKustomization(),
|
build.WithSingleKustomization(),
|
||||||
|
build.WithInMemoryBuild(diffKsArgs.inMemoryBuild),
|
||||||
)
|
)
|
||||||
} else {
|
} else {
|
||||||
builder, err = build.NewBuilder(name, diffKsArgs.path,
|
builder, err = build.NewBuilder(name, diffKsArgs.path,
|
||||||
|
|
@ -124,6 +128,7 @@ func diffKsCmdRun(cmd *cobra.Command, args []string) error {
|
||||||
build.WithRecursive(diffKsArgs.recursive),
|
build.WithRecursive(diffKsArgs.recursive),
|
||||||
build.WithLocalSources(diffKsArgs.localSources),
|
build.WithLocalSources(diffKsArgs.localSources),
|
||||||
build.WithSingleKustomization(),
|
build.WithSingleKustomization(),
|
||||||
|
build.WithInMemoryBuild(diffKsArgs.inMemoryBuild),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -65,6 +65,52 @@ const (
|
||||||
|
|
||||||
var defaultTimeout = 80 * time.Second
|
var defaultTimeout = 80 * time.Second
|
||||||
|
|
||||||
|
// buildBackend controls how the kustomization manifest is generated
|
||||||
|
// and which filesystem is used for the kustomize build.
|
||||||
|
type buildBackend interface {
|
||||||
|
Generate(gen *kustomize.Generator, dirPath string) (filesys.FileSystem, string, kustomize.Action, error)
|
||||||
|
Cleanup(dirPath string, action kustomize.Action) error
|
||||||
|
}
|
||||||
|
|
||||||
|
// onDiskBackend writes to the source directory, matching upstream behaviour.
|
||||||
|
type onDiskBackend struct{}
|
||||||
|
|
||||||
|
func (onDiskBackend) Generate(gen *kustomize.Generator, dirPath string) (filesys.FileSystem, string, kustomize.Action, error) {
|
||||||
|
action, err := gen.WriteFile(dirPath, kustomize.WithSaveOriginalKustomization())
|
||||||
|
if err != nil {
|
||||||
|
return nil, "", action, err
|
||||||
|
}
|
||||||
|
return filesys.MakeFsOnDisk(), dirPath, action, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (onDiskBackend) Cleanup(dirPath string, action kustomize.Action) error {
|
||||||
|
return kustomize.CleanDirectory(dirPath, action)
|
||||||
|
}
|
||||||
|
|
||||||
|
const memFSRoot = "/work"
|
||||||
|
|
||||||
|
// inMemoryBackend builds in an in-memory filesystem without modifying the source directory.
|
||||||
|
type inMemoryBackend struct{}
|
||||||
|
|
||||||
|
func (inMemoryBackend) Generate(gen *kustomize.Generator, dirPath string) (filesys.FileSystem, string, kustomize.Action, error) {
|
||||||
|
manifest, kfilePath, action, err := gen.GenerateManifest(dirPath)
|
||||||
|
if err != nil {
|
||||||
|
return nil, "", action, err
|
||||||
|
}
|
||||||
|
|
||||||
|
memFS := filesys.MakeFsInMemory()
|
||||||
|
if err := loadDirToMemFS(dirPath, memFSRoot, memFS); err != nil {
|
||||||
|
return nil, "", action, fmt.Errorf("failed to load source dir: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := memFS.WriteFile(filepath.Join(memFSRoot, filepath.Base(kfilePath)), manifest); err != nil {
|
||||||
|
return nil, "", action, err
|
||||||
|
}
|
||||||
|
return memFS, memFSRoot, action, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (inMemoryBackend) Cleanup(string, kustomize.Action) error { return nil }
|
||||||
|
|
||||||
// Builder builds yaml manifests
|
// Builder builds yaml manifests
|
||||||
// It retrieves the kustomization object from the k8s cluster
|
// It retrieves the kustomization object from the k8s cluster
|
||||||
// and overlays the manifests with the resources specified in the resourcesPath
|
// and overlays the manifests with the resources specified in the resourcesPath
|
||||||
|
|
@ -88,6 +134,7 @@ type Builder struct {
|
||||||
localSources map[string]string
|
localSources map[string]string
|
||||||
// diff needs to handle kustomizations one by one
|
// diff needs to handle kustomizations one by one
|
||||||
singleKustomization bool
|
singleKustomization bool
|
||||||
|
backend buildBackend
|
||||||
}
|
}
|
||||||
|
|
||||||
// BuilderOptionFunc is a function that configures a Builder
|
// BuilderOptionFunc is a function that configures a Builder
|
||||||
|
|
@ -198,6 +245,16 @@ func WithLocalSources(localSources map[string]string) BuilderOptionFunc {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// WithInMemoryBuild sets the in-memory build backend
|
||||||
|
func WithInMemoryBuild(inMemoryBuild bool) BuilderOptionFunc {
|
||||||
|
return func(b *Builder) error {
|
||||||
|
if inMemoryBuild {
|
||||||
|
b.backend = inMemoryBackend{}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// WithSingleKustomization sets the single kustomization field to true
|
// WithSingleKustomization sets the single kustomization field to true
|
||||||
func WithSingleKustomization() BuilderOptionFunc {
|
func WithSingleKustomization() BuilderOptionFunc {
|
||||||
return func(b *Builder) error {
|
return func(b *Builder) error {
|
||||||
|
|
@ -223,6 +280,14 @@ func withSpinnerFrom(in *Builder) BuilderOptionFunc {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// withBackend sets the build backend
|
||||||
|
func withBackend(s buildBackend) BuilderOptionFunc {
|
||||||
|
return func(b *Builder) error {
|
||||||
|
b.backend = s
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// withKustomization sets the kustomization field
|
// withKustomization sets the kustomization field
|
||||||
func withKustomization(k *kustomizev1.Kustomization) BuilderOptionFunc {
|
func withKustomization(k *kustomizev1.Kustomization) BuilderOptionFunc {
|
||||||
return func(b *Builder) error {
|
return func(b *Builder) error {
|
||||||
|
|
@ -258,6 +323,10 @@ func NewBuilder(name, resources string, opts ...BuilderOptionFunc) (*Builder, er
|
||||||
b.timeout = defaultTimeout
|
b.timeout = defaultTimeout
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if b.backend == nil {
|
||||||
|
b.backend = onDiskBackend{}
|
||||||
|
}
|
||||||
|
|
||||||
if b.dryRun && b.kustomizationFile == "" && b.kustomization == nil {
|
if b.dryRun && b.kustomizationFile == "" && b.kustomization == nil {
|
||||||
return nil, fmt.Errorf("kustomization file is required for dry-run")
|
return nil, fmt.Errorf("kustomization file is required for dry-run")
|
||||||
}
|
}
|
||||||
|
|
@ -378,9 +447,9 @@ func (b *Builder) build() (m resmap.ResMap, err error) {
|
||||||
b.kustomization = k
|
b.kustomization = k
|
||||||
|
|
||||||
// generate kustomization.yaml if needed
|
// generate kustomization.yaml if needed
|
||||||
action, er := b.generate(*k, b.resourcesPath)
|
buildFS, buildDir, action, er := b.generate(*k, b.resourcesPath)
|
||||||
if er != nil {
|
if er != nil {
|
||||||
errf := kustomize.CleanDirectory(b.resourcesPath, action)
|
errf := b.backend.Cleanup(b.resourcesPath, action)
|
||||||
err = fmt.Errorf("failed to generate kustomization.yaml: %w", fmt.Errorf("%v %v", er, errf))
|
err = fmt.Errorf("failed to generate kustomization.yaml: %w", fmt.Errorf("%v %v", er, errf))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
@ -388,14 +457,14 @@ func (b *Builder) build() (m resmap.ResMap, err error) {
|
||||||
b.action = action
|
b.action = action
|
||||||
|
|
||||||
defer func() {
|
defer func() {
|
||||||
errf := b.Cancel()
|
errf := b.backend.Cleanup(b.resourcesPath, b.action)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
err = errf
|
err = errf
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
|
|
||||||
// build the kustomization
|
// build the kustomization
|
||||||
m, err = b.do(ctx, *k, b.resourcesPath)
|
m, err = b.do(ctx, *k, buildFS, buildDir)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
@ -436,6 +505,7 @@ func (b *Builder) kustomizationBuild(k *kustomizev1.Kustomization) ([]*unstructu
|
||||||
WithRecursive(b.recursive),
|
WithRecursive(b.recursive),
|
||||||
WithLocalSources(b.localSources),
|
WithLocalSources(b.localSources),
|
||||||
WithDryRun(b.dryRun),
|
WithDryRun(b.dryRun),
|
||||||
|
withBackend(b.backend),
|
||||||
)
|
)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
|
|
@ -490,10 +560,10 @@ func (b *Builder) unMarshallKustomization() (*kustomizev1.Kustomization, error)
|
||||||
return k, nil
|
return k, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (b *Builder) generate(kustomization kustomizev1.Kustomization, dirPath string) (kustomize.Action, error) {
|
func (b *Builder) generate(kustomization kustomizev1.Kustomization, dirPath string) (filesys.FileSystem, string, kustomize.Action, error) {
|
||||||
data, err := runtime.DefaultUnstructuredConverter.ToUnstructured(&kustomization)
|
data, err := runtime.DefaultUnstructuredConverter.ToUnstructured(&kustomization)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", err
|
return nil, "", kustomize.UnchangedAction, err
|
||||||
}
|
}
|
||||||
|
|
||||||
// a scanner will be used down the line to parse the list
|
// a scanner will be used down the line to parse the list
|
||||||
|
|
@ -505,12 +575,32 @@ func (b *Builder) generate(kustomization kustomizev1.Kustomization, dirPath stri
|
||||||
b.mu.Lock()
|
b.mu.Lock()
|
||||||
defer b.mu.Unlock()
|
defer b.mu.Unlock()
|
||||||
|
|
||||||
return gen.WriteFile(dirPath, kustomize.WithSaveOriginalKustomization())
|
return b.backend.Generate(gen, dirPath)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (b *Builder) do(ctx context.Context, kustomization kustomizev1.Kustomization, dirPath string) (resmap.ResMap, error) {
|
// loadDirToMemFS copies srcDir into dstDir on the given filesystem.
|
||||||
fs := filesys.MakeFsOnDisk()
|
func loadDirToMemFS(srcDir, dstDir string, fs filesys.FileSystem) error {
|
||||||
|
return filepath.Walk(srcDir, func(p string, info os.FileInfo, err error) error {
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
rel, err := filepath.Rel(srcDir, p)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
target := filepath.Join(dstDir, rel)
|
||||||
|
if info.IsDir() {
|
||||||
|
return fs.MkdirAll(target)
|
||||||
|
}
|
||||||
|
data, err := os.ReadFile(p)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return fs.WriteFile(target, data)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func (b *Builder) do(ctx context.Context, kustomization kustomizev1.Kustomization, fs filesys.FileSystem, dirPath string) (resmap.ResMap, error) {
|
||||||
// acquire the lock
|
// acquire the lock
|
||||||
b.mu.Lock()
|
b.mu.Lock()
|
||||||
defer b.mu.Unlock()
|
defer b.mu.Unlock()
|
||||||
|
|
@ -734,12 +824,7 @@ func (b *Builder) Cancel() error {
|
||||||
b.mu.Lock()
|
b.mu.Lock()
|
||||||
defer b.mu.Unlock()
|
defer b.mu.Unlock()
|
||||||
|
|
||||||
err := kustomize.CleanDirectory(b.resourcesPath, b.action)
|
return b.backend.Cleanup(b.resourcesPath, b.action)
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (b *Builder) StartSpinner() error {
|
func (b *Builder) StartSpinner() error {
|
||||||
|
|
|
||||||
|
|
@ -18,16 +18,20 @@ package build
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"os"
|
||||||
|
"path/filepath"
|
||||||
"strings"
|
"strings"
|
||||||
"testing"
|
"testing"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
kustomizev1 "github.com/fluxcd/kustomize-controller/api/v1"
|
kustomizev1 "github.com/fluxcd/kustomize-controller/api/v1"
|
||||||
"github.com/fluxcd/pkg/apis/meta"
|
"github.com/fluxcd/pkg/apis/meta"
|
||||||
|
"github.com/fluxcd/pkg/kustomize"
|
||||||
"github.com/google/go-cmp/cmp"
|
"github.com/google/go-cmp/cmp"
|
||||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||||
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
|
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
|
||||||
"sigs.k8s.io/kustomize/api/resource"
|
"sigs.k8s.io/kustomize/api/resource"
|
||||||
|
"sigs.k8s.io/kustomize/kyaml/filesys"
|
||||||
"sigs.k8s.io/kustomize/kyaml/yaml"
|
"sigs.k8s.io/kustomize/kyaml/yaml"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
@ -611,3 +615,132 @@ func Test_kustomizationPath(t *testing.T) {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func Test_loadDirToMemFS(t *testing.T) {
|
||||||
|
srcDir := t.TempDir()
|
||||||
|
|
||||||
|
nested := filepath.Join(srcDir, "nested")
|
||||||
|
if err := os.MkdirAll(nested, 0o755); err != nil {
|
||||||
|
t.Fatalf("mkdir: %v", err)
|
||||||
|
}
|
||||||
|
if err := os.WriteFile(filepath.Join(nested, "file.yaml"), []byte("nested-content"), 0o644); err != nil {
|
||||||
|
t.Fatalf("write: %v", err)
|
||||||
|
}
|
||||||
|
if err := os.WriteFile(filepath.Join(srcDir, "root.yaml"), []byte("root-content"), 0o644); err != nil {
|
||||||
|
t.Fatalf("write: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
memFS := filesys.MakeFsInMemory()
|
||||||
|
dst := "/target"
|
||||||
|
if err := loadDirToMemFS(srcDir, dst, memFS); err != nil {
|
||||||
|
t.Fatalf("loadDirToMemFS: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
tests := []struct {
|
||||||
|
path string
|
||||||
|
content string
|
||||||
|
}{
|
||||||
|
{filepath.Join(dst, "root.yaml"), "root-content"},
|
||||||
|
{filepath.Join(dst, "nested", "file.yaml"), "nested-content"},
|
||||||
|
}
|
||||||
|
for _, tt := range tests {
|
||||||
|
data, err := memFS.ReadFile(tt.path)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("ReadFile(%s): %v", tt.path, err)
|
||||||
|
}
|
||||||
|
if diff := cmp.Diff(string(data), tt.content); diff != "" {
|
||||||
|
t.Errorf("content mismatch for %s: (-got +want)%s", tt.path, diff)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func Test_inMemoryBackend_Generate(t *testing.T) {
|
||||||
|
srcDir := t.TempDir()
|
||||||
|
|
||||||
|
kusYAML := `apiVersion: kustomize.config.k8s.io/v1beta1
|
||||||
|
kind: Kustomization
|
||||||
|
resources:
|
||||||
|
- configmap.yaml
|
||||||
|
`
|
||||||
|
cmYAML := `apiVersion: v1
|
||||||
|
kind: ConfigMap
|
||||||
|
metadata:
|
||||||
|
name: test-cm
|
||||||
|
data:
|
||||||
|
key: value
|
||||||
|
`
|
||||||
|
if err := os.WriteFile(filepath.Join(srcDir, "kustomization.yaml"), []byte(kusYAML), 0o644); err != nil {
|
||||||
|
t.Fatalf("write: %v", err)
|
||||||
|
}
|
||||||
|
if err := os.WriteFile(filepath.Join(srcDir, "configmap.yaml"), []byte(cmYAML), 0o644); err != nil {
|
||||||
|
t.Fatalf("write: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// snapshot source dir
|
||||||
|
beforeFiles := map[string]string{}
|
||||||
|
filepath.Walk(srcDir, func(p string, info os.FileInfo, err error) error {
|
||||||
|
if err != nil || info.IsDir() {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
data, _ := os.ReadFile(p)
|
||||||
|
rel, _ := filepath.Rel(srcDir, p)
|
||||||
|
beforeFiles[rel] = string(data)
|
||||||
|
return nil
|
||||||
|
})
|
||||||
|
|
||||||
|
ks := unstructured.Unstructured{Object: map[string]interface{}{
|
||||||
|
"apiVersion": "kustomize.toolkit.fluxcd.io/v1",
|
||||||
|
"kind": "Kustomization",
|
||||||
|
"metadata": map[string]interface{}{"name": "test", "namespace": "default"},
|
||||||
|
"spec": map[string]interface{}{
|
||||||
|
"targetNamespace": "my-ns",
|
||||||
|
},
|
||||||
|
}}
|
||||||
|
gen := kustomize.NewGenerator(srcDir, ks)
|
||||||
|
|
||||||
|
backend := inMemoryBackend{}
|
||||||
|
fs, dir, action, err := backend.Generate(gen, srcDir)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("Generate: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if dir != memFSRoot {
|
||||||
|
t.Errorf("expected dir %q, got %q", memFSRoot, dir)
|
||||||
|
}
|
||||||
|
if action != kustomize.UnchangedAction {
|
||||||
|
t.Errorf("expected UnchangedAction, got %q", action)
|
||||||
|
}
|
||||||
|
|
||||||
|
// kustomization.yaml should contain the merged targetNamespace
|
||||||
|
data, err := fs.ReadFile(filepath.Join(memFSRoot, "kustomization.yaml"))
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("ReadFile kustomization.yaml: %v", err)
|
||||||
|
}
|
||||||
|
if !strings.Contains(string(data), "my-ns") {
|
||||||
|
t.Errorf("expected kustomization to contain targetNamespace, got:\n%s", data)
|
||||||
|
}
|
||||||
|
|
||||||
|
// resource file should be copied verbatim
|
||||||
|
data, err = fs.ReadFile(filepath.Join(memFSRoot, "configmap.yaml"))
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("ReadFile configmap.yaml: %v", err)
|
||||||
|
}
|
||||||
|
if diff := cmp.Diff(string(data), cmYAML); diff != "" {
|
||||||
|
t.Errorf("configmap mismatch: (-got +want)%s", diff)
|
||||||
|
}
|
||||||
|
|
||||||
|
// source directory must be unmodified
|
||||||
|
afterFiles := map[string]string{}
|
||||||
|
filepath.Walk(srcDir, func(p string, info os.FileInfo, err error) error {
|
||||||
|
if err != nil || info.IsDir() {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
data, _ := os.ReadFile(p)
|
||||||
|
rel, _ := filepath.Rel(srcDir, p)
|
||||||
|
afterFiles[rel] = string(data)
|
||||||
|
return nil
|
||||||
|
})
|
||||||
|
if diff := cmp.Diff(afterFiles, beforeFiles); diff != "" {
|
||||||
|
t.Errorf("source directory was modified: (-got +want)%s", diff)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -230,6 +230,7 @@ func (b *Builder) kustomizationDiff(kustomization *kustomizev1.Kustomization) (s
|
||||||
WithRecursive(b.recursive),
|
WithRecursive(b.recursive),
|
||||||
WithLocalSources(b.localSources),
|
WithLocalSources(b.localSources),
|
||||||
WithSingleKustomization(),
|
WithSingleKustomization(),
|
||||||
|
withBackend(b.backend),
|
||||||
)
|
)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", false, err
|
return "", false, err
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue