From 454e471af8f448d9c9cb1c8d985f10051c6f4f37 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Budai?= Date: Tue, 14 Jul 2020 09:59:28 +0200 Subject: [PATCH] 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 --- internal/weldr/api.go | 8 ++++---- internal/weldr/api_test.go | 1 + 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/internal/weldr/api.go b/internal/weldr/api.go index 7fffe1349..5a6a23f39 100644 --- a/internal/weldr/api.go +++ b/internal/weldr/api.go @@ -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) diff --git a/internal/weldr/api_test.go b/internal/weldr/api_test.go index 1b6b10b80..4afef1baf 100644 --- a/internal/weldr/api_test.go +++ b/internal/weldr/api_test.go @@ -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