summaryrefslogtreecommitdiff
path: root/image
diff options
context:
space:
mode:
authorRob Cowsill <42620235+rcowsill@users.noreply.github.com>2021-01-21 21:55:29 +0000
committerRob Cowsill <42620235+rcowsill@users.noreply.github.com>2021-01-21 22:04:23 +0000
commit42dba8c3f9a821c64864c49e60fff9b3ba3e86c5 (patch)
treebc7561b13a017739479927df814c024520341e5f /image
parentb865beba22aac576b95952fef97d4e775632c362 (diff)
downloaddocker-42dba8c3f9a821c64864c49e60fff9b3ba3e86c5.tar.gz
Fix spurious error from "docker load"
"docker load" validates parent links by comparing image histories, and the History struct has a time.Time member "Created". Time.UnmarshalJSON can read RFC3339 timestamps with offset "+00:00", but t.MarshalJSON writes them with offset "Z". Equivalent times in these two formats are not equal when compared with the == operator. This causes checkValidParent to incorrectly return false when the parent image history contains times using offset "+00:00". In that case the history copied to the child image will have been converted into "Z" form when marshaled out. This patch adds an "Equal" method to History, which compares "Created" times with t.Equal. This is used instead of reflect.DeepEqual in checkValidParent. Signed-off-by: Rob Cowsill <42620235+rcowsill@users.noreply.github.com>
Diffstat (limited to 'image')
-rw-r--r--image/image.go11
-rw-r--r--image/image_test.go23
-rw-r--r--image/tarexport/load.go3
3 files changed, 35 insertions, 2 deletions
diff --git a/image/image.go b/image/image.go
index 29de613a3e..a9db58fd65 100644
--- a/image/image.go
+++ b/image/image.go
@@ -4,6 +4,7 @@ import (
"encoding/json"
"errors"
"io"
+ "reflect"
"runtime"
"strings"
"time"
@@ -218,6 +219,16 @@ func NewHistory(author, comment, createdBy string, isEmptyLayer bool) History {
}
}
+// Equal compares two history structs for equality
+func (h History) Equal(i History) bool {
+ if !h.Created.Equal(i.Created) {
+ return false
+ }
+ i.Created = h.Created
+
+ return reflect.DeepEqual(h, i)
+}
+
// Exporter provides interface for loading and saving images
type Exporter interface {
Load(io.ReadCloser, io.Writer, bool) error
diff --git a/image/image_test.go b/image/image_test.go
index b174b80908..21f81c768d 100644
--- a/image/image_test.go
+++ b/image/image_test.go
@@ -56,6 +56,29 @@ func TestMarshalKeyOrder(t *testing.T) {
}
}
+const sampleHistoryJSON = `{
+ "created": "2021-01-13T09:35:56Z",
+ "created_by": "image_test.go"
+}`
+
+func TestHistoryEqual(t *testing.T) {
+ h := historyFromJSON(t, sampleHistoryJSON)
+ hCopy := h
+ assert.Check(t, h.Equal(hCopy))
+
+ hUTC := historyFromJSON(t, `{"created": "2021-01-13T14:00:00Z"}`)
+ hOffset0 := historyFromJSON(t, `{"created": "2021-01-13T14:00:00+00:00"}`)
+ assert.Check(t, hUTC.Created != hOffset0.Created)
+ assert.Check(t, hUTC.Equal(hOffset0))
+}
+
+func historyFromJSON(t *testing.T, historyJSON string) History {
+ var h History
+ err := json.Unmarshal([]byte(historyJSON), &h)
+ assert.Check(t, err)
+ return h
+}
+
func TestImage(t *testing.T) {
cid := "50a16564e727"
config := &container.Config{
diff --git a/image/tarexport/load.go b/image/tarexport/load.go
index bbbb238b2b..37ac4bf082 100644
--- a/image/tarexport/load.go
+++ b/image/tarexport/load.go
@@ -8,7 +8,6 @@ import (
"io/ioutil"
"os"
"path/filepath"
- "reflect"
"runtime"
"github.com/containerd/containerd/platforms"
@@ -406,7 +405,7 @@ func checkValidParent(img, parent *image.Image) bool {
return false
}
for i, h := range parent.History {
- if !reflect.DeepEqual(h, img.History[i]) {
+ if !h.Equal(img.History[i]) {
return false
}
}