2023-06-22 21:41:50 +00:00
|
|
|
package filesystem
|
|
|
|
|
|
|
|
import (
|
|
|
|
"encoding/base64"
|
2023-07-17 21:25:29 +00:00
|
|
|
"fmt"
|
2023-06-22 21:41:50 +00:00
|
|
|
"os"
|
|
|
|
"path/filepath"
|
|
|
|
"strings"
|
2023-07-17 21:25:29 +00:00
|
|
|
|
|
|
|
"golang.org/x/mod/semver"
|
2023-06-22 21:41:50 +00:00
|
|
|
)
|
|
|
|
|
|
|
|
type DirEntry struct {
|
|
|
|
Name string
|
|
|
|
Content string
|
|
|
|
IsFile bool
|
|
|
|
Permissions os.FileMode
|
|
|
|
}
|
|
|
|
|
|
|
|
// FilterDirForEntryFile filers the given dirEntries, returns entries of the entryFile and .env file
|
|
|
|
func FilterDirForEntryFile(dirEntries []DirEntry, entryFile string) []DirEntry {
|
|
|
|
var filteredDirEntries []DirEntry
|
|
|
|
|
|
|
|
dotEnvFile := filepath.Join(filepath.Dir(entryFile), ".env")
|
|
|
|
filters := []string{entryFile, dotEnvFile}
|
|
|
|
|
|
|
|
for _, dirEntry := range dirEntries {
|
|
|
|
match := false
|
|
|
|
if dirEntry.IsFile {
|
|
|
|
for _, filter := range filters {
|
|
|
|
if filter == dirEntry.Name {
|
|
|
|
match = true
|
|
|
|
break
|
|
|
|
}
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
for _, filter := range filters {
|
|
|
|
if strings.HasPrefix(filter, dirEntry.Name) {
|
|
|
|
match = true
|
|
|
|
break
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if match {
|
|
|
|
filteredDirEntries = append(filteredDirEntries, dirEntry)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return filteredDirEntries
|
|
|
|
}
|
|
|
|
|
2023-09-20 23:22:44 +00:00
|
|
|
// FilterDirForCompatibility returns the content of the entry file if agent version is less than 2.19.0
|
2023-07-17 21:25:29 +00:00
|
|
|
func FilterDirForCompatibility(dirEntries []DirEntry, entryFilePath, agentVersion string) (string, error) {
|
|
|
|
if semver.Compare(fmt.Sprintf("v%s", agentVersion), "v2.19.0") == -1 {
|
|
|
|
for _, dirEntry := range dirEntries {
|
|
|
|
if dirEntry.IsFile {
|
|
|
|
if dirEntry.Name == entryFilePath {
|
|
|
|
return DecodeFileContent(dirEntry.Content)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return "", fmt.Errorf("Entry file %s not found in dir entries", entryFilePath)
|
|
|
|
}
|
|
|
|
|
|
|
|
return "", nil
|
|
|
|
}
|
|
|
|
|
2023-06-22 21:41:50 +00:00
|
|
|
// LoadDir reads all files and folders recursively from the given directory
|
|
|
|
// File content is base64-encoded
|
|
|
|
func LoadDir(dir string) ([]DirEntry, error) {
|
|
|
|
var dirEntries []DirEntry
|
|
|
|
|
|
|
|
err := filepath.WalkDir(
|
|
|
|
dir,
|
|
|
|
func(path string, d os.DirEntry, err error) error {
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
|
|
|
fileInfo, err := d.Info()
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
|
|
|
relativePath, err := filepath.Rel(dir, path)
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
if relativePath == "." {
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
|
|
|
dirEntry := DirEntry{
|
|
|
|
Name: relativePath,
|
|
|
|
Permissions: fileInfo.Mode().Perm(),
|
|
|
|
}
|
|
|
|
|
|
|
|
if !fileInfo.IsDir() {
|
|
|
|
// Read file contents
|
|
|
|
fileContent, err := os.ReadFile(path)
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
|
|
|
dirEntry.Content = base64.StdEncoding.EncodeToString(fileContent)
|
|
|
|
dirEntry.IsFile = true
|
|
|
|
}
|
|
|
|
|
|
|
|
dirEntries = append(dirEntries, dirEntry)
|
|
|
|
return nil
|
|
|
|
})
|
|
|
|
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
|
|
|
|
return dirEntries, nil
|
|
|
|
}
|
|
|
|
|
|
|
|
// PersistDir writes the provided array of files and folders back to the given directory.
|
|
|
|
func PersistDir(dir string, dirEntries []DirEntry) error {
|
|
|
|
for _, dirEntry := range dirEntries {
|
|
|
|
path := filepath.Join(dir, dirEntry.Name)
|
|
|
|
|
|
|
|
if dirEntry.IsFile {
|
|
|
|
// Create the directory path if it doesn't exist
|
|
|
|
err := os.MkdirAll(filepath.Dir(path), 0744)
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
|
|
|
// Write file contents
|
|
|
|
err = os.WriteFile(path, []byte(dirEntry.Content), dirEntry.Permissions)
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
// Create the directory
|
|
|
|
err := os.MkdirAll(path, dirEntry.Permissions)
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
2023-07-17 21:25:29 +00:00
|
|
|
func DecodeFileContent(encodedFileContent string) (string, error) {
|
|
|
|
decodedBytes, err := base64.StdEncoding.DecodeString(encodedFileContent)
|
|
|
|
if err != nil {
|
|
|
|
return "", err
|
|
|
|
}
|
|
|
|
return string(decodedBytes), nil
|
|
|
|
}
|
|
|
|
|
2023-06-22 21:41:50 +00:00
|
|
|
func DecodeDirEntries(dirEntries []DirEntry) error {
|
|
|
|
for index, dirEntry := range dirEntries {
|
|
|
|
if dirEntry.IsFile && dirEntry.Content != "" {
|
2023-07-17 21:25:29 +00:00
|
|
|
decodedFile, err := DecodeFileContent(dirEntry.Content)
|
2023-06-22 21:41:50 +00:00
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
2023-07-17 21:25:29 +00:00
|
|
|
dirEntries[index].Content = decodedFile
|
2023-06-22 21:41:50 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return nil
|
|
|
|
}
|