Skip to content

Commit c767c32

Browse files
committed
* clean up temporary files
1 parent a3e6ebd commit c767c32

File tree

3 files changed

+81
-35
lines changed

3 files changed

+81
-35
lines changed

decompression.go

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,10 +21,15 @@ func defaultTarReader(xzReader *xz.Reader) (func() (*tar.Header, error), func()
2121
}
2222

2323
func decompressTarXz(tarReader func(*xz.Reader) (func() (*tar.Header, error), func() io.Reader), path, extractPath string) error {
24-
tempExtractPath, err := os.MkdirTemp("", "embedded_postgres")
24+
tempExtractPath, err := os.MkdirTemp(filepath.Dir(extractPath), "temp_")
2525
if err != nil {
2626
return errorUnableToExtract(path, extractPath, err)
2727
}
28+
defer func() {
29+
if err := os.RemoveAll(tempExtractPath); err != nil {
30+
panic(err)
31+
}
32+
}()
2833

2934
tarFile, err := os.Open(path)
3035
if err != nil {

decompression_test.go

Lines changed: 23 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,13 +3,16 @@ package embeddedpostgres
33
import (
44
"archive/tar"
55
"errors"
6+
"fmt"
67
"io"
78
"os"
9+
"path"
810
"path/filepath"
911
"syscall"
1012
"testing"
1113

1214
"github.com/stretchr/testify/assert"
15+
"github.com/stretchr/testify/require"
1316
"github.com/xi2/xz"
1417
)
1518

@@ -41,7 +44,12 @@ func Test_decompressTarXz(t *testing.T) {
4144
func Test_decompressTarXz_ErrorWhenFileNotExists(t *testing.T) {
4245
err := decompressTarXz(defaultTarReader, "/does-not-exist", "/also-fake")
4346

44-
assert.EqualError(t, err, "unable to extract postgres archive /does-not-exist to /also-fake, if running parallel tests, configure RuntimePath to isolate testing directories, open /does-not-exist: no such file or directory")
47+
assert.Error(t, err)
48+
assert.Contains(
49+
t,
50+
err.Error(),
51+
"unable to extract postgres archive /does-not-exist to /also-fake, if running parallel tests, configure RuntimePath to isolate testing directories",
52+
)
4553
}
4654

4755
func Test_decompressTarXz_ErrorWhenErrorDuringRead(t *testing.T) {
@@ -181,6 +189,18 @@ func Test_decompressTarXz_ErrorWithInvalidDestination(t *testing.T) {
181189
archive, cleanUp := createTempXzArchive()
182190
defer cleanUp()
183191

184-
err := decompressTarXz(defaultTarReader, archive, string(rune(0)))
185-
assert.EqualError(t, err, "unable to extract postgres archive: mkdir \x00: invalid argument")
192+
tempDir, err := os.MkdirTemp("", "temp_tar_test")
193+
require.NoError(t, err)
194+
defer func() {
195+
os.RemoveAll(tempDir)
196+
}()
197+
198+
op := fmt.Sprintf(path.Join(tempDir, "%c"), rune(0))
199+
200+
err = decompressTarXz(defaultTarReader, archive, op)
201+
assert.EqualError(
202+
t,
203+
err,
204+
fmt.Sprintf("unable to extract postgres archive: mkdir %s: invalid argument", op),
205+
)
186206
}

remote_fetch.go

Lines changed: 52 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -80,51 +80,72 @@ func decompressResponse(bodyBytes []byte, contentLength int64, cacheLocator Cach
8080
return errorFetchingPostgres(err)
8181
}
8282

83+
cacheLocation, _ := cacheLocator()
84+
85+
if err := os.MkdirAll(filepath.Dir(cacheLocation), 0755); err != nil {
86+
return errorExtractingPostgres(err)
87+
}
88+
8389
for _, file := range zipReader.File {
8490
if !file.FileHeader.FileInfo().IsDir() && strings.HasSuffix(file.FileHeader.Name, ".txz") {
85-
archiveReader, err := file.Open()
86-
if err != nil {
87-
return errorExtractingPostgres(err)
91+
if err := decompressSingleFile(file, cacheLocation); err != nil {
92+
return err
8893
}
8994

90-
archiveBytes, err := io.ReadAll(archiveReader)
91-
if err != nil {
92-
return errorExtractingPostgres(err)
93-
}
95+
// we have successfully found the file, return early
96+
return nil
97+
}
98+
}
9499

95-
// if multiple processes attempt to extract
96-
// to prevent file corruption when multiple processes attempt to extract at the same time
97-
// first to a cache location, and then move the file into place.
98-
tmp, err := os.CreateTemp("", "embedded_postgres")
99-
if err != nil {
100-
return errorExtractingPostgres(err)
101-
}
100+
return fmt.Errorf("error fetching postgres: cannot find binary in archive retrieved from %s", downloadURL)
101+
}
102102

103-
if err := os.WriteFile(tmp.Name(), archiveBytes, file.FileHeader.Mode()); err != nil {
104-
return errorExtractingPostgres(err)
105-
}
103+
func decompressSingleFile(file *zip.File, cacheLocation string) error {
104+
renamed := false
105+
106+
archiveReader, err := file.Open()
107+
if err != nil {
108+
return errorExtractingPostgres(err)
109+
}
106110

107-
cacheLocation, _ := cacheLocator()
111+
archiveBytes, err := io.ReadAll(archiveReader)
112+
if err != nil {
113+
return errorExtractingPostgres(err)
114+
}
108115

109-
if err := os.MkdirAll(filepath.Dir(cacheLocation), 0755); err != nil {
110-
return errorExtractingPostgres(err)
116+
// if multiple processes attempt to extract
117+
// to prevent file corruption when multiple processes attempt to extract at the same time
118+
// first to a cache location, and then move the file into place.
119+
tmp, err := os.CreateTemp(filepath.Dir(cacheLocation), "temp_")
120+
if err != nil {
121+
return errorExtractingPostgres(err)
122+
}
123+
defer func() {
124+
// if anything failed before the rename then the temporary file should be cleaned up.
125+
// if the rename was successful then there is no temporary file to remove.
126+
if !renamed {
127+
if err := os.Remove(tmp.Name()); err != nil {
128+
panic(err)
111129
}
130+
}
131+
}()
112132

113-
// Windows cannot rename a file if is it still open.
114-
// The file needs to be manually closed to allow the rename to happen
115-
if err := tmp.Close(); err != nil {
116-
return errorExtractingPostgres(err)
117-
}
133+
if err := os.WriteFile(tmp.Name(), archiveBytes, file.FileHeader.Mode()); err != nil {
134+
return errorExtractingPostgres(err)
135+
}
118136

119-
if err := renameOrIgnore(tmp.Name(), cacheLocation); err != nil {
120-
return errorExtractingPostgres(err)
121-
}
137+
// Windows cannot rename a file if is it still open.
138+
// The file needs to be manually closed to allow the rename to happen
139+
if err := tmp.Close(); err != nil {
140+
return errorExtractingPostgres(err)
141+
}
122142

123-
return nil
124-
}
143+
if err := renameOrIgnore(tmp.Name(), cacheLocation); err != nil {
144+
return errorExtractingPostgres(err)
125145
}
146+
renamed = true
126147

127-
return fmt.Errorf("error fetching postgres: cannot find binary in archive retrieved from %s", downloadURL)
148+
return nil
128149
}
129150

130151
func errorExtractingPostgres(err error) error {

0 commit comments

Comments
 (0)