Skip to content

Commit

Permalink
Ensure proper FS root is set while bootstrapping
Browse files Browse the repository at this point in the history
This ensures relative paths to e.g. bases can be used.

Signed-off-by: Hidde Beydals <hello@hidde.co>
  • Loading branch information
hiddeco committed May 24, 2022
1 parent e09078f commit ad22030
Show file tree
Hide file tree
Showing 4 changed files with 39 additions and 20 deletions.
2 changes: 1 addition & 1 deletion cmd/flux/install.go
Original file line number Diff line number Diff line change
Expand Up @@ -194,7 +194,7 @@ func installCmdRun(cmd *cobra.Command, args []string) error {
return nil
}

applyOutput, err := utils.Apply(ctx, kubeconfigArgs, kubeclientOptions, filepath.Join(tmpDir, manifest.Path))
applyOutput, err := utils.Apply(ctx, kubeconfigArgs, kubeclientOptions, tmpDir, filepath.Join(tmpDir, manifest.Path))
if err != nil {
return fmt.Errorf("install failed: %w", err)
}
Expand Down
12 changes: 5 additions & 7 deletions internal/bootstrap/bootstrap_plain_git.go
Original file line number Diff line number Diff line change
Expand Up @@ -163,19 +163,17 @@ func (b *PlainGitBootstrapper) ReconcileComponents(ctx context.Context, manifest

// Conditionally install manifests
if mustInstallManifests(ctx, b.kube, options.Namespace) {
componentsYAML := filepath.Join(b.git.Path(), manifests.Path)
b.logger.Actionf("installing components in %q namespace", options.Namespace)

// Apply components using any existing customisations
componentsYAML := filepath.Join(b.git.Path(), manifests.Path)
kfile := filepath.Join(filepath.Dir(componentsYAML), konfig.DefaultKustomizationFileName())
if _, err := os.Stat(kfile); err == nil {
// Apply the components and their patches
b.logger.Actionf("installing components in %q namespace", options.Namespace)
if _, err := utils.Apply(ctx, b.restClientGetter, b.restClientOptions, kfile); err != nil {
if _, err := utils.Apply(ctx, b.restClientGetter, b.restClientOptions, b.git.Path(), kfile); err != nil {
return err
}
} else {
// Apply the CRDs and controllers
if _, err := utils.Apply(ctx, b.restClientGetter, b.restClientOptions, componentsYAML); err != nil {
if _, err := utils.Apply(ctx, b.restClientGetter, b.restClientOptions, b.git.Path(), componentsYAML); err != nil {
return err
}
}
Expand Down Expand Up @@ -328,7 +326,7 @@ func (b *PlainGitBootstrapper) ReconcileSyncConfig(ctx context.Context, options

// Apply to cluster
b.logger.Actionf("applying sync manifests")
if _, err := utils.Apply(ctx, b.restClientGetter, b.restClientOptions, filepath.Join(b.git.Path(), kusManifests.Path)); err != nil {
if _, err := utils.Apply(ctx, b.restClientGetter, b.restClientOptions, b.git.Path(), filepath.Join(b.git.Path(), kusManifests.Path)); err != nil {
return err
}

Expand Down
29 changes: 21 additions & 8 deletions internal/utils/apply.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import (
"bytes"
"context"
"fmt"
"github.com/fluxcd/flux2/pkg/manifestgen/kustomization"
"os"
"path/filepath"
"time"
Expand All @@ -33,14 +34,12 @@ import (

runclient "github.com/fluxcd/pkg/runtime/client"
"github.com/fluxcd/pkg/ssa"

"github.com/fluxcd/flux2/pkg/manifestgen/kustomization"
)

// Apply is the equivalent of 'kubectl apply --server-side -f'.
// If the given manifest is a kustomization.yaml, then apply performs the equivalent of 'kubectl apply --server-side -k'.
func Apply(ctx context.Context, rcg genericclioptions.RESTClientGetter, opts *runclient.Options, manifestPath string) (string, error) {
objs, err := readObjects(manifestPath)
func Apply(ctx context.Context, rcg genericclioptions.RESTClientGetter, opts *runclient.Options, root, manifestPath string) (string, error) {
objs, err := readObjects(root, manifestPath)
if err != nil {
return "", err
}
Expand Down Expand Up @@ -92,13 +91,17 @@ func Apply(ctx context.Context, rcg genericclioptions.RESTClientGetter, opts *ru
return changeSet.String(), nil
}

func readObjects(manifestPath string) ([]*unstructured.Unstructured, error) {
if _, err := os.Stat(manifestPath); err != nil {
func readObjects(root, manifestPath string) ([]*unstructured.Unstructured, error) {
fi, err := os.Lstat(manifestPath)
if err != nil {
return nil, err
}
if fi.IsDir() || !fi.Mode().IsRegular() {
return nil, fmt.Errorf("expected %q to be a file", manifestPath)
}

if filepath.Base(manifestPath) == konfig.DefaultKustomizationFileName() {
resources, err := kustomization.Build(filepath.Dir(manifestPath))
if isRecognizedKustomizationFile(manifestPath) {
resources, err := kustomization.BuildWithRoot(root, filepath.Dir(manifestPath))
if err != nil {
return nil, err
}
Expand Down Expand Up @@ -152,3 +155,13 @@ func waitForSet(rcg genericclioptions.RESTClientGetter, opts *runclient.Options,
}
return man.WaitForSet(changeSet.ToObjMetadataSet(), ssa.WaitOptions{Interval: 2 * time.Second, Timeout: time.Minute})
}

func isRecognizedKustomizationFile(path string) bool {
base := filepath.Base(path)
for _, v := range konfig.RecognizedKustomizationFileNames() {
if base == v {
return true
}
}
return false
}
16 changes: 12 additions & 4 deletions pkg/manifestgen/kustomization/kustomization.go
Original file line number Diff line number Diff line change
Expand Up @@ -138,14 +138,22 @@ func Generate(options Options) (*manifestgen.Manifest, error) {
var kustomizeBuildMutex sync.Mutex

// Build takes the path to a directory with a konfig.RecognizedKustomizationFileNames,
// builds it, and returns the resulting manifests as multi-doc YAML.
// builds it, and returns the resulting manifests as multi-doc YAML. It restricts the
// Kustomize file system to the parent directory of the base.
func Build(base string) ([]byte, error) {
// TODO(hidde): drop this when consumers have moved away to BuildWithRoot.
parent := filepath.Dir(strings.TrimSuffix(base, string(filepath.Separator)))
return BuildWithRoot(parent, base)
}

// BuildWithRoot takes the path to a directory with a konfig.RecognizedKustomizationFileNames,
// builds it, and returns the resulting manifests as multi-doc YAML.
// The Kustomize file system is restricted to root.
func BuildWithRoot(root, base string) ([]byte, error) {
kustomizeBuildMutex.Lock()
defer kustomizeBuildMutex.Unlock()

// TODO(hidde): make this configurable to a specific root (relative to base)
parent := filepath.Dir(strings.TrimSuffix(base, string(filepath.Separator)))
fs, err := filesys.MakeFsOnDiskSecureBuild(parent)
fs, err := filesys.MakeFsOnDiskSecureBuild(root)
if err != nil {
return nil, err
}
Expand Down

0 comments on commit ad22030

Please sign in to comment.