Skip to content

Commit

Permalink
Symbol link issues
Browse files Browse the repository at this point in the history
  • Loading branch information
denis256 committed Dec 20, 2024
1 parent f76ae52 commit 8542090
Showing 1 changed file with 133 additions and 10 deletions.
143 changes: 133 additions & 10 deletions cli/commands/stack/action.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,13 @@ package stack
import (
"context"
"fmt"
"io"
"net/url"
"os"
"path/filepath"

"github.com/gruntwork-io/terragrunt/config"
getter "github.com/hashicorp/go-getter/v2"
getter "github.com/hashicorp/go-getter"

"github.com/gruntwork-io/terragrunt/internal/errors"
"github.com/gruntwork-io/terragrunt/options"
Expand Down Expand Up @@ -53,17 +55,11 @@ func processStackFile(ctx context.Context, opts *options.TerragruntOptions, stac
return errors.New(fmt.Errorf("failed to create base directory: %w", err))
}

//client := getter.Client{
// Getters: getter.Getters,
// Decompressors: getter.Decompressors,
// DisableSymlinks: true,
//}

for _, unit := range stackFile.Units {
destPath := filepath.Join(baseDir, unit.Path)
dest, err := filepath.Abs(destPath)
if err != nil {
return errors.New(fmt.Errorf("failed to get absolute path for destination '%s': %w", destPath, err))
return errors.New(fmt.Errorf("failed to get absolute path for destination '%s': %w", dest, err))
}

src := unit.Source
Expand All @@ -72,10 +68,137 @@ func processStackFile(ctx context.Context, opts *options.TerragruntOptions, stac
opts.Logger.Warnf("failed to get absolute path for source '%s': %v", unit.Source, err)
src = unit.Source
}

opts.Logger.Infof("Processing unit: %s (%s) to %s", unit.Name, src, dest)

if _, err := getter.GetAny(ctx, dest, src); err != nil {
return fmt.Errorf("failed to fetch source '%s' to destination '%s': %w", unit.Source, destPath, err)
client := &getter.Client{
Src: src,
Dst: dest,
Mode: getter.ClientModeAny,
Dir: true,
DisableSymlinks: true,
Options: []getter.ClientOption{
getter.WithInsecure(),
getter.WithContext(ctx),
getter.WithGetters(map[string]getter.Getter{
"file": &CustomFileProvider{},
}),
},
}
if err := client.Get(); err != nil {
return fmt.Errorf("failed to fetch source '%s' to destination '%s': %w", unit.Source, dest, err)
}
}

return nil
}

type CustomFileProvider struct {
client *getter.Client
}

// Get implements downloading functionality
func (p *CustomFileProvider) Get(dst string, u *url.URL) error {
src := u.Path

// Check if source exists
fi, err := os.Stat(src)
if err != nil {
return err
}

if fi.IsDir() {
return p.copyDir(src, dst)
}
return p.copyFile(src, dst)
}

// GetFile implements single file download
func (p *CustomFileProvider) GetFile(dst string, u *url.URL) error {
return p.copyFile(u.Path, dst)
}

// ClientMode determines if we're getting a directory or single file
func (p *CustomFileProvider) ClientMode(u *url.URL) (getter.ClientMode, error) {
fi, err := os.Stat(u.Path)
if err != nil {
return getter.ClientModeInvalid, err
}

if fi.IsDir() {
return getter.ClientModeDir, nil
}
return getter.ClientModeFile, nil
}

// SetClient sets the client for this provider
func (p *CustomFileProvider) SetClient(c *getter.Client) {
p.client = c
}

func (p *CustomFileProvider) copyFile(src, dst string) error {
// Create destination directory if it doesn't exist
if err := os.MkdirAll(filepath.Dir(dst), 0755); err != nil {
return fmt.Errorf("failed to create destination directory: %v", err)
}

// Open source file
srcFile, err := os.Open(src)
if err != nil {
return fmt.Errorf("failed to open source file: %v", err)
}
defer srcFile.Close()

// Create destination file
dstFile, err := os.Create(dst)
if err != nil {
return fmt.Errorf("failed to create destination file: %v", err)
}
defer dstFile.Close()

// Copy the contents
if _, err := io.Copy(dstFile, srcFile); err != nil {
return fmt.Errorf("failed to copy file contents: %v", err)
}

// Copy file mode
srcInfo, err := os.Stat(src)
if err != nil {
return fmt.Errorf("failed to stat source file: %v", err)
}

return os.Chmod(dst, srcInfo.Mode())
}

func (p *CustomFileProvider) copyDir(src, dst string) error {
// Create the destination directory
srcInfo, err := os.Stat(src)
if err != nil {
return fmt.Errorf("failed to stat source directory: %v", err)
}

if err := os.MkdirAll(dst, srcInfo.Mode()); err != nil {
return fmt.Errorf("failed to create destination directory: %v", err)
}

// Read directory contents
entries, err := os.ReadDir(src)
if err != nil {
return fmt.Errorf("failed to read source directory: %v", err)
}

for _, entry := range entries {
srcPath := filepath.Join(src, entry.Name())
dstPath := filepath.Join(dst, entry.Name())

if entry.IsDir() {
if err := p.copyDir(srcPath, dstPath); err != nil {
return err
}
} else {
if err := p.copyFile(srcPath, dstPath); err != nil {
return err
}
}
}

Expand Down

0 comments on commit 8542090

Please sign in to comment.