11package image
22
33import (
4- "archive/tar"
5- "bufio"
64 "bytes"
75 "context"
86 "encoding/json"
@@ -20,9 +18,7 @@ import (
2018 "github.com/docker/cli/cli/command/completion"
2119 "github.com/docker/cli/cli/command/image/build"
2220 "github.com/docker/cli/cli/streams"
23- "github.com/docker/cli/cli/trust"
2421 "github.com/docker/cli/internal/jsonstream"
25- "github.com/docker/cli/internal/lazyregexp"
2622 "github.com/docker/cli/opts"
2723 buildtypes "github.com/docker/docker/api/types/build"
2824 "github.com/docker/docker/api/types/container"
@@ -65,7 +61,6 @@ type buildOptions struct {
6561 target string
6662 imageIDFile string
6763 platform string
68- untrusted bool
6964}
7065
7166// dockerfileFromStdin returns true when the user specified that the Dockerfile
@@ -144,7 +139,8 @@ func NewBuildCommand(dockerCli command.Cli) *cobra.Command {
144139 flags .SetAnnotation ("target" , annotation .ExternalURL , []string {"https://docs.docker.com/reference/cli/docker/buildx/build/#target" })
145140 flags .StringVar (& options .imageIDFile , "iidfile" , "" , "Write the image ID to the file" )
146141
147- command .AddTrustVerificationFlags (flags , & options .untrusted , dockerCli .ContentTrustEnabled ())
142+ flags .Bool ("disable-content-trust" , dockerCli .ContentTrustEnabled (), "Skip image verification (deprecated)" )
143+ _ = flags .MarkHidden ("disable-content-trust" )
148144
149145 flags .StringVar (& options .platform , "platform" , os .Getenv ("DOCKER_DEFAULT_PLATFORM" ), "Set platform if server is multi-platform capable" )
150146 flags .SetAnnotation ("platform" , "version" , []string {"1.38" })
@@ -286,26 +282,6 @@ func runBuild(ctx context.Context, dockerCli command.Cli, options buildOptions)
286282 ctx , cancel := context .WithCancel (ctx )
287283 defer cancel ()
288284
289- var resolvedTags []* resolvedTag
290- if ! options .untrusted {
291- translator := func (ctx context.Context , ref reference.NamedTagged ) (reference.Canonical , error ) {
292- return TrustedReference (ctx , dockerCli , ref )
293- }
294- // if there is a tar wrapper, the dockerfile needs to be replaced inside it
295- if buildCtx != nil {
296- // Wrap the tar archive to replace the Dockerfile entry with the rewritten
297- // Dockerfile which uses trusted pulls.
298- buildCtx = replaceDockerfileForContentTrust (ctx , buildCtx , relDockerfile , translator , & resolvedTags )
299- } else if dockerfileCtx != nil {
300- // if there was not archive context still do the possible replacements in Dockerfile
301- newDockerfile , _ , err := rewriteDockerfileFromForContentTrust (ctx , dockerfileCtx , translator )
302- if err != nil {
303- return err
304- }
305- dockerfileCtx = io .NopCloser (bytes .NewBuffer (newDockerfile ))
306- }
307- }
308-
309285 if options .compress {
310286 buildCtx , err = build .Compress (buildCtx )
311287 if err != nil {
@@ -402,21 +378,10 @@ func runBuild(ctx context.Context, dockerCli command.Cli, options buildOptions)
402378 return err
403379 }
404380 }
405- if ! options .untrusted {
406- // Since the build was successful, now we must tag any of the resolved
407- // images from the above Dockerfile rewrite.
408- for _ , resolved := range resolvedTags {
409- if err := trust .TagTrusted (ctx , dockerCli .Client (), dockerCli .Err (), resolved .digestRef , resolved .tagRef ); err != nil {
410- return err
411- }
412- }
413- }
414381
415382 return nil
416383}
417384
418- type translatorFunc func (context.Context , reference.NamedTagged ) (reference.Canonical , error )
419-
420385// validateTag checks if the given image name can be resolved.
421386func validateTag (rawRepo string ) (string , error ) {
422387 _ , err := reference .ParseNormalizedNamed (rawRepo )
@@ -427,118 +392,6 @@ func validateTag(rawRepo string) (string, error) {
427392 return rawRepo , nil
428393}
429394
430- var dockerfileFromLinePattern = lazyregexp .New (`(?i)^[\s]*FROM[ \f\r\t\v]+(?P<image>[^ \f\r\t\v\n#]+)` )
431-
432- // resolvedTag records the repository, tag, and resolved digest reference
433- // from a Dockerfile rewrite.
434- type resolvedTag struct {
435- digestRef reference.Canonical
436- tagRef reference.NamedTagged
437- }
438-
439- // noBaseImageSpecifier is the symbol used by the FROM
440- // command to specify that no base image is to be used.
441- const noBaseImageSpecifier = "scratch"
442-
443- // rewriteDockerfileFromForContentTrust rewrites the given Dockerfile by resolving images in
444- // "FROM <image>" instructions to a digest reference. `translator` is a
445- // function that takes a repository name and tag reference and returns a
446- // trusted digest reference.
447- // This should be called *only* when content trust is enabled
448- func rewriteDockerfileFromForContentTrust (ctx context.Context , dockerfile io.Reader , translator translatorFunc ) (newDockerfile []byte , resolvedTags []* resolvedTag , err error ) {
449- scanner := bufio .NewScanner (dockerfile )
450- buf := bytes .NewBuffer (nil )
451-
452- // Scan the lines of the Dockerfile, looking for a "FROM" line.
453- for scanner .Scan () {
454- line := scanner .Text ()
455-
456- matches := dockerfileFromLinePattern .FindStringSubmatch (line )
457- if matches != nil && matches [1 ] != noBaseImageSpecifier {
458- // Replace the line with a resolved "FROM repo@digest"
459- var ref reference.Named
460- ref , err = reference .ParseNormalizedNamed (matches [1 ])
461- if err != nil {
462- return nil , nil , err
463- }
464- ref = reference .TagNameOnly (ref )
465- if ref , ok := ref .(reference.NamedTagged ); ok {
466- trustedRef , err := translator (ctx , ref )
467- if err != nil {
468- return nil , nil , err
469- }
470-
471- line = dockerfileFromLinePattern .ReplaceAllLiteralString (line , "FROM " + reference .FamiliarString (trustedRef ))
472- resolvedTags = append (resolvedTags , & resolvedTag {
473- digestRef : trustedRef ,
474- tagRef : ref ,
475- })
476- }
477- }
478-
479- _ , err := fmt .Fprintln (buf , line )
480- if err != nil {
481- return nil , nil , err
482- }
483- }
484-
485- return buf .Bytes (), resolvedTags , scanner .Err ()
486- }
487-
488- // replaceDockerfileForContentTrust wraps the given input tar archive stream and
489- // uses the translator to replace the Dockerfile which uses a trusted reference.
490- // Returns a new tar archive stream with the replaced Dockerfile.
491- func replaceDockerfileForContentTrust (ctx context.Context , inputTarStream io.ReadCloser , dockerfileName string , translator translatorFunc , resolvedTags * []* resolvedTag ) io.ReadCloser {
492- pipeReader , pipeWriter := io .Pipe ()
493- go func () {
494- tarReader := tar .NewReader (inputTarStream )
495- tarWriter := tar .NewWriter (pipeWriter )
496-
497- defer inputTarStream .Close ()
498-
499- for {
500- hdr , err := tarReader .Next ()
501- if err == io .EOF {
502- // Signals end of archive.
503- _ = tarWriter .Close ()
504- _ = pipeWriter .Close ()
505- return
506- }
507- if err != nil {
508- _ = pipeWriter .CloseWithError (err )
509- return
510- }
511-
512- content := io .Reader (tarReader )
513- if hdr .Name == dockerfileName {
514- // This entry is the Dockerfile. Since the tar archive was
515- // generated from a directory on the local filesystem, the
516- // Dockerfile will only appear once in the archive.
517- var newDockerfile []byte
518- newDockerfile , * resolvedTags , err = rewriteDockerfileFromForContentTrust (ctx , content , translator )
519- if err != nil {
520- _ = pipeWriter .CloseWithError (err )
521- return
522- }
523- hdr .Size = int64 (len (newDockerfile ))
524- content = bytes .NewBuffer (newDockerfile )
525- }
526-
527- if err := tarWriter .WriteHeader (hdr ); err != nil {
528- _ = pipeWriter .CloseWithError (err )
529- return
530- }
531-
532- if _ , err := io .Copy (tarWriter , content ); err != nil {
533- _ = pipeWriter .CloseWithError (err )
534- return
535- }
536- }
537- }()
538-
539- return pipeReader
540- }
541-
542395func imageBuildOptions (dockerCli command.Cli , options buildOptions ) buildtypes.ImageBuildOptions {
543396 configFile := dockerCli .ConfigFile ()
544397 return buildtypes.ImageBuildOptions {
0 commit comments