mirror of https://github.com/portainer/portainer
feat(edge/stack): add stack deployment info struct [EE-5523] (#9042)
parent
89c1d0e337
commit
c96e076871
|
@ -11,6 +11,7 @@ import (
|
|||
|
||||
"github.com/gofrs/uuid"
|
||||
portainer "github.com/portainer/portainer/api"
|
||||
"github.com/rs/zerolog/log"
|
||||
|
||||
"io"
|
||||
"os"
|
||||
|
@ -316,6 +317,43 @@ func (service *Service) StoreEdgeStackFileFromBytes(edgeStackIdentifier, fileNam
|
|||
return service.wrapFileStore(stackStorePath), nil
|
||||
}
|
||||
|
||||
// GetEdgeStackProjectPathByVersion returns the absolute path on the FS for a edge stack based
|
||||
// on its identifier and version.
|
||||
// EE only feature
|
||||
func (service *Service) GetEdgeStackProjectPathByVersion(edgeStackIdentifier string, version int) string {
|
||||
versionStr := fmt.Sprintf("v%d", version)
|
||||
return JoinPaths(service.wrapFileStore(EdgeStackStorePath), edgeStackIdentifier, versionStr)
|
||||
}
|
||||
|
||||
// StoreEdgeStackFileFromBytesByVersion creates a subfolder in the EdgeStackStorePath with version and stores a new file from bytes.
|
||||
// It returns the path to the folder where the file is stored.
|
||||
// EE only feature
|
||||
func (service *Service) StoreEdgeStackFileFromBytesByVersion(edgeStackIdentifier, fileName string, version int, data []byte) (string, error) {
|
||||
versionStr := fmt.Sprintf("v%d", version)
|
||||
stackStorePath := JoinPaths(EdgeStackStorePath, edgeStackIdentifier, versionStr)
|
||||
|
||||
err := service.createDirectoryInStore(stackStorePath)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
composeFilePath := JoinPaths(stackStorePath, fileName)
|
||||
r := bytes.NewReader(data)
|
||||
|
||||
err = service.createFileInStore(composeFilePath, r)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
return service.wrapFileStore(stackStorePath), nil
|
||||
}
|
||||
|
||||
// FormProjectPathByVersion returns the absolute path on the FS for a project based with version
|
||||
func (service *Service) FormProjectPathByVersion(path string, version int) string {
|
||||
versionStr := fmt.Sprintf("v%d", version)
|
||||
return JoinPaths(path, versionStr)
|
||||
}
|
||||
|
||||
// StoreRegistryManagementFileFromBytes creates a subfolder in the
|
||||
// ExtensionRegistryManagementStorePath and stores a new file from bytes.
|
||||
// It returns the path to the folder where the file is stored.
|
||||
|
@ -734,6 +772,56 @@ func FileExists(filePath string) (bool, error) {
|
|||
return true, nil
|
||||
}
|
||||
|
||||
// SafeCopyDirectory copies a directory from src to dst in a safe way.
|
||||
func (service *Service) SafeMoveDirectory(originalPath, newPath string) error {
|
||||
// 1. Backup the source directory to a different folder
|
||||
backupDir := fmt.Sprintf("%s-%s", filepath.Dir(originalPath), "backup")
|
||||
err := MoveDirectory(originalPath, backupDir)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to backup source directory: %w", err)
|
||||
}
|
||||
|
||||
defer func() {
|
||||
if err != nil {
|
||||
// If an error occurred, rollback the backup directory
|
||||
restoreErr := restoreBackup(originalPath, backupDir)
|
||||
if restoreErr != nil {
|
||||
log.Warn().Err(restoreErr).Msg("failed to restore backup during creating versioning folder")
|
||||
}
|
||||
}
|
||||
}()
|
||||
|
||||
// 2. Copy the backup directory to the destination directory
|
||||
err = CopyDir(backupDir, newPath, false)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to copy backup directory to destination directory: %w", err)
|
||||
}
|
||||
|
||||
// 3. Delete the backup directory
|
||||
err = os.RemoveAll(backupDir)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to delete backup directory: %w", err)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func restoreBackup(src, backupDir string) error {
|
||||
// Rollback by deleting the original directory and copying the
|
||||
// backup direcotry back to the source directory, and then deleting
|
||||
// the backup directory
|
||||
err := os.RemoveAll(src)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to delete destination directory: %w", err)
|
||||
}
|
||||
|
||||
err = MoveDirectory(backupDir, src)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to restore backup directory: %w", err)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func MoveDirectory(originalPath, newPath string) error {
|
||||
if _, err := os.Stat(originalPath); err != nil {
|
||||
return err
|
||||
|
|
|
@ -299,6 +299,12 @@ type (
|
|||
Endpoints []EndpointID `json:"Endpoints"`
|
||||
}
|
||||
|
||||
// StackDeploymentInfo records the information of a deployed stack
|
||||
StackDeploymentInfo struct {
|
||||
Version int `json:"Version"`
|
||||
ConfigHash string `json:"ConfigHash"`
|
||||
}
|
||||
|
||||
//EdgeStack represents an edge stack
|
||||
EdgeStack struct {
|
||||
// EdgeStack Identifier
|
||||
|
@ -340,6 +346,8 @@ type (
|
|||
Details EdgeStackStatusDetails `json:"Details"`
|
||||
Error string `json:"Error"`
|
||||
EndpointID EndpointID `json:"EndpointID"`
|
||||
// EE only feature
|
||||
DeploymentInfo StackDeploymentInfo `json:"DeploymentInfo"`
|
||||
|
||||
// Deprecated
|
||||
Type EdgeStackStatusType `json:"Type"`
|
||||
|
@ -1380,6 +1388,10 @@ type (
|
|||
RollbackStackFile(stackIdentifier, fileName string) error
|
||||
GetEdgeStackProjectPath(edgeStackIdentifier string) string
|
||||
StoreEdgeStackFileFromBytes(edgeStackIdentifier, fileName string, data []byte) (string, error)
|
||||
GetEdgeStackProjectPathByVersion(edgeStackIdentifier string, version int) string
|
||||
StoreEdgeStackFileFromBytesByVersion(edgeStackIdentifier, fileName string, version int, data []byte) (string, error)
|
||||
FormProjectPathByVersion(projectIdentifier string, version int) string
|
||||
SafeMoveDirectory(src, dst string) error
|
||||
StoreRegistryManagementFileFromBytes(folder, fileName string, data []byte) (string, error)
|
||||
KeyPairFilesExist() (bool, error)
|
||||
StoreKeyPair(private, public []byte, privatePEMHeader, publicPEMHeader string) error
|
||||
|
|
Loading…
Reference in New Issue