mirror of
https://github.com/portainer/portainer.git
synced 2025-07-19 13:29:41 +02:00
feat(edge-stack): relative path support for edge stack EE-5521 (#9103)
This commit is contained in:
parent
4cc96b4b30
commit
7cb6e3f66a
3 changed files with 163 additions and 26 deletions
142
api/filesystem/serialize.go
Normal file
142
api/filesystem/serialize.go
Normal file
|
@ -0,0 +1,142 @@
|
|||
package filesystem
|
||||
|
||||
import (
|
||||
"encoding/base64"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
)
|
||||
|
||||
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
|
||||
}
|
||||
|
||||
// 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
|
||||
}
|
||||
|
||||
func DecodeDirEntries(dirEntries []DirEntry) error {
|
||||
for index, dirEntry := range dirEntries {
|
||||
if dirEntry.IsFile && dirEntry.Content != "" {
|
||||
decodedBytes, err := base64.StdEncoding.DecodeString(dirEntry.Content)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
dirEntries[index].Content = string(decodedBytes)
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue