@@ -20,10 +20,9 @@ import (
20
20
"io/ioutil"
21
21
22
22
"os"
23
- "regexp"
24
- "strings"
25
23
26
24
"github.com/GoogleContainerTools/container-structure-test/cmd/container-structure-test/app/cmd/test"
25
+ v1 "github.com/opencontainers/image-spec/specs-go/v1"
27
26
28
27
"github.com/GoogleContainerTools/container-structure-test/pkg/color"
29
28
"github.com/GoogleContainerTools/container-structure-test/pkg/config"
@@ -33,6 +32,9 @@ import (
33
32
"github.com/GoogleContainerTools/container-structure-test/pkg/utils"
34
33
35
34
docker "github.com/fsouza/go-dockerclient"
35
+ "github.com/google/go-containerregistry/pkg/name"
36
+ "github.com/google/go-containerregistry/pkg/v1/daemon"
37
+ "github.com/google/go-containerregistry/pkg/v1/layout"
36
38
"github.com/sirupsen/logrus"
37
39
"github.com/spf13/cobra"
38
40
)
@@ -43,9 +45,6 @@ Be sure you know what you're doing before continuing!
43
45
44
46
Continue? (y/n)`
45
47
46
- var totalTests int
47
- var testReportFile * os.File
48
-
49
48
var (
50
49
opts = & config.StructureTestOptions {}
51
50
@@ -106,21 +105,76 @@ func run(out io.Writer) error {
106
105
107
106
var err error
108
107
108
+ if opts .ImageFromLayout != "" {
109
+ if opts .Driver != drivers .Docker {
110
+ logrus .Fatal ("--image-from-oci-layout is not supported when not using Docker driver" )
111
+ }
112
+ l , err := layout .ImageIndexFromPath (opts .ImageFromLayout )
113
+ if err != nil {
114
+ logrus .Fatalf ("loading %s as OCI layout: %v" , opts .ImageFromLayout , err )
115
+ }
116
+ m , err := l .IndexManifest ()
117
+ if err != nil {
118
+ logrus .Fatalf ("could not read OCI index manifest %s: %v" , opts .ImageFromLayout , err )
119
+ }
120
+
121
+ if len (m .Manifests ) != 1 {
122
+ logrus .Fatalf ("OCI layout contains %d entries. expected only one" , len (m .Manifests ))
123
+ }
124
+
125
+ desc := m .Manifests [0 ]
126
+
127
+ if desc .MediaType .IsIndex () {
128
+ logrus .Fatal ("multi-arch images are not supported yet." )
129
+ }
130
+
131
+ img , err := l .Image (desc .Digest )
132
+
133
+ if err != nil {
134
+ logrus .Fatalf ("could not get image from %s: %v" , opts .ImageFromLayout , err )
135
+ }
136
+
137
+ var tag name.Tag
138
+
139
+ ref := desc .Annotations [v1 .AnnotationRefName ]
140
+ if ref != "" {
141
+ tag , err = name .NewTag (ref )
142
+ if err != nil {
143
+ logrus .Fatalf ("could not parse ref annotation %s: %v" , v1 .AnnotationRefName , err )
144
+ }
145
+ } else {
146
+ if opts .DefaultImageTag == "" {
147
+ logrus .Fatalf ("index does not contain a reference annotation. --default-image-tag must be provided." )
148
+ }
149
+ tag , err = name .NewTag (opts .DefaultImageTag , name .StrictValidation )
150
+ if err != nil {
151
+ logrus .Fatalf ("could parse the default image tag %s: %v" , opts .DefaultImageTag , err )
152
+ }
153
+ }
154
+ if _ , err = daemon .Write (tag , img ); err != nil {
155
+ logrus .Fatalf ("error loading oci layout into daemon: %v, %s" , err )
156
+ }
157
+
158
+ opts .ImagePath = tag .String ()
159
+ args .Image = tag .String ()
160
+ }
161
+
109
162
if opts .Pull {
110
163
if opts .Driver != drivers .Docker {
111
164
logrus .Fatal ("image pull not supported when not using Docker driver" )
112
165
}
113
- var repository , tag string
114
- parts := splitImagePath (opts .ImagePath )
115
- if len (parts ) < 2 {
116
- logrus .Fatal ("no tag specified for provided image" )
166
+ ref , err := name .ParseReference (opts .ImagePath )
167
+ if err != nil {
168
+ logrus .Fatal (err )
117
169
}
118
- repository = parts [0 ]
119
- tag = parts [1 ]
120
170
client , err := docker .NewClientFromEnv ()
171
+ if err != nil {
172
+ logrus .Fatalf ("error connecting to daemon: %v" , err )
173
+ }
121
174
if err = client .PullImage (docker.PullImageOptions {
122
- Repository : repository ,
123
- Tag : tag ,
175
+ Repository : ref .Context ().RepositoryStr (),
176
+ Tag : ref .Identifier (),
177
+ Registry : ref .Context ().RegistryStr (),
124
178
OutputStream : out ,
125
179
}, docker.AuthConfiguration {}); err != nil {
126
180
logrus .Fatalf ("error pulling remote image %s: %s" , opts .ImagePath , err .Error ())
@@ -163,38 +217,17 @@ func runTests(out io.Writer, channel chan interface{}, args *drivers.DriverConfi
163
217
close (channel )
164
218
}
165
219
166
- func splitImagePath (imagePath string ) []string {
167
- var parts []string
168
- if strings .Contains (imagePath , "@" ) {
169
- parts = strings .Split (imagePath , "@" )
170
- } else {
171
- switch countColons := strings .Count (imagePath , ":" ); countColons {
172
- case 0 :
173
- parts = []string {imagePath }
174
- case 1 :
175
- match , _ := regexp .MatchString (`:\d{1,5}\/` , imagePath )
176
- if match {
177
- //colon is part of a registry port and no tag available
178
- parts = []string {imagePath }
179
- } else {
180
- //colon separates image name and tag
181
- parts = strings .Split (imagePath , ":" )
182
- }
183
- default :
184
- imageTagRegex , _ := regexp .Compile ("(.*):(.*)" )
185
- parts = imageTagRegex .FindStringSubmatch (imagePath )[1 :]
186
- }
187
- }
188
- return parts
189
- }
190
-
191
220
func AddTestFlags (cmd * cobra.Command ) {
192
221
cmd .Flags ().StringVarP (& opts .ImagePath , "image" , "i" , "" , "path to test image" )
222
+ cmd .Flags ().StringVar (& opts .ImageFromLayout , "image-from-oci-layout" , "" , "path to the oci layout to test against" )
223
+ cmd .Flags ().StringVar (& opts .DefaultImageTag , "default-image-tag" , "" , "default image tag to used when loading images to the daemon. required when --image-from-oci-layout refers to a oci layout lacking the reference annotation." )
224
+ cmd .MarkFlagsMutuallyExclusive ("image" , "image-from-oci-layout" )
193
225
cmd .Flags ().StringVarP (& opts .Driver , "driver" , "d" , "docker" , "driver to use when running tests" )
194
226
cmd .Flags ().StringVar (& opts .Metadata , "metadata" , "" , "path to image metadata file" )
195
227
cmd .Flags ().StringVar (& opts .Runtime , "runtime" , "" , "runtime to use with docker driver" )
196
228
197
229
cmd .Flags ().BoolVar (& opts .Pull , "pull" , false , "force a pull of the image before running tests" )
230
+ cmd .MarkFlagsMutuallyExclusive ("image-from-oci-layout" , "pull" )
198
231
cmd .Flags ().BoolVar (& opts .Save , "save" , false , "preserve created containers after test run" )
199
232
cmd .Flags ().BoolVarP (& opts .Quiet , "quiet" , "q" , false , "flag to suppress output" )
200
233
cmd .Flags ().BoolVarP (& opts .Force , "force" , "f" , false , "force run of host driver (without user prompt)" )
0 commit comments