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 }