Check disk space before trying a write from the downloader; don't make empty directories if we can't even write the file
This commit is contained in:
parent
9c53436470
commit
c718da20e3
|
@ -66,10 +66,19 @@ func (dl *Download) Execute() error {
|
||||||
return errors.New("downloader: failed opening request to download file")
|
return errors.New("downloader: failed opening request to download file")
|
||||||
}
|
}
|
||||||
defer res.Body.Close()
|
defer res.Body.Close()
|
||||||
if res.StatusCode >= 300 || res.StatusCode < 200 {
|
if res.StatusCode != http.StatusOK {
|
||||||
return errors.New("downloader: got bad response status from endpoint: " + res.Status)
|
return errors.New("downloader: got bad response status from endpoint: " + res.Status)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// If there is a Content-Length header on this request go ahead and check that we can
|
||||||
|
// even write the whole file before beginning this process. If there is no header present
|
||||||
|
// we'll just have to give it a spin and see how it goes.
|
||||||
|
if res.ContentLength > 0 {
|
||||||
|
if err := dl.server.Filesystem().HasSpaceFor(res.ContentLength); err != nil {
|
||||||
|
return errors.WrapIf(err, "downloader: failed to write file: not enough space")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fnameparts := strings.Split(dl.req.URL.Path, "/")
|
fnameparts := strings.Split(dl.req.URL.Path, "/")
|
||||||
p := filepath.Join(dl.req.Directory, fnameparts[len(fnameparts)-1])
|
p := filepath.Join(dl.req.Directory, fnameparts[len(fnameparts)-1])
|
||||||
dl.server.Log().WithField("path", p).Debug("writing remote file to disk")
|
dl.server.Log().WithField("path", p).Debug("writing remote file to disk")
|
||||||
|
|
|
@ -150,7 +150,7 @@ func (fs *Filesystem) CompressFiles(dir string, paths []string) (os.FileInfo, er
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := fs.hasSpaceFor(f.Size()); err != nil {
|
if err := fs.HasSpaceFor(f.Size()); err != nil {
|
||||||
_ = os.Remove(d)
|
_ = os.Remove(d)
|
||||||
|
|
||||||
return nil, err
|
return nil, err
|
||||||
|
|
|
@ -203,7 +203,7 @@ func (fs *Filesystem) DirectorySize(dir string) (int64, error) {
|
||||||
// Helper function to determine if a server has space available for a file of a given size.
|
// Helper function to determine if a server has space available for a file of a given size.
|
||||||
// If space is available, no error will be returned, otherwise an ErrNotEnoughSpace error
|
// If space is available, no error will be returned, otherwise an ErrNotEnoughSpace error
|
||||||
// will be raised.
|
// will be raised.
|
||||||
func (fs *Filesystem) hasSpaceFor(size int64) error {
|
func (fs *Filesystem) HasSpaceFor(size int64) error {
|
||||||
if fs.MaxDisk() == 0 {
|
if fs.MaxDisk() == 0 {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
|
@ -86,34 +86,36 @@ func (fs *Filesystem) Writefile(p string, r io.Reader) error {
|
||||||
var currentSize int64
|
var currentSize int64
|
||||||
// If the file does not exist on the system already go ahead and create the pathway
|
// If the file does not exist on the system already go ahead and create the pathway
|
||||||
// to it and an empty file. We'll then write to it later on after this completes.
|
// to it and an empty file. We'll then write to it later on after this completes.
|
||||||
if stat, err := os.Stat(cleaned); err != nil {
|
stat, err := os.Stat(cleaned)
|
||||||
if !os.IsNotExist(err) {
|
if err != nil && !os.IsNotExist(err) {
|
||||||
return err
|
return err
|
||||||
}
|
} else if err == nil {
|
||||||
|
|
||||||
if err := os.MkdirAll(filepath.Dir(cleaned), 0755); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
if err := fs.Chown(filepath.Dir(cleaned)); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if stat.IsDir() {
|
if stat.IsDir() {
|
||||||
return &Error{code: ErrCodeIsDirectory}
|
return &Error{code: ErrCodeIsDirectory}
|
||||||
}
|
}
|
||||||
|
|
||||||
currentSize = stat.Size()
|
currentSize = stat.Size()
|
||||||
}
|
}
|
||||||
|
|
||||||
br := bufio.NewReader(r)
|
br := bufio.NewReader(r)
|
||||||
// Check that the new size we're writing to the disk can fit. If there is currently a file
|
// Check that the new size we're writing to the disk can fit. If there is currently
|
||||||
// we'll subtract that current file size from the size of the buffer to determine the amount
|
// a file we'll subtract that current file size from the size of the buffer to determine
|
||||||
// of new data we're writing (or amount we're removing if smaller).
|
// the amount of new data we're writing (or amount we're removing if smaller).
|
||||||
if err := fs.hasSpaceFor(int64(br.Size()) - currentSize); err != nil {
|
if err := fs.HasSpaceFor(int64(br.Size()) - currentSize); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// If we were unable to stat the location because it did not exist, go ahead and create
|
||||||
|
// it now. We do this after checking the disk space so that we do not just create empty
|
||||||
|
// directories at random.
|
||||||
|
if err != nil {
|
||||||
|
if err := os.MkdirAll(filepath.Dir(cleaned), 0755); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if err := fs.Chown(filepath.Dir(cleaned)); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
o := &fileOpener{}
|
o := &fileOpener{}
|
||||||
// This will either create the file if it does not already exist, or open and
|
// This will either create the file if it does not already exist, or open and
|
||||||
// truncate the existing file.
|
// truncate the existing file.
|
||||||
|
@ -298,7 +300,7 @@ func (fs *Filesystem) Copy(p string) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check that copying this file wouldn't put the server over its limit.
|
// Check that copying this file wouldn't put the server over its limit.
|
||||||
if err := fs.hasSpaceFor(s.Size()); err != nil {
|
if err := fs.HasSpaceFor(s.Size()); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue
Block a user