get.porter.sh/porter@v1.3.0/pkg/porter/storage.go (about)

     1  package porter
     2  
     3  import (
     4  	"context"
     5  	"errors"
     6  	"fmt"
     7  	"io/fs"
     8  	"os"
     9  	"path/filepath"
    10  
    11  	"get.porter.sh/porter/pkg"
    12  	"get.porter.sh/porter/pkg/storage"
    13  	"get.porter.sh/porter/pkg/tracing"
    14  	"github.com/hashicorp/go-multierror"
    15  )
    16  
    17  type MigrateStorageOptions struct {
    18  	OldHome           string
    19  	OldStorageAccount string
    20  	Namespace         string
    21  }
    22  
    23  func (o MigrateStorageOptions) Validate() error {
    24  	if o.OldHome == "" {
    25  		return errors.New("--old-home is required")
    26  	}
    27  
    28  	return nil
    29  }
    30  
    31  func (p *Porter) MigrateStorage(ctx context.Context, opts MigrateStorageOptions) error {
    32  	if err := opts.Validate(); err != nil {
    33  		return err
    34  	}
    35  
    36  	migrateOpts := storage.MigrateOptions{
    37  		OldHome:           opts.OldHome,
    38  		OldStorageAccount: opts.OldStorageAccount,
    39  		NewNamespace:      opts.Namespace,
    40  	}
    41  	return p.Storage.Migrate(ctx, migrateOpts)
    42  }
    43  
    44  func (p *Porter) FixPermissions(ctx context.Context) error {
    45  	ctx, span := tracing.StartSpan(ctx)
    46  	defer span.EndSpan()
    47  
    48  	home, err := p.GetHomeDir()
    49  	if err != nil {
    50  		return err
    51  	}
    52  
    53  	span.Infof("Resetting file permissions in %s", home)
    54  
    55  	// Fix as many files as we can, and then report any errors
    56  	fixFile := func(path string, mode os.FileMode) error {
    57  		info, err := p.FileSystem.Stat(path)
    58  		if err != nil {
    59  			if os.IsNotExist(err) {
    60  				return nil
    61  			} else {
    62  				return span.Error(fmt.Errorf("error checking file permissions for %s: %w", path, err))
    63  			}
    64  		}
    65  
    66  		if info.IsDir() {
    67  			return span.Error(fmt.Errorf("fixFile was called on a directory %s", path))
    68  		}
    69  
    70  		if _, err = filepath.Rel(home, path); err != nil {
    71  			return span.Error(fmt.Errorf("fixFile was called on a path, %s, that isn't in the PORTER_HOME directory %s", path, home))
    72  		}
    73  
    74  		gotPerms := info.Mode().Perm()
    75  		if mode != gotPerms|mode {
    76  			if err := p.FileSystem.Chmod(path, mode); err != nil {
    77  				return span.Error(fmt.Errorf("could not set permissions on file %s to %o: %w", path, mode, err))
    78  			}
    79  		}
    80  		return nil
    81  	}
    82  
    83  	fixDir := func(dir string, mode os.FileMode) error {
    84  		var bigErr *multierror.Error
    85  		bigErr = multierror.Append(bigErr, p.FileSystem.Walk(dir, func(path string, info fs.FileInfo, err error) error {
    86  			if err != nil {
    87  				if !os.IsNotExist(err) {
    88  					bigErr = multierror.Append(bigErr, fmt.Errorf("error walking path %s: %w", path, err))
    89  				}
    90  				return nil
    91  			}
    92  
    93  			if info.IsDir() {
    94  				if err := p.FileSystem.Chmod(path, pkg.FileModeDirectory); err != nil {
    95  					bigErr = multierror.Append(bigErr, fmt.Errorf("could not set permissions on directory %s to %o: %w", path, mode, err))
    96  				}
    97  			} else {
    98  				if err = fixFile(path, mode); err != nil {
    99  					bigErr = multierror.Append(bigErr, err)
   100  				}
   101  			}
   102  			return nil
   103  		}))
   104  		return bigErr.ErrorOrNil()
   105  	}
   106  
   107  	var bigErr *multierror.Error
   108  	dataFiles := []string{filepath.Join(home, "schema.json")}
   109  	if p.ConfigFilePath != "" {
   110  		dataFiles = append(dataFiles, p.ConfigFilePath)
   111  	}
   112  	for _, file := range dataFiles {
   113  		if err := fixFile(file, pkg.FileModeWritable); err != nil {
   114  			bigErr = multierror.Append(bigErr, err)
   115  		}
   116  	}
   117  
   118  	dataDirs := []string{"installations", "claims", "results", "outputs", "cache", "credentials", "parameters"}
   119  	for _, dir := range dataDirs {
   120  		if err := fixDir(filepath.Join(home, dir), pkg.FileModeWritable); err != nil {
   121  			bigErr = multierror.Append(bigErr, err)
   122  		}
   123  	}
   124  
   125  	porterPath, _ := p.GetPorterPath(ctx)
   126  	binFiles := []string{porterPath}
   127  	for _, file := range binFiles {
   128  		if err := fixFile(file, pkg.FileModeExecutable); err != nil {
   129  			bigErr = multierror.Append(bigErr, err)
   130  		}
   131  	}
   132  
   133  	binDirs := []string{"mixins", "plugins", "runtimes"}
   134  	for _, dir := range binDirs {
   135  		if err := fixDir(filepath.Join(home, dir), pkg.FileModeExecutable); err != nil {
   136  			bigErr = multierror.Append(bigErr, err)
   137  		}
   138  	}
   139  
   140  	return span.Error(bigErr.ErrorOrNil())
   141  }