8
8
"strings"
9
9
"time"
10
10
11
+ nameref "github.com/google/go-containerregistry/pkg/name"
12
+
11
13
"github.com/stacklok/toolhive/pkg/certs"
12
14
"github.com/stacklok/toolhive/pkg/container/images"
13
15
"github.com/stacklok/toolhive/pkg/container/templates"
@@ -29,6 +31,20 @@ func HandleProtocolScheme(
29
31
imageManager images.ImageManager ,
30
32
serverOrImage string ,
31
33
caCertPath string ,
34
+ ) (string , error ) {
35
+ return BuildFromProtocolSchemeWithName (ctx , imageManager , serverOrImage , caCertPath , "" )
36
+ }
37
+
38
+ // BuildFromProtocolSchemeWithName checks if the serverOrImage string contains a protocol scheme (uvx://, npx://, or go://)
39
+ // and builds a Docker image for it if needed with a custom image name.
40
+ // If imageName is empty, a default name will be generated.
41
+ // Returns the Docker image name to use and any error encountered.
42
+ func BuildFromProtocolSchemeWithName (
43
+ ctx context.Context ,
44
+ imageManager images.ImageManager ,
45
+ serverOrImage string ,
46
+ caCertPath string ,
47
+ imageName string ,
32
48
) (string , error ) {
33
49
transportType , packageName , err := parseProtocolScheme (serverOrImage )
34
50
if err != nil {
@@ -40,7 +56,7 @@ func HandleProtocolScheme(
40
56
return "" , err
41
57
}
42
58
43
- return buildImageFromTemplate (ctx , imageManager , transportType , packageName , templateData )
59
+ return buildImageFromTemplateWithName (ctx , imageManager , transportType , packageName , templateData , imageName )
44
60
}
45
61
46
62
// parseProtocolScheme extracts the transport type and package name from the protocol scheme.
@@ -243,13 +259,15 @@ func generateImageName(transportType templates.TransportType, packageName string
243
259
tag ))
244
260
}
245
261
246
- // buildImageFromTemplate builds a Docker image from the template data.
247
- func buildImageFromTemplate (
262
+ // buildImageFromTemplateWithName builds a Docker image from the template data with a custom image name.
263
+ // If imageName is empty, a default name will be generated.
264
+ func buildImageFromTemplateWithName (
248
265
ctx context.Context ,
249
266
imageManager images.ImageManager ,
250
267
transportType templates.TransportType ,
251
268
packageName string ,
252
269
templateData templates.TemplateData ,
270
+ imageName string ,
253
271
) (string , error ) {
254
272
255
273
// Get the Dockerfile content
@@ -277,21 +295,33 @@ func buildImageFromTemplate(
277
295
}
278
296
defer caCertCleanup ()
279
297
280
- // Generate image name
281
- imageName := generateImageName (transportType , packageName )
298
+ // Use provided image name or generate one
299
+ finalImageName := imageName
300
+ if finalImageName == "" {
301
+ finalImageName = generateImageName (transportType , packageName )
302
+ } else {
303
+ // Validate the provided image name using go-containerregistry
304
+ ref , err := nameref .ParseReference (finalImageName )
305
+ if err != nil {
306
+ return "" , fmt .Errorf ("invalid image name format '%s': %w" , finalImageName , err )
307
+ }
308
+ // Use the normalized reference string
309
+ finalImageName = ref .String ()
310
+ logger .Debugf ("Using validated image name: %s" , finalImageName )
311
+ }
282
312
283
313
// Log the build process
284
314
logger .Debugf ("Building Docker image for %s package: %s" , transportType , packageName )
285
315
logger .Debugf ("Using Dockerfile:\n %s" , dockerfileContent )
286
316
287
317
// Build the Docker image
288
318
logger .Infof ("Building Docker image for %s package: %s" , transportType , packageName )
289
- if err := imageManager .BuildImage (ctx , buildCtx .Dir , imageName ); err != nil {
319
+ if err := imageManager .BuildImage (ctx , buildCtx .Dir , finalImageName ); err != nil {
290
320
return "" , fmt .Errorf ("failed to build Docker image: %w" , err )
291
321
}
292
- logger .Infof ("Successfully built Docker image: %s" , imageName )
322
+ logger .Infof ("Successfully built Docker image: %s" , finalImageName )
293
323
294
- return imageName , nil
324
+ return finalImageName , nil
295
325
}
296
326
297
327
// Replace slashes with dashes to create a valid Docker image name. If there
0 commit comments