Skip to content

Commit f3bcac2

Browse files
authored
refactor: improve overlayFS errors (#17808)
1 parent 4d00b76 commit f3bcac2

File tree

3 files changed

+19
-62
lines changed

3 files changed

+19
-62
lines changed

coderd/files/overlay.go

Lines changed: 17 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -4,15 +4,12 @@ import (
44
"io/fs"
55
"path"
66
"strings"
7-
8-
"golang.org/x/xerrors"
97
)
108

11-
// overlayFS allows you to "join" together the template files tar file fs.FS
12-
// with the Terraform modules tar file fs.FS. We could potentially turn this
13-
// into something more parameterized/configurable, but the requirements here are
14-
// a _bit_ odd, because every file in the modulesFS includes the
15-
// .terraform/modules/ folder at the beginning of it's path.
9+
// overlayFS allows you to "join" together multiple fs.FS. Files in any specific
10+
// overlay will only be accessible if their path starts with the base path
11+
// provided for the overlay. eg. An overlay at the path .terraform/modules
12+
// should contain files with paths inside the .terraform/modules folder.
1613
type overlayFS struct {
1714
baseFS fs.FS
1815
overlays []Overlay
@@ -23,64 +20,32 @@ type Overlay struct {
2320
fs.FS
2421
}
2522

26-
func NewOverlayFS(baseFS fs.FS, overlays []Overlay) (fs.FS, error) {
27-
if err := valid(baseFS); err != nil {
28-
return nil, xerrors.Errorf("baseFS: %w", err)
29-
}
30-
31-
for _, overlay := range overlays {
32-
if err := valid(overlay.FS); err != nil {
33-
return nil, xerrors.Errorf("overlayFS: %w", err)
34-
}
35-
}
36-
23+
func NewOverlayFS(baseFS fs.FS, overlays []Overlay) fs.FS {
3724
return overlayFS{
3825
baseFS: baseFS,
3926
overlays: overlays,
40-
}, nil
27+
}
4128
}
4229

43-
func (f overlayFS) Open(p string) (fs.File, error) {
30+
func (f overlayFS) target(p string) fs.FS {
31+
target := f.baseFS
4432
for _, overlay := range f.overlays {
4533
if strings.HasPrefix(path.Clean(p), overlay.Path) {
46-
return overlay.FS.Open(p)
34+
target = overlay.FS
35+
break
4736
}
4837
}
49-
return f.baseFS.Open(p)
38+
return target
5039
}
5140

52-
func (f overlayFS) ReadDir(p string) ([]fs.DirEntry, error) {
53-
for _, overlay := range f.overlays {
54-
if strings.HasPrefix(path.Clean(p), overlay.Path) {
55-
//nolint:forcetypeassert
56-
return overlay.FS.(fs.ReadDirFS).ReadDir(p)
57-
}
58-
}
59-
//nolint:forcetypeassert
60-
return f.baseFS.(fs.ReadDirFS).ReadDir(p)
41+
func (f overlayFS) Open(p string) (fs.File, error) {
42+
return f.target(p).Open(p)
6143
}
6244

63-
func (f overlayFS) ReadFile(p string) ([]byte, error) {
64-
for _, overlay := range f.overlays {
65-
if strings.HasPrefix(path.Clean(p), overlay.Path) {
66-
//nolint:forcetypeassert
67-
return overlay.FS.(fs.ReadFileFS).ReadFile(p)
68-
}
69-
}
70-
//nolint:forcetypeassert
71-
return f.baseFS.(fs.ReadFileFS).ReadFile(p)
45+
func (f overlayFS) ReadDir(p string) ([]fs.DirEntry, error) {
46+
return fs.ReadDir(f.target(p), p)
7247
}
7348

74-
// valid checks that the fs.FS implements the required interfaces.
75-
// The fs.FS interface is not sufficient.
76-
func valid(fsys fs.FS) error {
77-
_, ok := fsys.(fs.ReadDirFS)
78-
if !ok {
79-
return xerrors.New("overlayFS does not implement ReadDirFS")
80-
}
81-
_, ok = fsys.(fs.ReadFileFS)
82-
if !ok {
83-
return xerrors.New("overlayFS does not implement ReadFileFS")
84-
}
85-
return nil
49+
func (f overlayFS) ReadFile(p string) ([]byte, error) {
50+
return fs.ReadFile(f.target(p), p)
8651
}

coderd/files/overlay_test.go

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,11 +21,10 @@ func TestOverlayFS(t *testing.T) {
2121
afero.WriteFile(b, ".terraform/modules/modules.json", []byte("{}"), 0o644)
2222
afero.WriteFile(b, ".terraform/modules/example_module/main.tf", []byte("terraform {}"), 0o644)
2323

24-
it, err := files.NewOverlayFS(afero.NewIOFS(a), []files.Overlay{{
24+
it := files.NewOverlayFS(afero.NewIOFS(a), []files.Overlay{{
2525
Path: ".terraform/modules",
2626
FS: afero.NewIOFS(b),
2727
}})
28-
require.NoError(t, err)
2928

3029
content, err := fs.ReadFile(it, "main.tf")
3130
require.NoError(t, err)

coderd/parameters.go

Lines changed: 1 addition & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -97,14 +97,7 @@ func (api *API) templateVersionDynamicParameters(rw http.ResponseWriter, r *http
9797
return
9898
}
9999
defer api.FileCache.Release(tf.CachedModuleFiles.UUID)
100-
templateFS, err = files.NewOverlayFS(templateFS, []files.Overlay{{Path: ".terraform/modules", FS: moduleFilesFS}})
101-
if err != nil {
102-
httpapi.Write(ctx, rw, http.StatusInternalServerError, codersdk.Response{
103-
Message: "Internal error creating overlay filesystem.",
104-
Detail: err.Error(),
105-
})
106-
return
107-
}
100+
templateFS = files.NewOverlayFS(templateFS, []files.Overlay{{Path: ".terraform/modules", FS: moduleFilesFS}})
108101
}
109102
} else if !xerrors.Is(err, sql.ErrNoRows) {
110103
httpapi.Write(ctx, rw, http.StatusInternalServerError, codersdk.Response{

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy