@@ -49,79 +49,100 @@ type inputNormalized struct {
49
49
Do func (ctx context.Context , dstRef registry.Reference ) (ociregistry.Descriptor , error ) `json:"-"`
50
50
}
51
51
52
- func NormalizeInput (raw inputRaw ) (inputNormalized , error ) {
53
- var normal inputNormalized
54
-
55
- switch raw .Type {
56
- case "" :
57
- // TODO is there one of the two types that I might push by hand more often than the other that could be the default when this is unspecified?
58
- return normal , fmt .Errorf ("missing type" )
59
-
60
- case typeManifest , typeBlob :
61
- normal .Type = raw .Type
62
-
63
- default :
64
- return normal , fmt .Errorf ("unknown type: %s" , raw .Type )
65
- }
66
-
67
- if raw .Refs == nil {
68
- return normal , fmt .Errorf ("missing refs entirely (JSON input glitch?)" )
69
- }
70
- if len (raw .Refs ) == 0 {
71
- return normal , fmt .Errorf ("zero refs specified for pushing (need at least one)" )
72
- }
73
- normal .Refs = make ([]registry.Reference , len (raw .Refs ))
74
- var refsDigest ociregistry.Digest // if any ref has a digest, they all have to have the same digest (and our data has to match)
75
- for i , refString := range raw .Refs {
52
+ func normalizeInputRefs (deployType deployType , rawRefs []string ) ([]registry.Reference , ociregistry.Digest , error ) {
53
+ refs := make ([]registry.Reference , len (rawRefs ))
54
+ var commonDigest ociregistry.Digest // if any ref has a digest, they all have to have the same digest (and our data has to match)
55
+ for i , refString := range rawRefs {
76
56
ref , err := registry .ParseRef (refString )
77
57
if err != nil {
78
- return normal , fmt .Errorf ("%s: failed to parse ref: %w" , refString , err )
58
+ return nil , "" , fmt .Errorf ("%s: failed to parse ref: %w" , refString , err )
79
59
}
80
60
81
61
if ref .Digest != "" {
82
- if refsDigest == "" {
83
- refsDigest = ref .Digest
84
- } else if ref .Digest != refsDigest {
85
- return normal , fmt .Errorf ("refs digest mismatch in %s: %s" , ref , refsDigest )
62
+ if commonDigest == "" {
63
+ commonDigest = ref .Digest
64
+ } else if ref .Digest != commonDigest {
65
+ return nil , "" , fmt .Errorf ("refs digest mismatch in %s: %s" , ref , commonDigest )
86
66
}
87
67
}
88
68
89
- if normal . Type == typeBlob && ref .Tag != "" {
90
- return normal , fmt .Errorf ("cannot push blobs to a tag: %s" , ref )
69
+ if deployType == typeBlob && ref .Tag != "" {
70
+ return nil , "" , fmt .Errorf ("cannot push blobs to a tag: %s" , ref )
91
71
}
92
72
93
- normal . Refs [i ] = ref
73
+ refs [i ] = ref
94
74
}
95
- debugId := normal .Refs [0 ]
96
75
97
- normal .Lookup = make (map [ociregistry.Digest ]registry.Reference , len (raw .Lookup ))
98
- var lookupDigest ociregistry.Digest // if we store this out here, we can abuse it later to get the "last" lookup digest (for getting the single key in the case of len(lookup) == 1 without a new loop)
99
- for d , refString := range raw .Lookup {
100
- lookupDigest = ociregistry .Digest (d )
101
- if lookupDigest != "" {
76
+ return refs , commonDigest , nil
77
+ }
78
+
79
+ func normalizeInputLookup (rawLookup map [string ]string ) (map [ociregistry.Digest ]registry.Reference , ociregistry.Digest , error ) {
80
+ lookups := make (map [ociregistry.Digest ]registry.Reference , len (rawLookup ))
81
+ var commonDigest ociregistry.Digest // if we store this out here, we can abuse it later to get the "last" lookup digest (for getting the single key in the case of len(lookup) == 1 without a new loop)
82
+ for d , refString := range rawLookup {
83
+ commonDigest = ociregistry .Digest (d )
84
+ if commonDigest != "" {
102
85
// normal.Lookup[""] is a special case for fallback (where to look for any child object that isn't explicitly referenced)
103
- if err := lookupDigest .Validate (); err != nil {
104
- return normal , fmt .Errorf ("%s: lookup key %q invalid: %w" , debugId , lookupDigest , err )
86
+ if err := commonDigest .Validate (); err != nil {
87
+ return nil , "" , fmt .Errorf ("lookup key %q invalid: %w" , commonDigest , err )
105
88
}
106
89
}
107
90
if ref , err := registry .ParseRef (refString ); err != nil {
108
- return normal , fmt .Errorf ("%s: failed to parse lookup ref %q: %v" , debugId , refString , err )
91
+ return nil , "" , fmt .Errorf ("failed to parse lookup ref %q: %v" , refString , err )
109
92
} else {
110
- if ref .Tag != "" && lookupDigest != "" {
93
+ if ref .Tag != "" && commonDigest != "" {
111
94
//return normal, fmt.Errorf("%s: tag on by-digest lookup ref makes no sense: %s (%s)", debugId, ref, d)
112
95
}
113
96
114
- if ref .Digest == "" && lookupDigest != "" {
115
- ref .Digest = lookupDigest
97
+ if ref .Digest == "" && commonDigest != "" {
98
+ ref .Digest = commonDigest
116
99
}
117
- if ref .Digest != lookupDigest && lookupDigest != "" {
118
- return normal , fmt .Errorf ("%s: digest on lookup ref should either be omitted or match key: %s vs %s" , debugId , ref , d )
100
+ if ref .Digest != commonDigest && commonDigest != "" {
101
+ return nil , "" , fmt .Errorf ("digest on lookup ref should either be omitted or match key: %s vs %s" , ref , d )
119
102
}
120
103
121
- normal . Lookup [ lookupDigest ] = ref
104
+ lookups [ commonDigest ] = ref
122
105
}
123
106
}
124
107
108
+ return lookups , commonDigest , nil
109
+ }
110
+
111
+ func NormalizeInput (raw inputRaw ) (inputNormalized , error ) {
112
+ var normal inputNormalized
113
+ var lookupDigest ociregistry.Digest
114
+ var refsDigest ociregistry.Digest
115
+ var err error
116
+
117
+ switch raw .Type {
118
+ case "" :
119
+ // TODO is there one of the two types that I might push by hand more often than the other that could be the default when this is unspecified?
120
+ return normal , fmt .Errorf ("missing type" )
121
+
122
+ case typeManifest , typeBlob :
123
+ normal .Type = raw .Type
124
+
125
+ default :
126
+ return normal , fmt .Errorf ("unknown type: %s" , raw .Type )
127
+ }
128
+
129
+ if raw .Refs == nil {
130
+ return normal , fmt .Errorf ("missing refs entirely (JSON input glitch?)" )
131
+ }
132
+ if len (raw .Refs ) == 0 {
133
+ return normal , fmt .Errorf ("zero refs specified for pushing (need at least one)" )
134
+ }
135
+ normal .Refs , refsDigest , err = normalizeInputRefs (normal .Type , raw .Refs )
136
+ if err != nil {
137
+ return normal , err
138
+ }
139
+
140
+ debugId := normal .Refs [0 ]
141
+ normal .Lookup , lookupDigest , err = normalizeInputLookup (raw .Lookup )
142
+ if err != nil {
143
+ return normal , fmt .Errorf ("%s: %w" , debugId , err )
144
+ }
145
+
125
146
if raw .Data == nil || bytes .Equal (raw .Data , []byte ("null" )) {
126
147
// if we have no Data, let's see if we have enough information to infer an object to copy
127
148
if lookupRef , ok := normal .Lookup [refsDigest ]; refsDigest != "" && ok {
0 commit comments