api/weldr: bring tars back from the future

By default, go's tar archiver uses USTAR header format. Unfortunately, this
format doesn't support sub-second resolution for ModTime. Go solves this by
*rounding* the time. Sometimes, this creates an archive containing a file
with modtime from the future. When such archive is untarred by GNU tar,
the following message is produced:

tar: bf548dfd-0a90-40e6-bbf2-dcdd82fcbb4e.json: time stamp 2020-07-13
13:34:31 is 0.356223173 s in the future

We have two options here:

1) Use gnu header format that supports sub-second resolution. Unfortunately,
   it seems that not all tar archivers support this format (e.g. 7-zip).

2) The other option is to truncate the date (instead of rounding).

I went with option 2.

Also, this commit adds a test to check that the header is not from the future.
Without this fix, the test is actually failing, I verified this manually.

Fixes #854
This commit is contained in:
Ondřej Budai 2020-07-14 09:59:28 +02:00 committed by Tom Gundersen
parent 4b0409df5b
commit 454e471af8
2 changed files with 5 additions and 4 deletions

View file

@ -2270,7 +2270,7 @@ func (api *API) composeMetadataHandler(writer http.ResponseWriter, request *http
Name: uuid.String() + ".json",
Mode: 0600,
Size: int64(len(metadata)),
ModTime: time.Now(),
ModTime: time.Now().Truncate(time.Second),
}
err = tw.WriteHeader(hdr)
common.PanicOnError(err)
@ -2331,7 +2331,7 @@ func (api *API) composeResultsHandler(writer http.ResponseWriter, request *http.
Name: uuid.String() + ".json",
Mode: 0644,
Size: int64(len(metadata)),
ModTime: time.Now(),
ModTime: time.Now().Truncate(time.Second),
}
err = tw.WriteHeader(hdr)
common.PanicOnError(err)
@ -2348,7 +2348,7 @@ func (api *API) composeResultsHandler(writer http.ResponseWriter, request *http.
Name: "logs/osbuild.log",
Mode: 0644,
Size: int64(fileContents.Len()),
ModTime: time.Now(),
ModTime: time.Now().Truncate(time.Second),
}
err = tw.WriteHeader(hdr)
common.PanicOnError(err)
@ -2362,7 +2362,7 @@ func (api *API) composeResultsHandler(writer http.ResponseWriter, request *http.
Name: uuid.String() + "-" + compose.ImageBuild.ImageType.Filename(),
Mode: 0644,
Size: int64(fileSize),
ModTime: time.Now(),
ModTime: time.Now().Truncate(time.Second),
}
err = tw.WriteHeader(hdr)
common.PanicOnError(err)

View file

@ -679,6 +679,7 @@ func TestComposeLogs(t *testing.T) {
h, err := tr.Next()
require.NoErrorf(t, err, "untarring failed with error")
require.Falsef(t, h.ModTime.After(time.Now()), "ModTime cannot be in the future")
require.Equalf(t, c.ExpectedFileName, h.Name, "%s: unexpected file name", c.Path)
var buffer bytes.Buffer