Skip to content

Commit

Permalink
Disable grab download resume
Browse files Browse the repository at this point in the history
This is to mitigate cases like #4296

By default grab tries to resume the download if the file name determined from either the url or from content-type headers already exists. This makes things go side ways, if the existing file is smaller than the new one, the old content would still be there and only the "extra" new bytes would get written. I.e. the download would be "resumed". 🤦

This is probably not a fix for the root cause in #4296 as the only way I've been able to make grab fail with `bad content length` is by crafting a custom http server that maliciously borks `Content-Length` header.

This is a minimal possible fix that we can easily backport. @twz123 is already working on bigger refactoring of autopilot download functionality that gets rid of grab. Grab seems to bring more (bad) surprises than real benefits. In the end, we just download files and we should pretty much always just replace them. No need for full library dependecy for that.

Signed-off-by: Jussi Nummelin <jnummelin@mirantis.com>
  • Loading branch information
jnummelin committed Sep 23, 2024
1 parent bb4dfd5 commit ff0da08
Show file tree
Hide file tree
Showing 3 changed files with 27 additions and 1 deletion.
9 changes: 8 additions & 1 deletion pkg/autopilot/controller/signal/common/download.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,8 @@ type DownloadManifest struct {
apdl.Config

SuccessState string
// A hook that will be called after the download itself is done succesfully
AfterTransferSuccess func() error
}

type DownloadManifestBuilder interface {
Expand Down Expand Up @@ -90,7 +92,12 @@ func (r *downloadController) Reconcile(ctx context.Context, req cr.Request) (cr.

} else {
logger.Infof("Download of '%s' successful", manifest.URL)

// When download is successful, run the post-download hook
if manifest.AfterTransferSuccess != nil {
if err := manifest.AfterTransferSuccess(); err != nil {
return cr.Result{}, fmt.Errorf("failed to run post-download hook: %w", err)
}
}
// When the download is complete move the status to the success state
signalData.Status = apsigv2.NewStatus(manifest.SuccessState)
}
Expand Down
9 changes: 9 additions & 0 deletions pkg/autopilot/controller/signal/k0s/download.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@ package k0s

import (
"crypto/sha256"
"os"
"path/filepath"

apcomm "github.com/k0sproject/k0s/pkg/autopilot/common"
apdel "github.com/k0sproject/k0s/pkg/autopilot/controller/delegate"
Expand Down Expand Up @@ -88,6 +90,13 @@ func (b downloadManifestBuilderK0s) Build(signalNode crcli.Object, signalData ap
ExpectedHash: signalData.Command.K0sUpdate.Sha256,
Hasher: sha256.New(),
DownloadDir: b.k0sBinaryDir,
Filename: filepath.Join(b.k0sBinaryDir, "k0s.tmp"),
},
// After the download is done, we need to rename the file to the correct name
AfterTransferSuccess: func() error {
src := filepath.Join(b.k0sBinaryDir, "k0s.tmp")
dst := filepath.Join(b.k0sBinaryDir, "k0s")
return os.Rename(src, dst)
},
SuccessState: Cordoning,
}
Expand Down
10 changes: 10 additions & 0 deletions pkg/autopilot/download/downloader.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ type Config struct {
ExpectedHash string
Hasher hash.Hash
DownloadDir string
Filename string
}

type downloader struct {
Expand Down Expand Up @@ -72,6 +73,15 @@ func (d *downloader) Download(ctx context.Context) error {
dlreq.SetChecksum(d.config.Hasher, expectedHash, true)
}

// We're never really resuming downloads, so disable this feature.
// This also allows to re-download the file if it's already present.
dlreq.NoResume = true

if d.config.Filename != "" {
d.logger.Infof("Setting filename to %s", d.config.Filename)
dlreq.Filename = d.config.Filename
}

client := grab.NewClient()
// Set user agent to mitigate 403 errors from GitHub
// See https://github.com/cavaliergopher/grab/issues/104
Expand Down

0 comments on commit ff0da08

Please sign in to comment.