Skip to content

Commit

Permalink
Merge pull request #14 from mattfarina/fix-13
Browse files Browse the repository at this point in the history
Fixing issue of process holding on to file during rename
  • Loading branch information
flavio authored Aug 17, 2021
2 parents f766ce4 + d7a53ea commit b6b4b3e
Showing 1 changed file with 15 additions and 8 deletions.
23 changes: 15 additions & 8 deletions internal/downloader/download.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,6 @@ import (
"crypto/sha256"
"encoding/hex"
"fmt"
"github.com/flavio/kuberlr/internal/common"
"github.com/flavio/kuberlr/internal/osexec"
"io"
"io/ioutil"
"net/http"
Expand All @@ -16,6 +14,9 @@ import (
"strings"
"time"

"github.com/flavio/kuberlr/internal/common"
"github.com/flavio/kuberlr/internal/osexec"

"github.com/blang/semver/v4"
"github.com/schollz/progressbar/v3"
)
Expand Down Expand Up @@ -153,8 +154,9 @@ func (d *Downloder) download(desc, urlToGet, destination string, mode os.FileMod
if err != nil {
return fmt.Errorf("Error trying to create temporary file in %s: %v", os.TempDir(), err)
}
defer temporaryDestinationFile.Close()
defer os.Remove(temporaryDestinationFile.Name())

tmpname := temporaryDestinationFile.Name()
defer os.Remove(tmpname)

// write progress to stderr, writing to stdout would
// break bash/zsh/shell completion
Expand All @@ -175,25 +177,30 @@ func (d *Downloder) download(desc, urlToGet, destination string, mode os.FileMod

_, err = io.Copy(io.MultiWriter(temporaryDestinationFile, bar, hasher), resp.Body)
if err != nil {
temporaryDestinationFile.Close()
return fmt.Errorf(
"Error while downloading text of %s into file %s: %v",
urlToGet, temporaryDestinationFile.Name(), err)
urlToGet, tmpname, err)
}

// Closing the file handler prior to performing a rename so this process (the
// open file handler) does not conflict with the rename.
temporaryDestinationFile.Close()

shaActual := hex.EncodeToString(hasher.Sum(nil))
if shaExpected != shaActual {
return &common.ShaMismatchError{URL: urlToGet, ShaExpected: shaExpected, ShaActual: shaActual}
}

err = os.Rename(temporaryDestinationFile.Name(), destination)
err = os.Rename(tmpname, destination)
if err != nil {
linkErr, ok := err.(*os.LinkError)
if ok {
fmt.Fprintf(os.Stderr, "Cross-device error trying to rename a file: %s -- will do a full copy\n", linkErr)
tempInput, err := ioutil.ReadFile(temporaryDestinationFile.Name())
tempInput, err := ioutil.ReadFile(tmpname)
if err != nil {
return fmt.Errorf("Error reading temporary file %s: %v",
temporaryDestinationFile.Name(), err)
tmpname, err)
}
err = ioutil.WriteFile(destination, tempInput, mode)
}
Expand Down

0 comments on commit b6b4b3e

Please sign in to comment.